Merge tag 'm68k-for-v6.4-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 25 Apr 2023 16:37:43 +0000 (09:37 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 25 Apr 2023 16:37:43 +0000 (09:37 -0700)
Pull m68k updates from Geert Uytterhoeven:

 - defconfig updates

 - miscellaneous fixes and improvements

* tag 'm68k-for-v6.4-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k:
  m68k: kexec: Include <linux/reboot.h>
  m68k: defconfig: Update defconfigs for v6.3-rc1
  m68k: Remove obsolete config NO_KERNEL_MSG
  nubus: Drop noop match function

2336 files changed:
.gitignore
.mailmap
CREDITS
Documentation/ABI/obsolete/sysfs-selinux-checkreqprot [deleted file]
Documentation/ABI/obsolete/sysfs-selinux-disable [deleted file]
Documentation/ABI/removed/sysfs-selinux-checkreqprot [new file with mode: 0644]
Documentation/ABI/removed/sysfs-selinux-disable [new file with mode: 0644]
Documentation/ABI/stable/sysfs-block
Documentation/RCU/Design/Expedited-Grace-Periods/Expedited-Grace-Periods.rst
Documentation/RCU/Design/Memory-Ordering/Tree-RCU-Memory-Ordering.rst
Documentation/RCU/RTFP.txt
Documentation/RCU/UP.rst
Documentation/RCU/checklist.rst
Documentation/RCU/lockdep.rst
Documentation/RCU/torture.rst
Documentation/RCU/whatisRCU.rst
Documentation/admin-guide/hw-vuln/mds.rst
Documentation/admin-guide/hw-vuln/tsx_async_abort.rst
Documentation/admin-guide/index.rst
Documentation/admin-guide/kernel-parameters.rst
Documentation/admin-guide/kernel-parameters.txt
Documentation/admin-guide/quickly-build-trimmed-linux.rst [new file with mode: 0644]
Documentation/admin-guide/ras.rst
Documentation/admin-guide/reporting-issues.rst
Documentation/admin-guide/security-bugs.rst [deleted file]
Documentation/admin-guide/sysctl/kernel.rst
Documentation/admin-guide/unicode.rst
Documentation/arc/arc.rst [deleted file]
Documentation/arc/features.rst [deleted file]
Documentation/arc/index.rst [deleted file]
Documentation/arch.rst [deleted file]
Documentation/arch/arc/arc.rst [new file with mode: 0644]
Documentation/arch/arc/features.rst [new file with mode: 0644]
Documentation/arch/arc/index.rst [new file with mode: 0644]
Documentation/arch/ia64/aliasing.rst [new file with mode: 0644]
Documentation/arch/ia64/efirtc.rst [new file with mode: 0644]
Documentation/arch/ia64/err_inject.rst [new file with mode: 0644]
Documentation/arch/ia64/features.rst [new file with mode: 0644]
Documentation/arch/ia64/fsys.rst [new file with mode: 0644]
Documentation/arch/ia64/ia64.rst [new file with mode: 0644]
Documentation/arch/ia64/index.rst [new file with mode: 0644]
Documentation/arch/ia64/irq-redir.rst [new file with mode: 0644]
Documentation/arch/ia64/mca.rst [new file with mode: 0644]
Documentation/arch/ia64/serial.rst [new file with mode: 0644]
Documentation/arch/index.rst [new file with mode: 0644]
Documentation/arch/m68k/buddha-driver.rst [new file with mode: 0644]
Documentation/arch/m68k/features.rst [new file with mode: 0644]
Documentation/arch/m68k/index.rst [new file with mode: 0644]
Documentation/arch/m68k/kernel-options.rst [new file with mode: 0644]
Documentation/arch/nios2/features.rst [new file with mode: 0644]
Documentation/arch/nios2/index.rst [new file with mode: 0644]
Documentation/arch/nios2/nios2.rst [new file with mode: 0644]
Documentation/arch/openrisc/features.rst [new file with mode: 0644]
Documentation/arch/openrisc/index.rst [new file with mode: 0644]
Documentation/arch/openrisc/openrisc_port.rst [new file with mode: 0644]
Documentation/arch/openrisc/todo.rst [new file with mode: 0644]
Documentation/arch/parisc/debugging.rst [new file with mode: 0644]
Documentation/arch/parisc/features.rst [new file with mode: 0644]
Documentation/arch/parisc/index.rst [new file with mode: 0644]
Documentation/arch/parisc/registers.rst [new file with mode: 0644]
Documentation/arch/sh/booting.rst [new file with mode: 0644]
Documentation/arch/sh/features.rst [new file with mode: 0644]
Documentation/arch/sh/index.rst [new file with mode: 0644]
Documentation/arch/sh/new-machine.rst [new file with mode: 0644]
Documentation/arch/sh/register-banks.rst [new file with mode: 0644]
Documentation/arch/sparc/adi.rst [new file with mode: 0644]
Documentation/arch/sparc/console.rst [new file with mode: 0644]
Documentation/arch/sparc/features.rst [new file with mode: 0644]
Documentation/arch/sparc/index.rst [new file with mode: 0644]
Documentation/arch/sparc/oradax/dax-hv-api.txt [new file with mode: 0644]
Documentation/arch/sparc/oradax/oracle-dax.rst [new file with mode: 0644]
Documentation/arch/x86/amd-memory-encryption.rst [new file with mode: 0644]
Documentation/arch/x86/amd_hsmp.rst [new file with mode: 0644]
Documentation/arch/x86/boot.rst [new file with mode: 0644]
Documentation/arch/x86/booting-dt.rst [new file with mode: 0644]
Documentation/arch/x86/buslock.rst [new file with mode: 0644]
Documentation/arch/x86/cpuinfo.rst [new file with mode: 0644]
Documentation/arch/x86/earlyprintk.rst [new file with mode: 0644]
Documentation/arch/x86/elf_auxvec.rst [new file with mode: 0644]
Documentation/arch/x86/entry_64.rst [new file with mode: 0644]
Documentation/arch/x86/exception-tables.rst [new file with mode: 0644]
Documentation/arch/x86/features.rst [new file with mode: 0644]
Documentation/arch/x86/i386/IO-APIC.rst [new file with mode: 0644]
Documentation/arch/x86/i386/index.rst [new file with mode: 0644]
Documentation/arch/x86/ifs.rst [new file with mode: 0644]
Documentation/arch/x86/index.rst [new file with mode: 0644]
Documentation/arch/x86/intel-hfi.rst [new file with mode: 0644]
Documentation/arch/x86/intel_txt.rst [new file with mode: 0644]
Documentation/arch/x86/iommu.rst [new file with mode: 0644]
Documentation/arch/x86/kernel-stacks.rst [new file with mode: 0644]
Documentation/arch/x86/mds.rst [new file with mode: 0644]
Documentation/arch/x86/microcode.rst [new file with mode: 0644]
Documentation/arch/x86/mtrr.rst [new file with mode: 0644]
Documentation/arch/x86/orc-unwinder.rst [new file with mode: 0644]
Documentation/arch/x86/pat.rst [new file with mode: 0644]
Documentation/arch/x86/pti.rst [new file with mode: 0644]
Documentation/arch/x86/resctrl.rst [new file with mode: 0644]
Documentation/arch/x86/sgx.rst [new file with mode: 0644]
Documentation/arch/x86/sva.rst [new file with mode: 0644]
Documentation/arch/x86/tdx.rst [new file with mode: 0644]
Documentation/arch/x86/tlb.rst [new file with mode: 0644]
Documentation/arch/x86/topology.rst [new file with mode: 0644]
Documentation/arch/x86/tsx_async_abort.rst [new file with mode: 0644]
Documentation/arch/x86/usb-legacy-support.rst [new file with mode: 0644]
Documentation/arch/x86/x86_64/5level-paging.rst [new file with mode: 0644]
Documentation/arch/x86/x86_64/boot-options.rst [new file with mode: 0644]
Documentation/arch/x86/x86_64/cpu-hotplug-spec.rst [new file with mode: 0644]
Documentation/arch/x86/x86_64/fake-numa-for-cpusets.rst [new file with mode: 0644]
Documentation/arch/x86/x86_64/fsgs.rst [new file with mode: 0644]
Documentation/arch/x86/x86_64/index.rst [new file with mode: 0644]
Documentation/arch/x86/x86_64/machinecheck.rst [new file with mode: 0644]
Documentation/arch/x86/x86_64/mm.rst [new file with mode: 0644]
Documentation/arch/x86/x86_64/uefi.rst [new file with mode: 0644]
Documentation/arch/x86/xstate.rst [new file with mode: 0644]
Documentation/arch/x86/zero-page.rst [new file with mode: 0644]
Documentation/arch/xtensa/atomctl.rst [new file with mode: 0644]
Documentation/arch/xtensa/booting.rst [new file with mode: 0644]
Documentation/arch/xtensa/features.rst [new file with mode: 0644]
Documentation/arch/xtensa/index.rst [new file with mode: 0644]
Documentation/arch/xtensa/mmu.rst [new file with mode: 0644]
Documentation/arm/index.rst
Documentation/arm/sti/overview.rst
Documentation/arm/sti/stih415-overview.rst [deleted file]
Documentation/arm/sti/stih416-overview.rst [deleted file]
Documentation/bpf/bpf_devel_QA.rst
Documentation/conf.py
Documentation/core-api/asm-annotations.rst
Documentation/core-api/dma-api-howto.rst
Documentation/dev-tools/kmemleak.rst
Documentation/devicetree/bindings/interrupt-controller/loongarch,cpu-interrupt-controller.yaml [deleted file]
Documentation/devicetree/bindings/interrupt-controller/loongson,cpu-interrupt-controller.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
Documentation/devicetree/bindings/pinctrl/qcom,sm8550-lpass-lpi-pinctrl.yaml
Documentation/devicetree/bindings/serial/renesas,scif.yaml
Documentation/driver-api/clk.rst
Documentation/driver-api/device-io.rst
Documentation/driver-api/firmware/fw_search_path.rst
Documentation/driver-api/vfio.rst
Documentation/filesystems/erofs.rst
Documentation/filesystems/ext4/blockgroup.rst
Documentation/filesystems/idmappings.rst
Documentation/filesystems/mount_api.rst
Documentation/filesystems/proc.rst
Documentation/filesystems/vfs.rst
Documentation/firmware-guide/acpi/enumeration.rst
Documentation/ia64/aliasing.rst [deleted file]
Documentation/ia64/efirtc.rst [deleted file]
Documentation/ia64/err_inject.rst [deleted file]
Documentation/ia64/features.rst [deleted file]
Documentation/ia64/fsys.rst [deleted file]
Documentation/ia64/ia64.rst [deleted file]
Documentation/ia64/index.rst [deleted file]
Documentation/ia64/irq-redir.rst [deleted file]
Documentation/ia64/mca.rst [deleted file]
Documentation/ia64/serial.rst [deleted file]
Documentation/index.rst
Documentation/kbuild/llvm.rst
Documentation/kernel-hacking/false-sharing.rst [new file with mode: 0644]
Documentation/kernel-hacking/index.rst
Documentation/litmus-tests/README
Documentation/litmus-tests/locking/DCL-broken.litmus [new file with mode: 0644]
Documentation/litmus-tests/locking/DCL-fixed.litmus [new file with mode: 0644]
Documentation/litmus-tests/locking/RM-broken.litmus [new file with mode: 0644]
Documentation/litmus-tests/locking/RM-fixed.litmus [new file with mode: 0644]
Documentation/m68k/buddha-driver.rst [deleted file]
Documentation/m68k/features.rst [deleted file]
Documentation/m68k/index.rst [deleted file]
Documentation/m68k/kernel-options.rst [deleted file]
Documentation/maintainer/rebasing-and-merging.rst
Documentation/mm/hugetlbfs_reserv.rst
Documentation/mm/physical_memory.rst
Documentation/mm/zsmalloc.rst
Documentation/netlink/genetlink-c.yaml
Documentation/netlink/genetlink-legacy.yaml
Documentation/netlink/genetlink.yaml
Documentation/netlink/specs/ethtool.yaml
Documentation/netlink/specs/fou.yaml
Documentation/netlink/specs/netdev.yaml
Documentation/networking/devlink/ice.rst
Documentation/networking/ip-sysctl.rst
Documentation/networking/xdp-rx-metadata.rst
Documentation/nios2/features.rst [deleted file]
Documentation/nios2/index.rst [deleted file]
Documentation/nios2/nios2.rst [deleted file]
Documentation/openrisc/features.rst [deleted file]
Documentation/openrisc/index.rst [deleted file]
Documentation/openrisc/openrisc_port.rst [deleted file]
Documentation/openrisc/todo.rst [deleted file]
Documentation/parisc/debugging.rst [deleted file]
Documentation/parisc/features.rst [deleted file]
Documentation/parisc/index.rst [deleted file]
Documentation/parisc/registers.rst [deleted file]
Documentation/process/coding-style.rst
Documentation/process/contribution-maturity-model.rst [new file with mode: 0644]
Documentation/process/howto.rst
Documentation/process/index.rst
Documentation/process/kernel-docs.rst
Documentation/process/maintainer-tip.rst
Documentation/process/programming-language.rst
Documentation/process/researcher-guidelines.rst
Documentation/process/security-bugs.rst [new file with mode: 0644]
Documentation/process/stable-kernel-rules.rst
Documentation/process/submitting-patches.rst
Documentation/riscv/vm-layout.rst
Documentation/rust/arch-support.rst
Documentation/scheduler/sched-capacity.rst
Documentation/sh/booting.rst [deleted file]
Documentation/sh/features.rst [deleted file]
Documentation/sh/index.rst [deleted file]
Documentation/sh/new-machine.rst [deleted file]
Documentation/sh/register-banks.rst [deleted file]
Documentation/sound/hd-audio/models.rst
Documentation/sparc/adi.rst [deleted file]
Documentation/sparc/console.rst [deleted file]
Documentation/sparc/features.rst [deleted file]
Documentation/sparc/index.rst [deleted file]
Documentation/sparc/oradax/dax-hv-api.txt [deleted file]
Documentation/sparc/oradax/oracle-dax.rst [deleted file]
Documentation/trace/ftrace.rst
Documentation/translations/it_IT/admin-guide/security-bugs.rst
Documentation/translations/it_IT/core-api/symbol-namespaces.rst
Documentation/translations/it_IT/doc-guide/parse-headers.rst
Documentation/translations/it_IT/index.rst
Documentation/translations/it_IT/kernel-hacking/locking.rst
Documentation/translations/it_IT/process/5.Posting.rst
Documentation/translations/it_IT/process/changes.rst
Documentation/translations/it_IT/process/clang-format.rst
Documentation/translations/it_IT/process/coding-style.rst
Documentation/translations/it_IT/process/deprecated.rst
Documentation/translations/it_IT/process/email-clients.rst
Documentation/translations/it_IT/process/index.rst
Documentation/translations/it_IT/process/maintainer-pgp-guide.rst
Documentation/translations/it_IT/process/programming-language.rst
Documentation/translations/it_IT/process/stable-kernel-rules.rst
Documentation/translations/it_IT/process/submitting-patches.rst
Documentation/translations/it_IT/process/volatile-considered-harmful.rst
Documentation/translations/ja_JP/howto.rst
Documentation/translations/ko_KR/howto.rst
Documentation/translations/sp_SP/howto.rst
Documentation/translations/sp_SP/memory-barriers.txt
Documentation/translations/sp_SP/process/deprecated.rst [new file with mode: 0644]
Documentation/translations/sp_SP/process/index.rst
Documentation/translations/sp_SP/process/submitting-patches.rst
Documentation/translations/zh_CN/admin-guide/mm/damon/lru_sort.rst
Documentation/translations/zh_CN/admin-guide/security-bugs.rst
Documentation/translations/zh_CN/arch.rst [deleted file]
Documentation/translations/zh_CN/arch/index.rst [new file with mode: 0644]
Documentation/translations/zh_CN/arch/openrisc/index.rst [new file with mode: 0644]
Documentation/translations/zh_CN/arch/openrisc/openrisc_port.rst [new file with mode: 0644]
Documentation/translations/zh_CN/arch/openrisc/todo.rst [new file with mode: 0644]
Documentation/translations/zh_CN/arch/parisc/debugging.rst [new file with mode: 0644]
Documentation/translations/zh_CN/arch/parisc/index.rst [new file with mode: 0644]
Documentation/translations/zh_CN/arch/parisc/registers.rst [new file with mode: 0644]
Documentation/translations/zh_CN/index.rst
Documentation/translations/zh_CN/mm/hugetlbfs_reserv.rst
Documentation/translations/zh_CN/openrisc/index.rst [deleted file]
Documentation/translations/zh_CN/openrisc/openrisc_port.rst [deleted file]
Documentation/translations/zh_CN/openrisc/todo.rst [deleted file]
Documentation/translations/zh_CN/parisc/debugging.rst [deleted file]
Documentation/translations/zh_CN/parisc/index.rst [deleted file]
Documentation/translations/zh_CN/parisc/registers.rst [deleted file]
Documentation/translations/zh_CN/process/howto.rst
Documentation/translations/zh_CN/scheduler/sched-capacity.rst
Documentation/translations/zh_TW/admin-guide/security-bugs.rst
Documentation/translations/zh_TW/process/howto.rst
Documentation/usb/gadget_uvc.rst [new file with mode: 0644]
Documentation/usb/index.rst
Documentation/userspace-api/ELF.rst [new file with mode: 0644]
Documentation/userspace-api/index.rst
Documentation/userspace-api/media/v4l/pixfmt-rgb.rst
Documentation/userspace-api/netlink/specs.rst
Documentation/virt/kvm/api.rst
Documentation/x86/amd-memory-encryption.rst [deleted file]
Documentation/x86/amd_hsmp.rst [deleted file]
Documentation/x86/boot.rst [deleted file]
Documentation/x86/booting-dt.rst [deleted file]
Documentation/x86/buslock.rst [deleted file]
Documentation/x86/cpuinfo.rst [deleted file]
Documentation/x86/earlyprintk.rst [deleted file]
Documentation/x86/elf_auxvec.rst [deleted file]
Documentation/x86/entry_64.rst [deleted file]
Documentation/x86/exception-tables.rst [deleted file]
Documentation/x86/features.rst [deleted file]
Documentation/x86/i386/IO-APIC.rst [deleted file]
Documentation/x86/i386/index.rst [deleted file]
Documentation/x86/ifs.rst [deleted file]
Documentation/x86/index.rst [deleted file]
Documentation/x86/intel-hfi.rst [deleted file]
Documentation/x86/intel_txt.rst [deleted file]
Documentation/x86/iommu.rst [deleted file]
Documentation/x86/kernel-stacks.rst [deleted file]
Documentation/x86/mds.rst [deleted file]
Documentation/x86/microcode.rst [deleted file]
Documentation/x86/mtrr.rst [deleted file]
Documentation/x86/orc-unwinder.rst [deleted file]
Documentation/x86/pat.rst [deleted file]
Documentation/x86/pti.rst [deleted file]
Documentation/x86/resctrl.rst [deleted file]
Documentation/x86/sgx.rst [deleted file]
Documentation/x86/sva.rst [deleted file]
Documentation/x86/tdx.rst [deleted file]
Documentation/x86/tlb.rst [deleted file]
Documentation/x86/topology.rst [deleted file]
Documentation/x86/tsx_async_abort.rst [deleted file]
Documentation/x86/usb-legacy-support.rst [deleted file]
Documentation/x86/x86_64/5level-paging.rst [deleted file]
Documentation/x86/x86_64/boot-options.rst [deleted file]
Documentation/x86/x86_64/cpu-hotplug-spec.rst [deleted file]
Documentation/x86/x86_64/fake-numa-for-cpusets.rst [deleted file]
Documentation/x86/x86_64/fsgs.rst [deleted file]
Documentation/x86/x86_64/index.rst [deleted file]
Documentation/x86/x86_64/machinecheck.rst [deleted file]
Documentation/x86/x86_64/mm.rst [deleted file]
Documentation/x86/x86_64/uefi.rst [deleted file]
Documentation/x86/xstate.rst [deleted file]
Documentation/x86/zero-page.rst [deleted file]
Documentation/xtensa/atomctl.rst [deleted file]
Documentation/xtensa/booting.rst [deleted file]
Documentation/xtensa/features.rst [deleted file]
Documentation/xtensa/index.rst [deleted file]
Documentation/xtensa/mmu.rst [deleted file]
MAINTAINERS
Makefile
arch/alpha/lib/fpreg.c
arch/arm/Kconfig
arch/arm/boot/compressed/Makefile
arch/arm/boot/dts/e60k02.dtsi
arch/arm/boot/dts/e70k02.dtsi
arch/arm/boot/dts/imx6sl-tolino-shine2hd.dts
arch/arm/boot/dts/imx6ull-colibri.dtsi
arch/arm/boot/dts/imx7d-remarkable2.dts
arch/arm/boot/dts/qcom-apq8026-lg-lenok.dts
arch/arm/boot/dts/rk3288.dtsi
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/include/asm/assembler.h
arch/arm/lib/uaccess_with_memcpy.c
arch/arm/vfp/entry.S
arch/arm/vfp/vfphw.S
arch/arm/vfp/vfpmodule.c
arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-kbox-a-230-ls.dts
arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var1.dts
arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var2.dts
arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var4.dts
arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts
arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi
arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
arch/arm64/boot/dts/freescale/imx8mm-nitrogen-r2.dts
arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
arch/arm64/boot/dts/freescale/imx8mn.dtsi
arch/arm64/boot/dts/freescale/imx8mp-verdin-dev.dtsi
arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
arch/arm64/boot/dts/freescale/imx8mp.dtsi
arch/arm64/boot/dts/freescale/imx93.dtsi
arch/arm64/boot/dts/nvidia/tegra194.dtsi
arch/arm64/boot/dts/nvidia/tegra234.dtsi
arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
arch/arm64/boot/dts/qcom/ipq8074-hk10.dtsi
arch/arm64/boot/dts/qcom/msm8916-thwc-uf896.dts
arch/arm64/boot/dts/qcom/msm8916-thwc-ufi001c.dts
arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi
arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
arch/arm64/boot/dts/qcom/sa8540p-ride.dts
arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi
arch/arm64/boot/dts/qcom/sc7280.dtsi
arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi
arch/arm64/boot/dts/qcom/sc8280xp.dtsi
arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts
arch/arm64/boot/dts/qcom/sm6115.dtsi
arch/arm64/boot/dts/qcom/sm6375.dtsi
arch/arm64/boot/dts/qcom/sm8150.dtsi
arch/arm64/boot/dts/qcom/sm8250-mtp.dts
arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish.dts
arch/arm64/boot/dts/qcom/sm8350.dtsi
arch/arm64/boot/dts/qcom/sm8450.dtsi
arch/arm64/boot/dts/qcom/sm8550.dtsi
arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351m.dts
arch/arm64/boot/dts/rockchip/rk3326-odroid-go.dtsi
arch/arm64/boot/dts/rockchip/rk3326-odroid-go2-v11.dts
arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts
arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi
arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi
arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi
arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
arch/arm64/boot/dts/rockchip/rk3399.dtsi
arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353x.dtsi
arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts
arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi
arch/arm64/boot/dts/rockchip/rk3588s.dtsi
arch/arm64/include/asm/kvm_host.h
arch/arm64/kernel/compat_alignment.c
arch/arm64/kernel/efi-header.S
arch/arm64/kvm/Kconfig
arch/arm64/kvm/arch_timer.c
arch/arm64/kvm/arm.c
arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
arch/arm64/kvm/hyp/nvhe/sys_regs.c
arch/arm64/kvm/hypercalls.c
arch/arm64/kvm/mmu.c
arch/arm64/kvm/pmu-emul.c
arch/arm64/kvm/sys_regs.c
arch/arm64/net/bpf_jit.h
arch/arm64/net/bpf_jit_comp.c
arch/csky/include/asm/processor.h
arch/ia64/kernel/efi.c
arch/ia64/kernel/fsys.S
arch/ia64/mm/ioremap.c
arch/ia64/pci/pci.c
arch/loongarch/Kconfig
arch/loongarch/include/asm/acpi.h
arch/loongarch/include/asm/addrspace.h
arch/loongarch/include/asm/bootinfo.h
arch/loongarch/include/asm/cpu-features.h
arch/loongarch/include/asm/cpu.h
arch/loongarch/include/asm/io.h
arch/loongarch/include/asm/loongarch.h
arch/loongarch/include/asm/module.lds.h
arch/loongarch/include/uapi/asm/ptrace.h
arch/loongarch/kernel/cpu-probe.c
arch/loongarch/kernel/proc.c
arch/loongarch/kernel/ptrace.c
arch/loongarch/kernel/setup.c
arch/loongarch/kernel/stacktrace.c
arch/loongarch/kernel/unwind.c
arch/loongarch/kernel/unwind_prologue.c
arch/loongarch/mm/init.c
arch/loongarch/net/bpf_jit.c
arch/loongarch/power/suspend_asm.S
arch/m68k/Kconfig.machine
arch/mips/bmips/dma.c
arch/mips/bmips/setup.c
arch/mips/configs/mtx1_defconfig
arch/mips/kernel/vmlinux.lds.S
arch/mips/kvm/Kconfig
arch/nios2/include/asm/thread_info.h
arch/powerpc/boot/dts/fsl/t1040rdb-rev-a.dts
arch/powerpc/boot/dts/fsl/t1040rdb.dts
arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
arch/powerpc/configs/ppc6xx_defconfig
arch/powerpc/include/asm/book3s/64/tlbflush.h
arch/powerpc/include/asm/kasan.h
arch/powerpc/include/asm/string.h
arch/powerpc/kernel/prom_init_check.sh
arch/powerpc/kernel/ptrace/ptrace-view.c
arch/powerpc/kvm/Kconfig
arch/powerpc/kvm/powerpc.c
arch/powerpc/mm/fault.c
arch/powerpc/mm/numa.c
arch/powerpc/platforms/pseries/Kconfig
arch/powerpc/platforms/pseries/papr_scm.c
arch/powerpc/platforms/pseries/vas.c
arch/powerpc/xmon/xmon.c
arch/riscv/Kconfig
arch/riscv/Kconfig.erratas
arch/riscv/Makefile
arch/riscv/boot/dts/canaan/k210.dtsi
arch/riscv/errata/sifive/errata.c
arch/riscv/include/asm/fixmap.h
arch/riscv/include/asm/ftrace.h
arch/riscv/include/asm/hwcap.h
arch/riscv/include/asm/mmu.h
arch/riscv/include/asm/patch.h
arch/riscv/include/asm/pgtable.h
arch/riscv/include/asm/tlbflush.h
arch/riscv/kernel/compat_vdso/Makefile
arch/riscv/kernel/ftrace.c
arch/riscv/kernel/patch.c
arch/riscv/kernel/setup.c
arch/riscv/kernel/signal.c
arch/riscv/kernel/stacktrace.c
arch/riscv/kvm/Kconfig
arch/riscv/kvm/vcpu_timer.c
arch/riscv/mm/context.c
arch/riscv/mm/fault.c
arch/riscv/mm/init.c
arch/riscv/mm/tlbflush.c
arch/riscv/net/bpf_jit_comp64.c
arch/riscv/purgatory/Makefile
arch/s390/Makefile
arch/s390/boot/ipl_report.c
arch/s390/configs/debug_defconfig
arch/s390/configs/defconfig
arch/s390/configs/zfcpdump_defconfig
arch/s390/kernel/ptrace.c
arch/s390/kvm/Kconfig
arch/s390/kvm/intercept.c
arch/s390/kvm/kvm-s390.c
arch/s390/lib/uaccess.c
arch/s390/net/bpf_jit_comp.c
arch/s390/pci/pci.c
arch/s390/pci/pci_bus.c
arch/s390/pci/pci_bus.h
arch/sh/Kconfig.cpu
arch/sh/include/asm/processor_32.h
arch/sh/kernel/signal_32.c
arch/x86/Kconfig
arch/x86/Kconfig.debug
arch/x86/Makefile.um
arch/x86/boot/header.S
arch/x86/entry/entry_64.S
arch/x86/events/amd/core.c
arch/x86/include/asm/alternative.h
arch/x86/include/asm/bootparam_utils.h
arch/x86/include/asm/intel-family.h
arch/x86/include/asm/page_64_types.h
arch/x86/include/asm/pgtable_64_types.h
arch/x86/include/asm/resctrl.h
arch/x86/include/asm/sev-common.h
arch/x86/include/asm/svm.h
arch/x86/include/asm/uaccess_64.h
arch/x86/include/asm/xen/cpuid.h
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/mce/core.c
arch/x86/kernel/cpu/microcode/amd.c
arch/x86/kernel/cpu/mshyperv.c
arch/x86/kernel/cpu/resctrl/ctrlmondata.c
arch/x86/kernel/cpu/resctrl/internal.h
arch/x86/kernel/cpu/resctrl/monitor.c
arch/x86/kernel/cpu/resctrl/rdtgroup.c
arch/x86/kernel/cpu/sgx/main.c
arch/x86/kernel/cpu/sgx/sgx.h
arch/x86/kernel/fpu/xstate.c
arch/x86/kernel/ftrace_64.S
arch/x86/kernel/kexec-bzimage64.c
arch/x86/kernel/pci-dma.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/sev.c
arch/x86/kernel/x86_init.c
arch/x86/kvm/Kconfig
arch/x86/kvm/ioapic.c
arch/x86/kvm/kvm_onhyperv.h
arch/x86/kvm/svm/avic.c
arch/x86/kvm/svm/sev.c
arch/x86/kvm/svm/svm.c
arch/x86/kvm/svm/svm_onhyperv.h
arch/x86/kvm/vmx/nested.c
arch/x86/kvm/vmx/vmenter.S
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/x86.c
arch/x86/lib/Makefile
arch/x86/lib/clear_page_64.S
arch/x86/lib/copy_user_64.S
arch/x86/lib/copy_user_uncached_64.S [new file with mode: 0644]
arch/x86/lib/memcpy_64.S
arch/x86/lib/memset_64.S
arch/x86/lib/usercopy_64.c
arch/x86/mm/cpu_entry_area.c
arch/x86/mm/mem_encrypt_identity.c
arch/x86/mm/pat/set_memory.c
arch/x86/mm/tlb.c
arch/x86/pci/fixup.c
arch/x86/platform/pvh/enlighten.c
arch/x86/purgatory/Makefile
arch/x86/xen/Makefile
arch/x86/xen/enlighten_pv.c
arch/x86/xen/enlighten_pvh.c
arch/x86/xen/time.c
arch/x86/xen/vga.c
arch/x86/xen/xen-ops.h
arch/xtensa/include/asm/initialize_mmu.h
arch/xtensa/kernel/traps.c
block/Kconfig
block/bfq-iosched.c
block/blk-core.c
block/blk-map.c
block/blk-mq.c
block/blk-mq.h
block/genhd.c
certs/system_keyring.c
crypto/asymmetric_keys/pkcs7_verify.c
crypto/asymmetric_keys/restrict.c
crypto/asymmetric_keys/verify_pefile.c
crypto/asymmetric_keys/x509_cert_parser.c
drivers/accel/Makefile
drivers/accel/ivpu/ivpu_drv.c
drivers/accel/ivpu/ivpu_drv.h
drivers/accel/ivpu/ivpu_hw_mtl.c
drivers/accel/ivpu/ivpu_ipc.h
drivers/accel/ivpu/ivpu_job.c
drivers/accel/ivpu/ivpu_pm.c
drivers/accel/ivpu/ivpu_pm.h
drivers/acpi/acpi_video.c
drivers/acpi/acpica/evevent.c
drivers/acpi/acpica/hwsleep.c
drivers/acpi/acpica/utglobal.c
drivers/acpi/bus.c
drivers/acpi/pptt.c
drivers/acpi/processor_driver.c
drivers/acpi/processor_thermal.c
drivers/acpi/resource.c
drivers/acpi/video_detect.c
drivers/acpi/x86/utils.c
drivers/ata/pata_parport/pata_parport.c
drivers/atm/idt77252.c
drivers/base/cacheinfo.c
drivers/base/cpu.c
drivers/block/drbd/drbd_nl.c
drivers/block/drbd/drbd_receiver.c
drivers/block/drbd/drbd_state.c
drivers/block/loop.c
drivers/block/null_blk/main.c
drivers/block/sunvdc.c
drivers/block/ublk_drv.c
drivers/block/virtio_blk.c
drivers/bluetooth/btbcm.c
drivers/bluetooth/btintel.c
drivers/bluetooth/btintel.h
drivers/bluetooth/btqcomsmd.c
drivers/bluetooth/btsdio.c
drivers/bluetooth/btusb.c
drivers/bus/imx-weim.c
drivers/char/random.c
drivers/char/tpm/eventlog/acpi.c
drivers/char/tpm/eventlog/common.c
drivers/char/tpm/st33zp24/i2c.c
drivers/char/tpm/st33zp24/spi.c
drivers/char/tpm/tpm-chip.c
drivers/char/tpm/tpm.h
drivers/char/tpm/tpm_ftpm_tee.c
drivers/char/tpm/tpm_tis.c
drivers/char/tpm/tpm_tis_core.c
drivers/char/tpm/tpm_tis_core.h
drivers/char/tpm/tpm_tis_i2c_cr50.c
drivers/char/tpm/tpm_tis_spi_main.c
drivers/char/tpm/tpm_tis_synquacer.c
drivers/clk/Kconfig
drivers/clk/bcm/clk-bcm2835-aux.c
drivers/clk/bcm/clk-bcm2835.c
drivers/clk/clk-fixed-mmio.c
drivers/clk/clk-fsl-sai.c
drivers/clk/clk-k210.c
drivers/clk/clk-renesas-pcie.c
drivers/clk/hisilicon/clk-hi3559a.c
drivers/clk/imx/clk-imx6ul.c
drivers/clk/microchip/clk-mpfs-ccc.c
drivers/clk/sprd/common.c
drivers/counter/104-quad-8.c
drivers/cpufreq/amd-pstate.c
drivers/cpuidle/cpuidle-psci-domain.c
drivers/cxl/core/hdm.c
drivers/cxl/core/pci.c
drivers/cxl/core/pmem.c
drivers/cxl/core/port.c
drivers/cxl/core/region.c
drivers/cxl/cxl.h
drivers/cxl/cxlpci.h
drivers/cxl/port.c
drivers/dma/apple-admac.c
drivers/dma/dmaengine.c
drivers/dma/xilinx/xdma.c
drivers/firmware/arm_scmi/bus.c
drivers/firmware/arm_scmi/driver.c
drivers/firmware/arm_scmi/mailbox.c
drivers/firmware/efi/earlycon.c
drivers/firmware/efi/efi-init.c
drivers/firmware/efi/libstub/Makefile.zboot
drivers/firmware/efi/libstub/arm64-stub.c
drivers/firmware/efi/libstub/arm64.c
drivers/firmware/efi/libstub/efi-stub-entry.c
drivers/firmware/efi/libstub/efi-stub.c
drivers/firmware/efi/libstub/efistub.h
drivers/firmware/efi/libstub/randomalloc.c
drivers/firmware/efi/libstub/screen_info.c
drivers/firmware/efi/libstub/smbios.c
drivers/firmware/efi/libstub/zboot-header.S
drivers/firmware/efi/libstub/zboot.c
drivers/firmware/efi/sysfb_efi.c
drivers/firmware/psci/psci.c
drivers/firmware/qcom_scm.c
drivers/firmware/sysfb.c
drivers/firmware/sysfb_simplefb.c
drivers/firmware/xilinx/zynqmp.c
drivers/fpga/dfl-pci.c
drivers/fpga/fpga-bridge.c
drivers/fpga/intel-m10-bmc-sec-update.c
drivers/fpga/xilinx-pr-decoupler.c
drivers/gpio/Kconfig
drivers/gpio/gpio-104-dio-48e.c
drivers/gpio/gpio-104-idi-48.c
drivers/gpio/gpio-davinci.c
drivers/gpio/gpiolib-acpi.c
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c
drivers/gpu/drm/amd/amdgpu/nv.c
drivers/gpu/drm/amd/amdgpu/soc15.c
drivers/gpu/drm/amd/amdgpu/soc21.c
drivers/gpu/drm/amd/amdgpu/umc_v8_10.h
drivers/gpu/drm/amd/amdgpu/vi.c
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
drivers/gpu/drm/amd/amdkfd/kfd_device.c
drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
drivers/gpu/drm/amd/amdkfd/kfd_module.c
drivers/gpu/drm/amd/amdkfd/kfd_priv.h
drivers/gpu/drm/amd/amdkfd/kfd_process.c
drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c
drivers/gpu/drm/amd/display/dc/link/link_detection.c
drivers/gpu/drm/amd/display/modules/power/power_helpers.c
drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_4.h
drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
drivers/gpu/drm/armada/armada_drv.c
drivers/gpu/drm/bridge/lontium-lt8912b.c
drivers/gpu/drm/display/drm_hdmi_helper.c
drivers/gpu/drm/drm_atomic.c
drivers/gpu/drm/drm_buddy.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/drm_gem.c
drivers/gpu/drm/drm_gem_shmem_helper.c
drivers/gpu/drm/drm_panel_orientation_quirks.c
drivers/gpu/drm/etnaviv/etnaviv_drv.c
drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
drivers/gpu/drm/i915/display/icl_dsi.c
drivers/gpu/drm/i915/display/intel_color.c
drivers/gpu/drm/i915/display/intel_color.h
drivers/gpu/drm/i915/display/intel_crtc.c
drivers/gpu/drm/i915/display/intel_display.c
drivers/gpu/drm/i915/display/intel_display_types.h
drivers/gpu/drm/i915/display/intel_dmc.c
drivers/gpu/drm/i915/display/intel_dp_aux.c
drivers/gpu/drm/i915/display/intel_dp_mst.c
drivers/gpu/drm/i915/display/intel_dpt.c
drivers/gpu/drm/i915/display/intel_fbdev.c
drivers/gpu/drm/i915/display/intel_psr.c
drivers/gpu/drm/i915/display/intel_snps_phy.c
drivers/gpu/drm/i915/display/intel_tc.c
drivers/gpu/drm/i915/gem/i915_gem_lmem.c
drivers/gpu/drm/i915/gem/i915_gem_object.h
drivers/gpu/drm/i915/gem/i915_gem_object_types.h
drivers/gpu/drm/i915/gem/i915_gem_ttm.c
drivers/gpu/drm/i915/gt/intel_execlists_submission.c
drivers/gpu/drm/i915/gt/intel_gt.c
drivers/gpu/drm/i915/gt/intel_gt_pm.c
drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c
drivers/gpu/drm/i915/gt/intel_rc6.c
drivers/gpu/drm/i915/gt/intel_rps.c
drivers/gpu/drm/i915/gt/intel_rps.h
drivers/gpu/drm/i915/gt/intel_sseu.h
drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c
drivers/gpu/drm/i915/gt/uc/intel_huc.c
drivers/gpu/drm/i915/gt/uc/intel_huc.h
drivers/gpu/drm/i915/i915_active.c
drivers/gpu/drm/i915/i915_perf.c
drivers/gpu/drm/i915/i915_perf_types.h
drivers/gpu/drm/i915/i915_pmu.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/meson/meson_drv.c
drivers/gpu/drm/meson/meson_dw_hdmi.c
drivers/gpu/drm/meson/meson_vpp.c
drivers/gpu/drm/msm/Kconfig
drivers/gpu/drm/msm/adreno/a5xx_gpu.c
drivers/gpu/drm/msm/adreno/a5xx_preempt.c
drivers/gpu/drm/msm/adreno/a6xx_gmu.c
drivers/gpu/drm/msm/adreno/a6xx_gpu.c
drivers/gpu/drm/msm/adreno/adreno_device.c
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
drivers/gpu/drm/msm/msm_gem_shrinker.c
drivers/gpu/drm/msm/msm_gem_submit.c
drivers/gpu/drm/nouveau/dispnv50/disp.c
drivers/gpu/drm/nouveau/dispnv50/wndw.h
drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
drivers/gpu/drm/nouveau/nouveau_backlight.c
drivers/gpu/drm/nouveau/nouveau_dp.c
drivers/gpu/drm/nouveau/nouveau_gem.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga100.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf108.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk110.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp102.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/gv100.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h
drivers/gpu/drm/nouveau/nvkm/subdev/fb/tu102.c
drivers/gpu/drm/panfrost/panfrost_mmu.c
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
drivers/gpu/drm/scheduler/sched_entity.c
drivers/gpu/drm/scheduler/sched_main.c
drivers/gpu/drm/sun4i/sun4i_drv.c
drivers/gpu/drm/tests/drm_buddy_test.c
drivers/gpu/drm/tiny/cirrus.c
drivers/gpu/drm/ttm/ttm_bo.c
drivers/gpu/drm/ttm/ttm_device.c
drivers/gpu/drm/virtio/virtgpu_vq.c
drivers/gpu/host1x/dev.c
drivers/hid/Kconfig
drivers/hid/hid-core.c
drivers/hid/hid-cp2112.c
drivers/hid/hid-ids.h
drivers/hid/hid-input.c
drivers/hid/hid-logitech-hidpp.c
drivers/hid/hid-sensor-custom.c
drivers/hid/hid-topre.c
drivers/hid/intel-ish-hid/ipc/ipc.c
drivers/hid/intel-ish-hid/ishtp/bus.c
drivers/hid/uhid.c
drivers/hv/connection.c
drivers/hwmon/adt7475.c
drivers/hwmon/hwmon.c
drivers/hwmon/ina3221.c
drivers/hwmon/it87.c
drivers/hwmon/ltc2992.c
drivers/hwmon/peci/cputemp.c
drivers/hwmon/pmbus/adm1266.c
drivers/hwmon/pmbus/ucd9000.c
drivers/hwmon/tmp513.c
drivers/hwmon/xgene-hwmon.c
drivers/hwtracing/coresight/coresight-etm4x-core.c
drivers/hwtracing/coresight/coresight-etm4x.h
drivers/i2c/busses/i2c-hisi.c
drivers/i2c/busses/i2c-imx-lpi2c.c
drivers/i2c/busses/i2c-mchp-pci1xxxx.c
drivers/i2c/busses/i2c-mxs.c
drivers/i2c/busses/i2c-ocores.c
drivers/i2c/busses/i2c-xgene-slimpro.c
drivers/i2c/i2c-core-base.c
drivers/i2c/i2c-core-of.c
drivers/i2c/i2c-dev.c
drivers/i2c/i2c-slave-eeprom.c
drivers/i2c/i2c-slave-testunit.c
drivers/i2c/i2c-smbus.c
drivers/i2c/muxes/i2c-mux-ltc4306.c
drivers/i2c/muxes/i2c-mux-pca9541.c
drivers/i2c/muxes/i2c-mux-pca954x.c
drivers/iio/accel/kionix-kx022a.c
drivers/iio/adc/ad7791.c
drivers/iio/adc/at91-sama5d2_adc.c
drivers/iio/adc/ltc2497.c
drivers/iio/adc/max11410.c
drivers/iio/adc/palmas_gpadc.c
drivers/iio/adc/qcom-spmi-adc5.c
drivers/iio/adc/ti-ads7950.c
drivers/iio/dac/ad5755.c
drivers/iio/dac/cio-dac.c
drivers/iio/imu/Kconfig
drivers/iio/industrialio-buffer.c
drivers/iio/light/cm32181.c
drivers/iio/light/tsl2772.c
drivers/iio/light/vcnl4000.c
drivers/infiniband/core/cma.c
drivers/infiniband/core/verbs.c
drivers/infiniband/hw/erdma/erdma_cq.c
drivers/infiniband/hw/erdma/erdma_hw.h
drivers/infiniband/hw/erdma/erdma_main.c
drivers/infiniband/hw/erdma/erdma_qp.c
drivers/infiniband/hw/erdma/erdma_verbs.h
drivers/infiniband/hw/hfi1/file_ops.c
drivers/infiniband/hw/irdma/cm.c
drivers/infiniband/hw/irdma/cm.h
drivers/infiniband/hw/irdma/hw.c
drivers/infiniband/hw/irdma/utils.c
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/qib/qib_file_ops.c
drivers/infiniband/sw/rdmavt/qp.c
drivers/input/joystick/xpad.c
drivers/input/mouse/alps.c
drivers/input/mouse/focaltech.c
drivers/input/serio/i8042-acpipnpio.h
drivers/input/tablet/pegasus_notetaker.c
drivers/input/touchscreen/cyttsp5.c
drivers/input/touchscreen/goodix.c
drivers/interconnect/core.c
drivers/interconnect/imx/imx.c
drivers/interconnect/qcom/icc-rpm.c
drivers/interconnect/qcom/icc-rpmh.c
drivers/interconnect/qcom/msm8974.c
drivers/interconnect/qcom/osm-l3.c
drivers/interconnect/qcom/qcm2290.c
drivers/interconnect/qcom/sm8450.c
drivers/interconnect/qcom/sm8550.c
drivers/interconnect/samsung/exynos.c
drivers/iommu/exynos-iommu.c
drivers/iommu/intel/dmar.c
drivers/iommu/intel/iommu.h
drivers/iommu/intel/irq_remapping.c
drivers/iommu/intel/perfmon.c
drivers/iommu/iommufd/pages.c
drivers/md/Kconfig
drivers/md/dm-crypt.c
drivers/md/dm-stats.c
drivers/md/dm-stats.h
drivers/md/dm-thin.c
drivers/md/dm.c
drivers/md/md.c
drivers/media/i2c/imx290.c
drivers/media/i2c/m5mols/m5mols_core.c
drivers/media/i2c/ov2685.c
drivers/media/i2c/ov5695.c
drivers/media/platform/qcom/venus/firmware.c
drivers/memory/tegra/mc.c
drivers/memory/tegra/tegra124-emc.c
drivers/memory/tegra/tegra20-emc.c
drivers/memory/tegra/tegra30-emc.c
drivers/memstick/core/memstick.c
drivers/misc/ad525x_dpot-i2c.c
drivers/misc/vmw_vmci/vmci_context.c
drivers/misc/vmw_vmci/vmci_event.c
drivers/mmc/host/dw_mmc-starfive.c
drivers/mmc/host/sdhci_am654.c
drivers/mtd/maps/pismo.c
drivers/mtd/mtdblock.c
drivers/mtd/nand/ecc-mxic.c
drivers/mtd/nand/raw/meson_nand.c
drivers/mtd/nand/raw/nandsim.c
drivers/mtd/nand/raw/stm32_fmc2_nand.c
drivers/mtd/spi-nor/core.c
drivers/mtd/spi-nor/core.h
drivers/mtd/spi-nor/debugfs.c
drivers/mtd/ubi/block.c
drivers/mtd/ubi/build.c
drivers/mtd/ubi/wl.c
drivers/net/bonding/bond_main.c
drivers/net/can/cc770/cc770_platform.c
drivers/net/dsa/b53/b53_mmap.c
drivers/net/dsa/microchip/ksz8795.c
drivers/net/dsa/microchip/ksz8863_smi.c
drivers/net/dsa/microchip/ksz_common.c
drivers/net/dsa/mt7530.c
drivers/net/dsa/mv88e6xxx/chip.c
drivers/net/dsa/mv88e6xxx/global2.c
drivers/net/dsa/mv88e6xxx/global2.h
drivers/net/dsa/realtek/realtek-mdio.c
drivers/net/ethernet/Kconfig
drivers/net/ethernet/Makefile
drivers/net/ethernet/amazon/ena/ena_ethtool.c
drivers/net/ethernet/amazon/ena/ena_netdev.c
drivers/net/ethernet/aquantia/atlantic/aq_ring.c
drivers/net/ethernet/broadcom/bgmac.c
drivers/net/ethernet/broadcom/bgmac.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c
drivers/net/ethernet/cadence/macb_main.c
drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
drivers/net/ethernet/cavium/thunder/nicvf_main.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
drivers/net/ethernet/davicom/dm9000.c
drivers/net/ethernet/fealnx.c [new file with mode: 0644]
drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
drivers/net/ethernet/freescale/fec.h
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/freescale/fec_mpc52xx.c
drivers/net/ethernet/freescale/gianfar.c
drivers/net/ethernet/google/gve/gve.h
drivers/net/ethernet/google/gve/gve_ethtool.c
drivers/net/ethernet/google/gve/gve_tx.c
drivers/net/ethernet/i825xx/sni_82596.c
drivers/net/ethernet/ibm/emac/core.c
drivers/net/ethernet/ibm/emac/rgmii.c
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/intel/i40e/i40e_diag.c
drivers/net/ethernet/intel/i40e/i40e_diag.h
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_txrx.c
drivers/net/ethernet/intel/iavf/iavf.h
drivers/net/ethernet/intel/iavf/iavf_common.c
drivers/net/ethernet/intel/iavf/iavf_main.c
drivers/net/ethernet/intel/iavf/iavf_txrx.c
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
drivers/net/ethernet/intel/ice/ice.h
drivers/net/ethernet/intel/ice/ice_dcb.c
drivers/net/ethernet/intel/ice/ice_ethtool.c
drivers/net/ethernet/intel/ice/ice_lib.c
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/ice/ice_sched.c
drivers/net/ethernet/intel/ice/ice_sriov.c
drivers/net/ethernet/intel/ice/ice_switch.c
drivers/net/ethernet/intel/ice/ice_tc_lib.c
drivers/net/ethernet/intel/ice/ice_txrx.c
drivers/net/ethernet/intel/ice/ice_txrx_lib.c
drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c
drivers/net/ethernet/intel/ice/ice_xsk.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/igbvf/netdev.c
drivers/net/ethernet/intel/igbvf/vf.c
drivers/net/ethernet/intel/igc/igc_main.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c
drivers/net/ethernet/marvell/octeontx2/af/rvu.h
drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_npa.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h
drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
drivers/net/ethernet/mediatek/mtk_eth_soc.c
drivers/net/ethernet/mediatek/mtk_eth_soc.h
drivers/net/ethernet/mediatek/mtk_ppe.c
drivers/net/ethernet/mediatek/mtk_ppe_offload.c
drivers/net/ethernet/mediatek/mtk_sgmii.c
drivers/net/ethernet/mellanox/mlx4/en_rx.c
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
drivers/net/ethernet/mellanox/mlx5/core/dev.c
drivers/net/ethernet/mellanox/mlx5/core/ecpf.c
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/police.c
drivers/net/ethernet/mellanox/mlx5/core/en/tc/act_stats.c
drivers/net/ethernet/mellanox/mlx5/core/en/tc/int_port.c
drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c
drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
drivers/net/ethernet/mellanox/mlx5/core/main.c
drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2_tlv_multi.c
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
drivers/net/ethernet/microchip/lan966x/lan966x_police.c
drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c
drivers/net/ethernet/mscc/ocelot_stats.c
drivers/net/ethernet/natsemi/sonic.c
drivers/net/ethernet/netronome/nfp/nfd3/dp.c
drivers/net/ethernet/netronome/nfp/nfd3/ipsec.c
drivers/net/ethernet/netronome/nfp/nfdk/dp.c
drivers/net/ethernet/netronome/nfp/nfdk/ipsec.c
drivers/net/ethernet/netronome/nfp/nfp_net_common.c
drivers/net/ethernet/qlogic/qed/qed_dev.c
drivers/net/ethernet/qlogic/qed/qed_mng_tlv.c
drivers/net/ethernet/qlogic/qed/qed_sriov.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
drivers/net/ethernet/qualcomm/emac/emac.c
drivers/net/ethernet/realtek/r8169_phy_config.c
drivers/net/ethernet/renesas/ravb_main.c
drivers/net/ethernet/renesas/rswitch.c
drivers/net/ethernet/renesas/rswitch.h
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/sfc/ef10.c
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/efx_common.c
drivers/net/ethernet/smsc/smsc911x.c
drivers/net/ethernet/stmicro/stmmac/common.h
drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/sun/ldmvsw.c
drivers/net/ethernet/sun/niu.c
drivers/net/ethernet/sun/sunvnet.c
drivers/net/ethernet/ti/am65-cpsw-nuss.c
drivers/net/ethernet/ti/am65-cpts.c
drivers/net/ethernet/ti/cpsw-phy-sel.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/ethernet/ti/cpsw_new.c
drivers/net/ethernet/ti/netcp_ethss.c
drivers/net/ethernet/toshiba/ps3_gelic_net.c
drivers/net/ethernet/toshiba/ps3_gelic_net.h
drivers/net/ethernet/via/via-velocity.c
drivers/net/ethernet/via/via-velocity.h
drivers/net/ethernet/wangxun/libwx/wx_type.h
drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
drivers/net/ethernet/xilinx/ll_temac_main.c
drivers/net/ethernet/xircom/xirc2ps_cs.c
drivers/net/hamradio/Kconfig
drivers/net/ieee802154/ca8210.c
drivers/net/ipa/gsi_reg.c
drivers/net/ipa/gsi_reg.h
drivers/net/ipa/gsi_trans.c
drivers/net/ipa/ipa_reg.c
drivers/net/ipa/ipa_reg.h
drivers/net/ipa/reg.h
drivers/net/ipa/reg/gsi_reg-v4.5.c
drivers/net/ipa/reg/gsi_reg-v4.9.c
drivers/net/ipvlan/ipvlan_l3s.c
drivers/net/mdio/acpi_mdio.c
drivers/net/mdio/mdio-thunder.c
drivers/net/mdio/of_mdio.c
drivers/net/net_failover.c
drivers/net/phy/dp83869.c
drivers/net/phy/mdio_devres.c
drivers/net/phy/micrel.c
drivers/net/phy/microchip.c
drivers/net/phy/mscc/mscc_main.c
drivers/net/phy/nxp-c45-tja11xx.c
drivers/net/phy/phy.c
drivers/net/phy/phy_device.c
drivers/net/phy/phylink.c
drivers/net/phy/sfp-bus.c
drivers/net/phy/sfp.c
drivers/net/phy/smsc.c
drivers/net/tun.c
drivers/net/usb/asix_devices.c
drivers/net/usb/cdc_mbim.c
drivers/net/usb/lan78xx.c
drivers/net/usb/plusb.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/r8152.c
drivers/net/usb/smsc75xx.c
drivers/net/usb/smsc95xx.c
drivers/net/veth.c
drivers/net/virtio_net.c
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/wan/fsl_ucc_hdlc.c
drivers/net/wireguard/queueing.h
drivers/net/wireless/ath/ath11k/mhi.c
drivers/net/wireless/ath/ath9k/mci.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/ops.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/marvell/mwifiex/pcie.c
drivers/net/wireless/marvell/mwifiex/sdio.c
drivers/net/wireless/mediatek/mt76/mac80211.c
drivers/net/wireless/mediatek/mt76/mt76.h
drivers/net/wireless/mediatek/mt76/mt7603/main.c
drivers/net/wireless/mediatek/mt76/mt7615/mac.c
drivers/net/wireless/mediatek/mt76/mt7615/main.c
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
drivers/net/wireless/mediatek/mt76/mt76x02_util.c
drivers/net/wireless/mediatek/mt76/mt7915/init.c
drivers/net/wireless/mediatek/mt76/mt7915/main.c
drivers/net/wireless/mediatek/mt76/mt7921/init.c
drivers/net/wireless/mediatek/mt76/mt7921/main.c
drivers/net/wireless/mediatek/mt76/mt7921/pci.c
drivers/net/wireless/mediatek/mt76/mt7996/main.c
drivers/net/wireless/ti/wlcore/spi.c
drivers/net/wwan/iosm/iosm_ipc_imem.c
drivers/net/wwan/iosm/iosm_ipc_pcie.c
drivers/net/wwan/t7xx/Makefile
drivers/net/xen-netback/common.h
drivers/net/xen-netback/netback.c
drivers/nfc/fdp/i2c.c
drivers/nfc/pn533/usb.c
drivers/nfc/st-nci/ndlc.c
drivers/nvme/host/core.c
drivers/nvme/host/ioctl.c
drivers/nvme/host/multipath.c
drivers/nvme/host/pci.c
drivers/nvme/host/tcp.c
drivers/nvme/target/core.c
drivers/nvmem/core.c
drivers/of/dynamic.c
drivers/of/platform.c
drivers/pci/bus.c
drivers/pci/controller/dwc/pcie-designware.c
drivers/pci/doe.c
drivers/pci/msi/msi.c
drivers/pci/of.c
drivers/pci/pci.h
drivers/pci/probe.c
drivers/pci/remove.c
drivers/perf/amlogic/meson_g12_ddr_pmu.c
drivers/pinctrl/mediatek/Kconfig
drivers/pinctrl/pinctrl-at91-pio4.c
drivers/pinctrl/pinctrl-ocelot.c
drivers/pinctrl/stm32/pinctrl-stm32.c
drivers/platform/chrome/cros_ec_chardev.c
drivers/platform/mellanox/Kconfig
drivers/platform/surface/aggregator/bus.c
drivers/platform/x86/Kconfig
drivers/platform/x86/amd/pmc.c
drivers/platform/x86/asus-nb-wmi.c
drivers/platform/x86/dell/dell-wmi-ddv.c
drivers/platform/x86/gigabyte-wmi.c
drivers/platform/x86/ideapad-laptop.c
drivers/platform/x86/intel/int3472/tps68470_board_data.c
drivers/platform/x86/intel/pmc/core.c
drivers/platform/x86/intel/speed_select_if/isst_if_common.c
drivers/platform/x86/intel/speed_select_if/isst_if_common.h
drivers/platform/x86/intel/tpmi.c
drivers/platform/x86/intel/vsec.c
drivers/platform/x86/mlx-platform.c
drivers/platform/x86/think-lmi.c
drivers/platform/x86/thinkpad_acpi.c
drivers/power/supply/axp288_fuel_gauge.c
drivers/power/supply/bq24190_charger.c
drivers/power/supply/cros_usbpd-charger.c
drivers/power/supply/da9150-charger.c
drivers/power/supply/rk817_charger.c
drivers/ptp/ptp_qoriq.c
drivers/pwm/core.c
drivers/pwm/pwm-cros-ec.c
drivers/pwm/pwm-hibvt.c
drivers/pwm/pwm-iqs620a.c
drivers/pwm/pwm-meson.c
drivers/pwm/pwm-sprd.c
drivers/regulator/fan53555.c
drivers/regulator/fixed.c
drivers/regulator/sm5703-regulator.c
drivers/s390/crypto/vfio_ap_drv.c
drivers/sbus/char/oradax.c
drivers/scsi/device_handler/scsi_dh_alua.c
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
drivers/scsi/hosts.c
drivers/scsi/iscsi_tcp.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/megaraid/megaraid_sas_base.c
drivers/scsi/megaraid/megaraid_sas_fp.c
drivers/scsi/megaraid/megaraid_sas_fusion.c
drivers/scsi/mpi3mr/mpi3mr.h
drivers/scsi/mpi3mr/mpi3mr_app.c
drivers/scsi/mpi3mr/mpi3mr_fw.c
drivers/scsi/mpi3mr/mpi3mr_os.c
drivers/scsi/mpi3mr/mpi3mr_transport.c
drivers/scsi/mpt3sas/mpt3sas_base.c
drivers/scsi/mpt3sas/mpt3sas_transport.c
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/scsi.c
drivers/scsi/scsi_devinfo.c
drivers/scsi/scsi_scan.c
drivers/scsi/sd.c
drivers/scsi/sd_zbc.c
drivers/scsi/ses.c
drivers/scsi/storvsc_drv.c
drivers/soc/qcom/llcc-qcom.c
drivers/soc/qcom/rmtfs_mem.c
drivers/spi/spi-rockchip-sfc.c
drivers/spi/spi.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/r8188eu/Kconfig [deleted file]
drivers/staging/r8188eu/Makefile [deleted file]
drivers/staging/r8188eu/TODO [deleted file]
drivers/staging/r8188eu/core/rtw_ap.c [deleted file]
drivers/staging/r8188eu/core/rtw_br_ext.c [deleted file]
drivers/staging/r8188eu/core/rtw_cmd.c [deleted file]
drivers/staging/r8188eu/core/rtw_efuse.c [deleted file]
drivers/staging/r8188eu/core/rtw_fw.c [deleted file]
drivers/staging/r8188eu/core/rtw_ieee80211.c [deleted file]
drivers/staging/r8188eu/core/rtw_ioctl_set.c [deleted file]
drivers/staging/r8188eu/core/rtw_iol.c [deleted file]
drivers/staging/r8188eu/core/rtw_led.c [deleted file]
drivers/staging/r8188eu/core/rtw_mlme.c [deleted file]
drivers/staging/r8188eu/core/rtw_mlme_ext.c [deleted file]
drivers/staging/r8188eu/core/rtw_p2p.c [deleted file]
drivers/staging/r8188eu/core/rtw_pwrctrl.c [deleted file]
drivers/staging/r8188eu/core/rtw_recv.c [deleted file]
drivers/staging/r8188eu/core/rtw_rf.c [deleted file]
drivers/staging/r8188eu/core/rtw_security.c [deleted file]
drivers/staging/r8188eu/core/rtw_sta_mgt.c [deleted file]
drivers/staging/r8188eu/core/rtw_wlan_util.c [deleted file]
drivers/staging/r8188eu/core/rtw_xmit.c [deleted file]
drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c [deleted file]
drivers/staging/r8188eu/hal/HalHWImg8188E_BB.c [deleted file]
drivers/staging/r8188eu/hal/HalHWImg8188E_MAC.c [deleted file]
drivers/staging/r8188eu/hal/HalHWImg8188E_RF.c [deleted file]
drivers/staging/r8188eu/hal/HalPhyRf_8188e.c [deleted file]
drivers/staging/r8188eu/hal/HalPwrSeqCmd.c [deleted file]
drivers/staging/r8188eu/hal/hal_com.c [deleted file]
drivers/staging/r8188eu/hal/hal_intf.c [deleted file]
drivers/staging/r8188eu/hal/odm.c [deleted file]
drivers/staging/r8188eu/hal/odm_HWConfig.c [deleted file]
drivers/staging/r8188eu/hal/odm_RTL8188E.c [deleted file]
drivers/staging/r8188eu/hal/rtl8188e_cmd.c [deleted file]
drivers/staging/r8188eu/hal/rtl8188e_dm.c [deleted file]
drivers/staging/r8188eu/hal/rtl8188e_hal_init.c [deleted file]
drivers/staging/r8188eu/hal/rtl8188e_phycfg.c [deleted file]
drivers/staging/r8188eu/hal/rtl8188e_rf6052.c [deleted file]
drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c [deleted file]
drivers/staging/r8188eu/hal/rtl8188eu_xmit.c [deleted file]
drivers/staging/r8188eu/hal/usb_halinit.c [deleted file]
drivers/staging/r8188eu/hal/usb_ops_linux.c [deleted file]
drivers/staging/r8188eu/include/Hal8188EPhyCfg.h [deleted file]
drivers/staging/r8188eu/include/Hal8188EPhyReg.h [deleted file]
drivers/staging/r8188eu/include/Hal8188ERateAdaptive.h [deleted file]
drivers/staging/r8188eu/include/HalHWImg8188E_BB.h [deleted file]
drivers/staging/r8188eu/include/HalHWImg8188E_MAC.h [deleted file]
drivers/staging/r8188eu/include/HalHWImg8188E_RF.h [deleted file]
drivers/staging/r8188eu/include/HalPhyRf_8188e.h [deleted file]
drivers/staging/r8188eu/include/HalPwrSeqCmd.h [deleted file]
drivers/staging/r8188eu/include/HalVerDef.h [deleted file]
drivers/staging/r8188eu/include/drv_types.h [deleted file]
drivers/staging/r8188eu/include/hal_com.h [deleted file]
drivers/staging/r8188eu/include/hal_intf.h [deleted file]
drivers/staging/r8188eu/include/ieee80211.h [deleted file]
drivers/staging/r8188eu/include/odm.h [deleted file]
drivers/staging/r8188eu/include/odm_HWConfig.h [deleted file]
drivers/staging/r8188eu/include/odm_RTL8188E.h [deleted file]
drivers/staging/r8188eu/include/odm_RegDefine11N.h [deleted file]
drivers/staging/r8188eu/include/osdep_intf.h [deleted file]
drivers/staging/r8188eu/include/osdep_service.h [deleted file]
drivers/staging/r8188eu/include/rtl8188e_cmd.h [deleted file]
drivers/staging/r8188eu/include/rtl8188e_dm.h [deleted file]
drivers/staging/r8188eu/include/rtl8188e_hal.h [deleted file]
drivers/staging/r8188eu/include/rtl8188e_recv.h [deleted file]
drivers/staging/r8188eu/include/rtl8188e_rf.h [deleted file]
drivers/staging/r8188eu/include/rtl8188e_spec.h [deleted file]
drivers/staging/r8188eu/include/rtl8188e_xmit.h [deleted file]
drivers/staging/r8188eu/include/rtw_ap.h [deleted file]
drivers/staging/r8188eu/include/rtw_br_ext.h [deleted file]
drivers/staging/r8188eu/include/rtw_cmd.h [deleted file]
drivers/staging/r8188eu/include/rtw_eeprom.h [deleted file]
drivers/staging/r8188eu/include/rtw_efuse.h [deleted file]
drivers/staging/r8188eu/include/rtw_event.h [deleted file]
drivers/staging/r8188eu/include/rtw_fw.h [deleted file]
drivers/staging/r8188eu/include/rtw_ht.h [deleted file]
drivers/staging/r8188eu/include/rtw_io.h [deleted file]
drivers/staging/r8188eu/include/rtw_ioctl.h [deleted file]
drivers/staging/r8188eu/include/rtw_ioctl_set.h [deleted file]
drivers/staging/r8188eu/include/rtw_iol.h [deleted file]
drivers/staging/r8188eu/include/rtw_led.h [deleted file]
drivers/staging/r8188eu/include/rtw_mlme.h [deleted file]
drivers/staging/r8188eu/include/rtw_mlme_ext.h [deleted file]
drivers/staging/r8188eu/include/rtw_p2p.h [deleted file]
drivers/staging/r8188eu/include/rtw_pwrctrl.h [deleted file]
drivers/staging/r8188eu/include/rtw_recv.h [deleted file]
drivers/staging/r8188eu/include/rtw_rf.h [deleted file]
drivers/staging/r8188eu/include/rtw_security.h [deleted file]
drivers/staging/r8188eu/include/rtw_xmit.h [deleted file]
drivers/staging/r8188eu/include/sta_info.h [deleted file]
drivers/staging/r8188eu/include/usb_ops.h [deleted file]
drivers/staging/r8188eu/include/usb_osintf.h [deleted file]
drivers/staging/r8188eu/include/wifi.h [deleted file]
drivers/staging/r8188eu/include/wlan_bssdef.h [deleted file]
drivers/staging/r8188eu/os_dep/ioctl_linux.c [deleted file]
drivers/staging/r8188eu/os_dep/os_intfs.c [deleted file]
drivers/staging/r8188eu/os_dep/osdep_service.c [deleted file]
drivers/staging/r8188eu/os_dep/usb_intf.c [deleted file]
drivers/staging/r8188eu/os_dep/usb_ops_linux.c [deleted file]
drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
drivers/staging/rtl8723bs/include/rtw_security.h
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
drivers/target/iscsi/iscsi_target_parameters.c
drivers/tee/amdtee/core.c
drivers/tee/optee/call.c
drivers/tee/tee_shm.c
drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
drivers/thermal/intel/intel_powerclamp.c
drivers/thermal/intel/therm_throt.c
drivers/thermal/thermal_core.c
drivers/thermal/thermal_core.h
drivers/thermal/thermal_sysfs.c
drivers/thunderbolt/debugfs.c
drivers/thunderbolt/nhi.c
drivers/thunderbolt/nhi_regs.h
drivers/thunderbolt/quirks.c
drivers/thunderbolt/retimer.c
drivers/thunderbolt/sb_regs.h
drivers/thunderbolt/switch.c
drivers/thunderbolt/tb.h
drivers/thunderbolt/usb4.c
drivers/tty/hvc/hvc_xen.c
drivers/tty/serdev/core.c
drivers/tty/serial/8250/8250_em.c
drivers/tty/serial/8250/8250_fsl.c
drivers/tty/serial/8250/8250_port.c
drivers/tty/serial/8250/Kconfig
drivers/tty/serial/Kconfig
drivers/tty/serial/fsl_lpuart.c
drivers/tty/serial/qcom_geni_serial.c
drivers/tty/serial/sc16is7xx.c
drivers/tty/serial/sh-sci.c
drivers/tty/vt/vt.c
drivers/ufs/core/ufshcd.c
drivers/ufs/host/ufs-qcom.c
drivers/usb/cdns3/cdns3-pci-wrap.c
drivers/usb/cdns3/cdnsp-ep0.c
drivers/usb/cdns3/cdnsp-pci.c
drivers/usb/chipidea/ci.h
drivers/usb/chipidea/core.c
drivers/usb/chipidea/otg.c
drivers/usb/dwc2/drd.c
drivers/usb/dwc2/gadget.c
drivers/usb/dwc2/platform.c
drivers/usb/dwc3/core.h
drivers/usb/dwc3/dwc3-pci.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/composite.c
drivers/usb/gadget/function/f_fs.c
drivers/usb/gadget/function/u_audio.c
drivers/usb/gadget/legacy/inode.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-tegra.c
drivers/usb/host/xhci.c
drivers/usb/misc/onboard_usb_hub.c
drivers/usb/misc/onboard_usb_hub.h
drivers/usb/serial/cp210x.c
drivers/usb/serial/option.c
drivers/usb/storage/unusual_uas.h
drivers/usb/typec/altmodes/displayport.c
drivers/usb/typec/tcpm/tcpm.c
drivers/usb/typec/ucsi/ucsi.c
drivers/usb/typec/ucsi/ucsi_acpi.c
drivers/vdpa/mlx5/core/mlx5_vdpa.h
drivers/vdpa/mlx5/net/mlx5_vnet.c
drivers/vdpa/vdpa_sim/vdpa_sim.c
drivers/vdpa/vdpa_sim/vdpa_sim_net.c
drivers/vdpa/virtio_pci/vp_vdpa.c
drivers/vfio/pci/mlx5/main.c
drivers/vhost/Kconfig
drivers/vhost/scsi.c
drivers/vhost/vdpa.c
drivers/vhost/vhost.c
drivers/vhost/vhost.h
drivers/video/fbdev/amba-clcd.c
drivers/video/fbdev/au1200fb.c
drivers/video/fbdev/bw2.c
drivers/video/fbdev/cg3.c
drivers/video/fbdev/chipsfb.c
drivers/video/fbdev/clps711x-fb.c
drivers/video/fbdev/core/fb_defio.c
drivers/video/fbdev/core/fbcon.c
drivers/video/fbdev/core/fbmem.c
drivers/video/fbdev/geode/lxfb_core.c
drivers/video/fbdev/intelfb/intelfbdrv.c
drivers/video/fbdev/nvidia/nvidia.c
drivers/video/fbdev/offb.c
drivers/video/fbdev/omap/Makefile
drivers/video/fbdev/omap/lcd_osk.c [deleted file]
drivers/video/fbdev/omap/omapfb_main.c
drivers/video/fbdev/omap2/omapfb/dss/omapdss-boot-init.c
drivers/video/fbdev/pxa3xx-gcu.c
drivers/video/fbdev/sm501fb.c
drivers/video/fbdev/stifb.c
drivers/video/fbdev/tcx.c
drivers/video/fbdev/tgafb.c
drivers/video/fbdev/wm8505fb.c
drivers/video/fbdev/xilinxfb.c
drivers/video/logo/pnmtologo.c
drivers/virt/coco/sev-guest/sev-guest.c
drivers/w1/masters/ds2482.c
drivers/xen/xenfs/xensyms.c
fs/9p/xattr.c
fs/attr.c
fs/btrfs/backref.c
fs/btrfs/bio.c
fs/btrfs/block-group.c
fs/btrfs/delayed-inode.c
fs/btrfs/discard.c
fs/btrfs/disk-io.c
fs/btrfs/extent_map.c
fs/btrfs/file.c
fs/btrfs/free-space-cache.c
fs/btrfs/fs.h
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/qgroup.c
fs/btrfs/space-info.c
fs/btrfs/space-info.h
fs/btrfs/super.c
fs/btrfs/sysfs.c
fs/btrfs/transaction.c
fs/btrfs/volumes.c
fs/btrfs/xattr.c
fs/btrfs/zoned.c
fs/buffer.c
fs/ceph/xattr.c
fs/cifs/cached_dir.c
fs/cifs/cifs_debug.c
fs/cifs/cifs_dfs_ref.c
fs/cifs/cifs_fs_sb.h
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifsglob.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/dfs.c
fs/cifs/dfs.h
fs/cifs/dfs_cache.c
fs/cifs/dfs_cache.h
fs/cifs/file.c
fs/cifs/fs_context.c
fs/cifs/fs_context.h
fs/cifs/link.c
fs/cifs/misc.c
fs/cifs/smb2inode.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/cifs/smb2transport.c
fs/cifs/trace.h
fs/cifs/transport.c
fs/cifs/xattr.c
fs/configfs/dir.c
fs/crypto/keyring.c
fs/dax.c
fs/devpts/inode.c
fs/direct-io.c
fs/ecryptfs/inode.c
fs/erofs/data.c
fs/erofs/decompressor.c
fs/erofs/decompressor_lzma.c
fs/erofs/dir.c
fs/erofs/erofs_fs.h
fs/erofs/fscache.c
fs/erofs/inode.c
fs/erofs/internal.h
fs/erofs/namei.c
fs/erofs/pcpubuf.c
fs/erofs/super.c
fs/erofs/xattr.c
fs/erofs/xattr.h
fs/erofs/zdata.c
fs/erofs/zmap.c
fs/eventfd.c
fs/eventpoll.c
fs/ext2/xattr.c
fs/ext4/ext4.h
fs/ext4/fsmap.c
fs/ext4/inline.c
fs/ext4/inode.c
fs/ext4/ioctl.c
fs/ext4/namei.c
fs/ext4/page-io.c
fs/ext4/super.c
fs/ext4/sysfs.c
fs/ext4/xattr.c
fs/f2fs/xattr.c
fs/file.c
fs/fs-writeback.c
fs/fuse/dev.c
fs/fuse/file.c
fs/gfs2/dentry.c
fs/gfs2/xattr.c
fs/hfsplus/inode.c
fs/inode.c
fs/internal.h
fs/jbd2/journal.c
fs/jffs2/xattr.c
fs/jfs/jfs_metapage.c
fs/jfs/xattr.c
fs/kernfs/dir.c
fs/ksmbd/auth.c
fs/ksmbd/connection.c
fs/ksmbd/connection.h
fs/ksmbd/ksmbd_work.h
fs/ksmbd/server.c
fs/ksmbd/smb2pdu.c
fs/ksmbd/smb2pdu.h
fs/ksmbd/smb_common.c
fs/ksmbd/smb_common.h
fs/ksmbd/transport_rdma.c
fs/ksmbd/transport_tcp.c
fs/ksmbd/unicode.c
fs/libfs.c
fs/lockd/clnt4xdr.c
fs/lockd/xdr4.c
fs/locks.c
fs/namei.c
fs/namespace.c
fs/netfs/iterator.c
fs/nfs/Kconfig
fs/nfs/dir.c
fs/nfs/inode.c
fs/nfs/nfs3_fs.h
fs/nfs/nfs3acl.c
fs/nfs/nfs3super.c
fs/nfs/nfs4proc.c
fs/nfs/read.c
fs/nfs/super.c
fs/nfsd/Kconfig
fs/nfsd/blocklayout.c
fs/nfsd/nfs4callback.c
fs/nfsd/nfs4xdr.c
fs/nfsd/vfs.c
fs/nilfs2/btree.c
fs/nilfs2/direct.c
fs/nilfs2/ioctl.c
fs/nilfs2/segment.c
fs/nilfs2/super.c
fs/nilfs2/the_nilfs.c
fs/notify/fanotify/fanotify_user.c
fs/nsfs.c
fs/ntfs3/xattr.c
fs/ocfs2/aops.c
fs/ocfs2/namei.c
fs/ocfs2/refcounttree.c
fs/ocfs2/xattr.c
fs/open.c
fs/orangefs/xattr.c
fs/overlayfs/copy_up.c
fs/overlayfs/super.c
fs/pnode.c
fs/posix_acl.c
fs/qnx4/README [deleted file]
fs/qnx6/README [deleted file]
fs/read_write.c
fs/reiserfs/file.c
fs/reiserfs/inode.c
fs/reiserfs/namei.c
fs/reiserfs/reiserfs.h
fs/reiserfs/xattr.c
fs/reiserfs/xattr_security.c
fs/splice.c
fs/super.c
fs/sysv/dir.c
fs/sysv/namei.c
fs/sysv/sysv.h
fs/udf/inode.c
fs/ufs/dir.c
fs/userfaultfd.c
fs/verity/enable.c
fs/verity/verify.c
fs/xattr.c
fs/xfs/Makefile
fs/xfs/libxfs/xfs_alloc.c
fs/xfs/xfs_aops.c
fs/xfs/xfs_dahash_test.c [new file with mode: 0644]
fs/xfs/xfs_dahash_test.h [new file with mode: 0644]
fs/xfs/xfs_iomap.c
fs/xfs/xfs_qm.c
fs/xfs/xfs_super.c
fs/xfs/xfs_trace.h
fs/xfs/xfs_xattr.c
fs/zonefs/file.c
include/acpi/acpi_bus.h
include/acpi/actypes.h
include/acpi/video.h
include/asm-generic/atomic.h
include/asm-generic/cmpxchg-local.h
include/asm-generic/cmpxchg.h
include/asm-generic/io.h
include/crypto/public_key.h
include/drm/drm_bridge.h
include/drm/drm_gem.h
include/drm/gpu_scheduler.h
include/kunit/resource.h
include/kunit/test.h
include/kvm/arm_arch_timer.h
include/linux/acpi_mdio.h
include/linux/blk-mq.h
include/linux/blkdev.h
include/linux/clk-provider.h
include/linux/context_tracking.h
include/linux/context_tracking_state.h
include/linux/cpuhotplug.h
include/linux/cpumask.h
include/linux/efi.h
include/linux/fb.h
include/linux/find.h
include/linux/fs.h
include/linux/fs_context.h
include/linux/ftrace.h
include/linux/hid.h
include/linux/highmem.h
include/linux/i2c.h
include/linux/instrumented.h
include/linux/interconnect-provider.h
include/linux/io_uring.h
include/linux/jbd2.h
include/linux/kmsan.h
include/linux/kvm_host.h
include/linux/kvm_irqfd.h
include/linux/lockd/xdr4.h
include/linux/lockdep.h
include/linux/lsm_hook_defs.h
include/linux/lsm_hooks.h
include/linux/mlx5/device.h
include/linux/mlx5/driver.h
include/linux/mm_types.h
include/linux/netdevice.h
include/linux/notifier.h
include/linux/nvme-tcp.h
include/linux/nvme.h
include/linux/of_mdio.h
include/linux/pagemap.h
include/linux/pci-doe.h
include/linux/pci.h
include/linux/percpu_counter.h
include/linux/phy.h
include/linux/phylink.h
include/linux/pid.h
include/linux/posix_acl.h
include/linux/posix_acl_xattr.h
include/linux/proc_ns.h
include/linux/rtnetlink.h
include/linux/sched.h
include/linux/sched/task.h
include/linux/sched/vhost_task.h [new file with mode: 0644]
include/linux/security.h
include/linux/sfp.h
include/linux/skbuff.h
include/linux/srcu.h
include/linux/srcutiny.h
include/linux/srcutree.h
include/linux/stmmac.h
include/linux/sysfb.h
include/linux/thermal.h
include/linux/tick.h
include/linux/tracepoint.h
include/linux/uio.h
include/linux/xattr.h
include/net/bluetooth/hci_core.h
include/net/bonding.h
include/net/netfilter/nf_tables.h
include/net/netfilter/nf_tproxy.h
include/net/raw.h
include/net/xdp.h
include/scsi/scsi_device.h
include/scsi/scsi_devinfo.h
include/trace/events/erofs.h
include/trace/events/f2fs.h
include/trace/events/mmap.h
include/trace/events/rcu.h
include/trace/events/timer.h
include/trace/stages/stage5_get_offsets.h
include/uapi/asm-generic/fcntl.h
include/uapi/linux/btrfs.h
include/uapi/linux/fou.h
include/uapi/linux/landlock.h
include/uapi/linux/netdev.h
include/uapi/linux/rtnetlink.h
include/uapi/linux/virtio_blk.h
include/ufs/ufshcd.h
include/xen/interface/platform.h
init/Kconfig
init/initramfs.c
init/main.c
io_uring/alloc_cache.h
io_uring/filetable.c
io_uring/io-wq.c
io_uring/io_uring.c
io_uring/kbuf.c
io_uring/msg_ring.c
io_uring/net.c
io_uring/poll.c
io_uring/rsrc.c
io_uring/rsrc.h
io_uring/rw.c
io_uring/slist.h
io_uring/sqpoll.c
io_uring/uring_cmd.c
kernel/Makefile
kernel/bpf/bpf_inode_storage.c
kernel/bpf/btf.c
kernel/bpf/core.c
kernel/bpf/verifier.c
kernel/cgroup/cgroup.c
kernel/cgroup/cpuset.c
kernel/cgroup/legacy_freezer.c
kernel/cgroup/rstat.c
kernel/compat.c
kernel/dma/swiotlb.c
kernel/entry/common.c
kernel/events/core.c
kernel/fork.c
kernel/kcsan/Makefile
kernel/kcsan/core.c
kernel/kthread.c
kernel/locking/lockdep.c
kernel/locking/locktorture.c
kernel/locking/test-ww_mutex.c
kernel/nsproxy.c
kernel/pid.c
kernel/rcu/Kconfig
kernel/rcu/rcu.h
kernel/rcu/rcuscale.c
kernel/rcu/rcutorture.c
kernel/rcu/refscale.c
kernel/rcu/srcutiny.c
kernel/rcu/srcutree.c
kernel/rcu/tasks.h
kernel/rcu/tree.c
kernel/rcu/tree_exp.h
kernel/rcu/tree_nocb.h
kernel/sched/core.c
kernel/sched/fair.c
kernel/sys.c
kernel/time/tick-sched.c
kernel/trace/ftrace.c
kernel/trace/kprobe_event_gen_test.c
kernel/trace/ring_buffer.c
kernel/trace/trace.c
kernel/trace/trace_events_hist.c
kernel/trace/trace_events_synth.c
kernel/trace/trace_hwlat.c
kernel/trace/trace_osnoise.c
kernel/trace/trace_probe.c
kernel/vhost_task.c [new file with mode: 0644]
kernel/watch_queue.c
lib/Kconfig.debug
lib/dhry_run.c
lib/find_bit.c
lib/iov_iter.c
lib/kunit/debugfs.c
lib/kunit/kunit-test.c
lib/kunit/test.c
lib/list-test.c
lib/maple_tree.c
lib/percpu_counter.c
lib/test_maple_tree.c
lib/test_vmalloc.c
lib/zstd/common/zstd_deps.h
lib/zstd/decompress/huf_decompress.c
lib/zstd/decompress/zstd_decompress.c
mm/Kconfig
mm/backing-dev.c
mm/damon/paddr.c
mm/huge_memory.c
mm/hugetlb.c
mm/kfence/Makefile
mm/kfence/core.c
mm/khugepaged.c
mm/kmsan/hooks.c
mm/kmsan/shadow.c
mm/ksm.c
mm/madvise.c
mm/memory.c
mm/mempolicy.c
mm/migrate.c
mm/mincore.c
mm/mmap.c
mm/mprotect.c
mm/page-writeback.c
mm/page_alloc.c
mm/shmem.c
mm/slab.c
mm/swap.c
mm/swapfile.c
mm/vmalloc.c
mm/vmscan.c
net/9p/trans_xen.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/hci_sync.c
net/bluetooth/hidp/core.c
net/bluetooth/iso.c
net/bluetooth/l2cap_core.c
net/bluetooth/mgmt.c
net/bluetooth/sco.c
net/bpf/test_run.c
net/bridge/br_netfilter_hooks.c
net/bridge/br_switchdev.c
net/caif/caif_usb.c
net/can/bcm.c
net/can/isotp.c
net/can/j1939/transport.c
net/core/dev.c
net/core/net_namespace.c
net/core/netdev-genl-gen.c
net/core/netdev-genl-gen.h
net/core/netpoll.c
net/core/rtnetlink.c
net/core/skbuff.c
net/core/sock.c
net/core/sysctl_net_core.c
net/core/xdp.c
net/dsa/slave.c
net/dsa/tag.c
net/dsa/tag_brcm.c
net/ethtool/linkmodes.c
net/hsr/hsr_framereg.c
net/ieee802154/nl802154.c
net/ipv4/fib_frontend.c
net/ipv4/fou_nl.c
net/ipv4/fou_nl.h
net/ipv4/icmp.c
net/ipv4/inet_hashtables.c
net/ipv4/ip_gre.c
net/ipv4/ip_tunnel.c
net/ipv4/netfilter/nf_tproxy_ipv4.c
net/ipv4/ping.c
net/ipv4/raw.c
net/ipv4/raw_diag.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp_bpf.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/udp_bpf.c
net/ipv6/ila/ila_xlat.c
net/ipv6/ip6_gre.c
net/ipv6/ip6_output.c
net/ipv6/ip6_tunnel.c
net/ipv6/netfilter/nf_tproxy_ipv6.c
net/ipv6/raw.c
net/ipv6/rpl.c
net/ipv6/udp.c
net/iucv/iucv.c
net/l2tp/l2tp_ip.c
net/l2tp/l2tp_ip6.c
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/main.c
net/mac80211/rx.c
net/mac80211/sta_info.c
net/mac80211/util.c
net/mac80211/wme.c
net/mac802154/scan.c
net/mptcp/fastopen.c
net/mptcp/options.c
net/mptcp/pm_netlink.c
net/mptcp/protocol.c
net/mptcp/protocol.h
net/mptcp/subflow.c
net/ncsi/ncsi-manage.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_tables_api.c
net/netfilter/nft_last.c
net/netfilter/nft_lookup.c
net/netfilter/nft_masq.c
net/netfilter/nft_nat.c
net/netfilter/nft_quota.c
net/netfilter/nft_redir.c
net/netlink/af_netlink.c
net/nfc/netlink.c
net/openvswitch/actions.c
net/qrtr/af_qrtr.c
net/qrtr/ns.c
net/sched/act_api.c
net/sched/act_connmark.c
net/sched/cls_api.c
net/sched/cls_flower.c
net/sched/sch_qfq.c
net/sctp/socket.c
net/sctp/stream_interleave.c
net/smc/af_smc.c
net/smc/smc_cdc.c
net/smc/smc_core.c
net/socket.c
net/sunrpc/auth_gss/gss_krb5_crypto.c
net/sunrpc/auth_gss/gss_krb5_test.c
net/sunrpc/svc.c
net/sunrpc/svcauth_unix.c
net/sunrpc/xprtsock.c
net/tls/tls_device.c
net/tls/tls_main.c
net/tls/tls_sw.c
net/unix/af_unix.c
net/unix/unix_bpf.c
net/vmw_vsock/virtio_transport_common.c
net/vmw_vsock/vmci_transport.c
net/vmw_vsock/vsock_loopback.c
net/wireless/nl80211.c
net/wireless/sme.c
net/xdp/xdp_umem.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c
rust/Makefile
rust/kernel/print.rs
rust/kernel/str.rs
scripts/.gitignore
scripts/Makefile
scripts/Makefile.package
scripts/asn1_compiler.c
scripts/cc-version.sh
scripts/check-git [new file with mode: 0755]
scripts/checkpatch.pl
scripts/checksyscalls.sh
scripts/generate_rust_analyzer.py
scripts/is_rust_module.sh
scripts/kallsyms.c
scripts/kconfig/confdata.c
scripts/kconfig/merge_config.sh
scripts/list-gitignored.c [deleted file]
scripts/mod/modpost.c
scripts/package/builddeb
scripts/package/deb-build-option
scripts/package/gen-diff-patch [new file with mode: 0755]
scripts/package/mkdebian
scripts/package/mkspec
scripts/setlocalversion
security/Kconfig
security/apparmor/lsm.c
security/bpf/hooks.c
security/commoncap.c
security/device_cgroup.c
security/integrity/Kconfig
security/integrity/digsig.c
security/integrity/iint.c
security/keys/request_key.c
security/landlock/cred.c
security/landlock/fs.c
security/landlock/ptrace.c
security/landlock/setup.c
security/loadpin/loadpin.c
security/lockdown/lockdown.c
security/security.c
security/selinux/Kconfig
security/selinux/Makefile
security/selinux/avc.c
security/selinux/hooks.c
security/selinux/ibpkey.c
security/selinux/ima.c
security/selinux/include/avc.h
security/selinux/include/avc_ss.h
security/selinux/include/conditional.h
security/selinux/include/ima.h
security/selinux/include/security.h
security/selinux/netif.c
security/selinux/netlabel.c
security/selinux/netnode.c
security/selinux/netport.c
security/selinux/selinuxfs.c
security/selinux/ss/services.c
security/selinux/ss/services.h
security/selinux/status.c
security/selinux/xfrm.c
security/smack/smack_lsm.c
security/tomoyo/audit.c
security/tomoyo/common.c
security/tomoyo/common.h
security/tomoyo/tomoyo.c
security/yama/yama_lsm.c
sound/core/pcm_lib.c
sound/core/pcm_native.c
sound/firewire/tascam/tascam-stream.c
sound/hda/intel-dsp-config.c
sound/i2c/cs8427.c
sound/pci/asihpi/hpi6205.c
sound/pci/emu10k1/emupcm.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/ymfpci/ymfpci.c
sound/pci/ymfpci/ymfpci_main.c
sound/soc/amd/yc/acp6x-mach.c
sound/soc/codecs/da7213.c
sound/soc/codecs/da7219-aad.c
sound/soc/codecs/hdac_hdmi.c
sound/soc/codecs/hdmi-codec.c
sound/soc/codecs/lpass-rx-macro.c
sound/soc/codecs/lpass-tx-macro.c
sound/soc/codecs/lpass-wsa-macro.c
sound/soc/codecs/max98373.c
sound/soc/fsl/Kconfig
sound/soc/fsl/fsl_asrc_dma.c
sound/soc/fsl/fsl_sai.c
sound/soc/intel/avs/boards/da7219.c
sound/soc/intel/avs/boards/max98357a.c
sound/soc/intel/avs/boards/nau8825.c
sound/soc/intel/avs/boards/rt5682.c
sound/soc/intel/avs/boards/ssm4567.c
sound/soc/intel/boards/bytcr_rt5640.c
sound/soc/intel/boards/sof_sdw.c
sound/soc/intel/common/soc-acpi-intel-adl-match.c
sound/soc/qcom/qdsp6/q6prm.c
sound/soc/soc-pcm.c
sound/soc/sof/intel/hda-ctrl.c
sound/soc/sof/intel/hda-dsp.c
sound/soc/sof/intel/pci-apl.c
sound/soc/sof/intel/pci-cnl.c
sound/soc/sof/intel/pci-icl.c
sound/soc/sof/intel/pci-mtl.c
sound/soc/sof/intel/pci-skl.c
sound/soc/sof/intel/pci-tgl.c
sound/soc/sof/intel/pci-tng.c
sound/soc/sof/ipc3-topology.c
sound/soc/sof/ipc3.c
sound/soc/sof/ipc4-control.c
sound/soc/sof/ipc4-topology.c
sound/soc/sof/ipc4-topology.h
sound/soc/sof/ipc4.c
sound/soc/sof/pm.c
sound/soc/sof/sof-audio.c
sound/soc/sof/topology.c
sound/usb/endpoint.c
sound/usb/endpoint.h
sound/usb/format.c
sound/usb/pcm.c
tools/Makefile
tools/arch/arm64/include/uapi/asm/kvm.h
tools/arch/loongarch/include/uapi/asm/bitsperlong.h
tools/arch/x86/include/asm/cpufeatures.h
tools/arch/x86/include/asm/disabled-features.h
tools/arch/x86/include/asm/msr-index.h
tools/arch/x86/include/asm/required-features.h
tools/arch/x86/include/uapi/asm/kvm.h
tools/arch/x86/include/uapi/asm/svm.h
tools/arch/x86/lib/memcpy_64.S
tools/arch/x86/lib/memset_64.S
tools/bootconfig/test-bootconfig.sh
tools/include/linux/bits.h
tools/include/linux/err.h
tools/include/nolibc/.gitignore [new file with mode: 0644]
tools/include/nolibc/Makefile
tools/include/nolibc/arch-i386.h
tools/include/nolibc/arch-loongarch.h [new file with mode: 0644]
tools/include/nolibc/arch-x86_64.h
tools/include/nolibc/arch.h
tools/include/nolibc/nolibc.h
tools/include/nolibc/stackprotector.h [new file with mode: 0644]
tools/include/nolibc/std.h
tools/include/nolibc/stdint.h [new file with mode: 0644]
tools/include/nolibc/stdio.h
tools/include/nolibc/sys.h
tools/include/nolibc/types.h
tools/include/nolibc/unistd.h
tools/include/uapi/asm-generic/fcntl.h
tools/include/uapi/linux/fcntl.h
tools/include/uapi/linux/kvm.h
tools/include/uapi/linux/netdev.h
tools/include/uapi/linux/perf_event.h
tools/include/uapi/linux/prctl.h
tools/include/uapi/linux/vhost.h
tools/include/vdso/bits.h
tools/lib/bpf/libbpf_internal.h
tools/memory-model/Documentation/explanation.txt
tools/memory-model/Documentation/litmus-tests.txt
tools/memory-model/Documentation/locking.txt [new file with mode: 0644]
tools/memory-model/linux-kernel.bell
tools/memory-model/linux-kernel.cat
tools/memory-model/linux-kernel.def
tools/memory-model/litmus-tests/.gitignore
tools/memory-model/lock.cat
tools/memory-model/scripts/README
tools/memory-model/scripts/checkalllitmus.sh
tools/memory-model/scripts/checkghlitmus.sh
tools/memory-model/scripts/checklitmus.sh
tools/memory-model/scripts/checklitmushist.sh
tools/memory-model/scripts/checktheselitmus.sh [new file with mode: 0755]
tools/memory-model/scripts/cmplitmushist.sh
tools/memory-model/scripts/hwfnseg.sh [new file with mode: 0755]
tools/memory-model/scripts/initlitmushist.sh
tools/memory-model/scripts/judgelitmus.sh
tools/memory-model/scripts/newlitmushist.sh
tools/memory-model/scripts/parseargs.sh
tools/memory-model/scripts/runlitmus.sh [new file with mode: 0755]
tools/memory-model/scripts/runlitmushist.sh
tools/memory-model/scripts/simpletest.sh [new file with mode: 0755]
tools/mm/page_owner_sort.c
tools/net/ynl/cli.py
tools/net/ynl/lib/__init__.py
tools/net/ynl/lib/nlspec.py
tools/net/ynl/lib/ynl.py
tools/net/ynl/ynl-gen-c.py
tools/net/ynl/ynl-regen.sh
tools/objtool/Documentation/objtool.txt
tools/objtool/check.c
tools/perf/builtin-inject.c
tools/perf/builtin-stat.c
tools/perf/tests/shell/lib/perf_json_output_lint.py
tools/perf/tests/shell/stat+csv_output.sh
tools/perf/util/bpf_skel/off_cpu.bpf.c
tools/perf/util/stat.c
tools/perf/util/stat.h
tools/perf/util/target.h
tools/power/acpi/tools/pfrut/pfrut.c
tools/power/pm-graph/sleepgraph.py
tools/power/x86/turbostat/turbostat.8
tools/power/x86/turbostat/turbostat.c
tools/rcu/extract-stall.sh [changed mode: 0644->0755]
tools/testing/kunit/kunit.py
tools/testing/kunit/kunit_config.py
tools/testing/kunit/kunit_kernel.py
tools/testing/kunit/kunit_parser.py
tools/testing/kunit/kunit_printer.py
tools/testing/kunit/kunit_tool_test.py
tools/testing/kunit/qemu_config.py
tools/testing/kunit/qemu_configs/m68k.py [new file with mode: 0644]
tools/testing/kunit/qemu_configs/sh.py [new file with mode: 0644]
tools/testing/kunit/run_checks.py
tools/testing/radix-tree/maple.c
tools/testing/selftests/Makefile
tools/testing/selftests/amd-pstate/Makefile
tools/testing/selftests/amd-pstate/gitsource.sh
tools/testing/selftests/amd-pstate/run.sh
tools/testing/selftests/arm64/fp/Makefile
tools/testing/selftests/arm64/fp/za-fork.c
tools/testing/selftests/bpf/prog_tests/btf.c
tools/testing/selftests/bpf/prog_tests/uninit_stack.c [new file with mode: 0644]
tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c
tools/testing/selftests/bpf/prog_tests/xdp_metadata.c
tools/testing/selftests/bpf/progs/find_vma_fail1.c
tools/testing/selftests/bpf/progs/test_deny_namespace.c
tools/testing/selftests/bpf/progs/test_global_func10.c
tools/testing/selftests/bpf/progs/uninit_stack.c [new file with mode: 0644]
tools/testing/selftests/bpf/progs/xdp_hw_metadata.c
tools/testing/selftests/bpf/progs/xdp_metadata.c
tools/testing/selftests/bpf/progs/xdp_metadata2.c
tools/testing/selftests/bpf/verifier/calls.c
tools/testing/selftests/bpf/verifier/helper_access_var_len.c
tools/testing/selftests/bpf/verifier/int_ptr.c
tools/testing/selftests/bpf/verifier/search_pruning.c
tools/testing/selftests/bpf/verifier/sock.c
tools/testing/selftests/bpf/verifier/spill_fill.c
tools/testing/selftests/bpf/verifier/var_off.c
tools/testing/selftests/bpf/xdp_hw_metadata.c
tools/testing/selftests/bpf/xdp_metadata.h
tools/testing/selftests/cgroup/test_memcontrol.c
tools/testing/selftests/clone3/clone3.c
tools/testing/selftests/drivers/net/bonding/Makefile
tools/testing/selftests/drivers/net/bonding/bond-eth-type-change.sh [new file with mode: 0755]
tools/testing/selftests/drivers/net/bonding/bond_options.sh [new file with mode: 0755]
tools/testing/selftests/drivers/net/bonding/bond_topo_3d1c.sh [new file with mode: 0644]
tools/testing/selftests/drivers/net/bonding/option_prio.sh [deleted file]
tools/testing/selftests/hid/config
tools/testing/selftests/kselftest.h
tools/testing/selftests/kvm/aarch64/psci_test.c
tools/testing/selftests/kvm/include/test_util.h
tools/testing/selftests/kvm/include/x86_64/processor.h
tools/testing/selftests/kvm/lib/kvm_util.c
tools/testing/selftests/kvm/lib/s390x/diag318_test_handler.c
tools/testing/selftests/kvm/lib/test_util.c
tools/testing/selftests/kvm/lib/x86_64/processor.c
tools/testing/selftests/kvm/s390x/sync_regs_test.c
tools/testing/selftests/kvm/set_memory_region_test.c
tools/testing/selftests/kvm/x86_64/amx_test.c
tools/testing/selftests/kvm/x86_64/cr4_cpuid_sync_test.c
tools/testing/selftests/kvm/x86_64/debug_regs.c
tools/testing/selftests/kvm/x86_64/flds_emulation.h
tools/testing/selftests/kvm/x86_64/hyperv_clock.c
tools/testing/selftests/kvm/x86_64/hyperv_evmcs.c
tools/testing/selftests/kvm/x86_64/hyperv_features.c
tools/testing/selftests/kvm/x86_64/hyperv_ipi.c
tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
tools/testing/selftests/kvm/x86_64/hyperv_tlb_flush.c
tools/testing/selftests/kvm/x86_64/kvm_clock_test.c
tools/testing/selftests/kvm/x86_64/kvm_pv_test.c
tools/testing/selftests/kvm/x86_64/monitor_mwait_test.c
tools/testing/selftests/kvm/x86_64/nested_exceptions_test.c
tools/testing/selftests/kvm/x86_64/platform_info_test.c
tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
tools/testing/selftests/kvm/x86_64/smm_test.c
tools/testing/selftests/kvm/x86_64/state_test.c
tools/testing/selftests/kvm/x86_64/svm_int_ctl_test.c
tools/testing/selftests/kvm/x86_64/svm_nested_shutdown_test.c
tools/testing/selftests/kvm/x86_64/svm_nested_soft_inject_test.c
tools/testing/selftests/kvm/x86_64/svm_vmcall_test.c
tools/testing/selftests/kvm/x86_64/sync_regs_test.c
tools/testing/selftests/kvm/x86_64/triple_fault_event_test.c
tools/testing/selftests/kvm/x86_64/tsc_scaling_sync.c
tools/testing/selftests/kvm/x86_64/ucna_injection_test.c
tools/testing/selftests/kvm/x86_64/userspace_io_test.c
tools/testing/selftests/kvm/x86_64/userspace_msr_exit_test.c
tools/testing/selftests/kvm/x86_64/vmx_apic_access_test.c
tools/testing/selftests/kvm/x86_64/vmx_close_while_nested_test.c
tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c
tools/testing/selftests/kvm/x86_64/vmx_exception_with_invalid_guest_state.c
tools/testing/selftests/kvm/x86_64/vmx_invalid_nested_guest_state.c
tools/testing/selftests/kvm/x86_64/vmx_nested_tsc_scaling_test.c
tools/testing/selftests/kvm/x86_64/vmx_preemption_timer_test.c
tools/testing/selftests/kvm/x86_64/vmx_tsc_adjust_test.c
tools/testing/selftests/kvm/x86_64/xapic_ipi_test.c
tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c
tools/testing/selftests/kvm/x86_64/xen_vmcall_test.c
tools/testing/selftests/lib.mk
tools/testing/selftests/mm/mdwe_test.c
tools/testing/selftests/mount_setattr/mount_setattr_test.c
tools/testing/selftests/net/.gitignore
tools/testing/selftests/net/Makefile
tools/testing/selftests/net/bind_wildcard.c [new file with mode: 0644]
tools/testing/selftests/net/config
tools/testing/selftests/net/devlink_port_split.py
tools/testing/selftests/net/mptcp/userspace_pm.sh
tools/testing/selftests/net/openvswitch/ovs-dpctl.py
tools/testing/selftests/net/rps_default_mask.sh
tools/testing/selftests/netfilter/nft_nat.sh
tools/testing/selftests/nolibc/Makefile
tools/testing/selftests/nolibc/nolibc-test.c
tools/testing/selftests/prctl/.gitignore
tools/testing/selftests/prctl/Makefile
tools/testing/selftests/prctl/config [new file with mode: 0644]
tools/testing/selftests/prctl/set-anon-vma-name-test.c [new file with mode: 0644]
tools/testing/selftests/ptrace/peeksiginfo.c
tools/testing/selftests/rcutorture/bin/kvm-again.sh
tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh [new file with mode: 0755]
tools/testing/selftests/rcutorture/bin/torture.sh
tools/testing/selftests/rcutorture/configs/lock/CFLIST
tools/testing/selftests/rcutorture/configs/lock/LOCK08 [new file with mode: 0644]
tools/testing/selftests/rcutorture/configs/lock/LOCK08.boot [new file with mode: 0644]
tools/testing/selftests/rcutorture/configs/lock/LOCK09 [new file with mode: 0644]
tools/testing/selftests/rcutorture/configs/lock/LOCK09.boot [new file with mode: 0644]
tools/testing/selftests/rcutorture/configs/rcu/TREE01
tools/testing/selftests/rcutorture/configs/rcu/TREE04
tools/testing/selftests/rcutorture/doc/TREE_RCU-kconfig.txt
tools/testing/selftests/resctrl/cache.c
tools/testing/selftests/resctrl/cat_test.c
tools/testing/selftests/resctrl/cmt_test.c
tools/testing/selftests/resctrl/fill_buf.c
tools/testing/selftests/resctrl/mba_test.c
tools/testing/selftests/resctrl/mbm_test.c
tools/testing/selftests/resctrl/resctrl.h
tools/testing/selftests/resctrl/resctrl_tests.c
tools/testing/selftests/resctrl/resctrl_val.c
tools/testing/selftests/resctrl/resctrlfs.c
tools/testing/selftests/sched/cs_prctl_test.c
tools/testing/selftests/sigaltstack/current_stack_pointer.h [new file with mode: 0644]
tools/testing/selftests/sigaltstack/sas.c
tools/testing/selftests/x86/amx.c
tools/testing/vsock/vsock_test.c
tools/virtio/.gitignore
tools/virtio/virtio-trace/README
usr/gen_init_cpio.c
virt/kvm/eventfd.c
virt/kvm/kvm_main.c

index 8fe465f251c0368f7d66ba687aa4c5cbbfaf1b76..7f86e0837909446b5a619b0c4aa6175af13451e9 100644 (file)
@@ -78,6 +78,7 @@ modules.order
 # RPM spec file (make rpm-pkg)
 #
 /*.spec
+/rpmbuild/
 
 #
 # Debian directory (make deb-pkg)
@@ -102,6 +103,7 @@ modules.order
 !.get_maintainer.ignore
 !.gitattributes
 !.gitignore
+!.kunitconfig
 !.mailmap
 !.rustfmt.toml
 
index 5367faaf7831242fa334b1e55d8189fbd9ade7ab..6686879ce0d5db65f5341df07e6a77538df15566 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -28,6 +28,7 @@ Alexander Lobakin <alobakin@pm.me> <bloodyreaper@yandex.ru>
 Alexander Mikhalitsyn <alexander@mihalicyn.com> <alexander.mikhalitsyn@virtuozzo.com>
 Alexander Mikhalitsyn <alexander@mihalicyn.com> <aleksandr.mikhalitsyn@canonical.com>
 Alexandre Belloni <alexandre.belloni@bootlin.com> <alexandre.belloni@free-electrons.com>
+Alexandre Ghiti <alex@ghiti.fr> <alexandre.ghiti@canonical.com>
 Alexei Starovoitov <ast@kernel.org> <alexei.starovoitov@gmail.com>
 Alexei Starovoitov <ast@kernel.org> <ast@fb.com>
 Alexei Starovoitov <ast@kernel.org> <ast@plumgrid.com>
@@ -121,7 +122,7 @@ Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@gmail.com>
 Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@imgtec.com>
 Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@mips.com>
 <dev.kurt@vandijck-laurijssen.be> <kurt.van.dijck@eia.be>
-Dikshita Agarwal <dikshita@qti.qualcomm.com> <dikshita@codeaurora.org>
+Dikshita Agarwal <quic_dikshita@quicinc.com> <dikshita@codeaurora.org>
 Dmitry Baryshkov <dbaryshkov@gmail.com>
 Dmitry Baryshkov <dbaryshkov@gmail.com> <[dbaryshkov@gmail.com]>
 Dmitry Baryshkov <dbaryshkov@gmail.com> <dmitry_baryshkov@mentor.com>
@@ -132,10 +133,15 @@ Dmitry Safonov <0x7f454c46@gmail.com> <dsafonov@virtuozzo.com>
 Domen Puncer <domen@coderock.org>
 Douglas Gilbert <dougg@torque.net>
 Ed L. Cashin <ecashin@coraid.com>
+Enric Balletbo i Serra <eballetbo@kernel.org> <enric.balletbo@collabora.com>
+Enric Balletbo i Serra <eballetbo@kernel.org> <eballetbo@iseebcn.com>
 Erik Kaneda <erik.kaneda@intel.com> <erik.schmauss@intel.com>
 Eugen Hristev <eugen.hristev@collabora.com> <eugen.hristev@microchip.com>
 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
 Ezequiel Garcia <ezequiel@vanguardiasur.com.ar> <ezequiel@collabora.com>
+Faith Ekstrand <faith.ekstrand@collabora.com> <jason@jlekstrand.net>
+Faith Ekstrand <faith.ekstrand@collabora.com> <jason.ekstrand@intel.com>
+Faith Ekstrand <faith.ekstrand@collabora.com> <jason.ekstrand@collabora.com>
 Felipe W Damasio <felipewd@terra.com.br>
 Felix Kuhling <fxkuehl@gmx.de>
 Felix Moeller <felix@derklecks.de>
@@ -191,6 +197,7 @@ Jan Glauber <jan.glauber@gmail.com> <jang@linux.vnet.ibm.com>
 Jan Glauber <jan.glauber@gmail.com> <jglauber@cavium.com>
 Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@linux.intel.com>
 Jarkko Sakkinen <jarkko@kernel.org> <jarkko@profian.com>
+Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@tuni.fi>
 Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com>
 Jason Gunthorpe <jgg@ziepe.ca> <jgg@nvidia.com>
 Jason Gunthorpe <jgg@ziepe.ca> <jgunthorpe@obsidianresearch.com>
@@ -210,6 +217,9 @@ Jens Axboe <axboe@suse.de>
 Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
 Jernej Skrabec <jernej.skrabec@gmail.com> <jernej.skrabec@siol.net>
 Jessica Zhang <quic_jesszhan@quicinc.com> <jesszhan@codeaurora.org>
+Jiri Pirko <jiri@resnulli.us> <jiri@nvidia.com>
+Jiri Pirko <jiri@resnulli.us> <jiri@mellanox.com>
+Jiri Pirko <jiri@resnulli.us> <jpirko@redhat.com>
 Jiri Slaby <jirislaby@kernel.org> <jirislaby@gmail.com>
 Jiri Slaby <jirislaby@kernel.org> <jslaby@novell.com>
 Jiri Slaby <jirislaby@kernel.org> <jslaby@suse.com>
@@ -222,6 +232,8 @@ Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com>
 John Crispin <john@phrozen.org> <blogic@openwrt.org>
 John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
 John Stultz <johnstul@us.ibm.com>
+<jon.toppins+linux@gmail.com> <jtoppins@cumulusnetworks.com>
+<jon.toppins+linux@gmail.com> <jtoppins@redhat.com>
 Jordan Crouse <jordan@cosmicpenguin.net> <jcrouse@codeaurora.org>
 <josh@joshtriplett.org> <josh@freedesktop.org>
 <josh@joshtriplett.org> <josh@kernel.org>
@@ -255,7 +267,9 @@ Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski@samsung.com>
 Krzysztof Kozlowski <krzk@kernel.org> <krzysztof.kozlowski@canonical.com>
 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
 Kuogee Hsieh <quic_khsieh@quicinc.com> <khsieh@codeaurora.org>
+Leonard Crestez <leonard.crestez@nxp.com> Leonard Crestez <cdleonard@gmail.com>
 Leonardo Bras <leobras.c@gmail.com> <leonardo@linux.ibm.com>
+Leonard Göhrs <l.goehrs@pengutronix.de>
 Leonid I Ananiev <leonid.i.ananiev@intel.com>
 Leon Romanovsky <leon@kernel.org> <leon@leon.nu>
 Leon Romanovsky <leon@kernel.org> <leonro@mellanox.com>
@@ -285,6 +299,8 @@ Martin Kepplinger <martink@posteo.de> <martin.kepplinger@puri.sm>
 Martin Kepplinger <martink@posteo.de> <martin.kepplinger@theobroma-systems.com>
 Martyna Szapar-Mudlaw <martyna.szapar-mudlaw@linux.intel.com> <martyna.szapar-mudlaw@intel.com>
 Mathieu Othacehe <m.othacehe@gmail.com>
+Mat Martineau <martineau@kernel.org> <mathew.j.martineau@linux.intel.com>
+Mat Martineau <martineau@kernel.org> <mathewm@codeaurora.org>
 Matthew Wilcox <willy@infradead.org> <matthew.r.wilcox@intel.com>
 Matthew Wilcox <willy@infradead.org> <matthew@wil.cx>
 Matthew Wilcox <willy@infradead.org> <mawilcox@linuxonhyperv.com>
@@ -306,6 +322,8 @@ Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@osg.samsung.com>
 Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@redhat.com>
 Mauro Carvalho Chehab <mchehab@kernel.org> <m.chehab@samsung.com>
 Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@s-opensource.com>
+Maxim Mikityanskiy <maxtram95@gmail.com> <maximmi@mellanox.com>
+Maxim Mikityanskiy <maxtram95@gmail.com> <maximmi@nvidia.com>
 Maxime Ripard <mripard@kernel.org> <maxime.ripard@bootlin.com>
 Maxime Ripard <mripard@kernel.org> <maxime.ripard@free-electrons.com>
 Mayuresh Janorkar <mayur@ti.com>
@@ -369,6 +387,7 @@ Quentin Monnet <quentin@isovalent.com> <quentin.monnet@netronome.com>
 Quentin Perret <qperret@qperret.net> <quentin.perret@arm.com>
 Rafael J. Wysocki <rjw@rjwysocki.net> <rjw@sisk.pl>
 Rajeev Nandan <quic_rajeevny@quicinc.com> <rajeevny@codeaurora.org>
+Rajendra Nayak <quic_rjendra@quicinc.com> <rnayak@codeaurora.org>
 Rajesh Shah <rajesh.shah@intel.com>
 Ralf Baechle <ralf@linux-mips.org>
 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
@@ -377,6 +396,9 @@ Rémi Denis-Courmont <rdenis@simphalempin.com>
 Ricardo Ribalda <ribalda@kernel.org> <ricardo@ribalda.com>
 Ricardo Ribalda <ribalda@kernel.org> Ricardo Ribalda Delgado <ribalda@kernel.org>
 Ricardo Ribalda <ribalda@kernel.org> <ricardo.ribalda@gmail.com>
+Richard Leitner <richard.leitner@linux.dev> <dev@g0hl1n.net>
+Richard Leitner <richard.leitner@linux.dev> <me@g0hl1n.net>
+Richard Leitner <richard.leitner@linux.dev> <richard.leitner@skidata.com>
 Robert Foss <rfoss@kernel.org> <robert.foss@linaro.org>
 Roman Gushchin <roman.gushchin@linux.dev> <guro@fb.com>
 Roman Gushchin <roman.gushchin@linux.dev> <guroan@gmail.com>
@@ -387,6 +409,7 @@ Ross Zwisler <zwisler@kernel.org> <ross.zwisler@linux.intel.com>
 Rudolf Marek <R.Marek@sh.cvut.cz>
 Rui Saraiva <rmps@joel.ist.utl.pt>
 Sachin P Sant <ssant@in.ibm.com>
+Sai Prakash Ranjan <quic_saipraka@quicinc.com> <saiprakash.ranjan@codeaurora.org>
 Sakari Ailus <sakari.ailus@linux.intel.com> <sakari.ailus@iki.fi>
 Sam Ravnborg <sam@mars.ravnborg.org>
 Sankeerth Billakanti <quic_sbillaka@quicinc.com> <sbillaka@codeaurora.org>
@@ -411,7 +434,10 @@ Shuah Khan <shuah@kernel.org> <shuah.kh@samsung.com>
 Simon Arlott <simon@octiron.net> <simon@fire.lp0.eu>
 Simon Kelley <simon@thekelleys.org.uk>
 Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr>
-Stephen Hemminger <shemminger@osdl.org>
+Stephen Hemminger <stephen@networkplumber.org> <shemminger@linux-foundation.org>
+Stephen Hemminger <stephen@networkplumber.org> <shemminger@osdl.org>
+Stephen Hemminger <stephen@networkplumber.org> <sthemmin@microsoft.com>
+Stephen Hemminger <stephen@networkplumber.org> <sthemmin@vyatta.com>
 Steve Wise <larrystevenwise@gmail.com> <swise@chelsio.com>
 Steve Wise <larrystevenwise@gmail.com> <swise@opengridcomputing.com>
 Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
@@ -424,6 +450,10 @@ Thomas Graf <tgraf@suug.ch>
 Thomas Körper <socketcan@esd.eu> <thomas.koerper@esd.eu>
 Thomas Pedersen <twp@codeaurora.org>
 Tiezhu Yang <yangtiezhu@loongson.cn> <kernelpatch@126.com>
+Tobias Klauser <tklauser@distanz.ch> <tobias.klauser@gmail.com>
+Tobias Klauser <tklauser@distanz.ch> <klto@zhaw.ch>
+Tobias Klauser <tklauser@distanz.ch> <tklauser@nuerscht.ch>
+Tobias Klauser <tklauser@distanz.ch> <tklauser@xenon.tklauser.home>
 Todor Tomov <todor.too@gmail.com> <todor.tomov@linaro.org>
 Tony Luck <tony.luck@intel.com>
 TripleX Chung <xxx.phy@gmail.com> <triplex@zh-kernel.org>
diff --git a/CREDITS b/CREDITS
index 847059166a1528e86fb52e7b28744b1fdf50ef7b..b6c93e0a62c31b9bf396944b164e6b899eb228be 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -229,6 +229,10 @@ S: University of Notre Dame
 S: Notre Dame, Indiana
 S: USA
 
+N: Kai Bankett
+E: chaosman@ontika.net
+D: QNX6 filesystem
+
 N: Greg Banks
 E: gnb@alphalink.com.au
 D: IDT77105 ATM network driver
@@ -886,6 +890,10 @@ W: http://jdelvare.nerim.net/
 D: Several hardware monitoring drivers
 S: France
 
+N: Frank "Jedi/Sector One" Denis
+E: j@pureftpd.org
+D: QNX4 filesystem
+
 N: Peter Denison
 E: peterd@pnd-pc.demon.co.uk
 W: http://www.pnd-pc.demon.co.uk/promise/
@@ -1259,6 +1267,10 @@ S: USA
 N: Adam Fritzler
 E: mid@zigamorph.net
 
+N: Richard "Scuba" A. Frowijn
+E: scuba@wxs.nl
+D: QNX4 filesystem
+
 N: Fernando Fuganti
 E: fuganti@conectiva.com.br
 E: fuganti@netbank.com.br
@@ -2218,6 +2230,10 @@ D: Digiboard PC/Xe and PC/Xi, Digiboard EPCA
 D: NUMA support, Slab allocators, Page migration
 D: Scalability, Time subsystem
 
+N: Anders Larsen
+E: al@alarsen.net
+D: QNX4 filesystem
+
 N: Paul Laufer
 E: paul@laufernet.com
 D: Soundblaster driver fixes, ISAPnP quirk
diff --git a/Documentation/ABI/obsolete/sysfs-selinux-checkreqprot b/Documentation/ABI/obsolete/sysfs-selinux-checkreqprot
deleted file mode 100644 (file)
index ed6b52c..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-What:          /sys/fs/selinux/checkreqprot
-Date:          April 2005 (predates git)
-KernelVersion: 2.6.12-rc2 (predates git)
-Contact:       selinux@vger.kernel.org
-Description:
-
-       The selinuxfs "checkreqprot" node allows SELinux to be configured
-       to check the protection requested by userspace for mmap/mprotect
-       calls instead of the actual protection applied by the kernel.
-       This was a compatibility mechanism for legacy userspace and
-       for the READ_IMPLIES_EXEC personality flag.  However, if set to
-       1, it weakens security by allowing mappings to be made executable
-       without authorization by policy.  The default value of checkreqprot
-       at boot was changed starting in Linux v4.4 to 0 (i.e. check the
-       actual protection), and Android and Linux distributions have been
-       explicitly writing a "0" to /sys/fs/selinux/checkreqprot during
-       initialization for some time.  Support for setting checkreqprot to 1
-       will be removed no sooner than June 2021, at which point the kernel
-       will always cease using checkreqprot internally and will always
-       check the actual protections being applied upon mmap/mprotect calls.
-       The checkreqprot selinuxfs node will remain for backward compatibility
-       but will discard writes of the "0" value and will reject writes of the
-       "1" value when this mechanism is removed.
diff --git a/Documentation/ABI/obsolete/sysfs-selinux-disable b/Documentation/ABI/obsolete/sysfs-selinux-disable
deleted file mode 100644 (file)
index c340278..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-What:          /sys/fs/selinux/disable
-Date:          April 2005 (predates git)
-KernelVersion: 2.6.12-rc2 (predates git)
-Contact:       selinux@vger.kernel.org
-Description:
-
-       The selinuxfs "disable" node allows SELinux to be disabled at runtime
-       prior to a policy being loaded into the kernel.  If disabled via this
-       mechanism, SELinux will remain disabled until the system is rebooted.
-
-       The preferred method of disabling SELinux is via the "selinux=0" boot
-       parameter, but the selinuxfs "disable" node was created to make it
-       easier for systems with primitive bootloaders that did not allow for
-       easy modification of the kernel command line.  Unfortunately, allowing
-       for SELinux to be disabled at runtime makes it difficult to secure the
-       kernel's LSM hooks using the "__ro_after_init" feature.
-
-       Thankfully, the need for the SELinux runtime disable appears to be
-       gone, the default Kconfig configuration disables this selinuxfs node,
-       and only one of the major distributions, Fedora, supports disabling
-       SELinux at runtime.  Fedora is in the process of removing the
-       selinuxfs "disable" node and once that is complete we will start the
-       slow process of removing this code from the kernel.
-
-       More information on /sys/fs/selinux/disable can be found under the
-       CONFIG_SECURITY_SELINUX_DISABLE Kconfig option.
diff --git a/Documentation/ABI/removed/sysfs-selinux-checkreqprot b/Documentation/ABI/removed/sysfs-selinux-checkreqprot
new file mode 100644 (file)
index 0000000..f599a0a
--- /dev/null
@@ -0,0 +1,26 @@
+What:          /sys/fs/selinux/checkreqprot
+Date:          April 2005 (predates git)
+KernelVersion: 2.6.12-rc2 (predates git)
+Contact:       selinux@vger.kernel.org
+Description:
+
+       REMOVAL UPDATE: The SELinux checkreqprot functionality was removed in
+       March 2023, the original deprecation notice is shown below.
+
+       The selinuxfs "checkreqprot" node allows SELinux to be configured
+       to check the protection requested by userspace for mmap/mprotect
+       calls instead of the actual protection applied by the kernel.
+       This was a compatibility mechanism for legacy userspace and
+       for the READ_IMPLIES_EXEC personality flag.  However, if set to
+       1, it weakens security by allowing mappings to be made executable
+       without authorization by policy.  The default value of checkreqprot
+       at boot was changed starting in Linux v4.4 to 0 (i.e. check the
+       actual protection), and Android and Linux distributions have been
+       explicitly writing a "0" to /sys/fs/selinux/checkreqprot during
+       initialization for some time.  Support for setting checkreqprot to 1
+       will be removed no sooner than June 2021, at which point the kernel
+       will always cease using checkreqprot internally and will always
+       check the actual protections being applied upon mmap/mprotect calls.
+       The checkreqprot selinuxfs node will remain for backward compatibility
+       but will discard writes of the "0" value and will reject writes of the
+       "1" value when this mechanism is removed.
diff --git a/Documentation/ABI/removed/sysfs-selinux-disable b/Documentation/ABI/removed/sysfs-selinux-disable
new file mode 100644 (file)
index 0000000..cb783c6
--- /dev/null
@@ -0,0 +1,29 @@
+What:          /sys/fs/selinux/disable
+Date:          April 2005 (predates git)
+KernelVersion: 2.6.12-rc2 (predates git)
+Contact:       selinux@vger.kernel.org
+Description:
+
+       REMOVAL UPDATE: The SELinux runtime disable functionality was removed
+       in March 2023, the original deprecation notice is shown below.
+
+       The selinuxfs "disable" node allows SELinux to be disabled at runtime
+       prior to a policy being loaded into the kernel.  If disabled via this
+       mechanism, SELinux will remain disabled until the system is rebooted.
+
+       The preferred method of disabling SELinux is via the "selinux=0" boot
+       parameter, but the selinuxfs "disable" node was created to make it
+       easier for systems with primitive bootloaders that did not allow for
+       easy modification of the kernel command line.  Unfortunately, allowing
+       for SELinux to be disabled at runtime makes it difficult to secure the
+       kernel's LSM hooks using the "__ro_after_init" feature.
+
+       Thankfully, the need for the SELinux runtime disable appears to be
+       gone, the default Kconfig configuration disables this selinuxfs node,
+       and only one of the major distributions, Fedora, supports disabling
+       SELinux at runtime.  Fedora is in the process of removing the
+       selinuxfs "disable" node and once that is complete we will start the
+       slow process of removing this code from the kernel.
+
+       More information on /sys/fs/selinux/disable can be found under the
+       CONFIG_SECURITY_SELINUX_DISABLE Kconfig option.
index ac1e519272aa2bb40a72eed5c50c49e51429a8e4..282de3680367d4a3b3c86b1bdb54352d18c0fedd 100644 (file)
@@ -705,6 +705,15 @@ Description:
                zoned will report "none".
 
 
+What:          /sys/block/<disk>/hidden
+Date:          March 2023
+Contact:       linux-block@vger.kernel.org
+Description:
+               [RO] the block device is hidden. it doesn’t produce events, and
+               can’t be opened from userspace or using blkdev_get*.
+               Used for the underlying components of multipath devices.
+
+
 What:          /sys/block/<disk>/stat
 Date:          February 2008
 Contact:       Jerome Marchand <jmarchan@redhat.com>
index c9c957c85bac1a5bdd4a69af5136ea4600a19250..93d899d532584003a5480b28ad823f1f76940b0c 100644 (file)
@@ -277,7 +277,7 @@ the following access functions:
 
 Again, only one request in a given batch need actually carry out a
 grace-period operation, which means there must be an efficient way to
-identify which of many concurrent reqeusts will initiate the grace
+identify which of many concurrent requests will initiate the grace
 period, and that there be an efficient way for the remaining requests to
 wait for that grace period to complete. However, that is the topic of
 the next section.
@@ -405,7 +405,7 @@ Use of Workqueues
 In earlier implementations, the task requesting the expedited grace
 period also drove it to completion. This straightforward approach had
 the disadvantage of needing to account for POSIX signals sent to user
-tasks, so more recent implemementations use the Linux kernel's
+tasks, so more recent implementations use the Linux kernel's
 workqueues (see Documentation/core-api/workqueue.rst).
 
 The requesting task still does counter snapshotting and funnel-lock
@@ -465,7 +465,7 @@ corresponding disadvantage that workqueues cannot be used until they are
 initialized, which does not happen until some time after the scheduler
 spawns the first task. Given that there are parts of the kernel that
 really do want to execute grace periods during this mid-boot “dead
-zone”, expedited grace periods must do something else during thie time.
+zone”, expedited grace periods must do something else during this time.
 
 What they do is to fall back to the old practice of requiring that the
 requesting task drive the expedited grace period, as was the case before
index 7fdf151a8680a2de1d85fc1819ac60aa234e1e8a..5750f125361b066b7e0d3668af7609d2027b0682 100644 (file)
@@ -168,7 +168,7 @@ an ``atomic_add_return()`` of zero) to detect idle CPUs.
 +-----------------------------------------------------------------------+
 
 The approach must be extended to handle one final case, that of waking a
-task blocked in ``synchronize_rcu()``. This task might be affinitied to
+task blocked in ``synchronize_rcu()``. This task might be affined to
 a CPU that is not yet aware that the grace period has ended, and thus
 might not yet be subject to the grace period's memory ordering.
 Therefore, there is an ``smp_mb()`` after the return from
index 588d97366a463bc7fb9e8f6451bb3c8e36e6c758..db8f16b392aa6d1525744767f0732cf090f8e170 100644 (file)
@@ -201,7 +201,7 @@ work looked at debugging uses of RCU [Seyster:2011:RFA:2075416.2075425].
 In 2012, Josh Triplett received his Ph.D. with his dissertation
 covering RCU-protected resizable hash tables and the relationship
 between memory barriers and read-side traversal order:  If the updater
-is making changes in the opposite direction from the read-side traveral
+is making changes in the opposite direction from the read-side traversal
 order, the updater need only execute a memory-barrier instruction,
 but if in the same direction, the updater needs to wait for a grace
 period between the individual updates [JoshTriplettPhD].  Also in 2012,
@@ -1245,7 +1245,7 @@ Oregon Health and Sciences University"
 [Viewed September 5, 2005]"
 ,annotation={
        First posting showing how RCU can be safely adapted for
-       preemptable RCU read side critical sections.
+       preemptible RCU read side critical sections.
 }
 }
 
@@ -1888,7 +1888,7 @@ Revised:
 \url{https://lore.kernel.org/r/20070910183004.GA3299@linux.vnet.ibm.com}
 [Viewed October 25, 2007]"
 ,annotation={
-       Final patch for preemptable RCU to -rt.  (Later patches were
+       Final patch for preemptible RCU to -rt.  (Later patches were
        to mainline, eventually incorporated.)
 }
 }
@@ -2275,7 +2275,7 @@ lot of {Linux} into your technology!!!"
 \url{https://lore.kernel.org/r/20090724001429.GA17374@linux.vnet.ibm.com}
 [Viewed August 15, 2009]"
 ,annotation={
-       First posting of simple and fast preemptable RCU.
+       First posting of simple and fast preemptible RCU.
 }
 }
 
@@ -2639,7 +2639,7 @@ lot of {Linux} into your technology!!!"
        RCU-protected hash tables, barriers vs. read-side traversal order.
        .
        If the updater is making changes in the opposite direction from
-       the read-side traveral order, the updater need only execute a
+       the read-side traversal order, the updater need only execute a
        memory-barrier instruction, but if in the same direction, the
        updater needs to wait for a grace period between the individual
        updates.
index 8b20fd45f2558d8d5d6d6076d624b134f0b70bdf..4060d7a2f62aa19a8ecc45cfaf686efaf5e1df97 100644 (file)
@@ -107,7 +107,7 @@ UP systems, including PREEMPT SMP builds running on UP systems.
 
 Quick Quiz #3:
        Why can't synchronize_rcu() return immediately on UP systems running
-       preemptable RCU?
+       preemptible RCU?
 
 .. _answer_quick_quiz_up:
 
@@ -143,7 +143,7 @@ Answer to Quick Quiz #2:
 
 Answer to Quick Quiz #3:
        Why can't synchronize_rcu() return immediately on UP systems
-       running preemptable RCU?
+       running preemptible RCU?
 
        Because some other task might have been preempted in the middle
        of an RCU read-side critical section.  If synchronize_rcu()
index cc361fb01ed4e3bf5c7d6ef7fe29564f17aef76a..bd3c58c44befdd3a04811c81e4887bad6f321255 100644 (file)
@@ -70,7 +70,7 @@ over a rather long period of time, but improvements are always welcome!
        can serve as rcu_read_lock_sched(), but is less readable and
        prevents lockdep from detecting locking issues.
 
-       Please not that you *cannot* rely on code known to be built
+       Please note that you *cannot* rely on code known to be built
        only in non-preemptible kernels.  Such code can and will break,
        especially in kernels built with CONFIG_PREEMPT_COUNT=y.
 
index 2749f43ec1b03f68c11291b956f07641e1bfd8ec..69e73a39bd112c3888d3ad117b1cc7d4d958fdbd 100644 (file)
@@ -65,7 +65,7 @@ checking of rcu_dereference() primitives:
        rcu_access_pointer(p):
                Return the value of the pointer and omit all barriers,
                but retain the compiler constraints that prevent duplicating
-               or coalescsing.  This is useful when testing the
+               or coalescing.  This is useful when testing the
                value of the pointer itself, for example, against NULL.
 
 The rcu_dereference_check() check expression can be any boolean
index 0316ba0c692255d523a885abba51997085f7e8be..b3b6dfa85248ea2e9619c259a87b16108441d875 100644 (file)
@@ -216,7 +216,7 @@ Kernel boot arguments can also be supplied, for example, to control
 rcutorture's module parameters.  For example, to test a change to RCU's
 CPU stall-warning code, use "--bootargs 'rcutorture.stall_cpu=30'".
 This will of course result in the scripting reporting a failure, namely
-the resuling RCU CPU stall warning.  As noted above, reducing memory may
+the resulting RCU CPU stall warning.  As noted above, reducing memory may
 require disabling rcutorture's callback-flooding tests::
 
        kvm.sh --cpus 448 --configs '56*TREE04' --memory 128M \
@@ -370,5 +370,5 @@ You can also re-run a previous remote run in a manner similar to kvm.sh:
                tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28-remote \
                --duration 24h
 
-In this case, most of the kvm-again.sh parmeters may be supplied following
+In this case, most of the kvm-again.sh parameters may be supplied following
 the pathname of the old run-results directory.
index 2c5563a91998f93d25c2e81c49336b60c26d330e..8eddef28d3a1102a1442d9393d0120b81e3c44b3 100644 (file)
@@ -597,10 +597,10 @@ to avoid having to write your own callback::
 If the occasional sleep is permitted, the single-argument form may
 be used, omitting the rcu_head structure from struct foo.
 
-       kfree_rcu(old_fp);
+       kfree_rcu_mightsleep(old_fp);
 
-This variant of kfree_rcu() almost never blocks, but might do so by
-invoking synchronize_rcu() in response to memory-allocation failure.
+This variant almost never blocks, but might do so by invoking
+synchronize_rcu() in response to memory-allocation failure.
 
 Again, see checklist.rst for additional rules governing the use of RCU.
 
index f491de74ea79020392c74f905e48f8f34c799318..48ca0bd85604ecb84895c802bbfb22bcb8a60e6c 100644 (file)
@@ -58,7 +58,7 @@ Because the buffers are potentially shared between Hyper-Threads cross
 Hyper-Thread attacks are possible.
 
 Deeper technical information is available in the MDS specific x86
-architecture section: :ref:`Documentation/x86/mds.rst <mds>`.
+architecture section: :ref:`Documentation/arch/x86/mds.rst <mds>`.
 
 
 Attack scenarios
index 76673affd917351d2f34095adb5545d24105d5d1..014167ef8dd1b48da829d823b0324143e6a559ab 100644 (file)
@@ -63,7 +63,7 @@ attacker needs to begin a TSX transaction and raise an asynchronous abort
 which in turn potentially leaks data stored in the buffers.
 
 More detailed technical information is available in the TAA specific x86
-architecture section: :ref:`Documentation/x86/tsx_async_abort.rst <tsx_async_abort>`.
+architecture section: :ref:`Documentation/arch/x86/tsx_async_abort.rst <tsx_async_abort>`.
 
 
 Attack scenarios
index 0ad7e7ec0d2742ca2bc21b88820ec761c8f65a06..43ea35613dfcd464f2d861a5baaa62a4fd0fa18e 100644 (file)
@@ -36,7 +36,7 @@ problems and bugs in particular.
 
    reporting-issues
    reporting-regressions
-   security-bugs
+   quickly-build-trimmed-linux
    bug-hunting
    bug-bisect
    tainted-kernels
index 19600c50277b70a512ccfa7efb98ca8e24851262..1ba8f2a44aacdec188276ffbaa5bc6b5e0bf547f 100644 (file)
@@ -128,10 +128,11 @@ parameter is applicable::
        KVM     Kernel Virtual Machine support is enabled.
        LIBATA  Libata driver is enabled
        LP      Printer support is enabled.
+       LOONGARCH LoongArch architecture is enabled.
        LOOP    Loopback device support is enabled.
        M68k    M68k architecture is enabled.
                        These options have more detailed description inside of
-                       Documentation/m68k/kernel-options.rst.
+                       Documentation/arch/m68k/kernel-options.rst.
        MDA     MDA console support is enabled.
        MIPS    MIPS architecture is enabled.
        MOUSE   Appropriate mouse support is enabled.
@@ -177,7 +178,7 @@ parameter is applicable::
        X86-32  X86-32, aka i386 architecture is enabled.
        X86-64  X86-64 architecture is enabled.
                        More X86-64 boot options can be found in
-                       Documentation/x86/x86_64/boot-options.rst.
+                       Documentation/arch/x86/x86_64/boot-options.rst.
        X86     Either 32-bit or 64-bit x86 (same as X86-32+X86-64)
        X86_UV  SGI UV support is enabled.
        XEN     Xen support is enabled
@@ -192,10 +193,10 @@ In addition, the following text indicates that the option::
 Parameters denoted with BOOT are actually interpreted by the boot
 loader, and have no meaning to the kernel directly.
 Do not modify the syntax of boot loader parameters without extreme
-need or coordination with <Documentation/x86/boot.rst>.
+need or coordination with <Documentation/arch/x86/boot.rst>.
 
 There are also arch-specific kernel-parameters not documented here.
-See for example <Documentation/x86/x86_64/boot-options.rst>.
+See for example <Documentation/arch/x86/x86_64/boot-options.rst>.
 
 Note that ALL kernel parameters listed below are CASE SENSITIVE, and that
 a trailing = on the name of any parameter states that that parameter will
index 6221a1d057dd58de265283de65e785c618ea6758..10e2e5c3ff0bb23c3b6b1ce9f59e41d7aac0ca17 100644 (file)
 
        debug_objects   [KNL] Enable object debugging
 
-       no_debug_objects
-                       [KNL] Disable object debugging
-
        debug_guardpage_minorder=
                        [KNL] When CONFIG_DEBUG_PAGEALLOC is set, this
                        parameter allows control of the order of pages that will
 
        mce             [X86-32] Machine Check Exception
 
-       mce=option      [X86-64] See Documentation/x86/x86_64/boot-options.rst
+       mce=option      [X86-64] See Documentation/arch/x86/x86_64/boot-options.rst
 
        md=             [HW] RAID subsystems devices and level
                        See Documentation/admin-guide/md.rst.
                        deep    - Suspend-To-RAM or equivalent (if supported)
                        See Documentation/admin-guide/pm/sleep-states.rst.
 
-       meye.*=         [HW] Set MotionEye Camera parameters
-                       See Documentation/admin-guide/media/meye.rst.
-
        mfgpt_irq=      [IA-32] Specify the IRQ to use for the
                        Multi-Function General Purpose Timers on AMD Geode
                        platforms.
                        1 to enable accounting
                        Default value is 0.
 
-       nfsaddrs=       [NFS] Deprecated.  Use ip= instead.
-                       See Documentation/admin-guide/nfs/nfsroot.rst.
-
-       nfsroot=        [NFS] nfs root filesystem for disk-less boxes.
-                       See Documentation/admin-guide/nfs/nfsroot.rst.
+       nfs.cache_getent=
+                       [NFS] sets the pathname to the program which is used
+                       to update the NFS client cache entries.
 
-       nfsrootdebug    [NFS] enable nfsroot debugging messages.
-                       See Documentation/admin-guide/nfs/nfsroot.rst.
+       nfs.cache_getent_timeout=
+                       [NFS] sets the timeout after which an attempt to
+                       update a cache entry is deemed to have failed.
 
        nfs.callback_nr_threads=
                        [NFSv4] set the total number of threads that the
                        [NFS] set the TCP port on which the NFSv4 callback
                        channel should listen.
 
-       nfs.cache_getent=
-                       [NFS] sets the pathname to the program which is used
-                       to update the NFS client cache entries.
-
-       nfs.cache_getent_timeout=
-                       [NFS] sets the timeout after which an attempt to
-                       update a cache entry is deemed to have failed.
-
-       nfs.idmap_cache_timeout=
-                       [NFS] set the maximum lifetime for idmapper cache
-                       entries.
-
        nfs.enable_ino64=
                        [NFS] enable 64-bit inode numbers.
                        If zero, the NFS client will fake up a 32-bit inode
                        of returning the full 64-bit number.
                        The default is to return 64-bit inode numbers.
 
+       nfs.idmap_cache_timeout=
+                       [NFS] set the maximum lifetime for idmapper cache
+                       entries.
+
        nfs.max_session_cb_slots=
                        [NFSv4.1] Sets the maximum number of session
                        slots the client will assign to the callback
                        will be autodetected by the client, and it will fall
                        back to using the idmapper.
                        To turn off this behaviour, set the value to '0'.
+
        nfs.nfs4_unique_id=
                        [NFS4] Specify an additional fixed unique ident-
                        ification string that NFSv4 clients can insert into
                        their nfs_client_id4 string.  This is typically a
                        UUID that is generated at system install time.
 
-       nfs.send_implementation_id =
-                       [NFSv4.1] Send client implementation identification
-                       information in exchange_id requests.
-                       If zero, no implementation identification information
-                       will be sent.
-                       The default is to send the implementation identification
-                       information.
-
-       nfs.recover_lost_locks =
+       nfs.recover_lost_locks=
                        [NFSv4] Attempt to recover locks that were lost due
                        to a lease timeout on the server. Please note that
                        doing this risks data corruption, since there are
                        The default parameter value of '0' causes the kernel
                        not to attempt recovery of lost locks.
 
-       nfs4.layoutstats_timer =
+       nfs.send_implementation_id=
+                       [NFSv4.1] Send client implementation identification
+                       information in exchange_id requests.
+                       If zero, no implementation identification information
+                       will be sent.
+                       The default is to send the implementation identification
+                       information.
+
+       nfs4.layoutstats_timer=
                        [NFSv4.2] Change the rate at which the kernel sends
                        layoutstats to the pNFS metadata server.
 
                        driver. A non-zero value sets the minimum interval
                        in seconds between layoutstats transmissions.
 
-       nfsd.inter_copy_offload_enable =
+       nfsd.inter_copy_offload_enable=
                        [NFSv4.2] When set to 1, the server will support
                        server-to-server copies for which this server is
                        the destination of the copy.
 
-       nfsd.nfsd4_ssc_umount_timeout =
+       nfsd.nfs4_disable_idmapping=
+                       [NFSv4] When set to the default of '1', the NFSv4
+                       server will return only numeric uids and gids to
+                       clients using auth_sys, and will accept numeric uids
+                       and gids from such clients.  This is intended to ease
+                       migration from NFSv2/v3.
+
+       nfsd.nfsd4_ssc_umount_timeout=
                        [NFSv4.2] When used as the destination of a
                        server-to-server copy, knfsd temporarily mounts
                        the source server.  It caches the mount in case
                        used for the number of milliseconds specified by
                        this parameter.
 
-       nfsd.nfs4_disable_idmapping=
-                       [NFSv4] When set to the default of '1', the NFSv4
-                       server will return only numeric uids and gids to
-                       clients using auth_sys, and will accept numeric uids
-                       and gids from such clients.  This is intended to ease
-                       migration from NFSv2/v3.
+       nfsaddrs=       [NFS] Deprecated.  Use ip= instead.
+                       See Documentation/admin-guide/nfs/nfsroot.rst.
+
+       nfsroot=        [NFS] nfs root filesystem for disk-less boxes.
+                       See Documentation/admin-guide/nfs/nfsroot.rst.
 
+       nfsrootdebug    [NFS] enable nfsroot debugging messages.
+                       See Documentation/admin-guide/nfs/nfsroot.rst.
 
        nmi_backtrace.backtrace_idle [KNL]
                        Dump stacks even of idle CPUs in response to an
        no5lvl          [X86-64] Disable 5-level paging mode. Forces
                        kernel to use 4-level paging instead.
 
-       nofsgsbase      [X86] Disables FSGSBASE instructions.
+       noaliencache    [MM, NUMA, SLAB] Disables the allocation of alien
+                       caches in the slab allocator.  Saves per-node memory,
+                       but will impact performance.
+
+       noalign         [KNL,ARM]
+
+       noaltinstr      [S390] Disables alternative instructions patching
+                       (CPU alternatives feature).
+
+       noapic          [SMP,APIC] Tells the kernel to not make use of any
+                       IOAPICs that may be present in the system.
+
+       noautogroup     Disable scheduler automatic task group creation.
+
+       nocache         [ARM]
 
        no_console_suspend
                        [HW] Never suspend the console
                        /sys/module/printk/parameters/console_suspend) to
                        turn on/off it dynamically.
 
-       novmcoredd      [KNL,KDUMP]
-                       Disable device dump. Device dump allows drivers to
-                       append dump data to vmcore so you can collect driver
-                       specified debug info.  Drivers can append the data
-                       without any limit and this data is stored in memory,
-                       so this may cause significant memory stress.  Disabling
-                       device dump can help save memory but the driver debug
-                       data will be no longer available.  This parameter
-                       is only available when CONFIG_PROC_VMCORE_DEVICE_DUMP
-                       is set.
-
-       noaliencache    [MM, NUMA, SLAB] Disables the allocation of alien
-                       caches in the slab allocator.  Saves per-node memory,
-                       but will impact performance.
-
-       noalign         [KNL,ARM]
-
-       noaltinstr      [S390] Disables alternative instructions patching
-                       (CPU alternatives feature).
-
-       noapic          [SMP,APIC] Tells the kernel to not make use of any
-                       IOAPICs that may be present in the system.
-
-       noautogroup     Disable scheduler automatic task group creation.
-
-       nocache         [ARM]
+       no_debug_objects
+                       [KNL] Disable object debugging
 
        nodsp           [SH] Disable hardware DSP at boot time.
 
 
        noexec          [IA-64]
 
-       nosmap          [PPC]
-                       Disable SMAP (Supervisor Mode Access Prevention)
-                       even if it is supported by processor.
-
-       nosmep          [PPC64s]
-                       Disable SMEP (Supervisor Mode Execution Prevention)
-                       even if it is supported by processor.
-
        noexec32        [X86-64]
                        This affects only 32-bit executables.
                        noexec32=on: enable non-executable mappings (default)
                        noexec32=off: disable non-executable mappings
                                read implies executable mappings
 
+       no_file_caps    Tells the kernel not to honor file capabilities.  The
+                       only way then for a file to be executed with privilege
+                       is to be setuid root or executed by root.
+
        nofpu           [MIPS,SH] Disable hardware FPU at boot time.
 
+       nofsgsbase      [X86] Disables FSGSBASE instructions.
+
        nofxsr          [BUGS=X86-32] Disables x86 floating point extended
                        register save and restore. The kernel will only save
                        legacy floating-point registers on task switch.
 
-       nohugeiomap     [KNL,X86,PPC,ARM64] Disable kernel huge I/O mappings.
-
-       nohugevmalloc   [KNL,X86,PPC,ARM64] Disable kernel huge vmalloc mappings.
-
-       nosmt           [KNL,S390] Disable symmetric multithreading (SMT).
-                       Equivalent to smt=1.
-
-                       [KNL,X86] Disable symmetric multithreading (SMT).
-                       nosmt=force: Force disable SMT, cannot be undone
-                                    via the sysfs control file.
-
-       nospectre_v1    [X86,PPC] Disable mitigations for Spectre Variant 1
-                       (bounds check bypass). With this option data leaks are
-                       possible in the system.
-
-       nospectre_v2    [X86,PPC_E500,ARM64] Disable all mitigations for
-                       the Spectre variant 2 (indirect branch prediction)
-                       vulnerability. System may allow data leaks with this
-                       option.
-
-       nospectre_bhb   [ARM64] Disable all mitigations for Spectre-BHB (branch
-                       history injection) vulnerability. System may allow data leaks
-                       with this option.
-
-       nospec_store_bypass_disable
-                       [HW] Disable all mitigations for the Speculative Store Bypass vulnerability
-
-       no_uaccess_flush
-                       [PPC] Don't flush the L1-D cache after accessing user data.
-
-       noxsave         [BUGS=X86] Disables x86 extended register state save
-                       and restore using xsave. The kernel will fallback to
-                       enabling legacy floating-point and sse state.
-
-       noxsaveopt      [X86] Disables xsaveopt used in saving x86 extended
-                       register states. The kernel will fall back to use
-                       xsave to save the states. By using this parameter,
-                       performance of saving the states is degraded because
-                       xsave doesn't support modified optimization while
-                       xsaveopt supports it on xsaveopt enabled systems.
-
-       noxsaves        [X86] Disables xsaves and xrstors used in saving and
-                       restoring x86 extended register state in compacted
-                       form of xsave area. The kernel will fall back to use
-                       xsaveopt and xrstor to save and restore the states
-                       in standard form of xsave area. By using this
-                       parameter, xsave area per process might occupy more
-                       memory on xsaves enabled systems.
-
-       nohlt           [ARM,ARM64,MICROBLAZE,SH] Forces the kernel to busy wait
-                       in do_idle() and not use the arch_cpu_idle()
-                       implementation; requires CONFIG_GENERIC_IDLE_POLL_SETUP
-                       to be effective. This is useful on platforms where the
-                       sleep(SH) or wfi(ARM,ARM64) instructions do not work
-                       correctly or when doing power measurements to evaluate
-                       the impact of the sleep instructions. This is also
-                       useful when using JTAG debugger.
-
-       no_file_caps    Tells the kernel not to honor file capabilities.  The
-                       only way then for a file to be executed with privilege
-                       is to be setuid root or executed by root.
-
        nohalt          [IA-64] Tells the kernel not to use the power saving
                        function PAL_HALT_LIGHT when idle. This increases
                        power-consumption. On the positive side, it reduces
 
        nohibernate     [HIBERNATION] Disable hibernation and resume.
 
+       nohlt           [ARM,ARM64,MICROBLAZE,SH] Forces the kernel to busy wait
+                       in do_idle() and not use the arch_cpu_idle()
+                       implementation; requires CONFIG_GENERIC_IDLE_POLL_SETUP
+                       to be effective. This is useful on platforms where the
+                       sleep(SH) or wfi(ARM,ARM64) instructions do not work
+                       correctly or when doing power measurements to evaluate
+                       the impact of the sleep instructions. This is also
+                       useful when using JTAG debugger.
+
+       nohugeiomap     [KNL,X86,PPC,ARM64] Disable kernel huge I/O mappings.
+
+       nohugevmalloc   [KNL,X86,PPC,ARM64] Disable kernel huge vmalloc mappings.
+
        nohz=           [KNL] Boottime enable/disable dynamic ticks
                        Valid arguments: on, off
                        Default: on
                        Note that this argument takes precedence over
                        the CONFIG_RCU_NOCB_CPU_DEFAULT_ALL option.
 
-       noiotrap        [SH] Disables trapped I/O port accesses.
-
-       noirqdebug      [X86-32] Disables the code which attempts to detect and
-                       disable unhandled interrupt sources.
-
-       no_timer_check  [X86,APIC] Disables the code which tests for
-                       broken timer IRQ sources.
-
-       noisapnp        [ISAPNP] Disables ISA PnP code.
-
        noinitrd        [RAM] Tells the kernel not to load any configured
                        initial RAM disk.
 
 
        noinvpcid       [X86] Disable the INVPCID cpu feature.
 
+       noiotrap        [SH] Disables trapped I/O port accesses.
+
+       noirqdebug      [X86-32] Disables the code which attempts to detect and
+                       disable unhandled interrupt sources.
+
+       noisapnp        [ISAPNP] Disables ISA PnP code.
+
        nojitter        [IA-64] Disables jitter checking for ITC timers.
 
        nokaslr         [KNL]
                        kernel and module base offset ASLR (Address Space
                        Layout Randomization).
 
-       no-kvmclock     [X86,KVM] Disable paravirtualized KVM clock driver
-
        no-kvmapf       [X86,KVM] Disable paravirtualized asynchronous page
                        fault handling.
 
-       no-vmw-sched-clock
-                       [X86,PV_OPS] Disable paravirtualized VMware scheduler
-                       clock and use the default one.
-
-       no-steal-acc    [X86,PV_OPS,ARM64,PPC/PSERIES] Disable paravirtualized
-                       steal time accounting. steal time is computed, but
-                       won't influence scheduler behaviour
+       no-kvmclock     [X86,KVM] Disable paravirtualized KVM clock driver
 
        nolapic         [X86-32,APIC] Do not enable or use the local APIC.
 
        nomfgpt         [X86-32] Disable Multi-Function General Purpose
                        Timer usage (for AMD Geode machines).
 
-       nonmi_ipi       [X86] Disable using NMI IPIs during panic/reboot to
-                       shutdown the other cpus.  Instead use the REBOOT_VECTOR
-                       irq.
-
        nomodeset       Disable kernel modesetting. Most systems' firmware
                        sets up a display mode and provides framebuffer memory
                        for output. With nomodeset, DRM and fbdev drivers will
 
        nomodule        Disable module load
 
+       nonmi_ipi       [X86] Disable using NMI IPIs during panic/reboot to
+                       shutdown the other cpus.  Instead use the REBOOT_VECTOR
+                       irq.
+
        nopat           [X86] Disable PAT (page attribute table extension of
                        pagetables) support.
 
        nopku           [X86] Disable Memory Protection Keys CPU feature found
                        in some Intel CPUs.
 
+       nopti           [X86-64]
+                       Equivalent to pti=off
+
        nopv=           [X86,XEN,KVM,HYPER_V,VMWARE]
                        Disables the PV optimizations forcing the guest to run
                        as generic guest with no PV drivers. Currently support
        noresume        [SWSUSP] Disables resume and restores original swap
                        space.
 
+       nosbagart       [IA-64]
+
        no-scroll       [VGA] Disables scrollback.
                        This is required for the Braillex ib80-piezo Braille
                        reader made by F.H. Papenmeier (Germany).
 
-       nosbagart       [IA-64]
-
        nosgx           [X86-64,SGX] Disables Intel SGX kernel support.
 
+       nosmap          [PPC]
+                       Disable SMAP (Supervisor Mode Access Prevention)
+                       even if it is supported by processor.
+
+       nosmep          [PPC64s]
+                       Disable SMEP (Supervisor Mode Execution Prevention)
+                       even if it is supported by processor.
+
        nosmp           [SMP] Tells an SMP kernel to act as a UP kernel,
                        and disable the IO APIC.  legacy for "maxcpus=0".
 
+       nosmt           [KNL,S390] Disable symmetric multithreading (SMT).
+                       Equivalent to smt=1.
+
+                       [KNL,X86] Disable symmetric multithreading (SMT).
+                       nosmt=force: Force disable SMT, cannot be undone
+                                    via the sysfs control file.
+
        nosoftlockup    [KNL] Disable the soft-lockup detector.
 
+       nospec_store_bypass_disable
+                       [HW] Disable all mitigations for the Speculative Store Bypass vulnerability
+
+       nospectre_bhb   [ARM64] Disable all mitigations for Spectre-BHB (branch
+                       history injection) vulnerability. System may allow data leaks
+                       with this option.
+
+       nospectre_v1    [X86,PPC] Disable mitigations for Spectre Variant 1
+                       (bounds check bypass). With this option data leaks are
+                       possible in the system.
+
+       nospectre_v2    [X86,PPC_E500,ARM64] Disable all mitigations for
+                       the Spectre variant 2 (indirect branch prediction)
+                       vulnerability. System may allow data leaks with this
+                       option.
+
+       no-steal-acc    [X86,PV_OPS,ARM64,PPC/PSERIES] Disable paravirtualized
+                       steal time accounting. steal time is computed, but
+                       won't influence scheduler behaviour
+
        nosync          [HW,M68K] Disables sync negotiation for all devices.
 
+       no_timer_check  [X86,APIC] Disables the code which tests for
+                       broken timer IRQ sources.
+
+       no_uaccess_flush
+                       [PPC] Don't flush the L1-D cache after accessing user data.
+
+       novmcoredd      [KNL,KDUMP]
+                       Disable device dump. Device dump allows drivers to
+                       append dump data to vmcore so you can collect driver
+                       specified debug info.  Drivers can append the data
+                       without any limit and this data is stored in memory,
+                       so this may cause significant memory stress.  Disabling
+                       device dump can help save memory but the driver debug
+                       data will be no longer available.  This parameter
+                       is only available when CONFIG_PROC_VMCORE_DEVICE_DUMP
+                       is set.
+
+       no-vmw-sched-clock
+                       [X86,PV_OPS] Disable paravirtualized VMware scheduler
+                       clock and use the default one.
+
        nowatchdog      [KNL] Disable both lockup detectors, i.e.
                        soft-lockup and NMI watchdog (hard-lockup).
 
                        LEGACY_XAPIC_DISABLED bit set in the
                        IA32_XAPIC_DISABLE_STATUS MSR.
 
+       noxsave         [BUGS=X86] Disables x86 extended register state save
+                       and restore using xsave. The kernel will fallback to
+                       enabling legacy floating-point and sse state.
+
+       noxsaveopt      [X86] Disables xsaveopt used in saving x86 extended
+                       register states. The kernel will fall back to use
+                       xsave to save the states. By using this parameter,
+                       performance of saving the states is degraded because
+                       xsave doesn't support modified optimization while
+                       xsaveopt supports it on xsaveopt enabled systems.
+
+       noxsaves        [X86] Disables xsaves and xrstors used in saving and
+                       restoring x86 extended register state in compacted
+                       form of xsave area. The kernel will fall back to use
+                       xsaveopt and xrstor to save and restore the states
+                       in standard form of xsave area. By using this
+                       parameter, xsave area per process might occupy more
+                       memory on xsaves enabled systems.
+
        nps_mtm_hs_ctr= [KNL,ARC]
                        This parameter sets the maximum duration, in
                        cycles, each HW thread of the CTOP can run
                        and performance comparison.
 
        pirq=           [SMP,APIC] Manual mp-table setup
-                       See Documentation/x86/i386/IO-APIC.rst.
+                       See Documentation/arch/x86/i386/IO-APIC.rst.
 
        plip=           [PPT,NET] Parallel port network link
                        Format: { parport<nr> | timid | 0 }
 
                        Not specifying this option is equivalent to pti=auto.
 
-       nopti           [X86-64]
-                       Equivalent to pti=off
-
        pty.legacy_count=
                        [KNL] Number of legacy pty's. Overwrites compiled-in
                        default number.
 
        serialnumber    [BUGS=X86-32]
 
-       sev=option[,option...] [X86-64] See Documentation/x86/x86_64/boot-options.rst
+       sev=option[,option...] [X86-64] See Documentation/arch/x86/x86_64/boot-options.rst
 
        shapers=        [NET]
                        Maximal number of shapers.
                        Can be used multiple times for multiple devices.
 
        vga=            [BOOT,X86-32] Select a particular video mode
-                       See Documentation/x86/boot.rst and
+                       See Documentation/arch/x86/boot.rst and
                        Documentation/admin-guide/svga.rst.
                        Use vga=ask for menu.
                        This is actually a boot loader parameter; the value is
                        When enabled, memory and cache locality will be
                        impacted.
 
+       writecombine=   [LOONGARCH] Control the MAT (Memory Access Type) of
+                       ioremap_wc().
+
+                       on   - Enable writecombine, use WUC for ioremap_wc()
+                       off  - Disable writecombine, use SUC for ioremap_wc()
+
        x2apic_phys     [X86-64,APIC] Use x2apic physical mode instead of
                        default x2apic cluster mode on platforms
                        supporting x2apic.
diff --git a/Documentation/admin-guide/quickly-build-trimmed-linux.rst b/Documentation/admin-guide/quickly-build-trimmed-linux.rst
new file mode 100644 (file)
index 0000000..ff4f4cc
--- /dev/null
@@ -0,0 +1,1092 @@
+.. SPDX-License-Identifier: (GPL-2.0+ OR CC-BY-4.0)
+.. [see the bottom of this file for redistribution information]
+
+===========================================
+How to quickly build a trimmed Linux kernel
+===========================================
+
+This guide explains how to swiftly build Linux kernels that are ideal for
+testing purposes, but perfectly fine for day-to-day use, too.
+
+The essence of the process (aka 'TL;DR')
+========================================
+
+*[If you are new to compiling Linux, ignore this TLDR and head over to the next
+section below: it contains a step-by-step guide, which is more detailed, but
+still brief and easy to follow; that guide and its accompanying reference
+section also mention alternatives, pitfalls, and additional aspects, all of
+which might be relevant for you.]*
+
+If your system uses techniques like Secure Boot, prepare it to permit starting
+self-compiled Linux kernels; install compilers and everything else needed for
+building Linux; make sure to have 12 Gigabyte free space in your home directory.
+Now run the following commands to download fresh Linux mainline sources, which
+you then use to configure, build and install your own kernel::
+
+    git clone --depth 1 -b master \
+      https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git ~/linux/
+    cd ~/linux/
+    # Hint: if you want to apply patches, do it at this point. See below for details.
+    # Hint: it's recommended to tag your build at this point. See below for details.
+    yes "" | make localmodconfig
+    # Hint: at this point you might want to adjust the build configuration; you'll
+    #   have to, if you are running Debian. See below for details.
+    make -j $(nproc --all)
+    # Note: on many commodity distributions the next command suffices, but on Arch
+    #   Linux, its derivatives, and some others it does not. See below for details.
+    command -v installkernel && sudo make modules_install install
+    reboot
+
+If you later want to build a newer mainline snapshot, use these commands::
+
+    cd ~/linux/
+    git fetch --depth 1 origin
+    # Note: the next command will discard any changes you did to the code:
+    git checkout --force --detach origin/master
+    # Reminder: if you want to (re)apply patches, do it at this point.
+    # Reminder: you might want to add or modify a build tag at this point.
+    make olddefconfig
+    make -j $(nproc --all)
+    # Reminder: the next command on some distributions does not suffice.
+    command -v installkernel && sudo make modules_install install
+    reboot
+
+Step-by-step guide
+==================
+
+Compiling your own Linux kernel is easy in principle. There are various ways to
+do it. Which of them actually work and is the best depends on the circumstances.
+
+This guide describes a way perfectly suited for those who want to quickly
+install Linux from sources without being bothered by complicated details; the
+goal is to cover everything typically needed on mainstream Linux distributions
+running on commodity PC or server hardware.
+
+The described approach is great for testing purposes, for example to try a
+proposed fix or to check if a problem was already fixed in the latest codebase.
+Nonetheless, kernels built this way are also totally fine for day-to-day use
+while at the same time being easy to keep up to date.
+
+The following steps describe the important aspects of the process; a
+comprehensive reference section later explains each of them in more detail. It
+sometimes also describes alternative approaches, pitfalls, as well as errors
+that might occur at a particular point -- and how to then get things rolling
+again.
+
+..
+   Note: if you see this note, you are reading the text's source file. You
+   might want to switch to a rendered version, as it makes it a lot easier to
+   quickly look something up in the reference section and afterwards jump back
+   to where you left off. Find a the latest rendered version here:
+   https://docs.kernel.org/admin-guide/quickly-build-trimmed-linux.html
+
+.. _backup_sbs:
+
+ * Create a fresh backup and put system repair and restore tools at hand, just
+   to be prepared for the unlikely case of something going sideways.
+
+   [:ref:`details<backup>`]
+
+.. _secureboot_sbs:
+
+ * On platforms with 'Secure Boot' or similar techniques, prepare everything to
+   ensure the system will permit your self-compiled kernel to boot later. The
+   quickest and easiest way to achieve this on commodity x86 systems is to
+   disable such techniques in the BIOS setup utility; alternatively, remove
+   their restrictions through a process initiated by
+   ``mokutil --disable-validation``.
+
+   [:ref:`details<secureboot>`]
+
+.. _buildrequires_sbs:
+
+ * Install all software required to build a Linux kernel. Often you will need:
+   'bc', 'binutils' ('ld' et al.), 'bison', 'flex', 'gcc', 'git', 'openssl',
+   'pahole', 'perl', and the development headers for 'libelf' and 'openssl'. The
+   reference section shows how to quickly install those on various popular Linux
+   distributions.
+
+   [:ref:`details<buildrequires>`]
+
+.. _diskspace_sbs:
+
+ * Ensure to have enough free space for building and installing Linux. For the
+   latter 150 Megabyte in /lib/ and 100 in /boot/ are a safe bet. For storing
+   sources and build artifacts 12 Gigabyte in your home directory should
+   typically suffice. If you have less available, be sure to check the reference
+   section for the step that explains adjusting your kernels build
+   configuration: it mentions a trick that reduce the amount of required space
+   in /home/ to around 4 Gigabyte.
+
+   [:ref:`details<diskspace>`]
+
+.. _sources_sbs:
+
+ * Retrieve the sources of the Linux version you intend to build; then change
+   into the directory holding them, as all further commands in this guide are
+   meant to be executed from there.
+
+   *[Note: the following paragraphs describe how to retrieve the sources by
+   partially cloning the Linux stable git repository. This is called a shallow
+   clone. The reference section explains two alternatives:* :ref:`packaged
+   archives<sources_archive>` *and* :ref:`a full git clone<sources_full>` *;
+   prefer the latter, if downloading a lot of data does not bother you, as that
+   will avoid some* :ref:`peculiar characteristics of shallow clones the
+   reference section explains<sources_shallow>` *.]*
+
+   First, execute the following command to retrieve a fresh mainline codebase::
+
+     git clone --no-checkout --depth 1 -b master \
+       https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git ~/linux/
+     cd ~/linux/
+
+   If you want to access recent mainline releases and pre-releases, deepen you
+   clone's history to the oldest mainline version you are interested in::
+
+     git fetch --shallow-exclude=v6.0 origin
+
+   In case you want to access a stable/longterm release (say v6.1.5), simply add
+   the branch holding that series; afterwards fetch the history at least up to
+   the mainline version that started the series (v6.1)::
+
+     git remote set-branches --add origin linux-6.1.y
+     git fetch --shallow-exclude=v6.0 origin
+
+   Now checkout the code you are interested in. If you just performed the
+   initial clone, you will be able to check out a fresh mainline codebase, which
+   is ideal for checking whether developers already fixed an issue::
+
+      git checkout --detach origin/master
+
+   If you deepened your clone, you instead of ``origin/master`` can specify the
+   version you deepened to (``v6.0`` above); later releases like ``v6.1`` and
+   pre-release like ``v6.2-rc1`` will work, too. Stable or longterm versions
+   like ``v6.1.5`` work just the same, if you added the appropriate
+   stable/longterm branch as described.
+
+   [:ref:`details<sources>`]
+
+.. _patching_sbs:
+
+ * In case you want to apply a kernel patch, do so now. Often a command like
+   this will do the trick::
+
+     patch -p1 < ../proposed-fix.patch
+
+   If the ``-p1`` is actually needed, depends on how the patch was created; in
+   case it does not apply thus try without it.
+
+   If you cloned the sources with git and anything goes sideways, run ``git
+   reset --hard`` to undo any changes to the sources.
+
+   [:ref:`details<patching>`]
+
+.. _tagging_sbs:
+
+ * If you patched your kernel or have one of the same version installed already,
+   better add a unique tag to the one you are about to build::
+
+     echo "-proposed_fix" > localversion
+
+   Running ``uname -r`` under your kernel later will then print something like
+   '6.1-rc4-proposed_fix'.
+
+   [:ref:`details<tagging>`]
+
+ .. _configuration_sbs:
+
+ * Create the build configuration for your kernel based on an existing
+   configuration.
+
+   If you already prepared such a '.config' file yourself, copy it to
+   ~/linux/ and run ``make olddefconfig``.
+
+   Use the same command, if your distribution or somebody else already tailored
+   your running kernel to your or your hardware's needs: the make target
+   'olddefconfig' will then try to use that kernel's .config as base.
+
+   Using this make target is fine for everybody else, too -- but you often can
+   save a lot of time by using this command instead::
+
+     yes "" | make localmodconfig
+
+   This will try to pick your distribution's kernel as base, but then disable
+   modules for any features apparently superfluous for your setup. This will
+   reduce the compile time enormously, especially if you are running an
+   universal kernel from a commodity Linux distribution.
+
+   There is a catch: the make target 'localmodconfig' will disable kernel
+   features you have not directly or indirectly through some program utilized
+   since you booted the system. You can reduce or nearly eliminate that risk by
+   using tricks outlined in the reference section; for quick testing purposes
+   that risk is often negligible, but it is an aspect you want to keep in mind
+   in case your kernel behaves oddly.
+
+   [:ref:`details<configuration>`]
+
+.. _configmods_sbs:
+
+ * Check if you might want to or have to adjust some kernel configuration
+   options:
+
+  * Evaluate how you want to handle debug symbols. Enable them, if you later
+    might need to decode a stack trace found for example in a 'panic', 'Oops',
+    'warning', or 'BUG'; on the other hand disable them, if you are short on
+    storage space or prefer a smaller kernel binary. See the reference section
+    for details on how to do either. If neither applies, it will likely be fine
+    to simply not bother with this. [:ref:`details<configmods_debugsymbols>`]
+
+  * Are you running Debian? Then to avoid known problems by performing
+    additional adjustments explained in the reference section.
+    [:ref:`details<configmods_distros>`].
+
+  * If you want to influence the other aspects of the configuration, do so now
+    by using make targets like 'menuconfig' or 'xconfig'.
+    [:ref:`details<configmods_individual>`].
+
+.. _build_sbs:
+
+ * Build the image and the modules of your kernel::
+
+     make -j $(nproc --all)
+
+   If you want your kernel packaged up as deb, rpm, or tar file, see the
+   reference section for alternatives.
+
+   [:ref:`details<build>`]
+
+.. _install_sbs:
+
+ * Now install your kernel::
+
+     command -v installkernel && sudo make modules_install install
+
+   Often all left for you to do afterwards is a ``reboot``, as many commodity
+   Linux distributions will then create an initramfs (also known as initrd) and
+   an entry for your kernel in your bootloader's configuration; but on some
+   distributions you have to take care of these two steps manually for reasons
+   the reference section explains.
+
+   On a few distributions like Arch Linux and its derivatives the above command
+   does nothing at all; in that case you have to manually install your kernel,
+   as outlined in the reference section.
+
+   [:ref:`details<install>`]
+
+.. _another_sbs:
+
+ * To later build another kernel you need similar steps, but sometimes slightly
+   different commands.
+
+   First, switch back into the sources tree::
+
+      cd ~/linux/
+
+   In case you want to build a version from a stable/longterm series you have
+   not used yet (say 6.2.y), tell git to track it::
+
+      git remote set-branches --add origin linux-6.2.y
+
+   Now fetch the latest upstream changes; you again need to specify the earliest
+   version you care about, as git otherwise might retrieve the entire commit
+   history::
+
+     git fetch --shallow-exclude=v6.1 origin
+
+   If you modified the sources (for example by applying a patch), you now need
+   to discard those modifications; that's because git otherwise will not be able
+   to switch to the sources of another version due to potential conflicting
+   changes::
+
+     git reset --hard
+
+   Now checkout the version you are interested in, as explained above::
+
+     git checkout --detach origin/master
+
+   At this point you might want to patch the sources again or set/modify a build
+   tag, as explained earlier; afterwards adjust the build configuration to the
+   new codebase and build your next kernel::
+
+     # reminder: if you want to apply patches, do it at this point
+     # reminder: you might want to update your build tag at this point
+     make olddefconfig
+     make -j $(nproc --all)
+
+   Install the kernel as outlined above::
+
+     command -v installkernel && sudo make modules_install install
+
+   [:ref:`details<another>`]
+
+.. _uninstall_sbs:
+
+ * Your kernel is easy to remove later, as its parts are only stored in two
+   places and clearly identifiable by the kernel's release name. Just ensure to
+   not delete the kernel you are running, as that might render your system
+   unbootable.
+
+   Start by deleting the directory holding your kernel's modules, which is named
+   after its release name -- '6.0.1-foobar' in the following example::
+
+     sudo rm -rf /lib/modules/6.0.1-foobar
+
+   Now try the following command, which on some distributions will delete all
+   other kernel files installed while also removing the kernel's entry from the
+   bootloader configuration::
+
+     command -v kernel-install && sudo kernel-install -v remove 6.0.1-foobar
+
+   If that command does not output anything or fails, see the reference section;
+   do the same if any files named '*6.0.1-foobar*' remain in /boot/.
+
+   [:ref:`details<uninstall>`]
+
+.. _submit_improvements:
+
+Did you run into trouble following any of the above steps that is not cleared up
+by the reference section below? Or do you have ideas how to improve the text?
+Then please take a moment of your time and let the maintainer of this document
+know by email (Thorsten Leemhuis <linux@leemhuis.info>), ideally while CCing the
+Linux docs mailing list (linux-doc@vger.kernel.org). Such feedback is vital to
+improve this document further, which is in everybody's interest, as it will
+enable more people to master the task described here.
+
+Reference section for the step-by-step guide
+============================================
+
+This section holds additional information for each of the steps in the above
+guide.
+
+.. _backup:
+
+Prepare for emergencies
+-----------------------
+
+   *Create a fresh backup and put system repair and restore tools at hand*
+   [:ref:`... <backup_sbs>`]
+
+Remember, you are dealing with computers, which sometimes do unexpected things
+-- especially if you fiddle with crucial parts like the kernel of an operating
+system. That's what you are about to do in this process. Hence, better prepare
+for something going sideways, even if that should not happen.
+
+[:ref:`back to step-by-step guide <backup_sbs>`]
+
+.. _secureboot:
+
+Dealing with techniques like Secure Boot
+----------------------------------------
+
+   *On platforms with 'Secure Boot' or similar techniques, prepare everything to
+   ensure the system will permit your self-compiled kernel to boot later.*
+   [:ref:`... <secureboot_sbs>`]
+
+Many modern systems allow only certain operating systems to start; they thus by
+default will reject booting self-compiled kernels.
+
+You ideally deal with this by making your platform trust your self-built kernels
+with the help of a certificate and signing. How to do that is not described
+here, as it requires various steps that would take the text too far away from
+its purpose; 'Documentation/admin-guide/module-signing.rst' and various web
+sides already explain this in more detail.
+
+Temporarily disabling solutions like Secure Boot is another way to make your own
+Linux boot. On commodity x86 systems it is possible to do this in the BIOS Setup
+utility; the steps to do so are not described here, as they greatly vary between
+machines.
+
+On mainstream x86 Linux distributions there is a third and universal option:
+disable all Secure Boot restrictions for your Linux environment. You can
+initiate this process by running ``mokutil --disable-validation``; this will
+tell you to create a one-time password, which is safe to write down. Now
+restart; right after your BIOS performed all self-tests the bootloader Shim will
+show a blue box with a message 'Press any key to perform MOK management'. Hit
+some key before the countdown exposes. This will open a menu and choose 'Change
+Secure Boot state' there. Shim's 'MokManager' will now ask you to enter three
+randomly chosen characters from the one-time password specified earlier. Once
+you provided them, confirm that you really want to disable the validation.
+Afterwards, permit MokManager to reboot the machine.
+
+[:ref:`back to step-by-step guide <secureboot_sbs>`]
+
+.. _buildrequires:
+
+Install build requirements
+--------------------------
+
+   *Install all software required to build a Linux kernel.*
+   [:ref:`...<buildrequires_sbs>`]
+
+The kernel is pretty stand-alone, but besides tools like the compiler you will
+sometimes need a few libraries to build one. How to install everything needed
+depends on your Linux distribution and the configuration of the kernel you are
+about to build.
+
+Here are a few examples what you typically need on some mainstream
+distributions:
+
+ * Debian, Ubuntu, and derivatives::
+
+     sudo apt install bc binutils bison dwarves flex gcc git make openssl \
+       pahole perl-base libssl-dev libelf-dev
+
+ * Fedora and derivatives::
+
+     sudo dnf install binutils /usr/include/{libelf.h,openssl/pkcs7.h} \
+       /usr/bin/{bc,bison,flex,gcc,git,openssl,make,perl,pahole}
+
+ * openSUSE and derivatives::
+
+     sudo zypper install bc binutils bison dwarves flex gcc git make perl-base \
+       openssl openssl-devel libelf-dev
+
+In case you wonder why these lists include openssl and its development headers:
+they are needed for the Secure Boot support, which many distributions enable in
+their kernel configuration for x86 machines.
+
+Sometimes you will need tools for compression formats like bzip2, gzip, lz4,
+lzma, lzo, xz, or zstd as well.
+
+You might need additional libraries and their development headers in case you
+perform tasks not covered in this guide. For example, zlib will be needed when
+building kernel tools from the tools/ directory; adjusting the build
+configuration with make targets like 'menuconfig' or 'xconfig' will require
+development headers for ncurses or Qt5.
+
+[:ref:`back to step-by-step guide <buildrequires_sbs>`]
+
+.. _diskspace:
+
+Space requirements
+------------------
+
+   *Ensure to have enough free space for building and installing Linux.*
+   [:ref:`... <diskspace_sbs>`]
+
+The numbers mentioned are rough estimates with a big extra charge to be on the
+safe side, so often you will need less.
+
+If you have space constraints, remember to read the reference section when you
+reach the :ref:`section about configuration adjustments' <configmods>`, as
+ensuring debug symbols are disabled will reduce the consumed disk space by quite
+a few gigabytes.
+
+[:ref:`back to step-by-step guide <diskspace_sbs>`]
+
+
+.. _sources:
+
+Download the sources
+--------------------
+
+  *Retrieve the sources of the Linux version you intend to build.*
+  [:ref:`...<sources_sbs>`]
+
+The step-by-step guide outlines how to retrieve Linux' sources using a shallow
+git clone. There is :ref:`more to tell about this method<sources_shallow>` and
+two alternate ways worth describing: :ref:`packaged archives<sources_archive>`
+and :ref:`a full git clone<sources_full>`. And the aspects ':ref:`wouldn't it
+be wiser to use a proper pre-release than the latest mainline code
+<sources_snapshot>`' and ':ref:`how to get an even fresher mainline codebase
+<sources_fresher>`' need elaboration, too.
+
+Note, to keep things simple the commands used in this guide store the build
+artifacts in the source tree. If you prefer to separate them, simply add
+something like ``O=~/linux-builddir/`` to all make calls; also adjust the path
+in all commands that add files or modify any generated (like your '.config').
+
+[:ref:`back to step-by-step guide <sources_sbs>`]
+
+.. _sources_shallow:
+
+Noteworthy characteristics of shallow clones
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The step-by-step guide uses a shallow clone, as it is the best solution for most
+of this document's target audience. There are a few aspects of this approach
+worth mentioning:
+
+ * This document in most places uses ``git fetch`` with ``--shallow-exclude=``
+   to specify the earliest version you care about (or to be precise: its git
+   tag). You alternatively can use the parameter ``--shallow-since=`` to specify
+   an absolute (say ``'2023-07-15'``) or relative (``'12 months'``) date to
+   define the depth of the history you want to download. As a second
+   alternative, you can also specify a certain depth explicitly with a parameter
+   like ``--depth=1``, unless you add branches for stable/longterm kernels.
+
+ * When running ``git fetch``, remember to always specify the oldest version,
+   the time you care about, or an explicit depth as shown in the step-by-step
+   guide. Otherwise you will risk downloading nearly the entire git history,
+   which will consume quite a bit of time and bandwidth while also stressing the
+   servers.
+
+   Note, you do not have to use the same version or date all the time. But when
+   you change it over time, git will deepen or flatten the history to the
+   specified point. That allows you to retrieve versions you initially thought
+   you did not need -- or it will discard the sources of older versions, for
+   example in case you want to free up some disk space. The latter will happen
+   automatically when using ``--shallow-since=`` or
+   ``--depth=``.
+
+ * Be warned, when deepening your clone you might encounter an error like
+   'fatal: error in object: unshallow cafecaca0c0dacafecaca0c0dacafecaca0c0da'.
+   In that case run ``git repack -d`` and try again``
+
+ * In case you want to revert changes from a certain version (say Linux 6.3) or
+   perform a bisection (v6.2..v6.3), better tell ``git fetch`` to retrieve
+   objects up to three versions earlier (e.g. 6.0): ``git describe`` will then
+   be able to describe most commits just like it would in a full git clone.
+
+[:ref:`back to step-by-step guide <sources_sbs>`] [:ref:`back to section intro <sources>`]
+
+.. _sources_archive:
+
+Downloading the sources using a packages archive
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+People new to compiling Linux often assume downloading an archive via the
+front-page of https://kernel.org is the best approach to retrieve Linux'
+sources. It actually can be, if you are certain to build just one particular
+kernel version without changing any code. Thing is: you might be sure this will
+be the case, but in practice it often will turn out to be a wrong assumption.
+
+That's because when reporting or debugging an issue developers will often ask to
+give another version a try. They also might suggest temporarily undoing a commit
+with ``git revert`` or might provide various patches to try. Sometimes reporters
+will also be asked to use ``git bisect`` to find the change causing a problem.
+These things rely on git or are a lot easier and quicker to handle with it.
+
+A shallow clone also does not add any significant overhead. For example, when
+you use ``git clone --depth=1`` to create a shallow clone of the latest mainline
+codebase git will only retrieve a little more data than downloading the latest
+mainline pre-release (aka 'rc') via the front-page of kernel.org would.
+
+A shallow clone therefore is often the better choice. If you nevertheless want
+to use a packaged source archive, download one via kernel.org; afterwards
+extract its content to some directory and change to the subdirectory created
+during extraction. The rest of the step-by-step guide will work just fine, apart
+from things that rely on git -- but this mainly concerns the section on
+successive builds of other versions.
+
+[:ref:`back to step-by-step guide <sources_sbs>`] [:ref:`back to section intro <sources>`]
+
+.. _sources_full:
+
+Downloading the sources using a full git clone
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If downloading and storing a lot of data (~4,4 Gigabyte as of early 2023) is
+nothing that bothers you, instead of a shallow clone perform a full git clone
+instead. You then will avoid the specialties mentioned above and will have all
+versions and individual commits at hand at any time::
+
+    curl -L \
+      https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/clone.bundle \
+      -o linux-stable.git.bundle
+    git clone clone.bundle ~/linux/
+    rm linux-stable.git.bundle
+    cd ~/linux/
+    git remote set-url origin
+    https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
+    git fetch origin
+    git checkout --detach origin/master
+
+[:ref:`back to step-by-step guide <sources_sbs>`] [:ref:`back to section intro <sources>`]
+
+.. _sources_snapshot:
+
+Proper pre-releases (RCs) vs. latest mainline
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When cloning the sources using git and checking out origin/master, you often
+will retrieve a codebase that is somewhere between the latest and the next
+release or pre-release. This almost always is the code you want when giving
+mainline a shot: pre-releases like v6.1-rc5 are in no way special, as they do
+not get any significant extra testing before being published.
+
+There is one exception: you might want to stick to the latest mainline release
+(say v6.1) before its successor's first pre-release (v6.2-rc1) is out. That is
+because compiler errors and other problems are more likely to occur during this
+time, as mainline then is in its 'merge window': a usually two week long phase,
+in which the bulk of the changes for the next release is merged.
+
+[:ref:`back to step-by-step guide <sources_sbs>`] [:ref:`back to section intro <sources>`]
+
+.. _sources_fresher:
+
+Avoiding the mainline lag
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The explanations for both the shallow clone and the full clone both retrieve the
+code from the Linux stable git repository. That makes things simpler for this
+document's audience, as it allows easy access to both mainline and
+stable/longterm releases. This approach has just one downside:
+
+Changes merged into the mainline repository are only synced to the master branch
+of the Linux stable repository  every few hours. This lag most of the time is
+not something to worry about; but in case you really need the latest code, just
+add the mainline repo as additional remote and checkout the code from there::
+
+    git remote add mainline \
+      https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
+    git fetch mainline
+    git checkout --detach mainline/master
+
+When doing this with a shallow clone, remember to call ``git fetch`` with one
+of the parameters described earlier to limit the depth.
+
+[:ref:`back to step-by-step guide <sources_sbs>`] [:ref:`back to section intro <sources>`]
+
+.. _patching:
+
+Patch the sources (optional)
+----------------------------
+
+  *In case you want to apply a kernel patch, do so now.*
+  [:ref:`...<patching_sbs>`]
+
+This is the point where you might want to patch your kernel -- for example when
+a developer proposed a fix and asked you to check if it helps. The step-by-step
+guide already explains everything crucial here.
+
+[:ref:`back to step-by-step guide <patching_sbs>`]
+
+.. _tagging:
+
+Tagging this kernel build (optional, often wise)
+------------------------------------------------
+
+  *If you patched your kernel or already have that kernel version installed,
+  better tag your kernel by extending its release name:*
+  [:ref:`...<tagging_sbs>`]
+
+Tagging your kernel will help avoid confusion later, especially when you patched
+your kernel. Adding an individual tag will also ensure the kernel's image and
+its modules are installed in parallel to any existing kernels.
+
+There are various ways to add such a tag. The step-by-step guide realizes one by
+creating a 'localversion' file in your build directory from which the kernel
+build scripts will automatically pick up the tag. You can later change that file
+to use a different tag in subsequent builds or simply remove that file to dump
+the tag.
+
+[:ref:`back to step-by-step guide <tagging_sbs>`]
+
+.. _configuration:
+
+Define the build configuration for your kernel
+----------------------------------------------
+
+  *Create the build configuration for your kernel based on an existing
+  configuration.* [:ref:`... <configuration_sbs>`]
+
+There are various aspects for this steps that require a more careful
+explanation:
+
+Pitfalls when using another configuration file as base
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Make targets like localmodconfig and olddefconfig share a few common snares you
+want to be aware of:
+
+ * These targets will reuse a kernel build configuration in your build directory
+   (e.g. '~/linux/.config'), if one exists. In case you want to start from
+   scratch you thus need to delete it.
+
+ * The make targets try to find the configuration for your running kernel
+   automatically, but might choose poorly. A line like '# using defaults found
+   in /boot/config-6.0.7-250.fc36.x86_64' or 'using config:
+   '/boot/config-6.0.7-250.fc36.x86_64' tells you which file they picked. If
+   that is not the intended one, simply store it as '~/linux/.config'
+   before using these make targets.
+
+ * Unexpected things might happen if you try to use a config file prepared for
+   one kernel (say v6.0) on an older generation (say v5.15). In that case you
+   might want to use a configuration as base which your distribution utilized
+   when they used that or an slightly older kernel version.
+
+Influencing the configuration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The make target olddefconfig and the ``yes "" |`` used when utilizing
+localmodconfig will set any undefined build options to their default value. This
+among others will disable many kernel features that were introduced after your
+base kernel was released.
+
+If you want to set these configurations options manually, use ``oldconfig``
+instead of ``olddefconfig`` or omit the ``yes "" |`` when utilizing
+localmodconfig. Then for each undefined configuration option you will be asked
+how to proceed. In case you are unsure what to answer, simply hit 'enter' to
+apply the default value.
+
+Big pitfall when using localmodconfig
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As explained briefly in the step-by-step guide already: with localmodconfig it
+can easily happen that your self-built kernel will lack modules for tasks you
+did not perform before utilizing this make target. That's because those tasks
+require kernel modules that are normally autoloaded when you perform that task
+for the first time; if you didn't perform that task at least once before using
+localmodonfig, the latter will thus assume these modules are superfluous and
+disable them.
+
+You can try to avoid this by performing typical tasks that often will autoload
+additional kernel modules: start a VM, establish VPN connections, loop-mount a
+CD/DVD ISO, mount network shares (CIFS, NFS, ...), and connect all external
+devices (2FA keys, headsets, webcams, ...) as well as storage devices with file
+systems you otherwise do not utilize (btrfs, ext4, FAT, NTFS, XFS, ...). But it
+is hard to think of everything that might be needed -- even kernel developers
+often forget one thing or another at this point.
+
+Do not let that risk bother you, especially when compiling a kernel only for
+testing purposes: everything typically crucial will be there. And if you forget
+something important you can turn on a missing feature later and quickly run the
+commands to compile and install a better kernel.
+
+But if you plan to build and use self-built kernels regularly, you might want to
+reduce the risk by recording which modules your system loads over the course of
+a few weeks. You can automate this with `modprobed-db
+<https://github.com/graysky2/modprobed-db>`_. Afterwards use ``LSMOD=<path>`` to
+point localmodconfig to the list of modules modprobed-db noticed being used::
+
+    yes "" | make LSMOD="${HOME}"/.config/modprobed.db localmodconfig
+
+Remote building with localmodconfig
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you want to use localmodconfig to build a kernel for another machine, run
+``lsmod > lsmod_foo-machine`` on it and transfer that file to your build host.
+Now point the build scripts to the file like this: ``yes "" | make
+LSMOD=~/lsmod_foo-machine localmodconfig``. Note, in this case
+you likely want to copy a base kernel configuration from the other machine over
+as well and place it as .config in your build directory.
+
+[:ref:`back to step-by-step guide <configuration_sbs>`]
+
+.. _configmods:
+
+Adjust build configuration
+--------------------------
+
+   *Check if you might want to or have to adjust some kernel configuration
+   options:*
+
+Depending on your needs you at this point might want or have to adjust some
+kernel configuration options.
+
+.. _configmods_debugsymbols:
+
+Debug symbols
+~~~~~~~~~~~~~
+
+   *Evaluate how you want to handle debug symbols.*
+   [:ref:`...<configmods_sbs>`]
+
+Most users do not need to care about this, it's often fine to leave everything
+as it is; but you should take a closer look at this, if you might need to decode
+a stack trace or want to reduce space consumption.
+
+Having debug symbols available can be important when your kernel throws a
+'panic', 'Oops', 'warning', or 'BUG' later when running, as then you will be
+able to find the exact place where the problem occurred in the code. But
+collecting and embedding the needed debug information takes time and consumes
+quite a bit of space: in late 2022 the build artifacts for a typical x86 kernel
+configured with localmodconfig consumed around 5 Gigabyte of space with debug
+symbols, but less than 1 when they were disabled. The resulting kernel image and
+the modules are bigger as well, which increases load times.
+
+Hence, if you want a small kernel and are unlikely to decode a stack trace
+later, you might want to disable debug symbols to avoid above downsides::
+
+    ./scripts/config --file .config -d DEBUG_INFO \
+      -d DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT -d DEBUG_INFO_DWARF4 \
+      -d DEBUG_INFO_DWARF5 -e CONFIG_DEBUG_INFO_NONE
+    make olddefconfig
+
+You on the other hand definitely want to enable them, if there is a decent
+chance that you need to decode a stack trace later (as explained by 'Decode
+failure messages' in Documentation/admin-guide/tainted-kernels.rst in more
+detail)::
+
+    ./scripts/config --file .config -d DEBUG_INFO_NONE -e DEBUG_KERNEL
+      -e DEBUG_INFO -e DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT -e KALLSYMS -e KALLSYMS_ALL
+    make olddefconfig
+
+Note, many mainstream distributions enable debug symbols in their kernel
+configurations -- make targets like localmodconfig and olddefconfig thus will
+often pick that setting up.
+
+[:ref:`back to step-by-step guide <configmods_sbs>`]
+
+.. _configmods_distros:
+
+Distro specific adjustments
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+   *Are you running* [:ref:`... <configmods_sbs>`]
+
+The following sections help you to avoid build problems that are known to occur
+when following this guide on a few commodity distributions.
+
+**Debian:**
+
+ * Remove a stale reference to a certificate file that would cause your build to
+   fail::
+
+    ./scripts/config --file .config --set-str SYSTEM_TRUSTED_KEYS ''
+
+   Alternatively, download the needed certificate and make that configuration
+   option point to it, as `the Debian handbook explains in more detail
+   <https://debian-handbook.info/browse/stable/sect.kernel-compilation.html>`_
+   -- or generate your own, as explained in
+   Documentation/admin-guide/module-signing.rst.
+
+[:ref:`back to step-by-step guide <configmods_sbs>`]
+
+.. _configmods_individual:
+
+Individual adjustments
+~~~~~~~~~~~~~~~~~~~~~~
+
+   *If you want to influence the other aspects of the configuration, do so
+   now* [:ref:`... <configmods_sbs>`]
+
+You at this point can use a command like ``make menuconfig`` to enable or
+disable certain features using a text-based user interface; to use a graphical
+configuration utilize, use the make target ``xconfig`` or ``gconfig`` instead.
+All of them require development libraries from toolkits they are based on
+(ncurses, Qt5, Gtk2); an error message will tell you if something required is
+missing.
+
+[:ref:`back to step-by-step guide <configmods_sbs>`]
+
+.. _build:
+
+Build your kernel
+-----------------
+
+  *Build the image and the modules of your kernel* [:ref:`... <build_sbs>`]
+
+A lot can go wrong at this stage, but the instructions below will help you help
+yourself. Another subsection explains how to directly package your kernel up as
+deb, rpm or tar file.
+
+Dealing with build errors
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When a build error occurs, it might be caused by some aspect of your machine's
+setup that often can be fixed quickly; other times though the problem lies in
+the code and can only be fixed by a developer. A close examination of the
+failure messages coupled with some research on the internet will often tell you
+which of the two it is. To perform such a investigation, restart the build
+process like this::
+
+    make V=1
+
+The ``V=1`` activates verbose output, which might be needed to see the actual
+error. To make it easier to spot, this command also omits the ``-j $(nproc
+--all)`` used earlier to utilize every CPU core in the system for the job -- but
+this parallelism also results in some clutter when failures occur.
+
+After a few seconds the build process should run into the error again. Now try
+to find the most crucial line describing the problem. Then search the internet
+for the most important and non-generic section of that line (say 4 to 8 words);
+avoid or remove anything that looks remotely system-specific, like your username
+or local path names like ``/home/username/linux/``. First try your regular
+internet search engine with that string, afterwards search Linux kernel mailing
+lists via `lore.kernel.org/all/ <https://lore.kernel.org/all/>`_.
+
+This most of the time will find something that will explain what is wrong; quite
+often one of the hits will provide a solution for your problem, too. If you
+do not find anything that matches your problem, try again from a different angle
+by modifying your search terms or using another line from the error messages.
+
+In the end, most trouble you are to run into has likely been encountered and
+reported by others already. That includes issues where the cause is not your
+system, but lies the code. If you run into one of those, you might thus find a
+solution (e.g. a patch) or workaround for your problem, too.
+
+Package your kernel up
+~~~~~~~~~~~~~~~~~~~~~~
+
+The step-by-step guide uses the default make targets (e.g. 'bzImage' and
+'modules' on x86) to build the image and the modules of your kernel, which later
+steps of the guide then install. You instead can also directly build everything
+and directly package it up by using one of the following targets:
+
+ * ``make -j $(nproc --all) bindeb-pkg`` to generate a deb package
+
+ * ``make -j $(nproc --all) binrpm-pkg`` to generate a rpm package
+
+ * ``make -j $(nproc --all) tarbz2-pkg`` to generate a bz2 compressed tarball
+
+This is just a selection of available make targets for this purpose, see
+``make help`` for others. You can also use these targets after running
+``make -j $(nproc --all)``, as they will pick up everything already built.
+
+If you employ the targets to generate deb or rpm packages, ignore the
+step-by-step guide's instructions on installing and removing your kernel;
+instead install and remove the packages using the package utility for the format
+(e.g. dpkg and rpm) or a package management utility build on top of them (apt,
+aptitude, dnf/yum, zypper, ...). Be aware that the packages generated using
+these two make targets are designed to work on various distributions utilizing
+those formats, they thus will sometimes behave differently than your
+distribution's kernel packages.
+
+[:ref:`back to step-by-step guide <build_sbs>`]
+
+.. _install:
+
+Install your kernel
+-------------------
+
+  *Now install your kernel* [:ref:`... <install_sbs>`]
+
+What you need to do after executing the command in the step-by-step guide
+depends on the existence and the implementation of an ``installkernel``
+executable. Many commodity Linux distributions ship such a kernel installer in
+``/sbin/`` that does everything needed, hence there is nothing left for you
+except rebooting. But some distributions contain an installkernel that does
+only part of the job -- and a few lack it completely and leave all the work to
+you.
+
+If ``installkernel`` is found, the kernel's build system will delegate the
+actual installation of your kernel's image and related files to this executable.
+On almost all Linux distributions it will store the image as '/boot/vmlinuz-
+<your kernel's release name>' and put a 'System.map-<your kernel's release
+name>' alongside it. Your kernel will thus be installed in parallel to any
+existing ones, unless you already have one with exactly the same release name.
+
+Installkernel on many distributions will afterwards generate an 'initramfs'
+(often also called 'initrd'), which commodity distributions rely on for booting;
+hence be sure to keep the order of the two make targets used in the step-by-step
+guide, as things will go sideways if you install your kernel's image before its
+modules. Often installkernel will then add your kernel to the bootloader
+configuration, too. You have to take care of one or both of these tasks
+yourself, if your distributions installkernel doesn't handle them.
+
+A few distributions like Arch Linux and its derivatives totally lack an
+installkernel executable. On those just install the modules using the kernel's
+build system and then install the image and the System.map file manually::
+
+     sudo make modules_install
+     sudo install -m 0600 $(make -s image_name) /boot/vmlinuz-$(make -s kernelrelease)
+     sudo install -m 0600 System.map /boot/System.map-$(make -s kernelrelease)
+
+If your distribution boots with the help of an initramfs, now generate one for
+your kernel using the tools your distribution provides for this process.
+Afterwards add your kernel to your bootloader configuration and reboot.
+
+[:ref:`back to step-by-step guide <install_sbs>`]
+
+.. _another:
+
+Another round later
+-------------------
+
+  *To later build another kernel you need similar, but sometimes slightly
+  different commands* [:ref:`... <another_sbs>`]
+
+The process to build later kernels is similar, but at some points slightly
+different. You for example do not want to use 'localmodconfig' for succeeding
+kernel builds, as you already created a trimmed down configuration you want to
+use from now on. Hence instead just use ``oldconfig`` or ``olddefconfig`` to
+adjust your build configurations to the needs of the kernel version you are
+about to build.
+
+If you created a shallow-clone with git, remember what the :ref:`section that
+explained the setup described in more detail <sources>`: you need to use a
+slightly different ``git fetch`` command and when switching to another series
+need to add an additional remote branch.
+
+[:ref:`back to step-by-step guide <another_sbs>`]
+
+.. _uninstall:
+
+Uninstall the kernel later
+--------------------------
+
+  *All parts of your installed kernel are identifiable by its release name and
+  thus easy to remove later.* [:ref:`... <uninstall_sbs>`]
+
+Do not worry installing your kernel manually and thus bypassing your
+distribution's packaging system will totally mess up your machine: all parts of
+your kernel are easy to remove later, as files are stored in two places only and
+normally identifiable by the kernel's release name.
+
+One of the two places is a directory in /lib/modules/, which holds the modules
+for each installed kernel. This directory is named after the kernel's release
+name; hence, to remove all modules for one of your kernels, simply remove its
+modules directory in /lib/modules/.
+
+The other place is /boot/, where typically one to five files will be placed
+during installation of a kernel. All of them usually contain the release name in
+their file name, but how many files and their name depends somewhat on your
+distribution's installkernel executable (:ref:`see above <install>`) and its
+initramfs generator. On some distributions the ``kernel-install`` command
+mentioned in the step-by-step guide will remove all of these files for you --
+and the entry for your kernel in the bootloader configuration at the same time,
+too. On others you have to take care of these steps yourself. The following
+command should interactively remove the two main files of a kernel with the
+release name '6.0.1-foobar'::
+
+    rm -i /boot/{System.map,vmlinuz}-6.0.1-foobar
+
+Now remove the belonging initramfs, which often will be called something like
+``/boot/initramfs-6.0.1-foobar.img`` or ``/boot/initrd.img-6.0.1-foobar``.
+Afterwards check for other files in /boot/ that have '6.0.1-foobar' in their
+name and delete them as well. Now remove the kernel from your bootloader's
+configuration.
+
+Note, be very careful with wildcards like '*' when deleting files or directories
+for kernels manually: you might accidentally remove files of a 6.0.11 kernel
+when all you want is to remove 6.0 or 6.0.1.
+
+[:ref:`back to step-by-step guide <uninstall_sbs>`]
+
+.. _faq:
+
+FAQ
+===
+
+Why does this 'how-to' not work on my system?
+---------------------------------------------
+
+As initially stated, this guide is 'designed to cover everything typically
+needed [to build a kernel] on mainstream Linux distributions running on
+commodity PC or server hardware'. The outlined approach despite this should work
+on many other setups as well. But trying to cover every possible use-case in one
+guide would defeat its purpose, as without such a focus you would need dozens or
+hundreds of constructs along the lines of 'in case you are having <insert
+machine or distro>, you at this point have to do <this and that>
+<instead|additionally>'. Each of which would make the text longer, more
+complicated, and harder to follow.
+
+That being said: this of course is a balancing act. Hence, if you think an
+additional use-case is worth describing, suggest it to the maintainers of this
+document, as :ref:`described above <submit_improvements>`.
+
+
+..
+   end-of-content
+..
+   This document is maintained by Thorsten Leemhuis <linux@leemhuis.info>. If
+   you spot a typo or small mistake, feel free to let him know directly and
+   he'll fix it. You are free to do the same in a mostly informal way if you
+   want to contribute changes to the text -- but for copyright reasons please CC
+   linux-doc@vger.kernel.org and 'sign-off' your contribution as
+   Documentation/process/submitting-patches.rst explains in the section 'Sign
+   your work - the Developer's Certificate of Origin'.
+..
+   This text is available under GPL-2.0+ or CC-BY-4.0, as stated at the top
+   of the file. If you want to distribute this text under CC-BY-4.0 only,
+   please use 'The Linux kernel development community' for author attribution
+   and link this as source:
+   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/admin-guide/quickly-build-trimmed-linux.rst
+..
+   Note: Only the content of this RST file as found in the Linux kernel sources
+   is available under CC-BY-4.0, as versions of this text that were processed
+   (for example by the kernel's build system) might contain content taken from
+   files which use a more restrictive license.
+
index 7b481b2a368e7cbca173a665f339577dae1133f9..8e03751d126d01f6bed53b5f694f2c0a95c59893 100644 (file)
@@ -199,7 +199,7 @@ Architecture (MCA)\ [#f3]_.
   mode).
 
 .. [#f3] For more details about the Machine Check Architecture (MCA),
-  please read Documentation/x86/x86_64/machinecheck.rst at the Kernel tree.
+  please read Documentation/arch/x86/x86_64/machinecheck.rst at the Kernel tree.
 
 EDAC - Error Detection And Correction
 *************************************
index ec62151fe67209d28fe8b5043b80d042c35ad146..2fd5a030235ad05c72f4d167e5d56aaf280876d9 100644 (file)
@@ -395,7 +395,7 @@ might want to be aware of; it for example explains how to add your issue to the
 list of tracked regressions, to ensure it won't fall through the cracks.
 
 What qualifies as security issue is left to your judgment. Consider reading
-Documentation/admin-guide/security-bugs.rst before proceeding, as it
+Documentation/process/security-bugs.rst before proceeding, as it
 provides additional details how to best handle security issues.
 
 An issue is a 'really severe problem' when something totally unacceptably bad
@@ -1269,7 +1269,7 @@ them when sending the report by mail. If you filed it in a bug tracker, forward
 the report's text to these addresses; but on top of it put a small note where
 you mention that you filed it with a link to the ticket.
 
-See Documentation/admin-guide/security-bugs.rst for more information.
+See Documentation/process/security-bugs.rst for more information.
 
 
 Duties after the report went out
diff --git a/Documentation/admin-guide/security-bugs.rst b/Documentation/admin-guide/security-bugs.rst
deleted file mode 100644 (file)
index 82e2983..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-.. _securitybugs:
-
-Security bugs
-=============
-
-Linux kernel developers take security very seriously.  As such, we'd
-like to know when a security bug is found so that it can be fixed and
-disclosed as quickly as possible.  Please report security bugs to the
-Linux kernel security team.
-
-Contact
--------
-
-The Linux kernel security team can be contacted by email at
-<security@kernel.org>.  This is a private list of security officers
-who will help verify the bug report and develop and release a fix.
-If you already have a fix, please include it with your report, as
-that can speed up the process considerably.  It is possible that the
-security team will bring in extra help from area maintainers to
-understand and fix the security vulnerability.
-
-As it is with any bug, the more information provided the easier it
-will be to diagnose and fix.  Please review the procedure outlined in
-'Documentation/admin-guide/reporting-issues.rst' if you are unclear about what
-information is helpful.  Any exploit code is very helpful and will not
-be released without consent from the reporter unless it has already been
-made public.
-
-Please send plain text emails without attachments where possible.
-It is much harder to have a context-quoted discussion about a complex
-issue if all the details are hidden away in attachments.  Think of it like a
-:doc:`regular patch submission <../process/submitting-patches>`
-(even if you don't have a patch yet): describe the problem and impact, list
-reproduction steps, and follow it with a proposed fix, all in plain text.
-
-Disclosure and embargoed information
-------------------------------------
-
-The security list is not a disclosure channel.  For that, see Coordination
-below.
-
-Once a robust fix has been developed, the release process starts.  Fixes
-for publicly known bugs are released immediately.
-
-Although our preference is to release fixes for publicly undisclosed bugs
-as soon as they become available, this may be postponed at the request of
-the reporter or an affected party for up to 7 calendar days from the start
-of the release process, with an exceptional extension to 14 calendar days
-if it is agreed that the criticality of the bug requires more time.  The
-only valid reason for deferring the publication of a fix is to accommodate
-the logistics of QA and large scale rollouts which require release
-coordination.
-
-While embargoed information may be shared with trusted individuals in
-order to develop a fix, such information will not be published alongside
-the fix or on any other disclosure channel without the permission of the
-reporter.  This includes but is not limited to the original bug report
-and followup discussions (if any), exploits, CVE information or the
-identity of the reporter.
-
-In other words our only interest is in getting bugs fixed.  All other
-information submitted to the security list and any followup discussions
-of the report are treated confidentially even after the embargo has been
-lifted, in perpetuity.
-
-Coordination
-------------
-
-Fixes for sensitive bugs, such as those that might lead to privilege
-escalations, may need to be coordinated with the private
-<linux-distros@vs.openwall.org> mailing list so that distribution vendors
-are well prepared to issue a fixed kernel upon public disclosure of the
-upstream fix. Distros will need some time to test the proposed patch and
-will generally request at least a few days of embargo, and vendor update
-publication prefers to happen Tuesday through Thursday. When appropriate,
-the security team can assist with this coordination, or the reporter can
-include linux-distros from the start. In this case, remember to prefix
-the email Subject line with "[vs]" as described in the linux-distros wiki:
-<http://oss-security.openwall.org/wiki/mailing-lists/distros#how-to-use-the-lists>
-
-CVE assignment
---------------
-
-The security team does not normally assign CVEs, nor do we require them
-for reports or fixes, as this can needlessly complicate the process and
-may delay the bug handling. If a reporter wishes to have a CVE identifier
-assigned ahead of public disclosure, they will need to contact the private
-linux-distros list, described above. When such a CVE identifier is known
-before a patch is provided, it is desirable to mention it in the commit
-message if the reporter agrees.
-
-Non-disclosure agreements
--------------------------
-
-The Linux kernel security team is not a formal body and therefore unable
-to enter any non-disclosure agreements.
index 4b7bfea28cd770278556e73596b471ef476310f7..d85d90f5d000d863ebd6dc17c8f6422a333899ea 100644 (file)
@@ -95,7 +95,7 @@ is 0x15 and the full version number is 0x234, this file will contain
 the value 340 = 0x154.
 
 See the ``type_of_loader`` and ``ext_loader_type`` fields in
-Documentation/x86/boot.rst for additional information.
+Documentation/arch/x86/boot.rst for additional information.
 
 
 bootloader_version (x86 only)
@@ -105,7 +105,7 @@ The complete bootloader version number.  In the example above, this
 file will contain the value 564 = 0x234.
 
 See the ``type_of_loader`` and ``ext_loader_ver`` fields in
-Documentation/x86/boot.rst for additional information.
+Documentation/arch/x86/boot.rst for additional information.
 
 
 bpf_stats_enabled
index 290fe83ebe828525938878367f2a9e01cbb874da..cba7e5017d3683f8798029a9063b4ca260b30996 100644 (file)
@@ -3,11 +3,10 @@ Unicode support
 
                 Last update: 2005-01-17, version 1.4
 
-This file is maintained by H. Peter Anvin <unicode@lanana.org> as part
-of the Linux Assigned Names And Numbers Authority (LANANA) project.
-The current version can be found at:
-
-           http://www.lanana.org/docs/unicode/admin-guide/unicode.rst
+Note: The original version of this document, which was maintained at
+lanana.org as part of the Linux Assigned Names And Numbers Authority
+(LANANA) project, is no longer existent.  So, this version in the
+mainline Linux kernel is now the maintained main document.
 
 Introduction
 ------------
diff --git a/Documentation/arc/arc.rst b/Documentation/arc/arc.rst
deleted file mode 100644 (file)
index 6c4d978..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Linux kernel for ARC processors
-*******************************
-
-Other sources of information
-############################
-
-Below are some resources where more information can be found on
-ARC processors and relevant open source projects.
-
-- `<https://embarc.org>`_ - Community portal for open source on ARC.
-  Good place to start to find relevant FOSS projects, toolchain releases,
-  news items and more.
-
-- `<https://github.com/foss-for-synopsys-dwc-arc-processors>`_ -
-  Home for all development activities regarding open source projects for
-  ARC processors. Some of the projects are forks of various upstream projects,
-  where "work in progress" is hosted prior to submission to upstream projects.
-  Other projects are developed by Synopsys and made available to community
-  as open source for use on ARC Processors.
-
-- `Official Synopsys ARC Processors website
-  <https://www.synopsys.com/designware-ip/processor-solutions.html>`_ -
-  location, with access to some IP documentation (`Programmer's Reference
-  Manual, AKA PRM for ARC HS processors
-  <https://www.synopsys.com/dw/doc.php/ds/cc/programmers-reference-manual-ARC-HS.pdf>`_)
-  and free versions of some commercial tools (`Free nSIM
-  <https://www.synopsys.com/cgi-bin/dwarcnsim/req1.cgi>`_ and
-  `MetaWare Light Edition <https://www.synopsys.com/cgi-bin/arcmwtk_lite/reg1.cgi>`_).
-  Please note though, registration is required to access both the documentation and
-  the tools.
-
-Important note on ARC processors configurability
-################################################
-
-ARC processors are highly configurable and several configurable options
-are supported in Linux. Some options are transparent to software
-(i.e cache geometries, some can be detected at runtime and configured
-and used accordingly, while some need to be explicitly selected or configured
-in the kernel's configuration utility (AKA "make menuconfig").
-
-However not all configurable options are supported when an ARC processor
-is to run Linux. SoC design teams should refer to "Appendix E:
-Configuration for ARC Linux" in the ARC HS Databook for configurability
-guidelines.
-
-Following these guidelines and selecting valid configuration options
-up front is critical to help prevent any unwanted issues during
-SoC bringup and software development in general.
-
-Building the Linux kernel for ARC processors
-############################################
-
-The process of kernel building for ARC processors is the same as for any other
-architecture and could be done in 2 ways:
-
-- Cross-compilation: process of compiling for ARC targets on a development
-  host with a different processor architecture (generally x86_64/amd64).
-- Native compilation: process of compiling for ARC on a ARC platform
-  (hardware board or a simulator like QEMU) with complete development environment
-  (GNU toolchain, dtc, make etc) installed on the platform.
-
-In both cases, up-to-date GNU toolchain for ARC for the host is needed.
-Synopsys offers prebuilt toolchain releases which can be used for this purpose,
-available from:
-
-- Synopsys GNU toolchain releases:
-  `<https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/releases>`_
-
-- Linux kernel compilers collection:
-  `<https://mirrors.edge.kernel.org/pub/tools/crosstool>`_
-
-- Bootlin's toolchain collection: `<https://toolchains.bootlin.com>`_
-
-Once the toolchain is installed in the system, make sure its "bin" folder
-is added in your ``PATH`` environment variable. Then set ``ARCH=arc`` &
-``CROSS_COMPILE=arc-linux`` (or whatever matches installed ARC toolchain prefix)
-and then as usual ``make defconfig && make``.
-
-This will produce "vmlinux" file in the root of the kernel source tree
-usable for loading on the target system via JTAG.
-If you need to get an image usable with U-Boot bootloader,
-type ``make uImage`` and ``uImage`` will be produced in ``arch/arc/boot``
-folder.
diff --git a/Documentation/arc/features.rst b/Documentation/arc/features.rst
deleted file mode 100644 (file)
index b793583..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. kernel-feat:: $srctree/Documentation/features arc
diff --git a/Documentation/arc/index.rst b/Documentation/arc/index.rst
deleted file mode 100644 (file)
index 7b098d4..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-===================
-ARC architecture
-===================
-
-.. toctree::
-    :maxdepth: 1
-
-    arc
-
-    features
-
-.. only::  subproject and html
-
-   Indices
-   =======
-
-   * :ref:`genindex`
diff --git a/Documentation/arch.rst b/Documentation/arch.rst
deleted file mode 100644 (file)
index 41a66a8..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-CPU Architectures
-=================
-
-These books provide programming details about architecture-specific
-implementation.
-
-.. toctree::
-   :maxdepth: 2
-
-   arc/index
-   arm/index
-   arm64/index
-   ia64/index
-   loongarch/index
-   m68k/index
-   mips/index
-   nios2/index
-   openrisc/index
-   parisc/index
-   powerpc/index
-   riscv/index
-   s390/index
-   sh/index
-   sparc/index
-   x86/index
-   xtensa/index
diff --git a/Documentation/arch/arc/arc.rst b/Documentation/arch/arc/arc.rst
new file mode 100644 (file)
index 0000000..6c4d978
--- /dev/null
@@ -0,0 +1,85 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Linux kernel for ARC processors
+*******************************
+
+Other sources of information
+############################
+
+Below are some resources where more information can be found on
+ARC processors and relevant open source projects.
+
+- `<https://embarc.org>`_ - Community portal for open source on ARC.
+  Good place to start to find relevant FOSS projects, toolchain releases,
+  news items and more.
+
+- `<https://github.com/foss-for-synopsys-dwc-arc-processors>`_ -
+  Home for all development activities regarding open source projects for
+  ARC processors. Some of the projects are forks of various upstream projects,
+  where "work in progress" is hosted prior to submission to upstream projects.
+  Other projects are developed by Synopsys and made available to community
+  as open source for use on ARC Processors.
+
+- `Official Synopsys ARC Processors website
+  <https://www.synopsys.com/designware-ip/processor-solutions.html>`_ -
+  location, with access to some IP documentation (`Programmer's Reference
+  Manual, AKA PRM for ARC HS processors
+  <https://www.synopsys.com/dw/doc.php/ds/cc/programmers-reference-manual-ARC-HS.pdf>`_)
+  and free versions of some commercial tools (`Free nSIM
+  <https://www.synopsys.com/cgi-bin/dwarcnsim/req1.cgi>`_ and
+  `MetaWare Light Edition <https://www.synopsys.com/cgi-bin/arcmwtk_lite/reg1.cgi>`_).
+  Please note though, registration is required to access both the documentation and
+  the tools.
+
+Important note on ARC processors configurability
+################################################
+
+ARC processors are highly configurable and several configurable options
+are supported in Linux. Some options are transparent to software
+(i.e cache geometries, some can be detected at runtime and configured
+and used accordingly, while some need to be explicitly selected or configured
+in the kernel's configuration utility (AKA "make menuconfig").
+
+However not all configurable options are supported when an ARC processor
+is to run Linux. SoC design teams should refer to "Appendix E:
+Configuration for ARC Linux" in the ARC HS Databook for configurability
+guidelines.
+
+Following these guidelines and selecting valid configuration options
+up front is critical to help prevent any unwanted issues during
+SoC bringup and software development in general.
+
+Building the Linux kernel for ARC processors
+############################################
+
+The process of kernel building for ARC processors is the same as for any other
+architecture and could be done in 2 ways:
+
+- Cross-compilation: process of compiling for ARC targets on a development
+  host with a different processor architecture (generally x86_64/amd64).
+- Native compilation: process of compiling for ARC on a ARC platform
+  (hardware board or a simulator like QEMU) with complete development environment
+  (GNU toolchain, dtc, make etc) installed on the platform.
+
+In both cases, up-to-date GNU toolchain for ARC for the host is needed.
+Synopsys offers prebuilt toolchain releases which can be used for this purpose,
+available from:
+
+- Synopsys GNU toolchain releases:
+  `<https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/releases>`_
+
+- Linux kernel compilers collection:
+  `<https://mirrors.edge.kernel.org/pub/tools/crosstool>`_
+
+- Bootlin's toolchain collection: `<https://toolchains.bootlin.com>`_
+
+Once the toolchain is installed in the system, make sure its "bin" folder
+is added in your ``PATH`` environment variable. Then set ``ARCH=arc`` &
+``CROSS_COMPILE=arc-linux`` (or whatever matches installed ARC toolchain prefix)
+and then as usual ``make defconfig && make``.
+
+This will produce "vmlinux" file in the root of the kernel source tree
+usable for loading on the target system via JTAG.
+If you need to get an image usable with U-Boot bootloader,
+type ``make uImage`` and ``uImage`` will be produced in ``arch/arc/boot``
+folder.
diff --git a/Documentation/arch/arc/features.rst b/Documentation/arch/arc/features.rst
new file mode 100644 (file)
index 0000000..b793583
--- /dev/null
@@ -0,0 +1,3 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. kernel-feat:: $srctree/Documentation/features arc
diff --git a/Documentation/arch/arc/index.rst b/Documentation/arch/arc/index.rst
new file mode 100644 (file)
index 0000000..7b098d4
--- /dev/null
@@ -0,0 +1,17 @@
+===================
+ARC architecture
+===================
+
+.. toctree::
+    :maxdepth: 1
+
+    arc
+
+    features
+
+.. only::  subproject and html
+
+   Indices
+   =======
+
+   * :ref:`genindex`
diff --git a/Documentation/arch/ia64/aliasing.rst b/Documentation/arch/ia64/aliasing.rst
new file mode 100644 (file)
index 0000000..36a1e1d
--- /dev/null
@@ -0,0 +1,246 @@
+==================================
+Memory Attribute Aliasing on IA-64
+==================================
+
+Bjorn Helgaas <bjorn.helgaas@hp.com>
+
+May 4, 2006
+
+
+Memory Attributes
+=================
+
+    Itanium supports several attributes for virtual memory references.
+    The attribute is part of the virtual translation, i.e., it is
+    contained in the TLB entry.  The ones of most interest to the Linux
+    kernel are:
+
+       ==              ======================
+        WB             Write-back (cacheable)
+       UC              Uncacheable
+       WC              Write-coalescing
+       ==              ======================
+
+    System memory typically uses the WB attribute.  The UC attribute is
+    used for memory-mapped I/O devices.  The WC attribute is uncacheable
+    like UC is, but writes may be delayed and combined to increase
+    performance for things like frame buffers.
+
+    The Itanium architecture requires that we avoid accessing the same
+    page with both a cacheable mapping and an uncacheable mapping[1].
+
+    The design of the chipset determines which attributes are supported
+    on which regions of the address space.  For example, some chipsets
+    support either WB or UC access to main memory, while others support
+    only WB access.
+
+Memory Map
+==========
+
+    Platform firmware describes the physical memory map and the
+    supported attributes for each region.  At boot-time, the kernel uses
+    the EFI GetMemoryMap() interface.  ACPI can also describe memory
+    devices and the attributes they support, but Linux/ia64 currently
+    doesn't use this information.
+
+    The kernel uses the efi_memmap table returned from GetMemoryMap() to
+    learn the attributes supported by each region of physical address
+    space.  Unfortunately, this table does not completely describe the
+    address space because some machines omit some or all of the MMIO
+    regions from the map.
+
+    The kernel maintains another table, kern_memmap, which describes the
+    memory Linux is actually using and the attribute for each region.
+    This contains only system memory; it does not contain MMIO space.
+
+    The kern_memmap table typically contains only a subset of the system
+    memory described by the efi_memmap.  Linux/ia64 can't use all memory
+    in the system because of constraints imposed by the identity mapping
+    scheme.
+
+    The efi_memmap table is preserved unmodified because the original
+    boot-time information is required for kexec.
+
+Kernel Identity Mappings
+========================
+
+    Linux/ia64 identity mappings are done with large pages, currently
+    either 16MB or 64MB, referred to as "granules."  Cacheable mappings
+    are speculative[2], so the processor can read any location in the
+    page at any time, independent of the programmer's intentions.  This
+    means that to avoid attribute aliasing, Linux can create a cacheable
+    identity mapping only when the entire granule supports cacheable
+    access.
+
+    Therefore, kern_memmap contains only full granule-sized regions that
+    can referenced safely by an identity mapping.
+
+    Uncacheable mappings are not speculative, so the processor will
+    generate UC accesses only to locations explicitly referenced by
+    software.  This allows UC identity mappings to cover granules that
+    are only partially populated, or populated with a combination of UC
+    and WB regions.
+
+User Mappings
+=============
+
+    User mappings are typically done with 16K or 64K pages.  The smaller
+    page size allows more flexibility because only 16K or 64K has to be
+    homogeneous with respect to memory attributes.
+
+Potential Attribute Aliasing Cases
+==================================
+
+    There are several ways the kernel creates new mappings:
+
+mmap of /dev/mem
+----------------
+
+       This uses remap_pfn_range(), which creates user mappings.  These
+       mappings may be either WB or UC.  If the region being mapped
+       happens to be in kern_memmap, meaning that it may also be mapped
+       by a kernel identity mapping, the user mapping must use the same
+       attribute as the kernel mapping.
+
+       If the region is not in kern_memmap, the user mapping should use
+       an attribute reported as being supported in the EFI memory map.
+
+       Since the EFI memory map does not describe MMIO on some
+       machines, this should use an uncacheable mapping as a fallback.
+
+mmap of /sys/class/pci_bus/.../legacy_mem
+-----------------------------------------
+
+       This is very similar to mmap of /dev/mem, except that legacy_mem
+       only allows mmap of the one megabyte "legacy MMIO" area for a
+       specific PCI bus.  Typically this is the first megabyte of
+       physical address space, but it may be different on machines with
+       several VGA devices.
+
+       "X" uses this to access VGA frame buffers.  Using legacy_mem
+       rather than /dev/mem allows multiple instances of X to talk to
+       different VGA cards.
+
+       The /dev/mem mmap constraints apply.
+
+mmap of /proc/bus/pci/.../??.?
+------------------------------
+
+       This is an MMIO mmap of PCI functions, which additionally may or
+       may not be requested as using the WC attribute.
+
+       If WC is requested, and the region in kern_memmap is either WC
+       or UC, and the EFI memory map designates the region as WC, then
+       the WC mapping is allowed.
+
+       Otherwise, the user mapping must use the same attribute as the
+       kernel mapping.
+
+read/write of /dev/mem
+----------------------
+
+       This uses copy_from_user(), which implicitly uses a kernel
+       identity mapping.  This is obviously safe for things in
+       kern_memmap.
+
+       There may be corner cases of things that are not in kern_memmap,
+       but could be accessed this way.  For example, registers in MMIO
+       space are not in kern_memmap, but could be accessed with a UC
+       mapping.  This would not cause attribute aliasing.  But
+       registers typically can be accessed only with four-byte or
+       eight-byte accesses, and the copy_from_user() path doesn't allow
+       any control over the access size, so this would be dangerous.
+
+ioremap()
+---------
+
+       This returns a mapping for use inside the kernel.
+
+       If the region is in kern_memmap, we should use the attribute
+       specified there.
+
+       If the EFI memory map reports that the entire granule supports
+       WB, we should use that (granules that are partially reserved
+       or occupied by firmware do not appear in kern_memmap).
+
+       If the granule contains non-WB memory, but we can cover the
+       region safely with kernel page table mappings, we can use
+       ioremap_page_range() as most other architectures do.
+
+       Failing all of the above, we have to fall back to a UC mapping.
+
+Past Problem Cases
+==================
+
+mmap of various MMIO regions from /dev/mem by "X" on Intel platforms
+--------------------------------------------------------------------
+
+      The EFI memory map may not report these MMIO regions.
+
+      These must be allowed so that X will work.  This means that
+      when the EFI memory map is incomplete, every /dev/mem mmap must
+      succeed.  It may create either WB or UC user mappings, depending
+      on whether the region is in kern_memmap or the EFI memory map.
+
+mmap of 0x0-0x9FFFF /dev/mem by "hwinfo" on HP sx1000 with VGA enabled
+----------------------------------------------------------------------
+
+      The EFI memory map reports the following attributes:
+
+        =============== ======= ==================
+        0x00000-0x9FFFF WB only
+        0xA0000-0xBFFFF UC only (VGA frame buffer)
+        0xC0000-0xFFFFF WB only
+        =============== ======= ==================
+
+      This mmap is done with user pages, not kernel identity mappings,
+      so it is safe to use WB mappings.
+
+      The kernel VGA driver may ioremap the VGA frame buffer at 0xA0000,
+      which uses a granule-sized UC mapping.  This granule will cover some
+      WB-only memory, but since UC is non-speculative, the processor will
+      never generate an uncacheable reference to the WB-only areas unless
+      the driver explicitly touches them.
+
+mmap of 0x0-0xFFFFF legacy_mem by "X"
+-------------------------------------
+
+      If the EFI memory map reports that the entire range supports the
+      same attributes, we can allow the mmap (and we will prefer WB if
+      supported, as is the case with HP sx[12]000 machines with VGA
+      disabled).
+
+      If EFI reports the range as partly WB and partly UC (as on sx[12]000
+      machines with VGA enabled), we must fail the mmap because there's no
+      safe attribute to use.
+
+      If EFI reports some of the range but not all (as on Intel firmware
+      that doesn't report the VGA frame buffer at all), we should fail the
+      mmap and force the user to map just the specific region of interest.
+
+mmap of 0xA0000-0xBFFFF legacy_mem by "X" on HP sx1000 with VGA disabled
+------------------------------------------------------------------------
+
+      The EFI memory map reports the following attributes::
+
+        0x00000-0xFFFFF WB only (no VGA MMIO hole)
+
+      This is a special case of the previous case, and the mmap should
+      fail for the same reason as above.
+
+read of /sys/devices/.../rom
+----------------------------
+
+      For VGA devices, this may cause an ioremap() of 0xC0000.  This
+      used to be done with a UC mapping, because the VGA frame buffer
+      at 0xA0000 prevents use of a WB granule.  The UC mapping causes
+      an MCA on HP sx[12]000 chipsets.
+
+      We should use WB page table mappings to avoid covering the VGA
+      frame buffer.
+
+Notes
+=====
+
+    [1] SDM rev 2.2, vol 2, sec 4.4.1.
+    [2] SDM rev 2.2, vol 2, sec 4.4.6.
diff --git a/Documentation/arch/ia64/efirtc.rst b/Documentation/arch/ia64/efirtc.rst
new file mode 100644 (file)
index 0000000..fd83284
--- /dev/null
@@ -0,0 +1,144 @@
+==========================
+EFI Real Time Clock driver
+==========================
+
+S. Eranian <eranian@hpl.hp.com>
+
+March 2000
+
+1. Introduction
+===============
+
+This document describes the efirtc.c driver has provided for
+the IA-64 platform.
+
+The purpose of this driver is to supply an API for kernel and user applications
+to get access to the Time Service offered by EFI version 0.92.
+
+EFI provides 4 calls one can make once the OS is booted: GetTime(),
+SetTime(), GetWakeupTime(), SetWakeupTime() which are all supported by this
+driver. We describe those calls as well the design of the driver in the
+following sections.
+
+2. Design Decisions
+===================
+
+The original ideas was to provide a very simple driver to get access to,
+at first, the time of day service. This is required in order to access, in a
+portable way, the CMOS clock. A program like /sbin/hwclock uses such a clock
+to initialize the system view of the time during boot.
+
+Because we wanted to minimize the impact on existing user-level apps using
+the CMOS clock, we decided to expose an API that was very similar to the one
+used today with the legacy RTC driver (driver/char/rtc.c). However, because
+EFI provides a simpler services, not all ioctl() are available. Also
+new ioctl()s have been introduced for things that EFI provides but not the
+legacy.
+
+EFI uses a slightly different way of representing the time, noticeably
+the reference date is different. Year is the using the full 4-digit format.
+The Epoch is January 1st 1998. For backward compatibility reasons we don't
+expose this new way of representing time. Instead we use something very
+similar to the struct tm, i.e. struct rtc_time, as used by hwclock.
+One of the reasons for doing it this way is to allow for EFI to still evolve
+without necessarily impacting any of the user applications. The decoupling
+enables flexibility and permits writing wrapper code is ncase things change.
+
+The driver exposes two interfaces, one via the device file and a set of
+ioctl()s. The other is read-only via the /proc filesystem.
+
+As of today we don't offer a /proc/sys interface.
+
+To allow for a uniform interface between the legacy RTC and EFI time service,
+we have created the include/linux/rtc.h header file to contain only the
+"public" API of the two drivers.  The specifics of the legacy RTC are still
+in include/linux/mc146818rtc.h.
+
+
+3. Time of day service
+======================
+
+The part of the driver gives access to the time of day service of EFI.
+Two ioctl()s, compatible with the legacy RTC calls:
+
+       Read the CMOS clock::
+
+               ioctl(d, RTC_RD_TIME, &rtc);
+
+       Write the CMOS clock::
+
+               ioctl(d, RTC_SET_TIME, &rtc);
+
+The rtc is a pointer to a data structure defined in rtc.h which is close
+to a struct tm::
+
+  struct rtc_time {
+          int tm_sec;
+          int tm_min;
+          int tm_hour;
+          int tm_mday;
+          int tm_mon;
+          int tm_year;
+          int tm_wday;
+          int tm_yday;
+          int tm_isdst;
+  };
+
+The driver takes care of converting back an forth between the EFI time and
+this format.
+
+Those two ioctl()s can be exercised with the hwclock command:
+
+For reading::
+
+       # /sbin/hwclock --show
+       Mon Mar  6 15:32:32 2000  -0.910248 seconds
+
+For setting::
+
+       # /sbin/hwclock --systohc
+
+Root privileges are required to be able to set the time of day.
+
+4. Wakeup Alarm service
+=======================
+
+EFI provides an API by which one can program when a machine should wakeup,
+i.e. reboot. This is very different from the alarm provided by the legacy
+RTC which is some kind of interval timer alarm. For this reason we don't use
+the same ioctl()s to get access to the service. Instead we have
+introduced 2 news ioctl()s to the interface of an RTC.
+
+We have added 2 new ioctl()s that are specific to the EFI driver:
+
+       Read the current state of the alarm::
+
+               ioctl(d, RTC_WKALM_RD, &wkt)
+
+       Set the alarm or change its status::
+
+               ioctl(d, RTC_WKALM_SET, &wkt)
+
+The wkt structure encapsulates a struct rtc_time + 2 extra fields to get
+status information::
+
+  struct rtc_wkalrm {
+
+          unsigned char enabled; /* =1 if alarm is enabled */
+          unsigned char pending; /* =1 if alarm is pending  */
+
+          struct rtc_time time;
+  }
+
+As of today, none of the existing user-level apps supports this feature.
+However writing such a program should be hard by simply using those two
+ioctl().
+
+Root privileges are required to be able to set the alarm.
+
+5. References
+=============
+
+Checkout the following Web site for more information on EFI:
+
+http://developer.intel.com/technology/efi/
diff --git a/Documentation/arch/ia64/err_inject.rst b/Documentation/arch/ia64/err_inject.rst
new file mode 100644 (file)
index 0000000..900f71e
--- /dev/null
@@ -0,0 +1,1067 @@
+========================================
+IPF Machine Check (MC) error inject tool
+========================================
+
+IPF Machine Check (MC) error inject tool is used to inject MC
+errors from Linux. The tool is a test bed for IPF MC work flow including
+hardware correctable error handling, OS recoverable error handling, MC
+event logging, etc.
+
+The tool includes two parts: a kernel driver and a user application
+sample. The driver provides interface to PAL to inject error
+and query error injection capabilities. The driver code is in
+arch/ia64/kernel/err_inject.c. The application sample (shown below)
+provides a combination of various errors and calls the driver's interface
+(sysfs interface) to inject errors or query error injection capabilities.
+
+The tool can be used to test Intel IPF machine MC handling capabilities.
+It's especially useful for people who can not access hardware MC injection
+tool to inject error. It's also very useful to integrate with other
+software test suits to do stressful testing on IPF.
+
+Below is a sample application as part of the whole tool. The sample
+can be used as a working test tool. Or it can be expanded to include
+more features. It also can be a integrated into a library or other user
+application to have more thorough test.
+
+The sample application takes err.conf as error configuration input. GCC
+compiles the code. After you install err_inject driver, you can run
+this sample application to inject errors.
+
+Errata: Itanium 2 Processors Specification Update lists some errata against
+the pal_mc_error_inject PAL procedure. The following err.conf has been tested
+on latest Montecito PAL.
+
+err.conf::
+
+  #This is configuration file for err_inject_tool.
+  #The format of the each line is:
+  #cpu, loop, interval, err_type_info, err_struct_info, err_data_buffer
+  #where
+  #    cpu: logical cpu number the error will be inject in.
+  #    loop: times the error will be injected.
+  #    interval: In second. every so often one error is injected.
+  #    err_type_info, err_struct_info: PAL parameters.
+  #
+  #Note: All values are hex w/o or w/ 0x prefix.
+
+
+  #On cpu2, inject only total 0x10 errors, interval 5 seconds
+  #corrected, data cache, hier-2, physical addr(assigned by tool code).
+  #working on Montecito latest PAL.
+  2, 10, 5, 4101, 95
+
+  #On cpu4, inject and consume total 0x10 errors, interval 5 seconds
+  #corrected, data cache, hier-2, physical addr(assigned by tool code).
+  #working on Montecito latest PAL.
+  4, 10, 5, 4109, 95
+
+  #On cpu15, inject and consume total 0x10 errors, interval 5 seconds
+  #recoverable, DTR0, hier-2.
+  #working on Montecito latest PAL.
+  0xf, 0x10, 5, 4249, 15
+
+The sample application source code:
+
+err_injection_tool.c::
+
+  /*
+   * This program is free software; you can redistribute it and/or modify
+   * it under the terms of the GNU General Public License as published by
+   * the Free Software Foundation; either version 2 of the License, or
+   * (at your option) any later version.
+   *
+   * This program is distributed in the hope that it will be useful, but
+   * WITHOUT ANY WARRANTY; without even the implied warranty of
+   * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+   * NON INFRINGEMENT.  See the GNU General Public License for more
+   * details.
+   *
+   * You should have received a copy of the GNU General Public License
+   * along with this program; if not, write to the Free Software
+   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   *
+   * Copyright (C) 2006 Intel Co
+   *   Fenghua Yu <fenghua.yu@intel.com>
+   *
+   */
+  #include <sys/types.h>
+  #include <sys/stat.h>
+  #include <fcntl.h>
+  #include <stdio.h>
+  #include <sched.h>
+  #include <unistd.h>
+  #include <stdlib.h>
+  #include <stdarg.h>
+  #include <string.h>
+  #include <errno.h>
+  #include <time.h>
+  #include <sys/ipc.h>
+  #include <sys/sem.h>
+  #include <sys/wait.h>
+  #include <sys/mman.h>
+  #include <sys/shm.h>
+
+  #define MAX_FN_SIZE          256
+  #define MAX_BUF_SIZE                 256
+  #define DATA_BUF_SIZE                256
+  #define NR_CPUS              512
+  #define MAX_TASK_NUM         2048
+  #define MIN_INTERVAL         5       // seconds
+  #define      ERR_DATA_BUFFER_SIZE    3       // Three 8-byte.
+  #define PARA_FIELD_NUM               5
+  #define MASK_SIZE            (NR_CPUS/64)
+  #define PATH_FORMAT "/sys/devices/system/cpu/cpu%d/err_inject/"
+
+  int sched_setaffinity(pid_t pid, unsigned int len, unsigned long *mask);
+
+  int verbose;
+  #define vbprintf if (verbose) printf
+
+  int log_info(int cpu, const char *fmt, ...)
+  {
+       FILE *log;
+       char fn[MAX_FN_SIZE];
+       char buf[MAX_BUF_SIZE];
+       va_list args;
+
+       sprintf(fn, "%d.log", cpu);
+       log=fopen(fn, "a+");
+       if (log==NULL) {
+               perror("Error open:");
+               return -1;
+       }
+
+       va_start(args, fmt);
+       vprintf(fmt, args);
+       memset(buf, 0, MAX_BUF_SIZE);
+       vsprintf(buf, fmt, args);
+       va_end(args);
+
+       fwrite(buf, sizeof(buf), 1, log);
+       fclose(log);
+
+       return 0;
+  }
+
+  typedef unsigned long u64;
+  typedef unsigned int  u32;
+
+  typedef union err_type_info_u {
+       struct {
+               u64     mode            : 3,    /* 0-2 */
+                       err_inj         : 3,    /* 3-5 */
+                       err_sev         : 2,    /* 6-7 */
+                       err_struct      : 5,    /* 8-12 */
+                       struct_hier     : 3,    /* 13-15 */
+                       reserved        : 48;   /* 16-63 */
+       } err_type_info_u;
+       u64     err_type_info;
+  } err_type_info_t;
+
+  typedef union err_struct_info_u {
+       struct {
+               u64     siv             : 1,    /* 0     */
+                       c_t             : 2,    /* 1-2   */
+                       cl_p            : 3,    /* 3-5   */
+                       cl_id           : 3,    /* 6-8   */
+                       cl_dp           : 1,    /* 9     */
+                       reserved1       : 22,   /* 10-31 */
+                       tiv             : 1,    /* 32    */
+                       trigger         : 4,    /* 33-36 */
+                       trigger_pl      : 3,    /* 37-39 */
+                       reserved2       : 24;   /* 40-63 */
+       } err_struct_info_cache;
+       struct {
+               u64     siv             : 1,    /* 0     */
+                       tt              : 2,    /* 1-2   */
+                       tc_tr           : 2,    /* 3-4   */
+                       tr_slot         : 8,    /* 5-12  */
+                       reserved1       : 19,   /* 13-31 */
+                       tiv             : 1,    /* 32    */
+                       trigger         : 4,    /* 33-36 */
+                       trigger_pl      : 3,    /* 37-39 */
+                       reserved2       : 24;   /* 40-63 */
+       } err_struct_info_tlb;
+       struct {
+               u64     siv             : 1,    /* 0     */
+                       regfile_id      : 4,    /* 1-4   */
+                       reg_num         : 7,    /* 5-11  */
+                       reserved1       : 20,   /* 12-31 */
+                       tiv             : 1,    /* 32    */
+                       trigger         : 4,    /* 33-36 */
+                       trigger_pl      : 3,    /* 37-39 */
+                       reserved2       : 24;   /* 40-63 */
+       } err_struct_info_register;
+       struct {
+               u64     reserved;
+       } err_struct_info_bus_processor_interconnect;
+       u64     err_struct_info;
+  } err_struct_info_t;
+
+  typedef union err_data_buffer_u {
+       struct {
+               u64     trigger_addr;           /* 0-63         */
+               u64     inj_addr;               /* 64-127       */
+               u64     way             : 5,    /* 128-132      */
+                       index           : 20,   /* 133-152      */
+                                       : 39;   /* 153-191      */
+       } err_data_buffer_cache;
+       struct {
+               u64     trigger_addr;           /* 0-63         */
+               u64     inj_addr;               /* 64-127       */
+               u64     way             : 5,    /* 128-132      */
+                       index           : 20,   /* 133-152      */
+                       reserved        : 39;   /* 153-191      */
+       } err_data_buffer_tlb;
+       struct {
+               u64     trigger_addr;           /* 0-63         */
+       } err_data_buffer_register;
+       struct {
+               u64     reserved;               /* 0-63         */
+       } err_data_buffer_bus_processor_interconnect;
+       u64 err_data_buffer[ERR_DATA_BUFFER_SIZE];
+  } err_data_buffer_t;
+
+  typedef union capabilities_u {
+       struct {
+               u64     i               : 1,
+                       d               : 1,
+                       rv              : 1,
+                       tag             : 1,
+                       data            : 1,
+                       mesi            : 1,
+                       dp              : 1,
+                       reserved1       : 3,
+                       pa              : 1,
+                       va              : 1,
+                       wi              : 1,
+                       reserved2       : 20,
+                       trigger         : 1,
+                       trigger_pl      : 1,
+                       reserved3       : 30;
+       } capabilities_cache;
+       struct {
+               u64     d               : 1,
+                       i               : 1,
+                       rv              : 1,
+                       tc              : 1,
+                       tr              : 1,
+                       reserved1       : 27,
+                       trigger         : 1,
+                       trigger_pl      : 1,
+                       reserved2       : 30;
+       } capabilities_tlb;
+       struct {
+               u64     gr_b0           : 1,
+                       gr_b1           : 1,
+                       fr              : 1,
+                       br              : 1,
+                       pr              : 1,
+                       ar              : 1,
+                       cr              : 1,
+                       rr              : 1,
+                       pkr             : 1,
+                       dbr             : 1,
+                       ibr             : 1,
+                       pmc             : 1,
+                       pmd             : 1,
+                       reserved1       : 3,
+                       regnum          : 1,
+                       reserved2       : 15,
+                       trigger         : 1,
+                       trigger_pl      : 1,
+                       reserved3       : 30;
+       } capabilities_register;
+       struct {
+               u64     reserved;
+       } capabilities_bus_processor_interconnect;
+  } capabilities_t;
+
+  typedef struct resources_s {
+       u64     ibr0            : 1,
+               ibr2            : 1,
+               ibr4            : 1,
+               ibr6            : 1,
+               dbr0            : 1,
+               dbr2            : 1,
+               dbr4            : 1,
+               dbr6            : 1,
+               reserved        : 48;
+  } resources_t;
+
+
+  long get_page_size(void)
+  {
+       long page_size=sysconf(_SC_PAGESIZE);
+       return page_size;
+  }
+
+  #define PAGE_SIZE (get_page_size()==-1?0x4000:get_page_size())
+  #define SHM_SIZE (2*PAGE_SIZE*NR_CPUS)
+  #define SHM_VA 0x2000000100000000
+
+  int shmid;
+  void *shmaddr;
+
+  int create_shm(void)
+  {
+       key_t key;
+       char fn[MAX_FN_SIZE];
+
+       /* cpu0 is always existing */
+       sprintf(fn, PATH_FORMAT, 0);
+       if ((key = ftok(fn, 's')) == -1) {
+               perror("ftok");
+               return -1;
+       }
+
+       shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT);
+       if (shmid == -1) {
+               if (errno==EEXIST) {
+                       shmid = shmget(key, SHM_SIZE, 0);
+                       if (shmid == -1) {
+                               perror("shmget");
+                               return -1;
+                       }
+               }
+               else {
+                       perror("shmget");
+                       return -1;
+               }
+       }
+       vbprintf("shmid=%d", shmid);
+
+       /* connect to the segment: */
+       shmaddr = shmat(shmid, (void *)SHM_VA, 0);
+       if (shmaddr == (void*)-1) {
+               perror("shmat");
+               return -1;
+       }
+
+       memset(shmaddr, 0, SHM_SIZE);
+       mlock(shmaddr, SHM_SIZE);
+
+       return 0;
+  }
+
+  int free_shm()
+  {
+       munlock(shmaddr, SHM_SIZE);
+          shmdt(shmaddr);
+       semctl(shmid, 0, IPC_RMID);
+
+       return 0;
+  }
+
+  #ifdef _SEM_SEMUN_UNDEFINED
+  union semun
+  {
+       int val;
+       struct semid_ds *buf;
+       unsigned short int *array;
+       struct seminfo *__buf;
+  };
+  #endif
+
+  u32 mode=1; /* 1: physical mode; 2: virtual mode. */
+  int one_lock=1;
+  key_t key[NR_CPUS];
+  int semid[NR_CPUS];
+
+  int create_sem(int cpu)
+  {
+       union semun arg;
+       char fn[MAX_FN_SIZE];
+       int sid;
+
+       sprintf(fn, PATH_FORMAT, cpu);
+       sprintf(fn, "%s/%s", fn, "err_type_info");
+       if ((key[cpu] = ftok(fn, 'e')) == -1) {
+               perror("ftok");
+               return -1;
+       }
+
+       if (semid[cpu]!=0)
+               return 0;
+
+       /* clear old semaphore */
+       if ((sid = semget(key[cpu], 1, 0)) != -1)
+               semctl(sid, 0, IPC_RMID);
+
+       /* get one semaphore */
+       if ((semid[cpu] = semget(key[cpu], 1, IPC_CREAT | IPC_EXCL)) == -1) {
+               perror("semget");
+               printf("Please remove semaphore with key=0x%lx, then run the tool.\n",
+                       (u64)key[cpu]);
+               return -1;
+       }
+
+       vbprintf("semid[%d]=0x%lx, key[%d]=%lx\n",cpu,(u64)semid[cpu],cpu,
+               (u64)key[cpu]);
+       /* initialize the semaphore to 1: */
+       arg.val = 1;
+       if (semctl(semid[cpu], 0, SETVAL, arg) == -1) {
+               perror("semctl");
+               return -1;
+       }
+
+       return 0;
+  }
+
+  static int lock(int cpu)
+  {
+       struct sembuf lock;
+
+       lock.sem_num = cpu;
+       lock.sem_op = 1;
+       semop(semid[cpu], &lock, 1);
+
+          return 0;
+  }
+
+  static int unlock(int cpu)
+  {
+       struct sembuf unlock;
+
+       unlock.sem_num = cpu;
+       unlock.sem_op = -1;
+       semop(semid[cpu], &unlock, 1);
+
+          return 0;
+  }
+
+  void free_sem(int cpu)
+  {
+       semctl(semid[cpu], 0, IPC_RMID);
+  }
+
+  int wr_multi(char *fn, unsigned long *data, int size)
+  {
+       int fd;
+       char buf[MAX_BUF_SIZE];
+       int ret;
+
+       if (size==1)
+               sprintf(buf, "%lx", *data);
+       else if (size==3)
+               sprintf(buf, "%lx,%lx,%lx", data[0], data[1], data[2]);
+       else {
+               fprintf(stderr,"write to file with wrong size!\n");
+               return -1;
+       }
+
+       fd=open(fn, O_RDWR);
+       if (!fd) {
+               perror("Error:");
+               return -1;
+       }
+       ret=write(fd, buf, sizeof(buf));
+       close(fd);
+       return ret;
+  }
+
+  int wr(char *fn, unsigned long data)
+  {
+       return wr_multi(fn, &data, 1);
+  }
+
+  int rd(char *fn, unsigned long *data)
+  {
+       int fd;
+       char buf[MAX_BUF_SIZE];
+
+       fd=open(fn, O_RDONLY);
+       if (fd<0) {
+               perror("Error:");
+               return -1;
+       }
+       read(fd, buf, MAX_BUF_SIZE);
+       *data=strtoul(buf, NULL, 16);
+       close(fd);
+       return 0;
+  }
+
+  int rd_status(char *path, int *status)
+  {
+       char fn[MAX_FN_SIZE];
+       sprintf(fn, "%s/status", path);
+       if (rd(fn, (u64*)status)<0) {
+               perror("status reading error.\n");
+               return -1;
+       }
+
+       return 0;
+  }
+
+  int rd_capabilities(char *path, u64 *capabilities)
+  {
+       char fn[MAX_FN_SIZE];
+       sprintf(fn, "%s/capabilities", path);
+       if (rd(fn, capabilities)<0) {
+               perror("capabilities reading error.\n");
+               return -1;
+       }
+
+       return 0;
+  }
+
+  int rd_all(char *path)
+  {
+       unsigned long err_type_info, err_struct_info, err_data_buffer;
+       int status;
+       unsigned long capabilities, resources;
+       char fn[MAX_FN_SIZE];
+
+       sprintf(fn, "%s/err_type_info", path);
+       if (rd(fn, &err_type_info)<0) {
+               perror("err_type_info reading error.\n");
+               return -1;
+       }
+       printf("err_type_info=%lx\n", err_type_info);
+
+       sprintf(fn, "%s/err_struct_info", path);
+       if (rd(fn, &err_struct_info)<0) {
+               perror("err_struct_info reading error.\n");
+               return -1;
+       }
+       printf("err_struct_info=%lx\n", err_struct_info);
+
+       sprintf(fn, "%s/err_data_buffer", path);
+       if (rd(fn, &err_data_buffer)<0) {
+               perror("err_data_buffer reading error.\n");
+               return -1;
+       }
+       printf("err_data_buffer=%lx\n", err_data_buffer);
+
+       sprintf(fn, "%s/status", path);
+       if (rd("status", (u64*)&status)<0) {
+               perror("status reading error.\n");
+               return -1;
+       }
+       printf("status=%d\n", status);
+
+       sprintf(fn, "%s/capabilities", path);
+       if (rd(fn,&capabilities)<0) {
+               perror("capabilities reading error.\n");
+               return -1;
+       }
+       printf("capabilities=%lx\n", capabilities);
+
+       sprintf(fn, "%s/resources", path);
+       if (rd(fn, &resources)<0) {
+               perror("resources reading error.\n");
+               return -1;
+       }
+       printf("resources=%lx\n", resources);
+
+       return 0;
+  }
+
+  int query_capabilities(char *path, err_type_info_t err_type_info,
+                       u64 *capabilities)
+  {
+       char fn[MAX_FN_SIZE];
+       err_struct_info_t err_struct_info;
+       err_data_buffer_t err_data_buffer;
+
+       err_struct_info.err_struct_info=0;
+       memset(err_data_buffer.err_data_buffer, -1, ERR_DATA_BUFFER_SIZE*8);
+
+       sprintf(fn, "%s/err_type_info", path);
+       wr(fn, err_type_info.err_type_info);
+       sprintf(fn, "%s/err_struct_info", path);
+       wr(fn, 0x0);
+       sprintf(fn, "%s/err_data_buffer", path);
+       wr_multi(fn, err_data_buffer.err_data_buffer, ERR_DATA_BUFFER_SIZE);
+
+       // Fire pal_mc_error_inject procedure.
+       sprintf(fn, "%s/call_start", path);
+       wr(fn, mode);
+
+       if (rd_capabilities(path, capabilities)<0)
+               return -1;
+
+       return 0;
+  }
+
+  int query_all_capabilities()
+  {
+       int status;
+       err_type_info_t err_type_info;
+       int err_sev, err_struct, struct_hier;
+       int cap=0;
+       u64 capabilities;
+       char path[MAX_FN_SIZE];
+
+       err_type_info.err_type_info=0;                  // Initial
+       err_type_info.err_type_info_u.mode=0;           // Query mode;
+       err_type_info.err_type_info_u.err_inj=0;
+
+       printf("All capabilities implemented in pal_mc_error_inject:\n");
+       sprintf(path, PATH_FORMAT ,0);
+       for (err_sev=0;err_sev<3;err_sev++)
+               for (err_struct=0;err_struct<5;err_struct++)
+                       for (struct_hier=0;struct_hier<5;struct_hier++)
+       {
+               status=-1;
+               capabilities=0;
+               err_type_info.err_type_info_u.err_sev=err_sev;
+               err_type_info.err_type_info_u.err_struct=err_struct;
+               err_type_info.err_type_info_u.struct_hier=struct_hier;
+
+               if (query_capabilities(path, err_type_info, &capabilities)<0)
+                       continue;
+
+               if (rd_status(path, &status)<0)
+                       continue;
+
+               if (status==0) {
+                       cap=1;
+                       printf("For err_sev=%d, err_struct=%d, struct_hier=%d: ",
+                               err_sev, err_struct, struct_hier);
+                       printf("capabilities 0x%lx\n", capabilities);
+               }
+       }
+       if (!cap) {
+               printf("No capabilities supported.\n");
+               return 0;
+       }
+
+       return 0;
+  }
+
+  int err_inject(int cpu, char *path, err_type_info_t err_type_info,
+               err_struct_info_t err_struct_info,
+               err_data_buffer_t err_data_buffer)
+  {
+       int status;
+       char fn[MAX_FN_SIZE];
+
+       log_info(cpu, "err_type_info=%lx, err_struct_info=%lx, ",
+               err_type_info.err_type_info,
+               err_struct_info.err_struct_info);
+       log_info(cpu,"err_data_buffer=[%lx,%lx,%lx]\n",
+               err_data_buffer.err_data_buffer[0],
+               err_data_buffer.err_data_buffer[1],
+               err_data_buffer.err_data_buffer[2]);
+       sprintf(fn, "%s/err_type_info", path);
+       wr(fn, err_type_info.err_type_info);
+       sprintf(fn, "%s/err_struct_info", path);
+       wr(fn, err_struct_info.err_struct_info);
+       sprintf(fn, "%s/err_data_buffer", path);
+       wr_multi(fn, err_data_buffer.err_data_buffer, ERR_DATA_BUFFER_SIZE);
+
+       // Fire pal_mc_error_inject procedure.
+       sprintf(fn, "%s/call_start", path);
+       wr(fn,mode);
+
+       if (rd_status(path, &status)<0) {
+               vbprintf("fail: read status\n");
+               return -100;
+       }
+
+       if (status!=0) {
+               log_info(cpu, "fail: status=%d\n", status);
+               return status;
+       }
+
+       return status;
+  }
+
+  static int construct_data_buf(char *path, err_type_info_t err_type_info,
+               err_struct_info_t err_struct_info,
+               err_data_buffer_t *err_data_buffer,
+               void *va1)
+  {
+       char fn[MAX_FN_SIZE];
+       u64 virt_addr=0, phys_addr=0;
+
+       vbprintf("va1=%lx\n", (u64)va1);
+       memset(&err_data_buffer->err_data_buffer_cache, 0, ERR_DATA_BUFFER_SIZE*8);
+
+       switch (err_type_info.err_type_info_u.err_struct) {
+               case 1: // Cache
+                       switch (err_struct_info.err_struct_info_cache.cl_id) {
+                               case 1: //Virtual addr
+                                       err_data_buffer->err_data_buffer_cache.inj_addr=(u64)va1;
+                                       break;
+                               case 2: //Phys addr
+                                       sprintf(fn, "%s/virtual_to_phys", path);
+                                       virt_addr=(u64)va1;
+                                       if (wr(fn,virt_addr)<0)
+                                               return -1;
+                                       rd(fn, &phys_addr);
+                                       err_data_buffer->err_data_buffer_cache.inj_addr=phys_addr;
+                                       break;
+                               default:
+                                       printf("Not supported cl_id\n");
+                                       break;
+                       }
+                       break;
+               case 2: //  TLB
+                       break;
+               case 3: //  Register file
+                       break;
+               case 4: //  Bus/system interconnect
+               default:
+                       printf("Not supported err_struct\n");
+                       break;
+       }
+
+       return 0;
+  }
+
+  typedef struct {
+       u64 cpu;
+       u64 loop;
+       u64 interval;
+       u64 err_type_info;
+       u64 err_struct_info;
+       u64 err_data_buffer[ERR_DATA_BUFFER_SIZE];
+  } parameters_t;
+
+  parameters_t line_para;
+  int para;
+
+  static int empty_data_buffer(u64 *err_data_buffer)
+  {
+       int empty=1;
+       int i;
+
+       for (i=0;i<ERR_DATA_BUFFER_SIZE; i++)
+          if (err_data_buffer[i]!=-1)
+               empty=0;
+
+       return empty;
+  }
+
+  int err_inj()
+  {
+       err_type_info_t err_type_info;
+       err_struct_info_t err_struct_info;
+       err_data_buffer_t err_data_buffer;
+       int count;
+       FILE *fp;
+       unsigned long cpu, loop, interval, err_type_info_conf, err_struct_info_conf;
+       u64 err_data_buffer_conf[ERR_DATA_BUFFER_SIZE];
+       int num;
+       int i;
+       char path[MAX_FN_SIZE];
+       parameters_t parameters[MAX_TASK_NUM]={};
+       pid_t child_pid[MAX_TASK_NUM];
+       time_t current_time;
+       int status;
+
+       if (!para) {
+           fp=fopen("err.conf", "r");
+           if (fp==NULL) {
+               perror("Error open err.conf");
+               return -1;
+           }
+
+           num=0;
+           while (!feof(fp)) {
+               char buf[256];
+               memset(buf,0,256);
+               fgets(buf, 256, fp);
+               count=sscanf(buf, "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx\n",
+                               &cpu, &loop, &interval,&err_type_info_conf,
+                               &err_struct_info_conf,
+                               &err_data_buffer_conf[0],
+                               &err_data_buffer_conf[1],
+                               &err_data_buffer_conf[2]);
+               if (count!=PARA_FIELD_NUM+3) {
+                       err_data_buffer_conf[0]=-1;
+                       err_data_buffer_conf[1]=-1;
+                       err_data_buffer_conf[2]=-1;
+                       count=sscanf(buf, "%lx, %lx, %lx, %lx, %lx\n",
+                               &cpu, &loop, &interval,&err_type_info_conf,
+                               &err_struct_info_conf);
+                       if (count!=PARA_FIELD_NUM)
+                               continue;
+               }
+
+               parameters[num].cpu=cpu;
+               parameters[num].loop=loop;
+               parameters[num].interval= interval>MIN_INTERVAL
+                                         ?interval:MIN_INTERVAL;
+               parameters[num].err_type_info=err_type_info_conf;
+               parameters[num].err_struct_info=err_struct_info_conf;
+               memcpy(parameters[num++].err_data_buffer,
+                       err_data_buffer_conf,ERR_DATA_BUFFER_SIZE*8) ;
+
+               if (num>=MAX_TASK_NUM)
+                       break;
+           }
+       }
+       else {
+               parameters[0].cpu=line_para.cpu;
+               parameters[0].loop=line_para.loop;
+               parameters[0].interval= line_para.interval>MIN_INTERVAL
+                                         ?line_para.interval:MIN_INTERVAL;
+               parameters[0].err_type_info=line_para.err_type_info;
+               parameters[0].err_struct_info=line_para.err_struct_info;
+               memcpy(parameters[0].err_data_buffer,
+                       line_para.err_data_buffer,ERR_DATA_BUFFER_SIZE*8) ;
+
+               num=1;
+       }
+
+       /* Create semaphore: If one_lock, one semaphore for all processors.
+          Otherwise, one semaphore for each processor. */
+       if (one_lock) {
+               if (create_sem(0)) {
+                       printf("Can not create semaphore...exit\n");
+                       free_sem(0);
+                       return -1;
+               }
+       }
+       else {
+               for (i=0;i<num;i++) {
+                  if (create_sem(parameters[i].cpu)) {
+                       printf("Can not create semaphore for cpu%d...exit\n",i);
+                       free_sem(parameters[num].cpu);
+                       return -1;
+                  }
+               }
+       }
+
+       /* Create a shm segment which will be used to inject/consume errors on.*/
+       if (create_shm()==-1) {
+               printf("Error to create shm...exit\n");
+               return -1;
+       }
+
+       for (i=0;i<num;i++) {
+               pid_t pid;
+
+               current_time=time(NULL);
+               log_info(parameters[i].cpu, "\nBegine at %s", ctime(&current_time));
+               log_info(parameters[i].cpu, "Configurations:\n");
+               log_info(parameters[i].cpu,"On cpu%ld: loop=%lx, interval=%lx(s)",
+                       parameters[i].cpu,
+                       parameters[i].loop,
+                       parameters[i].interval);
+               log_info(parameters[i].cpu," err_type_info=%lx,err_struct_info=%lx\n",
+                       parameters[i].err_type_info,
+                       parameters[i].err_struct_info);
+
+               sprintf(path, PATH_FORMAT, (int)parameters[i].cpu);
+               err_type_info.err_type_info=parameters[i].err_type_info;
+               err_struct_info.err_struct_info=parameters[i].err_struct_info;
+               memcpy(err_data_buffer.err_data_buffer,
+                       parameters[i].err_data_buffer,
+                       ERR_DATA_BUFFER_SIZE*8);
+
+               pid=fork();
+               if (pid==0) {
+                       unsigned long mask[MASK_SIZE];
+                       int j, k;
+
+                       void *va1, *va2;
+
+                       /* Allocate two memory areas va1 and va2 in shm */
+                       va1=shmaddr+parameters[i].cpu*PAGE_SIZE;
+                       va2=shmaddr+parameters[i].cpu*PAGE_SIZE+PAGE_SIZE;
+
+                       vbprintf("va1=%lx, va2=%lx\n", (u64)va1, (u64)va2);
+                       memset(va1, 0x1, PAGE_SIZE);
+                       memset(va2, 0x2, PAGE_SIZE);
+
+                       if (empty_data_buffer(err_data_buffer.err_data_buffer))
+                               /* If not specified yet, construct data buffer
+                                * with va1
+                                */
+                               construct_data_buf(path, err_type_info,
+                                       err_struct_info, &err_data_buffer,va1);
+
+                       for (j=0;j<MASK_SIZE;j++)
+                               mask[j]=0;
+
+                       cpu=parameters[i].cpu;
+                       k = cpu%64;
+                       j = cpu/64;
+                       mask[j] = 1UL << k;
+
+                       if (sched_setaffinity(0, MASK_SIZE*8, mask)==-1) {
+                               perror("Error sched_setaffinity:");
+                               return -1;
+                       }
+
+                       for (j=0; j<parameters[i].loop; j++) {
+                               log_info(parameters[i].cpu,"Injection ");
+                               log_info(parameters[i].cpu,"on cpu%ld: #%d/%ld ",
+
+                                       parameters[i].cpu,j+1, parameters[i].loop);
+
+                               /* Hold the lock */
+                               if (one_lock)
+                                       lock(0);
+                               else
+                               /* Hold lock on this cpu */
+                                       lock(parameters[i].cpu);
+
+                               if ((status=err_inject(parameters[i].cpu,
+                                          path, err_type_info,
+                                          err_struct_info, err_data_buffer))
+                                          ==0) {
+                                       /* consume the error for "inject only"*/
+                                       memcpy(va2, va1, PAGE_SIZE);
+                                       memcpy(va1, va2, PAGE_SIZE);
+                                       log_info(parameters[i].cpu,
+                                               "successful\n");
+                               }
+                               else {
+                                       log_info(parameters[i].cpu,"fail:");
+                                       log_info(parameters[i].cpu,
+                                               "status=%d\n", status);
+                                       unlock(parameters[i].cpu);
+                                       break;
+                               }
+                               if (one_lock)
+                               /* Release the lock */
+                                       unlock(0);
+                               /* Release lock on this cpu */
+                               else
+                                       unlock(parameters[i].cpu);
+
+                               if (j < parameters[i].loop-1)
+                                       sleep(parameters[i].interval);
+                       }
+                       current_time=time(NULL);
+                       log_info(parameters[i].cpu, "Done at %s", ctime(&current_time));
+                       return 0;
+               }
+               else if (pid<0) {
+                       perror("Error fork:");
+                       continue;
+               }
+               child_pid[i]=pid;
+       }
+       for (i=0;i<num;i++)
+               waitpid(child_pid[i], NULL, 0);
+
+       if (one_lock)
+               free_sem(0);
+       else
+               for (i=0;i<num;i++)
+                       free_sem(parameters[i].cpu);
+
+       printf("All done.\n");
+
+       return 0;
+  }
+
+  void help()
+  {
+       printf("err_inject_tool:\n");
+       printf("\t-q: query all capabilities. default: off\n");
+       printf("\t-m: procedure mode. 1: physical 2: virtual. default: 1\n");
+       printf("\t-i: inject errors. default: off\n");
+       printf("\t-l: one lock per cpu. default: one lock for all\n");
+       printf("\t-e: error parameters:\n");
+       printf("\t\tcpu,loop,interval,err_type_info,err_struct_info[,err_data_buffer[0],err_data_buffer[1],err_data_buffer[2]]\n");
+       printf("\t\t   cpu: logical cpu number the error will be inject in.\n");
+       printf("\t\t   loop: times the error will be injected.\n");
+       printf("\t\t   interval: In second. every so often one error is injected.\n");
+       printf("\t\t   err_type_info, err_struct_info: PAL parameters.\n");
+       printf("\t\t   err_data_buffer: PAL parameter. Optional. If not present,\n");
+       printf("\t\t                    it's constructed by tool automatically. Be\n");
+       printf("\t\t                    careful to provide err_data_buffer and make\n");
+       printf("\t\t                    sure it's working with the environment.\n");
+       printf("\t    Note:no space between error parameters.\n");
+       printf("\t    default: Take error parameters from err.conf instead of command line.\n");
+       printf("\t-v: verbose. default: off\n");
+       printf("\t-h: help\n\n");
+       printf("The tool will take err.conf file as ");
+       printf("input to inject single or multiple errors ");
+       printf("on one or multiple cpus in parallel.\n");
+  }
+
+  int main(int argc, char **argv)
+  {
+       char c;
+       int do_err_inj=0;
+       int do_query_all=0;
+       int count;
+       u32 m;
+
+       /* Default one lock for all cpu's */
+       one_lock=1;
+       while ((c = getopt(argc, argv, "m:iqvhle:")) != EOF)
+               switch (c) {
+                       case 'm':       /* Procedure mode. 1: phys 2: virt */
+                               count=sscanf(optarg, "%x", &m);
+                               if (count!=1 || (m!=1 && m!=2)) {
+                                       printf("Wrong mode number.\n");
+                                       help();
+                                       return -1;
+                               }
+                               mode=m;
+                               break;
+                       case 'i':       /* Inject errors */
+                               do_err_inj=1;
+                               break;
+                       case 'q':       /* Query */
+                               do_query_all=1;
+                               break;
+                       case 'v':       /* Verbose */
+                               verbose=1;
+                               break;
+                       case 'l':       /* One lock per cpu */
+                               one_lock=0;
+                               break;
+                       case 'e':       /* error arguments */
+                               /* Take parameters:
+                                * #cpu, loop, interval, err_type_info, err_struct_info[, err_data_buffer]
+                                * err_data_buffer is optional. Recommend not to specify
+                                * err_data_buffer. Better to use tool to generate it.
+                                */
+                               count=sscanf(optarg,
+                                       "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx\n",
+                                       &line_para.cpu,
+                                       &line_para.loop,
+                                       &line_para.interval,
+                                       &line_para.err_type_info,
+                                       &line_para.err_struct_info,
+                                       &line_para.err_data_buffer[0],
+                                       &line_para.err_data_buffer[1],
+                                       &line_para.err_data_buffer[2]);
+                               if (count!=PARA_FIELD_NUM+3) {
+                                   line_para.err_data_buffer[0]=-1,
+                                   line_para.err_data_buffer[1]=-1,
+                                   line_para.err_data_buffer[2]=-1;
+                                   count=sscanf(optarg, "%lx, %lx, %lx, %lx, %lx\n",
+                                               &line_para.cpu,
+                                               &line_para.loop,
+                                               &line_para.interval,
+                                               &line_para.err_type_info,
+                                               &line_para.err_struct_info);
+                                   if (count!=PARA_FIELD_NUM) {
+                                       printf("Wrong error arguments.\n");
+                                       help();
+                                       return -1;
+                                   }
+                               }
+                               para=1;
+                               break;
+                       continue;
+                               break;
+                       case 'h':
+                               help();
+                               return 0;
+                       default:
+                               break;
+               }
+
+       if (do_query_all)
+               query_all_capabilities();
+       if (do_err_inj)
+               err_inj();
+
+       if (!do_query_all &&  !do_err_inj)
+               help();
+
+       return 0;
+  }
diff --git a/Documentation/arch/ia64/features.rst b/Documentation/arch/ia64/features.rst
new file mode 100644 (file)
index 0000000..d7226fd
--- /dev/null
@@ -0,0 +1,3 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. kernel-feat:: $srctree/Documentation/features ia64
diff --git a/Documentation/arch/ia64/fsys.rst b/Documentation/arch/ia64/fsys.rst
new file mode 100644 (file)
index 0000000..a702d2c
--- /dev/null
@@ -0,0 +1,303 @@
+===================================
+Light-weight System Calls for IA-64
+===================================
+
+                       Started: 13-Jan-2003
+
+                   Last update: 27-Sep-2003
+
+                     David Mosberger-Tang
+                     <davidm@hpl.hp.com>
+
+Using the "epc" instruction effectively introduces a new mode of
+execution to the ia64 linux kernel.  We call this mode the
+"fsys-mode".  To recap, the normal states of execution are:
+
+  - kernel mode:
+       Both the register stack and the memory stack have been
+       switched over to kernel memory.  The user-level state is saved
+       in a pt-regs structure at the top of the kernel memory stack.
+
+  - user mode:
+       Both the register stack and the kernel stack are in
+       user memory.  The user-level state is contained in the
+       CPU registers.
+
+  - bank 0 interruption-handling mode:
+       This is the non-interruptible state which all
+       interruption-handlers start execution in.  The user-level
+       state remains in the CPU registers and some kernel state may
+       be stored in bank 0 of registers r16-r31.
+
+In contrast, fsys-mode has the following special properties:
+
+  - execution is at privilege level 0 (most-privileged)
+
+  - CPU registers may contain a mixture of user-level and kernel-level
+    state (it is the responsibility of the kernel to ensure that no
+    security-sensitive kernel-level state is leaked back to
+    user-level)
+
+  - execution is interruptible and preemptible (an fsys-mode handler
+    can disable interrupts and avoid all other interruption-sources
+    to avoid preemption)
+
+  - neither the memory-stack nor the register-stack can be trusted while
+    in fsys-mode (they point to the user-level stacks, which may
+    be invalid, or completely bogus addresses)
+
+In summary, fsys-mode is much more similar to running in user-mode
+than it is to running in kernel-mode.  Of course, given that the
+privilege level is at level 0, this means that fsys-mode requires some
+care (see below).
+
+
+How to tell fsys-mode
+=====================
+
+Linux operates in fsys-mode when (a) the privilege level is 0 (most
+privileged) and (b) the stacks have NOT been switched to kernel memory
+yet.  For convenience, the header file <asm-ia64/ptrace.h> provides
+three macros::
+
+       user_mode(regs)
+       user_stack(task,regs)
+       fsys_mode(task,regs)
+
+The "regs" argument is a pointer to a pt_regs structure.  The "task"
+argument is a pointer to the task structure to which the "regs"
+pointer belongs to.  user_mode() returns TRUE if the CPU state pointed
+to by "regs" was executing in user mode (privilege level 3).
+user_stack() returns TRUE if the state pointed to by "regs" was
+executing on the user-level stack(s).  Finally, fsys_mode() returns
+TRUE if the CPU state pointed to by "regs" was executing in fsys-mode.
+The fsys_mode() macro is equivalent to the expression::
+
+       !user_mode(regs) && user_stack(task,regs)
+
+How to write an fsyscall handler
+================================
+
+The file arch/ia64/kernel/fsys.S contains a table of fsyscall-handlers
+(fsyscall_table).  This table contains one entry for each system call.
+By default, a system call is handled by fsys_fallback_syscall().  This
+routine takes care of entering (full) kernel mode and calling the
+normal Linux system call handler.  For performance-critical system
+calls, it is possible to write a hand-tuned fsyscall_handler.  For
+example, fsys.S contains fsys_getpid(), which is a hand-tuned version
+of the getpid() system call.
+
+The entry and exit-state of an fsyscall handler is as follows:
+
+Machine state on entry to fsyscall handler
+------------------------------------------
+
+  ========= ===============================================================
+  r10      0
+  r11      saved ar.pfs (a user-level value)
+  r15      system call number
+  r16      "current" task pointer (in normal kernel-mode, this is in r13)
+  r32-r39   system call arguments
+  b6       return address (a user-level value)
+  ar.pfs    previous frame-state (a user-level value)
+  PSR.be    cleared to zero (i.e., little-endian byte order is in effect)
+  -         all other registers may contain values passed in from user-mode
+  ========= ===============================================================
+
+Required machine state on exit to fsyscall handler
+--------------------------------------------------
+
+  ========= ===========================================================
+  r11      saved ar.pfs (as passed into the fsyscall handler)
+  r15      system call number (as passed into the fsyscall handler)
+  r32-r39   system call arguments (as passed into the fsyscall handler)
+  b6       return address (as passed into the fsyscall handler)
+  ar.pfs    previous frame-state (as passed into the fsyscall handler)
+  ========= ===========================================================
+
+Fsyscall handlers can execute with very little overhead, but with that
+speed comes a set of restrictions:
+
+ * Fsyscall-handlers MUST check for any pending work in the flags
+   member of the thread-info structure and if any of the
+   TIF_ALLWORK_MASK flags are set, the handler needs to fall back on
+   doing a full system call (by calling fsys_fallback_syscall).
+
+ * Fsyscall-handlers MUST preserve incoming arguments (r32-r39, r11,
+   r15, b6, and ar.pfs) because they will be needed in case of a
+   system call restart.  Of course, all "preserved" registers also
+   must be preserved, in accordance to the normal calling conventions.
+
+ * Fsyscall-handlers MUST check argument registers for containing a
+   NaT value before using them in any way that could trigger a
+   NaT-consumption fault.  If a system call argument is found to
+   contain a NaT value, an fsyscall-handler may return immediately
+   with r8=EINVAL, r10=-1.
+
+ * Fsyscall-handlers MUST NOT use the "alloc" instruction or perform
+   any other operation that would trigger mandatory RSE
+   (register-stack engine) traffic.
+
+ * Fsyscall-handlers MUST NOT write to any stacked registers because
+   it is not safe to assume that user-level called a handler with the
+   proper number of arguments.
+
+ * Fsyscall-handlers need to be careful when accessing per-CPU variables:
+   unless proper safe-guards are taken (e.g., interruptions are avoided),
+   execution may be pre-empted and resumed on another CPU at any given
+   time.
+
+ * Fsyscall-handlers must be careful not to leak sensitive kernel'
+   information back to user-level.  In particular, before returning to
+   user-level, care needs to be taken to clear any scratch registers
+   that could contain sensitive information (note that the current
+   task pointer is not considered sensitive: it's already exposed
+   through ar.k6).
+
+ * Fsyscall-handlers MUST NOT access user-memory without first
+   validating access-permission (this can be done typically via
+   probe.r.fault and/or probe.w.fault) and without guarding against
+   memory access exceptions (this can be done with the EX() macros
+   defined by asmmacro.h).
+
+The above restrictions may seem draconian, but remember that it's
+possible to trade off some of the restrictions by paying a slightly
+higher overhead.  For example, if an fsyscall-handler could benefit
+from the shadow register bank, it could temporarily disable PSR.i and
+PSR.ic, switch to bank 0 (bsw.0) and then use the shadow registers as
+needed.  In other words, following the above rules yields extremely
+fast system call execution (while fully preserving system call
+semantics), but there is also a lot of flexibility in handling more
+complicated cases.
+
+Signal handling
+===============
+
+The delivery of (asynchronous) signals must be delayed until fsys-mode
+is exited.  This is accomplished with the help of the lower-privilege
+transfer trap: arch/ia64/kernel/process.c:do_notify_resume_user()
+checks whether the interrupted task was in fsys-mode and, if so, sets
+PSR.lp and returns immediately.  When fsys-mode is exited via the
+"br.ret" instruction that lowers the privilege level, a trap will
+occur.  The trap handler clears PSR.lp again and returns immediately.
+The kernel exit path then checks for and delivers any pending signals.
+
+PSR Handling
+============
+
+The "epc" instruction doesn't change the contents of PSR at all.  This
+is in contrast to a regular interruption, which clears almost all
+bits.  Because of that, some care needs to be taken to ensure things
+work as expected.  The following discussion describes how each PSR bit
+is handled.
+
+======= =======================================================================
+PSR.be Cleared when entering fsys-mode.  A srlz.d instruction is used
+       to ensure the CPU is in little-endian mode before the first
+       load/store instruction is executed.  PSR.be is normally NOT
+       restored upon return from an fsys-mode handler.  In other
+       words, user-level code must not rely on PSR.be being preserved
+       across a system call.
+PSR.up Unchanged.
+PSR.ac Unchanged.
+PSR.mfl Unchanged.  Note: fsys-mode handlers must not write-registers!
+PSR.mfh        Unchanged.  Note: fsys-mode handlers must not write-registers!
+PSR.ic Unchanged.  Note: fsys-mode handlers can clear the bit, if needed.
+PSR.i  Unchanged.  Note: fsys-mode handlers can clear the bit, if needed.
+PSR.pk Unchanged.
+PSR.dt Unchanged.
+PSR.dfl        Unchanged.  Note: fsys-mode handlers must not write-registers!
+PSR.dfh        Unchanged.  Note: fsys-mode handlers must not write-registers!
+PSR.sp Unchanged.
+PSR.pp Unchanged.
+PSR.di Unchanged.
+PSR.si Unchanged.
+PSR.db Unchanged.  The kernel prevents user-level from setting a hardware
+       breakpoint that triggers at any privilege level other than
+       3 (user-mode).
+PSR.lp Unchanged.
+PSR.tb Lazy redirect.  If a taken-branch trap occurs while in
+       fsys-mode, the trap-handler modifies the saved machine state
+       such that execution resumes in the gate page at
+       syscall_via_break(), with privilege level 3.  Note: the
+       taken branch would occur on the branch invoking the
+       fsyscall-handler, at which point, by definition, a syscall
+       restart is still safe.  If the system call number is invalid,
+       the fsys-mode handler will return directly to user-level.  This
+       return will trigger a taken-branch trap, but since the trap is
+       taken _after_ restoring the privilege level, the CPU has already
+       left fsys-mode, so no special treatment is needed.
+PSR.rt Unchanged.
+PSR.cpl        Cleared to 0.
+PSR.is Unchanged (guaranteed to be 0 on entry to the gate page).
+PSR.mc Unchanged.
+PSR.it Unchanged (guaranteed to be 1).
+PSR.id Unchanged.  Note: the ia64 linux kernel never sets this bit.
+PSR.da Unchanged.  Note: the ia64 linux kernel never sets this bit.
+PSR.dd Unchanged.  Note: the ia64 linux kernel never sets this bit.
+PSR.ss Lazy redirect.  If set, "epc" will cause a Single Step Trap to
+       be taken.  The trap handler then modifies the saved machine
+       state such that execution resumes in the gate page at
+       syscall_via_break(), with privilege level 3.
+PSR.ri Unchanged.
+PSR.ed Unchanged.  Note: This bit could only have an effect if an fsys-mode
+       handler performed a speculative load that gets NaTted.  If so, this
+       would be the normal & expected behavior, so no special treatment is
+       needed.
+PSR.bn Unchanged.  Note: fsys-mode handlers may clear the bit, if needed.
+       Doing so requires clearing PSR.i and PSR.ic as well.
+PSR.ia Unchanged.  Note: the ia64 linux kernel never sets this bit.
+======= =======================================================================
+
+Using fast system calls
+=======================
+
+To use fast system calls, userspace applications need simply call
+__kernel_syscall_via_epc().  For example
+
+-- example fgettimeofday() call --
+
+-- fgettimeofday.S --
+
+::
+
+  #include <asm/asmmacro.h>
+
+  GLOBAL_ENTRY(fgettimeofday)
+  .prologue
+  .save ar.pfs, r11
+  mov r11 = ar.pfs
+  .body
+
+  mov r2 = 0xa000000000020660;;  // gate address
+                              // found by inspection of System.map for the
+                              // __kernel_syscall_via_epc() function.  See
+                              // below for how to do this for real.
+
+  mov b7 = r2
+  mov r15 = 1087                      // gettimeofday syscall
+  ;;
+  br.call.sptk.many b6 = b7
+  ;;
+
+  .restore sp
+
+  mov ar.pfs = r11
+  br.ret.sptk.many rp;;              // return to caller
+  END(fgettimeofday)
+
+-- end fgettimeofday.S --
+
+In reality, getting the gate address is accomplished by two extra
+values passed via the ELF auxiliary vector (include/asm-ia64/elf.h)
+
+ * AT_SYSINFO : is the address of __kernel_syscall_via_epc()
+ * AT_SYSINFO_EHDR : is the address of the kernel gate ELF DSO
+
+The ELF DSO is a pre-linked library that is mapped in by the kernel at
+the gate page.  It is a proper ELF shared object so, with a dynamic
+loader that recognises the library, you should be able to make calls to
+the exported functions within it as with any other shared library.
+AT_SYSINFO points into the kernel DSO at the
+__kernel_syscall_via_epc() function for historical reasons (it was
+used before the kernel DSO) and as a convenience.
diff --git a/Documentation/arch/ia64/ia64.rst b/Documentation/arch/ia64/ia64.rst
new file mode 100644 (file)
index 0000000..b725019
--- /dev/null
@@ -0,0 +1,49 @@
+===========================================
+Linux kernel release for the IA-64 Platform
+===========================================
+
+   These are the release notes for Linux since version 2.4 for IA-64
+   platform.  This document provides information specific to IA-64
+   ONLY, to get additional information about the Linux kernel also
+   read the original Linux README provided with the kernel.
+
+Installing the Kernel
+=====================
+
+ - IA-64 kernel installation is the same as the other platforms, see
+   original README for details.
+
+
+Software Requirements
+=====================
+
+   Compiling and running this kernel requires an IA-64 compliant GCC
+   compiler.  And various software packages also compiled with an
+   IA-64 compliant GCC compiler.
+
+
+Configuring the Kernel
+======================
+
+   Configuration is the same, see original README for details.
+
+
+Compiling the Kernel:
+
+ - Compiling this kernel doesn't differ from other platform so read
+   the original README for details BUT make sure you have an IA-64
+   compliant GCC compiler.
+
+IA-64 Specifics
+===============
+
+ - General issues:
+
+    * Hardly any performance tuning has been done. Obvious targets
+      include the library routines (IP checksum, etc.). Less
+      obvious targets include making sure we don't flush the TLB
+      needlessly, etc.
+
+    * SMP locks cleanup/optimization
+
+    * IA32 support.  Currently experimental.  It mostly works.
diff --git a/Documentation/arch/ia64/index.rst b/Documentation/arch/ia64/index.rst
new file mode 100644 (file)
index 0000000..761f215
--- /dev/null
@@ -0,0 +1,19 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==================
+IA-64 Architecture
+==================
+
+.. toctree::
+   :maxdepth: 1
+
+   ia64
+   aliasing
+   efirtc
+   err_inject
+   fsys
+   irq-redir
+   mca
+   serial
+
+   features
diff --git a/Documentation/arch/ia64/irq-redir.rst b/Documentation/arch/ia64/irq-redir.rst
new file mode 100644 (file)
index 0000000..6bbbbe4
--- /dev/null
@@ -0,0 +1,80 @@
+==============================
+IRQ affinity on IA64 platforms
+==============================
+
+07.01.2002, Erich Focht <efocht@ess.nec.de>
+
+
+By writing to /proc/irq/IRQ#/smp_affinity the interrupt routing can be
+controlled. The behavior on IA64 platforms is slightly different from
+that described in Documentation/core-api/irq/irq-affinity.rst for i386 systems.
+
+Because of the usage of SAPIC mode and physical destination mode the
+IRQ target is one particular CPU and cannot be a mask of several
+CPUs. Only the first non-zero bit is taken into account.
+
+
+Usage examples
+==============
+
+The target CPU has to be specified as a hexadecimal CPU mask. The
+first non-zero bit is the selected CPU. This format has been kept for
+compatibility reasons with i386.
+
+Set the delivery mode of interrupt 41 to fixed and route the
+interrupts to CPU #3 (logical CPU number) (2^3=0x08)::
+
+     echo "8" >/proc/irq/41/smp_affinity
+
+Set the default route for IRQ number 41 to CPU 6 in lowest priority
+delivery mode (redirectable)::
+
+     echo "r 40" >/proc/irq/41/smp_affinity
+
+The output of the command::
+
+     cat /proc/irq/IRQ#/smp_affinity
+
+gives the target CPU mask for the specified interrupt vector. If the CPU
+mask is preceded by the character "r", the interrupt is redirectable
+(i.e. lowest priority mode routing is used), otherwise its route is
+fixed.
+
+
+
+Initialization and default behavior
+===================================
+
+If the platform features IRQ redirection (info provided by SAL) all
+IO-SAPIC interrupts are initialized with CPU#0 as their default target
+and the routing is the so called "lowest priority mode" (actually
+fixed SAPIC mode with hint). The XTP chipset registers are used as hints
+for the IRQ routing. Currently in Linux XTP registers can have three
+values:
+
+       - minimal for an idle task,
+       - normal if any other task runs,
+       - maximal if the CPU is going to be switched off.
+
+The IRQ is routed to the CPU with lowest XTP register value, the
+search begins at the default CPU. Therefore most of the interrupts
+will be handled by CPU #0.
+
+If the platform doesn't feature interrupt redirection IOSAPIC fixed
+routing is used. The target CPUs are distributed in a round robin
+manner. IRQs will be routed only to the selected target CPUs. Check
+with::
+
+        cat /proc/interrupts
+
+
+
+Comments
+========
+
+On large (multi-node) systems it is recommended to route the IRQs to
+the node to which the corresponding device is connected.
+For systems like the NEC AzusA we get IRQ node-affinity for free. This
+is because usually the chipsets on each node redirect the interrupts
+only to their own CPUs (as they cannot see the XTP registers on the
+other nodes).
diff --git a/Documentation/arch/ia64/mca.rst b/Documentation/arch/ia64/mca.rst
new file mode 100644 (file)
index 0000000..08270bb
--- /dev/null
@@ -0,0 +1,198 @@
+=============================================================
+An ad-hoc collection of notes on IA64 MCA and INIT processing
+=============================================================
+
+Feel free to update it with notes about any area that is not clear.
+
+---
+
+MCA/INIT are completely asynchronous.  They can occur at any time, when
+the OS is in any state.  Including when one of the cpus is already
+holding a spinlock.  Trying to get any lock from MCA/INIT state is
+asking for deadlock.  Also the state of structures that are protected
+by locks is indeterminate, including linked lists.
+
+---
+
+The complicated ia64 MCA process.  All of this is mandated by Intel's
+specification for ia64 SAL, error recovery and unwind, it is not as
+if we have a choice here.
+
+* MCA occurs on one cpu, usually due to a double bit memory error.
+  This is the monarch cpu.
+
+* SAL sends an MCA rendezvous interrupt (which is a normal interrupt)
+  to all the other cpus, the slaves.
+
+* Slave cpus that receive the MCA interrupt call down into SAL, they
+  end up spinning disabled while the MCA is being serviced.
+
+* If any slave cpu was already spinning disabled when the MCA occurred
+  then it cannot service the MCA interrupt.  SAL waits ~20 seconds then
+  sends an unmaskable INIT event to the slave cpus that have not
+  already rendezvoused.
+
+* Because MCA/INIT can be delivered at any time, including when the cpu
+  is down in PAL in physical mode, the registers at the time of the
+  event are _completely_ undefined.  In particular the MCA/INIT
+  handlers cannot rely on the thread pointer, PAL physical mode can
+  (and does) modify TP.  It is allowed to do that as long as it resets
+  TP on return.  However MCA/INIT events expose us to these PAL
+  internal TP changes.  Hence curr_task().
+
+* If an MCA/INIT event occurs while the kernel was running (not user
+  space) and the kernel has called PAL then the MCA/INIT handler cannot
+  assume that the kernel stack is in a fit state to be used.  Mainly
+  because PAL may or may not maintain the stack pointer internally.
+  Because the MCA/INIT handlers cannot trust the kernel stack, they
+  have to use their own, per-cpu stacks.  The MCA/INIT stacks are
+  preformatted with just enough task state to let the relevant handlers
+  do their job.
+
+* Unlike most other architectures, the ia64 struct task is embedded in
+  the kernel stack[1].  So switching to a new kernel stack means that
+  we switch to a new task as well.  Because various bits of the kernel
+  assume that current points into the struct task, switching to a new
+  stack also means a new value for current.
+
+* Once all slaves have rendezvoused and are spinning disabled, the
+  monarch is entered.  The monarch now tries to diagnose the problem
+  and decide if it can recover or not.
+
+* Part of the monarch's job is to look at the state of all the other
+  tasks.  The only way to do that on ia64 is to call the unwinder,
+  as mandated by Intel.
+
+* The starting point for the unwind depends on whether a task is
+  running or not.  That is, whether it is on a cpu or is blocked.  The
+  monarch has to determine whether or not a task is on a cpu before it
+  knows how to start unwinding it.  The tasks that received an MCA or
+  INIT event are no longer running, they have been converted to blocked
+  tasks.  But (and its a big but), the cpus that received the MCA
+  rendezvous interrupt are still running on their normal kernel stacks!
+
+* To distinguish between these two cases, the monarch must know which
+  tasks are on a cpu and which are not.  Hence each slave cpu that
+  switches to an MCA/INIT stack, registers its new stack using
+  set_curr_task(), so the monarch can tell that the _original_ task is
+  no longer running on that cpu.  That gives us a decent chance of
+  getting a valid backtrace of the _original_ task.
+
+* MCA/INIT can be nested, to a depth of 2 on any cpu.  In the case of a
+  nested error, we want diagnostics on the MCA/INIT handler that
+  failed, not on the task that was originally running.  Again this
+  requires set_curr_task() so the MCA/INIT handlers can register their
+  own stack as running on that cpu.  Then a recursive error gets a
+  trace of the failing handler's "task".
+
+[1]
+    My (Keith Owens) original design called for ia64 to separate its
+    struct task and the kernel stacks.  Then the MCA/INIT data would be
+    chained stacks like i386 interrupt stacks.  But that required
+    radical surgery on the rest of ia64, plus extra hard wired TLB
+    entries with its associated performance degradation.  David
+    Mosberger vetoed that approach.  Which meant that separate kernel
+    stacks meant separate "tasks" for the MCA/INIT handlers.
+
+---
+
+INIT is less complicated than MCA.  Pressing the nmi button or using
+the equivalent command on the management console sends INIT to all
+cpus.  SAL picks one of the cpus as the monarch and the rest are
+slaves.  All the OS INIT handlers are entered at approximately the same
+time.  The OS monarch prints the state of all tasks and returns, after
+which the slaves return and the system resumes.
+
+At least that is what is supposed to happen.  Alas there are broken
+versions of SAL out there.  Some drive all the cpus as monarchs.  Some
+drive them all as slaves.  Some drive one cpu as monarch, wait for that
+cpu to return from the OS then drive the rest as slaves.  Some versions
+of SAL cannot even cope with returning from the OS, they spin inside
+SAL on resume.  The OS INIT code has workarounds for some of these
+broken SAL symptoms, but some simply cannot be fixed from the OS side.
+
+---
+
+The scheduler hooks used by ia64 (curr_task, set_curr_task) are layer
+violations.  Unfortunately MCA/INIT start off as massive layer
+violations (can occur at _any_ time) and they build from there.
+
+At least ia64 makes an attempt at recovering from hardware errors, but
+it is a difficult problem because of the asynchronous nature of these
+errors.  When processing an unmaskable interrupt we sometimes need
+special code to cope with our inability to take any locks.
+
+---
+
+How is ia64 MCA/INIT different from x86 NMI?
+
+* x86 NMI typically gets delivered to one cpu.  MCA/INIT gets sent to
+  all cpus.
+
+* x86 NMI cannot be nested.  MCA/INIT can be nested, to a depth of 2
+  per cpu.
+
+* x86 has a separate struct task which points to one of multiple kernel
+  stacks.  ia64 has the struct task embedded in the single kernel
+  stack, so switching stack means switching task.
+
+* x86 does not call the BIOS so the NMI handler does not have to worry
+  about any registers having changed.  MCA/INIT can occur while the cpu
+  is in PAL in physical mode, with undefined registers and an undefined
+  kernel stack.
+
+* i386 backtrace is not very sensitive to whether a process is running
+  or not.  ia64 unwind is very, very sensitive to whether a process is
+  running or not.
+
+---
+
+What happens when MCA/INIT is delivered what a cpu is running user
+space code?
+
+The user mode registers are stored in the RSE area of the MCA/INIT on
+entry to the OS and are restored from there on return to SAL, so user
+mode registers are preserved across a recoverable MCA/INIT.  Since the
+OS has no idea what unwind data is available for the user space stack,
+MCA/INIT never tries to backtrace user space.  Which means that the OS
+does not bother making the user space process look like a blocked task,
+i.e. the OS does not copy pt_regs and switch_stack to the user space
+stack.  Also the OS has no idea how big the user space RSE and memory
+stacks are, which makes it too risky to copy the saved state to a user
+mode stack.
+
+---
+
+How do we get a backtrace on the tasks that were running when MCA/INIT
+was delivered?
+
+mca.c:::ia64_mca_modify_original_stack().  That identifies and
+verifies the original kernel stack, copies the dirty registers from
+the MCA/INIT stack's RSE to the original stack's RSE, copies the
+skeleton struct pt_regs and switch_stack to the original stack, fills
+in the skeleton structures from the PAL minstate area and updates the
+original stack's thread.ksp.  That makes the original stack look
+exactly like any other blocked task, i.e. it now appears to be
+sleeping.  To get a backtrace, just start with thread.ksp for the
+original task and unwind like any other sleeping task.
+
+---
+
+How do we identify the tasks that were running when MCA/INIT was
+delivered?
+
+If the previous task has been verified and converted to a blocked
+state, then sos->prev_task on the MCA/INIT stack is updated to point to
+the previous task.  You can look at that field in dumps or debuggers.
+To help distinguish between the handler and the original tasks,
+handlers have _TIF_MCA_INIT set in thread_info.flags.
+
+The sos data is always in the MCA/INIT handler stack, at offset
+MCA_SOS_OFFSET.  You can get that value from mca_asm.h or calculate it
+as KERNEL_STACK_SIZE - sizeof(struct pt_regs) - sizeof(struct
+ia64_sal_os_state), with 16 byte alignment for all structures.
+
+Also the comm field of the MCA/INIT task is modified to include the pid
+of the original task, for humans to use.  For example, a comm field of
+'MCA 12159' means that pid 12159 was running when the MCA was
+delivered.
diff --git a/Documentation/arch/ia64/serial.rst b/Documentation/arch/ia64/serial.rst
new file mode 100644 (file)
index 0000000..1de70c3
--- /dev/null
@@ -0,0 +1,165 @@
+==============
+Serial Devices
+==============
+
+Serial Device Naming
+====================
+
+    As of 2.6.10, serial devices on ia64 are named based on the
+    order of ACPI and PCI enumeration.  The first device in the
+    ACPI namespace (if any) becomes /dev/ttyS0, the second becomes
+    /dev/ttyS1, etc., and PCI devices are named sequentially
+    starting after the ACPI devices.
+
+    Prior to 2.6.10, there were confusing exceptions to this:
+
+       - Firmware on some machines (mostly from HP) provides an HCDP
+         table[1] that tells the kernel about devices that can be used
+         as a serial console.  If the user specified "console=ttyS0"
+         or the EFI ConOut path contained only UART devices, the
+         kernel registered the device described by the HCDP as
+         /dev/ttyS0.
+
+       - If there was no HCDP, we assumed there were UARTs at the
+         legacy COM port addresses (I/O ports 0x3f8 and 0x2f8), so
+         the kernel registered those as /dev/ttyS0 and /dev/ttyS1.
+
+    Any additional ACPI or PCI devices were registered sequentially
+    after /dev/ttyS0 as they were discovered.
+
+    With an HCDP, device names changed depending on EFI configuration
+    and "console=" arguments.  Without an HCDP, device names didn't
+    change, but we registered devices that might not really exist.
+
+    For example, an HP rx1600 with a single built-in serial port
+    (described in the ACPI namespace) plus an MP[2] (a PCI device) has
+    these ports:
+
+      ==========  ==========     ============    ============   =======
+      Type        MMIO           pre-2.6.10      pre-2.6.10     2.6.10+
+                 address
+                                (EFI console    (EFI console
+                                 on builtin)     on MP port)
+      ==========  ==========     ============    ============   =======
+      builtin     0xff5e0000        ttyS0           ttyS1         ttyS0
+      MP UPS      0xf8031000        ttyS1           ttyS2         ttyS1
+      MP Console  0xf8030000        ttyS2           ttyS0         ttyS2
+      MP 2        0xf8030010        ttyS3           ttyS3         ttyS3
+      MP 3        0xf8030038        ttyS4           ttyS4         ttyS4
+      ==========  ==========     ============    ============   =======
+
+Console Selection
+=================
+
+    EFI knows what your console devices are, but it doesn't tell the
+    kernel quite enough to actually locate them.  The DIG64 HCDP
+    table[1] does tell the kernel where potential serial console
+    devices are, but not all firmware supplies it.  Also, EFI supports
+    multiple simultaneous consoles and doesn't tell the kernel which
+    should be the "primary" one.
+
+    So how do you tell Linux which console device to use?
+
+       - If your firmware supplies the HCDP, it is simplest to
+         configure EFI with a single device (either a UART or a VGA
+         card) as the console.  Then you don't need to tell Linux
+         anything; the kernel will automatically use the EFI console.
+
+         (This works only in 2.6.6 or later; prior to that you had
+         to specify "console=ttyS0" to get a serial console.)
+
+       - Without an HCDP, Linux defaults to a VGA console unless you
+         specify a "console=" argument.
+
+    NOTE: Don't assume that a serial console device will be /dev/ttyS0.
+    It might be ttyS1, ttyS2, etc.  Make sure you have the appropriate
+    entries in /etc/inittab (for getty) and /etc/securetty (to allow
+    root login).
+
+Early Serial Console
+====================
+
+    The kernel can't start using a serial console until it knows where
+    the device lives.  Normally this happens when the driver enumerates
+    all the serial devices, which can happen a minute or more after the
+    kernel starts booting.
+
+    2.6.10 and later kernels have an "early uart" driver that works
+    very early in the boot process.  The kernel will automatically use
+    this if the user supplies an argument like "console=uart,io,0x3f8",
+    or if the EFI console path contains only a UART device and the
+    firmware supplies an HCDP.
+
+Troubleshooting Serial Console Problems
+=======================================
+
+    No kernel output after elilo prints "Uncompressing Linux... done":
+
+       - You specified "console=ttyS0" but Linux changed the device
+         to which ttyS0 refers.  Configure exactly one EFI console
+         device[3] and remove the "console=" option.
+
+       - The EFI console path contains both a VGA device and a UART.
+         EFI and elilo use both, but Linux defaults to VGA.  Remove
+         the VGA device from the EFI console path[3].
+
+       - Multiple UARTs selected as EFI console devices.  EFI and
+         elilo use all selected devices, but Linux uses only one.
+         Make sure only one UART is selected in the EFI console
+         path[3].
+
+       - You're connected to an HP MP port[2] but have a non-MP UART
+         selected as EFI console device.  EFI uses the MP as a
+         console device even when it isn't explicitly selected.
+         Either move the console cable to the non-MP UART, or change
+         the EFI console path[3] to the MP UART.
+
+    Long pause (60+ seconds) between "Uncompressing Linux... done" and
+    start of kernel output:
+
+       - No early console because you used "console=ttyS<n>".  Remove
+         the "console=" option if your firmware supplies an HCDP.
+
+       - If you don't have an HCDP, the kernel doesn't know where
+         your console lives until the driver discovers serial
+         devices.  Use "console=uart,io,0x3f8" (or appropriate
+         address for your machine).
+
+    Kernel and init script output works fine, but no "login:" prompt:
+
+       - Add getty entry to /etc/inittab for console tty.  Look for
+         the "Adding console on ttyS<n>" message that tells you which
+         device is the console.
+
+    "login:" prompt, but can't login as root:
+
+       - Add entry to /etc/securetty for console tty.
+
+    No ACPI serial devices found in 2.6.17 or later:
+
+       - Turn on CONFIG_PNP and CONFIG_PNPACPI.  Prior to 2.6.17, ACPI
+         serial devices were discovered by 8250_acpi.  In 2.6.17,
+         8250_acpi was replaced by the combination of 8250_pnp and
+         CONFIG_PNPACPI.
+
+
+
+[1]
+    http://www.dig64.org/specifications/agreement
+    The table was originally defined as the "HCDP" for "Headless
+    Console/Debug Port."  The current version is the "PCDP" for
+    "Primary Console and Debug Port Devices."
+
+[2]
+    The HP MP (management processor) is a PCI device that provides
+    several UARTs.  One of the UARTs is often used as a console; the
+    EFI Boot Manager identifies it as "Acpi(HWP0002,700)/Pci(...)/Uart".
+    The external connection is usually a 25-pin connector, and a
+    special dongle converts that to three 9-pin connectors, one of
+    which is labelled "Console."
+
+[3]
+    EFI console devices are configured using the EFI Boot Manager
+    "Boot option maintenance" menu.  You may have to interrupt the
+    boot sequence to use this menu, and you will have to reset the
+    box after changing console configuration.
diff --git a/Documentation/arch/index.rst b/Documentation/arch/index.rst
new file mode 100644 (file)
index 0000000..80ee310
--- /dev/null
@@ -0,0 +1,28 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+CPU Architectures
+=================
+
+These books provide programming details about architecture-specific
+implementation.
+
+.. toctree::
+   :maxdepth: 2
+
+   arc/index
+   ../arm/index
+   ../arm64/index
+   ia64/index
+   ../loongarch/index
+   m68k/index
+   ../mips/index
+   nios2/index
+   openrisc/index
+   parisc/index
+   ../powerpc/index
+   ../riscv/index
+   ../s390/index
+   sh/index
+   sparc/index
+   x86/index
+   xtensa/index
diff --git a/Documentation/arch/m68k/buddha-driver.rst b/Documentation/arch/m68k/buddha-driver.rst
new file mode 100644 (file)
index 0000000..20e4014
--- /dev/null
@@ -0,0 +1,209 @@
+=====================================
+Amiga Buddha and Catweasel IDE Driver
+=====================================
+
+The Amiga Buddha and Catweasel IDE Driver (part of ide.c) was written by
+Geert Uytterhoeven based on the following specifications:
+
+------------------------------------------------------------------------
+
+Register map of the Buddha IDE controller and the
+Buddha-part of the Catweasel Zorro-II version
+
+The Autoconfiguration has been implemented just as Commodore
+described  in  their  manuals, no tricks have been used (for
+example leaving some address lines out of the equations...).
+If you want to configure the board yourself (for example let
+a  Linux  kernel  configure the card), look at the Commodore
+Docs.  Reading the nibbles should give this information::
+
+  Vendor number: 4626 ($1212)
+  product number: 0 (42 for Catweasel Z-II)
+  Serial number: 0
+  Rom-vector: $1000
+
+The  card  should be a Z-II board, size 64K, not for freemem
+list, Rom-Vektor is valid, no second Autoconfig-board on the
+same card, no space preference, supports "Shutup_forever".
+
+Setting  the  base address should be done in two steps, just
+as  the Amiga Kickstart does:  The lower nibble of the 8-Bit
+address is written to $4a, then the whole Byte is written to
+$48, while it doesn't matter how often you're writing to $4a
+as  long as $48 is not touched.  After $48 has been written,
+the  whole card disappears from $e8 and is mapped to the new
+address just written.  Make sure $4a is written before $48,
+otherwise your chance is only 1:16 to find the board :-).
+
+The local memory-map is even active when mapped to $e8:
+
+==============  ===========================================
+$0-$7e         Autokonfig-space, see Z-II docs.
+
+$80-$7fd       reserved
+
+$7fe           Speed-select Register: Read & Write
+               (description see further down)
+
+$800-$8ff      IDE-Select 0 (Port 0, Register set 0)
+
+$900-$9ff      IDE-Select 1 (Port 0, Register set 1)
+
+$a00-$aff      IDE-Select 2 (Port 1, Register set 0)
+
+$b00-$bff      IDE-Select 3 (Port 1, Register set 1)
+
+$c00-$cff      IDE-Select 4 (Port 2, Register set 0,
+                Catweasel only!)
+
+$d00-$dff      IDE-Select 5 (Port 3, Register set 1,
+               Catweasel only!)
+
+$e00-$eff      local expansion port, on Catweasel Z-II the
+               Catweasel registers are also mapped here.
+               Never touch, use multidisk.device!
+
+$f00           read only, Byte-access: Bit 7 shows the
+               level of the IRQ-line of IDE port 0.
+
+$f01-$f3f      mirror of $f00
+
+$f40           read only, Byte-access: Bit 7 shows the
+               level of the IRQ-line of IDE port 1.
+
+$f41-$f7f      mirror of $f40
+
+$f80           read only, Byte-access: Bit 7 shows the
+               level of the IRQ-line of IDE port 2.
+               (Catweasel only!)
+
+$f81-$fbf      mirror of $f80
+
+$fc0           write-only: Writing any value to this
+               register enables IRQs to be passed from the
+               IDE ports to the Zorro bus. This mechanism
+               has been implemented to be compatible with
+               harddisks that are either defective or have
+               a buggy firmware and pull the IRQ line up
+               while starting up. If interrupts would
+               always be passed to the bus, the computer
+               might not start up. Once enabled, this flag
+               can not be disabled again. The level of the
+               flag can not be determined by software
+               (what for? Write to me if it's necessary!).
+
+$fc1-$fff      mirror of $fc0
+
+$1000-$ffff    Buddha-Rom with offset $1000 in the rom
+               chip. The addresses $0 to $fff of the rom
+               chip cannot be read. Rom is Byte-wide and
+               mapped to even addresses.
+==============  ===========================================
+
+The  IDE ports issue an INT2.  You can read the level of the
+IRQ-lines  of  the  IDE-ports by reading from the three (two
+for  Buddha-only)  registers  $f00, $f40 and $f80.  This way
+more  than one I/O request can be handled and you can easily
+determine  what  driver  has  to serve the INT2.  Buddha and
+Catweasel  expansion  boards  can issue an INT6.  A separate
+memory  map  is available for the I/O module and the sysop's
+I/O module.
+
+The IDE ports are fed by the address lines A2 to A4, just as
+the  Amiga  1200  and  Amiga  4000  IDE ports are.  This way
+existing  drivers  can be easily ported to Buddha.  A move.l
+polls  two  words  out of the same address of IDE port since
+every  word  is  mirrored  once.  movem is not possible, but
+it's  not  necessary  either,  because  you can only speedup
+68000  systems  with  this  technique.   A 68020 system with
+fastmem is faster with move.l.
+
+If you're using the mirrored registers of the IDE-ports with
+A6=1,  the Buddha doesn't care about the speed that you have
+selected  in  the  speed  register (see further down).  With
+A6=1  (for example $840 for port 0, register set 0), a 780ns
+access  is being made.  These registers should be used for a
+command   access   to  the  harddisk/CD-Rom,  since  command
+accesses  are Byte-wide and have to be made slower according
+to the ATA-X3T9 manual.
+
+Now  for the speed-register:  The register is byte-wide, and
+only  the  upper  three  bits are used (Bits 7 to 5).  Bit 4
+must  always  be set to 1 to be compatible with later Buddha
+versions  (if  I'll  ever  update this one).  I presume that
+I'll  never use the lower four bits, but they have to be set
+to 1 by definition.
+
+The  values in this table have to be shifted 5 bits to the
+left and or'd with $1f (this sets the lower 5 bits).
+
+All  the timings have in common:  Select and IOR/IOW rise at
+the  same  time.   IOR  and  IOW have a propagation delay of
+about  30ns  to  the clocks on the Zorro bus, that's why the
+values  are no multiple of 71.  One clock-cycle is 71ns long
+(exactly 70,5 at 14,18 Mhz on PAL systems).
+
+value 0 (Default after reset)
+  497ns Select (7 clock cycles) , IOR/IOW after 172ns (2 clock cycles)
+  (same timing as the Amiga 1200 does on it's IDE port without
+  accelerator card)
+
+value 1
+  639ns Select (9 clock cycles), IOR/IOW after 243ns (3 clock cycles)
+
+value 2
+  781ns Select (11 clock cycles), IOR/IOW after 314ns (4 clock cycles)
+
+value 3
+  355ns Select (5 clock cycles), IOR/IOW after 101ns (1 clock cycle)
+
+value 4
+  355ns Select (5 clock cycles), IOR/IOW after 172ns (2 clock cycles)
+
+value 5
+  355ns Select (5 clock cycles), IOR/IOW after 243ns (3 clock cycles)
+
+value 6
+  1065ns Select (15 clock cycles), IOR/IOW after 314ns (4 clock cycles)
+
+value 7
+  355ns Select, (5 clock cycles), IOR/IOW after 101ns (1 clock cycle)
+
+When accessing IDE registers with A6=1 (for example $84x),
+the timing will always be mode 0 8-bit compatible, no matter
+what you have selected in the speed register:
+
+781ns select, IOR/IOW after 4 clock cycles (=314ns) aktive.
+
+All  the  timings with a very short select-signal (the 355ns
+fast  accesses)  depend  on the accelerator card used in the
+system:  Sometimes two more clock cycles are inserted by the
+bus  interface,  making  the  whole access 497ns long.  This
+doesn't  affect  the  reliability  of the controller nor the
+performance  of  the  card,  since  this doesn't happen very
+often.
+
+All  the  timings  are  calculated  and  only  confirmed  by
+measurements  that allowed me to count the clock cycles.  If
+the  system  is clocked by an oscillator other than 28,37516
+Mhz  (for  example  the  NTSC-frequency  28,63636 Mhz), each
+clock  cycle is shortened to a bit less than 70ns (not worth
+mentioning).   You  could think of a small performance boost
+by  overclocking  the  system,  but  you would either need a
+multisync  monitor,  or  a  graphics card, and your internal
+diskdrive would go crazy, that's why you shouldn't tune your
+Amiga this way.
+
+Giving  you  the  possibility  to  write  software  that  is
+compatible  with both the Buddha and the Catweasel Z-II, The
+Buddha  acts  just  like  a  Catweasel  Z-II  with no device
+connected  to  the  third  IDE-port.   The IRQ-register $f80
+always  shows a "no IRQ here" on the Buddha, and accesses to
+the  third  IDE  port  are  going into data's Nirwana on the
+Buddha.
+
+Jens Schönfeld february 19th, 1997
+
+updated may 27th, 1997
+
+eMail: sysop@nostlgic.tng.oche.de
diff --git a/Documentation/arch/m68k/features.rst b/Documentation/arch/m68k/features.rst
new file mode 100644 (file)
index 0000000..5107a21
--- /dev/null
@@ -0,0 +1,3 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. kernel-feat:: $srctree/Documentation/features m68k
diff --git a/Documentation/arch/m68k/index.rst b/Documentation/arch/m68k/index.rst
new file mode 100644 (file)
index 0000000..0f890db
--- /dev/null
@@ -0,0 +1,20 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=================
+m68k Architecture
+=================
+
+.. toctree::
+   :maxdepth: 2
+
+   kernel-options
+   buddha-driver
+
+   features
+
+.. only::  subproject and html
+
+   Indices
+   =======
+
+   * :ref:`genindex`
diff --git a/Documentation/arch/m68k/kernel-options.rst b/Documentation/arch/m68k/kernel-options.rst
new file mode 100644 (file)
index 0000000..2008a20
--- /dev/null
@@ -0,0 +1,911 @@
+===================================
+Command Line Options for Linux/m68k
+===================================
+
+Last Update: 2 May 1999
+
+Linux/m68k version: 2.2.6
+
+Author: Roman.Hodek@informatik.uni-erlangen.de (Roman Hodek)
+
+Update: jds@kom.auc.dk (Jes Sorensen) and faq@linux-m68k.org (Chris Lawrence)
+
+0) Introduction
+===============
+
+Often I've been asked which command line options the Linux/m68k
+kernel understands, or how the exact syntax for the ... option is, or
+... about the option ... . I hope, this document supplies all the
+answers...
+
+Note that some options might be outdated, their descriptions being
+incomplete or missing. Please update the information and send in the
+patches.
+
+
+1) Overview of the Kernel's Option Processing
+=============================================
+
+The kernel knows three kinds of options on its command line:
+
+  1) kernel options
+  2) environment settings
+  3) arguments for init
+
+To which of these classes an argument belongs is determined as
+follows: If the option is known to the kernel itself, i.e. if the name
+(the part before the '=') or, in some cases, the whole argument string
+is known to the kernel, it belongs to class 1. Otherwise, if the
+argument contains an '=', it is of class 2, and the definition is put
+into init's environment. All other arguments are passed to init as
+command line options.
+
+This document describes the valid kernel options for Linux/m68k in
+the version mentioned at the start of this file. Later revisions may
+add new such options, and some may be missing in older versions.
+
+In general, the value (the part after the '=') of an option is a
+list of values separated by commas. The interpretation of these values
+is up to the driver that "owns" the option. This association of
+options with drivers is also the reason that some are further
+subdivided.
+
+
+2) General Kernel Options
+=========================
+
+2.1) root=
+----------
+
+:Syntax: root=/dev/<device>
+:or:     root=<hex_number>
+
+This tells the kernel which device it should mount as the root
+filesystem. The device must be a block device with a valid filesystem
+on it.
+
+The first syntax gives the device by name. These names are converted
+into a major/minor number internally in the kernel in an unusual way.
+Normally, this "conversion" is done by the device files in /dev, but
+this isn't possible here, because the root filesystem (with /dev)
+isn't mounted yet... So the kernel parses the name itself, with some
+hardcoded name to number mappings. The name must always be a
+combination of two or three letters, followed by a decimal number.
+Valid names are::
+
+  /dev/ram: -> 0x0100 (initial ramdisk)
+  /dev/hda: -> 0x0300 (first IDE disk)
+  /dev/hdb: -> 0x0340 (second IDE disk)
+  /dev/sda: -> 0x0800 (first SCSI disk)
+  /dev/sdb: -> 0x0810 (second SCSI disk)
+  /dev/sdc: -> 0x0820 (third SCSI disk)
+  /dev/sdd: -> 0x0830 (forth SCSI disk)
+  /dev/sde: -> 0x0840 (fifth SCSI disk)
+  /dev/fd : -> 0x0200 (floppy disk)
+
+The name must be followed by a decimal number, that stands for the
+partition number. Internally, the value of the number is just
+added to the device number mentioned in the table above. The
+exceptions are /dev/ram and /dev/fd, where /dev/ram refers to an
+initial ramdisk loaded by your bootstrap program (please consult the
+instructions for your bootstrap program to find out how to load an
+initial ramdisk). As of kernel version 2.0.18 you must specify
+/dev/ram as the root device if you want to boot from an initial
+ramdisk. For the floppy devices, /dev/fd, the number stands for the
+floppy drive number (there are no partitions on floppy disks). I.e.,
+/dev/fd0 stands for the first drive, /dev/fd1 for the second, and so
+on. Since the number is just added, you can also force the disk format
+by adding a number greater than 3. If you look into your /dev
+directory, use can see the /dev/fd0D720 has major 2 and minor 16. You
+can specify this device for the root FS by writing "root=/dev/fd16" on
+the kernel command line.
+
+[Strange and maybe uninteresting stuff ON]
+
+This unusual translation of device names has some strange
+consequences: If, for example, you have a symbolic link from /dev/fd
+to /dev/fd0D720 as an abbreviation for floppy driver #0 in DD format,
+you cannot use this name for specifying the root device, because the
+kernel cannot see this symlink before mounting the root FS and it
+isn't in the table above. If you use it, the root device will not be
+set at all, without an error message. Another example: You cannot use a
+partition on e.g. the sixth SCSI disk as the root filesystem, if you
+want to specify it by name. This is, because only the devices up to
+/dev/sde are in the table above, but not /dev/sdf. Although, you can
+use the sixth SCSI disk for the root FS, but you have to specify the
+device by number... (see below). Or, even more strange, you can use the
+fact that there is no range checking of the partition number, and your
+knowledge that each disk uses 16 minors, and write "root=/dev/sde17"
+(for /dev/sdf1).
+
+[Strange and maybe uninteresting stuff OFF]
+
+If the device containing your root partition isn't in the table
+above, you can also specify it by major and minor numbers. These are
+written in hex, with no prefix and no separator between. E.g., if you
+have a CD with contents appropriate as a root filesystem in the first
+SCSI CD-ROM drive, you boot from it by "root=0b00". Here, hex "0b" =
+decimal 11 is the major of SCSI CD-ROMs, and the minor 0 stands for
+the first of these. You can find out all valid major numbers by
+looking into include/linux/major.h.
+
+In addition to major and minor numbers, if the device containing your
+root partition uses a partition table format with unique partition
+identifiers, then you may use them.  For instance,
+"root=PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF".  It is also
+possible to reference another partition on the same device using a
+known partition UUID as the starting point.  For example,
+if partition 5 of the device has the UUID of
+00112233-4455-6677-8899-AABBCCDDEEFF then partition 3 may be found as
+follows:
+
+  PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF/PARTNROFF=-2
+
+Authoritative information can be found in
+"Documentation/admin-guide/kernel-parameters.rst".
+
+
+2.2) ro, rw
+-----------
+
+:Syntax: ro
+:or:     rw
+
+These two options tell the kernel whether it should mount the root
+filesystem read-only or read-write. The default is read-only, except
+for ramdisks, which default to read-write.
+
+
+2.3) debug
+----------
+
+:Syntax: debug
+
+This raises the kernel log level to 10 (the default is 7). This is the
+same level as set by the "dmesg" command, just that the maximum level
+selectable by dmesg is 8.
+
+
+2.4) debug=
+-----------
+
+:Syntax: debug=<device>
+
+This option causes certain kernel messages be printed to the selected
+debugging device. This can aid debugging the kernel, since the
+messages can be captured and analyzed on some other machine. Which
+devices are possible depends on the machine type. There are no checks
+for the validity of the device name. If the device isn't implemented,
+nothing happens.
+
+Messages logged this way are in general stack dumps after kernel
+memory faults or bad kernel traps, and kernel panics. To be exact: all
+messages of level 0 (panic messages) and all messages printed while
+the log level is 8 or more (their level doesn't matter). Before stack
+dumps, the kernel sets the log level to 10 automatically. A level of
+at least 8 can also be set by the "debug" command line option (see
+2.3) and at run time with "dmesg -n 8".
+
+Devices possible for Amiga:
+
+ - "ser":
+         built-in serial port; parameters: 9600bps, 8N1
+ - "mem":
+         Save the messages to a reserved area in chip mem. After
+          rebooting, they can be read under AmigaOS with the tool
+          'dmesg'.
+
+Devices possible for Atari:
+
+ - "ser1":
+          ST-MFP serial port ("Modem1"); parameters: 9600bps, 8N1
+ - "ser2":
+          SCC channel B serial port ("Modem2"); parameters: 9600bps, 8N1
+ - "ser" :
+          default serial port
+           This is "ser2" for a Falcon, and "ser1" for any other machine
+ - "midi":
+          The MIDI port; parameters: 31250bps, 8N1
+ - "par" :
+          parallel port
+
+           The printing routine for this implements a timeout for the
+           case there's no printer connected (else the kernel would
+           lock up). The timeout is not exact, but usually a few
+           seconds.
+
+
+2.6) ramdisk_size=
+------------------
+
+:Syntax: ramdisk_size=<size>
+
+This option instructs the kernel to set up a ramdisk of the given
+size in KBytes. Do not use this option if the ramdisk contents are
+passed by bootstrap! In this case, the size is selected automatically
+and should not be overwritten.
+
+The only application is for root filesystems on floppy disks, that
+should be loaded into memory. To do that, select the corresponding
+size of the disk as ramdisk size, and set the root device to the disk
+drive (with "root=").
+
+
+2.7) swap=
+
+  I can't find any sign of this option in 2.2.6.
+
+2.8) buff=
+-----------
+
+  I can't find any sign of this option in 2.2.6.
+
+
+3) General Device Options (Amiga and Atari)
+===========================================
+
+3.1) ether=
+-----------
+
+:Syntax: ether=[<irq>[,<base_addr>[,<mem_start>[,<mem_end>]]]],<dev-name>
+
+<dev-name> is the name of a net driver, as specified in
+drivers/net/Space.c in the Linux source. Most prominent are eth0, ...
+eth3, sl0, ... sl3, ppp0, ..., ppp3, dummy, and lo.
+
+The non-ethernet drivers (sl, ppp, dummy, lo) obviously ignore the
+settings by this options. Also, the existing ethernet drivers for
+Linux/m68k (ariadne, a2065, hydra) don't use them because Zorro boards
+are really Plug-'n-Play, so the "ether=" option is useless altogether
+for Linux/m68k.
+
+
+3.2) hd=
+--------
+
+:Syntax: hd=<cylinders>,<heads>,<sectors>
+
+This option sets the disk geometry of an IDE disk. The first hd=
+option is for the first IDE disk, the second for the second one.
+(I.e., you can give this option twice.) In most cases, you won't have
+to use this option, since the kernel can obtain the geometry data
+itself. It exists just for the case that this fails for one of your
+disks.
+
+
+3.3) max_scsi_luns=
+-------------------
+
+:Syntax: max_scsi_luns=<n>
+
+Sets the maximum number of LUNs (logical units) of SCSI devices to
+be scanned. Valid values for <n> are between 1 and 8. Default is 8 if
+"Probe all LUNs on each SCSI device" was selected during the kernel
+configuration, else 1.
+
+
+3.4) st=
+--------
+
+:Syntax: st=<buffer_size>,[<write_thres>,[<max_buffers>]]
+
+Sets several parameters of the SCSI tape driver. <buffer_size> is
+the number of 512-byte buffers reserved for tape operations for each
+device. <write_thres> sets the number of blocks which must be filled
+to start an actual write operation to the tape. Maximum value is the
+total number of buffers. <max_buffer> limits the total number of
+buffers allocated for all tape devices.
+
+
+3.5) dmasound=
+--------------
+
+:Syntax: dmasound=[<buffers>,<buffer-size>[,<catch-radius>]]
+
+This option controls some configurations of the Linux/m68k DMA sound
+driver (Amiga and Atari): <buffers> is the number of buffers you want
+to use (minimum 4, default 4), <buffer-size> is the size of each
+buffer in kilobytes (minimum 4, default 32) and <catch-radius> says
+how much percent of error will be tolerated when setting a frequency
+(maximum 10, default 0). For example with 3% you can play 8000Hz
+AU-Files on the Falcon with its hardware frequency of 8195Hz and thus
+don't need to expand the sound.
+
+
+
+4) Options for Atari Only
+=========================
+
+4.1) video=
+-----------
+
+:Syntax: video=<fbname>:<sub-options...>
+
+The <fbname> parameter specifies the name of the frame buffer,
+eg. most atari users will want to specify `atafb` here. The
+<sub-options> is a comma-separated list of the sub-options listed
+below.
+
+NB:
+    Please notice that this option was renamed from `atavideo` to
+    `video` during the development of the 1.3.x kernels, thus you
+    might need to update your boot-scripts if upgrading to 2.x from
+    an 1.2.x kernel.
+
+NBB:
+    The behavior of video= was changed in 2.1.57 so the recommended
+    option is to specify the name of the frame buffer.
+
+4.1.1) Video Mode
+-----------------
+
+This sub-option may be any of the predefined video modes, as listed
+in atari/atafb.c in the Linux/m68k source tree. The kernel will
+activate the given video mode at boot time and make it the default
+mode, if the hardware allows. Currently defined names are:
+
+ - stlow           : 320x200x4
+ - stmid, default5 : 640x200x2
+ - sthigh, default4: 640x400x1
+ - ttlow           : 320x480x8, TT only
+ - ttmid, default1 : 640x480x4, TT only
+ - tthigh, default2: 1280x960x1, TT only
+ - vga2            : 640x480x1, Falcon only
+ - vga4            : 640x480x2, Falcon only
+ - vga16, default3 : 640x480x4, Falcon only
+ - vga256          : 640x480x8, Falcon only
+ - falh2           : 896x608x1, Falcon only
+ - falh16          : 896x608x4, Falcon only
+
+If no video mode is given on the command line, the kernel tries the
+modes names "default<n>" in turn, until one is possible with the
+hardware in use.
+
+A video mode setting doesn't make sense, if the external driver is
+activated by a "external:" sub-option.
+
+4.1.2) inverse
+--------------
+
+Invert the display. This affects only text consoles.
+Usually, the background is chosen to be black. With this
+option, you can make the background white.
+
+4.1.3) font
+-----------
+
+:Syntax: font:<fontname>
+
+Specify the font to use in text modes. Currently you can choose only
+between `VGA8x8`, `VGA8x16` and `PEARL8x8`. `VGA8x8` is default, if the
+vertical size of the display is less than 400 pixel rows. Otherwise, the
+`VGA8x16` font is the default.
+
+4.1.4) `hwscroll_`
+------------------
+
+:Syntax: `hwscroll_<n>`
+
+The number of additional lines of video memory to reserve for
+speeding up the scrolling ("hardware scrolling"). Hardware scrolling
+is possible only if the kernel can set the video base address in steps
+fine enough. This is true for STE, MegaSTE, TT, and Falcon. It is not
+possible with plain STs and graphics cards (The former because the
+base address must be on a 256 byte boundary there, the latter because
+the kernel doesn't know how to set the base address at all.)
+
+By default, <n> is set to the number of visible text lines on the
+display. Thus, the amount of video memory is doubled, compared to no
+hardware scrolling. You can turn off the hardware scrolling altogether
+by setting <n> to 0.
+
+4.1.5) internal:
+----------------
+
+:Syntax: internal:<xres>;<yres>[;<xres_max>;<yres_max>;<offset>]
+
+This option specifies the capabilities of some extended internal video
+hardware, like e.g. OverScan. <xres> and <yres> give the (extended)
+dimensions of the screen.
+
+If your OverScan needs a black border, you have to write the last
+three arguments of the "internal:". <xres_max> is the maximum line
+length the hardware allows, <yres_max> the maximum number of lines.
+<offset> is the offset of the visible part of the screen memory to its
+physical start, in bytes.
+
+Often, extended interval video hardware has to be activated somehow.
+For this, see the "sw_*" options below.
+
+4.1.6) external:
+----------------
+
+:Syntax:
+  external:<xres>;<yres>;<depth>;<org>;<scrmem>[;<scrlen>[;<vgabase>
+  [;<colw>[;<coltype>[;<xres_virtual>]]]]]
+
+.. I had to break this line...
+
+This is probably the most complicated parameter... It specifies that
+you have some external video hardware (a graphics board), and how to
+use it under Linux/m68k. The kernel cannot know more about the hardware
+than you tell it here! The kernel also is unable to set or change any
+video modes, since it doesn't know about any board internal. So, you
+have to switch to that video mode before you start Linux, and cannot
+switch to another mode once Linux has started.
+
+The first 3 parameters of this sub-option should be obvious: <xres>,
+<yres> and <depth> give the dimensions of the screen and the number of
+planes (depth). The depth is the logarithm to base 2 of the number
+of colors possible. (Or, the other way round: The number of colors is
+2^depth).
+
+You have to tell the kernel furthermore how the video memory is
+organized. This is done by a letter as <org> parameter:
+
+ 'n':
+      "normal planes", i.e. one whole plane after another
+ 'i':
+      "interleaved planes", i.e. 16 bit of the first plane, than 16 bit
+      of the next, and so on... This mode is used only with the
+      built-in Atari video modes, I think there is no card that
+      supports this mode.
+ 'p':
+      "packed pixels", i.e. <depth> consecutive bits stand for all
+      planes of one pixel; this is the most common mode for 8 planes
+      (256 colors) on graphic cards
+ 't':
+      "true color" (more or less packed pixels, but without a color
+      lookup table); usually depth is 24
+
+For monochrome modes (i.e., <depth> is 1), the <org> letter has a
+different meaning:
+
+ 'n':
+      normal colors, i.e. 0=white, 1=black
+ 'i':
+      inverted colors, i.e. 0=black, 1=white
+
+The next important information about the video hardware is the base
+address of the video memory. That is given in the <scrmem> parameter,
+as a hexadecimal number with a "0x" prefix. You have to find out this
+address in the documentation of your hardware.
+
+The next parameter, <scrlen>, tells the kernel about the size of the
+video memory. If it's missing, the size is calculated from <xres>,
+<yres>, and <depth>. For now, it is not useful to write a value here.
+It would be used only for hardware scrolling (which isn't possible
+with the external driver, because the kernel cannot set the video base
+address), or for virtual resolutions under X (which the X server
+doesn't support yet). So, it's currently best to leave this field
+empty, either by ending the "external:" after the video address or by
+writing two consecutive semicolons, if you want to give a <vgabase>
+(it is allowed to leave this parameter empty).
+
+The <vgabase> parameter is optional. If it is not given, the kernel
+cannot read or write any color registers of the video hardware, and
+thus you have to set appropriate colors before you start Linux. But if
+your card is somehow VGA compatible, you can tell the kernel the base
+address of the VGA register set, so it can change the color lookup
+table. You have to look up this address in your board's documentation.
+To avoid misunderstandings: <vgabase> is the _base_ address, i.e. a 4k
+aligned address. For read/writing the color registers, the kernel
+uses the addresses vgabase+0x3c7...vgabase+0x3c9. The <vgabase>
+parameter is written in hexadecimal with a "0x" prefix, just as
+<scrmem>.
+
+<colw> is meaningful only if <vgabase> is specified. It tells the
+kernel how wide each of the color register is, i.e. the number of bits
+per single color (red/green/blue). Default is 6, another quite usual
+value is 8.
+
+Also <coltype> is used together with <vgabase>. It tells the kernel
+about the color register model of your gfx board. Currently, the types
+"vga" (which is also the default) and "mv300" (SANG MV300) are
+implemented.
+
+Parameter <xres_virtual> is required for ProMST or ET4000 cards where
+the physical linelength differs from the visible length. With ProMST,
+xres_virtual must be set to 2048. For ET4000, xres_virtual depends on the
+initialisation of the video-card.
+If you're missing a corresponding yres_virtual: the external part is legacy,
+therefore we don't support hardware-dependent functions like hardware-scroll,
+panning or blanking.
+
+4.1.7) eclock:
+--------------
+
+The external pixel clock attached to the Falcon VIDEL shifter. This
+currently works only with the ScreenWonder!
+
+4.1.8) monitorcap:
+-------------------
+
+:Syntax: monitorcap:<vmin>;<vmax>;<hmin>;<hmax>
+
+This describes the capabilities of a multisync monitor. Don't use it
+with a fixed-frequency monitor! For now, only the Falcon frame buffer
+uses the settings of "monitorcap:".
+
+<vmin> and <vmax> are the minimum and maximum, resp., vertical frequencies
+your monitor can work with, in Hz. <hmin> and <hmax> are the same for
+the horizontal frequency, in kHz.
+
+  The defaults are 58;62;31;32 (VGA compatible).
+
+  The defaults for TV/SC1224/SC1435 cover both PAL and NTSC standards.
+
+4.1.9) keep
+------------
+
+If this option is given, the framebuffer device doesn't do any video
+mode calculations and settings on its own. The only Atari fb device
+that does this currently is the Falcon.
+
+What you reach with this: Settings for unknown video extensions
+aren't overridden by the driver, so you can still use the mode found
+when booting, when the driver doesn't know to set this mode itself.
+But this also means, that you can't switch video modes anymore...
+
+An example where you may want to use "keep" is the ScreenBlaster for
+the Falcon.
+
+
+4.2) atamouse=
+--------------
+
+:Syntax: atamouse=<x-threshold>,[<y-threshold>]
+
+With this option, you can set the mouse movement reporting threshold.
+This is the number of pixels of mouse movement that have to accumulate
+before the IKBD sends a new mouse packet to the kernel. Higher values
+reduce the mouse interrupt load and thus reduce the chance of keyboard
+overruns. Lower values give a slightly faster mouse responses and
+slightly better mouse tracking.
+
+You can set the threshold in x and y separately, but usually this is
+of little practical use. If there's just one number in the option, it
+is used for both dimensions. The default value is 2 for both
+thresholds.
+
+
+4.3) ataflop=
+-------------
+
+:Syntax: ataflop=<drive type>[,<trackbuffering>[,<steprateA>[,<steprateB>]]]
+
+   The drive type may be 0, 1, or 2, for DD, HD, and ED, resp. This
+   setting affects how many buffers are reserved and which formats are
+   probed (see also below). The default is 1 (HD). Only one drive type
+   can be selected. If you have two disk drives, select the "better"
+   type.
+
+   The second parameter <trackbuffer> tells the kernel whether to use
+   track buffering (1) or not (0). The default is machine-dependent:
+   no for the Medusa and yes for all others.
+
+   With the two following parameters, you can change the default
+   steprate used for drive A and B, resp.
+
+
+4.4) atascsi=
+-------------
+
+:Syntax: atascsi=<can_queue>[,<cmd_per_lun>[,<scat-gat>[,<host-id>[,<tagged>]]]]
+
+This option sets some parameters for the Atari native SCSI driver.
+Generally, any number of arguments can be omitted from the end. And
+for each of the numbers, a negative value means "use default". The
+defaults depend on whether TT-style or Falcon-style SCSI is used.
+Below, defaults are noted as n/m, where the first value refers to
+TT-SCSI and the latter to Falcon-SCSI. If an illegal value is given
+for one parameter, an error message is printed and that one setting is
+ignored (others aren't affected).
+
+  <can_queue>:
+    This is the maximum number of SCSI commands queued internally to the
+    Atari SCSI driver. A value of 1 effectively turns off the driver
+    internal multitasking (if it causes problems). Legal values are >=
+    1. <can_queue> can be as high as you like, but values greater than
+    <cmd_per_lun> times the number of SCSI targets (LUNs) you have
+    don't make sense. Default: 16/8.
+
+  <cmd_per_lun>:
+    Maximum number of SCSI commands issued to the driver for one
+    logical unit (LUN, usually one SCSI target). Legal values start
+    from 1. If tagged queuing (see below) is not used, values greater
+    than 2 don't make sense, but waste memory. Otherwise, the maximum
+    is the number of command tags available to the driver (currently
+    32). Default: 8/1. (Note: Values > 1 seem to cause problems on a
+    Falcon, cause not yet known.)
+
+    The <cmd_per_lun> value at a great part determines the amount of
+    memory SCSI reserves for itself. The formula is rather
+    complicated, but I can give you some hints:
+
+      no scatter-gather:
+       cmd_per_lun * 232 bytes
+      full scatter-gather:
+       cmd_per_lun * approx. 17 Kbytes
+
+  <scat-gat>:
+    Size of the scatter-gather table, i.e. the number of requests
+    consecutive on the disk that can be merged into one SCSI command.
+    Legal values are between 0 and 255. Default: 255/0. Note: This
+    value is forced to 0 on a Falcon, since scatter-gather isn't
+    possible with the ST-DMA. Not using scatter-gather hurts
+    performance significantly.
+
+  <host-id>:
+    The SCSI ID to be used by the initiator (your Atari). This is
+    usually 7, the highest possible ID. Every ID on the SCSI bus must
+    be unique. Default: determined at run time: If the NV-RAM checksum
+    is valid, and bit 7 in byte 30 of the NV-RAM is set, the lower 3
+    bits of this byte are used as the host ID. (This method is defined
+    by Atari and also used by some TOS HD drivers.) If the above
+    isn't given, the default ID is 7. (both, TT and Falcon).
+
+  <tagged>:
+    0 means turn off tagged queuing support, all other values > 0 mean
+    use tagged queuing for targets that support it. Default: currently
+    off, but this may change when tagged queuing handling has been
+    proved to be reliable.
+
+    Tagged queuing means that more than one command can be issued to
+    one LUN, and the SCSI device itself orders the requests so they
+    can be performed in optimal order. Not all SCSI devices support
+    tagged queuing (:-().
+
+4.5 switches=
+-------------
+
+:Syntax: switches=<list of switches>
+
+With this option you can switch some hardware lines that are often
+used to enable/disable certain hardware extensions. Examples are
+OverScan, overclocking, ...
+
+The <list of switches> is a comma-separated list of the following
+items:
+
+  ikbd:
+       set RTS of the keyboard ACIA high
+  midi:
+       set RTS of the MIDI ACIA high
+  snd6:
+       set bit 6 of the PSG port A
+  snd7:
+       set bit 6 of the PSG port A
+
+It doesn't make sense to mention a switch more than once (no
+difference to only once), but you can give as many switches as you
+want to enable different features. The switch lines are set as early
+as possible during kernel initialization (even before determining the
+present hardware.)
+
+All of the items can also be prefixed with `ov_`, i.e. `ov_ikbd`,
+`ov_midi`, ... These options are meant for switching on an OverScan
+video extension. The difference to the bare option is that the
+switch-on is done after video initialization, and somehow synchronized
+to the HBLANK. A speciality is that ov_ikbd and ov_midi are switched
+off before rebooting, so that OverScan is disabled and TOS boots
+correctly.
+
+If you give an option both, with and without the `ov_` prefix, the
+earlier initialization (`ov_`-less) takes precedence. But the
+switching-off on reset still happens in this case.
+
+5) Options for Amiga Only:
+==========================
+
+5.1) video=
+-----------
+
+:Syntax: video=<fbname>:<sub-options...>
+
+The <fbname> parameter specifies the name of the frame buffer, valid
+options are `amifb`, `cyber`, 'virge', `retz3` and `clgen`, provided
+that the respective frame buffer devices have been compiled into the
+kernel (or compiled as loadable modules). The behavior of the <fbname>
+option was changed in 2.1.57 so it is now recommended to specify this
+option.
+
+The <sub-options> is a comma-separated list of the sub-options listed
+below. This option is organized similar to the Atari version of the
+"video"-option (4.1), but knows fewer sub-options.
+
+5.1.1) video mode
+-----------------
+
+Again, similar to the video mode for the Atari (see 4.1.1). Predefined
+modes depend on the used frame buffer device.
+
+OCS, ECS and AGA machines all use the color frame buffer. The following
+predefined video modes are available:
+
+NTSC modes:
+ - ntsc            : 640x200, 15 kHz, 60 Hz
+ - ntsc-lace       : 640x400, 15 kHz, 60 Hz interlaced
+
+PAL modes:
+ - pal             : 640x256, 15 kHz, 50 Hz
+ - pal-lace        : 640x512, 15 kHz, 50 Hz interlaced
+
+ECS modes:
+ - multiscan       : 640x480, 29 kHz, 57 Hz
+ - multiscan-lace  : 640x960, 29 kHz, 57 Hz interlaced
+ - euro36          : 640x200, 15 kHz, 72 Hz
+ - euro36-lace     : 640x400, 15 kHz, 72 Hz interlaced
+ - euro72          : 640x400, 29 kHz, 68 Hz
+ - euro72-lace     : 640x800, 29 kHz, 68 Hz interlaced
+ - super72         : 800x300, 23 kHz, 70 Hz
+ - super72-lace    : 800x600, 23 kHz, 70 Hz interlaced
+ - dblntsc-ff      : 640x400, 27 kHz, 57 Hz
+ - dblntsc-lace    : 640x800, 27 kHz, 57 Hz interlaced
+ - dblpal-ff       : 640x512, 27 kHz, 47 Hz
+ - dblpal-lace     : 640x1024, 27 kHz, 47 Hz interlaced
+ - dblntsc         : 640x200, 27 kHz, 57 Hz doublescan
+ - dblpal          : 640x256, 27 kHz, 47 Hz doublescan
+
+VGA modes:
+ - vga             : 640x480, 31 kHz, 60 Hz
+ - vga70           : 640x400, 31 kHz, 70 Hz
+
+Please notice that the ECS and VGA modes require either an ECS or AGA
+chipset, and that these modes are limited to 2-bit color for the ECS
+chipset and 8-bit color for the AGA chipset.
+
+5.1.2) depth
+------------
+
+:Syntax: depth:<nr. of bit-planes>
+
+Specify the number of bit-planes for the selected video-mode.
+
+5.1.3) inverse
+--------------
+
+Use inverted display (black on white). Functionally the same as the
+"inverse" sub-option for the Atari.
+
+5.1.4) font
+-----------
+
+:Syntax: font:<fontname>
+
+Specify the font to use in text modes. Functionally the same as the
+"font" sub-option for the Atari, except that `PEARL8x8` is used instead
+of `VGA8x8` if the vertical size of the display is less than 400 pixel
+rows.
+
+5.1.5) monitorcap:
+-------------------
+
+:Syntax: monitorcap:<vmin>;<vmax>;<hmin>;<hmax>
+
+This describes the capabilities of a multisync monitor. For now, only
+the color frame buffer uses the settings of "monitorcap:".
+
+<vmin> and <vmax> are the minimum and maximum, resp., vertical frequencies
+your monitor can work with, in Hz. <hmin> and <hmax> are the same for
+the horizontal frequency, in kHz.
+
+The defaults are 50;90;15;38 (Generic Amiga multisync monitor).
+
+
+5.2) fd_def_df0=
+----------------
+
+:Syntax: fd_def_df0=<value>
+
+Sets the df0 value for "silent" floppy drives. The value should be in
+hexadecimal with "0x" prefix.
+
+
+5.3) wd33c93=
+-------------
+
+:Syntax: wd33c93=<sub-options...>
+
+These options affect the A590/A2091, A3000 and GVP Series II SCSI
+controllers.
+
+The <sub-options> is a comma-separated list of the sub-options listed
+below.
+
+5.3.1) nosync
+-------------
+
+:Syntax: nosync:bitmask
+
+bitmask is a byte where the 1st 7 bits correspond with the 7
+possible SCSI devices. Set a bit to prevent sync negotiation on that
+device. To maintain backwards compatibility, a command-line such as
+"wd33c93=255" will be automatically translated to
+"wd33c93=nosync:0xff". The default is to disable sync negotiation for
+all devices, eg. nosync:0xff.
+
+5.3.2) period
+-------------
+
+:Syntax: period:ns
+
+`ns` is the minimum # of nanoseconds in a SCSI data transfer
+period. Default is 500; acceptable values are 250 - 1000.
+
+5.3.3) disconnect
+-----------------
+
+:Syntax: disconnect:x
+
+Specify x = 0 to never allow disconnects, 2 to always allow them.
+x = 1 does 'adaptive' disconnects, which is the default and generally
+the best choice.
+
+5.3.4) debug
+------------
+
+:Syntax: debug:x
+
+If `DEBUGGING_ON` is defined, x is a bit mask that causes various
+types of debug output to printed - see the DB_xxx defines in
+wd33c93.h.
+
+5.3.5) clock
+------------
+
+:Syntax: clock:x
+
+x = clock input in MHz for WD33c93 chip. Normal values would be from
+8 through 20. The default value depends on your hostadapter(s),
+default for the A3000 internal controller is 14, for the A2091 it's 8
+and for the GVP hostadapters it's either 8 or 14, depending on the
+hostadapter and the SCSI-clock jumper present on some GVP
+hostadapters.
+
+5.3.6) next
+-----------
+
+No argument. Used to separate blocks of keywords when there's more
+than one wd33c93-based host adapter in the system.
+
+5.3.7) nodma
+------------
+
+:Syntax: nodma:x
+
+If x is 1 (or if the option is just written as "nodma"), the WD33c93
+controller will not use DMA (= direct memory access) to access the
+Amiga's memory.  This is useful for some systems (like A3000's and
+A4000's with the A3640 accelerator, revision 3.0) that have problems
+using DMA to chip memory.  The default is 0, i.e. to use DMA if
+possible.
+
+
+5.4) gvp11=
+-----------
+
+:Syntax: gvp11=<addr-mask>
+
+The earlier versions of the GVP driver did not handle DMA
+address-mask settings correctly which made it necessary for some
+people to use this option, in order to get their GVP controller
+running under Linux. These problems have hopefully been solved and the
+use of this option is now highly unrecommended!
+
+Incorrect use can lead to unpredictable behavior, so please only use
+this option if you *know* what you are doing and have a reason to do
+so. In any case if you experience problems and need to use this
+option, please inform us about it by mailing to the Linux/68k kernel
+mailing list.
+
+The address mask set by this option specifies which addresses are
+valid for DMA with the GVP Series II SCSI controller. An address is
+valid, if no bits are set except the bits that are set in the mask,
+too.
+
+Some versions of the GVP can only DMA into a 24 bit address range,
+some can address a 25 bit address range while others can use the whole
+32 bit address range for DMA. The correct setting depends on your
+controller and should be autodetected by the driver. An example is the
+24 bit region which is specified by a mask of 0x00fffffe.
diff --git a/Documentation/arch/nios2/features.rst b/Documentation/arch/nios2/features.rst
new file mode 100644 (file)
index 0000000..8449e63
--- /dev/null
@@ -0,0 +1,3 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. kernel-feat:: $srctree/Documentation/features nios2
diff --git a/Documentation/arch/nios2/index.rst b/Documentation/arch/nios2/index.rst
new file mode 100644 (file)
index 0000000..4468fe1
--- /dev/null
@@ -0,0 +1,12 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==============================
+Nios II Specific Documentation
+==============================
+
+.. toctree::
+   :maxdepth: 2
+   :numbered:
+
+   nios2
+   features
diff --git a/Documentation/arch/nios2/nios2.rst b/Documentation/arch/nios2/nios2.rst
new file mode 100644 (file)
index 0000000..43da3f7
--- /dev/null
@@ -0,0 +1,24 @@
+=================================
+Linux on the Nios II architecture
+=================================
+
+This is a port of Linux to Nios II (nios2) processor.
+
+In order to compile for Nios II, you need a version of GCC with support for the generic
+system call ABI. Please see this link for more information on how compiling and booting
+software for the Nios II platform:
+http://www.rocketboards.org/foswiki/Documentation/NiosIILinuxUserManual
+
+For reference, please see the following link:
+http://www.altera.com/literature/lit-nio2.jsp
+
+What is Nios II?
+================
+Nios II is a 32-bit embedded-processor architecture designed specifically for the
+Altera family of FPGAs. In order to support Linux, Nios II needs to be configured
+with MMU and hardware multiplier enabled.
+
+Nios II ABI
+===========
+Please refer to chapter "Application Binary Interface" in Nios II Processor Reference
+Handbook.
diff --git a/Documentation/arch/openrisc/features.rst b/Documentation/arch/openrisc/features.rst
new file mode 100644 (file)
index 0000000..3f7c40d
--- /dev/null
@@ -0,0 +1,3 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. kernel-feat:: $srctree/Documentation/features openrisc
diff --git a/Documentation/arch/openrisc/index.rst b/Documentation/arch/openrisc/index.rst
new file mode 100644 (file)
index 0000000..6879f99
--- /dev/null
@@ -0,0 +1,20 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=====================
+OpenRISC Architecture
+=====================
+
+.. toctree::
+   :maxdepth: 2
+
+   openrisc_port
+   todo
+
+   features
+
+.. only::  subproject and html
+
+   Indices
+   =======
+
+   * :ref:`genindex`
diff --git a/Documentation/arch/openrisc/openrisc_port.rst b/Documentation/arch/openrisc/openrisc_port.rst
new file mode 100644 (file)
index 0000000..657ac4a
--- /dev/null
@@ -0,0 +1,121 @@
+==============
+OpenRISC Linux
+==============
+
+This is a port of Linux to the OpenRISC class of microprocessors; the initial
+target architecture, specifically, is the 32-bit OpenRISC 1000 family (or1k).
+
+For information about OpenRISC processors and ongoing development:
+
+       =======         =============================
+       website         https://openrisc.io
+       email           openrisc@lists.librecores.org
+       =======         =============================
+
+---------------------------------------------------------------------
+
+Build instructions for OpenRISC toolchain and Linux
+===================================================
+
+In order to build and run Linux for OpenRISC, you'll need at least a basic
+toolchain and, perhaps, the architectural simulator.  Steps to get these bits
+in place are outlined here.
+
+1) Toolchain
+
+Toolchain binaries can be obtained from openrisc.io or our github releases page.
+Instructions for building the different toolchains can be found on openrisc.io
+or Stafford's toolchain build and release scripts.
+
+       ==========      =================================================
+       binaries        https://github.com/openrisc/or1k-gcc/releases
+       toolchains      https://openrisc.io/software
+       building        https://github.com/stffrdhrn/or1k-toolchain-build
+       ==========      =================================================
+
+2) Building
+
+Build the Linux kernel as usual::
+
+       make ARCH=openrisc CROSS_COMPILE="or1k-linux-" defconfig
+       make ARCH=openrisc CROSS_COMPILE="or1k-linux-"
+
+3) Running on FPGA (optional)
+
+The OpenRISC community typically uses FuseSoC to manage building and programming
+an SoC into an FPGA.  The below is an example of programming a De0 Nano
+development board with the OpenRISC SoC.  During the build FPGA RTL is code
+downloaded from the FuseSoC IP cores repository and built using the FPGA vendor
+tools.  Binaries are loaded onto the board with openocd.
+
+::
+
+       git clone https://github.com/olofk/fusesoc
+       cd fusesoc
+       sudo pip install -e .
+
+       fusesoc init
+       fusesoc build de0_nano
+       fusesoc pgm de0_nano
+
+       openocd -f interface/altera-usb-blaster.cfg \
+               -f board/or1k_generic.cfg
+
+       telnet localhost 4444
+       > init
+       > halt; load_image vmlinux ; reset
+
+4) Running on a Simulator (optional)
+
+QEMU is a processor emulator which we recommend for simulating the OpenRISC
+platform.  Please follow the OpenRISC instructions on the QEMU website to get
+Linux running on QEMU.  You can build QEMU yourself, but your Linux distribution
+likely provides binary packages to support OpenRISC.
+
+       =============   ======================================================
+       qemu openrisc   https://wiki.qemu.org/Documentation/Platforms/OpenRISC
+       =============   ======================================================
+
+---------------------------------------------------------------------
+
+Terminology
+===========
+
+In the code, the following particles are used on symbols to limit the scope
+to more or less specific processor implementations:
+
+========= =======================================
+openrisc: the OpenRISC class of processors
+or1k:     the OpenRISC 1000 family of processors
+or1200:   the OpenRISC 1200 processor
+========= =======================================
+
+---------------------------------------------------------------------
+
+History
+========
+
+18-11-2003     Matjaz Breskvar (phoenix@bsemi.com)
+       initial port of linux to OpenRISC/or32 architecture.
+        all the core stuff is implemented and seams usable.
+
+08-12-2003     Matjaz Breskvar (phoenix@bsemi.com)
+       complete change of TLB miss handling.
+       rewrite of exceptions handling.
+       fully functional sash-3.6 in default initrd.
+       a much improved version with changes all around.
+
+10-04-2004     Matjaz Breskvar (phoenix@bsemi.com)
+       alot of bugfixes all over.
+       ethernet support, functional http and telnet servers.
+       running many standard linux apps.
+
+26-06-2004     Matjaz Breskvar (phoenix@bsemi.com)
+       port to 2.6.x
+
+30-11-2004     Matjaz Breskvar (phoenix@bsemi.com)
+       lots of bugfixes and enhancments.
+       added opencores framebuffer driver.
+
+09-10-2010    Jonas Bonn (jonas@southpole.se)
+       major rewrite to bring up to par with upstream Linux 2.6.36
diff --git a/Documentation/arch/openrisc/todo.rst b/Documentation/arch/openrisc/todo.rst
new file mode 100644 (file)
index 0000000..420b18b
--- /dev/null
@@ -0,0 +1,15 @@
+====
+TODO
+====
+
+The OpenRISC Linux port is fully functional and has been tracking upstream
+since 2.6.35.  There are, however, remaining items to be completed within
+the coming months.  Here's a list of known-to-be-less-than-stellar items
+that are due for investigation shortly, i.e. our TODO list:
+
+-  Implement the rest of the DMA API... dma_map_sg, etc.
+
+-  Finish the renaming cleanup... there are references to or32 in the code
+   which was an older name for the architecture.  The name we've settled on is
+   or1k and this change is slowly trickling through the stack.  For the time
+   being, or32 is equivalent to or1k.
diff --git a/Documentation/arch/parisc/debugging.rst b/Documentation/arch/parisc/debugging.rst
new file mode 100644 (file)
index 0000000..de1b604
--- /dev/null
@@ -0,0 +1,46 @@
+=================
+PA-RISC Debugging
+=================
+
+okay, here are some hints for debugging the lower-level parts of
+linux/parisc.
+
+
+1. Absolute addresses
+=====================
+
+A lot of the assembly code currently runs in real mode, which means
+absolute addresses are used instead of virtual addresses as in the
+rest of the kernel.  To translate an absolute address to a virtual
+address you can lookup in System.map, add __PAGE_OFFSET (0x10000000
+currently).
+
+
+2. HPMCs
+========
+
+When real-mode code tries to access non-existent memory, you'll get
+an HPMC instead of a kernel oops.  To debug an HPMC, try to find
+the System Responder/Requestor addresses.  The System Requestor
+address should match (one of the) processor HPAs (high addresses in
+the I/O range); the System Responder address is the address real-mode
+code tried to access.
+
+Typical values for the System Responder address are addresses larger
+than __PAGE_OFFSET (0x10000000) which mean a virtual address didn't
+get translated to a physical address before real-mode code tried to
+access it.
+
+
+3. Q bit fun
+============
+
+Certain, very critical code has to clear the Q bit in the PSW.  What
+happens when the Q bit is cleared is the CPU does not update the
+registers interruption handlers read to find out where the machine
+was interrupted - so if you get an interruption between the instruction
+that clears the Q bit and the RFI that sets it again you don't know
+where exactly it happened.  If you're lucky the IAOQ will point to the
+instruction that cleared the Q bit, if you're not it points anywhere
+at all.  Usually Q bit problems will show themselves in unexplainable
+system hangs or running off the end of physical memory.
diff --git a/Documentation/arch/parisc/features.rst b/Documentation/arch/parisc/features.rst
new file mode 100644 (file)
index 0000000..501d7c4
--- /dev/null
@@ -0,0 +1,3 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. kernel-feat:: $srctree/Documentation/features parisc
diff --git a/Documentation/arch/parisc/index.rst b/Documentation/arch/parisc/index.rst
new file mode 100644 (file)
index 0000000..2406857
--- /dev/null
@@ -0,0 +1,20 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+====================
+PA-RISC Architecture
+====================
+
+.. toctree::
+   :maxdepth: 2
+
+   debugging
+   registers
+
+   features
+
+.. only::  subproject and html
+
+   Indices
+   =======
+
+   * :ref:`genindex`
diff --git a/Documentation/arch/parisc/registers.rst b/Documentation/arch/parisc/registers.rst
new file mode 100644 (file)
index 0000000..59c8ecf
--- /dev/null
@@ -0,0 +1,154 @@
+================================
+Register Usage for Linux/PA-RISC
+================================
+
+[ an asterisk is used for planned usage which is currently unimplemented ]
+
+General Registers as specified by ABI
+=====================================
+
+Control Registers
+-----------------
+
+===============================        ===============================================
+CR 0 (Recovery Counter)                used for ptrace
+CR 1-CR 7(undefined)           unused
+CR 8 (Protection ID)           per-process value*
+CR 9, 12, 13 (PIDS)            unused
+CR10 (CCR)                     lazy FPU saving*
+CR11                           as specified by ABI (SAR)
+CR14 (interruption vector)     initialized to fault_vector
+CR15 (EIEM)                    initialized to all ones*
+CR16 (Interval Timer)          read for cycle count/write starts Interval Tmr
+CR17-CR22                      interruption parameters
+CR19                           Interrupt Instruction Register
+CR20                           Interrupt Space Register
+CR21                           Interrupt Offset Register
+CR22                           Interrupt PSW
+CR23 (EIRR)                    read for pending interrupts/write clears bits
+CR24 (TR 0)                    Kernel Space Page Directory Pointer
+CR25 (TR 1)                    User   Space Page Directory Pointer
+CR26 (TR 2)                    not used
+CR27 (TR 3)                    Thread descriptor pointer
+CR28 (TR 4)                    not used
+CR29 (TR 5)                    not used
+CR30 (TR 6)                    current / 0
+CR31 (TR 7)                    Temporary register, used in various places
+===============================        ===============================================
+
+Space Registers (kernel mode)
+-----------------------------
+
+===============================        ===============================================
+SR0                            temporary space register
+SR4-SR7                        set to 0
+SR1                            temporary space register
+SR2                            kernel should not clobber this
+SR3                            used for userspace accesses (current process)
+===============================        ===============================================
+
+Space Registers (user mode)
+---------------------------
+
+===============================        ===============================================
+SR0                            temporary space register
+SR1                             temporary space register
+SR2                             holds space of linux gateway page
+SR3                             holds user address space value while in kernel
+SR4-SR7                         Defines short address space for user/kernel
+===============================        ===============================================
+
+
+Processor Status Word
+---------------------
+
+===============================        ===============================================
+W (64-bit addresses)           0
+E (Little-endian)              0
+S (Secure Interval Timer)      0
+T (Taken Branch Trap)          0
+H (Higher-privilege trap)      0
+L (Lower-privilege trap)       0
+N (Nullify next instruction)   used by C code
+X (Data memory break disable)  0
+B (Taken Branch)               used by C code
+C (code address translation)   1, 0 while executing real-mode code
+V (divide step correction)     used by C code
+M (HPMC mask)                  0, 1 while executing HPMC handler*
+C/B (carry/borrow bits)                used by C code
+O (ordered references)         1*
+F (performance monitor)                0
+R (Recovery Counter trap)      0
+Q (collect interruption state) 1 (0 in code directly preceding an rfi)
+P (Protection Identifiers)     1*
+D (Data address translation)   1, 0 while executing real-mode code
+I (external interrupt mask)    used by cli()/sti() macros
+===============================        ===============================================
+
+"Invisible" Registers
+---------------------
+
+===============================        ===============================================
+PSW default W value            0
+PSW default E value            0
+Shadow Registers               used by interruption handler code
+TOC enable bit                 1
+===============================        ===============================================
+
+-------------------------------------------------------------------------
+
+The PA-RISC architecture defines 7 registers as "shadow registers".
+Those are used in RETURN FROM INTERRUPTION AND RESTORE instruction to reduce
+the state save and restore time by eliminating the need for general register
+(GR) saves and restores in interruption handlers.
+Shadow registers are the GRs 1, 8, 9, 16, 17, 24, and 25.
+
+-------------------------------------------------------------------------
+
+Register usage notes, originally from John Marvin, with some additional
+notes from Randolph Chung.
+
+For the general registers:
+
+r1,r2,r19-r26,r28,r29 & r31 can be used without saving them first. And of
+course, you need to save them if you care about them, before calling
+another procedure. Some of the above registers do have special meanings
+that you should be aware of:
+
+    r1:
+       The addil instruction is hardwired to place its result in r1,
+       so if you use that instruction be aware of that.
+
+    r2:
+       This is the return pointer. In general you don't want to
+       use this, since you need the pointer to get back to your
+       caller. However, it is grouped with this set of registers
+       since the caller can't rely on the value being the same
+       when you return, i.e. you can copy r2 to another register
+       and return through that register after trashing r2, and
+       that should not cause a problem for the calling routine.
+
+    r19-r22:
+       these are generally regarded as temporary registers.
+       Note that in 64 bit they are arg7-arg4.
+
+    r23-r26:
+       these are arg3-arg0, i.e. you can use them if you
+       don't care about the values that were passed in anymore.
+
+    r28,r29:
+       are ret0 and ret1. They are what you pass return values
+       in. r28 is the primary return. When returning small structures
+       r29 may also be used to pass data back to the caller.
+
+    r30:
+       stack pointer
+
+    r31:
+       the ble instruction puts the return pointer in here.
+
+
+    r3-r18,r27,r30 need to be saved and restored. r3-r18 are just
+    general purpose registers. r27 is the data pointer, and is
+    used to make references to global variables easier. r30 is
+    the stack pointer.
diff --git a/Documentation/arch/sh/booting.rst b/Documentation/arch/sh/booting.rst
new file mode 100644 (file)
index 0000000..d851c49
--- /dev/null
@@ -0,0 +1,12 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+DeviceTree Booting
+------------------
+
+  Device-tree compatible SH bootloaders are expected to provide the physical
+  address of the device tree blob in r4. Since legacy bootloaders did not
+  guarantee any particular initial register state, kernels built to
+  inter-operate with old bootloaders must either use a builtin DTB or
+  select a legacy board option (something other than CONFIG_SH_DEVICE_TREE)
+  that does not use device tree. Support for the latter is being phased out
+  in favor of device tree.
diff --git a/Documentation/arch/sh/features.rst b/Documentation/arch/sh/features.rst
new file mode 100644 (file)
index 0000000..f722af3
--- /dev/null
@@ -0,0 +1,3 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. kernel-feat:: $srctree/Documentation/features sh
diff --git a/Documentation/arch/sh/index.rst b/Documentation/arch/sh/index.rst
new file mode 100644 (file)
index 0000000..c647767
--- /dev/null
@@ -0,0 +1,56 @@
+=======================
+SuperH Interfaces Guide
+=======================
+
+:Author: Paul Mundt
+
+.. toctree::
+    :maxdepth: 1
+
+    booting
+    new-machine
+    register-banks
+
+    features
+
+Memory Management
+=================
+
+SH-4
+----
+
+Store Queue API
+~~~~~~~~~~~~~~~
+
+.. kernel-doc:: arch/sh/kernel/cpu/sh4/sq.c
+   :export:
+
+Machine Specific Interfaces
+===========================
+
+mach-dreamcast
+--------------
+
+.. kernel-doc:: arch/sh/boards/mach-dreamcast/rtc.c
+   :internal:
+
+mach-x3proto
+------------
+
+.. kernel-doc:: arch/sh/boards/mach-x3proto/ilsel.c
+   :export:
+
+Busses
+======
+
+SuperHyway
+----------
+
+.. kernel-doc:: drivers/sh/superhyway/superhyway.c
+   :export:
+
+Maple
+-----
+
+.. kernel-doc:: drivers/sh/maple/maple.c
+   :export:
diff --git a/Documentation/arch/sh/new-machine.rst b/Documentation/arch/sh/new-machine.rst
new file mode 100644 (file)
index 0000000..e501c52
--- /dev/null
@@ -0,0 +1,277 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=============================
+Adding a new board to LinuxSH
+=============================
+
+               Paul Mundt <lethal@linux-sh.org>
+
+This document attempts to outline what steps are necessary to add support
+for new boards to the LinuxSH port under the new 2.5 and 2.6 kernels. This
+also attempts to outline some of the noticeable changes between the 2.4
+and the 2.5/2.6 SH backend.
+
+1. New Directory Structure
+==========================
+
+The first thing to note is the new directory structure. Under 2.4, most
+of the board-specific code (with the exception of stboards) ended up
+in arch/sh/kernel/ directly, with board-specific headers ending up in
+include/asm-sh/. For the new kernel, things are broken out by board type,
+companion chip type, and CPU type. Looking at a tree view of this directory
+hierarchy looks like the following:
+
+Board-specific code::
+
+    .
+    |-- arch
+    |   `-- sh
+    |       `-- boards
+    |           |-- adx
+    |           |   `-- board-specific files
+    |           |-- bigsur
+    |           |   `-- board-specific files
+    |           |
+    |           ... more boards here ...
+    |
+    `-- include
+       `-- asm-sh
+           |-- adx
+           |   `-- board-specific headers
+           |-- bigsur
+           |   `-- board-specific headers
+           |
+           .. more boards here ...
+
+Next, for companion chips::
+
+    .
+    `-- arch
+       `-- sh
+           `-- cchips
+               `-- hd6446x
+                   `-- hd64461
+                       `-- cchip-specific files
+
+... and so on. Headers for the companion chips are treated the same way as
+board-specific headers. Thus, include/asm-sh/hd64461 is home to all of the
+hd64461-specific headers.
+
+Finally, CPU family support is also abstracted::
+
+    .
+    |-- arch
+    |   `-- sh
+    |       |-- kernel
+    |       |   `-- cpu
+    |       |       |-- sh2
+    |       |       |   `-- SH-2 generic files
+    |       |       |-- sh3
+    |       |       |   `-- SH-3 generic files
+    |       |       `-- sh4
+    |       |           `-- SH-4 generic files
+    |       `-- mm
+    |           `-- This is also broken out per CPU family, so each family can
+    |               have their own set of cache/tlb functions.
+    |
+    `-- include
+       `-- asm-sh
+           |-- cpu-sh2
+           |   `-- SH-2 specific headers
+           |-- cpu-sh3
+           |   `-- SH-3 specific headers
+           `-- cpu-sh4
+               `-- SH-4 specific headers
+
+It should be noted that CPU subtypes are _not_ abstracted. Thus, these still
+need to be dealt with by the CPU family specific code.
+
+2. Adding a New Board
+=====================
+
+The first thing to determine is whether the board you are adding will be
+isolated, or whether it will be part of a family of boards that can mostly
+share the same board-specific code with minor differences.
+
+In the first case, this is just a matter of making a directory for your
+board in arch/sh/boards/ and adding rules to hook your board in with the
+build system (more on this in the next section). However, for board families
+it makes more sense to have a common top-level arch/sh/boards/ directory
+and then populate that with sub-directories for each member of the family.
+Both the Solution Engine and the hp6xx boards are an example of this.
+
+After you have setup your new arch/sh/boards/ directory, remember that you
+should also add a directory in include/asm-sh for headers localized to this
+board (if there are going to be more than one). In order to interoperate
+seamlessly with the build system, it's best to have this directory the same
+as the arch/sh/boards/ directory name, though if your board is again part of
+a family, the build system has ways of dealing with this (via incdir-y
+overloading), and you can feel free to name the directory after the family
+member itself.
+
+There are a few things that each board is required to have, both in the
+arch/sh/boards and the include/asm-sh/ hierarchy. In order to better
+explain this, we use some examples for adding an imaginary board. For
+setup code, we're required at the very least to provide definitions for
+get_system_type() and platform_setup(). For our imaginary board, this
+might look something like::
+
+    /*
+    * arch/sh/boards/vapor/setup.c - Setup code for imaginary board
+    */
+    #include <linux/init.h>
+
+    const char *get_system_type(void)
+    {
+           return "FooTech Vaporboard";
+    }
+
+    int __init platform_setup(void)
+    {
+           /*
+           * If our hardware actually existed, we would do real
+           * setup here. Though it's also sane to leave this empty
+           * if there's no real init work that has to be done for
+           * this board.
+           */
+
+           /* Start-up imaginary PCI ... */
+
+           /* And whatever else ... */
+
+           return 0;
+    }
+
+Our new imaginary board will also have to tie into the machvec in order for it
+to be of any use.
+
+machvec functions fall into a number of categories:
+
+ - I/O functions to IO memory (inb etc) and PCI/main memory (readb etc).
+ - I/O mapping functions (ioport_map, ioport_unmap, etc).
+ - a 'heartbeat' function.
+ - PCI and IRQ initialization routines.
+ - Consistent allocators (for boards that need special allocators,
+   particularly for allocating out of some board-specific SRAM for DMA
+   handles).
+
+There are machvec functions added and removed over time, so always be sure to
+consult include/asm-sh/machvec.h for the current state of the machvec.
+
+The kernel will automatically wrap in generic routines for undefined function
+pointers in the machvec at boot time, as machvec functions are referenced
+unconditionally throughout most of the tree. Some boards have incredibly
+sparse machvecs (such as the dreamcast and sh03), whereas others must define
+virtually everything (rts7751r2d).
+
+Adding a new machine is relatively trivial (using vapor as an example):
+
+If the board-specific definitions are quite minimalistic, as is the case for
+the vast majority of boards, simply having a single board-specific header is
+sufficient.
+
+ - add a new file include/asm-sh/vapor.h which contains prototypes for
+   any machine specific IO functions prefixed with the machine name, for
+   example vapor_inb. These will be needed when filling out the machine
+   vector.
+
+   Note that these prototypes are generated automatically by setting
+   __IO_PREFIX to something sensible. A typical example would be::
+
+       #define __IO_PREFIX vapor
+       #include <asm/io_generic.h>
+
+   somewhere in the board-specific header. Any boards being ported that still
+   have a legacy io.h should remove it entirely and switch to the new model.
+
+ - Add machine vector definitions to the board's setup.c. At a bare minimum,
+   this must be defined as something like::
+
+       struct sh_machine_vector mv_vapor __initmv = {
+               .mv_name = "vapor",
+       };
+       ALIAS_MV(vapor)
+
+ - finally add a file arch/sh/boards/vapor/io.c, which contains definitions of
+   the machine specific io functions (if there are enough to warrant it).
+
+3. Hooking into the Build System
+================================
+
+Now that we have the corresponding directories setup, and all of the
+board-specific code is in place, it's time to look at how to get the
+whole mess to fit into the build system.
+
+Large portions of the build system are now entirely dynamic, and merely
+require the proper entry here and there in order to get things done.
+
+The first thing to do is to add an entry to arch/sh/Kconfig, under the
+"System type" menu::
+
+    config SH_VAPOR
+           bool "Vapor"
+           help
+           select Vapor if configuring for a FooTech Vaporboard.
+
+next, this has to be added into arch/sh/Makefile. All boards require a
+machdir-y entry in order to be built. This entry needs to be the name of
+the board directory as it appears in arch/sh/boards, even if it is in a
+sub-directory (in which case, all parent directories below arch/sh/boards/
+need to be listed). For our new board, this entry can look like::
+
+    machdir-$(CONFIG_SH_VAPOR) += vapor
+
+provided that we've placed everything in the arch/sh/boards/vapor/ directory.
+
+Next, the build system assumes that your include/asm-sh directory will also
+be named the same. If this is not the case (as is the case with multiple
+boards belonging to a common family), then the directory name needs to be
+implicitly appended to incdir-y. The existing code manages this for the
+Solution Engine and hp6xx boards, so see these for an example.
+
+Once that is taken care of, it's time to add an entry for the mach type.
+This is done by adding an entry to the end of the arch/sh/tools/mach-types
+list. The method for doing this is self explanatory, and so we won't waste
+space restating it here. After this is done, you will be able to use
+implicit checks for your board if you need this somewhere throughout the
+common code, such as::
+
+       /* Make sure we're on the FooTech Vaporboard */
+       if (!mach_is_vapor())
+               return -ENODEV;
+
+also note that the mach_is_boardname() check will be implicitly forced to
+lowercase, regardless of the fact that the mach-types entries are all
+uppercase. You can read the script if you really care, but it's pretty ugly,
+so you probably don't want to do that.
+
+Now all that's left to do is providing a defconfig for your new board. This
+way, other people who end up with this board can simply use this config
+for reference instead of trying to guess what settings are supposed to be
+used on it.
+
+Also, as soon as you have copied over a sample .config for your new board
+(assume arch/sh/configs/vapor_defconfig), you can also use this directly as a
+build target, and it will be implicitly listed as such in the help text.
+
+Looking at the 'make help' output, you should now see something like:
+
+Architecture specific targets (sh):
+
+  =======================   =============================================
+  zImage                    Compressed kernel image (arch/sh/boot/zImage)
+  adx_defconfig             Build for adx
+  cqreek_defconfig          Build for cqreek
+  dreamcast_defconfig       Build for dreamcast
+  ...
+  vapor_defconfig           Build for vapor
+  =======================   =============================================
+
+which then allows you to do::
+
+    $ make ARCH=sh CROSS_COMPILE=sh4-linux- vapor_defconfig vmlinux
+
+which will in turn copy the defconfig for this board, run it through
+oldconfig (prompting you for any new options since the time of creation),
+and start you on your way to having a functional kernel for your new
+board.
diff --git a/Documentation/arch/sh/register-banks.rst b/Documentation/arch/sh/register-banks.rst
new file mode 100644 (file)
index 0000000..2bef5c8
--- /dev/null
@@ -0,0 +1,40 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==========================================
+Notes on register bank usage in the kernel
+==========================================
+
+Introduction
+------------
+
+The SH-3 and SH-4 CPU families traditionally include a single partial register
+bank (selected by SR.RB, only r0 ... r7 are banked), whereas other families
+may have more full-featured banking or simply no such capabilities at all.
+
+SR.RB banking
+-------------
+
+In the case of this type of banking, banked registers are mapped directly to
+r0 ... r7 if SR.RB is set to the bank we are interested in, otherwise ldc/stc
+can still be used to reference the banked registers (as r0_bank ... r7_bank)
+when in the context of another bank. The developer must keep the SR.RB value
+in mind when writing code that utilizes these banked registers, for obvious
+reasons. Userspace is also not able to poke at the bank1 values, so these can
+be used rather effectively as scratch registers by the kernel.
+
+Presently the kernel uses several of these registers.
+
+       - r0_bank, r1_bank (referenced as k0 and k1, used for scratch
+         registers when doing exception handling).
+
+       - r2_bank (used to track the EXPEVT/INTEVT code)
+
+               - Used by do_IRQ() and friends for doing irq mapping based off
+                 of the interrupt exception vector jump table offset
+
+       - r6_bank (global interrupt mask)
+
+               - The SR.IMASK interrupt handler makes use of this to set the
+                 interrupt priority level (used by local_irq_enable())
+
+       - r7_bank (current)
diff --git a/Documentation/arch/sparc/adi.rst b/Documentation/arch/sparc/adi.rst
new file mode 100644 (file)
index 0000000..dbcd8b6
--- /dev/null
@@ -0,0 +1,286 @@
+================================
+Application Data Integrity (ADI)
+================================
+
+SPARC M7 processor adds the Application Data Integrity (ADI) feature.
+ADI allows a task to set version tags on any subset of its address
+space. Once ADI is enabled and version tags are set for ranges of
+address space of a task, the processor will compare the tag in pointers
+to memory in these ranges to the version set by the application
+previously. Access to memory is granted only if the tag in given pointer
+matches the tag set by the application. In case of mismatch, processor
+raises an exception.
+
+Following steps must be taken by a task to enable ADI fully:
+
+1. Set the user mode PSTATE.mcde bit. This acts as master switch for
+   the task's entire address space to enable/disable ADI for the task.
+
+2. Set TTE.mcd bit on any TLB entries that correspond to the range of
+   addresses ADI is being enabled on. MMU checks the version tag only
+   on the pages that have TTE.mcd bit set.
+
+3. Set the version tag for virtual addresses using stxa instruction
+   and one of the MCD specific ASIs. Each stxa instruction sets the
+   given tag for one ADI block size number of bytes. This step must
+   be repeated for entire page to set tags for entire page.
+
+ADI block size for the platform is provided by the hypervisor to kernel
+in machine description tables. Hypervisor also provides the number of
+top bits in the virtual address that specify the version tag.  Once
+version tag has been set for a memory location, the tag is stored in the
+physical memory and the same tag must be present in the ADI version tag
+bits of the virtual address being presented to the MMU. For example on
+SPARC M7 processor, MMU uses bits 63-60 for version tags and ADI block
+size is same as cacheline size which is 64 bytes. A task that sets ADI
+version to, say 10, on a range of memory, must access that memory using
+virtual addresses that contain 0xa in bits 63-60.
+
+ADI is enabled on a set of pages using mprotect() with PROT_ADI flag.
+When ADI is enabled on a set of pages by a task for the first time,
+kernel sets the PSTATE.mcde bit for the task. Version tags for memory
+addresses are set with an stxa instruction on the addresses using
+ASI_MCD_PRIMARY or ASI_MCD_ST_BLKINIT_PRIMARY. ADI block size is
+provided by the hypervisor to the kernel.  Kernel returns the value of
+ADI block size to userspace using auxiliary vector along with other ADI
+info. Following auxiliary vectors are provided by the kernel:
+
+       ============    ===========================================
+       AT_ADI_BLKSZ    ADI block size. This is the granularity and
+                       alignment, in bytes, of ADI versioning.
+       AT_ADI_NBITS    Number of ADI version bits in the VA
+       ============    ===========================================
+
+
+IMPORTANT NOTES
+===============
+
+- Version tag values of 0x0 and 0xf are reserved. These values match any
+  tag in virtual address and never generate a mismatch exception.
+
+- Version tags are set on virtual addresses from userspace even though
+  tags are stored in physical memory. Tags are set on a physical page
+  after it has been allocated to a task and a pte has been created for
+  it.
+
+- When a task frees a memory page it had set version tags on, the page
+  goes back to free page pool. When this page is re-allocated to a task,
+  kernel clears the page using block initialization ASI which clears the
+  version tags as well for the page. If a page allocated to a task is
+  freed and allocated back to the same task, old version tags set by the
+  task on that page will no longer be present.
+
+- ADI tag mismatches are not detected for non-faulting loads.
+
+- Kernel does not set any tags for user pages and it is entirely a
+  task's responsibility to set any version tags. Kernel does ensure the
+  version tags are preserved if a page is swapped out to the disk and
+  swapped back in. It also preserves that version tags if a page is
+  migrated.
+
+- ADI works for any size pages. A userspace task need not be aware of
+  page size when using ADI. It can simply select a virtual address
+  range, enable ADI on the range using mprotect() and set version tags
+  for the entire range. mprotect() ensures range is aligned to page size
+  and is a multiple of page size.
+
+- ADI tags can only be set on writable memory. For example, ADI tags can
+  not be set on read-only mappings.
+
+
+
+ADI related traps
+=================
+
+With ADI enabled, following new traps may occur:
+
+Disrupting memory corruption
+----------------------------
+
+       When a store accesses a memory location that has TTE.mcd=1,
+       the task is running with ADI enabled (PSTATE.mcde=1), and the ADI
+       tag in the address used (bits 63:60) does not match the tag set on
+       the corresponding cacheline, a memory corruption trap occurs. By
+       default, it is a disrupting trap and is sent to the hypervisor
+       first. Hypervisor creates a sun4v error report and sends a
+       resumable error (TT=0x7e) trap to the kernel. The kernel sends
+       a SIGSEGV to the task that resulted in this trap with the following
+       info::
+
+               siginfo.si_signo = SIGSEGV;
+               siginfo.errno = 0;
+               siginfo.si_code = SEGV_ADIDERR;
+               siginfo.si_addr = addr; /* PC where first mismatch occurred */
+               siginfo.si_trapno = 0;
+
+
+Precise memory corruption
+-------------------------
+
+       When a store accesses a memory location that has TTE.mcd=1,
+       the task is running with ADI enabled (PSTATE.mcde=1), and the ADI
+       tag in the address used (bits 63:60) does not match the tag set on
+       the corresponding cacheline, a memory corruption trap occurs. If
+       MCD precise exception is enabled (MCDPERR=1), a precise
+       exception is sent to the kernel with TT=0x1a. The kernel sends
+       a SIGSEGV to the task that resulted in this trap with the following
+       info::
+
+               siginfo.si_signo = SIGSEGV;
+               siginfo.errno = 0;
+               siginfo.si_code = SEGV_ADIPERR;
+               siginfo.si_addr = addr; /* address that caused trap */
+               siginfo.si_trapno = 0;
+
+       NOTE:
+               ADI tag mismatch on a load always results in precise trap.
+
+
+MCD disabled
+------------
+
+       When a task has not enabled ADI and attempts to set ADI version
+       on a memory address, processor sends an MCD disabled trap. This
+       trap is handled by hypervisor first and the hypervisor vectors this
+       trap through to the kernel as Data Access Exception trap with
+       fault type set to 0xa (invalid ASI). When this occurs, the kernel
+       sends the task SIGSEGV signal with following info::
+
+               siginfo.si_signo = SIGSEGV;
+               siginfo.errno = 0;
+               siginfo.si_code = SEGV_ACCADI;
+               siginfo.si_addr = addr; /* address that caused trap */
+               siginfo.si_trapno = 0;
+
+
+Sample program to use ADI
+-------------------------
+
+Following sample program is meant to illustrate how to use the ADI
+functionality::
+
+  #include <unistd.h>
+  #include <stdio.h>
+  #include <stdlib.h>
+  #include <elf.h>
+  #include <sys/ipc.h>
+  #include <sys/shm.h>
+  #include <sys/mman.h>
+  #include <asm/asi.h>
+
+  #ifndef AT_ADI_BLKSZ
+  #define AT_ADI_BLKSZ 48
+  #endif
+  #ifndef AT_ADI_NBITS
+  #define AT_ADI_NBITS 49
+  #endif
+
+  #ifndef PROT_ADI
+  #define PROT_ADI     0x10
+  #endif
+
+  #define BUFFER_SIZE     32*1024*1024UL
+
+  main(int argc, char* argv[], char* envp[])
+  {
+          unsigned long i, mcde, adi_blksz, adi_nbits;
+          char *shmaddr, *tmp_addr, *end, *veraddr, *clraddr;
+          int shmid, version;
+       Elf64_auxv_t *auxv;
+
+       adi_blksz = 0;
+
+       while(*envp++ != NULL);
+       for (auxv = (Elf64_auxv_t *)envp; auxv->a_type != AT_NULL; auxv++) {
+               switch (auxv->a_type) {
+               case AT_ADI_BLKSZ:
+                       adi_blksz = auxv->a_un.a_val;
+                       break;
+               case AT_ADI_NBITS:
+                       adi_nbits = auxv->a_un.a_val;
+                       break;
+               }
+       }
+       if (adi_blksz == 0) {
+               fprintf(stderr, "Oops! ADI is not supported\n");
+               exit(1);
+       }
+
+       printf("ADI capabilities:\n");
+       printf("\tBlock size = %ld\n", adi_blksz);
+       printf("\tNumber of bits = %ld\n", adi_nbits);
+
+          if ((shmid = shmget(2, BUFFER_SIZE,
+                                  IPC_CREAT | SHM_R | SHM_W)) < 0) {
+                  perror("shmget failed");
+                  exit(1);
+          }
+
+          shmaddr = shmat(shmid, NULL, 0);
+          if (shmaddr == (char *)-1) {
+                  perror("shm attach failed");
+                  shmctl(shmid, IPC_RMID, NULL);
+                  exit(1);
+          }
+
+       if (mprotect(shmaddr, BUFFER_SIZE, PROT_READ|PROT_WRITE|PROT_ADI)) {
+               perror("mprotect failed");
+               goto err_out;
+       }
+
+          /* Set the ADI version tag on the shm segment
+           */
+          version = 10;
+          tmp_addr = shmaddr;
+          end = shmaddr + BUFFER_SIZE;
+          while (tmp_addr < end) {
+                  asm volatile(
+                          "stxa %1, [%0]0x90\n\t"
+                          :
+                          : "r" (tmp_addr), "r" (version));
+                  tmp_addr += adi_blksz;
+          }
+       asm volatile("membar #Sync\n\t");
+
+          /* Create a versioned address from the normal address by placing
+        * version tag in the upper adi_nbits bits
+           */
+          tmp_addr = (void *) ((unsigned long)shmaddr << adi_nbits);
+          tmp_addr = (void *) ((unsigned long)tmp_addr >> adi_nbits);
+          veraddr = (void *) (((unsigned long)version << (64-adi_nbits))
+                          | (unsigned long)tmp_addr);
+
+          printf("Starting the writes:\n");
+          for (i = 0; i < BUFFER_SIZE; i++) {
+                  veraddr[i] = (char)(i);
+                  if (!(i % (1024 * 1024)))
+                          printf(".");
+          }
+          printf("\n");
+
+          printf("Verifying data...");
+       fflush(stdout);
+          for (i = 0; i < BUFFER_SIZE; i++)
+                  if (veraddr[i] != (char)i)
+                          printf("\nIndex %lu mismatched\n", i);
+          printf("Done.\n");
+
+          /* Disable ADI and clean up
+           */
+       if (mprotect(shmaddr, BUFFER_SIZE, PROT_READ|PROT_WRITE)) {
+               perror("mprotect failed");
+               goto err_out;
+       }
+
+          if (shmdt((const void *)shmaddr) != 0)
+                  perror("Detach failure");
+          shmctl(shmid, IPC_RMID, NULL);
+
+          exit(0);
+
+  err_out:
+          if (shmdt((const void *)shmaddr) != 0)
+                  perror("Detach failure");
+          shmctl(shmid, IPC_RMID, NULL);
+          exit(1);
+  }
diff --git a/Documentation/arch/sparc/console.rst b/Documentation/arch/sparc/console.rst
new file mode 100644 (file)
index 0000000..73132db
--- /dev/null
@@ -0,0 +1,9 @@
+Steps for sending 'break' on sunhv console
+==========================================
+
+On Baremetal:
+   1. press   Esc + 'B'
+
+On LDOM:
+   1. press    Ctrl + ']'
+   2. telnet> send  break
diff --git a/Documentation/arch/sparc/features.rst b/Documentation/arch/sparc/features.rst
new file mode 100644 (file)
index 0000000..c0c9246
--- /dev/null
@@ -0,0 +1,3 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. kernel-feat:: $srctree/Documentation/features sparc
diff --git a/Documentation/arch/sparc/index.rst b/Documentation/arch/sparc/index.rst
new file mode 100644 (file)
index 0000000..ae88422
--- /dev/null
@@ -0,0 +1,13 @@
+==================
+Sparc Architecture
+==================
+
+.. toctree::
+   :maxdepth: 1
+
+   console
+   adi
+
+   oradax/oracle-dax
+
+   features
diff --git a/Documentation/arch/sparc/oradax/dax-hv-api.txt b/Documentation/arch/sparc/oradax/dax-hv-api.txt
new file mode 100644 (file)
index 0000000..7ecd0bf
--- /dev/null
@@ -0,0 +1,1433 @@
+Excerpt from UltraSPARC Virtual Machine Specification
+Compiled from version 3.0.20+15
+Publication date 2017-09-25 08:21
+Copyright © 2008, 2015 Oracle and/or its affiliates. All rights reserved.
+Extracted via "pdftotext -f 547 -l 572 -layout sun4v_20170925.pdf"
+Authors:
+        Charles Kunzman
+        Sam Glidden
+        Mark Cianchetti
+
+
+Chapter 36. Coprocessor services
+        The following APIs provide access via the Hypervisor to hardware assisted data processing functionality.
+        These APIs may only be provided by certain platforms, and may not be available to all virtual machines
+        even on supported platforms. Restrictions on the use of these APIs may be imposed in order to support
+        live-migration and other system management activities.
+
+36.1. Data Analytics Accelerator
+        The Data Analytics Accelerator (DAX) functionality is a collection of hardware coprocessors that provide
+        high speed processoring of database-centric operations. The coprocessors may support one or more of
+        the following data query operations: search, extraction, compression, decompression, and translation. The
+        functionality offered may vary by virtual machine implementation.
+
+        The DAX is a virtual device to sun4v guests, with supported data operations indicated by the virtual device
+        compatibility property. Functionality is accessed through the submission of Command Control Blocks
+        (CCBs) via the ccb_submit API function. The operations are processed asynchronously, with the status
+        of the submitted operations reported through a Completion Area linked to each CCB. Each CCB has a
+        separate Completion Area and, unless execution order is specifically restricted through the use of serial-
+        conditional flags, the execution order of submitted CCBs is arbitrary. Likewise, the time to completion
+        for a given CCB is never guaranteed.
+
+        Guest software may implement a software timeout on CCB operations, and if the timeout is exceeded, the
+        operation may be cancelled or killed via the ccb_kill API function. It is recommended for guest software
+        to implement a software timeout to account for certain RAS errors which may result in lost CCBs. It is
+        recommended such implementation use the ccb_info API function to check the status of a CCB prior to
+        killing it in order to determine if the CCB is still in queue, or may have been lost due to a RAS error.
+
+        There is no fixed limit on the number of outstanding CCBs guest software may have queued in the virtual
+        machine, however, internal resource limitations within the virtual machine can cause CCB submissions
+        to be temporarily rejected with EWOULDBLOCK. In such cases, guests should continue to attempt
+        submissions until they succeed; waiting for an outstanding CCB to complete is not necessary, and would
+        not be a guarantee that a future submission would succeed.
+
+        The availablility of DAX coprocessor command service is indicated by the presence of the DAX virtual
+        device node in the guest MD (Section 8.24.17, “Database Analytics Accelerators (DAX) virtual-device
+        node”).
+
+36.1.1. DAX Compatibility Property
+        The query functionality may vary based on the compatibility property of the virtual device:
+
+36.1.1.1. "ORCL,sun4v-dax" Device Compatibility
+        Available CCB commands:
+
+        • No-op/Sync
+
+        • Extract
+
+        • Scan Value
+
+        • Inverted Scan Value
+
+        • Scan Range
+
+
+                                                     509
+\f                                             Coprocessor services
+
+
+        • Inverted Scan Range
+
+        • Translate
+
+        • Inverted Translate
+
+        • Select
+
+        See Section 36.2.1, “Query CCB Command Formats” for the corresponding CCB input and output formats.
+
+        Only version 0 CCBs are available.
+
+36.1.1.2. "ORCL,sun4v-dax-fc" Device Compatibility
+        "ORCL,sun4v-dax-fc" is compatible with the "ORCL,sun4v-dax" interface, and includes additional CCB
+        bit fields and controls.
+
+36.1.1.3. "ORCL,sun4v-dax2" Device Compatibility
+        Available CCB commands:
+
+        • No-op/Sync
+
+        • Extract
+
+        • Scan Value
+
+        • Inverted Scan Value
+
+        • Scan Range
+
+        • Inverted Scan Range
+
+        • Translate
+
+        • Inverted Translate
+
+        • Select
+
+        See Section 36.2.1, “Query CCB Command Formats” for the corresponding CCB input and output formats.
+
+        Version 0 and 1 CCBs are available. Only version 0 CCBs may use Huffman encoded data, whereas only
+        version 1 CCBs may use OZIP.
+
+36.1.2. DAX Virtual Device Interrupts
+        The DAX virtual device has multiple interrupts associated with it which may be used by the guest if
+        desired. The number of device interrupts available to the guest is indicated in the virtual device node of the
+        guest MD (Section 8.24.17, “Database Analytics Accelerators (DAX) virtual-device node”). If the device
+        node indicates N interrupts available, the guest may use any value from 0 to N - 1 (inclusive) in a CCB
+        interrupt number field. Using values outside this range will result in the CCB being rejected for an invalid
+        field value.
+
+        The interrupts may be bound and managed using the standard sun4v device interrupts API (Chapter 16,
+        Device interrupt services). Sysino interrupts are not available for DAX devices.
+
+36.2. Coprocessor Control Block (CCB)
+        CCBs are either 64 or 128 bytes long, depending on the operation type. The exact contents of the CCB
+        are command specific, but all CCBs contain at least one memory buffer address. All memory locations
+
+
+                                                      510
+\f                                    Coprocessor services
+
+
+referenced by a CCB must be pinned in memory until the CCB either completes execution or is killed
+via the ccb_kill API call. Changes in virtual address mappings occurring after CCB submission are not
+guaranteed to be visible, and as such all virtual address updates need to be synchronized with CCB
+execution.
+
+All CCBs begin with a common 32-bit header.
+
+Table 36.1. CCB Header Format
+Bits          Field Description
+[31:28]       CCB version. For API version 2.0: set to 1 if CCB uses OZIP encoding; set to 0 if the CCB
+              uses Huffman encoding; otherwise either 0 or 1. For API version 1.0: always set to 0.
+[27]          When API version 2.0 is negotiated, this is the Pipeline Flag [512]. It is reserved in
+              API version 1.0
+[26]          Long CCB flag [512]
+[25]          Conditional synchronization flag [512]
+[24]          Serial synchronization flag
+[23:16]       CCB operation code:
+               0x00        No Operation (No-op) or Sync
+               0x01        Extract
+               0x02        Scan Value
+               0x12        Inverted Scan Value
+               0x03        Scan Range
+               0x13        Inverted Scan Range
+               0x04        Translate
+               0x14        Inverted Translate
+               0x05        Select
+[15:13]       Reserved
+[12:11]       Table address type
+               0b'00       No address
+               0b'01       Alternate context virtual address
+               0b'10       Real address
+               0b'11       Primary context virtual address
+[10:8]        Output/Destination address type
+               0b'000      No address
+               0b'001      Alternate context virtual address
+               0b'010      Real address
+               0b'011      Primary context virtual address
+               0b'100      Reserved
+               0b'101      Reserved
+               0b'110      Reserved
+               0b'111      Reserved
+[7:5]         Secondary source address type
+
+
+                                            511
+\f                                    Coprocessor services
+
+
+Bits           Field Description
+                0b'000       No address
+                0b'001       Alternate context virtual address
+                0b'010       Real address
+                0b'011       Primary context virtual address
+                0b'100       Reserved
+                0b'101       Reserved
+                0b'110       Reserved
+                0b'111       Reserved
+[4:2]          Primary source address type
+                0b'000       No address
+                0b'001       Alternate context virtual address
+                0b'010       Real address
+                0b'011       Primary context virtual address
+                0b'100       Reserved
+                0b'101       Reserved
+                0b'110       Reserved
+                0b'111       Reserved
+[1:0]          Completion area address type
+                0b'00        No address
+                0b'01        Alternate context virtual address
+                0b'10        Real address
+                0b'11        Primary context virtual address
+
+The Long CCB flag indicates whether the submitted CCB is 64 or 128 bytes long; value is 0 for 64 bytes
+and 1 for 128 bytes.
+
+The Serial and Conditional flags allow simple relative ordering between CCBs. Any CCB with the Serial
+flag set will execute sequentially relative to any previous CCB that is also marked as Serial in the same
+CCB submission. CCBs without the Serial flag set execute independently, even if they are between CCBs
+with the Serial flag set. CCBs marked solely with the Serial flag will execute upon the completion of the
+previous Serial CCB, regardless of the completion status of that CCB. The Conditional flag allows CCBs
+to conditionally execute based on the successful execution of the closest CCB marked with the Serial flag.
+A CCB may only be conditional on exactly one CCB, however, a CCB may be marked both Conditional
+and Serial to allow execution chaining. The flags do NOT allow fan-out chaining, where multiple CCBs
+execute in parallel based on the completion of another CCB.
+
+The Pipeline flag is an optimization that directs the output of one CCB (the "source" CCB) directly to
+the input of the next CCB (the "target" CCB). The target CCB thus does not need to read the input from
+memory. The Pipeline flag is advisory and may be dropped.
+
+Both the Pipeline and Serial bits must be set in the source CCB. The Conditional bit must be set in the
+target CCB. Exactly one CCB must be made conditional on the source CCB; either 0 or 2 target CCBs
+is invalid. However, Pipelines can be extended beyond two CCBs: the sequence would start with a CCB
+with both the Pipeline and Serial bits set, proceed through CCBs with the Pipeline, Serial, and Conditional
+bits set, and terminate at a CCB that has the Conditional bit set, but not the Pipeline bit.
+
+
+                                             512
+\f                                               Coprocessor services
+
+
+          The input of the target CCB must start within 64 bytes of the output of the source CCB or the pipeline flag
+          will be ignored. All CCBs in a pipeline must be submitted in the same call to ccb_submit.
+
+          The various address type fields indicate how the various address values used in the CCB should be
+          interpreted by the virtual machine. Not all of the types specified are used by every CCB format. Types
+          which are not applicable to the given CCB command should be indicated as type 0 (No address). Virtual
+          addresses used in the CCB must have translation entries present in either the TLB or a configured TSB
+          for the submitting virtual processor. Virtual addresses which cannot be translated by the virtual machine
+          will result in the CCB submission being rejected, with the causal virtual address indicated. The CCB
+          may be resubmitted after inserting the translation, or the address may be translated by guest software and
+          resubmitted using the real address translation.
+
+36.2.1. Query CCB Command Formats
+36.2.1.1. Supported Data Formats, Elements Sizes and Offsets
+          Data for query commands may be encoded in multiple possible formats. The data query commands use a
+          common set of values to indicate the encoding formats of the data being processed. Some encoding formats
+          require multiple data streams for processing, requiring the specification of both primary data formats (the
+          encoded data) and secondary data streams (meta-data for the encoded data).
+
+36.2.1.1.1. Primary Input Format
+
+          The primary input format code is a 4-bit field when it is used. There are 10 primary input formats available.
+          The packed formats are not endian neutral. Code values not listed below are reserved.
+
+          Code        Format                              Description
+          0x0         Fixed width byte packed             Up to 16 bytes
+          0x1         Fixed width bit packed              Up to 15 bits (CCB version 0) or 23 bits (CCB version
+                                                          1); bits are read most significant bit to least significant bit
+                                                          within a byte
+          0x2         Variable width byte packed          Data stream of lengths must be provided as a secondary
+                                                          input
+          0x4         Fixed width byte packed with run Up to 16 bytes; data stream of run lengths must be
+                      length encoding                  provided as a secondary input
+          0x5         Fixed width bit packed with run Up to 15 bits (CCB version 0) or 23 bits (CCB version
+                      length encoding                 1); bits are read most significant bit to least significant bit
+                                                      within a byte; data stream of run lengths must be provided
+                                                      as a secondary input
+          0x8         Fixed width byte packed with Up to 16 bytes before the encoding; compressed stream
+                      Huffman (CCB version 0) or bits are read most significant bit to least significant bit
+                      OZIP (CCB version 1) encoding within a byte; pointer to the encoding table must be
+                                                    provided
+          0x9         Fixed width bit packed with Up to 15 bits (CCB version 0) or 23 bits (CCB version
+                      Huffman (CCB version 0) or 1); compressed stream bits are read most significant bit to
+                      OZIP (CCB version 1) encoding least significant bit within a byte; pointer to the encoding
+                                                    table must be provided
+          0xA         Variable width byte packed with Up to 16 bytes before the encoding; compressed stream
+                      Huffman (CCB version 0) or bits are read most significant bit to least significant bit
+                      OZIP (CCB version 1) encoding within a byte; data stream of lengths must be provided as
+                                                      a secondary input; pointer to the encoding table must be
+                                                      provided
+
+
+                                                        513
+\f                                               Coprocessor services
+
+
+          Code        Format                              Description
+          0xC         Fixed width byte packed with        Up to 16 bytes before the encoding; compressed stream
+                      run length encoding, followed by    bits are read most significant bit to least significant bit
+                      Huffman (CCB version 0) or          within a byte; data stream of run lengths must be provided
+                      OZIP (CCB version 1) encoding       as a secondary input; pointer to the encoding table must
+                                                          be provided
+          0xD         Fixed width bit packed with         Up to 15 bits (CCB version 0) or 23 bits(CCB version 1)
+                      run length encoding, followed by    before the encoding; compressed stream bits are read most
+                      Huffman (CCB version 0) or          significant bit to least significant bit within a byte; data
+                      OZIP (CCB version 1) encoding       stream of run lengths must be provided as a secondary
+                                                          input; pointer to the encoding table must be provided
+
+          If OZIP encoding is used, there must be no reserved bytes in the table.
+
+36.2.1.1.2. Primary Input Element Size
+
+          For primary input data streams with fixed size elements, the element size must be indicated in the CCB
+          command. The size is encoded as the number of bits or bytes, minus one. The valid value range for this
+          field depends on the input format selected, as listed in the table above.
+
+36.2.1.1.3. Secondary Input Format
+
+          For primary input data streams which require a secondary input stream, the secondary input stream is
+          always encoded in a fixed width, bit-packed format. The bits are read from most significant bit to least
+          significant bit within a byte. There are two encoding options for the secondary input stream data elements,
+          depending on whether the value of 0 is needed:
+
+          Secondary           Input Description
+          Format Code
+          0                          Element is stored as value minus 1 (0 evaluates to 1, 1 evaluates
+                                     to 2, etc)
+          1                          Element is stored as value
+
+36.2.1.1.4. Secondary Input Element Size
+
+          Secondary input element size is encoded as a two bit field:
+
+          Secondary Input Size Description
+          Code
+          0x0                        1 bit
+          0x1                        2 bits
+          0x2                        4 bits
+          0x3                        8 bits
+
+36.2.1.1.5. Input Element Offsets
+
+          Bit-wise input data streams may have any alignment within the base addressed byte. The offset, specified
+          from most significant bit to least significant bit, is provided as a fixed 3 bit field for each input type. A
+          value of 0 indicates that the first input element begins at the most significant bit in the first byte, and a
+          value of 7 indicates it begins with the least significant bit.
+
+          This field should be zero for any byte-wise primary input data streams.
+
+
+                                                        514
+\f                                              Coprocessor services
+
+
+36.2.1.1.6. Output Format
+
+          Query commands support multiple sizes and encodings for output data streams. There are four possible
+          output encodings, and up to four supported element sizes per encoding. Not all output encodings are
+          supported for every command. The format is indicated by a 4-bit field in the CCB:
+
+           Output Format Code        Description
+           0x0                       Byte aligned, 1 byte elements
+           0x1                       Byte aligned, 2 byte elements
+           0x2                       Byte aligned, 4 byte elements
+           0x3                       Byte aligned, 8 byte elements
+           0x4                       16 byte aligned, 16 byte elements
+           0x5                       Reserved
+           0x6                       Reserved
+           0x7                       Reserved
+           0x8                       Packed vector of single bit elements
+           0x9                       Reserved
+           0xA                       Reserved
+           0xB                       Reserved
+           0xC                       Reserved
+           0xD                       2 byte elements where each element is the index value of a bit,
+                                     from an bit vector, which was 1.
+           0xE                       4 byte elements where each element is the index value of a bit,
+                                     from an bit vector, which was 1.
+           0xF                       Reserved
+
+36.2.1.1.7. Application Data Integrity (ADI)
+
+          On platforms which support ADI, the ADI version number may be specified for each separate memory
+          access type used in the CCB command. ADI checking only occurs when reading data. When writing data,
+          the specified ADI version number overwrites any existing ADI value in memory.
+
+          An ADI version value of 0 or 0xF indicates the ADI checking is disabled for that data access, even if it is
+          enabled in memory. By setting the appropriate flag in CCB_SUBMIT (Section 36.3.1, “ccb_submit”) it is
+          also an option to disable ADI checking for all inputs accessed via virtual address for all CCBs submitted
+          during that hypercall invocation.
+
+          The ADI value is only guaranteed to be checked on the first 64 bytes of each data access. Mismatches on
+          subsequent data chunks may not be detected, so guest software should be careful to use page size checking
+          to protect against buffer overruns.
+
+36.2.1.1.8. Page size checking
+
+          All data accesses used in CCB commands must be bounded within a single memory page. When addresses
+          are provided using a virtual address, the page size for checking is extracted from the TTE for that virtual
+          address. When using real addresses, the guest must supply the page size in the same field as the address
+          value. The page size must be one of the sizes supported by the underlying virtual machine. Using a value
+          that is not supported may result in the CCB submission being rejected or the generation of a CCB parsing
+          error in the completion area.
+
+
+                                                       515
+\f                                               Coprocessor services
+
+
+36.2.1.2. Extract command
+
+        Converts an input vector in one format to an output vector in another format. All input format types are
+        supported.
+
+        The only supported output format is a padded, byte-aligned output stream, using output codes 0x0 - 0x4.
+        When the specified output element size is larger than the extracted input element size, zeros are padded to
+        the extracted input element. First, if the decompressed input size is not a whole number of bytes, 0 bits are
+        padded to the most significant bit side till the next byte boundary. Next, if the output element size is larger
+        than the byte padded input element, bytes of value 0 are added based on the Padding Direction bit in the
+        CCB. If the output element size is smaller than the byte-padded input element size, the input element is
+        truncated by dropped from the least significant byte side until the selected output size is reached.
+
+        The return value of the CCB completion area is invalid. The “number of elements processed” field in the
+        CCB completion area will be valid.
+
+        The extract CCB is a 64-byte “short format” CCB.
+
+        The extract CCB command format can be specified by the following packed C structure for a big-endian
+        machine:
+
+
+                  struct extract_ccb {
+                         uint32_t header;
+                         uint32_t control;
+                         uint64_t completion;
+                         uint64_t primary_input;
+                         uint64_t data_access_control;
+                         uint64_t secondary_input;
+                         uint64_t reserved;
+                         uint64_t output;
+                         uint64_t table;
+                  };
+
+
+        The exact field offsets, sizes, and composition are as follows:
+
+         Offset         Size            Field Description
+         0              4               CCB header (Table 36.1, “CCB Header Format”)
+         4              4               Command control
+                                        Bits        Field Description
+                                        [31:28]     Primary Input Format (see Section 36.2.1.1.1, “Primary Input
+                                                    Format”)
+                                        [27:23]     Primary Input Element Size (see Section 36.2.1.1.2, “Primary
+                                                    Input Element Size”)
+                                        [22:20]     Primary Input Starting Offset (see Section 36.2.1.1.5, “Input
+                                                    Element Offsets”)
+                                        [19]        Secondary Input Format (see Section 36.2.1.1.3, “Secondary
+                                                    Input Format”)
+                                        [18:16]     Secondary Input Starting Offset (see Section 36.2.1.1.5, “Input
+                                                    Element Offsets”)
+
+
+                                                       516
+\f                        Coprocessor services
+
+
+Offset   Size   Field Description
+                Bits         Field Description
+                [15:14]      Secondary Input Element Size (see Section 36.2.1.1.4,
+                             “Secondary Input Element Size”
+                [13:10]      Output Format (see Section 36.2.1.1.6, “Output Format”)
+                [9]          Padding Direction selector: A value of 1 causes padding bytes
+                             to be added to the left side of output elements. A value of 0
+                             causes padding bytes to be added to the right side of output
+                             elements.
+                [8:0]        Reserved
+8        8      Completion
+                Bits         Field Description
+                [63:60]      ADI version (see Section 36.2.1.1.7, “Application Data
+                             Integrity (ADI)”)
+                [59]         If set to 1, a virtual device interrupt will be generated using
+                             the device interrupt number specified in the lower bits of this
+                             completion word. If 0, the lower bits of this completion word
+                             are ignored.
+                [58:6]       Completion area address bits [58:6]. Address type is
+                             determined by CCB header.
+                [5:0]        Virtual device interrupt number for completion interrupt, if
+                             enabled.
+16       8      Primary Input
+                Bits         Field Description
+                [63:60]      ADI version (see Section 36.2.1.1.7, “Application Data
+                             Integrity (ADI)”)
+                [59:56]      If using real address, these bits should be filled in with the
+                             page size code for the page boundary checking the guest wants
+                             the virtual machine to use when accessing this data stream
+                             (checking is only guaranteed to be performed when using API
+                             version 1.1 and later). If using a virtual address, this field will
+                             be used as as primary input address bits [59:56].
+                [55:0]       Primary input address bits [55:0]. Address type is determined
+                             by CCB header.
+24       8      Data Access Control
+                Bits         Field Description
+                [63:62]      Flow Control
+                             Value      Description
+                             0b'00      Disable flow control
+                             0b'01      Enable flow control (only valid with "ORCL,sun4v-
+                                        dax-fc" compatible virtual device variants)
+                             0b'10      Reserved
+                             0b'11      Reserved
+                [61:60]      Reserved (API 1.0)
+
+
+                                517
+\f                       Coprocessor services
+
+
+Offset   Size   Field Description
+                Bits        Field Description
+                            Pipeline target (API 2.0)
+                            Value      Description
+                            0b'00      Connect to primary input
+                            0b'01      Connect to secondary input
+                            0b'10      Reserved
+                            0b'11      Reserved
+                [59:40]     Output buffer size given in units of 64 bytes, minus 1. Value of
+                            0 means 64 bytes, value of 1 means 128 bytes, etc. Buffer size is
+                            only enforced if flow control is enabled in Flow Control field.
+                [39:32]     Reserved
+                [31:30]     Output Data Cache Allocation
+                            Value      Description
+                            0b'00      Do not allocate cache lines for output data stream.
+                            0b'01      Force cache lines for output data stream to be
+                                       allocated in the cache that is local to the submitting
+                                       virtual cpu.
+                            0b'10      Allocate cache lines for output data stream, but allow
+                                       existing cache lines associated with the data to remain
+                                       in their current cache instance. Any memory not
+                                       already in cache will be allocated in the cache local
+                                       to the submitting virtual cpu.
+                            0b'11      Reserved
+                [29:26]     Reserved
+                [25:24]     Primary Input Length Format
+                            Value      Description
+                            0b'00      Number of primary symbols
+                            0b'01      Number of primary bytes
+                            0b'10      Number of primary bits
+                            0b'11      Reserved
+                [23:0]      Primary Input Length
+                            Format                      Field Value
+                            # of primary symbols        Number of input elements to process,
+                                                        minus 1. Command execution stops
+                                                        once count is reached.
+                            # of primary bytes          Number of input bytes to process,
+                                                        minus 1. Command execution stops
+                                                        once count is reached. The count is
+                                                        done before any decompression or
+                                                        decoding.
+                            # of primary bits           Number of input bits to process,
+                                                        minus 1. Command execution stops
+
+
+
+                               518
+\f                                                Coprocessor services
+
+
+        Offset          Size           Field Description
+                                        Bits         Field Description
+                                                     Format                     Field Value
+                                                                                once count is reached. The count is
+                                                                                done before any decompression or
+                                                                                decoding, and does not include any
+                                                                                bits skipped by the Primary Input
+                                                                                Offset field value of the command
+                                                                                control word.
+        32              8              Secondary Input, if used by Primary Input Format. Same fields as Primary
+                                       Input.
+        40              8              Reserved
+        48              8              Output (same fields as Primary Input)
+        56              8              Symbol Table (if used by Primary Input)
+                                        Bits         Field Description
+                                        [63:60]      ADI version (see Section 36.2.1.1.7, “Application Data
+                                                     Integrity (ADI)”)
+                                        [59:56]      If using real address, these bits should be filled in with the
+                                                     page size code for the page boundary checking the guest wants
+                                                     the virtual machine to use when accessing this data stream
+                                                     (checking is only guaranteed to be performed when using API
+                                                     version 1.1 and later). If using a virtual address, this field will
+                                                     be used as as symbol table address bits [59:56].
+                                        [55:4]       Symbol table address bits [55:4]. Address type is determined
+                                                     by CCB header.
+                                        [3:0]        Symbol table version
+                                                     Value     Description
+                                                     0         Huffman encoding. Must use 64 byte aligned table
+                                                               address. (Only available when using version 0 CCBs)
+                                                     1         OZIP encoding. Must use 16 byte aligned table
+                                                               address. (Only available when using version 1 CCBs)
+
+
+36.2.1.3. Scan commands
+
+        The scan commands search a stream of input data elements for values which match the selection criteria.
+        All the input format types are supported. There are multiple formats for the scan commands, allowing the
+        scan to search for exact matches to one value, exact matches to either of two values, or any value within
+        a specified range. The specific type of scan is indicated by the command code in the CCB header. For the
+        scan range commands, the boundary conditions can be specified as greater-than-or-equal-to a value, less-
+        than-or-equal-to a value, or both by using two boundary values.
+
+        There are two supported formats for the output stream: the bit vector and index array formats (codes 0x8,
+        0xD, and 0xE). For the standard scan command using the bit vector output, for each input element there
+        exists one bit in the vector that is set if the input element matched the scan criteria, or clear if not. The
+        inverted scan command inverts the polarity of the bits in the output. The most significant bit of the first
+        byte of the output stream corresponds to the first element in the input stream. The standard index array
+        output format contains one array entry for each input element that matched the scan criteria. Each array
+
+
+
+                                                         519
+\f                                       Coprocessor services
+
+
+entry is the index of an input element that matched the scan criteria. An inverted scan command produces
+a similar array, but of all the input elements which did NOT match the scan criteria.
+
+The return value of the CCB completion area contains the number of input elements found which match
+the scan criteria (or number that did not match for the inverted scans). The “number of elements processed”
+field in the CCB completion area will be valid, indicating the number of input elements processed.
+
+These commands are 128-byte “long format” CCBs.
+
+The scan CCB command format can be specified by the following packed C structure for a big-endian
+machine:
+
+
+         struct scan_ccb         {
+                uint32_t         header;
+                uint32_t         control;
+                uint64_t         completion;
+                uint64_t         primary_input;
+                uint64_t         data_access_control;
+                uint64_t         secondary_input;
+                uint64_t         match_criteria0;
+                uint64_t         output;
+                uint64_t         table;
+                uint64_t         match_criteria1;
+                uint64_t         match_criteria2;
+                uint64_t         match_criteria3;
+                uint64_t         reserved[5];
+         };
+
+
+The exact field offsets, sizes, and composition are as follows:
+
+Offset         Size            Field Description
+0              4               CCB header (Table 36.1, “CCB Header Format”)
+4              4               Command control
+                               Bits         Field Description
+                               [31:28]      Primary Input Format (see Section 36.2.1.1.1, “Primary Input
+                                            Format”)
+                               [27:23]      Primary Input Element Size (see Section 36.2.1.1.2, “Primary
+                                            Input Element Size”)
+                               [22:20]      Primary Input Starting Offset (see Section 36.2.1.1.5, “Input
+                                            Element Offsets”)
+                               [19]         Secondary Input Format (see Section 36.2.1.1.3, “Secondary
+                                            Input Format”)
+                               [18:16]      Secondary Input Starting Offset (see Section 36.2.1.1.5, “Input
+                                            Element Offsets”)
+                               [15:14]      Secondary Input Element Size (see Section 36.2.1.1.4,
+                                            “Secondary Input Element Size”
+                               [13:10]      Output Format (see Section 36.2.1.1.6, “Output Format”)
+                               [9:5]        Operand size for first scan criteria value. In a scan value
+                                            operation, this is one of two potential exact match values.
+                                            In a scan range operation, this is the size of the upper range
+
+
+                                               520
+\f                        Coprocessor services
+
+
+Offset   Size   Field Description
+                Bits         Field Description
+                             boundary. The value of this field is the number of bytes in the
+                             operand, minus 1. Values 0xF-0x1E are reserved. A value of
+                             0x1F indicates this operand is not in use for this scan operation.
+                [4:0]        Operand size for second scan criteria value. In a scan value
+                             operation, this is one of two potential exact match values.
+                             In a scan range operation, this is the size of the lower range
+                             boundary. The value of this field is the number of bytes in the
+                             operand, minus 1. Values 0xF-0x1E are reserved. A value of
+                             0x1F indicates this operand is not in use for this scan operation.
+8        8      Completion (same fields as Section 36.2.1.2, “Extract command”)
+16       8      Primary Input (same fields as Section 36.2.1.2, “Extract command”)
+24       8      Data Access Control (same fields as Section 36.2.1.2, “Extract command”)
+32       8      Secondary Input, if used by Primary Input Format. Same fields as Primary
+                Input.
+40       4      Most significant 4 bytes of first scan criteria operand. If first operand is less
+                than 4 bytes, the value is left-aligned to the lowest address bytes.
+44       4      Most significant 4 bytes of second scan criteria operand. If second operand
+                is less than 4 bytes, the value is left-aligned to the lowest address bytes.
+48       8      Output (same fields as Primary Input)
+56       8      Symbol Table (if used by Primary Input). Same fields as Section 36.2.1.2,
+                “Extract command”
+64       4      Next 4 most significant bytes of first scan criteria operand occurring after the
+                bytes specified at offset 40, if needed by the operand size. If first operand
+                is less than 8 bytes, the valid bytes are left-aligned to the lowest address.
+68       4      Next 4 most significant bytes of second scan criteria operand occurring after
+                the bytes specified at offset 44, if needed by the operand size. If second
+                operand is less than 8 bytes, the valid bytes are left-aligned to the lowest
+                address.
+72       4      Next 4 most significant bytes of first scan criteria operand occurring after the
+                bytes specified at offset 64, if needed by the operand size. If first operand
+                is less than 12 bytes, the valid bytes are left-aligned to the lowest address.
+76       4      Next 4 most significant bytes of second scan criteria operand occurring after
+                the bytes specified at offset 68, if needed by the operand size. If second
+                operand is less than 12 bytes, the valid bytes are left-aligned to the lowest
+                address.
+80       4      Next 4 most significant bytes of first scan criteria operand occurring after the
+                bytes specified at offset 72, if needed by the operand size. If first operand
+                is less than 16 bytes, the valid bytes are left-aligned to the lowest address.
+84       4      Next 4 most significant bytes of second scan criteria operand occurring after
+                the bytes specified at offset 76, if needed by the operand size. If second
+                operand is less than 16 bytes, the valid bytes are left-aligned to the lowest
+                address.
+
+
+
+
+                                521
+\f                                               Coprocessor services
+
+
+36.2.1.4. Translate commands
+
+        The translate commands takes an input array of indices, and a table of single bit values indexed by those
+        indices, and outputs a bit vector or index array created by reading the tables bit value at each index in
+        the input array. The output should therefore contain exactly one bit per index in the input data stream,
+        when outputting as a bit vector. When outputting as an index array, the number of elements depends on the
+        values read in the bit table, but will always be less than, or equal to, the number of input elements. Only
+        a restricted subset of the possible input format types are supported. No variable width or Huffman/OZIP
+        encoded input streams are allowed. The primary input data element size must be 3 bytes or less.
+
+        The maximum table index size allowed is 15 bits, however, larger input elements may be used to provide
+        additional processing of the output values. If 2 or 3 byte values are used, the least significant 15 bits are
+        used as an index into the bit table. The most significant 9 bits (when using 3-byte input elements) or single
+        bit (when using 2-byte input elements) are compared against a fixed 9-bit test value provided in the CCB.
+        If the values match, the value from the bit table is used as the output element value. If the values do not
+        match, the output data element value is forced to 0.
+
+        In the inverted translate operation, the bit value read from bit table is inverted prior to its use. The additional
+        additional processing based on any additional non-index bits remains unchanged, and still forces the output
+        element value to 0 on a mismatch. The specific type of translate command is indicated by the command
+        code in the CCB header.
+
+        There are two supported formats for the output stream: the bit vector and index array formats (codes 0x8,
+        0xD, and 0xE). The index array format is an array of indices of bits which would have been set if the
+        output format was a bit array.
+
+        The return value of the CCB completion area contains the number of bits set in the output bit vector,
+        or number of elements in the output index array. The “number of elements processed” field in the CCB
+        completion area will be valid, indicating the number of input elements processed.
+
+        These commands are 64-byte “short format” CCBs.
+
+        The translate CCB command format can be specified by the following packed C structure for a big-endian
+        machine:
+
+
+                 struct translate_ccb {
+                        uint32_t header;
+                        uint32_t control;
+                        uint64_t completion;
+                        uint64_t primary_input;
+                        uint64_t data_access_control;
+                        uint64_t secondary_input;
+                        uint64_t reserved;
+                        uint64_t output;
+                        uint64_t table;
+                 };
+
+
+        The exact field offsets, sizes, and composition are as follows:
+
+
+        Offset          Size             Field Description
+        0               4                CCB header (Table 36.1, “CCB Header Format”)
+
+
+                                                        522
+\f                        Coprocessor services
+
+
+Offset   Size   Field Description
+4        4      Command control
+                Bits         Field Description
+                [31:28]      Primary Input Format (see Section 36.2.1.1.1, “Primary Input
+                             Format”)
+                [27:23]      Primary Input Element Size (see Section 36.2.1.1.2, “Primary
+                             Input Element Size”)
+                [22:20]      Primary Input Starting Offset (see Section 36.2.1.1.5, “Input
+                             Element Offsets”)
+                [19]         Secondary Input Format (see Section 36.2.1.1.3, “Secondary
+                             Input Format”)
+                [18:16]      Secondary Input Starting Offset (see Section 36.2.1.1.5, “Input
+                             Element Offsets”)
+                [15:14]      Secondary Input Element Size (see Section 36.2.1.1.4,
+                             “Secondary Input Element Size”
+                [13:10]      Output Format (see Section 36.2.1.1.6, “Output Format”)
+                [9]          Reserved
+                [8:0]        Test value used for comparison against the most significant bits
+                             in the input values, when using 2 or 3 byte input elements.
+8        8      Completion (same fields as Section 36.2.1.2, “Extract command”
+16       8      Primary Input (same fields as Section 36.2.1.2, “Extract command”
+24       8      Data Access Control (same fields as Section 36.2.1.2, “Extract command”,
+                except Primary Input Length Format may not use the 0x0 value)
+32       8      Secondary Input, if used by Primary Input Format. Same fields as Primary
+                Input.
+40       8      Reserved
+48       8      Output (same fields as Primary Input)
+56       8      Bit Table
+                Bits         Field Description
+                [63:60]      ADI version (see Section 36.2.1.1.7, “Application Data
+                             Integrity (ADI)”)
+                [59:56]      If using real address, these bits should be filled in with the
+                             page size code for the page boundary checking the guest wants
+                             the virtual machine to use when accessing this data stream
+                             (checking is only guaranteed to be performed when using API
+                             version 1.1 and later). If using a virtual address, this field will
+                             be used as as bit table address bits [59:56]
+                [55:4]       Bit table address bits [55:4]. Address type is determined by
+                             CCB header. Address must be 64-byte aligned (CCB version
+                             0) or 16-byte aligned (CCB version 1).
+                [3:0]        Bit table version
+                             Value      Description
+                             0          4KB table size
+                             1          8KB table size
+
+
+
+                                 523
+\f                                              Coprocessor services
+
+
+36.2.1.5. Select command
+        The select command filters the primary input data stream by using a secondary input bit vector to determine
+        which input elements to include in the output. For each bit set at a given index N within the bit vector,
+        the Nth input element is included in the output. If the bit is not set, the element is not included. Only a
+        restricted subset of the possible input format types are supported. No variable width or run length encoded
+        input streams are allowed, since the secondary input stream is used for the filtering bit vector.
+
+        The only supported output format is a padded, byte-aligned output stream. The stream follows the same
+        rules and restrictions as padded output stream described in Section 36.2.1.2, “Extract command”.
+
+        The return value of the CCB completion area contains the number of bits set in the input bit vector. The
+        "number of elements processed" field in the CCB completion area will be valid, indicating the number
+        of input elements processed.
+
+        The select CCB is a 64-byte “short format” CCB.
+
+        The select CCB command format can be specified by the following packed C structure for a big-endian
+        machine:
+
+
+                  struct select_ccb {
+                         uint32_t header;
+                         uint32_t control;
+                         uint64_t completion;
+                         uint64_t primary_input;
+                         uint64_t data_access_control;
+                         uint64_t secondary_input;
+                         uint64_t reserved;
+                         uint64_t output;
+                         uint64_t table;
+                  };
+
+
+        The exact field offsets, sizes, and composition are as follows:
+
+         Offset        Size            Field Description
+         0             4               CCB header (Table 36.1, “CCB Header Format”)
+         4             4               Command control
+                                       Bits        Field Description
+                                       [31:28]     Primary Input Format (see Section 36.2.1.1.1, “Primary Input
+                                                   Format”)
+                                       [27:23]     Primary Input Element Size (see Section 36.2.1.1.2, “Primary
+                                                   Input Element Size”)
+                                       [22:20]     Primary Input Starting Offset (see Section 36.2.1.1.5, “Input
+                                                   Element Offsets”)
+                                       [19]        Secondary Input Format (see Section 36.2.1.1.3, “Secondary
+                                                   Input Format”)
+                                       [18:16]     Secondary Input Starting Offset (see Section 36.2.1.1.5, “Input
+                                                   Element Offsets”)
+                                       [15:14]     Secondary Input Element Size (see Section 36.2.1.1.4,
+                                                   “Secondary Input Element Size”
+
+
+                                                      524
+\f                                               Coprocessor services
+
+
+        Offset         Size            Field Description
+                                       Bits         Field Description
+                                       [13:10]      Output Format (see Section 36.2.1.1.6, “Output Format”)
+                                       [9]          Padding Direction selector: A value of 1 causes padding bytes
+                                                    to be added to the left side of output elements. A value of 0
+                                                    causes padding bytes to be added to the right side of output
+                                                    elements.
+                                       [8:0]        Reserved
+        8              8               Completion (same fields as Section 36.2.1.2, “Extract command”
+        16             8               Primary Input (same fields as Section 36.2.1.2, “Extract command”
+        24             8               Data Access Control (same fields as Section 36.2.1.2, “Extract command”)
+        32             8               Secondary Bit Vector Input. Same fields as Primary Input.
+        40             8               Reserved
+        48             8               Output (same fields as Primary Input)
+        56             8               Symbol Table (if used by Primary Input). Same fields as Section 36.2.1.2,
+                                       “Extract command”
+
+36.2.1.6. No-op and Sync commands
+        The no-op (no operation) command is a CCB which has no processing effect. The CCB, when processed
+        by the virtual machine, simply updates the completion area with its execution status. The CCB may have
+        the serial-conditional flags set in order to restrict when it executes.
+
+        The sync command is a variant of the no-op command which with restricted execution timing. A sync
+        command CCB will only execute when all previous commands submitted in the same request have
+        completed. This is stronger than the conditional flag sequencing, which is only dependent on a single
+        previous serial CCB. While the relative ordering is guaranteed, virtual machine implementations with
+        shared hardware resources may cause the sync command to wait for longer than the minimum required
+        time.
+
+        The return value of the CCB completion area is invalid for these CCBs. The “number of elements
+        processed” field is also invalid for these CCBs.
+
+        These commands are 64-byte “short format” CCBs.
+
+        The no-op CCB command format can be specified by the following packed C structure for a big-endian
+        machine:
+
+
+                 struct nop_ccb {
+                        uint32_t header;
+                        uint32_t control;
+                        uint64_t completion;
+                        uint64_t reserved[6];
+                 };
+
+
+        The exact field offsets, sizes, and composition are as follows:
+
+        Offset         Size            Field Description
+        0              4               CCB header (Table 36.1, “CCB Header Format”)
+
+
+                                                       525
+\f                                          Coprocessor services
+
+
+       Offset        Size          Field Description
+       4             4             Command control
+                                   Bits        Field Description
+                                   [31]        If set, this CCB functions as a Sync command. If clear, this
+                                               CCB functions as a No-op command.
+                                   [30:0]      Reserved
+       8             8             Completion (same fields as Section 36.2.1.2, “Extract command”
+       16            46            Reserved
+
+36.2.2. CCB Completion Area
+       All CCB commands use a common 128-byte Completion Area format, which can be specified by the
+       following packed C structure for a big-endian machine:
+
+
+                struct completion_area {
+                       uint8_t status_flag;
+                       uint8_t error_note;
+                       uint8_t rsvd0[2];
+                       uint32_t error_values;
+                       uint32_t output_size;
+                       uint32_t rsvd1;
+                       uint64_t run_time;
+                       uint64_t run_stats;
+                       uint32_t elements;
+                       uint8_t rsvd2[20];
+                       uint64_t return_value;
+                       uint64_t extra_return_value[8];
+                };
+
+
+       The Completion Area must be a 128-byte aligned memory location. The exact layout can be described
+       using byte offsets and sizes relative to the memory base:
+
+       Offset        Size          Field Description
+       0             1             CCB execution status
+                                   0x0                  Command not yet completed
+                                   0x1                  Command ran and succeeded
+                                   0x2                  Command ran and failed (partial results may be been
+                                                        produced)
+                                   0x3                  Command ran and was killed (partial execution may
+                                                        have occurred)
+                                   0x4                  Command was not run
+                                   0x5-0xF              Reserved
+       1             1             Error reason code
+                                   0x0                  Reserved
+                                   0x1                  Buffer overflow
+
+
+                                                  526
+\f                                      Coprocessor services
+
+
+Offset          Size           Field Description
+                                0x2                 CCB decoding error
+                                0x3                 Page overflow
+                                0x4-0x6             Reserved
+                                0x7                 Command was killed
+                                0x8                 Command execution timeout
+                                0x9                 ADI miscompare error
+                                0xA                 Data format error
+                                0xB-0xD             Reserved
+                                0xE                 Unexpected hardware error (Do not retry)
+                                0xF                 Unexpected hardware error (Retry is ok)
+                                0x10-0x7F           Reserved
+                                0x80                Partial Symbol Warning
+                                0x81-0xFF           Reserved
+2               2              Reserved
+4               4              If a partial symbol warning was generated, this field contains the number
+                               of remaining bits which were not decoded.
+8               4              Number of bytes of output produced
+12              4              Reserved
+16              8              Runtime of command (unspecified time units)
+24              8              Reserved
+32              4              Number of elements processed
+36              20             Reserved
+56              8              Return value
+64              64             Extended return value
+
+The CCB completion area should be treated as read-only by guest software. The CCB execution status
+byte will be cleared by the Hypervisor to reflect the pending execution status when the CCB is submitted
+successfully. All other fields are considered invalid upon CCB submission until the CCB execution status
+byte becomes non-zero.
+
+CCBs which complete with status 0x2 or 0x3 may produce partial results and/or side effects due to partial
+execution of the CCB command. Some valid data may be accessible depending on the fault type, however,
+it is recommended that guest software treat the destination buffer as being in an unknown state. If a CCB
+completes with a status byte of 0x2, the error reason code byte can be read to determine what corrective
+action should be taken.
+
+A buffer overflow indicates that the results of the operation exceeded the size of the output buffer indicated
+in the CCB. The operation can be retried by resubmitting the CCB with a larger output buffer.
+
+A CCB decoding error indicates that the CCB contained some invalid field values. It may be also be
+triggered if the CCB output is directed at a non-existent secondary input and the pipelining hint is followed.
+
+A page overflow error indicates that the operation required accessing a memory location beyond the page
+size associated with a given address. No data will have been read or written past the page boundary, but
+partial results may have been written to the destination buffer. The CCB can be resubmitted with a larger
+page size memory allocation to complete the operation.
+
+
+                                              527
+\f                                            Coprocessor services
+
+
+       In the case of pipelined CCBs, a page overflow error will be triggered if the output from the pipeline source
+       CCB ends before the input of the pipeline target CCB. Page boundaries are ignored when the pipeline
+       hint is followed.
+
+       Command kill indicates that the CCB execution was halted or prevented by use of the ccb_kill API call.
+
+       Command timeout indicates that the CCB execution began, but did not complete within a pre-determined
+       limit set by the virtual machine. The command may have produced some or no output. The CCB may be
+       resubmitted with no alterations.
+
+       ADI miscompare indicates that the memory buffer version specified in the CCB did not match the value
+       in memory when accessed by the virtual machine. Guest software should not attempt to resubmit the CCB
+       without determining the cause of the version mismatch.
+
+       A data format error indicates that the input data stream did not follow the specified data input formatting
+       selected in the CCB.
+
+       Some CCBs which encounter hardware errors may be resubmitted without change. Persistent hardware
+       errors may result in multiple failures until RAS software can identify and isolate the faulty component.
+
+       The output size field indicates the number of bytes of valid output in the destination buffer. This field is
+       not valid for all possible CCB commands.
+
+       The runtime field indicates the execution time of the CCB command once it leaves the internal virtual
+       machine queue. The time units are fixed, but unspecified, allowing only relative timing comparisons
+       by guest software. The time units may also vary by hardware platform, and should not be construed to
+       represent any absolute time value.
+
+       Some data query commands process data in units of elements. If applicable to the command, the number of
+       elements processed is indicated in the listed field. This field is not valid for all possible CCB commands.
+
+       The return value and extended return value fields are output locations for commands which do not use
+       a destination output buffer, or have secondary return results. The field is not valid for all possible CCB
+       commands.
+
+36.3. Hypervisor API Functions
+36.3.1. ccb_submit
+       trap#             FAST_TRAP
+       function#         CCB_SUBMIT
+       arg0              address
+       arg1              length
+       arg2              flags
+       arg3              reserved
+       ret0              status
+       ret1              length
+       ret2              status data
+       ret3              reserved
+
+       Submit one or more coprocessor control blocks (CCBs) for evaluation and processing by the virtual
+       machine. The CCBs are passed in a linear array indicated by address. length indicates the size of
+       the array in bytes.
+
+
+                                                     528
+\f                                      Coprocessor services
+
+
+The address should be aligned to the size indicated by length, rounded up to the nearest power of
+two. Virtual machines implementations may reject submissions which do not adhere to that alignment.
+length must be a multiple of 64 bytes. If length is zero, the maximum supported array length will be
+returned as length in ret1. In all other cases, the length value in ret1 will reflect the number of bytes
+successfully consumed from the input CCB array.
+
+      Implementation note
+      Virtual machines should never reject submissions based on the alignment of address if the
+      entire array is contained within a single memory page of the smallest page size supported by the
+      virtual machine.
+
+A guest may choose to submit addresses used in this API function, including the CCB array address,
+as either a real or virtual addresses, with the type of each address indicated in flags. Virtual addresses
+must be present in either the TLB or an active TSB to be processed. The translation context for virtual
+addresses is determined by a combination of CCB contents and the flags argument.
+
+The flags argument is divided into multiple fields defined as follows:
+
+
+Bits            Field Description
+[63:16]         Reserved
+[15]            Disable ADI for VA reads (in API 2.0)
+                Reserved (in API 1.0)
+[14]            Virtual addresses within CCBs are translated in privileged context
+[13:12]         Alternate translation context for virtual addresses within CCBs:
+                 0b'00        CCBs requesting alternate context are rejected
+                 0b'01        Reserved
+                 0b'10        CCBs requesting alternate context use secondary context
+                 0b'11        CCBs requesting alternate context use nucleus context
+[11:9]          Reserved
+[8]             Queue info flag
+[7]             All-or-nothing flag
+[6]             If address is a virtual address, treat its translation context as privileged
+[5:4]           Address type of address:
+                 0b'00        Real address
+                 0b'01        Virtual address in primary context
+                 0b'10        Virtual address in secondary context
+                 0b'11        Virtual address in nucleus context
+[3:2]           Reserved
+[1:0]           CCB command type:
+                 0b'00        Reserved
+                 0b'01        Reserved
+                 0b'10        Query command
+                 0b'11        Reserved
+
+
+
+                                              529
+\f                                             Coprocessor services
+
+
+         The CCB submission type and address type for the CCB array must be provided in the flags argument.
+         All other fields are optional values which change the default behavior of the CCB processing.
+
+         When set to one, the "Disable ADI for VA reads" bit will turn off ADI checking when using a virtual
+         address to load data. ADI checking will still be done when loading real-addressed memory. This bit is only
+         available when using major version 2 of the coprocessor API group; at major version 1 it is reserved. For
+         more information about using ADI and DAX, see Section 36.2.1.1.7, “Application Data Integrity (ADI)”.
+
+         By default, all virtual addresses are treated as user addresses. If the virtual address translations are
+         privileged, they must be marked as such in the appropriate flags field. The virtual addresses used within
+         the submitted CCBs must all be translated with the same privilege level.
+
+         By default, all virtual addresses used within the submitted CCBs are translated using the primary context
+         active at the time of the submission. The address type field within a CCB allows each address to request
+         translation in an alternate address context. The address context used when the alternate address context is
+         requested is selected in the flags argument.
+
+         The all-or-nothing flag specifies whether the virtual machine should allow partial submissions of the
+         input CCB array. When using CCBs with serial-conditional flags, it is strongly recommended to use
+         the all-or-nothing flag to avoid broken conditional chains. Using long CCB chains on a machine under
+         high coprocessor load may make this impractical, however, and require submitting without the flag.
+         When submitting serial-conditional CCBs without the all-or-nothing flag, guest software must manually
+         implement the serial-conditional behavior at any point where the chain was not submitted in a single API
+         call, and resubmission of the remaining CCBs should clear any conditional flag that might be set in the
+         first remaining CCB. Failure to do so will produce indeterminate CCB execution status and ordering.
+
+         When the all-or-nothing flag is not specified, callers should check the value of length in ret1 to determine
+         how many CCBs from the array were successfully submitted. Any remaining CCBs can be resubmitted
+         without modifications.
+
+         The value of length in ret1 is also valid when the API call returns an error, and callers should always
+         check its value to determine which CCBs in the array were already processed. This will additionally
+         identify which CCB encountered the processing error, and was not submitted successfully.
+
+         If the queue info flag is used during submission, and at least one CCB was successfully submitted, the
+         length value in ret1 will be a multi-field value defined as follows:
+          Bits          Field Description
+          [63:48]       DAX unit instance identifier
+          [47:32]       DAX queue instance identifier
+          [31:16]       Reserved
+          [15:0]        Number of CCB bytes successfully submitted
+
+         The value of status data depends on the status value. See error status code descriptions for details.
+         The value is undefined for status values that do not specifically list a value for the status data.
+
+         The API has a reserved input and output register which will be used in subsequent minor versions of this
+         API function. Guest software implementations should treat that register as voltile across the function call
+         in order to maintain forward compatibility.
+
+36.3.1.1. Errors
+          EOK                       One or more CCBs have been accepted and enqueued in the virtual machine
+                                    and no errors were been encountered during submission. Some submitted
+                                    CCBs may not have been enqueued due to internal virtual machine limitations,
+                                    and may be resubmitted without changes.
+
+
+                                                       530
+\f                        Coprocessor services
+
+
+EWOULDBLOCK    An internal resource conflict within the virtual machine has prevented it from
+               being able to complete the CCB submissions sufficiently quickly, requiring
+               it to abandon processing before it was complete. Some CCBs may have been
+               successfully enqueued prior to the block, and all remaining CCBs may be
+               resubmitted without changes.
+EBADALIGN      CCB array is not on a 64-byte boundary, or the array length is not a multiple
+               of 64 bytes.
+ENORADDR       A real address used either for the CCB array, or within one of the submitted
+               CCBs, is not valid for the guest. Some CCBs may have been enqueued prior
+               to the error being detected.
+ENOMAP         A virtual address used either for the CCB array, or within one of the submitted
+               CCBs, could not be translated by the virtual machine using either the TLB
+               or TSB contents. The submission may be retried after adding the required
+               mapping, or by converting the virtual address into a real address. Due to the
+               shared nature of address translation resources, there is no theoretical limit on
+               the number of times the translation may fail, and it is recommended all guests
+               implement some real address based backup. The virtual address which failed
+               translation is returned as status data in ret2. Some CCBs may have been
+               enqueued prior to the error being detected.
+EINVAL         The virtual machine detected an invalid CCB during submission, or invalid
+               input arguments, such as bad flag values. Note that not all invalid CCB values
+               will be detected during submission, and some may be reported as errors in the
+               completion area instead. Some CCBs may have been enqueued prior to the
+               error being detected. This error may be returned if the CCB version is invalid.
+ETOOMANY       The request was submitted with the all-or-nothing flag set, and the array size is
+               greater than the virtual machine can support in a single request. The maximum
+               supported size for the current virtual machine can be queried by submitting a
+               request with a zero length array, as described above.
+ENOACCESS      The guest does not have permission to submit CCBs, or an address used in a
+               CCBs lacks sufficient permissions to perform the required operation (no write
+               permission on the destination buffer address, for example). A virtual address
+               which fails permission checking is returned as status data in ret2. Some
+               CCBs may have been enqueued prior to the error being detected.
+EUNAVAILABLE   The requested CCB operation could not be performed at this time. The
+               restricted operation availability may apply only to the first unsuccessfully
+               submitted CCB, or may apply to a larger scope. The status should not be
+               interpreted as permanent, and the guest should attempt to submit CCBs in
+               the future which had previously been unable to be performed. The status
+               data provides additional information about scope of the restricted availability
+               as follows:
+               Value       Description
+               0           Processing for the exact CCB instance submitted was unavailable,
+                           and it is recommended the guest emulate the operation. The
+                           guest should continue to submit all other CCBs, and assume no
+                           restrictions beyond this exact CCB instance.
+               1           Processing is unavailable for all CCBs using the requested opcode,
+                           and it is recommended the guest emulate the operation. The
+                           guest should continue to submit all other CCBs that use different
+                           opcodes, but can expect continued rejections of CCBs using the
+                           same opcode in the near future.
+
+
+                                 531
+\f                                              Coprocessor services
+
+
+                                      Value     Description
+                                      2         Processing is unavailable for all CCBs using the requested CCB
+                                                version, and it is recommended the guest emulate the operation.
+                                                The guest should continue to submit all other CCBs that use
+                                                different CCB versions, but can expect continued rejections of
+                                                CCBs using the same CCB version in the near future.
+                                      3         Processing is unavailable for all CCBs on the submitting vcpu,
+                                                and it is recommended the guest emulate the operation or resubmit
+                                                the CCB on a different vcpu. The guest should continue to submit
+                                                CCBs on all other vcpus but can expect continued rejections of all
+                                                CCBs on this vcpu in the near future.
+                                      4         Processing is unavailable for all CCBs, and it is recommended
+                                                the guest emulate the operation. The guest should expect all CCB
+                                                submissions to be similarly rejected in the near future.
+
+
+36.3.2. ccb_info
+
+        trap#               FAST_TRAP
+        function#           CCB_INFO
+        arg0                address
+        ret0                status
+        ret1                CCB state
+        ret2                position
+        ret3                dax
+        ret4                queue
+
+       Requests status information on a previously submitted CCB. The previously submitted CCB is identified
+       by the 64-byte aligned real address of the CCBs completion area.
+
+       A CCB can be in one of 4 states:
+
+
+        State                     Value       Description
+        COMPLETED                 0           The CCB has been fetched and executed, and is no longer active in
+                                              the virtual machine.
+        ENQUEUED                  1           The requested CCB is current in a queue awaiting execution.
+        INPROGRESS                2           The CCB has been fetched and is currently being executed. It may still
+                                              be possible to stop the execution using the ccb_kill hypercall.
+        NOTFOUND                  3           The CCB could not be located in the virtual machine, and does not
+                                              appear to have been executed. This may occur if the CCB was lost
+                                              due to a hardware error, or the CCB may not have been successfully
+                                              submitted to the virtual machine in the first place.
+
+               Implementation note
+               Some platforms may not be able to report CCBs that are currently being processed, and therefore
+               guest software should invoke the ccb_kill hypercall prior to assuming the request CCB will never
+               be executed because it was in the NOTFOUND state.
+
+
+                                                       532
+\f                                             Coprocessor services
+
+
+         The position return value is only valid when the state is ENQUEUED. The value returned is the number
+         of other CCBs ahead of the requested CCB, to provide a relative estimate of when the CCB may execute.
+
+         The dax return value is only valid when the state is ENQUEUED. The value returned is the DAX unit
+         instance identifier for the DAX unit processing the queue where the requested CCB is located. The value
+         matches the value that would have been, or was, returned by ccb_submit using the queue info flag.
+
+         The queue return value is only valid when the state is ENQUEUED. The value returned is the DAX
+         queue instance identifier for the DAX unit processing the queue where the requested CCB is located. The
+         value matches the value that would have been, or was, returned by ccb_submit using the queue info flag.
+
+36.3.2.1. Errors
+
+          EOK                       The request was processed and the CCB state is valid.
+          EBADALIGN                 address is not on a 64-byte aligned.
+          ENORADDR                  The real address provided for address is not valid.
+          EINVAL                    The CCB completion area contents are not valid.
+          EWOULDBLOCK               Internal resource constraints prevented the CCB state from being queried at this
+                                    time. The guest should retry the request.
+          ENOACCESS                 The guest does not have permission to access the coprocessor virtual device
+                                    functionality.
+
+36.3.3. ccb_kill
+
+          trap#           FAST_TRAP
+          function#       CCB_KILL
+          arg0            address
+          ret0            status
+          ret1            result
+
+         Request to stop execution of a previously submitted CCB. The previously submitted CCB is identified by
+         the 64-byte aligned real address of the CCBs completion area.
+
+         The kill attempt can produce one of several values in the result return value, reflecting the CCB state
+         and actions taken by the Hypervisor:
+
+          Result                Value       Description
+          COMPLETED             0           The CCB has been fetched and executed, and is no longer active in
+                                            the virtual machine. It could not be killed and no action was taken.
+          DEQUEUED              1           The requested CCB was still enqueued when the kill request was
+                                            submitted, and has been removed from the queue. Since the CCB
+                                            never began execution, no memory modifications were produced by
+                                            it, and the completion area will never be updated. The same CCB may
+                                            be submitted again, if desired, with no modifications required.
+          KILLED                2           The CCB had been fetched and was being executed when the kill
+                                            request was submitted. The CCB execution was stopped, and the CCB
+                                            is no longer active in the virtual machine. The CCB completion area
+                                            will reflect the killed status, with the subsequent implications that
+                                            partial results may have been produced. Partial results may include full
+
+
+                                                      533
+\f                                              Coprocessor services
+
+
+          Result                 Value       Description
+                                             command execution if the command was stopped just prior to writing
+                                             to the completion area.
+          NOTFOUND               3           The CCB could not be located in the virtual machine, and does not
+                                             appear to have been executed. This may occur if the CCB was lost
+                                             due to a hardware error, or the CCB may not have been successfully
+                                             submitted to the virtual machine in the first place. CCBs in the state
+                                             are guaranteed to never execute in the future unless resubmitted.
+
+36.3.3.1. Interactions with Pipelined CCBs
+
+         If the pipeline target CCB is killed but the pipeline source CCB was skipped, the completion area of the
+         target CCB may contain status (4,0) "Command was skipped" instead of (3,7) "Command was killed".
+
+         If the pipeline source CCB is killed, the pipeline target CCB's completion status may read (1,0) "Success".
+         This does not mean the target CCB was processed; since the source CCB was killed, there was no
+         meaningful output on which the target CCB could operate.
+
+36.3.3.2. Errors
+
+          EOK                        The request was processed and the result is valid.
+          EBADALIGN                  address is not on a 64-byte aligned.
+          ENORADDR                   The real address provided for address is not valid.
+          EINVAL                     The CCB completion area contents are not valid.
+          EWOULDBLOCK                Internal resource constraints prevented the CCB from being killed at this time.
+                                     The guest should retry the request.
+          ENOACCESS                  The guest does not have permission to access the coprocessor virtual device
+                                     functionality.
+
+36.3.4. dax_info
+          trap#            FAST_TRAP
+          function#        DAX_INFO
+          ret0             status
+          ret1             Number of enabled DAX units
+          ret2             Number of disabled DAX units
+
+         Returns the number of DAX units that are enabled for the calling guest to submit CCBs. The number of
+         DAX units that are disabled for the calling guest are also returned. A disabled DAX unit would have been
+         available for CCB submission to the calling guest had it not been offlined.
+
+36.3.4.1. Errors
+
+          EOK                        The request was processed and the number of enabled/disabled DAX units
+                                     are valid.
+
+
+
+
+                                                       534
+\f
diff --git a/Documentation/arch/sparc/oradax/oracle-dax.rst b/Documentation/arch/sparc/oradax/oracle-dax.rst
new file mode 100644 (file)
index 0000000..d1e14d5
--- /dev/null
@@ -0,0 +1,445 @@
+=======================================
+Oracle Data Analytics Accelerator (DAX)
+=======================================
+
+DAX is a coprocessor which resides on the SPARC M7 (DAX1) and M8
+(DAX2) processor chips, and has direct access to the CPU's L3 caches
+as well as physical memory. It can perform several operations on data
+streams with various input and output formats.  A driver provides a
+transport mechanism and has limited knowledge of the various opcodes
+and data formats. A user space library provides high level services
+and translates these into low level commands which are then passed
+into the driver and subsequently the Hypervisor and the coprocessor.
+The library is the recommended way for applications to use the
+coprocessor, and the driver interface is not intended for general use.
+This document describes the general flow of the driver, its
+structures, and its programmatic interface. It also provides example
+code sufficient to write user or kernel applications that use DAX
+functionality.
+
+The user library is open source and available at:
+
+    https://oss.oracle.com/git/gitweb.cgi?p=libdax.git
+
+The Hypervisor interface to the coprocessor is described in detail in
+the accompanying document, dax-hv-api.txt, which is a plain text
+excerpt of the (Oracle internal) "UltraSPARC Virtual Machine
+Specification" version 3.0.20+15, dated 2017-09-25.
+
+
+High Level Overview
+===================
+
+A coprocessor request is described by a Command Control Block
+(CCB). The CCB contains an opcode and various parameters. The opcode
+specifies what operation is to be done, and the parameters specify
+options, flags, sizes, and addresses.  The CCB (or an array of CCBs)
+is passed to the Hypervisor, which handles queueing and scheduling of
+requests to the available coprocessor execution units. A status code
+returned indicates if the request was submitted successfully or if
+there was an error.  One of the addresses given in each CCB is a
+pointer to a "completion area", which is a 128 byte memory block that
+is written by the coprocessor to provide execution status. No
+interrupt is generated upon completion; the completion area must be
+polled by software to find out when a transaction has finished, but
+the M7 and later processors provide a mechanism to pause the virtual
+processor until the completion status has been updated by the
+coprocessor. This is done using the monitored load and mwait
+instructions, which are described in more detail later.  The DAX
+coprocessor was designed so that after a request is submitted, the
+kernel is no longer involved in the processing of it.  The polling is
+done at the user level, which results in almost zero latency between
+completion of a request and resumption of execution of the requesting
+thread.
+
+
+Addressing Memory
+=================
+
+The kernel does not have access to physical memory in the Sun4v
+architecture, as there is an additional level of memory virtualization
+present. This intermediate level is called "real" memory, and the
+kernel treats this as if it were physical.  The Hypervisor handles the
+translations between real memory and physical so that each logical
+domain (LDOM) can have a partition of physical memory that is isolated
+from that of other LDOMs.  When the kernel sets up a virtual mapping,
+it specifies a virtual address and the real address to which it should
+be mapped.
+
+The DAX coprocessor can only operate on physical memory, so before a
+request can be fed to the coprocessor, all the addresses in a CCB must
+be converted into physical addresses. The kernel cannot do this since
+it has no visibility into physical addresses. So a CCB may contain
+either the virtual or real addresses of the buffers or a combination
+of them. An "address type" field is available for each address that
+may be given in the CCB. In all cases, the Hypervisor will translate
+all the addresses to physical before dispatching to hardware. Address
+translations are performed using the context of the process initiating
+the request.
+
+
+The Driver API
+==============
+
+An application makes requests to the driver via the write() system
+call, and gets results (if any) via read(). The completion areas are
+made accessible via mmap(), and are read-only for the application.
+
+The request may either be an immediate command or an array of CCBs to
+be submitted to the hardware.
+
+Each open instance of the device is exclusive to the thread that
+opened it, and must be used by that thread for all subsequent
+operations. The driver open function creates a new context for the
+thread and initializes it for use.  This context contains pointers and
+values used internally by the driver to keep track of submitted
+requests. The completion area buffer is also allocated, and this is
+large enough to contain the completion areas for many concurrent
+requests.  When the device is closed, any outstanding transactions are
+flushed and the context is cleaned up.
+
+On a DAX1 system (M7), the device will be called "oradax1", while on a
+DAX2 system (M8) it will be "oradax2". If an application requires one
+or the other, it should simply attempt to open the appropriate
+device. Only one of the devices will exist on any given system, so the
+name can be used to determine what the platform supports.
+
+The immediate commands are CCB_DEQUEUE, CCB_KILL, and CCB_INFO. For
+all of these, success is indicated by a return value from write()
+equal to the number of bytes given in the call. Otherwise -1 is
+returned and errno is set.
+
+CCB_DEQUEUE
+-----------
+
+Tells the driver to clean up resources associated with past
+requests. Since no interrupt is generated upon the completion of a
+request, the driver must be told when it may reclaim resources.  No
+further status information is returned, so the user should not
+subsequently call read().
+
+CCB_KILL
+--------
+
+Kills a CCB during execution. The CCB is guaranteed to not continue
+executing once this call returns successfully. On success, read() must
+be called to retrieve the result of the action.
+
+CCB_INFO
+--------
+
+Retrieves information about a currently executing CCB. Note that some
+Hypervisors might return 'notfound' when the CCB is in 'inprogress'
+state. To ensure a CCB in the 'notfound' state will never be executed,
+CCB_KILL must be invoked on that CCB. Upon success, read() must be
+called to retrieve the details of the action.
+
+Submission of an array of CCBs for execution
+---------------------------------------------
+
+A write() whose length is a multiple of the CCB size is treated as a
+submit operation. The file offset is treated as the index of the
+completion area to use, and may be set via lseek() or using the
+pwrite() system call. If -1 is returned then errno is set to indicate
+the error. Otherwise, the return value is the length of the array that
+was actually accepted by the coprocessor. If the accepted length is
+equal to the requested length, then the submission was completely
+successful and there is no further status needed; hence, the user
+should not subsequently call read(). Partial acceptance of the CCB
+array is indicated by a return value less than the requested length,
+and read() must be called to retrieve further status information.  The
+status will reflect the error caused by the first CCB that was not
+accepted, and status_data will provide additional data in some cases.
+
+MMAP
+----
+
+The mmap() function provides access to the completion area allocated
+in the driver.  Note that the completion area is not writeable by the
+user process, and the mmap call must not specify PROT_WRITE.
+
+
+Completion of a Request
+=======================
+
+The first byte in each completion area is the command status which is
+updated by the coprocessor hardware. Software may take advantage of
+new M7/M8 processor capabilities to efficiently poll this status byte.
+First, a "monitored load" is achieved via a Load from Alternate Space
+(ldxa, lduba, etc.) with ASI 0x84 (ASI_MONITOR_PRIMARY).  Second, a
+"monitored wait" is achieved via the mwait instruction (a write to
+%asr28). This instruction is like pause in that it suspends execution
+of the virtual processor for the given number of nanoseconds, but in
+addition will terminate early when one of several events occur. If the
+block of data containing the monitored location is modified, then the
+mwait terminates. This causes software to resume execution immediately
+(without a context switch or kernel to user transition) after a
+transaction completes. Thus the latency between transaction completion
+and resumption of execution may be just a few nanoseconds.
+
+
+Application Life Cycle of a DAX Submission
+==========================================
+
+ - open dax device
+ - call mmap() to get the completion area address
+ - allocate a CCB and fill in the opcode, flags, parameters, addresses, etc.
+ - submit CCB via write() or pwrite()
+ - go into a loop executing monitored load + monitored wait and
+   terminate when the command status indicates the request is complete
+   (CCB_KILL or CCB_INFO may be used any time as necessary)
+ - perform a CCB_DEQUEUE
+ - call munmap() for completion area
+ - close the dax device
+
+
+Memory Constraints
+==================
+
+The DAX hardware operates only on physical addresses. Therefore, it is
+not aware of virtual memory mappings and the discontiguities that may
+exist in the physical memory that a virtual buffer maps to. There is
+no I/O TLB or any scatter/gather mechanism. All buffers, whether input
+or output, must reside in a physically contiguous region of memory.
+
+The Hypervisor translates all addresses within a CCB to physical
+before handing off the CCB to DAX. The Hypervisor determines the
+virtual page size for each virtual address given, and uses this to
+program a size limit for each address. This prevents the coprocessor
+from reading or writing beyond the bound of the virtual page, even
+though it is accessing physical memory directly. A simpler way of
+saying this is that a DAX operation will never "cross" a virtual page
+boundary. If an 8k virtual page is used, then the data is strictly
+limited to 8k. If a user's buffer is larger than 8k, then a larger
+page size must be used, or the transaction size will be truncated to
+8k.
+
+Huge pages. A user may allocate huge pages using standard interfaces.
+Memory buffers residing on huge pages may be used to achieve much
+larger DAX transaction sizes, but the rules must still be followed,
+and no transaction will cross a page boundary, even a huge page.  A
+major caveat is that Linux on Sparc presents 8Mb as one of the huge
+page sizes. Sparc does not actually provide a 8Mb hardware page size,
+and this size is synthesized by pasting together two 4Mb pages. The
+reasons for this are historical, and it creates an issue because only
+half of this 8Mb page can actually be used for any given buffer in a
+DAX request, and it must be either the first half or the second half;
+it cannot be a 4Mb chunk in the middle, since that crosses a
+(hardware) page boundary. Note that this entire issue may be hidden by
+higher level libraries.
+
+
+CCB Structure
+-------------
+A CCB is an array of 8 64-bit words. Several of these words provide
+command opcodes, parameters, flags, etc., and the rest are addresses
+for the completion area, output buffer, and various inputs::
+
+   struct ccb {
+       u64   control;
+       u64   completion;
+       u64   input0;
+       u64   access;
+       u64   input1;
+       u64   op_data;
+       u64   output;
+       u64   table;
+   };
+
+See libdax/common/sys/dax1/dax1_ccb.h for a detailed description of
+each of these fields, and see dax-hv-api.txt for a complete description
+of the Hypervisor API available to the guest OS (ie, Linux kernel).
+
+The first word (control) is examined by the driver for the following:
+ - CCB version, which must be consistent with hardware version
+ - Opcode, which must be one of the documented allowable commands
+ - Address types, which must be set to "virtual" for all the addresses
+   given by the user, thereby ensuring that the application can
+   only access memory that it owns
+
+
+Example Code
+============
+
+The DAX is accessible to both user and kernel code.  The kernel code
+can make hypercalls directly while the user code must use wrappers
+provided by the driver. The setup of the CCB is nearly identical for
+both; the only difference is in preparation of the completion area. An
+example of user code is given now, with kernel code afterwards.
+
+In order to program using the driver API, the file
+arch/sparc/include/uapi/asm/oradax.h must be included.
+
+First, the proper device must be opened. For M7 it will be
+/dev/oradax1 and for M8 it will be /dev/oradax2. The simplest
+procedure is to attempt to open both, as only one will succeed::
+
+       fd = open("/dev/oradax1", O_RDWR);
+       if (fd < 0)
+               fd = open("/dev/oradax2", O_RDWR);
+       if (fd < 0)
+              /* No DAX found */
+
+Next, the completion area must be mapped::
+
+      completion_area = mmap(NULL, DAX_MMAP_LEN, PROT_READ, MAP_SHARED, fd, 0);
+
+All input and output buffers must be fully contained in one hardware
+page, since as explained above, the DAX is strictly constrained by
+virtual page boundaries.  In addition, the output buffer must be
+64-byte aligned and its size must be a multiple of 64 bytes because
+the coprocessor writes in units of cache lines.
+
+This example demonstrates the DAX Scan command, which takes as input a
+vector and a match value, and produces a bitmap as the output. For
+each input element that matches the value, the corresponding bit is
+set in the output.
+
+In this example, the input vector consists of a series of single bits,
+and the match value is 0. So each 0 bit in the input will produce a 1
+in the output, and vice versa, which produces an output bitmap which
+is the input bitmap inverted.
+
+For details of all the parameters and bits used in this CCB, please
+refer to section 36.2.1.3 of the DAX Hypervisor API document, which
+describes the Scan command in detail::
+
+       ccb->control =       /* Table 36.1, CCB Header Format */
+                 (2L << 48)     /* command = Scan Value */
+               | (3L << 40)     /* output address type = primary virtual */
+               | (3L << 34)     /* primary input address type = primary virtual */
+                            /* Section 36.2.1, Query CCB Command Formats */
+               | (1 << 28)     /* 36.2.1.1.1 primary input format = fixed width bit packed */
+               | (0 << 23)     /* 36.2.1.1.2 primary input element size = 0 (1 bit) */
+               | (8 << 10)     /* 36.2.1.1.6 output format = bit vector */
+               | (0 <<  5)     /* 36.2.1.3 First scan criteria size = 0 (1 byte) */
+               | (31 << 0);    /* 36.2.1.3 Disable second scan criteria */
+
+       ccb->completion = 0;    /* Completion area address, to be filled in by driver */
+
+       ccb->input0 = (unsigned long) input; /* primary input address */
+
+       ccb->access =       /* Section 36.2.1.2, Data Access Control */
+                 (2 << 24)    /* Primary input length format = bits */
+               | (nbits - 1); /* number of bits in primary input stream, minus 1 */
+
+       ccb->input1 = 0;       /* secondary input address, unused */
+
+       ccb->op_data = 0;      /* scan criteria (value to be matched) */
+
+       ccb->output = (unsigned long) output;   /* output address */
+
+       ccb->table = 0;        /* table address, unused */
+
+The CCB submission is a write() or pwrite() system call to the
+driver. If the call fails, then a read() must be used to retrieve the
+status::
+
+       if (pwrite(fd, ccb, 64, 0) != 64) {
+               struct ccb_exec_result status;
+               read(fd, &status, sizeof(status));
+               /* bail out */
+       }
+
+After a successful submission of the CCB, the completion area may be
+polled to determine when the DAX is finished. Detailed information on
+the contents of the completion area can be found in section 36.2.2 of
+the DAX HV API document::
+
+       while (1) {
+               /* Monitored Load */
+               __asm__ __volatile__("lduba [%1] 0x84, %0\n"
+                                    : "=r" (status)
+                                    : "r"  (completion_area));
+
+               if (status)          /* 0 indicates command in progress */
+                       break;
+
+               /* MWAIT */
+               __asm__ __volatile__("wr %%g0, 1000, %%asr28\n" ::);    /* 1000 ns */
+       }
+
+A completion area status of 1 indicates successful completion of the
+CCB and validity of the output bitmap, which may be used immediately.
+All other non-zero values indicate error conditions which are
+described in section 36.2.2::
+
+       if (completion_area[0] != 1) {  /* section 36.2.2, 1 = command ran and succeeded */
+               /* completion_area[0] contains the completion status */
+               /* completion_area[1] contains an error code, see 36.2.2 */
+       }
+
+After the completion area has been processed, the driver must be
+notified that it can release any resources associated with the
+request. This is done via the dequeue operation::
+
+       struct dax_command cmd;
+       cmd.command = CCB_DEQUEUE;
+       if (write(fd, &cmd, sizeof(cmd)) != sizeof(cmd)) {
+               /* bail out */
+       }
+
+Finally, normal program cleanup should be done, i.e., unmapping
+completion area, closing the dax device, freeing memory etc.
+
+Kernel example
+--------------
+
+The only difference in using the DAX in kernel code is the treatment
+of the completion area. Unlike user applications which mmap the
+completion area allocated by the driver, kernel code must allocate its
+own memory to use for the completion area, and this address and its
+type must be given in the CCB::
+
+       ccb->control |=      /* Table 36.1, CCB Header Format */
+               (3L << 32);     /* completion area address type = primary virtual */
+
+       ccb->completion = (unsigned long) completion_area;   /* Completion area address */
+
+The dax submit hypercall is made directly. The flags used in the
+ccb_submit call are documented in the DAX HV API in section 36.3.1/
+
+::
+
+  #include <asm/hypervisor.h>
+
+       hv_rv = sun4v_ccb_submit((unsigned long)ccb, 64,
+                                HV_CCB_QUERY_CMD |
+                                HV_CCB_ARG0_PRIVILEGED | HV_CCB_ARG0_TYPE_PRIMARY |
+                                HV_CCB_VA_PRIVILEGED,
+                                0, &bytes_accepted, &status_data);
+
+       if (hv_rv != HV_EOK) {
+               /* hv_rv is an error code, status_data contains */
+               /* potential additional status, see 36.3.1.1 */
+       }
+
+After the submission, the completion area polling code is identical to
+that in user land::
+
+       while (1) {
+               /* Monitored Load */
+               __asm__ __volatile__("lduba [%1] 0x84, %0\n"
+                                    : "=r" (status)
+                                    : "r"  (completion_area));
+
+               if (status)          /* 0 indicates command in progress */
+                       break;
+
+               /* MWAIT */
+               __asm__ __volatile__("wr %%g0, 1000, %%asr28\n" ::);    /* 1000 ns */
+       }
+
+       if (completion_area[0] != 1) {  /* section 36.2.2, 1 = command ran and succeeded */
+               /* completion_area[0] contains the completion status */
+               /* completion_area[1] contains an error code, see 36.2.2 */
+       }
+
+The output bitmap is ready for consumption immediately after the
+completion status indicates success.
+
+Excer[t from UltraSPARC Virtual Machine Specification
+=====================================================
+
+ .. include:: dax-hv-api.txt
+    :literal:
diff --git a/Documentation/arch/x86/amd-memory-encryption.rst b/Documentation/arch/x86/amd-memory-encryption.rst
new file mode 100644 (file)
index 0000000..934310c
--- /dev/null
@@ -0,0 +1,133 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=====================
+AMD Memory Encryption
+=====================
+
+Secure Memory Encryption (SME) and Secure Encrypted Virtualization (SEV) are
+features found on AMD processors.
+
+SME provides the ability to mark individual pages of memory as encrypted using
+the standard x86 page tables.  A page that is marked encrypted will be
+automatically decrypted when read from DRAM and encrypted when written to
+DRAM.  SME can therefore be used to protect the contents of DRAM from physical
+attacks on the system.
+
+SEV enables running encrypted virtual machines (VMs) in which the code and data
+of the guest VM are secured so that a decrypted version is available only
+within the VM itself. SEV guest VMs have the concept of private and shared
+memory. Private memory is encrypted with the guest-specific key, while shared
+memory may be encrypted with hypervisor key. When SME is enabled, the hypervisor
+key is the same key which is used in SME.
+
+A page is encrypted when a page table entry has the encryption bit set (see
+below on how to determine its position).  The encryption bit can also be
+specified in the cr3 register, allowing the PGD table to be encrypted. Each
+successive level of page tables can also be encrypted by setting the encryption
+bit in the page table entry that points to the next table. This allows the full
+page table hierarchy to be encrypted. Note, this means that just because the
+encryption bit is set in cr3, doesn't imply the full hierarchy is encrypted.
+Each page table entry in the hierarchy needs to have the encryption bit set to
+achieve that. So, theoretically, you could have the encryption bit set in cr3
+so that the PGD is encrypted, but not set the encryption bit in the PGD entry
+for a PUD which results in the PUD pointed to by that entry to not be
+encrypted.
+
+When SEV is enabled, instruction pages and guest page tables are always treated
+as private. All the DMA operations inside the guest must be performed on shared
+memory. Since the memory encryption bit is controlled by the guest OS when it
+is operating in 64-bit or 32-bit PAE mode, in all other modes the SEV hardware
+forces the memory encryption bit to 1.
+
+Support for SME and SEV can be determined through the CPUID instruction. The
+CPUID function 0x8000001f reports information related to SME::
+
+       0x8000001f[eax]:
+               Bit[0] indicates support for SME
+               Bit[1] indicates support for SEV
+       0x8000001f[ebx]:
+               Bits[5:0]  pagetable bit number used to activate memory
+                          encryption
+               Bits[11:6] reduction in physical address space, in bits, when
+                          memory encryption is enabled (this only affects
+                          system physical addresses, not guest physical
+                          addresses)
+
+If support for SME is present, MSR 0xc00100010 (MSR_AMD64_SYSCFG) can be used to
+determine if SME is enabled and/or to enable memory encryption::
+
+       0xc0010010:
+               Bit[23]   0 = memory encryption features are disabled
+                         1 = memory encryption features are enabled
+
+If SEV is supported, MSR 0xc0010131 (MSR_AMD64_SEV) can be used to determine if
+SEV is active::
+
+       0xc0010131:
+               Bit[0]    0 = memory encryption is not active
+                         1 = memory encryption is active
+
+Linux relies on BIOS to set this bit if BIOS has determined that the reduction
+in the physical address space as a result of enabling memory encryption (see
+CPUID information above) will not conflict with the address space resource
+requirements for the system.  If this bit is not set upon Linux startup then
+Linux itself will not set it and memory encryption will not be possible.
+
+The state of SME in the Linux kernel can be documented as follows:
+
+       - Supported:
+         The CPU supports SME (determined through CPUID instruction).
+
+       - Enabled:
+         Supported and bit 23 of MSR_AMD64_SYSCFG is set.
+
+       - Active:
+         Supported, Enabled and the Linux kernel is actively applying
+         the encryption bit to page table entries (the SME mask in the
+         kernel is non-zero).
+
+SME can also be enabled and activated in the BIOS. If SME is enabled and
+activated in the BIOS, then all memory accesses will be encrypted and it will
+not be necessary to activate the Linux memory encryption support.  If the BIOS
+merely enables SME (sets bit 23 of the MSR_AMD64_SYSCFG), then Linux can activate
+memory encryption by default (CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT=y) or
+by supplying mem_encrypt=on on the kernel command line.  However, if BIOS does
+not enable SME, then Linux will not be able to activate memory encryption, even
+if configured to do so by default or the mem_encrypt=on command line parameter
+is specified.
+
+Secure Nested Paging (SNP)
+==========================
+
+SEV-SNP introduces new features (SEV_FEATURES[1:63]) which can be enabled
+by the hypervisor for security enhancements. Some of these features need
+guest side implementation to function correctly. The below table lists the
+expected guest behavior with various possible scenarios of guest/hypervisor
+SNP feature support.
+
++-----------------+---------------+---------------+------------------+
+| Feature Enabled | Guest needs   | Guest has     | Guest boot       |
+| by the HV       | implementation| implementation| behaviour        |
++=================+===============+===============+==================+
+|      No         |      No       |      No       |     Boot         |
+|                 |               |               |                  |
++-----------------+---------------+---------------+------------------+
+|      No         |      Yes      |      No       |     Boot         |
+|                 |               |               |                  |
++-----------------+---------------+---------------+------------------+
+|      No         |      Yes      |      Yes      |     Boot         |
+|                 |               |               |                  |
++-----------------+---------------+---------------+------------------+
+|      Yes        |      No       |      No       | Boot with        |
+|                 |               |               | feature enabled  |
++-----------------+---------------+---------------+------------------+
+|      Yes        |      Yes      |      No       | Graceful boot    |
+|                 |               |               | failure          |
++-----------------+---------------+---------------+------------------+
+|      Yes        |      Yes      |      Yes      | Boot with        |
+|                 |               |               | feature enabled  |
++-----------------+---------------+---------------+------------------+
+
+More details in AMD64 APM[1] Vol 2: 15.34.10 SEV_STATUS MSR
+
+[1] https://www.amd.com/system/files/TechDocs/40332.pdf
diff --git a/Documentation/arch/x86/amd_hsmp.rst b/Documentation/arch/x86/amd_hsmp.rst
new file mode 100644 (file)
index 0000000..440e4b6
--- /dev/null
@@ -0,0 +1,86 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============================================
+AMD HSMP interface
+============================================
+
+Newer Fam19h EPYC server line of processors from AMD support system
+management functionality via HSMP (Host System Management Port).
+
+The Host System Management Port (HSMP) is an interface to provide
+OS-level software with access to system management functions via a
+set of mailbox registers.
+
+More details on the interface can be found in chapter
+"7 Host System Management Port (HSMP)" of the family/model PPR
+Eg: https://www.amd.com/system/files/TechDocs/55898_B1_pub_0.50.zip
+
+HSMP interface is supported on EPYC server CPU models only.
+
+
+HSMP device
+============================================
+
+amd_hsmp driver under the drivers/platforms/x86/ creates miscdevice
+/dev/hsmp to let user space programs run hsmp mailbox commands.
+
+$ ls -al /dev/hsmp
+crw-r--r-- 1 root root 10, 123 Jan 21 21:41 /dev/hsmp
+
+Characteristics of the dev node:
+ * Write mode is used for running set/configure commands
+ * Read mode is used for running get/status monitor commands
+
+Access restrictions:
+ * Only root user is allowed to open the file in write mode.
+ * The file can be opened in read mode by all the users.
+
+In-kernel integration:
+ * Other subsystems in the kernel can use the exported transport
+   function hsmp_send_message().
+ * Locking across callers is taken care by the driver.
+
+
+An example
+==========
+
+To access hsmp device from a C program.
+First, you need to include the headers::
+
+  #include <linux/amd_hsmp.h>
+
+Which defines the supported messages/message IDs.
+
+Next thing, open the device file, as follows::
+
+  int file;
+
+  file = open("/dev/hsmp", O_RDWR);
+  if (file < 0) {
+    /* ERROR HANDLING; you can check errno to see what went wrong */
+    exit(1);
+  }
+
+The following IOCTL is defined:
+
+``ioctl(file, HSMP_IOCTL_CMD, struct hsmp_message *msg)``
+  The argument is a pointer to a::
+
+    struct hsmp_message {
+       __u32   msg_id;                         /* Message ID */
+       __u16   num_args;                       /* Number of input argument words in message */
+       __u16   response_sz;                    /* Number of expected output/response words */
+       __u32   args[HSMP_MAX_MSG_LEN];         /* argument/response buffer */
+       __u16   sock_ind;                       /* socket number */
+    };
+
+The ioctl would return a non-zero on failure; you can read errno to see
+what happened. The transaction returns 0 on success.
+
+More details on the interface and message definitions can be found in chapter
+"7 Host System Management Port (HSMP)" of the respective family/model PPR
+eg: https://www.amd.com/system/files/TechDocs/55898_B1_pub_0.50.zip
+
+User space C-APIs are made available by linking against the esmi library,
+which is provided by the E-SMS project https://developer.amd.com/e-sms/.
+See: https://github.com/amd/esmi_ib_library
diff --git a/Documentation/arch/x86/boot.rst b/Documentation/arch/x86/boot.rst
new file mode 100644 (file)
index 0000000..33520ec
--- /dev/null
@@ -0,0 +1,1443 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===========================
+The Linux/x86 Boot Protocol
+===========================
+
+On the x86 platform, the Linux kernel uses a rather complicated boot
+convention.  This has evolved partially due to historical aspects, as
+well as the desire in the early days to have the kernel itself be a
+bootable image, the complicated PC memory model and due to changed
+expectations in the PC industry caused by the effective demise of
+real-mode DOS as a mainstream operating system.
+
+Currently, the following versions of the Linux/x86 boot protocol exist.
+
+=============  ============================================================
+Old kernels    zImage/Image support only.  Some very early kernels
+               may not even support a command line.
+
+Protocol 2.00  (Kernel 1.3.73) Added bzImage and initrd support, as
+               well as a formalized way to communicate between the
+               boot loader and the kernel.  setup.S made relocatable,
+               although the traditional setup area still assumed
+               writable.
+
+Protocol 2.01  (Kernel 1.3.76) Added a heap overrun warning.
+
+Protocol 2.02  (Kernel 2.4.0-test3-pre3) New command line protocol.
+               Lower the conventional memory ceiling.  No overwrite
+               of the traditional setup area, thus making booting
+               safe for systems which use the EBDA from SMM or 32-bit
+               BIOS entry points.  zImage deprecated but still
+               supported.
+
+Protocol 2.03  (Kernel 2.4.18-pre1) Explicitly makes the highest possible
+               initrd address available to the bootloader.
+
+Protocol 2.04  (Kernel 2.6.14) Extend the syssize field to four bytes.
+
+Protocol 2.05  (Kernel 2.6.20) Make protected mode kernel relocatable.
+               Introduce relocatable_kernel and kernel_alignment fields.
+
+Protocol 2.06  (Kernel 2.6.22) Added a field that contains the size of
+               the boot command line.
+
+Protocol 2.07  (Kernel 2.6.24) Added paravirtualised boot protocol.
+               Introduced hardware_subarch and hardware_subarch_data
+               and KEEP_SEGMENTS flag in load_flags.
+
+Protocol 2.08  (Kernel 2.6.26) Added crc32 checksum and ELF format
+               payload. Introduced payload_offset and payload_length
+               fields to aid in locating the payload.
+
+Protocol 2.09  (Kernel 2.6.26) Added a field of 64-bit physical
+               pointer to single linked list of struct setup_data.
+
+Protocol 2.10  (Kernel 2.6.31) Added a protocol for relaxed alignment
+               beyond the kernel_alignment added, new init_size and
+               pref_address fields.  Added extended boot loader IDs.
+
+Protocol 2.11  (Kernel 3.6) Added a field for offset of EFI handover
+               protocol entry point.
+
+Protocol 2.12  (Kernel 3.8) Added the xloadflags field and extension fields
+               to struct boot_params for loading bzImage and ramdisk
+               above 4G in 64bit.
+
+Protocol 2.13  (Kernel 3.14) Support 32- and 64-bit flags being set in
+               xloadflags to support booting a 64-bit kernel from 32-bit
+               EFI
+
+Protocol 2.14  BURNT BY INCORRECT COMMIT
+                ae7e1238e68f2a472a125673ab506d49158c1889
+               (x86/boot: Add ACPI RSDP address to setup_header)
+               DO NOT USE!!! ASSUME SAME AS 2.13.
+
+Protocol 2.15  (Kernel 5.5) Added the kernel_info and kernel_info.setup_type_max.
+=============  ============================================================
+
+.. note::
+     The protocol version number should be changed only if the setup header
+     is changed. There is no need to update the version number if boot_params
+     or kernel_info are changed. Additionally, it is recommended to use
+     xloadflags (in this case the protocol version number should not be
+     updated either) or kernel_info to communicate supported Linux kernel
+     features to the boot loader. Due to very limited space available in
+     the original setup header every update to it should be considered
+     with great care. Starting from the protocol 2.15 the primary way to
+     communicate things to the boot loader is the kernel_info.
+
+
+Memory Layout
+=============
+
+The traditional memory map for the kernel loader, used for Image or
+zImage kernels, typically looks like::
+
+               |                        |
+       0A0000  +------------------------+
+               |  Reserved for BIOS     |      Do not use.  Reserved for BIOS EBDA.
+       09A000  +------------------------+
+               |  Command line          |
+               |  Stack/heap            |      For use by the kernel real-mode code.
+       098000  +------------------------+
+               |  Kernel setup          |      The kernel real-mode code.
+       090200  +------------------------+
+               |  Kernel boot sector    |      The kernel legacy boot sector.
+       090000  +------------------------+
+               |  Protected-mode kernel |      The bulk of the kernel image.
+       010000  +------------------------+
+               |  Boot loader           |      <- Boot sector entry point 0000:7C00
+       001000  +------------------------+
+               |  Reserved for MBR/BIOS |
+       000800  +------------------------+
+               |  Typically used by MBR |
+       000600  +------------------------+
+               |  BIOS use only         |
+       000000  +------------------------+
+
+When using bzImage, the protected-mode kernel was relocated to
+0x100000 ("high memory"), and the kernel real-mode block (boot sector,
+setup, and stack/heap) was made relocatable to any address between
+0x10000 and end of low memory. Unfortunately, in protocols 2.00 and
+2.01 the 0x90000+ memory range is still used internally by the kernel;
+the 2.02 protocol resolves that problem.
+
+It is desirable to keep the "memory ceiling" -- the highest point in
+low memory touched by the boot loader -- as low as possible, since
+some newer BIOSes have begun to allocate some rather large amounts of
+memory, called the Extended BIOS Data Area, near the top of low
+memory.         The boot loader should use the "INT 12h" BIOS call to verify
+how much low memory is available.
+
+Unfortunately, if INT 12h reports that the amount of memory is too
+low, there is usually nothing the boot loader can do but to report an
+error to the user.  The boot loader should therefore be designed to
+take up as little space in low memory as it reasonably can.  For
+zImage or old bzImage kernels, which need data written into the
+0x90000 segment, the boot loader should make sure not to use memory
+above the 0x9A000 point; too many BIOSes will break above that point.
+
+For a modern bzImage kernel with boot protocol version >= 2.02, a
+memory layout like the following is suggested::
+
+               ~                        ~
+               |  Protected-mode kernel |
+       100000  +------------------------+
+               |  I/O memory hole       |
+       0A0000  +------------------------+
+               |  Reserved for BIOS     |      Leave as much as possible unused
+               ~                        ~
+               |  Command line          |      (Can also be below the X+10000 mark)
+       X+10000 +------------------------+
+               |  Stack/heap            |      For use by the kernel real-mode code.
+       X+08000 +------------------------+
+               |  Kernel setup          |      The kernel real-mode code.
+               |  Kernel boot sector    |      The kernel legacy boot sector.
+       X       +------------------------+
+               |  Boot loader           |      <- Boot sector entry point 0000:7C00
+       001000  +------------------------+
+               |  Reserved for MBR/BIOS |
+       000800  +------------------------+
+               |  Typically used by MBR |
+       000600  +------------------------+
+               |  BIOS use only         |
+       000000  +------------------------+
+
+  ... where the address X is as low as the design of the boot loader permits.
+
+
+The Real-Mode Kernel Header
+===========================
+
+In the following text, and anywhere in the kernel boot sequence, "a
+sector" refers to 512 bytes.  It is independent of the actual sector
+size of the underlying medium.
+
+The first step in loading a Linux kernel should be to load the
+real-mode code (boot sector and setup code) and then examine the
+following header at offset 0x01f1.  The real-mode code can total up to
+32K, although the boot loader may choose to load only the first two
+sectors (1K) and then examine the bootup sector size.
+
+The header looks like:
+
+===========    ========        =====================   ============================================
+Offset/Size    Proto           Name                    Meaning
+===========    ========        =====================   ============================================
+01F1/1         ALL(1)          setup_sects             The size of the setup in sectors
+01F2/2         ALL             root_flags              If set, the root is mounted readonly
+01F4/4         2.04+(2)        syssize                 The size of the 32-bit code in 16-byte paras
+01F8/2         ALL             ram_size                DO NOT USE - for bootsect.S use only
+01FA/2         ALL             vid_mode                Video mode control
+01FC/2         ALL             root_dev                Default root device number
+01FE/2         ALL             boot_flag               0xAA55 magic number
+0200/2         2.00+           jump                    Jump instruction
+0202/4         2.00+           header                  Magic signature "HdrS"
+0206/2         2.00+           version                 Boot protocol version supported
+0208/4         2.00+           realmode_swtch          Boot loader hook (see below)
+020C/2         2.00+           start_sys_seg           The load-low segment (0x1000) (obsolete)
+020E/2         2.00+           kernel_version          Pointer to kernel version string
+0210/1         2.00+           type_of_loader          Boot loader identifier
+0211/1         2.00+           loadflags               Boot protocol option flags
+0212/2         2.00+           setup_move_size         Move to high memory size (used with hooks)
+0214/4         2.00+           code32_start            Boot loader hook (see below)
+0218/4         2.00+           ramdisk_image           initrd load address (set by boot loader)
+021C/4         2.00+           ramdisk_size            initrd size (set by boot loader)
+0220/4         2.00+           bootsect_kludge         DO NOT USE - for bootsect.S use only
+0224/2         2.01+           heap_end_ptr            Free memory after setup end
+0226/1         2.02+(3)        ext_loader_ver          Extended boot loader version
+0227/1         2.02+(3)        ext_loader_type         Extended boot loader ID
+0228/4         2.02+           cmd_line_ptr            32-bit pointer to the kernel command line
+022C/4         2.03+           initrd_addr_max         Highest legal initrd address
+0230/4         2.05+           kernel_alignment        Physical addr alignment required for kernel
+0234/1         2.05+           relocatable_kernel      Whether kernel is relocatable or not
+0235/1         2.10+           min_alignment           Minimum alignment, as a power of two
+0236/2         2.12+           xloadflags              Boot protocol option flags
+0238/4         2.06+           cmdline_size            Maximum size of the kernel command line
+023C/4         2.07+           hardware_subarch        Hardware subarchitecture
+0240/8         2.07+           hardware_subarch_data   Subarchitecture-specific data
+0248/4         2.08+           payload_offset          Offset of kernel payload
+024C/4         2.08+           payload_length          Length of kernel payload
+0250/8         2.09+           setup_data              64-bit physical pointer to linked list
+                                                       of struct setup_data
+0258/8         2.10+           pref_address            Preferred loading address
+0260/4         2.10+           init_size               Linear memory required during initialization
+0264/4         2.11+           handover_offset         Offset of handover entry point
+0268/4         2.15+           kernel_info_offset      Offset of the kernel_info
+===========    ========        =====================   ============================================
+
+.. note::
+  (1) For backwards compatibility, if the setup_sects field contains 0, the
+      real value is 4.
+
+  (2) For boot protocol prior to 2.04, the upper two bytes of the syssize
+      field are unusable, which means the size of a bzImage kernel
+      cannot be determined.
+
+  (3) Ignored, but safe to set, for boot protocols 2.02-2.09.
+
+If the "HdrS" (0x53726448) magic number is not found at offset 0x202,
+the boot protocol version is "old".  Loading an old kernel, the
+following parameters should be assumed::
+
+       Image type = zImage
+       initrd not supported
+       Real-mode kernel must be located at 0x90000.
+
+Otherwise, the "version" field contains the protocol version,
+e.g. protocol version 2.01 will contain 0x0201 in this field.  When
+setting fields in the header, you must make sure only to set fields
+supported by the protocol version in use.
+
+
+Details of Header Fields
+========================
+
+For each field, some are information from the kernel to the bootloader
+("read"), some are expected to be filled out by the bootloader
+("write"), and some are expected to be read and modified by the
+bootloader ("modify").
+
+All general purpose boot loaders should write the fields marked
+(obligatory).  Boot loaders who want to load the kernel at a
+nonstandard address should fill in the fields marked (reloc); other
+boot loaders can ignore those fields.
+
+The byte order of all fields is littleendian (this is x86, after all.)
+
+============   ===========
+Field name:    setup_sects
+Type:          read
+Offset/size:   0x1f1/1
+Protocol:      ALL
+============   ===========
+
+  The size of the setup code in 512-byte sectors.  If this field is
+  0, the real value is 4.  The real-mode code consists of the boot
+  sector (always one 512-byte sector) plus the setup code.
+
+============   =================
+Field name:    root_flags
+Type:          modify (optional)
+Offset/size:   0x1f2/2
+Protocol:      ALL
+============   =================
+
+  If this field is nonzero, the root defaults to readonly.  The use of
+  this field is deprecated; use the "ro" or "rw" options on the
+  command line instead.
+
+============   ===============================================
+Field name:    syssize
+Type:          read
+Offset/size:   0x1f4/4 (protocol 2.04+) 0x1f4/2 (protocol ALL)
+Protocol:      2.04+
+============   ===============================================
+
+  The size of the protected-mode code in units of 16-byte paragraphs.
+  For protocol versions older than 2.04 this field is only two bytes
+  wide, and therefore cannot be trusted for the size of a kernel if
+  the LOAD_HIGH flag is set.
+
+============   ===============
+Field name:    ram_size
+Type:          kernel internal
+Offset/size:   0x1f8/2
+Protocol:      ALL
+============   ===============
+
+  This field is obsolete.
+
+============   ===================
+Field name:    vid_mode
+Type:          modify (obligatory)
+Offset/size:   0x1fa/2
+============   ===================
+
+  Please see the section on SPECIAL COMMAND LINE OPTIONS.
+
+============   =================
+Field name:    root_dev
+Type:          modify (optional)
+Offset/size:   0x1fc/2
+Protocol:      ALL
+============   =================
+
+  The default root device device number.  The use of this field is
+  deprecated, use the "root=" option on the command line instead.
+
+============   =========
+Field name:    boot_flag
+Type:          read
+Offset/size:   0x1fe/2
+Protocol:      ALL
+============   =========
+
+  Contains 0xAA55.  This is the closest thing old Linux kernels have
+  to a magic number.
+
+============   =======
+Field name:    jump
+Type:          read
+Offset/size:   0x200/2
+Protocol:      2.00+
+============   =======
+
+  Contains an x86 jump instruction, 0xEB followed by a signed offset
+  relative to byte 0x202.  This can be used to determine the size of
+  the header.
+
+============   =======
+Field name:    header
+Type:          read
+Offset/size:   0x202/4
+Protocol:      2.00+
+============   =======
+
+  Contains the magic number "HdrS" (0x53726448).
+
+============   =======
+Field name:    version
+Type:          read
+Offset/size:   0x206/2
+Protocol:      2.00+
+============   =======
+
+  Contains the boot protocol version, in (major << 8)+minor format,
+  e.g. 0x0204 for version 2.04, and 0x0a11 for a hypothetical version
+  10.17.
+
+============   =================
+Field name:    realmode_swtch
+Type:          modify (optional)
+Offset/size:   0x208/4
+Protocol:      2.00+
+============   =================
+
+  Boot loader hook (see ADVANCED BOOT LOADER HOOKS below.)
+
+============   =============
+Field name:    start_sys_seg
+Type:          read
+Offset/size:   0x20c/2
+Protocol:      2.00+
+============   =============
+
+  The load low segment (0x1000).  Obsolete.
+
+============   ==============
+Field name:    kernel_version
+Type:          read
+Offset/size:   0x20e/2
+Protocol:      2.00+
+============   ==============
+
+  If set to a nonzero value, contains a pointer to a NUL-terminated
+  human-readable kernel version number string, less 0x200.  This can
+  be used to display the kernel version to the user.  This value
+  should be less than (0x200*setup_sects).
+
+  For example, if this value is set to 0x1c00, the kernel version
+  number string can be found at offset 0x1e00 in the kernel file.
+  This is a valid value if and only if the "setup_sects" field
+  contains the value 15 or higher, as::
+
+       0x1c00  < 15*0x200 (= 0x1e00) but
+       0x1c00 >= 14*0x200 (= 0x1c00)
+
+       0x1c00 >> 9 = 14, So the minimum value for setup_secs is 15.
+
+============   ==================
+Field name:    type_of_loader
+Type:          write (obligatory)
+Offset/size:   0x210/1
+Protocol:      2.00+
+============   ==================
+
+  If your boot loader has an assigned id (see table below), enter
+  0xTV here, where T is an identifier for the boot loader and V is
+  a version number.  Otherwise, enter 0xFF here.
+
+  For boot loader IDs above T = 0xD, write T = 0xE to this field and
+  write the extended ID minus 0x10 to the ext_loader_type field.
+  Similarly, the ext_loader_ver field can be used to provide more than
+  four bits for the bootloader version.
+
+  For example, for T = 0x15, V = 0x234, write::
+
+       type_of_loader  <- 0xE4
+       ext_loader_type <- 0x05
+       ext_loader_ver  <- 0x23
+
+  Assigned boot loader ids (hexadecimal):
+
+       == =======================================
+       0  LILO
+          (0x00 reserved for pre-2.00 bootloader)
+       1  Loadlin
+       2  bootsect-loader
+          (0x20, all other values reserved)
+       3  Syslinux
+       4  Etherboot/gPXE/iPXE
+       5  ELILO
+       7  GRUB
+       8  U-Boot
+       9  Xen
+       A  Gujin
+       B  Qemu
+       C  Arcturus Networks uCbootloader
+       D  kexec-tools
+       E  Extended (see ext_loader_type)
+       F  Special (0xFF = undefined)
+       10 Reserved
+       11 Minimal Linux Bootloader
+          <http://sebastian-plotz.blogspot.de>
+       12 OVMF UEFI virtualization stack
+       13 barebox
+       == =======================================
+
+  Please contact <hpa@zytor.com> if you need a bootloader ID value assigned.
+
+============   ===================
+Field name:    loadflags
+Type:          modify (obligatory)
+Offset/size:   0x211/1
+Protocol:      2.00+
+============   ===================
+
+  This field is a bitmask.
+
+  Bit 0 (read):        LOADED_HIGH
+
+       - If 0, the protected-mode code is loaded at 0x10000.
+       - If 1, the protected-mode code is loaded at 0x100000.
+
+  Bit 1 (kernel internal): KASLR_FLAG
+
+       - Used internally by the compressed kernel to communicate
+         KASLR status to kernel proper.
+
+           - If 1, KASLR enabled.
+           - If 0, KASLR disabled.
+
+  Bit 5 (write): QUIET_FLAG
+
+       - If 0, print early messages.
+       - If 1, suppress early messages.
+
+               This requests to the kernel (decompressor and early
+               kernel) to not write early messages that require
+               accessing the display hardware directly.
+
+  Bit 6 (obsolete): KEEP_SEGMENTS
+
+       Protocol: 2.07+
+
+        - This flag is obsolete.
+
+  Bit 7 (write): CAN_USE_HEAP
+
+       Set this bit to 1 to indicate that the value entered in the
+       heap_end_ptr is valid.  If this field is clear, some setup code
+       functionality will be disabled.
+
+
+============   ===================
+Field name:    setup_move_size
+Type:          modify (obligatory)
+Offset/size:   0x212/2
+Protocol:      2.00-2.01
+============   ===================
+
+  When using protocol 2.00 or 2.01, if the real mode kernel is not
+  loaded at 0x90000, it gets moved there later in the loading
+  sequence.  Fill in this field if you want additional data (such as
+  the kernel command line) moved in addition to the real-mode kernel
+  itself.
+
+  The unit is bytes starting with the beginning of the boot sector.
+
+  This field is can be ignored when the protocol is 2.02 or higher, or
+  if the real-mode code is loaded at 0x90000.
+
+============   ========================
+Field name:    code32_start
+Type:          modify (optional, reloc)
+Offset/size:   0x214/4
+Protocol:      2.00+
+============   ========================
+
+  The address to jump to in protected mode.  This defaults to the load
+  address of the kernel, and can be used by the boot loader to
+  determine the proper load address.
+
+  This field can be modified for two purposes:
+
+    1. as a boot loader hook (see Advanced Boot Loader Hooks below.)
+
+    2. if a bootloader which does not install a hook loads a
+       relocatable kernel at a nonstandard address it will have to modify
+       this field to point to the load address.
+
+============   ==================
+Field name:    ramdisk_image
+Type:          write (obligatory)
+Offset/size:   0x218/4
+Protocol:      2.00+
+============   ==================
+
+  The 32-bit linear address of the initial ramdisk or ramfs.  Leave at
+  zero if there is no initial ramdisk/ramfs.
+
+============   ==================
+Field name:    ramdisk_size
+Type:          write (obligatory)
+Offset/size:   0x21c/4
+Protocol:      2.00+
+============   ==================
+
+  Size of the initial ramdisk or ramfs.  Leave at zero if there is no
+  initial ramdisk/ramfs.
+
+============   ===============
+Field name:    bootsect_kludge
+Type:          kernel internal
+Offset/size:   0x220/4
+Protocol:      2.00+
+============   ===============
+
+  This field is obsolete.
+
+============   ==================
+Field name:    heap_end_ptr
+Type:          write (obligatory)
+Offset/size:   0x224/2
+Protocol:      2.01+
+============   ==================
+
+  Set this field to the offset (from the beginning of the real-mode
+  code) of the end of the setup stack/heap, minus 0x0200.
+
+============   ================
+Field name:    ext_loader_ver
+Type:          write (optional)
+Offset/size:   0x226/1
+Protocol:      2.02+
+============   ================
+
+  This field is used as an extension of the version number in the
+  type_of_loader field.  The total version number is considered to be
+  (type_of_loader & 0x0f) + (ext_loader_ver << 4).
+
+  The use of this field is boot loader specific.  If not written, it
+  is zero.
+
+  Kernels prior to 2.6.31 did not recognize this field, but it is safe
+  to write for protocol version 2.02 or higher.
+
+============   =====================================================
+Field name:    ext_loader_type
+Type:          write (obligatory if (type_of_loader & 0xf0) == 0xe0)
+Offset/size:   0x227/1
+Protocol:      2.02+
+============   =====================================================
+
+  This field is used as an extension of the type number in
+  type_of_loader field.  If the type in type_of_loader is 0xE, then
+  the actual type is (ext_loader_type + 0x10).
+
+  This field is ignored if the type in type_of_loader is not 0xE.
+
+  Kernels prior to 2.6.31 did not recognize this field, but it is safe
+  to write for protocol version 2.02 or higher.
+
+============   ==================
+Field name:    cmd_line_ptr
+Type:          write (obligatory)
+Offset/size:   0x228/4
+Protocol:      2.02+
+============   ==================
+
+  Set this field to the linear address of the kernel command line.
+  The kernel command line can be located anywhere between the end of
+  the setup heap and 0xA0000; it does not have to be located in the
+  same 64K segment as the real-mode code itself.
+
+  Fill in this field even if your boot loader does not support a
+  command line, in which case you can point this to an empty string
+  (or better yet, to the string "auto".)  If this field is left at
+  zero, the kernel will assume that your boot loader does not support
+  the 2.02+ protocol.
+
+============   ===============
+Field name:    initrd_addr_max
+Type:          read
+Offset/size:   0x22c/4
+Protocol:      2.03+
+============   ===============
+
+  The maximum address that may be occupied by the initial
+  ramdisk/ramfs contents.  For boot protocols 2.02 or earlier, this
+  field is not present, and the maximum address is 0x37FFFFFF.  (This
+  address is defined as the address of the highest safe byte, so if
+  your ramdisk is exactly 131072 bytes long and this field is
+  0x37FFFFFF, you can start your ramdisk at 0x37FE0000.)
+
+============   ============================
+Field name:    kernel_alignment
+Type:          read/modify (reloc)
+Offset/size:   0x230/4
+Protocol:      2.05+ (read), 2.10+ (modify)
+============   ============================
+
+  Alignment unit required by the kernel (if relocatable_kernel is
+  true.)  A relocatable kernel that is loaded at an alignment
+  incompatible with the value in this field will be realigned during
+  kernel initialization.
+
+  Starting with protocol version 2.10, this reflects the kernel
+  alignment preferred for optimal performance; it is possible for the
+  loader to modify this field to permit a lesser alignment.  See the
+  min_alignment and pref_address field below.
+
+============   ==================
+Field name:    relocatable_kernel
+Type:          read (reloc)
+Offset/size:   0x234/1
+Protocol:      2.05+
+============   ==================
+
+  If this field is nonzero, the protected-mode part of the kernel can
+  be loaded at any address that satisfies the kernel_alignment field.
+  After loading, the boot loader must set the code32_start field to
+  point to the loaded code, or to a boot loader hook.
+
+============   =============
+Field name:    min_alignment
+Type:          read (reloc)
+Offset/size:   0x235/1
+Protocol:      2.10+
+============   =============
+
+  This field, if nonzero, indicates as a power of two the minimum
+  alignment required, as opposed to preferred, by the kernel to boot.
+  If a boot loader makes use of this field, it should update the
+  kernel_alignment field with the alignment unit desired; typically::
+
+       kernel_alignment = 1 << min_alignment
+
+  There may be a considerable performance cost with an excessively
+  misaligned kernel.  Therefore, a loader should typically try each
+  power-of-two alignment from kernel_alignment down to this alignment.
+
+============   ==========
+Field name:    xloadflags
+Type:          read
+Offset/size:   0x236/2
+Protocol:      2.12+
+============   ==========
+
+  This field is a bitmask.
+
+  Bit 0 (read):        XLF_KERNEL_64
+
+       - If 1, this kernel has the legacy 64-bit entry point at 0x200.
+
+  Bit 1 (read): XLF_CAN_BE_LOADED_ABOVE_4G
+
+        - If 1, kernel/boot_params/cmdline/ramdisk can be above 4G.
+
+  Bit 2 (read):        XLF_EFI_HANDOVER_32
+
+       - If 1, the kernel supports the 32-bit EFI handoff entry point
+          given at handover_offset.
+
+  Bit 3 (read): XLF_EFI_HANDOVER_64
+
+       - If 1, the kernel supports the 64-bit EFI handoff entry point
+          given at handover_offset + 0x200.
+
+  Bit 4 (read): XLF_EFI_KEXEC
+
+       - If 1, the kernel supports kexec EFI boot with EFI runtime support.
+
+
+============   ============
+Field name:    cmdline_size
+Type:          read
+Offset/size:   0x238/4
+Protocol:      2.06+
+============   ============
+
+  The maximum size of the command line without the terminating
+  zero. This means that the command line can contain at most
+  cmdline_size characters. With protocol version 2.05 and earlier, the
+  maximum size was 255.
+
+============   ====================================
+Field name:    hardware_subarch
+Type:          write (optional, defaults to x86/PC)
+Offset/size:   0x23c/4
+Protocol:      2.07+
+============   ====================================
+
+  In a paravirtualized environment the hardware low level architectural
+  pieces such as interrupt handling, page table handling, and
+  accessing process control registers needs to be done differently.
+
+  This field allows the bootloader to inform the kernel we are in one
+  one of those environments.
+
+  ==========   ==============================
+  0x00000000   The default x86/PC environment
+  0x00000001   lguest
+  0x00000002   Xen
+  0x00000003   Moorestown MID
+  0x00000004   CE4100 TV Platform
+  ==========   ==============================
+
+============   =========================
+Field name:    hardware_subarch_data
+Type:          write (subarch-dependent)
+Offset/size:   0x240/8
+Protocol:      2.07+
+============   =========================
+
+  A pointer to data that is specific to hardware subarch
+  This field is currently unused for the default x86/PC environment,
+  do not modify.
+
+============   ==============
+Field name:    payload_offset
+Type:          read
+Offset/size:   0x248/4
+Protocol:      2.08+
+============   ==============
+
+  If non-zero then this field contains the offset from the beginning
+  of the protected-mode code to the payload.
+
+  The payload may be compressed. The format of both the compressed and
+  uncompressed data should be determined using the standard magic
+  numbers.  The currently supported compression formats are gzip
+  (magic numbers 1F 8B or 1F 9E), bzip2 (magic number 42 5A), LZMA
+  (magic number 5D 00), XZ (magic number FD 37), LZ4 (magic number
+  02 21) and ZSTD (magic number 28 B5). The uncompressed payload is
+  currently always ELF (magic number 7F 45 4C 46).
+
+============   ==============
+Field name:    payload_length
+Type:          read
+Offset/size:   0x24c/4
+Protocol:      2.08+
+============   ==============
+
+  The length of the payload.
+
+============   ===============
+Field name:    setup_data
+Type:          write (special)
+Offset/size:   0x250/8
+Protocol:      2.09+
+============   ===============
+
+  The 64-bit physical pointer to NULL terminated single linked list of
+  struct setup_data. This is used to define a more extensible boot
+  parameters passing mechanism. The definition of struct setup_data is
+  as follow::
+
+       struct setup_data {
+               u64 next;
+               u32 type;
+               u32 len;
+               u8  data[0];
+       };
+
+  Where, the next is a 64-bit physical pointer to the next node of
+  linked list, the next field of the last node is 0; the type is used
+  to identify the contents of data; the len is the length of data
+  field; the data holds the real payload.
+
+  This list may be modified at a number of points during the bootup
+  process.  Therefore, when modifying this list one should always make
+  sure to consider the case where the linked list already contains
+  entries.
+
+  The setup_data is a bit awkward to use for extremely large data objects,
+  both because the setup_data header has to be adjacent to the data object
+  and because it has a 32-bit length field. However, it is important that
+  intermediate stages of the boot process have a way to identify which
+  chunks of memory are occupied by kernel data.
+
+  Thus setup_indirect struct and SETUP_INDIRECT type were introduced in
+  protocol 2.15::
+
+    struct setup_indirect {
+      __u32 type;
+      __u32 reserved;  /* Reserved, must be set to zero. */
+      __u64 len;
+      __u64 addr;
+    };
+
+  The type member is a SETUP_INDIRECT | SETUP_* type. However, it cannot be
+  SETUP_INDIRECT itself since making the setup_indirect a tree structure
+  could require a lot of stack space in something that needs to parse it
+  and stack space can be limited in boot contexts.
+
+  Let's give an example how to point to SETUP_E820_EXT data using setup_indirect.
+  In this case setup_data and setup_indirect will look like this::
+
+    struct setup_data {
+      __u64 next = 0 or <addr_of_next_setup_data_struct>;
+      __u32 type = SETUP_INDIRECT;
+      __u32 len = sizeof(setup_indirect);
+      __u8 data[sizeof(setup_indirect)] = struct setup_indirect {
+        __u32 type = SETUP_INDIRECT | SETUP_E820_EXT;
+        __u32 reserved = 0;
+        __u64 len = <len_of_SETUP_E820_EXT_data>;
+        __u64 addr = <addr_of_SETUP_E820_EXT_data>;
+      }
+    }
+
+.. note::
+     SETUP_INDIRECT | SETUP_NONE objects cannot be properly distinguished
+     from SETUP_INDIRECT itself. So, this kind of objects cannot be provided
+     by the bootloaders.
+
+============   ============
+Field name:    pref_address
+Type:          read (reloc)
+Offset/size:   0x258/8
+Protocol:      2.10+
+============   ============
+
+  This field, if nonzero, represents a preferred load address for the
+  kernel.  A relocating bootloader should attempt to load at this
+  address if possible.
+
+  A non-relocatable kernel will unconditionally move itself and to run
+  at this address.
+
+============   =======
+Field name:    init_size
+Type:          read
+Offset/size:   0x260/4
+============   =======
+
+  This field indicates the amount of linear contiguous memory starting
+  at the kernel runtime start address that the kernel needs before it
+  is capable of examining its memory map.  This is not the same thing
+  as the total amount of memory the kernel needs to boot, but it can
+  be used by a relocating boot loader to help select a safe load
+  address for the kernel.
+
+  The kernel runtime start address is determined by the following algorithm::
+
+       if (relocatable_kernel)
+       runtime_start = align_up(load_address, kernel_alignment)
+       else
+       runtime_start = pref_address
+
+============   ===============
+Field name:    handover_offset
+Type:          read
+Offset/size:   0x264/4
+============   ===============
+
+  This field is the offset from the beginning of the kernel image to
+  the EFI handover protocol entry point. Boot loaders using the EFI
+  handover protocol to boot the kernel should jump to this offset.
+
+  See EFI HANDOVER PROTOCOL below for more details.
+
+============   ==================
+Field name:    kernel_info_offset
+Type:          read
+Offset/size:   0x268/4
+Protocol:      2.15+
+============   ==================
+
+  This field is the offset from the beginning of the kernel image to the
+  kernel_info. The kernel_info structure is embedded in the Linux image
+  in the uncompressed protected mode region.
+
+
+The kernel_info
+===============
+
+The relationships between the headers are analogous to the various data
+sections:
+
+  setup_header = .data
+  boot_params/setup_data = .bss
+
+What is missing from the above list? That's right:
+
+  kernel_info = .rodata
+
+We have been (ab)using .data for things that could go into .rodata or .bss for
+a long time, for lack of alternatives and -- especially early on -- inertia.
+Also, the BIOS stub is responsible for creating boot_params, so it isn't
+available to a BIOS-based loader (setup_data is, though).
+
+setup_header is permanently limited to 144 bytes due to the reach of the
+2-byte jump field, which doubles as a length field for the structure, combined
+with the size of the "hole" in struct boot_params that a protected-mode loader
+or the BIOS stub has to copy it into. It is currently 119 bytes long, which
+leaves us with 25 very precious bytes. This isn't something that can be fixed
+without revising the boot protocol entirely, breaking backwards compatibility.
+
+boot_params proper is limited to 4096 bytes, but can be arbitrarily extended
+by adding setup_data entries. It cannot be used to communicate properties of
+the kernel image, because it is .bss and has no image-provided content.
+
+kernel_info solves this by providing an extensible place for information about
+the kernel image. It is readonly, because the kernel cannot rely on a
+bootloader copying its contents anywhere, but that is OK; if it becomes
+necessary it can still contain data items that an enabled bootloader would be
+expected to copy into a setup_data chunk.
+
+All kernel_info data should be part of this structure. Fixed size data have to
+be put before kernel_info_var_len_data label. Variable size data have to be put
+after kernel_info_var_len_data label. Each chunk of variable size data has to
+be prefixed with header/magic and its size, e.g.::
+
+  kernel_info:
+          .ascii  "LToP"          /* Header, Linux top (structure). */
+          .long   kernel_info_var_len_data - kernel_info
+          .long   kernel_info_end - kernel_info
+          .long   0x01234567      /* Some fixed size data for the bootloaders. */
+  kernel_info_var_len_data:
+  example_struct:                 /* Some variable size data for the bootloaders. */
+          .ascii  "0123"          /* Header/Magic. */
+          .long   example_struct_end - example_struct
+          .ascii  "Struct"
+          .long   0x89012345
+  example_struct_end:
+  example_strings:                /* Some variable size data for the bootloaders. */
+          .ascii  "ABCD"          /* Header/Magic. */
+          .long   example_strings_end - example_strings
+          .asciz  "String_0"
+          .asciz  "String_1"
+  example_strings_end:
+  kernel_info_end:
+
+This way the kernel_info is self-contained blob.
+
+.. note::
+     Each variable size data header/magic can be any 4-character string,
+     without \0 at the end of the string, which does not collide with
+     existing variable length data headers/magics.
+
+
+Details of the kernel_info Fields
+=================================
+
+============   ========
+Field name:    header
+Offset/size:   0x0000/4
+============   ========
+
+  Contains the magic number "LToP" (0x506f544c).
+
+============   ========
+Field name:    size
+Offset/size:   0x0004/4
+============   ========
+
+  This field contains the size of the kernel_info including kernel_info.header.
+  It does not count kernel_info.kernel_info_var_len_data size. This field should be
+  used by the bootloaders to detect supported fixed size fields in the kernel_info
+  and beginning of kernel_info.kernel_info_var_len_data.
+
+============   ========
+Field name:    size_total
+Offset/size:   0x0008/4
+============   ========
+
+  This field contains the size of the kernel_info including kernel_info.header
+  and kernel_info.kernel_info_var_len_data.
+
+============   ==============
+Field name:    setup_type_max
+Offset/size:   0x000c/4
+============   ==============
+
+  This field contains maximal allowed type for setup_data and setup_indirect structs.
+
+
+The Image Checksum
+==================
+
+From boot protocol version 2.08 onwards the CRC-32 is calculated over
+the entire file using the characteristic polynomial 0x04C11DB7 and an
+initial remainder of 0xffffffff.  The checksum is appended to the
+file; therefore the CRC of the file up to the limit specified in the
+syssize field of the header is always 0.
+
+
+The Kernel Command Line
+=======================
+
+The kernel command line has become an important way for the boot
+loader to communicate with the kernel.  Some of its options are also
+relevant to the boot loader itself, see "special command line options"
+below.
+
+The kernel command line is a null-terminated string. The maximum
+length can be retrieved from the field cmdline_size.  Before protocol
+version 2.06, the maximum was 255 characters.  A string that is too
+long will be automatically truncated by the kernel.
+
+If the boot protocol version is 2.02 or later, the address of the
+kernel command line is given by the header field cmd_line_ptr (see
+above.)  This address can be anywhere between the end of the setup
+heap and 0xA0000.
+
+If the protocol version is *not* 2.02 or higher, the kernel
+command line is entered using the following protocol:
+
+  - At offset 0x0020 (word), "cmd_line_magic", enter the magic
+    number 0xA33F.
+
+  - At offset 0x0022 (word), "cmd_line_offset", enter the offset
+    of the kernel command line (relative to the start of the
+    real-mode kernel).
+
+  - The kernel command line *must* be within the memory region
+    covered by setup_move_size, so you may need to adjust this
+    field.
+
+
+Memory Layout of The Real-Mode Code
+===================================
+
+The real-mode code requires a stack/heap to be set up, as well as
+memory allocated for the kernel command line.  This needs to be done
+in the real-mode accessible memory in bottom megabyte.
+
+It should be noted that modern machines often have a sizable Extended
+BIOS Data Area (EBDA).  As a result, it is advisable to use as little
+of the low megabyte as possible.
+
+Unfortunately, under the following circumstances the 0x90000 memory
+segment has to be used:
+
+       - When loading a zImage kernel ((loadflags & 0x01) == 0).
+       - When loading a 2.01 or earlier boot protocol kernel.
+
+.. note::
+     For the 2.00 and 2.01 boot protocols, the real-mode code
+     can be loaded at another address, but it is internally
+     relocated to 0x90000.  For the "old" protocol, the
+     real-mode code must be loaded at 0x90000.
+
+When loading at 0x90000, avoid using memory above 0x9a000.
+
+For boot protocol 2.02 or higher, the command line does not have to be
+located in the same 64K segment as the real-mode setup code; it is
+thus permitted to give the stack/heap the full 64K segment and locate
+the command line above it.
+
+The kernel command line should not be located below the real-mode
+code, nor should it be located in high memory.
+
+
+Sample Boot Configuartion
+=========================
+
+As a sample configuration, assume the following layout of the real
+mode segment.
+
+    When loading below 0x90000, use the entire segment:
+
+        =============  ===================
+       0x0000-0x7fff   Real mode kernel
+       0x8000-0xdfff   Stack and heap
+       0xe000-0xffff   Kernel command line
+       =============   ===================
+
+    When loading at 0x90000 OR the protocol version is 2.01 or earlier:
+
+       =============   ===================
+       0x0000-0x7fff   Real mode kernel
+       0x8000-0x97ff   Stack and heap
+       0x9800-0x9fff   Kernel command line
+       =============   ===================
+
+Such a boot loader should enter the following fields in the header::
+
+       unsigned long base_ptr; /* base address for real-mode segment */
+
+       if ( setup_sects == 0 ) {
+               setup_sects = 4;
+       }
+
+       if ( protocol >= 0x0200 ) {
+               type_of_loader = <type code>;
+               if ( loading_initrd ) {
+                       ramdisk_image = <initrd_address>;
+                       ramdisk_size = <initrd_size>;
+               }
+
+               if ( protocol >= 0x0202 && loadflags & 0x01 )
+                       heap_end = 0xe000;
+               else
+                       heap_end = 0x9800;
+
+               if ( protocol >= 0x0201 ) {
+                       heap_end_ptr = heap_end - 0x200;
+                       loadflags |= 0x80; /* CAN_USE_HEAP */
+               }
+
+               if ( protocol >= 0x0202 ) {
+                       cmd_line_ptr = base_ptr + heap_end;
+                       strcpy(cmd_line_ptr, cmdline);
+               } else {
+                       cmd_line_magic  = 0xA33F;
+                       cmd_line_offset = heap_end;
+                       setup_move_size = heap_end + strlen(cmdline)+1;
+                       strcpy(base_ptr+cmd_line_offset, cmdline);
+               }
+       } else {
+               /* Very old kernel */
+
+               heap_end = 0x9800;
+
+               cmd_line_magic  = 0xA33F;
+               cmd_line_offset = heap_end;
+
+               /* A very old kernel MUST have its real-mode code
+                  loaded at 0x90000 */
+
+               if ( base_ptr != 0x90000 ) {
+                       /* Copy the real-mode kernel */
+                       memcpy(0x90000, base_ptr, (setup_sects+1)*512);
+                       base_ptr = 0x90000;              /* Relocated */
+               }
+
+               strcpy(0x90000+cmd_line_offset, cmdline);
+
+               /* It is recommended to clear memory up to the 32K mark */
+               memset(0x90000 + (setup_sects+1)*512, 0,
+                      (64-(setup_sects+1))*512);
+       }
+
+
+Loading The Rest of The Kernel
+==============================
+
+The 32-bit (non-real-mode) kernel starts at offset (setup_sects+1)*512
+in the kernel file (again, if setup_sects == 0 the real value is 4.)
+It should be loaded at address 0x10000 for Image/zImage kernels and
+0x100000 for bzImage kernels.
+
+The kernel is a bzImage kernel if the protocol >= 2.00 and the 0x01
+bit (LOAD_HIGH) in the loadflags field is set::
+
+       is_bzImage = (protocol >= 0x0200) && (loadflags & 0x01);
+       load_address = is_bzImage ? 0x100000 : 0x10000;
+
+Note that Image/zImage kernels can be up to 512K in size, and thus use
+the entire 0x10000-0x90000 range of memory.  This means it is pretty
+much a requirement for these kernels to load the real-mode part at
+0x90000.  bzImage kernels allow much more flexibility.
+
+Special Command Line Options
+============================
+
+If the command line provided by the boot loader is entered by the
+user, the user may expect the following command line options to work.
+They should normally not be deleted from the kernel command line even
+though not all of them are actually meaningful to the kernel.  Boot
+loader authors who need additional command line options for the boot
+loader itself should get them registered in
+Documentation/admin-guide/kernel-parameters.rst to make sure they will not
+conflict with actual kernel options now or in the future.
+
+  vga=<mode>
+       <mode> here is either an integer (in C notation, either
+       decimal, octal, or hexadecimal) or one of the strings
+       "normal" (meaning 0xFFFF), "ext" (meaning 0xFFFE) or "ask"
+       (meaning 0xFFFD).  This value should be entered into the
+       vid_mode field, as it is used by the kernel before the command
+       line is parsed.
+
+  mem=<size>
+       <size> is an integer in C notation optionally followed by
+       (case insensitive) K, M, G, T, P or E (meaning << 10, << 20,
+       << 30, << 40, << 50 or << 60).  This specifies the end of
+       memory to the kernel. This affects the possible placement of
+       an initrd, since an initrd should be placed near end of
+       memory.  Note that this is an option to *both* the kernel and
+       the bootloader!
+
+  initrd=<file>
+       An initrd should be loaded.  The meaning of <file> is
+       obviously bootloader-dependent, and some boot loaders
+       (e.g. LILO) do not have such a command.
+
+In addition, some boot loaders add the following options to the
+user-specified command line:
+
+  BOOT_IMAGE=<file>
+       The boot image which was loaded.  Again, the meaning of <file>
+       is obviously bootloader-dependent.
+
+  auto
+       The kernel was booted without explicit user intervention.
+
+If these options are added by the boot loader, it is highly
+recommended that they are located *first*, before the user-specified
+or configuration-specified command line.  Otherwise, "init=/bin/sh"
+gets confused by the "auto" option.
+
+
+Running the Kernel
+==================
+
+The kernel is started by jumping to the kernel entry point, which is
+located at *segment* offset 0x20 from the start of the real mode
+kernel.  This means that if you loaded your real-mode kernel code at
+0x90000, the kernel entry point is 9020:0000.
+
+At entry, ds = es = ss should point to the start of the real-mode
+kernel code (0x9000 if the code is loaded at 0x90000), sp should be
+set up properly, normally pointing to the top of the heap, and
+interrupts should be disabled.  Furthermore, to guard against bugs in
+the kernel, it is recommended that the boot loader sets fs = gs = ds =
+es = ss.
+
+In our example from above, we would do::
+
+       /* Note: in the case of the "old" kernel protocol, base_ptr must
+          be == 0x90000 at this point; see the previous sample code */
+
+       seg = base_ptr >> 4;
+
+       cli();  /* Enter with interrupts disabled! */
+
+       /* Set up the real-mode kernel stack */
+       _SS = seg;
+       _SP = heap_end;
+
+       _DS = _ES = _FS = _GS = seg;
+       jmp_far(seg+0x20, 0);   /* Run the kernel */
+
+If your boot sector accesses a floppy drive, it is recommended to
+switch off the floppy motor before running the kernel, since the
+kernel boot leaves interrupts off and thus the motor will not be
+switched off, especially if the loaded kernel has the floppy driver as
+a demand-loaded module!
+
+
+Advanced Boot Loader Hooks
+==========================
+
+If the boot loader runs in a particularly hostile environment (such as
+LOADLIN, which runs under DOS) it may be impossible to follow the
+standard memory location requirements.  Such a boot loader may use the
+following hooks that, if set, are invoked by the kernel at the
+appropriate time.  The use of these hooks should probably be
+considered an absolutely last resort!
+
+IMPORTANT: All the hooks are required to preserve %esp, %ebp, %esi and
+%edi across invocation.
+
+  realmode_swtch:
+       A 16-bit real mode far subroutine invoked immediately before
+       entering protected mode.  The default routine disables NMI, so
+       your routine should probably do so, too.
+
+  code32_start:
+       A 32-bit flat-mode routine *jumped* to immediately after the
+       transition to protected mode, but before the kernel is
+       uncompressed.  No segments, except CS, are guaranteed to be
+       set up (current kernels do, but older ones do not); you should
+       set them up to BOOT_DS (0x18) yourself.
+
+       After completing your hook, you should jump to the address
+       that was in this field before your boot loader overwrote it
+       (relocated, if appropriate.)
+
+
+32-bit Boot Protocol
+====================
+
+For machine with some new BIOS other than legacy BIOS, such as EFI,
+LinuxBIOS, etc, and kexec, the 16-bit real mode setup code in kernel
+based on legacy BIOS can not be used, so a 32-bit boot protocol needs
+to be defined.
+
+In 32-bit boot protocol, the first step in loading a Linux kernel
+should be to setup the boot parameters (struct boot_params,
+traditionally known as "zero page"). The memory for struct boot_params
+should be allocated and initialized to all zero. Then the setup header
+from offset 0x01f1 of kernel image on should be loaded into struct
+boot_params and examined. The end of setup header can be calculated as
+follow::
+
+       0x0202 + byte value at offset 0x0201
+
+In addition to read/modify/write the setup header of the struct
+boot_params as that of 16-bit boot protocol, the boot loader should
+also fill the additional fields of the struct boot_params as
+described in chapter Documentation/arch/x86/zero-page.rst.
+
+After setting up the struct boot_params, the boot loader can load the
+32/64-bit kernel in the same way as that of 16-bit boot protocol.
+
+In 32-bit boot protocol, the kernel is started by jumping to the
+32-bit kernel entry point, which is the start address of loaded
+32/64-bit kernel.
+
+At entry, the CPU must be in 32-bit protected mode with paging
+disabled; a GDT must be loaded with the descriptors for selectors
+__BOOT_CS(0x10) and __BOOT_DS(0x18); both descriptors must be 4G flat
+segment; __BOOT_CS must have execute/read permission, and __BOOT_DS
+must have read/write permission; CS must be __BOOT_CS and DS, ES, SS
+must be __BOOT_DS; interrupt must be disabled; %esi must hold the base
+address of the struct boot_params; %ebp, %edi and %ebx must be zero.
+
+64-bit Boot Protocol
+====================
+
+For machine with 64bit cpus and 64bit kernel, we could use 64bit bootloader
+and we need a 64-bit boot protocol.
+
+In 64-bit boot protocol, the first step in loading a Linux kernel
+should be to setup the boot parameters (struct boot_params,
+traditionally known as "zero page"). The memory for struct boot_params
+could be allocated anywhere (even above 4G) and initialized to all zero.
+Then, the setup header at offset 0x01f1 of kernel image on should be
+loaded into struct boot_params and examined. The end of setup header
+can be calculated as follows::
+
+       0x0202 + byte value at offset 0x0201
+
+In addition to read/modify/write the setup header of the struct
+boot_params as that of 16-bit boot protocol, the boot loader should
+also fill the additional fields of the struct boot_params as described
+in chapter Documentation/arch/x86/zero-page.rst.
+
+After setting up the struct boot_params, the boot loader can load
+64-bit kernel in the same way as that of 16-bit boot protocol, but
+kernel could be loaded above 4G.
+
+In 64-bit boot protocol, the kernel is started by jumping to the
+64-bit kernel entry point, which is the start address of loaded
+64-bit kernel plus 0x200.
+
+At entry, the CPU must be in 64-bit mode with paging enabled.
+The range with setup_header.init_size from start address of loaded
+kernel and zero page and command line buffer get ident mapping;
+a GDT must be loaded with the descriptors for selectors
+__BOOT_CS(0x10) and __BOOT_DS(0x18); both descriptors must be 4G flat
+segment; __BOOT_CS must have execute/read permission, and __BOOT_DS
+must have read/write permission; CS must be __BOOT_CS and DS, ES, SS
+must be __BOOT_DS; interrupt must be disabled; %rsi must hold the base
+address of the struct boot_params.
+
+EFI Handover Protocol (deprecated)
+==================================
+
+This protocol allows boot loaders to defer initialisation to the EFI
+boot stub. The boot loader is required to load the kernel/initrd(s)
+from the boot media and jump to the EFI handover protocol entry point
+which is hdr->handover_offset bytes from the beginning of
+startup_{32,64}.
+
+The boot loader MUST respect the kernel's PE/COFF metadata when it comes
+to section alignment, the memory footprint of the executable image beyond
+the size of the file itself, and any other aspect of the PE/COFF header
+that may affect correct operation of the image as a PE/COFF binary in the
+execution context provided by the EFI firmware.
+
+The function prototype for the handover entry point looks like this::
+
+    efi_main(void *handle, efi_system_table_t *table, struct boot_params *bp)
+
+'handle' is the EFI image handle passed to the boot loader by the EFI
+firmware, 'table' is the EFI system table - these are the first two
+arguments of the "handoff state" as described in section 2.3 of the
+UEFI specification. 'bp' is the boot loader-allocated boot params.
+
+The boot loader *must* fill out the following fields in bp::
+
+  - hdr.cmd_line_ptr
+  - hdr.ramdisk_image (if applicable)
+  - hdr.ramdisk_size  (if applicable)
+
+All other fields should be zero.
+
+NOTE: The EFI Handover Protocol is deprecated in favour of the ordinary PE/COFF
+      entry point, combined with the LINUX_EFI_INITRD_MEDIA_GUID based initrd
+      loading protocol (refer to [0] for an example of the bootloader side of
+      this), which removes the need for any knowledge on the part of the EFI
+      bootloader regarding the internal representation of boot_params or any
+      requirements/limitations regarding the placement of the command line
+      and ramdisk in memory, or the placement of the kernel image itself.
+
+[0] https://github.com/u-boot/u-boot/commit/ec80b4735a593961fe701cc3a5d717d4739b0fd0
diff --git a/Documentation/arch/x86/booting-dt.rst b/Documentation/arch/x86/booting-dt.rst
new file mode 100644 (file)
index 0000000..b089ffd
--- /dev/null
@@ -0,0 +1,21 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+DeviceTree Booting
+------------------
+
+  There is one single 32bit entry point to the kernel at code32_start,
+  the decompressor (the real mode entry point goes to the same  32bit
+  entry point once it switched into protected mode). That entry point
+  supports one calling convention which is documented in
+  Documentation/arch/x86/boot.rst
+  The physical pointer to the device-tree block is passed via setup_data
+  which requires at least boot protocol 2.09.
+  The type filed is defined as
+
+  #define SETUP_DTB                      2
+
+  This device-tree is used as an extension to the "boot page". As such it
+  does not parse / consider data which is already covered by the boot
+  page. This includes memory size, reserved ranges, command line arguments
+  or initrd address. It simply holds information which can not be retrieved
+  otherwise like interrupt routing or a list of devices behind an I2C bus.
diff --git a/Documentation/arch/x86/buslock.rst b/Documentation/arch/x86/buslock.rst
new file mode 100644 (file)
index 0000000..31ec0ef
--- /dev/null
@@ -0,0 +1,132 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: <isonum.txt>
+
+===============================
+Bus lock detection and handling
+===============================
+
+:Copyright: |copy| 2021 Intel Corporation
+:Authors: - Fenghua Yu <fenghua.yu@intel.com>
+          - Tony Luck <tony.luck@intel.com>
+
+Problem
+=======
+
+A split lock is any atomic operation whose operand crosses two cache lines.
+Since the operand spans two cache lines and the operation must be atomic,
+the system locks the bus while the CPU accesses the two cache lines.
+
+A bus lock is acquired through either split locked access to writeback (WB)
+memory or any locked access to non-WB memory. This is typically thousands of
+cycles slower than an atomic operation within a cache line. It also disrupts
+performance on other cores and brings the whole system to its knees.
+
+Detection
+=========
+
+Intel processors may support either or both of the following hardware
+mechanisms to detect split locks and bus locks.
+
+#AC exception for split lock detection
+--------------------------------------
+
+Beginning with the Tremont Atom CPU split lock operations may raise an
+Alignment Check (#AC) exception when a split lock operation is attemped.
+
+#DB exception for bus lock detection
+------------------------------------
+
+Some CPUs have the ability to notify the kernel by an #DB trap after a user
+instruction acquires a bus lock and is executed. This allows the kernel to
+terminate the application or to enforce throttling.
+
+Software handling
+=================
+
+The kernel #AC and #DB handlers handle bus lock based on the kernel
+parameter "split_lock_detect". Here is a summary of different options:
+
++------------------+----------------------------+-----------------------+
+|split_lock_detect=|#AC for split lock         |#DB for bus lock       |
++------------------+----------------------------+-----------------------+
+|off              |Do nothing                  |Do nothing             |
++------------------+----------------------------+-----------------------+
+|warn             |Kernel OOPs                 |Warn once per task and |
+|(default)        |Warn once per task, add a   |and continues to run.  |
+|                 |delay, add synchronization  |                       |
+|                 |to prevent more than one    |                       |
+|                 |core from executing a       |                       |
+|                 |split lock in parallel.     |                       |
+|                 |sysctl split_lock_mitigate  |                       |
+|                 |can be used to avoid the    |                       |
+|                 |delay and synchronization   |                       |
+|                 |When both features are      |                       |
+|                 |supported, warn in #AC      |                       |
++------------------+----------------------------+-----------------------+
+|fatal            |Kernel OOPs                 |Send SIGBUS to user.   |
+|                 |Send SIGBUS to user         |                       |
+|                 |When both features are      |                       |
+|                 |supported, fatal in #AC     |                       |
++------------------+----------------------------+-----------------------+
+|ratelimit:N      |Do nothing                  |Limit bus lock rate to |
+|(0 < N <= 1000)   |                           |N bus locks per second |
+|                 |                            |system wide and warn on|
+|                 |                            |bus locks.             |
++------------------+----------------------------+-----------------------+
+
+Usages
+======
+
+Detecting and handling bus lock may find usages in various areas:
+
+It is critical for real time system designers who build consolidated real
+time systems. These systems run hard real time code on some cores and run
+"untrusted" user processes on other cores. The hard real time cannot afford
+to have any bus lock from the untrusted processes to hurt real time
+performance. To date the designers have been unable to deploy these
+solutions as they have no way to prevent the "untrusted" user code from
+generating split lock and bus lock to block the hard real time code to
+access memory during bus locking.
+
+It's also useful for general computing to prevent guests or user
+applications from slowing down the overall system by executing instructions
+with bus lock.
+
+
+Guidance
+========
+off
+---
+
+Disable checking for split lock and bus lock. This option can be useful if
+there are legacy applications that trigger these events at a low rate so
+that mitigation is not needed.
+
+warn
+----
+
+A warning is emitted when a bus lock is detected which allows to identify
+the offending application. This is the default behavior.
+
+fatal
+-----
+
+In this case, the bus lock is not tolerated and the process is killed.
+
+ratelimit
+---------
+
+A system wide bus lock rate limit N is specified where 0 < N <= 1000. This
+allows a bus lock rate up to N bus locks per second. When the bus lock rate
+is exceeded then any task which is caught via the buslock #DB exception is
+throttled by enforced sleeps until the rate goes under the limit again.
+
+This is an effective mitigation in cases where a minimal impact can be
+tolerated, but an eventual Denial of Service attack has to be prevented. It
+allows to identify the offending processes and analyze whether they are
+malicious or just badly written.
+
+Selecting a rate limit of 1000 allows the bus to be locked for up to about
+seven million cycles each second (assuming 7000 cycles for each bus
+lock). On a 2 GHz processor that would be about 0.35% system slowdown.
diff --git a/Documentation/arch/x86/cpuinfo.rst b/Documentation/arch/x86/cpuinfo.rst
new file mode 100644 (file)
index 0000000..08246e8
--- /dev/null
@@ -0,0 +1,154 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=================
+x86 Feature Flags
+=================
+
+Introduction
+============
+
+On x86, flags appearing in /proc/cpuinfo have an X86_FEATURE definition
+in arch/x86/include/asm/cpufeatures.h. If the kernel cares about a feature
+or KVM want to expose the feature to a KVM guest, it can and should have
+an X86_FEATURE_* defined. These flags represent hardware features as
+well as software features.
+
+If users want to know if a feature is available on a given system, they
+try to find the flag in /proc/cpuinfo. If a given flag is present, it
+means that the kernel supports it and is currently making it available.
+If such flag represents a hardware feature, it also means that the
+hardware supports it.
+
+If the expected flag does not appear in /proc/cpuinfo, things are murkier.
+Users need to find out the reason why the flag is missing and find the way
+how to enable it, which is not always easy. There are several factors that
+can explain missing flags: the expected feature failed to enable, the feature
+is missing in hardware, platform firmware did not enable it, the feature is
+disabled at build or run time, an old kernel is in use, or the kernel does
+not support the feature and thus has not enabled it. In general, /proc/cpuinfo
+shows features which the kernel supports. For a full list of CPUID flags
+which the CPU supports, use tools/arch/x86/kcpuid.
+
+How are feature flags created?
+==============================
+
+a: Feature flags can be derived from the contents of CPUID leaves.
+------------------------------------------------------------------
+These feature definitions are organized mirroring the layout of CPUID
+leaves and grouped in words with offsets as mapped in enum cpuid_leafs
+in cpufeatures.h (see arch/x86/include/asm/cpufeatures.h for details).
+If a feature is defined with a X86_FEATURE_<name> definition in
+cpufeatures.h, and if it is detected at run time, the flags will be
+displayed accordingly in /proc/cpuinfo. For example, the flag "avx2"
+comes from X86_FEATURE_AVX2 in cpufeatures.h.
+
+b: Flags can be from scattered CPUID-based features.
+----------------------------------------------------
+Hardware features enumerated in sparsely populated CPUID leaves get
+software-defined values. Still, CPUID needs to be queried to determine
+if a given feature is present. This is done in init_scattered_cpuid_features().
+For instance, X86_FEATURE_CQM_LLC is defined as 11*32 + 0 and its presence is
+checked at runtime in the respective CPUID leaf [EAX=f, ECX=0] bit EDX[1].
+
+The intent of scattering CPUID leaves is to not bloat struct
+cpuinfo_x86.x86_capability[] unnecessarily. For instance, the CPUID leaf
+[EAX=7, ECX=0] has 30 features and is dense, but the CPUID leaf [EAX=7, EAX=1]
+has only one feature and would waste 31 bits of space in the x86_capability[]
+array. Since there is a struct cpuinfo_x86 for each possible CPU, the wasted
+memory is not trivial.
+
+c: Flags can be created synthetically under certain conditions for hardware features.
+-------------------------------------------------------------------------------------
+Examples of conditions include whether certain features are present in
+MSR_IA32_CORE_CAPS or specific CPU models are identified. If the needed
+conditions are met, the features are enabled by the set_cpu_cap or
+setup_force_cpu_cap macros. For example, if bit 5 is set in MSR_IA32_CORE_CAPS,
+the feature X86_FEATURE_SPLIT_LOCK_DETECT will be enabled and
+"split_lock_detect" will be displayed. The flag "ring3mwait" will be
+displayed only when running on INTEL_FAM6_XEON_PHI_[KNL|KNM] processors.
+
+d: Flags can represent purely software features.
+------------------------------------------------
+These flags do not represent hardware features. Instead, they represent a
+software feature implemented in the kernel. For example, Kernel Page Table
+Isolation is purely software feature and its feature flag X86_FEATURE_PTI is
+also defined in cpufeatures.h.
+
+Naming of Flags
+===============
+
+The script arch/x86/kernel/cpu/mkcapflags.sh processes the
+#define X86_FEATURE_<name> from cpufeatures.h and generates the
+x86_cap/bug_flags[] arrays in kernel/cpu/capflags.c. The names in the
+resulting x86_cap/bug_flags[] are used to populate /proc/cpuinfo. The naming
+of flags in the x86_cap/bug_flags[] are as follows:
+
+a: The name of the flag is from the string in X86_FEATURE_<name> by default.
+----------------------------------------------------------------------------
+By default, the flag <name> in /proc/cpuinfo is extracted from the respective
+X86_FEATURE_<name> in cpufeatures.h. For example, the flag "avx2" is from
+X86_FEATURE_AVX2.
+
+b: The naming can be overridden.
+--------------------------------
+If the comment on the line for the #define X86_FEATURE_* starts with a
+double-quote character (""), the string inside the double-quote characters
+will be the name of the flags. For example, the flag "sse4_1" comes from
+the comment "sse4_1" following the X86_FEATURE_XMM4_1 definition.
+
+There are situations in which overriding the displayed name of the flag is
+needed. For instance, /proc/cpuinfo is a userspace interface and must remain
+constant. If, for some reason, the naming of X86_FEATURE_<name> changes, one
+shall override the new naming with the name already used in /proc/cpuinfo.
+
+c: The naming override can be "", which means it will not appear in /proc/cpuinfo.
+----------------------------------------------------------------------------------
+The feature shall be omitted from /proc/cpuinfo if it does not make sense for
+the feature to be exposed to userspace. For example, X86_FEATURE_ALWAYS is
+defined in cpufeatures.h but that flag is an internal kernel feature used
+in the alternative runtime patching functionality. So, its name is overridden
+with "". Its flag will not appear in /proc/cpuinfo.
+
+Flags are missing when one or more of these happen
+==================================================
+
+a: The hardware does not enumerate support for it.
+--------------------------------------------------
+For example, when a new kernel is running on old hardware or the feature is
+not enabled by boot firmware. Even if the hardware is new, there might be a
+problem enabling the feature at run time, the flag will not be displayed.
+
+b: The kernel does not know about the flag.
+-------------------------------------------
+For example, when an old kernel is running on new hardware.
+
+c: The kernel disabled support for it at compile-time.
+------------------------------------------------------
+For example, if 5-level-paging is not enabled when building (i.e.,
+CONFIG_X86_5LEVEL is not selected) the flag "la57" will not show up [#f1]_.
+Even though the feature will still be detected via CPUID, the kernel disables
+it by clearing via setup_clear_cpu_cap(X86_FEATURE_LA57).
+
+d: The feature is disabled at boot-time.
+----------------------------------------
+A feature can be disabled either using a command-line parameter or because
+it failed to be enabled. The command-line parameter clearcpuid= can be used
+to disable features using the feature number as defined in
+/arch/x86/include/asm/cpufeatures.h. For instance, User Mode Instruction
+Protection can be disabled using clearcpuid=514. The number 514 is calculated
+from #define X86_FEATURE_UMIP (16*32 + 2).
+
+In addition, there exists a variety of custom command-line parameters that
+disable specific features. The list of parameters includes, but is not limited
+to, nofsgsbase, nosgx, noxsave, etc. 5-level paging can also be disabled using
+"no5lvl".
+
+e: The feature was known to be non-functional.
+----------------------------------------------
+The feature was known to be non-functional because a dependency was
+missing at runtime. For example, AVX flags will not show up if XSAVE feature
+is disabled since they depend on XSAVE feature. Another example would be broken
+CPUs and them missing microcode patches. Due to that, the kernel decides not to
+enable a feature.
+
+.. [#f1] 5-level paging uses linear address of 57 bits.
diff --git a/Documentation/arch/x86/earlyprintk.rst b/Documentation/arch/x86/earlyprintk.rst
new file mode 100644 (file)
index 0000000..51ef11e
--- /dev/null
@@ -0,0 +1,151 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============
+Early Printk
+============
+
+Mini-HOWTO for using the earlyprintk=dbgp boot option with a
+USB2 Debug port key and a debug cable, on x86 systems.
+
+You need two computers, the 'USB debug key' special gadget and
+two USB cables, connected like this::
+
+  [host/target] <-------> [USB debug key] <-------> [client/console]
+
+Hardware requirements
+=====================
+
+  a) Host/target system needs to have USB debug port capability.
+
+     You can check this capability by looking at a 'Debug port' bit in
+     the lspci -vvv output::
+
+       # lspci -vvv
+       ...
+       00:1d.7 USB Controller: Intel Corporation 82801H (ICH8 Family) USB2 EHCI Controller #1 (rev 03) (prog-if 20 [EHCI])
+               Subsystem: Lenovo ThinkPad T61
+               Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
+               Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
+               Latency: 0
+               Interrupt: pin D routed to IRQ 19
+               Region 0: Memory at fe227000 (32-bit, non-prefetchable) [size=1K]
+               Capabilities: [50] Power Management version 2
+                       Flags: PMEClk- DSI- D1- D2- AuxCurrent=375mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
+                       Status: D0 PME-Enable- DSel=0 DScale=0 PME+
+               Capabilities: [58] Debug port: BAR=1 offset=00a0
+                            ^^^^^^^^^^^ <==================== [ HERE ]
+               Kernel driver in use: ehci_hcd
+               Kernel modules: ehci-hcd
+       ...
+
+     .. note::
+       If your system does not list a debug port capability then you probably
+       won't be able to use the USB debug key.
+
+  b) You also need a NetChip USB debug cable/key:
+
+        http://www.plxtech.com/products/NET2000/NET20DC/default.asp
+
+     This is a small blue plastic connector with two USB connections;
+     it draws power from its USB connections.
+
+  c) You need a second client/console system with a high speed USB 2.0 port.
+
+  d) The NetChip device must be plugged directly into the physical
+     debug port on the "host/target" system. You cannot use a USB hub in
+     between the physical debug port and the "host/target" system.
+
+     The EHCI debug controller is bound to a specific physical USB
+     port and the NetChip device will only work as an early printk
+     device in this port.  The EHCI host controllers are electrically
+     wired such that the EHCI debug controller is hooked up to the
+     first physical port and there is no way to change this via software.
+     You can find the physical port through experimentation by trying
+     each physical port on the system and rebooting.  Or you can try
+     and use lsusb or look at the kernel info messages emitted by the
+     usb stack when you plug a usb device into various ports on the
+     "host/target" system.
+
+     Some hardware vendors do not expose the usb debug port with a
+     physical connector and if you find such a device send a complaint
+     to the hardware vendor, because there is no reason not to wire
+     this port into one of the physically accessible ports.
+
+  e) It is also important to note, that many versions of the NetChip
+     device require the "client/console" system to be plugged into the
+     right hand side of the device (with the product logo facing up and
+     readable left to right).  The reason being is that the 5 volt
+     power supply is taken from only one side of the device and it
+     must be the side that does not get rebooted.
+
+Software requirements
+=====================
+
+  a) On the host/target system:
+
+    You need to enable the following kernel config option::
+
+      CONFIG_EARLY_PRINTK_DBGP=y
+
+    And you need to add the boot command line: "earlyprintk=dbgp".
+
+    .. note::
+      If you are using Grub, append it to the 'kernel' line in
+      /etc/grub.conf.  If you are using Grub2 on a BIOS firmware system,
+      append it to the 'linux' line in /boot/grub2/grub.cfg. If you are
+      using Grub2 on an EFI firmware system, append it to the 'linux'
+      or 'linuxefi' line in /boot/grub2/grub.cfg or
+      /boot/efi/EFI/<distro>/grub.cfg.
+
+    On systems with more than one EHCI debug controller you must
+    specify the correct EHCI debug controller number.  The ordering
+    comes from the PCI bus enumeration of the EHCI controllers.  The
+    default with no number argument is "0" or the first EHCI debug
+    controller.  To use the second EHCI debug controller, you would
+    use the command line: "earlyprintk=dbgp1"
+
+    .. note::
+      normally earlyprintk console gets turned off once the
+      regular console is alive - use "earlyprintk=dbgp,keep" to keep
+      this channel open beyond early bootup. This can be useful for
+      debugging crashes under Xorg, etc.
+
+  b) On the client/console system:
+
+    You should enable the following kernel config option::
+
+      CONFIG_USB_SERIAL_DEBUG=y
+
+    On the next bootup with the modified kernel you should
+    get a /dev/ttyUSBx device(s).
+
+    Now this channel of kernel messages is ready to be used: start
+    your favorite terminal emulator (minicom, etc.) and set
+    it up to use /dev/ttyUSB0 - or use a raw 'cat /dev/ttyUSBx' to
+    see the raw output.
+
+  c) On Nvidia Southbridge based systems: the kernel will try to probe
+     and find out which port has a debug device connected.
+
+Testing
+=======
+
+You can test the output by using earlyprintk=dbgp,keep and provoking
+kernel messages on the host/target system. You can provoke a harmless
+kernel message by for example doing::
+
+     echo h > /proc/sysrq-trigger
+
+On the host/target system you should see this help line in "dmesg" output::
+
+     SysRq : HELP : loglevel(0-9) reBoot Crashdump terminate-all-tasks(E) memory-full-oom-kill(F) kill-all-tasks(I) saK show-backtrace-all-active-cpus(L) show-memory-usage(M) nice-all-RT-tasks(N) powerOff show-registers(P) show-all-timers(Q) unRaw Sync show-task-states(T) Unmount show-blocked-tasks(W) dump-ftrace-buffer(Z)
+
+On the client/console system do::
+
+       cat /dev/ttyUSB0
+
+And you should see the help line above displayed shortly after you've
+provoked it on the host system.
+
+If it does not work then please ask about it on the linux-kernel@vger.kernel.org
+mailing list or contact the x86 maintainers.
diff --git a/Documentation/arch/x86/elf_auxvec.rst b/Documentation/arch/x86/elf_auxvec.rst
new file mode 100644 (file)
index 0000000..18e4744
--- /dev/null
@@ -0,0 +1,53 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==================================
+x86-specific ELF Auxiliary Vectors
+==================================
+
+This document describes the semantics of the x86 auxiliary vectors.
+
+Introduction
+============
+
+ELF Auxiliary vectors enable the kernel to efficiently provide
+configuration-specific parameters to userspace. In this example, a program
+allocates an alternate stack based on the kernel-provided size::
+
+   #include <sys/auxv.h>
+   #include <elf.h>
+   #include <signal.h>
+   #include <stdlib.h>
+   #include <assert.h>
+   #include <err.h>
+
+   #ifndef AT_MINSIGSTKSZ
+   #define AT_MINSIGSTKSZ      51
+   #endif
+
+   ....
+   stack_t ss;
+
+   ss.ss_sp = malloc(ss.ss_size);
+   assert(ss.ss_sp);
+
+   ss.ss_size = getauxval(AT_MINSIGSTKSZ) + SIGSTKSZ;
+   ss.ss_flags = 0;
+
+   if (sigaltstack(&ss, NULL))
+        err(1, "sigaltstack");
+
+
+The exposed auxiliary vectors
+=============================
+
+AT_SYSINFO is used for locating the vsyscall entry point.  It is not
+exported on 64-bit mode.
+
+AT_SYSINFO_EHDR is the start address of the page containing the vDSO.
+
+AT_MINSIGSTKSZ denotes the minimum stack size required by the kernel to
+deliver a signal to user-space.  AT_MINSIGSTKSZ comprehends the space
+consumed by the kernel to accommodate the user context for the current
+hardware configuration.  It does not comprehend subsequent user-space stack
+consumption, which must be added by the user.  (e.g. Above, user-space adds
+SIGSTKSZ to AT_MINSIGSTKSZ.)
diff --git a/Documentation/arch/x86/entry_64.rst b/Documentation/arch/x86/entry_64.rst
new file mode 100644 (file)
index 0000000..0afdce3
--- /dev/null
@@ -0,0 +1,110 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==============
+Kernel Entries
+==============
+
+This file documents some of the kernel entries in
+arch/x86/entry/entry_64.S.  A lot of this explanation is adapted from
+an email from Ingo Molnar:
+
+https://lore.kernel.org/r/20110529191055.GC9835%40elte.hu
+
+The x86 architecture has quite a few different ways to jump into
+kernel code.  Most of these entry points are registered in
+arch/x86/kernel/traps.c and implemented in arch/x86/entry/entry_64.S
+for 64-bit, arch/x86/entry/entry_32.S for 32-bit and finally
+arch/x86/entry/entry_64_compat.S which implements the 32-bit compatibility
+syscall entry points and thus provides for 32-bit processes the
+ability to execute syscalls when running on 64-bit kernels.
+
+The IDT vector assignments are listed in arch/x86/include/asm/irq_vectors.h.
+
+Some of these entries are:
+
+ - system_call: syscall instruction from 64-bit code.
+
+ - entry_INT80_compat: int 0x80 from 32-bit or 64-bit code; compat syscall
+   either way.
+
+ - entry_INT80_compat, ia32_sysenter: syscall and sysenter from 32-bit
+   code
+
+ - interrupt: An array of entries.  Every IDT vector that doesn't
+   explicitly point somewhere else gets set to the corresponding
+   value in interrupts.  These point to a whole array of
+   magically-generated functions that make their way to common_interrupt()
+   with the interrupt number as a parameter.
+
+ - APIC interrupts: Various special-purpose interrupts for things
+   like TLB shootdown.
+
+ - Architecturally-defined exceptions like divide_error.
+
+There are a few complexities here.  The different x86-64 entries
+have different calling conventions.  The syscall and sysenter
+instructions have their own peculiar calling conventions.  Some of
+the IDT entries push an error code onto the stack; others don't.
+IDT entries using the IST alternative stack mechanism need their own
+magic to get the stack frames right.  (You can find some
+documentation in the AMD APM, Volume 2, Chapter 8 and the Intel SDM,
+Volume 3, Chapter 6.)
+
+Dealing with the swapgs instruction is especially tricky.  Swapgs
+toggles whether gs is the kernel gs or the user gs.  The swapgs
+instruction is rather fragile: it must nest perfectly and only in
+single depth, it should only be used if entering from user mode to
+kernel mode and then when returning to user-space, and precisely
+so. If we mess that up even slightly, we crash.
+
+So when we have a secondary entry, already in kernel mode, we *must
+not* use SWAPGS blindly - nor must we forget doing a SWAPGS when it's
+not switched/swapped yet.
+
+Now, there's a secondary complication: there's a cheap way to test
+which mode the CPU is in and an expensive way.
+
+The cheap way is to pick this info off the entry frame on the kernel
+stack, from the CS of the ptregs area of the kernel stack::
+
+       xorl %ebx,%ebx
+       testl $3,CS+8(%rsp)
+       je error_kernelspace
+       SWAPGS
+
+The expensive (paranoid) way is to read back the MSR_GS_BASE value
+(which is what SWAPGS modifies)::
+
+       movl $1,%ebx
+       movl $MSR_GS_BASE,%ecx
+       rdmsr
+       testl %edx,%edx
+       js 1f   /* negative -> in kernel */
+       SWAPGS
+       xorl %ebx,%ebx
+  1:   ret
+
+If we are at an interrupt or user-trap/gate-alike boundary then we can
+use the faster check: the stack will be a reliable indicator of
+whether SWAPGS was already done: if we see that we are a secondary
+entry interrupting kernel mode execution, then we know that the GS
+base has already been switched. If it says that we interrupted
+user-space execution then we must do the SWAPGS.
+
+But if we are in an NMI/MCE/DEBUG/whatever super-atomic entry context,
+which might have triggered right after a normal entry wrote CS to the
+stack but before we executed SWAPGS, then the only safe way to check
+for GS is the slower method: the RDMSR.
+
+Therefore, super-atomic entries (except NMI, which is handled separately)
+must use idtentry with paranoid=1 to handle gsbase correctly.  This
+triggers three main behavior changes:
+
+ - Interrupt entry will use the slower gsbase check.
+ - Interrupt entry from user mode will switch off the IST stack.
+ - Interrupt exit to kernel mode will not attempt to reschedule.
+
+We try to only use IST entries and the paranoid entry code for vectors
+that absolutely need the more expensive check for the GS base - and we
+generate all 'normal' entry points with the regular (faster) paranoid=0
+variant.
diff --git a/Documentation/arch/x86/exception-tables.rst b/Documentation/arch/x86/exception-tables.rst
new file mode 100644 (file)
index 0000000..efde1fe
--- /dev/null
@@ -0,0 +1,357 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===============================
+Kernel level exception handling
+===============================
+
+Commentary by Joerg Pommnitz <joerg@raleigh.ibm.com>
+
+When a process runs in kernel mode, it often has to access user
+mode memory whose address has been passed by an untrusted program.
+To protect itself the kernel has to verify this address.
+
+In older versions of Linux this was done with the
+int verify_area(int type, const void * addr, unsigned long size)
+function (which has since been replaced by access_ok()).
+
+This function verified that the memory area starting at address
+'addr' and of size 'size' was accessible for the operation specified
+in type (read or write). To do this, verify_read had to look up the
+virtual memory area (vma) that contained the address addr. In the
+normal case (correctly working program), this test was successful.
+It only failed for a few buggy programs. In some kernel profiling
+tests, this normally unneeded verification used up a considerable
+amount of time.
+
+To overcome this situation, Linus decided to let the virtual memory
+hardware present in every Linux-capable CPU handle this test.
+
+How does this work?
+
+Whenever the kernel tries to access an address that is currently not
+accessible, the CPU generates a page fault exception and calls the
+page fault handler::
+
+  void exc_page_fault(struct pt_regs *regs, unsigned long error_code)
+
+in arch/x86/mm/fault.c. The parameters on the stack are set up by
+the low level assembly glue in arch/x86/entry/entry_32.S. The parameter
+regs is a pointer to the saved registers on the stack, error_code
+contains a reason code for the exception.
+
+exc_page_fault() first obtains the inaccessible address from the CPU
+control register CR2. If the address is within the virtual address
+space of the process, the fault probably occurred, because the page
+was not swapped in, write protected or something similar. However,
+we are interested in the other case: the address is not valid, there
+is no vma that contains this address. In this case, the kernel jumps
+to the bad_area label.
+
+There it uses the address of the instruction that caused the exception
+(i.e. regs->eip) to find an address where the execution can continue
+(fixup). If this search is successful, the fault handler modifies the
+return address (again regs->eip) and returns. The execution will
+continue at the address in fixup.
+
+Where does fixup point to?
+
+Since we jump to the contents of fixup, fixup obviously points
+to executable code. This code is hidden inside the user access macros.
+I have picked the get_user() macro defined in arch/x86/include/asm/uaccess.h
+as an example. The definition is somewhat hard to follow, so let's peek at
+the code generated by the preprocessor and the compiler. I selected
+the get_user() call in drivers/char/sysrq.c for a detailed examination.
+
+The original code in sysrq.c line 587::
+
+        get_user(c, buf);
+
+The preprocessor output (edited to become somewhat readable)::
+
+  (
+    {
+      long __gu_err = - 14 , __gu_val = 0;
+      const __typeof__(*( (  buf ) )) *__gu_addr = ((buf));
+      if (((((0 + current_set[0])->tss.segment) == 0x18 )  ||
+        (((sizeof(*(buf))) <= 0xC0000000UL) &&
+        ((unsigned long)(__gu_addr ) <= 0xC0000000UL - (sizeof(*(buf)))))))
+        do {
+          __gu_err  = 0;
+          switch ((sizeof(*(buf)))) {
+            case 1:
+              __asm__ __volatile__(
+                "1:      mov" "b" " %2,%" "b" "1\n"
+                "2:\n"
+                ".section .fixup,\"ax\"\n"
+                "3:      movl %3,%0\n"
+                "        xor" "b" " %" "b" "1,%" "b" "1\n"
+                "        jmp 2b\n"
+                ".section __ex_table,\"a\"\n"
+                "        .align 4\n"
+                "        .long 1b,3b\n"
+                ".text"        : "=r"(__gu_err), "=q" (__gu_val): "m"((*(struct __large_struct *)
+                              (   __gu_addr   )) ), "i"(- 14 ), "0"(  __gu_err  )) ;
+                break;
+            case 2:
+              __asm__ __volatile__(
+                "1:      mov" "w" " %2,%" "w" "1\n"
+                "2:\n"
+                ".section .fixup,\"ax\"\n"
+                "3:      movl %3,%0\n"
+                "        xor" "w" " %" "w" "1,%" "w" "1\n"
+                "        jmp 2b\n"
+                ".section __ex_table,\"a\"\n"
+                "        .align 4\n"
+                "        .long 1b,3b\n"
+                ".text"        : "=r"(__gu_err), "=r" (__gu_val) : "m"((*(struct __large_struct *)
+                              (   __gu_addr   )) ), "i"(- 14 ), "0"(  __gu_err  ));
+                break;
+            case 4:
+              __asm__ __volatile__(
+                "1:      mov" "l" " %2,%" "" "1\n"
+                "2:\n"
+                ".section .fixup,\"ax\"\n"
+                "3:      movl %3,%0\n"
+                "        xor" "l" " %" "" "1,%" "" "1\n"
+                "        jmp 2b\n"
+                ".section __ex_table,\"a\"\n"
+                "        .align 4\n"        "        .long 1b,3b\n"
+                ".text"        : "=r"(__gu_err), "=r" (__gu_val) : "m"((*(struct __large_struct *)
+                              (   __gu_addr   )) ), "i"(- 14 ), "0"(__gu_err));
+                break;
+            default:
+              (__gu_val) = __get_user_bad();
+          }
+        } while (0) ;
+      ((c)) = (__typeof__(*((buf))))__gu_val;
+      __gu_err;
+    }
+  );
+
+WOW! Black GCC/assembly magic. This is impossible to follow, so let's
+see what code gcc generates::
+
+ >         xorl %edx,%edx
+ >         movl current_set,%eax
+ >         cmpl $24,788(%eax)
+ >         je .L1424
+ >         cmpl $-1073741825,64(%esp)
+ >         ja .L1423
+ > .L1424:
+ >         movl %edx,%eax
+ >         movl 64(%esp),%ebx
+ > #APP
+ > 1:      movb (%ebx),%dl                /* this is the actual user access */
+ > 2:
+ > .section .fixup,"ax"
+ > 3:      movl $-14,%eax
+ >         xorb %dl,%dl
+ >         jmp 2b
+ > .section __ex_table,"a"
+ >         .align 4
+ >         .long 1b,3b
+ > .text
+ > #NO_APP
+ > .L1423:
+ >         movzbl %dl,%esi
+
+The optimizer does a good job and gives us something we can actually
+understand. Can we? The actual user access is quite obvious. Thanks
+to the unified address space we can just access the address in user
+memory. But what does the .section stuff do?????
+
+To understand this we have to look at the final kernel::
+
+ > objdump --section-headers vmlinux
+ >
+ > vmlinux:     file format elf32-i386
+ >
+ > Sections:
+ > Idx Name          Size      VMA       LMA       File off  Algn
+ >   0 .text         00098f40  c0100000  c0100000  00001000  2**4
+ >                   CONTENTS, ALLOC, LOAD, READONLY, CODE
+ >   1 .fixup        000016bc  c0198f40  c0198f40  00099f40  2**0
+ >                   CONTENTS, ALLOC, LOAD, READONLY, CODE
+ >   2 .rodata       0000f127  c019a5fc  c019a5fc  0009b5fc  2**2
+ >                   CONTENTS, ALLOC, LOAD, READONLY, DATA
+ >   3 __ex_table    000015c0  c01a9724  c01a9724  000aa724  2**2
+ >                   CONTENTS, ALLOC, LOAD, READONLY, DATA
+ >   4 .data         0000ea58  c01abcf0  c01abcf0  000abcf0  2**4
+ >                   CONTENTS, ALLOC, LOAD, DATA
+ >   5 .bss          00018e21  c01ba748  c01ba748  000ba748  2**2
+ >                   ALLOC
+ >   6 .comment      00000ec4  00000000  00000000  000ba748  2**0
+ >                   CONTENTS, READONLY
+ >   7 .note         00001068  00000ec4  00000ec4  000bb60c  2**0
+ >                   CONTENTS, READONLY
+
+There are obviously 2 non standard ELF sections in the generated object
+file. But first we want to find out what happened to our code in the
+final kernel executable::
+
+ > objdump --disassemble --section=.text vmlinux
+ >
+ > c017e785 <do_con_write+c1> xorl   %edx,%edx
+ > c017e787 <do_con_write+c3> movl   0xc01c7bec,%eax
+ > c017e78c <do_con_write+c8> cmpl   $0x18,0x314(%eax)
+ > c017e793 <do_con_write+cf> je     c017e79f <do_con_write+db>
+ > c017e795 <do_con_write+d1> cmpl   $0xbfffffff,0x40(%esp,1)
+ > c017e79d <do_con_write+d9> ja     c017e7a7 <do_con_write+e3>
+ > c017e79f <do_con_write+db> movl   %edx,%eax
+ > c017e7a1 <do_con_write+dd> movl   0x40(%esp,1),%ebx
+ > c017e7a5 <do_con_write+e1> movb   (%ebx),%dl
+ > c017e7a7 <do_con_write+e3> movzbl %dl,%esi
+
+The whole user memory access is reduced to 10 x86 machine instructions.
+The instructions bracketed in the .section directives are no longer
+in the normal execution path. They are located in a different section
+of the executable file::
+
+ > objdump --disassemble --section=.fixup vmlinux
+ >
+ > c0199ff5 <.fixup+10b5> movl   $0xfffffff2,%eax
+ > c0199ffa <.fixup+10ba> xorb   %dl,%dl
+ > c0199ffc <.fixup+10bc> jmp    c017e7a7 <do_con_write+e3>
+
+And finally::
+
+ > objdump --full-contents --section=__ex_table vmlinux
+ >
+ >  c01aa7c4 93c017c0 e09f19c0 97c017c0 99c017c0  ................
+ >  c01aa7d4 f6c217c0 e99f19c0 a5e717c0 f59f19c0  ................
+ >  c01aa7e4 080a18c0 01a019c0 0a0a18c0 04a019c0  ................
+
+or in human readable byte order::
+
+ >  c01aa7c4 c017c093 c0199fe0 c017c097 c017c099  ................
+ >  c01aa7d4 c017c2f6 c0199fe9 c017e7a5 c0199ff5  ................
+                               ^^^^^^^^^^^^^^^^^
+                               this is the interesting part!
+ >  c01aa7e4 c0180a08 c019a001 c0180a0a c019a004  ................
+
+What happened? The assembly directives::
+
+  .section .fixup,"ax"
+  .section __ex_table,"a"
+
+told the assembler to move the following code to the specified
+sections in the ELF object file. So the instructions::
+
+  3:      movl $-14,%eax
+          xorb %dl,%dl
+          jmp 2b
+
+ended up in the .fixup section of the object file and the addresses::
+
+        .long 1b,3b
+
+ended up in the __ex_table section of the object file. 1b and 3b
+are local labels. The local label 1b (1b stands for next label 1
+backward) is the address of the instruction that might fault, i.e.
+in our case the address of the label 1 is c017e7a5:
+the original assembly code: > 1:      movb (%ebx),%dl
+and linked in vmlinux     : > c017e7a5 <do_con_write+e1> movb   (%ebx),%dl
+
+The local label 3 (backwards again) is the address of the code to handle
+the fault, in our case the actual value is c0199ff5:
+the original assembly code: > 3:      movl $-14,%eax
+and linked in vmlinux     : > c0199ff5 <.fixup+10b5> movl   $0xfffffff2,%eax
+
+If the fixup was able to handle the exception, control flow may be returned
+to the instruction after the one that triggered the fault, ie. local label 2b.
+
+The assembly code::
+
+ > .section __ex_table,"a"
+ >         .align 4
+ >         .long 1b,3b
+
+becomes the value pair::
+
+ >  c01aa7d4 c017c2f6 c0199fe9 c017e7a5 c0199ff5  ................
+                               ^this is ^this is
+                               1b       3b
+
+c017e7a5,c0199ff5 in the exception table of the kernel.
+
+So, what actually happens if a fault from kernel mode with no suitable
+vma occurs?
+
+#. access to invalid address::
+
+    > c017e7a5 <do_con_write+e1> movb   (%ebx),%dl
+#. MMU generates exception
+#. CPU calls exc_page_fault()
+#. exc_page_fault() calls do_user_addr_fault()
+#. do_user_addr_fault() calls kernelmode_fixup_or_oops()
+#. kernelmode_fixup_or_oops() calls fixup_exception() (regs->eip == c017e7a5);
+#. fixup_exception() calls search_exception_tables()
+#. search_exception_tables() looks up the address c017e7a5 in the
+   exception table (i.e. the contents of the ELF section __ex_table)
+   and returns the address of the associated fault handle code c0199ff5.
+#. fixup_exception() modifies its own return address to point to the fault
+   handle code and returns.
+#. execution continues in the fault handling code.
+#. a) EAX becomes -EFAULT (== -14)
+   b) DL  becomes zero (the value we "read" from user space)
+   c) execution continues at local label 2 (address of the
+      instruction immediately after the faulting user access).
+
+The steps 8a to 8c in a certain way emulate the faulting instruction.
+
+That's it, mostly. If you look at our example, you might ask why
+we set EAX to -EFAULT in the exception handler code. Well, the
+get_user() macro actually returns a value: 0, if the user access was
+successful, -EFAULT on failure. Our original code did not test this
+return value, however the inline assembly code in get_user() tries to
+return -EFAULT. GCC selected EAX to return this value.
+
+NOTE:
+Due to the way that the exception table is built and needs to be ordered,
+only use exceptions for code in the .text section.  Any other section
+will cause the exception table to not be sorted correctly, and the
+exceptions will fail.
+
+Things changed when 64-bit support was added to x86 Linux. Rather than
+double the size of the exception table by expanding the two entries
+from 32-bits to 64 bits, a clever trick was used to store addresses
+as relative offsets from the table itself. The assembly code changed
+from::
+
+    .long 1b,3b
+  to:
+          .long (from) - .
+          .long (to) - .
+
+and the C-code that uses these values converts back to absolute addresses
+like this::
+
+       ex_insn_addr(const struct exception_table_entry *x)
+       {
+               return (unsigned long)&x->insn + x->insn;
+       }
+
+In v4.6 the exception table entry was expanded with a new field "handler".
+This is also 32-bits wide and contains a third relative function
+pointer which points to one of:
+
+1) ``int ex_handler_default(const struct exception_table_entry *fixup)``
+     This is legacy case that just jumps to the fixup code
+
+2) ``int ex_handler_fault(const struct exception_table_entry *fixup)``
+     This case provides the fault number of the trap that occurred at
+     entry->insn. It is used to distinguish page faults from machine
+     check.
+
+More functions can easily be added.
+
+CONFIG_BUILDTIME_TABLE_SORT allows the __ex_table section to be sorted post
+link of the kernel image, via a host utility scripts/sorttable. It will set the
+symbol main_extable_sort_needed to 0, avoiding sorting the __ex_table section
+at boot time. With the exception table sorted, at runtime when an exception
+occurs we can quickly lookup the __ex_table entry via binary search.
+
+This is not just a boot time optimization, some architectures require this
+table to be sorted in order to handle exceptions relatively early in the boot
+process. For example, i386 makes use of this form of exception handling before
+paging support is even enabled!
diff --git a/Documentation/arch/x86/features.rst b/Documentation/arch/x86/features.rst
new file mode 100644 (file)
index 0000000..b663f15
--- /dev/null
@@ -0,0 +1,3 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. kernel-feat:: $srctree/Documentation/features x86
diff --git a/Documentation/arch/x86/i386/IO-APIC.rst b/Documentation/arch/x86/i386/IO-APIC.rst
new file mode 100644 (file)
index 0000000..ce4d8df
--- /dev/null
@@ -0,0 +1,123 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=======
+IO-APIC
+=======
+
+:Author: Ingo Molnar <mingo@kernel.org>
+
+Most (all) Intel-MP compliant SMP boards have the so-called 'IO-APIC',
+which is an enhanced interrupt controller. It enables us to route
+hardware interrupts to multiple CPUs, or to CPU groups. Without an
+IO-APIC, interrupts from hardware will be delivered only to the
+CPU which boots the operating system (usually CPU#0).
+
+Linux supports all variants of compliant SMP boards, including ones with
+multiple IO-APICs. Multiple IO-APICs are used in high-end servers to
+distribute IRQ load further.
+
+There are (a few) known breakages in certain older boards, such bugs are
+usually worked around by the kernel. If your MP-compliant SMP board does
+not boot Linux, then consult the linux-smp mailing list archives first.
+
+If your box boots fine with enabled IO-APIC IRQs, then your
+/proc/interrupts will look like this one::
+
+  hell:~> cat /proc/interrupts
+             CPU0
+    0:    1360293    IO-APIC-edge  timer
+    1:          4    IO-APIC-edge  keyboard
+    2:          0          XT-PIC  cascade
+   13:          1          XT-PIC  fpu
+   14:       1448    IO-APIC-edge  ide0
+   16:      28232   IO-APIC-level  Intel EtherExpress Pro 10/100 Ethernet
+   17:      51304   IO-APIC-level  eth0
+  NMI:          0
+  ERR:          0
+  hell:~>
+
+Some interrupts are still listed as 'XT PIC', but this is not a problem;
+none of those IRQ sources is performance-critical.
+
+
+In the unlikely case that your board does not create a working mp-table,
+you can use the pirq= boot parameter to 'hand-construct' IRQ entries. This
+is non-trivial though and cannot be automated. One sample /etc/lilo.conf
+entry::
+
+       append="pirq=15,11,10"
+
+The actual numbers depend on your system, on your PCI cards and on their
+PCI slot position. Usually PCI slots are 'daisy chained' before they are
+connected to the PCI chipset IRQ routing facility (the incoming PIRQ1-4
+lines)::
+
+               ,-.        ,-.        ,-.        ,-.        ,-.
+     PIRQ4 ----| |-.    ,-| |-.    ,-| |-.    ,-| |--------| |
+               |S|  \  /  |S|  \  /  |S|  \  /  |S|        |S|
+     PIRQ3 ----|l|-. `/---|l|-. `/---|l|-. `/---|l|--------|l|
+               |o|  \/    |o|  \/    |o|  \/    |o|        |o|
+     PIRQ2 ----|t|-./`----|t|-./`----|t|-./`----|t|--------|t|
+               |1| /\     |2| /\     |3| /\     |4|        |5|
+     PIRQ1 ----| |-  `----| |-  `----| |-  `----| |--------| |
+               `-'        `-'        `-'        `-'        `-'
+
+Every PCI card emits a PCI IRQ, which can be INTA, INTB, INTC or INTD::
+
+                               ,-.
+                         INTD--| |
+                               |S|
+                         INTC--|l|
+                               |o|
+                         INTB--|t|
+                               |x|
+                         INTA--| |
+                               `-'
+
+These INTA-D PCI IRQs are always 'local to the card', their real meaning
+depends on which slot they are in. If you look at the daisy chaining diagram,
+a card in slot4, issuing INTA IRQ, it will end up as a signal on PIRQ4 of
+the PCI chipset. Most cards issue INTA, this creates optimal distribution
+between the PIRQ lines. (distributing IRQ sources properly is not a
+necessity, PCI IRQs can be shared at will, but it's a good for performance
+to have non shared interrupts). Slot5 should be used for videocards, they
+do not use interrupts normally, thus they are not daisy chained either.
+
+so if you have your SCSI card (IRQ11) in Slot1, Tulip card (IRQ9) in
+Slot2, then you'll have to specify this pirq= line::
+
+       append="pirq=11,9"
+
+the following script tries to figure out such a default pirq= line from
+your PCI configuration::
+
+       echo -n pirq=; echo `scanpci | grep T_L | cut -c56-` | sed 's/ /,/g'
+
+note that this script won't work if you have skipped a few slots or if your
+board does not do default daisy-chaining. (or the IO-APIC has the PIRQ pins
+connected in some strange way). E.g. if in the above case you have your SCSI
+card (IRQ11) in Slot3, and have Slot1 empty::
+
+       append="pirq=0,9,11"
+
+[value '0' is a generic 'placeholder', reserved for empty (or non-IRQ emitting)
+slots.]
+
+Generally, it's always possible to find out the correct pirq= settings, just
+permute all IRQ numbers properly ... it will take some time though. An
+'incorrect' pirq line will cause the booting process to hang, or a device
+won't function properly (e.g. if it's inserted as a module).
+
+If you have 2 PCI buses, then you can use up to 8 pirq values, although such
+boards tend to have a good configuration.
+
+Be prepared that it might happen that you need some strange pirq line::
+
+       append="pirq=0,0,0,0,0,0,9,11"
+
+Use smart trial-and-error techniques to find out the correct pirq line ...
+
+Good luck and mail to linux-smp@vger.kernel.org or
+linux-kernel@vger.kernel.org if you have any problems that are not covered
+by this document.
+
diff --git a/Documentation/arch/x86/i386/index.rst b/Documentation/arch/x86/i386/index.rst
new file mode 100644 (file)
index 0000000..8747cf5
--- /dev/null
@@ -0,0 +1,10 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============
+i386 Support
+============
+
+.. toctree::
+   :maxdepth: 2
+
+   IO-APIC
diff --git a/Documentation/arch/x86/ifs.rst b/Documentation/arch/x86/ifs.rst
new file mode 100644 (file)
index 0000000..97abb69
--- /dev/null
@@ -0,0 +1,2 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. kernel-doc:: drivers/platform/x86/intel/ifs/ifs.h
diff --git a/Documentation/arch/x86/index.rst b/Documentation/arch/x86/index.rst
new file mode 100644 (file)
index 0000000..c73d133
--- /dev/null
@@ -0,0 +1,44 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==========================
+x86-specific Documentation
+==========================
+
+.. toctree::
+   :maxdepth: 2
+   :numbered:
+
+   boot
+   booting-dt
+   cpuinfo
+   topology
+   exception-tables
+   kernel-stacks
+   entry_64
+   earlyprintk
+   orc-unwinder
+   zero-page
+   tlb
+   mtrr
+   pat
+   intel-hfi
+   iommu
+   intel_txt
+   amd-memory-encryption
+   amd_hsmp
+   tdx
+   pti
+   mds
+   microcode
+   resctrl
+   tsx_async_abort
+   buslock
+   usb-legacy-support
+   i386/index
+   x86_64/index
+   ifs
+   sva
+   sgx
+   features
+   elf_auxvec
+   xstate
diff --git a/Documentation/arch/x86/intel-hfi.rst b/Documentation/arch/x86/intel-hfi.rst
new file mode 100644 (file)
index 0000000..49dea58
--- /dev/null
@@ -0,0 +1,72 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============================================================
+Hardware-Feedback Interface for scheduling on Intel Hardware
+============================================================
+
+Overview
+--------
+
+Intel has described the Hardware Feedback Interface (HFI) in the Intel 64 and
+IA-32 Architectures Software Developer's Manual (Intel SDM) Volume 3 Section
+14.6 [1]_.
+
+The HFI gives the operating system a performance and energy efficiency
+capability data for each CPU in the system. Linux can use the information from
+the HFI to influence task placement decisions.
+
+The Hardware Feedback Interface
+-------------------------------
+
+The Hardware Feedback Interface provides to the operating system information
+about the performance and energy efficiency of each CPU in the system. Each
+capability is given as a unit-less quantity in the range [0-255]. Higher values
+indicate higher capability. Energy efficiency and performance are reported in
+separate capabilities. Even though on some systems these two metrics may be
+related, they are specified as independent capabilities in the Intel SDM.
+
+These capabilities may change at runtime as a result of changes in the
+operating conditions of the system or the action of external factors. The rate
+at which these capabilities are updated is specific to each processor model. On
+some models, capabilities are set at boot time and never change. On others,
+capabilities may change every tens of milliseconds. For instance, a remote
+mechanism may be used to lower Thermal Design Power. Such change can be
+reflected in the HFI. Likewise, if the system needs to be throttled due to
+excessive heat, the HFI may reflect reduced performance on specific CPUs.
+
+The kernel or a userspace policy daemon can use these capabilities to modify
+task placement decisions. For instance, if either the performance or energy
+capabilities of a given logical processor becomes zero, it is an indication that
+the hardware recommends to the operating system to not schedule any tasks on
+that processor for performance or energy efficiency reasons, respectively.
+
+Implementation details for Linux
+--------------------------------
+
+The infrastructure to handle thermal event interrupts has two parts. In the
+Local Vector Table of a CPU's local APIC, there exists a register for the
+Thermal Monitor Register. This register controls how interrupts are delivered
+to a CPU when the thermal monitor generates and interrupt. Further details
+can be found in the Intel SDM Vol. 3 Section 10.5 [1]_.
+
+The thermal monitor may generate interrupts per CPU or per package. The HFI
+generates package-level interrupts. This monitor is configured and initialized
+via a set of machine-specific registers. Specifically, the HFI interrupt and
+status are controlled via designated bits in the IA32_PACKAGE_THERM_INTERRUPT
+and IA32_PACKAGE_THERM_STATUS registers, respectively. There exists one HFI
+table per package. Further details can be found in the Intel SDM Vol. 3
+Section 14.9 [1]_.
+
+The hardware issues an HFI interrupt after updating the HFI table and is ready
+for the operating system to consume it. CPUs receive such interrupt via the
+thermal entry in the Local APIC's Local Vector Table.
+
+When servicing such interrupt, the HFI driver parses the updated table and
+relays the update to userspace using the thermal notification framework. Given
+that there may be many HFI updates every second, the updates relayed to
+userspace are throttled at a rate of CONFIG_HZ jiffies.
+
+References
+----------
+
+.. [1] https://www.intel.com/sdm
diff --git a/Documentation/arch/x86/intel_txt.rst b/Documentation/arch/x86/intel_txt.rst
new file mode 100644 (file)
index 0000000..d83c1a2
--- /dev/null
@@ -0,0 +1,227 @@
+=====================
+Intel(R) TXT Overview
+=====================
+
+Intel's technology for safer computing, Intel(R) Trusted Execution
+Technology (Intel(R) TXT), defines platform-level enhancements that
+provide the building blocks for creating trusted platforms.
+
+Intel TXT was formerly known by the code name LaGrande Technology (LT).
+
+Intel TXT in Brief:
+
+-  Provides dynamic root of trust for measurement (DRTM)
+-  Data protection in case of improper shutdown
+-  Measurement and verification of launched environment
+
+Intel TXT is part of the vPro(TM) brand and is also available some
+non-vPro systems.  It is currently available on desktop systems
+based on the Q35, X38, Q45, and Q43 Express chipsets (e.g. Dell
+Optiplex 755, HP dc7800, etc.) and mobile systems based on the GM45,
+PM45, and GS45 Express chipsets.
+
+For more information, see http://www.intel.com/technology/security/.
+This site also has a link to the Intel TXT MLE Developers Manual,
+which has been updated for the new released platforms.
+
+Intel TXT has been presented at various events over the past few
+years, some of which are:
+
+      - LinuxTAG 2008:
+          http://www.linuxtag.org/2008/en/conf/events/vp-donnerstag.html
+
+      - TRUST2008:
+          http://www.trust-conference.eu/downloads/Keynote-Speakers/
+          3_David-Grawrock_The-Front-Door-of-Trusted-Computing.pdf
+
+      - IDF, Shanghai:
+          http://www.prcidf.com.cn/index_en.html
+
+      - IDFs 2006, 2007
+         (I'm not sure if/where they are online)
+
+Trusted Boot Project Overview
+=============================
+
+Trusted Boot (tboot) is an open source, pre-kernel/VMM module that
+uses Intel TXT to perform a measured and verified launch of an OS
+kernel/VMM.
+
+It is hosted on SourceForge at http://sourceforge.net/projects/tboot.
+The mercurial source repo is available at http://www.bughost.org/
+repos.hg/tboot.hg.
+
+Tboot currently supports launching Xen (open source VMM/hypervisor
+w/ TXT support since v3.2), and now Linux kernels.
+
+
+Value Proposition for Linux or "Why should you care?"
+=====================================================
+
+While there are many products and technologies that attempt to
+measure or protect the integrity of a running kernel, they all
+assume the kernel is "good" to begin with.  The Integrity
+Measurement Architecture (IMA) and Linux Integrity Module interface
+are examples of such solutions.
+
+To get trust in the initial kernel without using Intel TXT, a
+static root of trust must be used.  This bases trust in BIOS
+starting at system reset and requires measurement of all code
+executed between system reset through the completion of the kernel
+boot as well as data objects used by that code.  In the case of a
+Linux kernel, this means all of BIOS, any option ROMs, the
+bootloader and the boot config.  In practice, this is a lot of
+code/data, much of which is subject to change from boot to boot
+(e.g. changing NICs may change option ROMs).  Without reference
+hashes, these measurement changes are difficult to assess or
+confirm as benign.  This process also does not provide DMA
+protection, memory configuration/alias checks and locks, crash
+protection, or policy support.
+
+By using the hardware-based root of trust that Intel TXT provides,
+many of these issues can be mitigated.  Specifically: many
+pre-launch components can be removed from the trust chain, DMA
+protection is provided to all launched components, a large number
+of platform configuration checks are performed and values locked,
+protection is provided for any data in the event of an improper
+shutdown, and there is support for policy-based execution/verification.
+This provides a more stable measurement and a higher assurance of
+system configuration and initial state than would be otherwise
+possible.  Since the tboot project is open source, source code for
+almost all parts of the trust chain is available (excepting SMM and
+Intel-provided firmware).
+
+How Does it Work?
+=================
+
+-  Tboot is an executable that is launched by the bootloader as
+   the "kernel" (the binary the bootloader executes).
+-  It performs all of the work necessary to determine if the
+   platform supports Intel TXT and, if so, executes the GETSEC[SENTER]
+   processor instruction that initiates the dynamic root of trust.
+
+   -  If tboot determines that the system does not support Intel TXT
+      or is not configured correctly (e.g. the SINIT AC Module was
+      incorrect), it will directly launch the kernel with no changes
+      to any state.
+   -  Tboot will output various information about its progress to the
+      terminal, serial port, and/or an in-memory log; the output
+      locations can be configured with a command line switch.
+
+-  The GETSEC[SENTER] instruction will return control to tboot and
+   tboot then verifies certain aspects of the environment (e.g. TPM NV
+   lock, e820 table does not have invalid entries, etc.).
+-  It will wake the APs from the special sleep state the GETSEC[SENTER]
+   instruction had put them in and place them into a wait-for-SIPI
+   state.
+
+   -  Because the processors will not respond to an INIT or SIPI when
+      in the TXT environment, it is necessary to create a small VT-x
+      guest for the APs.  When they run in this guest, they will
+      simply wait for the INIT-SIPI-SIPI sequence, which will cause
+      VMEXITs, and then disable VT and jump to the SIPI vector.  This
+      approach seemed like a better choice than having to insert
+      special code into the kernel's MP wakeup sequence.
+
+-  Tboot then applies an (optional) user-defined launch policy to
+   verify the kernel and initrd.
+
+   -  This policy is rooted in TPM NV and is described in the tboot
+      project.  The tboot project also contains code for tools to
+      create and provision the policy.
+   -  Policies are completely under user control and if not present
+      then any kernel will be launched.
+   -  Policy action is flexible and can include halting on failures
+      or simply logging them and continuing.
+
+-  Tboot adjusts the e820 table provided by the bootloader to reserve
+   its own location in memory as well as to reserve certain other
+   TXT-related regions.
+-  As part of its launch, tboot DMA protects all of RAM (using the
+   VT-d PMRs).  Thus, the kernel must be booted with 'intel_iommu=on'
+   in order to remove this blanket protection and use VT-d's
+   page-level protection.
+-  Tboot will populate a shared page with some data about itself and
+   pass this to the Linux kernel as it transfers control.
+
+   -  The location of the shared page is passed via the boot_params
+      struct as a physical address.
+
+-  The kernel will look for the tboot shared page address and, if it
+   exists, map it.
+-  As one of the checks/protections provided by TXT, it makes a copy
+   of the VT-d DMARs in a DMA-protected region of memory and verifies
+   them for correctness.  The VT-d code will detect if the kernel was
+   launched with tboot and use this copy instead of the one in the
+   ACPI table.
+-  At this point, tboot and TXT are out of the picture until a
+   shutdown (S<n>)
+-  In order to put a system into any of the sleep states after a TXT
+   launch, TXT must first be exited.  This is to prevent attacks that
+   attempt to crash the system to gain control on reboot and steal
+   data left in memory.
+
+   -  The kernel will perform all of its sleep preparation and
+      populate the shared page with the ACPI data needed to put the
+      platform in the desired sleep state.
+   -  Then the kernel jumps into tboot via the vector specified in the
+      shared page.
+   -  Tboot will clean up the environment and disable TXT, then use the
+      kernel-provided ACPI information to actually place the platform
+      into the desired sleep state.
+   -  In the case of S3, tboot will also register itself as the resume
+      vector.  This is necessary because it must re-establish the
+      measured environment upon resume.  Once the TXT environment
+      has been restored, it will restore the TPM PCRs and then
+      transfer control back to the kernel's S3 resume vector.
+      In order to preserve system integrity across S3, the kernel
+      provides tboot with a set of memory ranges (RAM and RESERVED_KERN
+      in the e820 table, but not any memory that BIOS might alter over
+      the S3 transition) that tboot will calculate a MAC (message
+      authentication code) over and then seal with the TPM. On resume
+      and once the measured environment has been re-established, tboot
+      will re-calculate the MAC and verify it against the sealed value.
+      Tboot's policy determines what happens if the verification fails.
+      Note that the c/s 194 of tboot which has the new MAC code supports
+      this.
+
+That's pretty much it for TXT support.
+
+
+Configuring the System
+======================
+
+This code works with 32bit, 32bit PAE, and 64bit (x86_64) kernels.
+
+In BIOS, the user must enable:  TPM, TXT, VT-x, VT-d.  Not all BIOSes
+allow these to be individually enabled/disabled and the screens in
+which to find them are BIOS-specific.
+
+grub.conf needs to be modified as follows::
+
+        title Linux 2.6.29-tip w/ tboot
+          root (hd0,0)
+                kernel /tboot.gz logging=serial,vga,memory
+                module /vmlinuz-2.6.29-tip intel_iommu=on ro
+                       root=LABEL=/ rhgb console=ttyS0,115200 3
+                module /initrd-2.6.29-tip.img
+                module /Q35_SINIT_17.BIN
+
+The kernel option for enabling Intel TXT support is found under the
+Security top-level menu and is called "Enable Intel(R) Trusted
+Execution Technology (TXT)".  It is considered EXPERIMENTAL and
+depends on the generic x86 support (to allow maximum flexibility in
+kernel build options), since the tboot code will detect whether the
+platform actually supports Intel TXT and thus whether any of the
+kernel code is executed.
+
+The Q35_SINIT_17.BIN file is what Intel TXT refers to as an
+Authenticated Code Module.  It is specific to the chipset in the
+system and can also be found on the Trusted Boot site.  It is an
+(unencrypted) module signed by Intel that is used as part of the
+DRTM process to verify and configure the system.  It is signed
+because it operates at a higher privilege level in the system than
+any other macrocode and its correct operation is critical to the
+establishment of the DRTM.  The process for determining the correct
+SINIT ACM for a system is documented in the SINIT-guide.txt file
+that is on the tboot SourceForge site under the SINIT ACM downloads.
diff --git a/Documentation/arch/x86/iommu.rst b/Documentation/arch/x86/iommu.rst
new file mode 100644 (file)
index 0000000..42c7a6f
--- /dev/null
@@ -0,0 +1,151 @@
+=================
+x86 IOMMU Support
+=================
+
+The architecture specs can be obtained from the below locations.
+
+- Intel: http://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/vt-directed-io-spec.pdf
+- AMD: https://www.amd.com/system/files/TechDocs/48882_IOMMU.pdf
+
+This guide gives a quick cheat sheet for some basic understanding.
+
+Basic stuff
+-----------
+
+ACPI enumerates and lists the different IOMMUs on the platform, and
+device scope relationships between devices and which IOMMU controls
+them.
+
+Some ACPI Keywords:
+
+- DMAR - Intel DMA Remapping table
+- DRHD - Intel DMA Remapping Hardware Unit Definition
+- RMRR - Intel Reserved Memory Region Reporting Structure
+- IVRS - AMD I/O Virtualization Reporting Structure
+- IVDB - AMD I/O Virtualization Definition Block
+- IVHD - AMD I/O Virtualization Hardware Definition
+
+What is Intel RMRR?
+^^^^^^^^^^^^^^^^^^^
+
+There are some devices the BIOS controls, for e.g USB devices to perform
+PS2 emulation. The regions of memory used for these devices are marked
+reserved in the e820 map. When we turn on DMA translation, DMA to those
+regions will fail. Hence BIOS uses RMRR to specify these regions along with
+devices that need to access these regions. OS is expected to setup
+unity mappings for these regions for these devices to access these regions.
+
+What is AMD IVRS?
+^^^^^^^^^^^^^^^^^
+
+The architecture defines an ACPI-compatible data structure called an I/O
+Virtualization Reporting Structure (IVRS) that is used to convey information
+related to I/O virtualization to system software.  The IVRS describes the
+configuration and capabilities of the IOMMUs contained in the platform as
+well as information about the devices that each IOMMU virtualizes.
+
+The IVRS provides information about the following:
+
+- IOMMUs present in the platform including their capabilities and proper configuration
+- System I/O topology relevant to each IOMMU
+- Peripheral devices that cannot be otherwise enumerated
+- Memory regions used by SMI/SMM, platform firmware, and platform hardware. These are generally exclusion ranges to be configured by system software.
+
+How is an I/O Virtual Address (IOVA) generated?
+-----------------------------------------------
+
+Well behaved drivers call dma_map_*() calls before sending command to device
+that needs to perform DMA. Once DMA is completed and mapping is no longer
+required, driver performs dma_unmap_*() calls to unmap the region.
+
+Intel Specific Notes
+--------------------
+
+Graphics Problems?
+^^^^^^^^^^^^^^^^^^
+
+If you encounter issues with graphics devices, you can try adding
+option intel_iommu=igfx_off to turn off the integrated graphics engine.
+If this fixes anything, please ensure you file a bug reporting the problem.
+
+Some exceptions to IOVA
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Interrupt ranges are not address translated, (0xfee00000 - 0xfeefffff).
+The same is true for peer to peer transactions. Hence we reserve the
+address from PCI MMIO ranges so they are not allocated for IOVA addresses.
+
+AMD Specific Notes
+------------------
+
+Graphics Problems?
+^^^^^^^^^^^^^^^^^^
+
+If you encounter issues with integrated graphics devices, you can try adding
+option iommu=pt to the kernel command line use a 1:1 mapping for the IOMMU.  If
+this fixes anything, please ensure you file a bug reporting the problem.
+
+Fault reporting
+---------------
+When errors are reported, the IOMMU signals via an interrupt. The fault
+reason and device that caused it is printed on the console.
+
+
+Kernel Log Samples
+------------------
+
+Intel Boot Messages
+^^^^^^^^^^^^^^^^^^^
+
+Something like this gets printed indicating presence of DMAR tables
+in ACPI:
+
+::
+
+       ACPI: DMAR (v001 A M I  OEMDMAR  0x00000001 MSFT 0x00000097) @ 0x000000007f5b5ef0
+
+When DMAR is being processed and initialized by ACPI, prints DMAR locations
+and any RMRR's processed:
+
+::
+
+       ACPI DMAR:Host address width 36
+       ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed90000
+       ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed91000
+       ACPI DMAR:DRHD (flags: 0x00000001)base: 0x00000000fed93000
+       ACPI DMAR:RMRR base: 0x00000000000ed000 end: 0x00000000000effff
+       ACPI DMAR:RMRR base: 0x000000007f600000 end: 0x000000007fffffff
+
+When DMAR is enabled for use, you will notice:
+
+::
+
+       PCI-DMA: Using DMAR IOMMU
+
+Intel Fault reporting
+^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+       DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
+       DMAR:[fault reason 05] PTE Write access is not set
+       DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
+       DMAR:[fault reason 05] PTE Write access is not set
+
+AMD Boot Messages
+^^^^^^^^^^^^^^^^^
+
+Something like this gets printed indicating presence of the IOMMU:
+
+::
+
+       iommu: Default domain type: Translated
+       iommu: DMA domain TLB invalidation policy: lazy mode
+
+AMD Fault reporting
+^^^^^^^^^^^^^^^^^^^
+
+::
+
+       AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0007 address=0xffffc02000 flags=0x0000]
+       AMD-Vi: Event logged [IO_PAGE_FAULT device=07:00.0 domain=0x0007 address=0xffffc02000 flags=0x0000]
diff --git a/Documentation/arch/x86/kernel-stacks.rst b/Documentation/arch/x86/kernel-stacks.rst
new file mode 100644 (file)
index 0000000..6b0bcf0
--- /dev/null
@@ -0,0 +1,152 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=============
+Kernel Stacks
+=============
+
+Kernel stacks on x86-64 bit
+===========================
+
+Most of the text from Keith Owens, hacked by AK
+
+x86_64 page size (PAGE_SIZE) is 4K.
+
+Like all other architectures, x86_64 has a kernel stack for every
+active thread.  These thread stacks are THREAD_SIZE (2*PAGE_SIZE) big.
+These stacks contain useful data as long as a thread is alive or a
+zombie. While the thread is in user space the kernel stack is empty
+except for the thread_info structure at the bottom.
+
+In addition to the per thread stacks, there are specialized stacks
+associated with each CPU.  These stacks are only used while the kernel
+is in control on that CPU; when a CPU returns to user space the
+specialized stacks contain no useful data.  The main CPU stacks are:
+
+* Interrupt stack.  IRQ_STACK_SIZE
+
+  Used for external hardware interrupts.  If this is the first external
+  hardware interrupt (i.e. not a nested hardware interrupt) then the
+  kernel switches from the current task to the interrupt stack.  Like
+  the split thread and interrupt stacks on i386, this gives more room
+  for kernel interrupt processing without having to increase the size
+  of every per thread stack.
+
+  The interrupt stack is also used when processing a softirq.
+
+Switching to the kernel interrupt stack is done by software based on a
+per CPU interrupt nest counter. This is needed because x86-64 "IST"
+hardware stacks cannot nest without races.
+
+x86_64 also has a feature which is not available on i386, the ability
+to automatically switch to a new stack for designated events such as
+double fault or NMI, which makes it easier to handle these unusual
+events on x86_64.  This feature is called the Interrupt Stack Table
+(IST).  There can be up to 7 IST entries per CPU. The IST code is an
+index into the Task State Segment (TSS). The IST entries in the TSS
+point to dedicated stacks; each stack can be a different size.
+
+An IST is selected by a non-zero value in the IST field of an
+interrupt-gate descriptor.  When an interrupt occurs and the hardware
+loads such a descriptor, the hardware automatically sets the new stack
+pointer based on the IST value, then invokes the interrupt handler.  If
+the interrupt came from user mode, then the interrupt handler prologue
+will switch back to the per-thread stack.  If software wants to allow
+nested IST interrupts then the handler must adjust the IST values on
+entry to and exit from the interrupt handler.  (This is occasionally
+done, e.g. for debug exceptions.)
+
+Events with different IST codes (i.e. with different stacks) can be
+nested.  For example, a debug interrupt can safely be interrupted by an
+NMI.  arch/x86_64/kernel/entry.S::paranoidentry adjusts the stack
+pointers on entry to and exit from all IST events, in theory allowing
+IST events with the same code to be nested.  However in most cases, the
+stack size allocated to an IST assumes no nesting for the same code.
+If that assumption is ever broken then the stacks will become corrupt.
+
+The currently assigned IST stacks are:
+
+* ESTACK_DF.  EXCEPTION_STKSZ (PAGE_SIZE).
+
+  Used for interrupt 8 - Double Fault Exception (#DF).
+
+  Invoked when handling one exception causes another exception. Happens
+  when the kernel is very confused (e.g. kernel stack pointer corrupt).
+  Using a separate stack allows the kernel to recover from it well enough
+  in many cases to still output an oops.
+
+* ESTACK_NMI.  EXCEPTION_STKSZ (PAGE_SIZE).
+
+  Used for non-maskable interrupts (NMI).
+
+  NMI can be delivered at any time, including when the kernel is in the
+  middle of switching stacks.  Using IST for NMI events avoids making
+  assumptions about the previous state of the kernel stack.
+
+* ESTACK_DB.  EXCEPTION_STKSZ (PAGE_SIZE).
+
+  Used for hardware debug interrupts (interrupt 1) and for software
+  debug interrupts (INT3).
+
+  When debugging a kernel, debug interrupts (both hardware and
+  software) can occur at any time.  Using IST for these interrupts
+  avoids making assumptions about the previous state of the kernel
+  stack.
+
+  To handle nested #DB correctly there exist two instances of DB stacks. On
+  #DB entry the IST stackpointer for #DB is switched to the second instance
+  so a nested #DB starts from a clean stack. The nested #DB switches
+  the IST stackpointer to a guard hole to catch triple nesting.
+
+* ESTACK_MCE.  EXCEPTION_STKSZ (PAGE_SIZE).
+
+  Used for interrupt 18 - Machine Check Exception (#MC).
+
+  MCE can be delivered at any time, including when the kernel is in the
+  middle of switching stacks.  Using IST for MCE events avoids making
+  assumptions about the previous state of the kernel stack.
+
+For more details see the Intel IA32 or AMD AMD64 architecture manuals.
+
+
+Printing backtraces on x86
+==========================
+
+The question about the '?' preceding function names in an x86 stacktrace
+keeps popping up, here's an indepth explanation. It helps if the reader
+stares at print_context_stack() and the whole machinery in and around
+arch/x86/kernel/dumpstack.c.
+
+Adapted from Ingo's mail, Message-ID: <20150521101614.GA10889@gmail.com>:
+
+We always scan the full kernel stack for return addresses stored on
+the kernel stack(s) [1]_, from stack top to stack bottom, and print out
+anything that 'looks like' a kernel text address.
+
+If it fits into the frame pointer chain, we print it without a question
+mark, knowing that it's part of the real backtrace.
+
+If the address does not fit into our expected frame pointer chain we
+still print it, but we print a '?'. It can mean two things:
+
+ - either the address is not part of the call chain: it's just stale
+   values on the kernel stack, from earlier function calls. This is
+   the common case.
+
+ - or it is part of the call chain, but the frame pointer was not set
+   up properly within the function, so we don't recognize it.
+
+This way we will always print out the real call chain (plus a few more
+entries), regardless of whether the frame pointer was set up correctly
+or not - but in most cases we'll get the call chain right as well. The
+entries printed are strictly in stack order, so you can deduce more
+information from that as well.
+
+The most important property of this method is that we _never_ lose
+information: we always strive to print _all_ addresses on the stack(s)
+that look like kernel text addresses, so if debug information is wrong,
+we still print out the real call chain as well - just with more question
+marks than ideal.
+
+.. [1] For things like IRQ and IST stacks, we also scan those stacks, in
+       the right order, and try to cross from one stack into another
+       reconstructing the call chain. This works most of the time.
diff --git a/Documentation/arch/x86/mds.rst b/Documentation/arch/x86/mds.rst
new file mode 100644 (file)
index 0000000..5d4330b
--- /dev/null
@@ -0,0 +1,193 @@
+Microarchitectural Data Sampling (MDS) mitigation
+=================================================
+
+.. _mds:
+
+Overview
+--------
+
+Microarchitectural Data Sampling (MDS) is a family of side channel attacks
+on internal buffers in Intel CPUs. The variants are:
+
+ - Microarchitectural Store Buffer Data Sampling (MSBDS) (CVE-2018-12126)
+ - Microarchitectural Fill Buffer Data Sampling (MFBDS) (CVE-2018-12130)
+ - Microarchitectural Load Port Data Sampling (MLPDS) (CVE-2018-12127)
+ - Microarchitectural Data Sampling Uncacheable Memory (MDSUM) (CVE-2019-11091)
+
+MSBDS leaks Store Buffer Entries which can be speculatively forwarded to a
+dependent load (store-to-load forwarding) as an optimization. The forward
+can also happen to a faulting or assisting load operation for a different
+memory address, which can be exploited under certain conditions. Store
+buffers are partitioned between Hyper-Threads so cross thread forwarding is
+not possible. But if a thread enters or exits a sleep state the store
+buffer is repartitioned which can expose data from one thread to the other.
+
+MFBDS leaks Fill Buffer Entries. Fill buffers are used internally to manage
+L1 miss situations and to hold data which is returned or sent in response
+to a memory or I/O operation. Fill buffers can forward data to a load
+operation and also write data to the cache. When the fill buffer is
+deallocated it can retain the stale data of the preceding operations which
+can then be forwarded to a faulting or assisting load operation, which can
+be exploited under certain conditions. Fill buffers are shared between
+Hyper-Threads so cross thread leakage is possible.
+
+MLPDS leaks Load Port Data. Load ports are used to perform load operations
+from memory or I/O. The received data is then forwarded to the register
+file or a subsequent operation. In some implementations the Load Port can
+contain stale data from a previous operation which can be forwarded to
+faulting or assisting loads under certain conditions, which again can be
+exploited eventually. Load ports are shared between Hyper-Threads so cross
+thread leakage is possible.
+
+MDSUM is a special case of MSBDS, MFBDS and MLPDS. An uncacheable load from
+memory that takes a fault or assist can leave data in a microarchitectural
+structure that may later be observed using one of the same methods used by
+MSBDS, MFBDS or MLPDS.
+
+Exposure assumptions
+--------------------
+
+It is assumed that attack code resides in user space or in a guest with one
+exception. The rationale behind this assumption is that the code construct
+needed for exploiting MDS requires:
+
+ - to control the load to trigger a fault or assist
+
+ - to have a disclosure gadget which exposes the speculatively accessed
+   data for consumption through a side channel.
+
+ - to control the pointer through which the disclosure gadget exposes the
+   data
+
+The existence of such a construct in the kernel cannot be excluded with
+100% certainty, but the complexity involved makes it extremly unlikely.
+
+There is one exception, which is untrusted BPF. The functionality of
+untrusted BPF is limited, but it needs to be thoroughly investigated
+whether it can be used to create such a construct.
+
+
+Mitigation strategy
+-------------------
+
+All variants have the same mitigation strategy at least for the single CPU
+thread case (SMT off): Force the CPU to clear the affected buffers.
+
+This is achieved by using the otherwise unused and obsolete VERW
+instruction in combination with a microcode update. The microcode clears
+the affected CPU buffers when the VERW instruction is executed.
+
+For virtualization there are two ways to achieve CPU buffer
+clearing. Either the modified VERW instruction or via the L1D Flush
+command. The latter is issued when L1TF mitigation is enabled so the extra
+VERW can be avoided. If the CPU is not affected by L1TF then VERW needs to
+be issued.
+
+If the VERW instruction with the supplied segment selector argument is
+executed on a CPU without the microcode update there is no side effect
+other than a small number of pointlessly wasted CPU cycles.
+
+This does not protect against cross Hyper-Thread attacks except for MSBDS
+which is only exploitable cross Hyper-thread when one of the Hyper-Threads
+enters a C-state.
+
+The kernel provides a function to invoke the buffer clearing:
+
+    mds_clear_cpu_buffers()
+
+The mitigation is invoked on kernel/userspace, hypervisor/guest and C-state
+(idle) transitions.
+
+As a special quirk to address virtualization scenarios where the host has
+the microcode updated, but the hypervisor does not (yet) expose the
+MD_CLEAR CPUID bit to guests, the kernel issues the VERW instruction in the
+hope that it might actually clear the buffers. The state is reflected
+accordingly.
+
+According to current knowledge additional mitigations inside the kernel
+itself are not required because the necessary gadgets to expose the leaked
+data cannot be controlled in a way which allows exploitation from malicious
+user space or VM guests.
+
+Kernel internal mitigation modes
+--------------------------------
+
+ ======= ============================================================
+ off      Mitigation is disabled. Either the CPU is not affected or
+          mds=off is supplied on the kernel command line
+
+ full     Mitigation is enabled. CPU is affected and MD_CLEAR is
+          advertised in CPUID.
+
+ vmwerv          Mitigation is enabled. CPU is affected and MD_CLEAR is not
+         advertised in CPUID. That is mainly for virtualization
+         scenarios where the host has the updated microcode but the
+         hypervisor does not expose MD_CLEAR in CPUID. It's a best
+         effort approach without guarantee.
+ ======= ============================================================
+
+If the CPU is affected and mds=off is not supplied on the kernel command
+line then the kernel selects the appropriate mitigation mode depending on
+the availability of the MD_CLEAR CPUID bit.
+
+Mitigation points
+-----------------
+
+1. Return to user space
+^^^^^^^^^^^^^^^^^^^^^^^
+
+   When transitioning from kernel to user space the CPU buffers are flushed
+   on affected CPUs when the mitigation is not disabled on the kernel
+   command line. The migitation is enabled through the static key
+   mds_user_clear.
+
+   The mitigation is invoked in prepare_exit_to_usermode() which covers
+   all but one of the kernel to user space transitions.  The exception
+   is when we return from a Non Maskable Interrupt (NMI), which is
+   handled directly in do_nmi().
+
+   (The reason that NMI is special is that prepare_exit_to_usermode() can
+    enable IRQs.  In NMI context, NMIs are blocked, and we don't want to
+    enable IRQs with NMIs blocked.)
+
+
+2. C-State transition
+^^^^^^^^^^^^^^^^^^^^^
+
+   When a CPU goes idle and enters a C-State the CPU buffers need to be
+   cleared on affected CPUs when SMT is active. This addresses the
+   repartitioning of the store buffer when one of the Hyper-Threads enters
+   a C-State.
+
+   When SMT is inactive, i.e. either the CPU does not support it or all
+   sibling threads are offline CPU buffer clearing is not required.
+
+   The idle clearing is enabled on CPUs which are only affected by MSBDS
+   and not by any other MDS variant. The other MDS variants cannot be
+   protected against cross Hyper-Thread attacks because the Fill Buffer and
+   the Load Ports are shared. So on CPUs affected by other variants, the
+   idle clearing would be a window dressing exercise and is therefore not
+   activated.
+
+   The invocation is controlled by the static key mds_idle_clear which is
+   switched depending on the chosen mitigation mode and the SMT state of
+   the system.
+
+   The buffer clear is only invoked before entering the C-State to prevent
+   that stale data from the idling CPU from spilling to the Hyper-Thread
+   sibling after the store buffer got repartitioned and all entries are
+   available to the non idle sibling.
+
+   When coming out of idle the store buffer is partitioned again so each
+   sibling has half of it available. The back from idle CPU could be then
+   speculatively exposed to contents of the sibling. The buffers are
+   flushed either on exit to user space or on VMENTER so malicious code
+   in user space or the guest cannot speculatively access them.
+
+   The mitigation is hooked into all variants of halt()/mwait(), but does
+   not cover the legacy ACPI IO-Port mechanism because the ACPI idle driver
+   has been superseded by the intel_idle driver around 2010 and is
+   preferred on all affected CPUs which are expected to gain the MD_CLEAR
+   functionality in microcode. Aside of that the IO-Port mechanism is a
+   legacy interface which is only used on older systems which are either
+   not affected or do not receive microcode updates anymore.
diff --git a/Documentation/arch/x86/microcode.rst b/Documentation/arch/x86/microcode.rst
new file mode 100644 (file)
index 0000000..b627c6f
--- /dev/null
@@ -0,0 +1,240 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==========================
+The Linux Microcode Loader
+==========================
+
+:Authors: - Fenghua Yu <fenghua.yu@intel.com>
+          - Borislav Petkov <bp@suse.de>
+         - Ashok Raj <ashok.raj@intel.com>
+
+The kernel has a x86 microcode loading facility which is supposed to
+provide microcode loading methods in the OS. Potential use cases are
+updating the microcode on platforms beyond the OEM End-Of-Life support,
+and updating the microcode on long-running systems without rebooting.
+
+The loader supports three loading methods:
+
+Early load microcode
+====================
+
+The kernel can update microcode very early during boot. Loading
+microcode early can fix CPU issues before they are observed during
+kernel boot time.
+
+The microcode is stored in an initrd file. During boot, it is read from
+it and loaded into the CPU cores.
+
+The format of the combined initrd image is microcode in (uncompressed)
+cpio format followed by the (possibly compressed) initrd image. The
+loader parses the combined initrd image during boot.
+
+The microcode files in cpio name space are:
+
+on Intel:
+  kernel/x86/microcode/GenuineIntel.bin
+on AMD  :
+  kernel/x86/microcode/AuthenticAMD.bin
+
+During BSP (BootStrapping Processor) boot (pre-SMP), the kernel
+scans the microcode file in the initrd. If microcode matching the
+CPU is found, it will be applied in the BSP and later on in all APs
+(Application Processors).
+
+The loader also saves the matching microcode for the CPU in memory.
+Thus, the cached microcode patch is applied when CPUs resume from a
+sleep state.
+
+Here's a crude example how to prepare an initrd with microcode (this is
+normally done automatically by the distribution, when recreating the
+initrd, so you don't really have to do it yourself. It is documented
+here for future reference only).
+::
+
+  #!/bin/bash
+
+  if [ -z "$1" ]; then
+      echo "You need to supply an initrd file"
+      exit 1
+  fi
+
+  INITRD="$1"
+
+  DSTDIR=kernel/x86/microcode
+  TMPDIR=/tmp/initrd
+
+  rm -rf $TMPDIR
+
+  mkdir $TMPDIR
+  cd $TMPDIR
+  mkdir -p $DSTDIR
+
+  if [ -d /lib/firmware/amd-ucode ]; then
+          cat /lib/firmware/amd-ucode/microcode_amd*.bin > $DSTDIR/AuthenticAMD.bin
+  fi
+
+  if [ -d /lib/firmware/intel-ucode ]; then
+          cat /lib/firmware/intel-ucode/* > $DSTDIR/GenuineIntel.bin
+  fi
+
+  find . | cpio -o -H newc >../ucode.cpio
+  cd ..
+  mv $INITRD $INITRD.orig
+  cat ucode.cpio $INITRD.orig > $INITRD
+
+  rm -rf $TMPDIR
+
+
+The system needs to have the microcode packages installed into
+/lib/firmware or you need to fixup the paths above if yours are
+somewhere else and/or you've downloaded them directly from the processor
+vendor's site.
+
+Late loading
+============
+
+You simply install the microcode packages your distro supplies and
+run::
+
+  # echo 1 > /sys/devices/system/cpu/microcode/reload
+
+as root.
+
+The loading mechanism looks for microcode blobs in
+/lib/firmware/{intel-ucode,amd-ucode}. The default distro installation
+packages already put them there.
+
+Since kernel 5.19, late loading is not enabled by default.
+
+The /dev/cpu/microcode method has been removed in 5.19.
+
+Why is late loading dangerous?
+==============================
+
+Synchronizing all CPUs
+----------------------
+
+The microcode engine which receives the microcode update is shared
+between the two logical threads in a SMT system. Therefore, when
+the update is executed on one SMT thread of the core, the sibling
+"automatically" gets the update.
+
+Since the microcode can "simulate" MSRs too, while the microcode update
+is in progress, those simulated MSRs transiently cease to exist. This
+can result in unpredictable results if the SMT sibling thread happens to
+be in the middle of an access to such an MSR. The usual observation is
+that such MSR accesses cause #GPs to be raised to signal that former are
+not present.
+
+The disappearing MSRs are just one common issue which is being observed.
+Any other instruction that's being patched and gets concurrently
+executed by the other SMT sibling, can also result in similar,
+unpredictable behavior.
+
+To eliminate this case, a stop_machine()-based CPU synchronization was
+introduced as a way to guarantee that all logical CPUs will not execute
+any code but just wait in a spin loop, polling an atomic variable.
+
+While this took care of device or external interrupts, IPIs including
+LVT ones, such as CMCI etc, it cannot address other special interrupts
+that can't be shut off. Those are Machine Check (#MC), System Management
+(#SMI) and Non-Maskable interrupts (#NMI).
+
+Machine Checks
+--------------
+
+Machine Checks (#MC) are non-maskable. There are two kinds of MCEs.
+Fatal un-recoverable MCEs and recoverable MCEs. While un-recoverable
+errors are fatal, recoverable errors can also happen in kernel context
+are also treated as fatal by the kernel.
+
+On certain Intel machines, MCEs are also broadcast to all threads in a
+system. If one thread is in the middle of executing WRMSR, a MCE will be
+taken at the end of the flow. Either way, they will wait for the thread
+performing the wrmsr(0x79) to rendezvous in the MCE handler and shutdown
+eventually if any of the threads in the system fail to check in to the
+MCE rendezvous.
+
+To be paranoid and get predictable behavior, the OS can choose to set
+MCG_STATUS.MCIP. Since MCEs can be at most one in a system, if an
+MCE was signaled, the above condition will promote to a system reset
+automatically. OS can turn off MCIP at the end of the update for that
+core.
+
+System Management Interrupt
+---------------------------
+
+SMIs are also broadcast to all CPUs in the platform. Microcode update
+requests exclusive access to the core before writing to MSR 0x79. So if
+it does happen such that, one thread is in WRMSR flow, and the 2nd got
+an SMI, that thread will be stopped in the first instruction in the SMI
+handler.
+
+Since the secondary thread is stopped in the first instruction in SMI,
+there is very little chance that it would be in the middle of executing
+an instruction being patched. Plus OS has no way to stop SMIs from
+happening.
+
+Non-Maskable Interrupts
+-----------------------
+
+When thread0 of a core is doing the microcode update, if thread1 is
+pulled into NMI, that can cause unpredictable behavior due to the
+reasons above.
+
+OS can choose a variety of methods to avoid running into this situation.
+
+
+Is the microcode suitable for late loading?
+-------------------------------------------
+
+Late loading is done when the system is fully operational and running
+real workloads. Late loading behavior depends on what the base patch on
+the CPU is before upgrading to the new patch.
+
+This is true for Intel CPUs.
+
+Consider, for example, a CPU has patch level 1 and the update is to
+patch level 3.
+
+Between patch1 and patch3, patch2 might have deprecated a software-visible
+feature.
+
+This is unacceptable if software is even potentially using that feature.
+For instance, say MSR_X is no longer available after an update,
+accessing that MSR will cause a #GP fault.
+
+Basically there is no way to declare a new microcode update suitable
+for late-loading. This is another one of the problems that caused late
+loading to be not enabled by default.
+
+Builtin microcode
+=================
+
+The loader supports also loading of a builtin microcode supplied through
+the regular builtin firmware method CONFIG_EXTRA_FIRMWARE. Only 64-bit is
+currently supported.
+
+Here's an example::
+
+  CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin"
+  CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware"
+
+This basically means, you have the following tree structure locally::
+
+  /lib/firmware/
+  |-- amd-ucode
+  ...
+  |   |-- microcode_amd_fam15h.bin
+  ...
+  |-- intel-ucode
+  ...
+  |   |-- 06-3a-09
+  ...
+
+so that the build system can find those files and integrate them into
+the final kernel image. The early loader finds them and applies them.
+
+Needless to say, this method is not the most flexible one because it
+requires rebuilding the kernel each time updated microcode from the CPU
+vendor is available.
diff --git a/Documentation/arch/x86/mtrr.rst b/Documentation/arch/x86/mtrr.rst
new file mode 100644 (file)
index 0000000..f65ef03
--- /dev/null
@@ -0,0 +1,354 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=========================================
+MTRR (Memory Type Range Register) control
+=========================================
+
+:Authors: - Richard Gooch <rgooch@atnf.csiro.au> - 3 Jun 1999
+          - Luis R. Rodriguez <mcgrof@do-not-panic.com> - April 9, 2015
+
+
+Phasing out MTRR use
+====================
+
+MTRR use is replaced on modern x86 hardware with PAT. Direct MTRR use by
+drivers on Linux is now completely phased out, device drivers should use
+arch_phys_wc_add() in combination with ioremap_wc() to make MTRR effective on
+non-PAT systems while a no-op but equally effective on PAT enabled systems.
+
+Even if Linux does not use MTRRs directly, some x86 platform firmware may still
+set up MTRRs early before booting the OS. They do this as some platform
+firmware may still have implemented access to MTRRs which would be controlled
+and handled by the platform firmware directly. An example of platform use of
+MTRRs is through the use of SMI handlers, one case could be for fan control,
+the platform code would need uncachable access to some of its fan control
+registers. Such platform access does not need any Operating System MTRR code in
+place other than mtrr_type_lookup() to ensure any OS specific mapping requests
+are aligned with platform MTRR setup. If MTRRs are only set up by the platform
+firmware code though and the OS does not make any specific MTRR mapping
+requests mtrr_type_lookup() should always return MTRR_TYPE_INVALID.
+
+For details refer to Documentation/arch/x86/pat.rst.
+
+.. tip::
+  On Intel P6 family processors (Pentium Pro, Pentium II and later)
+  the Memory Type Range Registers (MTRRs) may be used to control
+  processor access to memory ranges. This is most useful when you have
+  a video (VGA) card on a PCI or AGP bus. Enabling write-combining
+  allows bus write transfers to be combined into a larger transfer
+  before bursting over the PCI/AGP bus. This can increase performance
+  of image write operations 2.5 times or more.
+
+  The Cyrix 6x86, 6x86MX and M II processors have Address Range
+  Registers (ARRs) which provide a similar functionality to MTRRs. For
+  these, the ARRs are used to emulate the MTRRs.
+
+  The AMD K6-2 (stepping 8 and above) and K6-3 processors have two
+  MTRRs. These are supported.  The AMD Athlon family provide 8 Intel
+  style MTRRs.
+
+  The Centaur C6 (WinChip) has 8 MCRs, allowing write-combining. These
+  are supported.
+
+  The VIA Cyrix III and VIA C3 CPUs offer 8 Intel style MTRRs.
+
+  The CONFIG_MTRR option creates a /proc/mtrr file which may be used
+  to manipulate your MTRRs. Typically the X server should use
+  this. This should have a reasonably generic interface so that
+  similar control registers on other processors can be easily
+  supported.
+
+There are two interfaces to /proc/mtrr: one is an ASCII interface
+which allows you to read and write. The other is an ioctl()
+interface. The ASCII interface is meant for administration. The
+ioctl() interface is meant for C programs (i.e. the X server). The
+interfaces are described below, with sample commands and C code.
+
+
+Reading MTRRs from the shell
+============================
+::
+
+  % cat /proc/mtrr
+  reg00: base=0x00000000 (   0MB), size= 128MB: write-back, count=1
+  reg01: base=0x08000000 ( 128MB), size=  64MB: write-back, count=1
+
+Creating MTRRs from the C-shell::
+
+  # echo "base=0xf8000000 size=0x400000 type=write-combining" >! /proc/mtrr
+
+or if you use bash::
+
+  # echo "base=0xf8000000 size=0x400000 type=write-combining" >| /proc/mtrr
+
+And the result thereof::
+
+  % cat /proc/mtrr
+  reg00: base=0x00000000 (   0MB), size= 128MB: write-back, count=1
+  reg01: base=0x08000000 ( 128MB), size=  64MB: write-back, count=1
+  reg02: base=0xf8000000 (3968MB), size=   4MB: write-combining, count=1
+
+This is for video RAM at base address 0xf8000000 and size 4 megabytes. To
+find out your base address, you need to look at the output of your X
+server, which tells you where the linear framebuffer address is. A
+typical line that you may get is::
+
+  (--) S3: PCI: 968 rev 0, Linear FB @ 0xf8000000
+
+Note that you should only use the value from the X server, as it may
+move the framebuffer base address, so the only value you can trust is
+that reported by the X server.
+
+To find out the size of your framebuffer (what, you don't actually
+know?), the following line will tell you::
+
+  (--) S3: videoram:  4096k
+
+That's 4 megabytes, which is 0x400000 bytes (in hexadecimal).
+A patch is being written for XFree86 which will make this automatic:
+in other words the X server will manipulate /proc/mtrr using the
+ioctl() interface, so users won't have to do anything. If you use a
+commercial X server, lobby your vendor to add support for MTRRs.
+
+
+Creating overlapping MTRRs
+==========================
+::
+
+  %echo "base=0xfb000000 size=0x1000000 type=write-combining" >/proc/mtrr
+  %echo "base=0xfb000000 size=0x1000 type=uncachable" >/proc/mtrr
+
+And the results::
+
+  % cat /proc/mtrr
+  reg00: base=0x00000000 (   0MB), size=  64MB: write-back, count=1
+  reg01: base=0xfb000000 (4016MB), size=  16MB: write-combining, count=1
+  reg02: base=0xfb000000 (4016MB), size=   4kB: uncachable, count=1
+
+Some cards (especially Voodoo Graphics boards) need this 4 kB area
+excluded from the beginning of the region because it is used for
+registers.
+
+NOTE: You can only create type=uncachable region, if the first
+region that you created is type=write-combining.
+
+
+Removing MTRRs from the C-shel
+==============================
+::
+
+  % echo "disable=2" >! /proc/mtrr
+
+or using bash::
+
+  % echo "disable=2" >| /proc/mtrr
+
+
+Reading MTRRs from a C program using ioctl()'s
+==============================================
+::
+
+  /*  mtrr-show.c
+
+      Source file for mtrr-show (example program to show MTRRs using ioctl()'s)
+
+      Copyright (C) 1997-1998  Richard Gooch
+
+      This program is free software; you can redistribute it and/or modify
+      it under the terms of the GNU General Public License as published by
+      the Free Software Foundation; either version 2 of the License, or
+      (at your option) any later version.
+
+      This program is distributed in the hope that it will be useful,
+      but WITHOUT ANY WARRANTY; without even the implied warranty of
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      GNU General Public License for more details.
+
+      You should have received a copy of the GNU General Public License
+      along with this program; if not, write to the Free Software
+      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+      Richard Gooch may be reached by email at  rgooch@atnf.csiro.au
+      The postal address is:
+        Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
+  */
+
+  /*
+      This program will use an ioctl() on /proc/mtrr to show the current MTRR
+      settings. This is an alternative to reading /proc/mtrr.
+
+
+      Written by      Richard Gooch   17-DEC-1997
+
+      Last updated by Richard Gooch   2-MAY-1998
+
+
+  */
+  #include <stdio.h>
+  #include <stdlib.h>
+  #include <string.h>
+  #include <sys/types.h>
+  #include <sys/stat.h>
+  #include <fcntl.h>
+  #include <sys/ioctl.h>
+  #include <errno.h>
+  #include <asm/mtrr.h>
+
+  #define TRUE 1
+  #define FALSE 0
+  #define ERRSTRING strerror (errno)
+
+  static char *mtrr_strings[MTRR_NUM_TYPES] =
+  {
+      "uncachable",               /* 0 */
+      "write-combining",          /* 1 */
+      "?",                        /* 2 */
+      "?",                        /* 3 */
+      "write-through",            /* 4 */
+      "write-protect",            /* 5 */
+      "write-back",               /* 6 */
+  };
+
+  int main ()
+  {
+      int fd;
+      struct mtrr_gentry gentry;
+
+      if ( ( fd = open ("/proc/mtrr", O_RDONLY, 0) ) == -1 )
+      {
+    if (errno == ENOENT)
+    {
+        fputs ("/proc/mtrr not found: not supported or you don't have a PPro?\n",
+        stderr);
+        exit (1);
+    }
+    fprintf (stderr, "Error opening /proc/mtrr\t%s\n", ERRSTRING);
+    exit (2);
+      }
+      for (gentry.regnum = 0; ioctl (fd, MTRRIOC_GET_ENTRY, &gentry) == 0;
+    ++gentry.regnum)
+      {
+    if (gentry.size < 1)
+    {
+        fprintf (stderr, "Register: %u disabled\n", gentry.regnum);
+        continue;
+    }
+    fprintf (stderr, "Register: %u base: 0x%lx size: 0x%lx type: %s\n",
+      gentry.regnum, gentry.base, gentry.size,
+      mtrr_strings[gentry.type]);
+      }
+      if (errno == EINVAL) exit (0);
+      fprintf (stderr, "Error doing ioctl(2) on /dev/mtrr\t%s\n", ERRSTRING);
+      exit (3);
+  }   /*  End Function main  */
+
+
+Creating MTRRs from a C programme using ioctl()'s
+=================================================
+::
+
+  /*  mtrr-add.c
+
+      Source file for mtrr-add (example programme to add an MTRRs using ioctl())
+
+      Copyright (C) 1997-1998  Richard Gooch
+
+      This program is free software; you can redistribute it and/or modify
+      it under the terms of the GNU General Public License as published by
+      the Free Software Foundation; either version 2 of the License, or
+      (at your option) any later version.
+
+      This program is distributed in the hope that it will be useful,
+      but WITHOUT ANY WARRANTY; without even the implied warranty of
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      GNU General Public License for more details.
+
+      You should have received a copy of the GNU General Public License
+      along with this program; if not, write to the Free Software
+      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+      Richard Gooch may be reached by email at  rgooch@atnf.csiro.au
+      The postal address is:
+        Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
+  */
+
+  /*
+      This programme will use an ioctl() on /proc/mtrr to add an entry. The first
+      available mtrr is used. This is an alternative to writing /proc/mtrr.
+
+
+      Written by      Richard Gooch   17-DEC-1997
+
+      Last updated by Richard Gooch   2-MAY-1998
+
+
+  */
+  #include <stdio.h>
+  #include <string.h>
+  #include <stdlib.h>
+  #include <unistd.h>
+  #include <sys/types.h>
+  #include <sys/stat.h>
+  #include <fcntl.h>
+  #include <sys/ioctl.h>
+  #include <errno.h>
+  #include <asm/mtrr.h>
+
+  #define TRUE 1
+  #define FALSE 0
+  #define ERRSTRING strerror (errno)
+
+  static char *mtrr_strings[MTRR_NUM_TYPES] =
+  {
+      "uncachable",               /* 0 */
+      "write-combining",          /* 1 */
+      "?",                        /* 2 */
+      "?",                        /* 3 */
+      "write-through",            /* 4 */
+      "write-protect",            /* 5 */
+      "write-back",               /* 6 */
+  };
+
+  int main (int argc, char **argv)
+  {
+      int fd;
+      struct mtrr_sentry sentry;
+
+      if (argc != 4)
+      {
+    fprintf (stderr, "Usage:\tmtrr-add base size type\n");
+    exit (1);
+      }
+      sentry.base = strtoul (argv[1], NULL, 0);
+      sentry.size = strtoul (argv[2], NULL, 0);
+      for (sentry.type = 0; sentry.type < MTRR_NUM_TYPES; ++sentry.type)
+      {
+    if (strcmp (argv[3], mtrr_strings[sentry.type]) == 0) break;
+      }
+      if (sentry.type >= MTRR_NUM_TYPES)
+      {
+    fprintf (stderr, "Illegal type: \"%s\"\n", argv[3]);
+    exit (2);
+      }
+      if ( ( fd = open ("/proc/mtrr", O_WRONLY, 0) ) == -1 )
+      {
+    if (errno == ENOENT)
+    {
+        fputs ("/proc/mtrr not found: not supported or you don't have a PPro?\n",
+        stderr);
+        exit (3);
+    }
+    fprintf (stderr, "Error opening /proc/mtrr\t%s\n", ERRSTRING);
+    exit (4);
+      }
+      if (ioctl (fd, MTRRIOC_ADD_ENTRY, &sentry) == -1)
+      {
+    fprintf (stderr, "Error doing ioctl(2) on /dev/mtrr\t%s\n", ERRSTRING);
+    exit (5);
+      }
+      fprintf (stderr, "Sleeping for 5 seconds so you can see the new entry\n");
+      sleep (5);
+      close (fd);
+      fputs ("I've just closed /proc/mtrr so now the new entry should be gone\n",
+      stderr);
+  }   /*  End Function main  */
diff --git a/Documentation/arch/x86/orc-unwinder.rst b/Documentation/arch/x86/orc-unwinder.rst
new file mode 100644 (file)
index 0000000..cdb2570
--- /dev/null
@@ -0,0 +1,182 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============
+ORC unwinder
+============
+
+Overview
+========
+
+The kernel CONFIG_UNWINDER_ORC option enables the ORC unwinder, which is
+similar in concept to a DWARF unwinder.  The difference is that the
+format of the ORC data is much simpler than DWARF, which in turn allows
+the ORC unwinder to be much simpler and faster.
+
+The ORC data consists of unwind tables which are generated by objtool.
+They contain out-of-band data which is used by the in-kernel ORC
+unwinder.  Objtool generates the ORC data by first doing compile-time
+stack metadata validation (CONFIG_STACK_VALIDATION).  After analyzing
+all the code paths of a .o file, it determines information about the
+stack state at each instruction address in the file and outputs that
+information to the .orc_unwind and .orc_unwind_ip sections.
+
+The per-object ORC sections are combined at link time and are sorted and
+post-processed at boot time.  The unwinder uses the resulting data to
+correlate instruction addresses with their stack states at run time.
+
+
+ORC vs frame pointers
+=====================
+
+With frame pointers enabled, GCC adds instrumentation code to every
+function in the kernel.  The kernel's .text size increases by about
+3.2%, resulting in a broad kernel-wide slowdown.  Measurements by Mel
+Gorman [1]_ have shown a slowdown of 5-10% for some workloads.
+
+In contrast, the ORC unwinder has no effect on text size or runtime
+performance, because the debuginfo is out of band.  So if you disable
+frame pointers and enable the ORC unwinder, you get a nice performance
+improvement across the board, and still have reliable stack traces.
+
+Ingo Molnar says:
+
+  "Note that it's not just a performance improvement, but also an
+  instruction cache locality improvement: 3.2% .text savings almost
+  directly transform into a similarly sized reduction in cache
+  footprint. That can transform to even higher speedups for workloads
+  whose cache locality is borderline."
+
+Another benefit of ORC compared to frame pointers is that it can
+reliably unwind across interrupts and exceptions.  Frame pointer based
+unwinds can sometimes skip the caller of the interrupted function, if it
+was a leaf function or if the interrupt hit before the frame pointer was
+saved.
+
+The main disadvantage of the ORC unwinder compared to frame pointers is
+that it needs more memory to store the ORC unwind tables: roughly 2-4MB
+depending on the kernel config.
+
+
+ORC vs DWARF
+============
+
+ORC debuginfo's advantage over DWARF itself is that it's much simpler.
+It gets rid of the complex DWARF CFI state machine and also gets rid of
+the tracking of unnecessary registers.  This allows the unwinder to be
+much simpler, meaning fewer bugs, which is especially important for
+mission critical oops code.
+
+The simpler debuginfo format also enables the unwinder to be much faster
+than DWARF, which is important for perf and lockdep.  In a basic
+performance test by Jiri Slaby [2]_, the ORC unwinder was about 20x
+faster than an out-of-tree DWARF unwinder.  (Note: That measurement was
+taken before some performance tweaks were added, which doubled
+performance, so the speedup over DWARF may be closer to 40x.)
+
+The ORC data format does have a few downsides compared to DWARF.  ORC
+unwind tables take up ~50% more RAM (+1.3MB on an x86 defconfig kernel)
+than DWARF-based eh_frame tables.
+
+Another potential downside is that, as GCC evolves, it's conceivable
+that the ORC data may end up being *too* simple to describe the state of
+the stack for certain optimizations.  But IMO this is unlikely because
+GCC saves the frame pointer for any unusual stack adjustments it does,
+so I suspect we'll really only ever need to keep track of the stack
+pointer and the frame pointer between call frames.  But even if we do
+end up having to track all the registers DWARF tracks, at least we will
+still be able to control the format, e.g. no complex state machines.
+
+
+ORC unwind table generation
+===========================
+
+The ORC data is generated by objtool.  With the existing compile-time
+stack metadata validation feature, objtool already follows all code
+paths, and so it already has all the information it needs to be able to
+generate ORC data from scratch.  So it's an easy step to go from stack
+validation to ORC data generation.
+
+It should be possible to instead generate the ORC data with a simple
+tool which converts DWARF to ORC data.  However, such a solution would
+be incomplete due to the kernel's extensive use of asm, inline asm, and
+special sections like exception tables.
+
+That could be rectified by manually annotating those special code paths
+using GNU assembler .cfi annotations in .S files, and homegrown
+annotations for inline asm in .c files.  But asm annotations were tried
+in the past and were found to be unmaintainable.  They were often
+incorrect/incomplete and made the code harder to read and keep updated.
+And based on looking at glibc code, annotating inline asm in .c files
+might be even worse.
+
+Objtool still needs a few annotations, but only in code which does
+unusual things to the stack like entry code.  And even then, far fewer
+annotations are needed than what DWARF would need, so they're much more
+maintainable than DWARF CFI annotations.
+
+So the advantages of using objtool to generate ORC data are that it
+gives more accurate debuginfo, with very few annotations.  It also
+insulates the kernel from toolchain bugs which can be very painful to
+deal with in the kernel since we often have to workaround issues in
+older versions of the toolchain for years.
+
+The downside is that the unwinder now becomes dependent on objtool's
+ability to reverse engineer GCC code flow.  If GCC optimizations become
+too complicated for objtool to follow, the ORC data generation might
+stop working or become incomplete.  (It's worth noting that livepatch
+already has such a dependency on objtool's ability to follow GCC code
+flow.)
+
+If newer versions of GCC come up with some optimizations which break
+objtool, we may need to revisit the current implementation.  Some
+possible solutions would be asking GCC to make the optimizations more
+palatable, or having objtool use DWARF as an additional input, or
+creating a GCC plugin to assist objtool with its analysis.  But for now,
+objtool follows GCC code quite well.
+
+
+Unwinder implementation details
+===============================
+
+Objtool generates the ORC data by integrating with the compile-time
+stack metadata validation feature, which is described in detail in
+tools/objtool/Documentation/objtool.txt.  After analyzing all
+the code paths of a .o file, it creates an array of orc_entry structs,
+and a parallel array of instruction addresses associated with those
+structs, and writes them to the .orc_unwind and .orc_unwind_ip sections
+respectively.
+
+The ORC data is split into the two arrays for performance reasons, to
+make the searchable part of the data (.orc_unwind_ip) more compact.  The
+arrays are sorted in parallel at boot time.
+
+Performance is further improved by the use of a fast lookup table which
+is created at runtime.  The fast lookup table associates a given address
+with a range of indices for the .orc_unwind table, so that only a small
+subset of the table needs to be searched.
+
+
+Etymology
+=========
+
+Orcs, fearsome creatures of medieval folklore, are the Dwarves' natural
+enemies.  Similarly, the ORC unwinder was created in opposition to the
+complexity and slowness of DWARF.
+
+"Although Orcs rarely consider multiple solutions to a problem, they do
+excel at getting things done because they are creatures of action, not
+thought." [3]_  Similarly, unlike the esoteric DWARF unwinder, the
+veracious ORC unwinder wastes no time or siloconic effort decoding
+variable-length zero-extended unsigned-integer byte-coded
+state-machine-based debug information entries.
+
+Similar to how Orcs frequently unravel the well-intentioned plans of
+their adversaries, the ORC unwinder frequently unravels stacks with
+brutal, unyielding efficiency.
+
+ORC stands for Oops Rewind Capability.
+
+
+.. [1] https://lore.kernel.org/r/20170602104048.jkkzssljsompjdwy@suse.de
+.. [2] https://lore.kernel.org/r/d2ca5435-6386-29b8-db87-7f227c2b713a@suse.cz
+.. [3] http://dustin.wikidot.com/half-orcs-and-orcs
diff --git a/Documentation/arch/x86/pat.rst b/Documentation/arch/x86/pat.rst
new file mode 100644 (file)
index 0000000..5d90177
--- /dev/null
@@ -0,0 +1,240 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==========================
+PAT (Page Attribute Table)
+==========================
+
+x86 Page Attribute Table (PAT) allows for setting the memory attribute at the
+page level granularity. PAT is complementary to the MTRR settings which allows
+for setting of memory types over physical address ranges. However, PAT is
+more flexible than MTRR due to its capability to set attributes at page level
+and also due to the fact that there are no hardware limitations on number of
+such attribute settings allowed. Added flexibility comes with guidelines for
+not having memory type aliasing for the same physical memory with multiple
+virtual addresses.
+
+PAT allows for different types of memory attributes. The most commonly used
+ones that will be supported at this time are:
+
+===  ==============
+WB   Write-back
+UC   Uncached
+WC   Write-combined
+WT   Write-through
+UC-  Uncached Minus
+===  ==============
+
+
+PAT APIs
+========
+
+There are many different APIs in the kernel that allows setting of memory
+attributes at the page level. In order to avoid aliasing, these interfaces
+should be used thoughtfully. Below is a table of interfaces available,
+their intended usage and their memory attribute relationships. Internally,
+these APIs use a reserve_memtype()/free_memtype() interface on the physical
+address range to avoid any aliasing.
+
++------------------------+----------+--------------+------------------+
+| API                    |    RAM   |  ACPI,...    |  Reserved/Holes  |
++------------------------+----------+--------------+------------------+
+| ioremap                |    --    |    UC-       |       UC-        |
++------------------------+----------+--------------+------------------+
+| ioremap_cache          |    --    |    WB        |       WB         |
++------------------------+----------+--------------+------------------+
+| ioremap_uc             |    --    |    UC        |       UC         |
++------------------------+----------+--------------+------------------+
+| ioremap_wc             |    --    |    --        |       WC         |
++------------------------+----------+--------------+------------------+
+| ioremap_wt             |    --    |    --        |       WT         |
++------------------------+----------+--------------+------------------+
+| set_memory_uc,         |    UC-   |    --        |       --         |
+| set_memory_wb          |          |              |                  |
++------------------------+----------+--------------+------------------+
+| set_memory_wc,         |    WC    |    --        |       --         |
+| set_memory_wb          |          |              |                  |
++------------------------+----------+--------------+------------------+
+| set_memory_wt,         |    WT    |    --        |       --         |
+| set_memory_wb          |          |              |                  |
++------------------------+----------+--------------+------------------+
+| pci sysfs resource     |    --    |    --        |       UC-        |
++------------------------+----------+--------------+------------------+
+| pci sysfs resource_wc  |    --    |    --        |       WC         |
+| is IORESOURCE_PREFETCH |          |              |                  |
++------------------------+----------+--------------+------------------+
+| pci proc               |    --    |    --        |       UC-        |
+| !PCIIOC_WRITE_COMBINE  |          |              |                  |
++------------------------+----------+--------------+------------------+
+| pci proc               |    --    |    --        |       WC         |
+| PCIIOC_WRITE_COMBINE   |          |              |                  |
++------------------------+----------+--------------+------------------+
+| /dev/mem               |    --    |   WB/WC/UC-  |    WB/WC/UC-     |
+| read-write             |          |              |                  |
++------------------------+----------+--------------+------------------+
+| /dev/mem               |    --    |    UC-       |       UC-        |
+| mmap SYNC flag         |          |              |                  |
++------------------------+----------+--------------+------------------+
+| /dev/mem               |    --    |   WB/WC/UC-  |  WB/WC/UC-       |
+| mmap !SYNC flag        |          |              |                  |
+| and                    |          |(from existing|  (from existing  |
+| any alias to this area |          |alias)        |  alias)          |
++------------------------+----------+--------------+------------------+
+| /dev/mem               |    --    |    WB        |       WB         |
+| mmap !SYNC flag        |          |              |                  |
+| no alias to this area  |          |              |                  |
+| and                    |          |              |                  |
+| MTRR says WB           |          |              |                  |
++------------------------+----------+--------------+------------------+
+| /dev/mem               |    --    |    --        |       UC-        |
+| mmap !SYNC flag        |          |              |                  |
+| no alias to this area  |          |              |                  |
+| and                    |          |              |                  |
+| MTRR says !WB          |          |              |                  |
++------------------------+----------+--------------+------------------+
+
+
+Advanced APIs for drivers
+=========================
+
+A. Exporting pages to users with remap_pfn_range, io_remap_pfn_range,
+vmf_insert_pfn.
+
+Drivers wanting to export some pages to userspace do it by using mmap
+interface and a combination of:
+
+  1) pgprot_noncached()
+  2) io_remap_pfn_range() or remap_pfn_range() or vmf_insert_pfn()
+
+With PAT support, a new API pgprot_writecombine is being added. So, drivers can
+continue to use the above sequence, with either pgprot_noncached() or
+pgprot_writecombine() in step 1, followed by step 2.
+
+In addition, step 2 internally tracks the region as UC or WC in memtype
+list in order to ensure no conflicting mapping.
+
+Note that this set of APIs only works with IO (non RAM) regions. If driver
+wants to export a RAM region, it has to do set_memory_uc() or set_memory_wc()
+as step 0 above and also track the usage of those pages and use set_memory_wb()
+before the page is freed to free pool.
+
+MTRR effects on PAT / non-PAT systems
+=====================================
+
+The following table provides the effects of using write-combining MTRRs when
+using ioremap*() calls on x86 for both non-PAT and PAT systems. Ideally
+mtrr_add() usage will be phased out in favor of arch_phys_wc_add() which will
+be a no-op on PAT enabled systems. The region over which a arch_phys_wc_add()
+is made, should already have been ioremapped with WC attributes or PAT entries,
+this can be done by using ioremap_wc() / set_memory_wc().  Devices which
+combine areas of IO memory desired to remain uncacheable with areas where
+write-combining is desirable should consider use of ioremap_uc() followed by
+set_memory_wc() to white-list effective write-combined areas.  Such use is
+nevertheless discouraged as the effective memory type is considered
+implementation defined, yet this strategy can be used as last resort on devices
+with size-constrained regions where otherwise MTRR write-combining would
+otherwise not be effective.
+::
+
+  ====  =======  ===  =========================  =====================
+  MTRR  Non-PAT  PAT  Linux ioremap value        Effective memory type
+  ====  =======  ===  =========================  =====================
+        PAT                                        Non-PAT |  PAT
+        |PCD                                               |
+        ||PWT                                              |
+        |||                                                |
+  WC    000      WB   _PAGE_CACHE_MODE_WB             WC   |   WC
+  WC    001      WC   _PAGE_CACHE_MODE_WC             WC*  |   WC
+  WC    010      UC-  _PAGE_CACHE_MODE_UC_MINUS       WC*  |   UC
+  WC    011      UC   _PAGE_CACHE_MODE_UC             UC   |   UC
+  ====  =======  ===  =========================  =====================
+
+  (*) denotes implementation defined and is discouraged
+
+.. note:: -- in the above table mean "Not suggested usage for the API". Some
+  of the --'s are strictly enforced by the kernel. Some others are not really
+  enforced today, but may be enforced in future.
+
+For ioremap and pci access through /sys or /proc - The actual type returned
+can be more restrictive, in case of any existing aliasing for that address.
+For example: If there is an existing uncached mapping, a new ioremap_wc can
+return uncached mapping in place of write-combine requested.
+
+set_memory_[uc|wc|wt] and set_memory_wb should be used in pairs, where driver
+will first make a region uc, wc or wt and switch it back to wb after use.
+
+Over time writes to /proc/mtrr will be deprecated in favor of using PAT based
+interfaces. Users writing to /proc/mtrr are suggested to use above interfaces.
+
+Drivers should use ioremap_[uc|wc] to access PCI BARs with [uc|wc] access
+types.
+
+Drivers should use set_memory_[uc|wc|wt] to set access type for RAM ranges.
+
+
+PAT debugging
+=============
+
+With CONFIG_DEBUG_FS enabled, PAT memtype list can be examined by::
+
+  # mount -t debugfs debugfs /sys/kernel/debug
+  # cat /sys/kernel/debug/x86/pat_memtype_list
+  PAT memtype list:
+  uncached-minus @ 0x7fadf000-0x7fae0000
+  uncached-minus @ 0x7fb19000-0x7fb1a000
+  uncached-minus @ 0x7fb1a000-0x7fb1b000
+  uncached-minus @ 0x7fb1b000-0x7fb1c000
+  uncached-minus @ 0x7fb1c000-0x7fb1d000
+  uncached-minus @ 0x7fb1d000-0x7fb1e000
+  uncached-minus @ 0x7fb1e000-0x7fb25000
+  uncached-minus @ 0x7fb25000-0x7fb26000
+  uncached-minus @ 0x7fb26000-0x7fb27000
+  uncached-minus @ 0x7fb27000-0x7fb28000
+  uncached-minus @ 0x7fb28000-0x7fb2e000
+  uncached-minus @ 0x7fb2e000-0x7fb2f000
+  uncached-minus @ 0x7fb2f000-0x7fb30000
+  uncached-minus @ 0x7fb31000-0x7fb32000
+  uncached-minus @ 0x80000000-0x90000000
+
+This list shows physical address ranges and various PAT settings used to
+access those physical address ranges.
+
+Another, more verbose way of getting PAT related debug messages is with
+"debugpat" boot parameter. With this parameter, various debug messages are
+printed to dmesg log.
+
+PAT Initialization
+==================
+
+The following table describes how PAT is initialized under various
+configurations. The PAT MSR must be updated by Linux in order to support WC
+and WT attributes. Otherwise, the PAT MSR has the value programmed in it
+by the firmware. Note, Xen enables WC attribute in the PAT MSR for guests.
+
+ ==== ===== ==========================  =========  =======
+ MTRR PAT   Call Sequence               PAT State  PAT MSR
+ ==== ===== ==========================  =========  =======
+ E    E     MTRR -> PAT init            Enabled    OS
+ E    D     MTRR -> PAT init            Disabled    -
+ D    E     MTRR -> PAT disable         Disabled   BIOS
+ D    D     MTRR -> PAT disable         Disabled    -
+ -    np/E  PAT  -> PAT disable         Disabled   BIOS
+ -    np/D  PAT  -> PAT disable         Disabled    -
+ E    !P/E  MTRR -> PAT init            Disabled   BIOS
+ D    !P/E  MTRR -> PAT disable         Disabled   BIOS
+ !M   !P/E  MTRR stub -> PAT disable    Disabled   BIOS
+ ==== ===== ==========================  =========  =======
+
+  Legend
+
+ ========= =======================================
+ E         Feature enabled in CPU
+ D        Feature disabled/unsupported in CPU
+ np       "nopat" boot option specified
+ !P       CONFIG_X86_PAT option unset
+ !M       CONFIG_MTRR option unset
+ Enabled   PAT state set to enabled
+ Disabled  PAT state set to disabled
+ OS        PAT initializes PAT MSR with OS setting
+ BIOS      PAT keeps PAT MSR with BIOS setting
+ ========= =======================================
+
diff --git a/Documentation/arch/x86/pti.rst b/Documentation/arch/x86/pti.rst
new file mode 100644 (file)
index 0000000..4b858a9
--- /dev/null
@@ -0,0 +1,195 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==========================
+Page Table Isolation (PTI)
+==========================
+
+Overview
+========
+
+Page Table Isolation (pti, previously known as KAISER [1]_) is a
+countermeasure against attacks on the shared user/kernel address
+space such as the "Meltdown" approach [2]_.
+
+To mitigate this class of attacks, we create an independent set of
+page tables for use only when running userspace applications.  When
+the kernel is entered via syscalls, interrupts or exceptions, the
+page tables are switched to the full "kernel" copy.  When the system
+switches back to user mode, the user copy is used again.
+
+The userspace page tables contain only a minimal amount of kernel
+data: only what is needed to enter/exit the kernel such as the
+entry/exit functions themselves and the interrupt descriptor table
+(IDT).  There are a few strictly unnecessary things that get mapped
+such as the first C function when entering an interrupt (see
+comments in pti.c).
+
+This approach helps to ensure that side-channel attacks leveraging
+the paging structures do not function when PTI is enabled.  It can be
+enabled by setting CONFIG_PAGE_TABLE_ISOLATION=y at compile time.
+Once enabled at compile-time, it can be disabled at boot with the
+'nopti' or 'pti=' kernel parameters (see kernel-parameters.txt).
+
+Page Table Management
+=====================
+
+When PTI is enabled, the kernel manages two sets of page tables.
+The first set is very similar to the single set which is present in
+kernels without PTI.  This includes a complete mapping of userspace
+that the kernel can use for things like copy_to_user().
+
+Although _complete_, the user portion of the kernel page tables is
+crippled by setting the NX bit in the top level.  This ensures
+that any missed kernel->user CR3 switch will immediately crash
+userspace upon executing its first instruction.
+
+The userspace page tables map only the kernel data needed to enter
+and exit the kernel.  This data is entirely contained in the 'struct
+cpu_entry_area' structure which is placed in the fixmap which gives
+each CPU's copy of the area a compile-time-fixed virtual address.
+
+For new userspace mappings, the kernel makes the entries in its
+page tables like normal.  The only difference is when the kernel
+makes entries in the top (PGD) level.  In addition to setting the
+entry in the main kernel PGD, a copy of the entry is made in the
+userspace page tables' PGD.
+
+This sharing at the PGD level also inherently shares all the lower
+layers of the page tables.  This leaves a single, shared set of
+userspace page tables to manage.  One PTE to lock, one set of
+accessed bits, dirty bits, etc...
+
+Overhead
+========
+
+Protection against side-channel attacks is important.  But,
+this protection comes at a cost:
+
+1. Increased Memory Use
+
+  a. Each process now needs an order-1 PGD instead of order-0.
+     (Consumes an additional 4k per process).
+  b. The 'cpu_entry_area' structure must be 2MB in size and 2MB
+     aligned so that it can be mapped by setting a single PMD
+     entry.  This consumes nearly 2MB of RAM once the kernel
+     is decompressed, but no space in the kernel image itself.
+
+2. Runtime Cost
+
+  a. CR3 manipulation to switch between the page table copies
+     must be done at interrupt, syscall, and exception entry
+     and exit (it can be skipped when the kernel is interrupted,
+     though.)  Moves to CR3 are on the order of a hundred
+     cycles, and are required at every entry and exit.
+  b. A "trampoline" must be used for SYSCALL entry.  This
+     trampoline depends on a smaller set of resources than the
+     non-PTI SYSCALL entry code, so requires mapping fewer
+     things into the userspace page tables.  The downside is
+     that stacks must be switched at entry time.
+  c. Global pages are disabled for all kernel structures not
+     mapped into both kernel and userspace page tables.  This
+     feature of the MMU allows different processes to share TLB
+     entries mapping the kernel.  Losing the feature means more
+     TLB misses after a context switch.  The actual loss of
+     performance is very small, however, never exceeding 1%.
+  d. Process Context IDentifiers (PCID) is a CPU feature that
+     allows us to skip flushing the entire TLB when switching page
+     tables by setting a special bit in CR3 when the page tables
+     are changed.  This makes switching the page tables (at context
+     switch, or kernel entry/exit) cheaper.  But, on systems with
+     PCID support, the context switch code must flush both the user
+     and kernel entries out of the TLB.  The user PCID TLB flush is
+     deferred until the exit to userspace, minimizing the cost.
+     See intel.com/sdm for the gory PCID/INVPCID details.
+  e. The userspace page tables must be populated for each new
+     process.  Even without PTI, the shared kernel mappings
+     are created by copying top-level (PGD) entries into each
+     new process.  But, with PTI, there are now *two* kernel
+     mappings: one in the kernel page tables that maps everything
+     and one for the entry/exit structures.  At fork(), we need to
+     copy both.
+  f. In addition to the fork()-time copying, there must also
+     be an update to the userspace PGD any time a set_pgd() is done
+     on a PGD used to map userspace.  This ensures that the kernel
+     and userspace copies always map the same userspace
+     memory.
+  g. On systems without PCID support, each CR3 write flushes
+     the entire TLB.  That means that each syscall, interrupt
+     or exception flushes the TLB.
+  h. INVPCID is a TLB-flushing instruction which allows flushing
+     of TLB entries for non-current PCIDs.  Some systems support
+     PCIDs, but do not support INVPCID.  On these systems, addresses
+     can only be flushed from the TLB for the current PCID.  When
+     flushing a kernel address, we need to flush all PCIDs, so a
+     single kernel address flush will require a TLB-flushing CR3
+     write upon the next use of every PCID.
+
+Possible Future Work
+====================
+1. We can be more careful about not actually writing to CR3
+   unless its value is actually changed.
+2. Allow PTI to be enabled/disabled at runtime in addition to the
+   boot-time switching.
+
+Testing
+========
+
+To test stability of PTI, the following test procedure is recommended,
+ideally doing all of these in parallel:
+
+1. Set CONFIG_DEBUG_ENTRY=y
+2. Run several copies of all of the tools/testing/selftests/x86/ tests
+   (excluding MPX and protection_keys) in a loop on multiple CPUs for
+   several minutes.  These tests frequently uncover corner cases in the
+   kernel entry code.  In general, old kernels might cause these tests
+   themselves to crash, but they should never crash the kernel.
+3. Run the 'perf' tool in a mode (top or record) that generates many
+   frequent performance monitoring non-maskable interrupts (see "NMI"
+   in /proc/interrupts).  This exercises the NMI entry/exit code which
+   is known to trigger bugs in code paths that did not expect to be
+   interrupted, including nested NMIs.  Using "-c" boosts the rate of
+   NMIs, and using two -c with separate counters encourages nested NMIs
+   and less deterministic behavior.
+   ::
+
+       while true; do perf record -c 10000 -e instructions,cycles -a sleep 10; done
+
+4. Launch a KVM virtual machine.
+5. Run 32-bit binaries on systems supporting the SYSCALL instruction.
+   This has been a lightly-tested code path and needs extra scrutiny.
+
+Debugging
+=========
+
+Bugs in PTI cause a few different signatures of crashes
+that are worth noting here.
+
+ * Failures of the selftests/x86 code.  Usually a bug in one of the
+   more obscure corners of entry_64.S
+ * Crashes in early boot, especially around CPU bringup.  Bugs
+   in the trampoline code or mappings cause these.
+ * Crashes at the first interrupt.  Caused by bugs in entry_64.S,
+   like screwing up a page table switch.  Also caused by
+   incorrectly mapping the IRQ handler entry code.
+ * Crashes at the first NMI.  The NMI code is separate from main
+   interrupt handlers and can have bugs that do not affect
+   normal interrupts.  Also caused by incorrectly mapping NMI
+   code.  NMIs that interrupt the entry code must be very
+   careful and can be the cause of crashes that show up when
+   running perf.
+ * Kernel crashes at the first exit to userspace.  entry_64.S
+   bugs, or failing to map some of the exit code.
+ * Crashes at first interrupt that interrupts userspace. The paths
+   in entry_64.S that return to userspace are sometimes separate
+   from the ones that return to the kernel.
+ * Double faults: overflowing the kernel stack because of page
+   faults upon page faults.  Caused by touching non-pti-mapped
+   data in the entry code, or forgetting to switch to kernel
+   CR3 before calling into C functions which are not pti-mapped.
+ * Userspace segfaults early in boot, sometimes manifesting
+   as mount(8) failing to mount the rootfs.  These have
+   tended to be TLB invalidation issues.  Usually invalidating
+   the wrong PCID, or otherwise missing an invalidation.
+
+.. [1] https://gruss.cc/files/kaiser.pdf
+.. [2] https://meltdownattack.com/meltdown.pdf
diff --git a/Documentation/arch/x86/resctrl.rst b/Documentation/arch/x86/resctrl.rst
new file mode 100644 (file)
index 0000000..387ccbc
--- /dev/null
@@ -0,0 +1,1447 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: <isonum.txt>
+
+===========================================
+User Interface for Resource Control feature
+===========================================
+
+:Copyright: |copy| 2016 Intel Corporation
+:Authors: - Fenghua Yu <fenghua.yu@intel.com>
+          - Tony Luck <tony.luck@intel.com>
+          - Vikas Shivappa <vikas.shivappa@intel.com>
+
+
+Intel refers to this feature as Intel Resource Director Technology(Intel(R) RDT).
+AMD refers to this feature as AMD Platform Quality of Service(AMD QoS).
+
+This feature is enabled by the CONFIG_X86_CPU_RESCTRL and the x86 /proc/cpuinfo
+flag bits:
+
+===============================================        ================================
+RDT (Resource Director Technology) Allocation  "rdt_a"
+CAT (Cache Allocation Technology)              "cat_l3", "cat_l2"
+CDP (Code and Data Prioritization)             "cdp_l3", "cdp_l2"
+CQM (Cache QoS Monitoring)                     "cqm_llc", "cqm_occup_llc"
+MBM (Memory Bandwidth Monitoring)              "cqm_mbm_total", "cqm_mbm_local"
+MBA (Memory Bandwidth Allocation)              "mba"
+SMBA (Slow Memory Bandwidth Allocation)         ""
+BMEC (Bandwidth Monitoring Event Configuration) ""
+===============================================        ================================
+
+Historically, new features were made visible by default in /proc/cpuinfo. This
+resulted in the feature flags becoming hard to parse by humans. Adding a new
+flag to /proc/cpuinfo should be avoided if user space can obtain information
+about the feature from resctrl's info directory.
+
+To use the feature mount the file system::
+
+ # mount -t resctrl resctrl [-o cdp[,cdpl2][,mba_MBps]] /sys/fs/resctrl
+
+mount options are:
+
+"cdp":
+       Enable code/data prioritization in L3 cache allocations.
+"cdpl2":
+       Enable code/data prioritization in L2 cache allocations.
+"mba_MBps":
+       Enable the MBA Software Controller(mba_sc) to specify MBA
+       bandwidth in MBps
+
+L2 and L3 CDP are controlled separately.
+
+RDT features are orthogonal. A particular system may support only
+monitoring, only control, or both monitoring and control.  Cache
+pseudo-locking is a unique way of using cache control to "pin" or
+"lock" data in the cache. Details can be found in
+"Cache Pseudo-Locking".
+
+
+The mount succeeds if either of allocation or monitoring is present, but
+only those files and directories supported by the system will be created.
+For more details on the behavior of the interface during monitoring
+and allocation, see the "Resource alloc and monitor groups" section.
+
+Info directory
+==============
+
+The 'info' directory contains information about the enabled
+resources. Each resource has its own subdirectory. The subdirectory
+names reflect the resource names.
+
+Each subdirectory contains the following files with respect to
+allocation:
+
+Cache resource(L3/L2)  subdirectory contains the following files
+related to allocation:
+
+"num_closids":
+               The number of CLOSIDs which are valid for this
+               resource. The kernel uses the smallest number of
+               CLOSIDs of all enabled resources as limit.
+"cbm_mask":
+               The bitmask which is valid for this resource.
+               This mask is equivalent to 100%.
+"min_cbm_bits":
+               The minimum number of consecutive bits which
+               must be set when writing a mask.
+
+"shareable_bits":
+               Bitmask of shareable resource with other executing
+               entities (e.g. I/O). User can use this when
+               setting up exclusive cache partitions. Note that
+               some platforms support devices that have their
+               own settings for cache use which can over-ride
+               these bits.
+"bit_usage":
+               Annotated capacity bitmasks showing how all
+               instances of the resource are used. The legend is:
+
+                       "0":
+                             Corresponding region is unused. When the system's
+                             resources have been allocated and a "0" is found
+                             in "bit_usage" it is a sign that resources are
+                             wasted.
+
+                       "H":
+                             Corresponding region is used by hardware only
+                             but available for software use. If a resource
+                             has bits set in "shareable_bits" but not all
+                             of these bits appear in the resource groups'
+                             schematas then the bits appearing in
+                             "shareable_bits" but no resource group will
+                             be marked as "H".
+                       "X":
+                             Corresponding region is available for sharing and
+                             used by hardware and software. These are the
+                             bits that appear in "shareable_bits" as
+                             well as a resource group's allocation.
+                       "S":
+                             Corresponding region is used by software
+                             and available for sharing.
+                       "E":
+                             Corresponding region is used exclusively by
+                             one resource group. No sharing allowed.
+                       "P":
+                             Corresponding region is pseudo-locked. No
+                             sharing allowed.
+
+Memory bandwidth(MB) subdirectory contains the following files
+with respect to allocation:
+
+"min_bandwidth":
+               The minimum memory bandwidth percentage which
+               user can request.
+
+"bandwidth_gran":
+               The granularity in which the memory bandwidth
+               percentage is allocated. The allocated
+               b/w percentage is rounded off to the next
+               control step available on the hardware. The
+               available bandwidth control steps are:
+               min_bandwidth + N * bandwidth_gran.
+
+"delay_linear":
+               Indicates if the delay scale is linear or
+               non-linear. This field is purely informational
+               only.
+
+"thread_throttle_mode":
+               Indicator on Intel systems of how tasks running on threads
+               of a physical core are throttled in cases where they
+               request different memory bandwidth percentages:
+
+               "max":
+                       the smallest percentage is applied
+                       to all threads
+               "per-thread":
+                       bandwidth percentages are directly applied to
+                       the threads running on the core
+
+If RDT monitoring is available there will be an "L3_MON" directory
+with the following files:
+
+"num_rmids":
+               The number of RMIDs available. This is the
+               upper bound for how many "CTRL_MON" + "MON"
+               groups can be created.
+
+"mon_features":
+               Lists the monitoring events if
+               monitoring is enabled for the resource.
+               Example::
+
+                       # cat /sys/fs/resctrl/info/L3_MON/mon_features
+                       llc_occupancy
+                       mbm_total_bytes
+                       mbm_local_bytes
+
+               If the system supports Bandwidth Monitoring Event
+               Configuration (BMEC), then the bandwidth events will
+               be configurable. The output will be::
+
+                       # cat /sys/fs/resctrl/info/L3_MON/mon_features
+                       llc_occupancy
+                       mbm_total_bytes
+                       mbm_total_bytes_config
+                       mbm_local_bytes
+                       mbm_local_bytes_config
+
+"mbm_total_bytes_config", "mbm_local_bytes_config":
+       Read/write files containing the configuration for the mbm_total_bytes
+       and mbm_local_bytes events, respectively, when the Bandwidth
+       Monitoring Event Configuration (BMEC) feature is supported.
+       The event configuration settings are domain specific and affect
+       all the CPUs in the domain. When either event configuration is
+       changed, the bandwidth counters for all RMIDs of both events
+       (mbm_total_bytes as well as mbm_local_bytes) are cleared for that
+       domain. The next read for every RMID will report "Unavailable"
+       and subsequent reads will report the valid value.
+
+       Following are the types of events supported:
+
+       ====    ========================================================
+       Bits    Description
+       ====    ========================================================
+       6       Dirty Victims from the QOS domain to all types of memory
+       5       Reads to slow memory in the non-local NUMA domain
+       4       Reads to slow memory in the local NUMA domain
+       3       Non-temporal writes to non-local NUMA domain
+       2       Non-temporal writes to local NUMA domain
+       1       Reads to memory in the non-local NUMA domain
+       0       Reads to memory in the local NUMA domain
+       ====    ========================================================
+
+       By default, the mbm_total_bytes configuration is set to 0x7f to count
+       all the event types and the mbm_local_bytes configuration is set to
+       0x15 to count all the local memory events.
+
+       Examples:
+
+       * To view the current configuration::
+         ::
+
+           # cat /sys/fs/resctrl/info/L3_MON/mbm_total_bytes_config
+           0=0x7f;1=0x7f;2=0x7f;3=0x7f
+
+           # cat /sys/fs/resctrl/info/L3_MON/mbm_local_bytes_config
+           0=0x15;1=0x15;3=0x15;4=0x15
+
+       * To change the mbm_total_bytes to count only reads on domain 0,
+         the bits 0, 1, 4 and 5 needs to be set, which is 110011b in binary
+         (in hexadecimal 0x33):
+         ::
+
+           # echo  "0=0x33" > /sys/fs/resctrl/info/L3_MON/mbm_total_bytes_config
+
+           # cat /sys/fs/resctrl/info/L3_MON/mbm_total_bytes_config
+           0=0x33;1=0x7f;2=0x7f;3=0x7f
+
+       * To change the mbm_local_bytes to count all the slow memory reads on
+         domain 0 and 1, the bits 4 and 5 needs to be set, which is 110000b
+         in binary (in hexadecimal 0x30):
+         ::
+
+           # echo  "0=0x30;1=0x30" > /sys/fs/resctrl/info/L3_MON/mbm_local_bytes_config
+
+           # cat /sys/fs/resctrl/info/L3_MON/mbm_local_bytes_config
+           0=0x30;1=0x30;3=0x15;4=0x15
+
+"max_threshold_occupancy":
+               Read/write file provides the largest value (in
+               bytes) at which a previously used LLC_occupancy
+               counter can be considered for re-use.
+
+Finally, in the top level of the "info" directory there is a file
+named "last_cmd_status". This is reset with every "command" issued
+via the file system (making new directories or writing to any of the
+control files). If the command was successful, it will read as "ok".
+If the command failed, it will provide more information that can be
+conveyed in the error returns from file operations. E.g.
+::
+
+       # echo L3:0=f7 > schemata
+       bash: echo: write error: Invalid argument
+       # cat info/last_cmd_status
+       mask f7 has non-consecutive 1-bits
+
+Resource alloc and monitor groups
+=================================
+
+Resource groups are represented as directories in the resctrl file
+system.  The default group is the root directory which, immediately
+after mounting, owns all the tasks and cpus in the system and can make
+full use of all resources.
+
+On a system with RDT control features additional directories can be
+created in the root directory that specify different amounts of each
+resource (see "schemata" below). The root and these additional top level
+directories are referred to as "CTRL_MON" groups below.
+
+On a system with RDT monitoring the root directory and other top level
+directories contain a directory named "mon_groups" in which additional
+directories can be created to monitor subsets of tasks in the CTRL_MON
+group that is their ancestor. These are called "MON" groups in the rest
+of this document.
+
+Removing a directory will move all tasks and cpus owned by the group it
+represents to the parent. Removing one of the created CTRL_MON groups
+will automatically remove all MON groups below it.
+
+All groups contain the following files:
+
+"tasks":
+       Reading this file shows the list of all tasks that belong to
+       this group. Writing a task id to the file will add a task to the
+       group. If the group is a CTRL_MON group the task is removed from
+       whichever previous CTRL_MON group owned the task and also from
+       any MON group that owned the task. If the group is a MON group,
+       then the task must already belong to the CTRL_MON parent of this
+       group. The task is removed from any previous MON group.
+
+
+"cpus":
+       Reading this file shows a bitmask of the logical CPUs owned by
+       this group. Writing a mask to this file will add and remove
+       CPUs to/from this group. As with the tasks file a hierarchy is
+       maintained where MON groups may only include CPUs owned by the
+       parent CTRL_MON group.
+       When the resource group is in pseudo-locked mode this file will
+       only be readable, reflecting the CPUs associated with the
+       pseudo-locked region.
+
+
+"cpus_list":
+       Just like "cpus", only using ranges of CPUs instead of bitmasks.
+
+
+When control is enabled all CTRL_MON groups will also contain:
+
+"schemata":
+       A list of all the resources available to this group.
+       Each resource has its own line and format - see below for details.
+
+"size":
+       Mirrors the display of the "schemata" file to display the size in
+       bytes of each allocation instead of the bits representing the
+       allocation.
+
+"mode":
+       The "mode" of the resource group dictates the sharing of its
+       allocations. A "shareable" resource group allows sharing of its
+       allocations while an "exclusive" resource group does not. A
+       cache pseudo-locked region is created by first writing
+       "pseudo-locksetup" to the "mode" file before writing the cache
+       pseudo-locked region's schemata to the resource group's "schemata"
+       file. On successful pseudo-locked region creation the mode will
+       automatically change to "pseudo-locked".
+
+When monitoring is enabled all MON groups will also contain:
+
+"mon_data":
+       This contains a set of files organized by L3 domain and by
+       RDT event. E.g. on a system with two L3 domains there will
+       be subdirectories "mon_L3_00" and "mon_L3_01".  Each of these
+       directories have one file per event (e.g. "llc_occupancy",
+       "mbm_total_bytes", and "mbm_local_bytes"). In a MON group these
+       files provide a read out of the current value of the event for
+       all tasks in the group. In CTRL_MON groups these files provide
+       the sum for all tasks in the CTRL_MON group and all tasks in
+       MON groups. Please see example section for more details on usage.
+
+Resource allocation rules
+-------------------------
+
+When a task is running the following rules define which resources are
+available to it:
+
+1) If the task is a member of a non-default group, then the schemata
+   for that group is used.
+
+2) Else if the task belongs to the default group, but is running on a
+   CPU that is assigned to some specific group, then the schemata for the
+   CPU's group is used.
+
+3) Otherwise the schemata for the default group is used.
+
+Resource monitoring rules
+-------------------------
+1) If a task is a member of a MON group, or non-default CTRL_MON group
+   then RDT events for the task will be reported in that group.
+
+2) If a task is a member of the default CTRL_MON group, but is running
+   on a CPU that is assigned to some specific group, then the RDT events
+   for the task will be reported in that group.
+
+3) Otherwise RDT events for the task will be reported in the root level
+   "mon_data" group.
+
+
+Notes on cache occupancy monitoring and control
+===============================================
+When moving a task from one group to another you should remember that
+this only affects *new* cache allocations by the task. E.g. you may have
+a task in a monitor group showing 3 MB of cache occupancy. If you move
+to a new group and immediately check the occupancy of the old and new
+groups you will likely see that the old group is still showing 3 MB and
+the new group zero. When the task accesses locations still in cache from
+before the move, the h/w does not update any counters. On a busy system
+you will likely see the occupancy in the old group go down as cache lines
+are evicted and re-used while the occupancy in the new group rises as
+the task accesses memory and loads into the cache are counted based on
+membership in the new group.
+
+The same applies to cache allocation control. Moving a task to a group
+with a smaller cache partition will not evict any cache lines. The
+process may continue to use them from the old partition.
+
+Hardware uses CLOSid(Class of service ID) and an RMID(Resource monitoring ID)
+to identify a control group and a monitoring group respectively. Each of
+the resource groups are mapped to these IDs based on the kind of group. The
+number of CLOSid and RMID are limited by the hardware and hence the creation of
+a "CTRL_MON" directory may fail if we run out of either CLOSID or RMID
+and creation of "MON" group may fail if we run out of RMIDs.
+
+max_threshold_occupancy - generic concepts
+------------------------------------------
+
+Note that an RMID once freed may not be immediately available for use as
+the RMID is still tagged the cache lines of the previous user of RMID.
+Hence such RMIDs are placed on limbo list and checked back if the cache
+occupancy has gone down. If there is a time when system has a lot of
+limbo RMIDs but which are not ready to be used, user may see an -EBUSY
+during mkdir.
+
+max_threshold_occupancy is a user configurable value to determine the
+occupancy at which an RMID can be freed.
+
+Schemata files - general concepts
+---------------------------------
+Each line in the file describes one resource. The line starts with
+the name of the resource, followed by specific values to be applied
+in each of the instances of that resource on the system.
+
+Cache IDs
+---------
+On current generation systems there is one L3 cache per socket and L2
+caches are generally just shared by the hyperthreads on a core, but this
+isn't an architectural requirement. We could have multiple separate L3
+caches on a socket, multiple cores could share an L2 cache. So instead
+of using "socket" or "core" to define the set of logical cpus sharing
+a resource we use a "Cache ID". At a given cache level this will be a
+unique number across the whole system (but it isn't guaranteed to be a
+contiguous sequence, there may be gaps).  To find the ID for each logical
+CPU look in /sys/devices/system/cpu/cpu*/cache/index*/id
+
+Cache Bit Masks (CBM)
+---------------------
+For cache resources we describe the portion of the cache that is available
+for allocation using a bitmask. The maximum value of the mask is defined
+by each cpu model (and may be different for different cache levels). It
+is found using CPUID, but is also provided in the "info" directory of
+the resctrl file system in "info/{resource}/cbm_mask". Intel hardware
+requires that these masks have all the '1' bits in a contiguous block. So
+0x3, 0x6 and 0xC are legal 4-bit masks with two bits set, but 0x5, 0x9
+and 0xA are not.  On a system with a 20-bit mask each bit represents 5%
+of the capacity of the cache. You could partition the cache into four
+equal parts with masks: 0x1f, 0x3e0, 0x7c00, 0xf8000.
+
+Memory bandwidth Allocation and monitoring
+==========================================
+
+For Memory bandwidth resource, by default the user controls the resource
+by indicating the percentage of total memory bandwidth.
+
+The minimum bandwidth percentage value for each cpu model is predefined
+and can be looked up through "info/MB/min_bandwidth". The bandwidth
+granularity that is allocated is also dependent on the cpu model and can
+be looked up at "info/MB/bandwidth_gran". The available bandwidth
+control steps are: min_bw + N * bw_gran. Intermediate values are rounded
+to the next control step available on the hardware.
+
+The bandwidth throttling is a core specific mechanism on some of Intel
+SKUs. Using a high bandwidth and a low bandwidth setting on two threads
+sharing a core may result in both threads being throttled to use the
+low bandwidth (see "thread_throttle_mode").
+
+The fact that Memory bandwidth allocation(MBA) may be a core
+specific mechanism where as memory bandwidth monitoring(MBM) is done at
+the package level may lead to confusion when users try to apply control
+via the MBA and then monitor the bandwidth to see if the controls are
+effective. Below are such scenarios:
+
+1. User may *not* see increase in actual bandwidth when percentage
+   values are increased:
+
+This can occur when aggregate L2 external bandwidth is more than L3
+external bandwidth. Consider an SKL SKU with 24 cores on a package and
+where L2 external  is 10GBps (hence aggregate L2 external bandwidth is
+240GBps) and L3 external bandwidth is 100GBps. Now a workload with '20
+threads, having 50% bandwidth, each consuming 5GBps' consumes the max L3
+bandwidth of 100GBps although the percentage value specified is only 50%
+<< 100%. Hence increasing the bandwidth percentage will not yield any
+more bandwidth. This is because although the L2 external bandwidth still
+has capacity, the L3 external bandwidth is fully used. Also note that
+this would be dependent on number of cores the benchmark is run on.
+
+2. Same bandwidth percentage may mean different actual bandwidth
+   depending on # of threads:
+
+For the same SKU in #1, a 'single thread, with 10% bandwidth' and '4
+thread, with 10% bandwidth' can consume upto 10GBps and 40GBps although
+they have same percentage bandwidth of 10%. This is simply because as
+threads start using more cores in an rdtgroup, the actual bandwidth may
+increase or vary although user specified bandwidth percentage is same.
+
+In order to mitigate this and make the interface more user friendly,
+resctrl added support for specifying the bandwidth in MBps as well.  The
+kernel underneath would use a software feedback mechanism or a "Software
+Controller(mba_sc)" which reads the actual bandwidth using MBM counters
+and adjust the memory bandwidth percentages to ensure::
+
+       "actual bandwidth < user specified bandwidth".
+
+By default, the schemata would take the bandwidth percentage values
+where as user can switch to the "MBA software controller" mode using
+a mount option 'mba_MBps'. The schemata format is specified in the below
+sections.
+
+L3 schemata file details (code and data prioritization disabled)
+----------------------------------------------------------------
+With CDP disabled the L3 schemata format is::
+
+       L3:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
+
+L3 schemata file details (CDP enabled via mount option to resctrl)
+------------------------------------------------------------------
+When CDP is enabled L3 control is split into two separate resources
+so you can specify independent masks for code and data like this::
+
+       L3DATA:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
+       L3CODE:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
+
+L2 schemata file details
+------------------------
+CDP is supported at L2 using the 'cdpl2' mount option. The schemata
+format is either::
+
+       L2:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
+
+or
+
+       L2DATA:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
+       L2CODE:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
+
+
+Memory bandwidth Allocation (default mode)
+------------------------------------------
+
+Memory b/w domain is L3 cache.
+::
+
+       MB:<cache_id0>=bandwidth0;<cache_id1>=bandwidth1;...
+
+Memory bandwidth Allocation specified in MBps
+---------------------------------------------
+
+Memory bandwidth domain is L3 cache.
+::
+
+       MB:<cache_id0>=bw_MBps0;<cache_id1>=bw_MBps1;...
+
+Slow Memory Bandwidth Allocation (SMBA)
+---------------------------------------
+AMD hardware supports Slow Memory Bandwidth Allocation (SMBA).
+CXL.memory is the only supported "slow" memory device. With the
+support of SMBA, the hardware enables bandwidth allocation on
+the slow memory devices. If there are multiple such devices in
+the system, the throttling logic groups all the slow sources
+together and applies the limit on them as a whole.
+
+The presence of SMBA (with CXL.memory) is independent of slow memory
+devices presence. If there are no such devices on the system, then
+configuring SMBA will have no impact on the performance of the system.
+
+The bandwidth domain for slow memory is L3 cache. Its schemata file
+is formatted as:
+::
+
+       SMBA:<cache_id0>=bandwidth0;<cache_id1>=bandwidth1;...
+
+Reading/writing the schemata file
+---------------------------------
+Reading the schemata file will show the state of all resources
+on all domains. When writing you only need to specify those values
+which you wish to change.  E.g.
+::
+
+  # cat schemata
+  L3DATA:0=fffff;1=fffff;2=fffff;3=fffff
+  L3CODE:0=fffff;1=fffff;2=fffff;3=fffff
+  # echo "L3DATA:2=3c0;" > schemata
+  # cat schemata
+  L3DATA:0=fffff;1=fffff;2=3c0;3=fffff
+  L3CODE:0=fffff;1=fffff;2=fffff;3=fffff
+
+Reading/writing the schemata file (on AMD systems)
+--------------------------------------------------
+Reading the schemata file will show the current bandwidth limit on all
+domains. The allocated resources are in multiples of one eighth GB/s.
+When writing to the file, you need to specify what cache id you wish to
+configure the bandwidth limit.
+
+For example, to allocate 2GB/s limit on the first cache id:
+
+::
+
+  # cat schemata
+    MB:0=2048;1=2048;2=2048;3=2048
+    L3:0=ffff;1=ffff;2=ffff;3=ffff
+
+  # echo "MB:1=16" > schemata
+  # cat schemata
+    MB:0=2048;1=  16;2=2048;3=2048
+    L3:0=ffff;1=ffff;2=ffff;3=ffff
+
+Reading/writing the schemata file (on AMD systems) with SMBA feature
+--------------------------------------------------------------------
+Reading and writing the schemata file is the same as without SMBA in
+above section.
+
+For example, to allocate 8GB/s limit on the first cache id:
+
+::
+
+  # cat schemata
+    SMBA:0=2048;1=2048;2=2048;3=2048
+      MB:0=2048;1=2048;2=2048;3=2048
+      L3:0=ffff;1=ffff;2=ffff;3=ffff
+
+  # echo "SMBA:1=64" > schemata
+  # cat schemata
+    SMBA:0=2048;1=  64;2=2048;3=2048
+      MB:0=2048;1=2048;2=2048;3=2048
+      L3:0=ffff;1=ffff;2=ffff;3=ffff
+
+Cache Pseudo-Locking
+====================
+CAT enables a user to specify the amount of cache space that an
+application can fill. Cache pseudo-locking builds on the fact that a
+CPU can still read and write data pre-allocated outside its current
+allocated area on a cache hit. With cache pseudo-locking, data can be
+preloaded into a reserved portion of cache that no application can
+fill, and from that point on will only serve cache hits. The cache
+pseudo-locked memory is made accessible to user space where an
+application can map it into its virtual address space and thus have
+a region of memory with reduced average read latency.
+
+The creation of a cache pseudo-locked region is triggered by a request
+from the user to do so that is accompanied by a schemata of the region
+to be pseudo-locked. The cache pseudo-locked region is created as follows:
+
+- Create a CAT allocation CLOSNEW with a CBM matching the schemata
+  from the user of the cache region that will contain the pseudo-locked
+  memory. This region must not overlap with any current CAT allocation/CLOS
+  on the system and no future overlap with this cache region is allowed
+  while the pseudo-locked region exists.
+- Create a contiguous region of memory of the same size as the cache
+  region.
+- Flush the cache, disable hardware prefetchers, disable preemption.
+- Make CLOSNEW the active CLOS and touch the allocated memory to load
+  it into the cache.
+- Set the previous CLOS as active.
+- At this point the closid CLOSNEW can be released - the cache
+  pseudo-locked region is protected as long as its CBM does not appear in
+  any CAT allocation. Even though the cache pseudo-locked region will from
+  this point on not appear in any CBM of any CLOS an application running with
+  any CLOS will be able to access the memory in the pseudo-locked region since
+  the region continues to serve cache hits.
+- The contiguous region of memory loaded into the cache is exposed to
+  user-space as a character device.
+
+Cache pseudo-locking increases the probability that data will remain
+in the cache via carefully configuring the CAT feature and controlling
+application behavior. There is no guarantee that data is placed in
+cache. Instructions like INVD, WBINVD, CLFLUSH, etc. can still evict
+“locked” data from cache. Power management C-states may shrink or
+power off cache. Deeper C-states will automatically be restricted on
+pseudo-locked region creation.
+
+It is required that an application using a pseudo-locked region runs
+with affinity to the cores (or a subset of the cores) associated
+with the cache on which the pseudo-locked region resides. A sanity check
+within the code will not allow an application to map pseudo-locked memory
+unless it runs with affinity to cores associated with the cache on which the
+pseudo-locked region resides. The sanity check is only done during the
+initial mmap() handling, there is no enforcement afterwards and the
+application self needs to ensure it remains affine to the correct cores.
+
+Pseudo-locking is accomplished in two stages:
+
+1) During the first stage the system administrator allocates a portion
+   of cache that should be dedicated to pseudo-locking. At this time an
+   equivalent portion of memory is allocated, loaded into allocated
+   cache portion, and exposed as a character device.
+2) During the second stage a user-space application maps (mmap()) the
+   pseudo-locked memory into its address space.
+
+Cache Pseudo-Locking Interface
+------------------------------
+A pseudo-locked region is created using the resctrl interface as follows:
+
+1) Create a new resource group by creating a new directory in /sys/fs/resctrl.
+2) Change the new resource group's mode to "pseudo-locksetup" by writing
+   "pseudo-locksetup" to the "mode" file.
+3) Write the schemata of the pseudo-locked region to the "schemata" file. All
+   bits within the schemata should be "unused" according to the "bit_usage"
+   file.
+
+On successful pseudo-locked region creation the "mode" file will contain
+"pseudo-locked" and a new character device with the same name as the resource
+group will exist in /dev/pseudo_lock. This character device can be mmap()'ed
+by user space in order to obtain access to the pseudo-locked memory region.
+
+An example of cache pseudo-locked region creation and usage can be found below.
+
+Cache Pseudo-Locking Debugging Interface
+----------------------------------------
+The pseudo-locking debugging interface is enabled by default (if
+CONFIG_DEBUG_FS is enabled) and can be found in /sys/kernel/debug/resctrl.
+
+There is no explicit way for the kernel to test if a provided memory
+location is present in the cache. The pseudo-locking debugging interface uses
+the tracing infrastructure to provide two ways to measure cache residency of
+the pseudo-locked region:
+
+1) Memory access latency using the pseudo_lock_mem_latency tracepoint. Data
+   from these measurements are best visualized using a hist trigger (see
+   example below). In this test the pseudo-locked region is traversed at
+   a stride of 32 bytes while hardware prefetchers and preemption
+   are disabled. This also provides a substitute visualization of cache
+   hits and misses.
+2) Cache hit and miss measurements using model specific precision counters if
+   available. Depending on the levels of cache on the system the pseudo_lock_l2
+   and pseudo_lock_l3 tracepoints are available.
+
+When a pseudo-locked region is created a new debugfs directory is created for
+it in debugfs as /sys/kernel/debug/resctrl/<newdir>. A single
+write-only file, pseudo_lock_measure, is present in this directory. The
+measurement of the pseudo-locked region depends on the number written to this
+debugfs file:
+
+1:
+     writing "1" to the pseudo_lock_measure file will trigger the latency
+     measurement captured in the pseudo_lock_mem_latency tracepoint. See
+     example below.
+2:
+     writing "2" to the pseudo_lock_measure file will trigger the L2 cache
+     residency (cache hits and misses) measurement captured in the
+     pseudo_lock_l2 tracepoint. See example below.
+3:
+     writing "3" to the pseudo_lock_measure file will trigger the L3 cache
+     residency (cache hits and misses) measurement captured in the
+     pseudo_lock_l3 tracepoint.
+
+All measurements are recorded with the tracing infrastructure. This requires
+the relevant tracepoints to be enabled before the measurement is triggered.
+
+Example of latency debugging interface
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In this example a pseudo-locked region named "newlock" was created. Here is
+how we can measure the latency in cycles of reading from this region and
+visualize this data with a histogram that is available if CONFIG_HIST_TRIGGERS
+is set::
+
+  # :> /sys/kernel/tracing/trace
+  # echo 'hist:keys=latency' > /sys/kernel/tracing/events/resctrl/pseudo_lock_mem_latency/trigger
+  # echo 1 > /sys/kernel/tracing/events/resctrl/pseudo_lock_mem_latency/enable
+  # echo 1 > /sys/kernel/debug/resctrl/newlock/pseudo_lock_measure
+  # echo 0 > /sys/kernel/tracing/events/resctrl/pseudo_lock_mem_latency/enable
+  # cat /sys/kernel/tracing/events/resctrl/pseudo_lock_mem_latency/hist
+
+  # event histogram
+  #
+  # trigger info: hist:keys=latency:vals=hitcount:sort=hitcount:size=2048 [active]
+  #
+
+  { latency:        456 } hitcount:          1
+  { latency:         50 } hitcount:         83
+  { latency:         36 } hitcount:         96
+  { latency:         44 } hitcount:        174
+  { latency:         48 } hitcount:        195
+  { latency:         46 } hitcount:        262
+  { latency:         42 } hitcount:        693
+  { latency:         40 } hitcount:       3204
+  { latency:         38 } hitcount:       3484
+
+  Totals:
+      Hits: 8192
+      Entries: 9
+    Dropped: 0
+
+Example of cache hits/misses debugging
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In this example a pseudo-locked region named "newlock" was created on the L2
+cache of a platform. Here is how we can obtain details of the cache hits
+and misses using the platform's precision counters.
+::
+
+  # :> /sys/kernel/tracing/trace
+  # echo 1 > /sys/kernel/tracing/events/resctrl/pseudo_lock_l2/enable
+  # echo 2 > /sys/kernel/debug/resctrl/newlock/pseudo_lock_measure
+  # echo 0 > /sys/kernel/tracing/events/resctrl/pseudo_lock_l2/enable
+  # cat /sys/kernel/tracing/trace
+
+  # tracer: nop
+  #
+  #                              _-----=> irqs-off
+  #                             / _----=> need-resched
+  #                            | / _---=> hardirq/softirq
+  #                            || / _--=> preempt-depth
+  #                            ||| /     delay
+  #           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
+  #              | |       |   ||||       |         |
+  pseudo_lock_mea-1672  [002] ....  3132.860500: pseudo_lock_l2: hits=4097 miss=0
+
+
+Examples for RDT allocation usage
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+1) Example 1
+
+On a two socket machine (one L3 cache per socket) with just four bits
+for cache bit masks, minimum b/w of 10% with a memory bandwidth
+granularity of 10%.
+::
+
+  # mount -t resctrl resctrl /sys/fs/resctrl
+  # cd /sys/fs/resctrl
+  # mkdir p0 p1
+  # echo "L3:0=3;1=c\nMB:0=50;1=50" > /sys/fs/resctrl/p0/schemata
+  # echo "L3:0=3;1=3\nMB:0=50;1=50" > /sys/fs/resctrl/p1/schemata
+
+The default resource group is unmodified, so we have access to all parts
+of all caches (its schemata file reads "L3:0=f;1=f").
+
+Tasks that are under the control of group "p0" may only allocate from the
+"lower" 50% on cache ID 0, and the "upper" 50% of cache ID 1.
+Tasks in group "p1" use the "lower" 50% of cache on both sockets.
+
+Similarly, tasks that are under the control of group "p0" may use a
+maximum memory b/w of 50% on socket0 and 50% on socket 1.
+Tasks in group "p1" may also use 50% memory b/w on both sockets.
+Note that unlike cache masks, memory b/w cannot specify whether these
+allocations can overlap or not. The allocations specifies the maximum
+b/w that the group may be able to use and the system admin can configure
+the b/w accordingly.
+
+If resctrl is using the software controller (mba_sc) then user can enter the
+max b/w in MB rather than the percentage values.
+::
+
+  # echo "L3:0=3;1=c\nMB:0=1024;1=500" > /sys/fs/resctrl/p0/schemata
+  # echo "L3:0=3;1=3\nMB:0=1024;1=500" > /sys/fs/resctrl/p1/schemata
+
+In the above example the tasks in "p1" and "p0" on socket 0 would use a max b/w
+of 1024MB where as on socket 1 they would use 500MB.
+
+2) Example 2
+
+Again two sockets, but this time with a more realistic 20-bit mask.
+
+Two real time tasks pid=1234 running on processor 0 and pid=5678 running on
+processor 1 on socket 0 on a 2-socket and dual core machine. To avoid noisy
+neighbors, each of the two real-time tasks exclusively occupies one quarter
+of L3 cache on socket 0.
+::
+
+  # mount -t resctrl resctrl /sys/fs/resctrl
+  # cd /sys/fs/resctrl
+
+First we reset the schemata for the default group so that the "upper"
+50% of the L3 cache on socket 0 and 50% of memory b/w cannot be used by
+ordinary tasks::
+
+  # echo "L3:0=3ff;1=fffff\nMB:0=50;1=100" > schemata
+
+Next we make a resource group for our first real time task and give
+it access to the "top" 25% of the cache on socket 0.
+::
+
+  # mkdir p0
+  # echo "L3:0=f8000;1=fffff" > p0/schemata
+
+Finally we move our first real time task into this resource group. We
+also use taskset(1) to ensure the task always runs on a dedicated CPU
+on socket 0. Most uses of resource groups will also constrain which
+processors tasks run on.
+::
+
+  # echo 1234 > p0/tasks
+  # taskset -cp 1 1234
+
+Ditto for the second real time task (with the remaining 25% of cache)::
+
+  # mkdir p1
+  # echo "L3:0=7c00;1=fffff" > p1/schemata
+  # echo 5678 > p1/tasks
+  # taskset -cp 2 5678
+
+For the same 2 socket system with memory b/w resource and CAT L3 the
+schemata would look like(Assume min_bandwidth 10 and bandwidth_gran is
+10):
+
+For our first real time task this would request 20% memory b/w on socket 0.
+::
+
+  # echo -e "L3:0=f8000;1=fffff\nMB:0=20;1=100" > p0/schemata
+
+For our second real time task this would request an other 20% memory b/w
+on socket 0.
+::
+
+  # echo -e "L3:0=f8000;1=fffff\nMB:0=20;1=100" > p0/schemata
+
+3) Example 3
+
+A single socket system which has real-time tasks running on core 4-7 and
+non real-time workload assigned to core 0-3. The real-time tasks share text
+and data, so a per task association is not required and due to interaction
+with the kernel it's desired that the kernel on these cores shares L3 with
+the tasks.
+::
+
+  # mount -t resctrl resctrl /sys/fs/resctrl
+  # cd /sys/fs/resctrl
+
+First we reset the schemata for the default group so that the "upper"
+50% of the L3 cache on socket 0, and 50% of memory bandwidth on socket 0
+cannot be used by ordinary tasks::
+
+  # echo "L3:0=3ff\nMB:0=50" > schemata
+
+Next we make a resource group for our real time cores and give it access
+to the "top" 50% of the cache on socket 0 and 50% of memory bandwidth on
+socket 0.
+::
+
+  # mkdir p0
+  # echo "L3:0=ffc00\nMB:0=50" > p0/schemata
+
+Finally we move core 4-7 over to the new group and make sure that the
+kernel and the tasks running there get 50% of the cache. They should
+also get 50% of memory bandwidth assuming that the cores 4-7 are SMT
+siblings and only the real time threads are scheduled on the cores 4-7.
+::
+
+  # echo F0 > p0/cpus
+
+4) Example 4
+
+The resource groups in previous examples were all in the default "shareable"
+mode allowing sharing of their cache allocations. If one resource group
+configures a cache allocation then nothing prevents another resource group
+to overlap with that allocation.
+
+In this example a new exclusive resource group will be created on a L2 CAT
+system with two L2 cache instances that can be configured with an 8-bit
+capacity bitmask. The new exclusive resource group will be configured to use
+25% of each cache instance.
+::
+
+  # mount -t resctrl resctrl /sys/fs/resctrl/
+  # cd /sys/fs/resctrl
+
+First, we observe that the default group is configured to allocate to all L2
+cache::
+
+  # cat schemata
+  L2:0=ff;1=ff
+
+We could attempt to create the new resource group at this point, but it will
+fail because of the overlap with the schemata of the default group::
+
+  # mkdir p0
+  # echo 'L2:0=0x3;1=0x3' > p0/schemata
+  # cat p0/mode
+  shareable
+  # echo exclusive > p0/mode
+  -sh: echo: write error: Invalid argument
+  # cat info/last_cmd_status
+  schemata overlaps
+
+To ensure that there is no overlap with another resource group the default
+resource group's schemata has to change, making it possible for the new
+resource group to become exclusive.
+::
+
+  # echo 'L2:0=0xfc;1=0xfc' > schemata
+  # echo exclusive > p0/mode
+  # grep . p0/*
+  p0/cpus:0
+  p0/mode:exclusive
+  p0/schemata:L2:0=03;1=03
+  p0/size:L2:0=262144;1=262144
+
+A new resource group will on creation not overlap with an exclusive resource
+group::
+
+  # mkdir p1
+  # grep . p1/*
+  p1/cpus:0
+  p1/mode:shareable
+  p1/schemata:L2:0=fc;1=fc
+  p1/size:L2:0=786432;1=786432
+
+The bit_usage will reflect how the cache is used::
+
+  # cat info/L2/bit_usage
+  0=SSSSSSEE;1=SSSSSSEE
+
+A resource group cannot be forced to overlap with an exclusive resource group::
+
+  # echo 'L2:0=0x1;1=0x1' > p1/schemata
+  -sh: echo: write error: Invalid argument
+  # cat info/last_cmd_status
+  overlaps with exclusive group
+
+Example of Cache Pseudo-Locking
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Lock portion of L2 cache from cache id 1 using CBM 0x3. Pseudo-locked
+region is exposed at /dev/pseudo_lock/newlock that can be provided to
+application for argument to mmap().
+::
+
+  # mount -t resctrl resctrl /sys/fs/resctrl/
+  # cd /sys/fs/resctrl
+
+Ensure that there are bits available that can be pseudo-locked, since only
+unused bits can be pseudo-locked the bits to be pseudo-locked needs to be
+removed from the default resource group's schemata::
+
+  # cat info/L2/bit_usage
+  0=SSSSSSSS;1=SSSSSSSS
+  # echo 'L2:1=0xfc' > schemata
+  # cat info/L2/bit_usage
+  0=SSSSSSSS;1=SSSSSS00
+
+Create a new resource group that will be associated with the pseudo-locked
+region, indicate that it will be used for a pseudo-locked region, and
+configure the requested pseudo-locked region capacity bitmask::
+
+  # mkdir newlock
+  # echo pseudo-locksetup > newlock/mode
+  # echo 'L2:1=0x3' > newlock/schemata
+
+On success the resource group's mode will change to pseudo-locked, the
+bit_usage will reflect the pseudo-locked region, and the character device
+exposing the pseudo-locked region will exist::
+
+  # cat newlock/mode
+  pseudo-locked
+  # cat info/L2/bit_usage
+  0=SSSSSSSS;1=SSSSSSPP
+  # ls -l /dev/pseudo_lock/newlock
+  crw------- 1 root root 243, 0 Apr  3 05:01 /dev/pseudo_lock/newlock
+
+::
+
+  /*
+  * Example code to access one page of pseudo-locked cache region
+  * from user space.
+  */
+  #define _GNU_SOURCE
+  #include <fcntl.h>
+  #include <sched.h>
+  #include <stdio.h>
+  #include <stdlib.h>
+  #include <unistd.h>
+  #include <sys/mman.h>
+
+  /*
+  * It is required that the application runs with affinity to only
+  * cores associated with the pseudo-locked region. Here the cpu
+  * is hardcoded for convenience of example.
+  */
+  static int cpuid = 2;
+
+  int main(int argc, char *argv[])
+  {
+    cpu_set_t cpuset;
+    long page_size;
+    void *mapping;
+    int dev_fd;
+    int ret;
+
+    page_size = sysconf(_SC_PAGESIZE);
+
+    CPU_ZERO(&cpuset);
+    CPU_SET(cpuid, &cpuset);
+    ret = sched_setaffinity(0, sizeof(cpuset), &cpuset);
+    if (ret < 0) {
+      perror("sched_setaffinity");
+      exit(EXIT_FAILURE);
+    }
+
+    dev_fd = open("/dev/pseudo_lock/newlock", O_RDWR);
+    if (dev_fd < 0) {
+      perror("open");
+      exit(EXIT_FAILURE);
+    }
+
+    mapping = mmap(0, page_size, PROT_READ | PROT_WRITE, MAP_SHARED,
+            dev_fd, 0);
+    if (mapping == MAP_FAILED) {
+      perror("mmap");
+      close(dev_fd);
+      exit(EXIT_FAILURE);
+    }
+
+    /* Application interacts with pseudo-locked memory @mapping */
+
+    ret = munmap(mapping, page_size);
+    if (ret < 0) {
+      perror("munmap");
+      close(dev_fd);
+      exit(EXIT_FAILURE);
+    }
+
+    close(dev_fd);
+    exit(EXIT_SUCCESS);
+  }
+
+Locking between applications
+----------------------------
+
+Certain operations on the resctrl filesystem, composed of read/writes
+to/from multiple files, must be atomic.
+
+As an example, the allocation of an exclusive reservation of L3 cache
+involves:
+
+  1. Read the cbmmasks from each directory or the per-resource "bit_usage"
+  2. Find a contiguous set of bits in the global CBM bitmask that is clear
+     in any of the directory cbmmasks
+  3. Create a new directory
+  4. Set the bits found in step 2 to the new directory "schemata" file
+
+If two applications attempt to allocate space concurrently then they can
+end up allocating the same bits so the reservations are shared instead of
+exclusive.
+
+To coordinate atomic operations on the resctrlfs and to avoid the problem
+above, the following locking procedure is recommended:
+
+Locking is based on flock, which is available in libc and also as a shell
+script command
+
+Write lock:
+
+ A) Take flock(LOCK_EX) on /sys/fs/resctrl
+ B) Read/write the directory structure.
+ C) funlock
+
+Read lock:
+
+ A) Take flock(LOCK_SH) on /sys/fs/resctrl
+ B) If success read the directory structure.
+ C) funlock
+
+Example with bash::
+
+  # Atomically read directory structure
+  $ flock -s /sys/fs/resctrl/ find /sys/fs/resctrl
+
+  # Read directory contents and create new subdirectory
+
+  $ cat create-dir.sh
+  find /sys/fs/resctrl/ > output.txt
+  mask = function-of(output.txt)
+  mkdir /sys/fs/resctrl/newres/
+  echo mask > /sys/fs/resctrl/newres/schemata
+
+  $ flock /sys/fs/resctrl/ ./create-dir.sh
+
+Example with C::
+
+  /*
+  * Example code do take advisory locks
+  * before accessing resctrl filesystem
+  */
+  #include <sys/file.h>
+  #include <stdlib.h>
+
+  void resctrl_take_shared_lock(int fd)
+  {
+    int ret;
+
+    /* take shared lock on resctrl filesystem */
+    ret = flock(fd, LOCK_SH);
+    if (ret) {
+      perror("flock");
+      exit(-1);
+    }
+  }
+
+  void resctrl_take_exclusive_lock(int fd)
+  {
+    int ret;
+
+    /* release lock on resctrl filesystem */
+    ret = flock(fd, LOCK_EX);
+    if (ret) {
+      perror("flock");
+      exit(-1);
+    }
+  }
+
+  void resctrl_release_lock(int fd)
+  {
+    int ret;
+
+    /* take shared lock on resctrl filesystem */
+    ret = flock(fd, LOCK_UN);
+    if (ret) {
+      perror("flock");
+      exit(-1);
+    }
+  }
+
+  void main(void)
+  {
+    int fd, ret;
+
+    fd = open("/sys/fs/resctrl", O_DIRECTORY);
+    if (fd == -1) {
+      perror("open");
+      exit(-1);
+    }
+    resctrl_take_shared_lock(fd);
+    /* code to read directory contents */
+    resctrl_release_lock(fd);
+
+    resctrl_take_exclusive_lock(fd);
+    /* code to read and write directory contents */
+    resctrl_release_lock(fd);
+  }
+
+Examples for RDT Monitoring along with allocation usage
+=======================================================
+Reading monitored data
+----------------------
+Reading an event file (for ex: mon_data/mon_L3_00/llc_occupancy) would
+show the current snapshot of LLC occupancy of the corresponding MON
+group or CTRL_MON group.
+
+
+Example 1 (Monitor CTRL_MON group and subset of tasks in CTRL_MON group)
+------------------------------------------------------------------------
+On a two socket machine (one L3 cache per socket) with just four bits
+for cache bit masks::
+
+  # mount -t resctrl resctrl /sys/fs/resctrl
+  # cd /sys/fs/resctrl
+  # mkdir p0 p1
+  # echo "L3:0=3;1=c" > /sys/fs/resctrl/p0/schemata
+  # echo "L3:0=3;1=3" > /sys/fs/resctrl/p1/schemata
+  # echo 5678 > p1/tasks
+  # echo 5679 > p1/tasks
+
+The default resource group is unmodified, so we have access to all parts
+of all caches (its schemata file reads "L3:0=f;1=f").
+
+Tasks that are under the control of group "p0" may only allocate from the
+"lower" 50% on cache ID 0, and the "upper" 50% of cache ID 1.
+Tasks in group "p1" use the "lower" 50% of cache on both sockets.
+
+Create monitor groups and assign a subset of tasks to each monitor group.
+::
+
+  # cd /sys/fs/resctrl/p1/mon_groups
+  # mkdir m11 m12
+  # echo 5678 > m11/tasks
+  # echo 5679 > m12/tasks
+
+fetch data (data shown in bytes)
+::
+
+  # cat m11/mon_data/mon_L3_00/llc_occupancy
+  16234000
+  # cat m11/mon_data/mon_L3_01/llc_occupancy
+  14789000
+  # cat m12/mon_data/mon_L3_00/llc_occupancy
+  16789000
+
+The parent ctrl_mon group shows the aggregated data.
+::
+
+  # cat /sys/fs/resctrl/p1/mon_data/mon_l3_00/llc_occupancy
+  31234000
+
+Example 2 (Monitor a task from its creation)
+--------------------------------------------
+On a two socket machine (one L3 cache per socket)::
+
+  # mount -t resctrl resctrl /sys/fs/resctrl
+  # cd /sys/fs/resctrl
+  # mkdir p0 p1
+
+An RMID is allocated to the group once its created and hence the <cmd>
+below is monitored from its creation.
+::
+
+  # echo $$ > /sys/fs/resctrl/p1/tasks
+  # <cmd>
+
+Fetch the data::
+
+  # cat /sys/fs/resctrl/p1/mon_data/mon_l3_00/llc_occupancy
+  31789000
+
+Example 3 (Monitor without CAT support or before creating CAT groups)
+---------------------------------------------------------------------
+
+Assume a system like HSW has only CQM and no CAT support. In this case
+the resctrl will still mount but cannot create CTRL_MON directories.
+But user can create different MON groups within the root group thereby
+able to monitor all tasks including kernel threads.
+
+This can also be used to profile jobs cache size footprint before being
+able to allocate them to different allocation groups.
+::
+
+  # mount -t resctrl resctrl /sys/fs/resctrl
+  # cd /sys/fs/resctrl
+  # mkdir mon_groups/m01
+  # mkdir mon_groups/m02
+
+  # echo 3478 > /sys/fs/resctrl/mon_groups/m01/tasks
+  # echo 2467 > /sys/fs/resctrl/mon_groups/m02/tasks
+
+Monitor the groups separately and also get per domain data. From the
+below its apparent that the tasks are mostly doing work on
+domain(socket) 0.
+::
+
+  # cat /sys/fs/resctrl/mon_groups/m01/mon_L3_00/llc_occupancy
+  31234000
+  # cat /sys/fs/resctrl/mon_groups/m01/mon_L3_01/llc_occupancy
+  34555
+  # cat /sys/fs/resctrl/mon_groups/m02/mon_L3_00/llc_occupancy
+  31234000
+  # cat /sys/fs/resctrl/mon_groups/m02/mon_L3_01/llc_occupancy
+  32789
+
+
+Example 4 (Monitor real time tasks)
+-----------------------------------
+
+A single socket system which has real time tasks running on cores 4-7
+and non real time tasks on other cpus. We want to monitor the cache
+occupancy of the real time threads on these cores.
+::
+
+  # mount -t resctrl resctrl /sys/fs/resctrl
+  # cd /sys/fs/resctrl
+  # mkdir p1
+
+Move the cpus 4-7 over to p1::
+
+  # echo f0 > p1/cpus
+
+View the llc occupancy snapshot::
+
+  # cat /sys/fs/resctrl/p1/mon_data/mon_L3_00/llc_occupancy
+  11234000
+
+Intel RDT Errata
+================
+
+Intel MBM Counters May Report System Memory Bandwidth Incorrectly
+-----------------------------------------------------------------
+
+Errata SKX99 for Skylake server and BDF102 for Broadwell server.
+
+Problem: Intel Memory Bandwidth Monitoring (MBM) counters track metrics
+according to the assigned Resource Monitor ID (RMID) for that logical
+core. The IA32_QM_CTR register (MSR 0xC8E), used to report these
+metrics, may report incorrect system bandwidth for certain RMID values.
+
+Implication: Due to the errata, system memory bandwidth may not match
+what is reported.
+
+Workaround: MBM total and local readings are corrected according to the
+following correction factor table:
+
++---------------+---------------+---------------+-----------------+
+|core count    |rmid count     |rmid threshold |correction factor|
++---------------+---------------+---------------+-----------------+
+|1             |8              |0              |1.000000         |
++---------------+---------------+---------------+-----------------+
+|2             |16             |0              |1.000000         |
++---------------+---------------+---------------+-----------------+
+|3             |24             |15             |0.969650         |
++---------------+---------------+---------------+-----------------+
+|4             |32             |0              |1.000000         |
++---------------+---------------+---------------+-----------------+
+|6             |48             |31             |0.969650         |
++---------------+---------------+---------------+-----------------+
+|7             |56             |47             |1.142857         |
++---------------+---------------+---------------+-----------------+
+|8             |64             |0              |1.000000         |
++---------------+---------------+---------------+-----------------+
+|9             |72             |63             |1.185115         |
++---------------+---------------+---------------+-----------------+
+|10            |80             |63             |1.066553         |
++---------------+---------------+---------------+-----------------+
+|11            |88             |79             |1.454545         |
++---------------+---------------+---------------+-----------------+
+|12            |96             |0              |1.000000         |
++---------------+---------------+---------------+-----------------+
+|13            |104            |95             |1.230769         |
++---------------+---------------+---------------+-----------------+
+|14            |112            |95             |1.142857         |
++---------------+---------------+---------------+-----------------+
+|15            |120            |95             |1.066667         |
++---------------+---------------+---------------+-----------------+
+|16            |128            |0              |1.000000         |
++---------------+---------------+---------------+-----------------+
+|17            |136            |127            |1.254863         |
++---------------+---------------+---------------+-----------------+
+|18            |144            |127            |1.185255         |
++---------------+---------------+---------------+-----------------+
+|19            |152            |0              |1.000000         |
++---------------+---------------+---------------+-----------------+
+|20            |160            |127            |1.066667         |
++---------------+---------------+---------------+-----------------+
+|21            |168            |0              |1.000000         |
++---------------+---------------+---------------+-----------------+
+|22            |176            |159            |1.454334         |
++---------------+---------------+---------------+-----------------+
+|23            |184            |0              |1.000000         |
++---------------+---------------+---------------+-----------------+
+|24            |192            |127            |0.969744         |
++---------------+---------------+---------------+-----------------+
+|25            |200            |191            |1.280246         |
++---------------+---------------+---------------+-----------------+
+|26            |208            |191            |1.230921         |
++---------------+---------------+---------------+-----------------+
+|27            |216            |0              |1.000000         |
++---------------+---------------+---------------+-----------------+
+|28            |224            |191            |1.143118         |
++---------------+---------------+---------------+-----------------+
+
+If rmid > rmid threshold, MBM total and local values should be multiplied
+by the correction factor.
+
+See:
+
+1. Erratum SKX99 in Intel Xeon Processor Scalable Family Specification Update:
+http://web.archive.org/web/20200716124958/https://www.intel.com/content/www/us/en/processors/xeon/scalable/xeon-scalable-spec-update.html
+
+2. Erratum BDF102 in Intel Xeon E5-2600 v4 Processor Product Family Specification Update:
+http://web.archive.org/web/20191125200531/https://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/xeon-e5-v4-spec-update.pdf
+
+3. The errata in Intel Resource Director Technology (Intel RDT) on 2nd Generation Intel Xeon Scalable Processors Reference Manual:
+https://software.intel.com/content/www/us/en/develop/articles/intel-resource-director-technology-rdt-reference-manual.html
+
+for further information.
diff --git a/Documentation/arch/x86/sgx.rst b/Documentation/arch/x86/sgx.rst
new file mode 100644 (file)
index 0000000..2bcbffa
--- /dev/null
@@ -0,0 +1,302 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===============================
+Software Guard eXtensions (SGX)
+===============================
+
+Overview
+========
+
+Software Guard eXtensions (SGX) hardware enables for user space applications
+to set aside private memory regions of code and data:
+
+* Privileged (ring-0) ENCLS functions orchestrate the construction of the
+  regions.
+* Unprivileged (ring-3) ENCLU functions allow an application to enter and
+  execute inside the regions.
+
+These memory regions are called enclaves. An enclave can be only entered at a
+fixed set of entry points. Each entry point can hold a single hardware thread
+at a time.  While the enclave is loaded from a regular binary file by using
+ENCLS functions, only the threads inside the enclave can access its memory. The
+region is denied from outside access by the CPU, and encrypted before it leaves
+from LLC.
+
+The support can be determined by
+
+       ``grep sgx /proc/cpuinfo``
+
+SGX must both be supported in the processor and enabled by the BIOS.  If SGX
+appears to be unsupported on a system which has hardware support, ensure
+support is enabled in the BIOS.  If a BIOS presents a choice between "Enabled"
+and "Software Enabled" modes for SGX, choose "Enabled".
+
+Enclave Page Cache
+==================
+
+SGX utilizes an *Enclave Page Cache (EPC)* to store pages that are associated
+with an enclave. It is contained in a BIOS-reserved region of physical memory.
+Unlike pages used for regular memory, pages can only be accessed from outside of
+the enclave during enclave construction with special, limited SGX instructions.
+
+Only a CPU executing inside an enclave can directly access enclave memory.
+However, a CPU executing inside an enclave may access normal memory outside the
+enclave.
+
+The kernel manages enclave memory similar to how it treats device memory.
+
+Enclave Page Types
+------------------
+
+**SGX Enclave Control Structure (SECS)**
+   Enclave's address range, attributes and other global data are defined
+   by this structure.
+
+**Regular (REG)**
+   Regular EPC pages contain the code and data of an enclave.
+
+**Thread Control Structure (TCS)**
+   Thread Control Structure pages define the entry points to an enclave and
+   track the execution state of an enclave thread.
+
+**Version Array (VA)**
+   Version Array pages contain 512 slots, each of which can contain a version
+   number for a page evicted from the EPC.
+
+Enclave Page Cache Map
+----------------------
+
+The processor tracks EPC pages in a hardware metadata structure called the
+*Enclave Page Cache Map (EPCM)*.  The EPCM contains an entry for each EPC page
+which describes the owning enclave, access rights and page type among the other
+things.
+
+EPCM permissions are separate from the normal page tables.  This prevents the
+kernel from, for instance, allowing writes to data which an enclave wishes to
+remain read-only.  EPCM permissions may only impose additional restrictions on
+top of normal x86 page permissions.
+
+For all intents and purposes, the SGX architecture allows the processor to
+invalidate all EPCM entries at will.  This requires that software be prepared to
+handle an EPCM fault at any time.  In practice, this can happen on events like
+power transitions when the ephemeral key that encrypts enclave memory is lost.
+
+Application interface
+=====================
+
+Enclave build functions
+-----------------------
+
+In addition to the traditional compiler and linker build process, SGX has a
+separate enclave “build” process.  Enclaves must be built before they can be
+executed (entered). The first step in building an enclave is opening the
+**/dev/sgx_enclave** device.  Since enclave memory is protected from direct
+access, special privileged instructions are then used to copy data into enclave
+pages and establish enclave page permissions.
+
+.. kernel-doc:: arch/x86/kernel/cpu/sgx/ioctl.c
+   :functions: sgx_ioc_enclave_create
+               sgx_ioc_enclave_add_pages
+               sgx_ioc_enclave_init
+               sgx_ioc_enclave_provision
+
+Enclave runtime management
+--------------------------
+
+Systems supporting SGX2 additionally support changes to initialized
+enclaves: modifying enclave page permissions and type, and dynamically
+adding and removing of enclave pages. When an enclave accesses an address
+within its address range that does not have a backing page then a new
+regular page will be dynamically added to the enclave. The enclave is
+still required to run EACCEPT on the new page before it can be used.
+
+.. kernel-doc:: arch/x86/kernel/cpu/sgx/ioctl.c
+   :functions: sgx_ioc_enclave_restrict_permissions
+               sgx_ioc_enclave_modify_types
+               sgx_ioc_enclave_remove_pages
+
+Enclave vDSO
+------------
+
+Entering an enclave can only be done through SGX-specific EENTER and ERESUME
+functions, and is a non-trivial process.  Because of the complexity of
+transitioning to and from an enclave, enclaves typically utilize a library to
+handle the actual transitions.  This is roughly analogous to how glibc
+implementations are used by most applications to wrap system calls.
+
+Another crucial characteristic of enclaves is that they can generate exceptions
+as part of their normal operation that need to be handled in the enclave or are
+unique to SGX.
+
+Instead of the traditional signal mechanism to handle these exceptions, SGX
+can leverage special exception fixup provided by the vDSO.  The kernel-provided
+vDSO function wraps low-level transitions to/from the enclave like EENTER and
+ERESUME.  The vDSO function intercepts exceptions that would otherwise generate
+a signal and return the fault information directly to its caller.  This avoids
+the need to juggle signal handlers.
+
+.. kernel-doc:: arch/x86/include/uapi/asm/sgx.h
+   :functions: vdso_sgx_enter_enclave_t
+
+ksgxd
+=====
+
+SGX support includes a kernel thread called *ksgxd*.
+
+EPC sanitization
+----------------
+
+ksgxd is started when SGX initializes.  Enclave memory is typically ready
+for use when the processor powers on or resets.  However, if SGX has been in
+use since the reset, enclave pages may be in an inconsistent state.  This might
+occur after a crash and kexec() cycle, for instance.  At boot, ksgxd
+reinitializes all enclave pages so that they can be allocated and re-used.
+
+The sanitization is done by going through EPC address space and applying the
+EREMOVE function to each physical page. Some enclave pages like SECS pages have
+hardware dependencies on other pages which prevents EREMOVE from functioning.
+Executing two EREMOVE passes removes the dependencies.
+
+Page reclaimer
+--------------
+
+Similar to the core kswapd, ksgxd, is responsible for managing the
+overcommitment of enclave memory.  If the system runs out of enclave memory,
+*ksgxd* “swaps” enclave memory to normal memory.
+
+Launch Control
+==============
+
+SGX provides a launch control mechanism. After all enclave pages have been
+copied, kernel executes EINIT function, which initializes the enclave. Only after
+this the CPU can execute inside the enclave.
+
+EINIT function takes an RSA-3072 signature of the enclave measurement.  The function
+checks that the measurement is correct and signature is signed with the key
+hashed to the four **IA32_SGXLEPUBKEYHASH{0, 1, 2, 3}** MSRs representing the
+SHA256 of a public key.
+
+Those MSRs can be configured by the BIOS to be either readable or writable.
+Linux supports only writable configuration in order to give full control to the
+kernel on launch control policy. Before calling EINIT function, the driver sets
+the MSRs to match the enclave's signing key.
+
+Encryption engines
+==================
+
+In order to conceal the enclave data while it is out of the CPU package, the
+memory controller has an encryption engine to transparently encrypt and decrypt
+enclave memory.
+
+In CPUs prior to Ice Lake, the Memory Encryption Engine (MEE) is used to
+encrypt pages leaving the CPU caches. MEE uses a n-ary Merkle tree with root in
+SRAM to maintain integrity of the encrypted data. This provides integrity and
+anti-replay protection but does not scale to large memory sizes because the time
+required to update the Merkle tree grows logarithmically in relation to the
+memory size.
+
+CPUs starting from Icelake use Total Memory Encryption (TME) in the place of
+MEE. TME-based SGX implementations do not have an integrity Merkle tree, which
+means integrity and replay-attacks are not mitigated.  B, it includes
+additional changes to prevent cipher text from being returned and SW memory
+aliases from being created.
+
+DMA to enclave memory is blocked by range registers on both MEE and TME systems
+(SDM section 41.10).
+
+Usage Models
+============
+
+Shared Library
+--------------
+
+Sensitive data and the code that acts on it is partitioned from the application
+into a separate library. The library is then linked as a DSO which can be loaded
+into an enclave. The application can then make individual function calls into
+the enclave through special SGX instructions. A run-time within the enclave is
+configured to marshal function parameters into and out of the enclave and to
+call the correct library function.
+
+Application Container
+---------------------
+
+An application may be loaded into a container enclave which is specially
+configured with a library OS and run-time which permits the application to run.
+The enclave run-time and library OS work together to execute the application
+when a thread enters the enclave.
+
+Impact of Potential Kernel SGX Bugs
+===================================
+
+EPC leaks
+---------
+
+When EPC page leaks happen, a WARNING like this is shown in dmesg:
+
+"EREMOVE returned ... and an EPC page was leaked.  SGX may become unusable..."
+
+This is effectively a kernel use-after-free of an EPC page, and due
+to the way SGX works, the bug is detected at freeing. Rather than
+adding the page back to the pool of available EPC pages, the kernel
+intentionally leaks the page to avoid additional errors in the future.
+
+When this happens, the kernel will likely soon leak more EPC pages, and
+SGX will likely become unusable because the memory available to SGX is
+limited. However, while this may be fatal to SGX, the rest of the kernel
+is unlikely to be impacted and should continue to work.
+
+As a result, when this happpens, user should stop running any new
+SGX workloads, (or just any new workloads), and migrate all valuable
+workloads. Although a machine reboot can recover all EPC memory, the bug
+should be reported to Linux developers.
+
+
+Virtual EPC
+===========
+
+The implementation has also a virtual EPC driver to support SGX enclaves
+in guests. Unlike the SGX driver, an EPC page allocated by the virtual
+EPC driver doesn't have a specific enclave associated with it. This is
+because KVM doesn't track how a guest uses EPC pages.
+
+As a result, the SGX core page reclaimer doesn't support reclaiming EPC
+pages allocated to KVM guests through the virtual EPC driver. If the
+user wants to deploy SGX applications both on the host and in guests
+on the same machine, the user should reserve enough EPC (by taking out
+total virtual EPC size of all SGX VMs from the physical EPC size) for
+host SGX applications so they can run with acceptable performance.
+
+Architectural behavior is to restore all EPC pages to an uninitialized
+state also after a guest reboot.  Because this state can be reached only
+through the privileged ``ENCLS[EREMOVE]`` instruction, ``/dev/sgx_vepc``
+provides the ``SGX_IOC_VEPC_REMOVE_ALL`` ioctl to execute the instruction
+on all pages in the virtual EPC.
+
+``EREMOVE`` can fail for three reasons.  Userspace must pay attention
+to expected failures and handle them as follows:
+
+1. Page removal will always fail when any thread is running in the
+   enclave to which the page belongs.  In this case the ioctl will
+   return ``EBUSY`` independent of whether it has successfully removed
+   some pages; userspace can avoid these failures by preventing execution
+   of any vcpu which maps the virtual EPC.
+
+2. Page removal will cause a general protection fault if two calls to
+   ``EREMOVE`` happen concurrently for pages that refer to the same
+   "SECS" metadata pages.  This can happen if there are concurrent
+   invocations to ``SGX_IOC_VEPC_REMOVE_ALL``, or if a ``/dev/sgx_vepc``
+   file descriptor in the guest is closed at the same time as
+   ``SGX_IOC_VEPC_REMOVE_ALL``; it will also be reported as ``EBUSY``.
+   This can be avoided in userspace by serializing calls to the ioctl()
+   and to close(), but in general it should not be a problem.
+
+3. Finally, page removal will fail for SECS metadata pages which still
+   have child pages.  Child pages can be removed by executing
+   ``SGX_IOC_VEPC_REMOVE_ALL`` on all ``/dev/sgx_vepc`` file descriptors
+   mapped into the guest.  This means that the ioctl() must be called
+   twice: an initial set of calls to remove child pages and a subsequent
+   set of calls to remove SECS pages.  The second set of calls is only
+   required for those mappings that returned a nonzero value from the
+   first call.  It indicates a bug in the kernel or the userspace client
+   if any of the second round of ``SGX_IOC_VEPC_REMOVE_ALL`` calls has
+   a return code other than 0.
diff --git a/Documentation/arch/x86/sva.rst b/Documentation/arch/x86/sva.rst
new file mode 100644 (file)
index 0000000..2e9b8b0
--- /dev/null
@@ -0,0 +1,286 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===========================================
+Shared Virtual Addressing (SVA) with ENQCMD
+===========================================
+
+Background
+==========
+
+Shared Virtual Addressing (SVA) allows the processor and device to use the
+same virtual addresses avoiding the need for software to translate virtual
+addresses to physical addresses. SVA is what PCIe calls Shared Virtual
+Memory (SVM).
+
+In addition to the convenience of using application virtual addresses
+by the device, it also doesn't require pinning pages for DMA.
+PCIe Address Translation Services (ATS) along with Page Request Interface
+(PRI) allow devices to function much the same way as the CPU handling
+application page-faults. For more information please refer to the PCIe
+specification Chapter 10: ATS Specification.
+
+Use of SVA requires IOMMU support in the platform. IOMMU is also
+required to support the PCIe features ATS and PRI. ATS allows devices
+to cache translations for virtual addresses. The IOMMU driver uses the
+mmu_notifier() support to keep the device TLB cache and the CPU cache in
+sync. When an ATS lookup fails for a virtual address, the device should
+use the PRI in order to request the virtual address to be paged into the
+CPU page tables. The device must use ATS again in order the fetch the
+translation before use.
+
+Shared Hardware Workqueues
+==========================
+
+Unlike Single Root I/O Virtualization (SR-IOV), Scalable IOV (SIOV) permits
+the use of Shared Work Queues (SWQ) by both applications and Virtual
+Machines (VM's). This allows better hardware utilization vs. hard
+partitioning resources that could result in under utilization. In order to
+allow the hardware to distinguish the context for which work is being
+executed in the hardware by SWQ interface, SIOV uses Process Address Space
+ID (PASID), which is a 20-bit number defined by the PCIe SIG.
+
+PASID value is encoded in all transactions from the device. This allows the
+IOMMU to track I/O on a per-PASID granularity in addition to using the PCIe
+Resource Identifier (RID) which is the Bus/Device/Function.
+
+
+ENQCMD
+======
+
+ENQCMD is a new instruction on Intel platforms that atomically submits a
+work descriptor to a device. The descriptor includes the operation to be
+performed, virtual addresses of all parameters, virtual address of a completion
+record, and the PASID (process address space ID) of the current process.
+
+ENQCMD works with non-posted semantics and carries a status back if the
+command was accepted by hardware. This allows the submitter to know if the
+submission needs to be retried or other device specific mechanisms to
+implement fairness or ensure forward progress should be provided.
+
+ENQCMD is the glue that ensures applications can directly submit commands
+to the hardware and also permits hardware to be aware of application context
+to perform I/O operations via use of PASID.
+
+Process Address Space Tagging
+=============================
+
+A new thread-scoped MSR (IA32_PASID) provides the connection between
+user processes and the rest of the hardware. When an application first
+accesses an SVA-capable device, this MSR is initialized with a newly
+allocated PASID. The driver for the device calls an IOMMU-specific API
+that sets up the routing for DMA and page-requests.
+
+For example, the Intel Data Streaming Accelerator (DSA) uses
+iommu_sva_bind_device(), which will do the following:
+
+- Allocate the PASID, and program the process page-table (%cr3 register) in the
+  PASID context entries.
+- Register for mmu_notifier() to track any page-table invalidations to keep
+  the device TLB in sync. For example, when a page-table entry is invalidated,
+  the IOMMU propagates the invalidation to the device TLB. This will force any
+  future access by the device to this virtual address to participate in
+  ATS. If the IOMMU responds with proper response that a page is not
+  present, the device would request the page to be paged in via the PCIe PRI
+  protocol before performing I/O.
+
+This MSR is managed with the XSAVE feature set as "supervisor state" to
+ensure the MSR is updated during context switch.
+
+PASID Management
+================
+
+The kernel must allocate a PASID on behalf of each process which will use
+ENQCMD and program it into the new MSR to communicate the process identity to
+platform hardware.  ENQCMD uses the PASID stored in this MSR to tag requests
+from this process.  When a user submits a work descriptor to a device using the
+ENQCMD instruction, the PASID field in the descriptor is auto-filled with the
+value from MSR_IA32_PASID. Requests for DMA from the device are also tagged
+with the same PASID. The platform IOMMU uses the PASID in the transaction to
+perform address translation. The IOMMU APIs setup the corresponding PASID
+entry in IOMMU with the process address used by the CPU (e.g. %cr3 register in
+x86).
+
+The MSR must be configured on each logical CPU before any application
+thread can interact with a device. Threads that belong to the same
+process share the same page tables, thus the same MSR value.
+
+PASID Life Cycle Management
+===========================
+
+PASID is initialized as INVALID_IOASID (-1) when a process is created.
+
+Only processes that access SVA-capable devices need to have a PASID
+allocated. This allocation happens when a process opens/binds an SVA-capable
+device but finds no PASID for this process. Subsequent binds of the same, or
+other devices will share the same PASID.
+
+Although the PASID is allocated to the process by opening a device,
+it is not active in any of the threads of that process. It's loaded to the
+IA32_PASID MSR lazily when a thread tries to submit a work descriptor
+to a device using the ENQCMD.
+
+That first access will trigger a #GP fault because the IA32_PASID MSR
+has not been initialized with the PASID value assigned to the process
+when the device was opened. The Linux #GP handler notes that a PASID has
+been allocated for the process, and so initializes the IA32_PASID MSR
+and returns so that the ENQCMD instruction is re-executed.
+
+On fork(2) or exec(2) the PASID is removed from the process as it no
+longer has the same address space that it had when the device was opened.
+
+On clone(2) the new task shares the same address space, so will be
+able to use the PASID allocated to the process. The IA32_PASID is not
+preemptively initialized as the PASID value might not be allocated yet or
+the kernel does not know whether this thread is going to access the device
+and the cleared IA32_PASID MSR reduces context switch overhead by xstate
+init optimization. Since #GP faults have to be handled on any threads that
+were created before the PASID was assigned to the mm of the process, newly
+created threads might as well be treated in a consistent way.
+
+Due to complexity of freeing the PASID and clearing all IA32_PASID MSRs in
+all threads in unbind, free the PASID lazily only on mm exit.
+
+If a process does a close(2) of the device file descriptor and munmap(2)
+of the device MMIO portal, then the driver will unbind the device. The
+PASID is still marked VALID in the PASID_MSR for any threads in the
+process that accessed the device. But this is harmless as without the
+MMIO portal they cannot submit new work to the device.
+
+Relationships
+=============
+
+ * Each process has many threads, but only one PASID.
+ * Devices have a limited number (~10's to 1000's) of hardware workqueues.
+   The device driver manages allocating hardware workqueues.
+ * A single mmap() maps a single hardware workqueue as a "portal" and
+   each portal maps down to a single workqueue.
+ * For each device with which a process interacts, there must be
+   one or more mmap()'d portals.
+ * Many threads within a process can share a single portal to access
+   a single device.
+ * Multiple processes can separately mmap() the same portal, in
+   which case they still share one device hardware workqueue.
+ * The single process-wide PASID is used by all threads to interact
+   with all devices.  There is not, for instance, a PASID for each
+   thread or each thread<->device pair.
+
+FAQ
+===
+
+* What is SVA/SVM?
+
+Shared Virtual Addressing (SVA) permits I/O hardware and the processor to
+work in the same address space, i.e., to share it. Some call it Shared
+Virtual Memory (SVM), but Linux community wanted to avoid confusing it with
+POSIX Shared Memory and Secure Virtual Machines which were terms already in
+circulation.
+
+* What is a PASID?
+
+A Process Address Space ID (PASID) is a PCIe-defined Transaction Layer Packet
+(TLP) prefix. A PASID is a 20-bit number allocated and managed by the OS.
+PASID is included in all transactions between the platform and the device.
+
+* How are shared workqueues different?
+
+Traditionally, in order for userspace applications to interact with hardware,
+there is a separate hardware instance required per process. For example,
+consider doorbells as a mechanism of informing hardware about work to process.
+Each doorbell is required to be spaced 4k (or page-size) apart for process
+isolation. This requires hardware to provision that space and reserve it in
+MMIO. This doesn't scale as the number of threads becomes quite large. The
+hardware also manages the queue depth for Shared Work Queues (SWQ), and
+consumers don't need to track queue depth. If there is no space to accept
+a command, the device will return an error indicating retry.
+
+A user should check Deferrable Memory Write (DMWr) capability on the device
+and only submits ENQCMD when the device supports it. In the new DMWr PCIe
+terminology, devices need to support DMWr completer capability. In addition,
+it requires all switch ports to support DMWr routing and must be enabled by
+the PCIe subsystem, much like how PCIe atomic operations are managed for
+instance.
+
+SWQ allows hardware to provision just a single address in the device. When
+used with ENQCMD to submit work, the device can distinguish the process
+submitting the work since it will include the PASID assigned to that
+process. This helps the device scale to a large number of processes.
+
+* Is this the same as a user space device driver?
+
+Communicating with the device via the shared workqueue is much simpler
+than a full blown user space driver. The kernel driver does all the
+initialization of the hardware. User space only needs to worry about
+submitting work and processing completions.
+
+* Is this the same as SR-IOV?
+
+Single Root I/O Virtualization (SR-IOV) focuses on providing independent
+hardware interfaces for virtualizing hardware. Hence, it's required to be
+almost fully functional interface to software supporting the traditional
+BARs, space for interrupts via MSI-X, its own register layout.
+Virtual Functions (VFs) are assisted by the Physical Function (PF)
+driver.
+
+Scalable I/O Virtualization builds on the PASID concept to create device
+instances for virtualization. SIOV requires host software to assist in
+creating virtual devices; each virtual device is represented by a PASID
+along with the bus/device/function of the device.  This allows device
+hardware to optimize device resource creation and can grow dynamically on
+demand. SR-IOV creation and management is very static in nature. Consult
+references below for more details.
+
+* Why not just create a virtual function for each app?
+
+Creating PCIe SR-IOV type Virtual Functions (VF) is expensive. VFs require
+duplicated hardware for PCI config space and interrupts such as MSI-X.
+Resources such as interrupts have to be hard partitioned between VFs at
+creation time, and cannot scale dynamically on demand. The VFs are not
+completely independent from the Physical Function (PF). Most VFs require
+some communication and assistance from the PF driver. SIOV, in contrast,
+creates a software-defined device where all the configuration and control
+aspects are mediated via the slow path. The work submission and completion
+happen without any mediation.
+
+* Does this support virtualization?
+
+ENQCMD can be used from within a guest VM. In these cases, the VMM helps
+with setting up a translation table to translate from Guest PASID to Host
+PASID. Please consult the ENQCMD instruction set reference for more
+details.
+
+* Does memory need to be pinned?
+
+When devices support SVA along with platform hardware such as IOMMU
+supporting such devices, there is no need to pin memory for DMA purposes.
+Devices that support SVA also support other PCIe features that remove the
+pinning requirement for memory.
+
+Device TLB support - Device requests the IOMMU to lookup an address before
+use via Address Translation Service (ATS) requests.  If the mapping exists
+but there is no page allocated by the OS, IOMMU hardware returns that no
+mapping exists.
+
+Device requests the virtual address to be mapped via Page Request
+Interface (PRI). Once the OS has successfully completed the mapping, it
+returns the response back to the device. The device requests again for
+a translation and continues.
+
+IOMMU works with the OS in managing consistency of page-tables with the
+device. When removing pages, it interacts with the device to remove any
+device TLB entry that might have been cached before removing the mappings from
+the OS.
+
+References
+==========
+
+VT-D:
+https://01.org/blogs/ashokraj/2018/recent-enhancements-intel-virtualization-technology-directed-i/o-intel-vt-d
+
+SIOV:
+https://01.org/blogs/2019/assignable-interfaces-intel-scalable-i/o-virtualization-linux
+
+ENQCMD in ISE:
+https://software.intel.com/sites/default/files/managed/c5/15/architecture-instruction-set-extensions-programming-reference.pdf
+
+DSA spec:
+https://software.intel.com/sites/default/files/341204-intel-data-streaming-accelerator-spec.pdf
diff --git a/Documentation/arch/x86/tdx.rst b/Documentation/arch/x86/tdx.rst
new file mode 100644 (file)
index 0000000..dc8d9fd
--- /dev/null
@@ -0,0 +1,261 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=====================================
+Intel Trust Domain Extensions (TDX)
+=====================================
+
+Intel's Trust Domain Extensions (TDX) protect confidential guest VMs from
+the host and physical attacks by isolating the guest register state and by
+encrypting the guest memory. In TDX, a special module running in a special
+mode sits between the host and the guest and manages the guest/host
+separation.
+
+Since the host cannot directly access guest registers or memory, much
+normal functionality of a hypervisor must be moved into the guest. This is
+implemented using a Virtualization Exception (#VE) that is handled by the
+guest kernel. A #VE is handled entirely inside the guest kernel, but some
+require the hypervisor to be consulted.
+
+TDX includes new hypercall-like mechanisms for communicating from the
+guest to the hypervisor or the TDX module.
+
+New TDX Exceptions
+==================
+
+TDX guests behave differently from bare-metal and traditional VMX guests.
+In TDX guests, otherwise normal instructions or memory accesses can cause
+#VE or #GP exceptions.
+
+Instructions marked with an '*' conditionally cause exceptions.  The
+details for these instructions are discussed below.
+
+Instruction-based #VE
+---------------------
+
+- Port I/O (INS, OUTS, IN, OUT)
+- HLT
+- MONITOR, MWAIT
+- WBINVD, INVD
+- VMCALL
+- RDMSR*,WRMSR*
+- CPUID*
+
+Instruction-based #GP
+---------------------
+
+- All VMX instructions: INVEPT, INVVPID, VMCLEAR, VMFUNC, VMLAUNCH,
+  VMPTRLD, VMPTRST, VMREAD, VMRESUME, VMWRITE, VMXOFF, VMXON
+- ENCLS, ENCLU
+- GETSEC
+- RSM
+- ENQCMD
+- RDMSR*,WRMSR*
+
+RDMSR/WRMSR Behavior
+--------------------
+
+MSR access behavior falls into three categories:
+
+- #GP generated
+- #VE generated
+- "Just works"
+
+In general, the #GP MSRs should not be used in guests.  Their use likely
+indicates a bug in the guest.  The guest may try to handle the #GP with a
+hypercall but it is unlikely to succeed.
+
+The #VE MSRs are typically able to be handled by the hypervisor.  Guests
+can make a hypercall to the hypervisor to handle the #VE.
+
+The "just works" MSRs do not need any special guest handling.  They might
+be implemented by directly passing through the MSR to the hardware or by
+trapping and handling in the TDX module.  Other than possibly being slow,
+these MSRs appear to function just as they would on bare metal.
+
+CPUID Behavior
+--------------
+
+For some CPUID leaves and sub-leaves, the virtualized bit fields of CPUID
+return values (in guest EAX/EBX/ECX/EDX) are configurable by the
+hypervisor. For such cases, the Intel TDX module architecture defines two
+virtualization types:
+
+- Bit fields for which the hypervisor controls the value seen by the guest
+  TD.
+
+- Bit fields for which the hypervisor configures the value such that the
+  guest TD either sees their native value or a value of 0.  For these bit
+  fields, the hypervisor can mask off the native values, but it can not
+  turn *on* values.
+
+A #VE is generated for CPUID leaves and sub-leaves that the TDX module does
+not know how to handle. The guest kernel may ask the hypervisor for the
+value with a hypercall.
+
+#VE on Memory Accesses
+======================
+
+There are essentially two classes of TDX memory: private and shared.
+Private memory receives full TDX protections.  Its content is protected
+against access from the hypervisor.  Shared memory is expected to be
+shared between guest and hypervisor and does not receive full TDX
+protections.
+
+A TD guest is in control of whether its memory accesses are treated as
+private or shared.  It selects the behavior with a bit in its page table
+entries.  This helps ensure that a guest does not place sensitive
+information in shared memory, exposing it to the untrusted hypervisor.
+
+#VE on Shared Memory
+--------------------
+
+Access to shared mappings can cause a #VE.  The hypervisor ultimately
+controls whether a shared memory access causes a #VE, so the guest must be
+careful to only reference shared pages it can safely handle a #VE.  For
+instance, the guest should be careful not to access shared memory in the
+#VE handler before it reads the #VE info structure (TDG.VP.VEINFO.GET).
+
+Shared mapping content is entirely controlled by the hypervisor. The guest
+should only use shared mappings for communicating with the hypervisor.
+Shared mappings must never be used for sensitive memory content like kernel
+stacks.  A good rule of thumb is that hypervisor-shared memory should be
+treated the same as memory mapped to userspace.  Both the hypervisor and
+userspace are completely untrusted.
+
+MMIO for virtual devices is implemented as shared memory.  The guest must
+be careful not to access device MMIO regions unless it is also prepared to
+handle a #VE.
+
+#VE on Private Pages
+--------------------
+
+An access to private mappings can also cause a #VE.  Since all kernel
+memory is also private memory, the kernel might theoretically need to
+handle a #VE on arbitrary kernel memory accesses.  This is not feasible, so
+TDX guests ensure that all guest memory has been "accepted" before memory
+is used by the kernel.
+
+A modest amount of memory (typically 512M) is pre-accepted by the firmware
+before the kernel runs to ensure that the kernel can start up without
+being subjected to a #VE.
+
+The hypervisor is permitted to unilaterally move accepted pages to a
+"blocked" state. However, if it does this, page access will not generate a
+#VE.  It will, instead, cause a "TD Exit" where the hypervisor is required
+to handle the exception.
+
+Linux #VE handler
+=================
+
+Just like page faults or #GP's, #VE exceptions can be either handled or be
+fatal.  Typically, an unhandled userspace #VE results in a SIGSEGV.
+An unhandled kernel #VE results in an oops.
+
+Handling nested exceptions on x86 is typically nasty business.  A #VE
+could be interrupted by an NMI which triggers another #VE and hilarity
+ensues.  The TDX #VE architecture anticipated this scenario and includes a
+feature to make it slightly less nasty.
+
+During #VE handling, the TDX module ensures that all interrupts (including
+NMIs) are blocked.  The block remains in place until the guest makes a
+TDG.VP.VEINFO.GET TDCALL.  This allows the guest to control when interrupts
+or a new #VE can be delivered.
+
+However, the guest kernel must still be careful to avoid potential
+#VE-triggering actions (discussed above) while this block is in place.
+While the block is in place, any #VE is elevated to a double fault (#DF)
+which is not recoverable.
+
+MMIO handling
+=============
+
+In non-TDX VMs, MMIO is usually implemented by giving a guest access to a
+mapping which will cause a VMEXIT on access, and then the hypervisor
+emulates the access.  That is not possible in TDX guests because VMEXIT
+will expose the register state to the host. TDX guests don't trust the host
+and can't have their state exposed to the host.
+
+In TDX, MMIO regions typically trigger a #VE exception in the guest.  The
+guest #VE handler then emulates the MMIO instruction inside the guest and
+converts it into a controlled TDCALL to the host, rather than exposing
+guest state to the host.
+
+MMIO addresses on x86 are just special physical addresses. They can
+theoretically be accessed with any instruction that accesses memory.
+However, the kernel instruction decoding method is limited. It is only
+designed to decode instructions like those generated by io.h macros.
+
+MMIO access via other means (like structure overlays) may result in an
+oops.
+
+Shared Memory Conversions
+=========================
+
+All TDX guest memory starts out as private at boot.  This memory can not
+be accessed by the hypervisor.  However, some kernel users like device
+drivers might have a need to share data with the hypervisor.  To do this,
+memory must be converted between shared and private.  This can be
+accomplished using some existing memory encryption helpers:
+
+ * set_memory_decrypted() converts a range of pages to shared.
+ * set_memory_encrypted() converts memory back to private.
+
+Device drivers are the primary user of shared memory, but there's no need
+to touch every driver. DMA buffers and ioremap() do the conversions
+automatically.
+
+TDX uses SWIOTLB for most DMA allocations. The SWIOTLB buffer is
+converted to shared on boot.
+
+For coherent DMA allocation, the DMA buffer gets converted on the
+allocation. Check force_dma_unencrypted() for details.
+
+Attestation
+===========
+
+Attestation is used to verify the TDX guest trustworthiness to other
+entities before provisioning secrets to the guest. For example, a key
+server may want to use attestation to verify that the guest is the
+desired one before releasing the encryption keys to mount the encrypted
+rootfs or a secondary drive.
+
+The TDX module records the state of the TDX guest in various stages of
+the guest boot process using the build time measurement register (MRTD)
+and runtime measurement registers (RTMR). Measurements related to the
+guest initial configuration and firmware image are recorded in the MRTD
+register. Measurements related to initial state, kernel image, firmware
+image, command line options, initrd, ACPI tables, etc are recorded in
+RTMR registers. For more details, as an example, please refer to TDX
+Virtual Firmware design specification, section titled "TD Measurement".
+At TDX guest runtime, the attestation process is used to attest to these
+measurements.
+
+The attestation process consists of two steps: TDREPORT generation and
+Quote generation.
+
+TDX guest uses TDCALL[TDG.MR.REPORT] to get the TDREPORT (TDREPORT_STRUCT)
+from the TDX module. TDREPORT is a fixed-size data structure generated by
+the TDX module which contains guest-specific information (such as build
+and boot measurements), platform security version, and the MAC to protect
+the integrity of the TDREPORT. A user-provided 64-Byte REPORTDATA is used
+as input and included in the TDREPORT. Typically it can be some nonce
+provided by attestation service so the TDREPORT can be verified uniquely.
+More details about the TDREPORT can be found in Intel TDX Module
+specification, section titled "TDG.MR.REPORT Leaf".
+
+After getting the TDREPORT, the second step of the attestation process
+is to send it to the Quoting Enclave (QE) to generate the Quote. TDREPORT
+by design can only be verified on the local platform as the MAC key is
+bound to the platform. To support remote verification of the TDREPORT,
+TDX leverages Intel SGX Quoting Enclave to verify the TDREPORT locally
+and convert it to a remotely verifiable Quote. Method of sending TDREPORT
+to QE is implementation specific. Attestation software can choose
+whatever communication channel available (i.e. vsock or TCP/IP) to
+send the TDREPORT to QE and receive the Quote.
+
+References
+==========
+
+TDX reference material is collected here:
+
+https://www.intel.com/content/www/us/en/developer/articles/technical/intel-trust-domain-extensions.html
diff --git a/Documentation/arch/x86/tlb.rst b/Documentation/arch/x86/tlb.rst
new file mode 100644 (file)
index 0000000..82ec58a
--- /dev/null
@@ -0,0 +1,83 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=======
+The TLB
+=======
+
+When the kernel unmaps or modified the attributes of a range of
+memory, it has two choices:
+
+ 1. Flush the entire TLB with a two-instruction sequence.  This is
+    a quick operation, but it causes collateral damage: TLB entries
+    from areas other than the one we are trying to flush will be
+    destroyed and must be refilled later, at some cost.
+ 2. Use the invlpg instruction to invalidate a single page at a
+    time.  This could potentially cost many more instructions, but
+    it is a much more precise operation, causing no collateral
+    damage to other TLB entries.
+
+Which method to do depends on a few things:
+
+ 1. The size of the flush being performed.  A flush of the entire
+    address space is obviously better performed by flushing the
+    entire TLB than doing 2^48/PAGE_SIZE individual flushes.
+ 2. The contents of the TLB.  If the TLB is empty, then there will
+    be no collateral damage caused by doing the global flush, and
+    all of the individual flush will have ended up being wasted
+    work.
+ 3. The size of the TLB.  The larger the TLB, the more collateral
+    damage we do with a full flush.  So, the larger the TLB, the
+    more attractive an individual flush looks.  Data and
+    instructions have separate TLBs, as do different page sizes.
+ 4. The microarchitecture.  The TLB has become a multi-level
+    cache on modern CPUs, and the global flushes have become more
+    expensive relative to single-page flushes.
+
+There is obviously no way the kernel can know all these things,
+especially the contents of the TLB during a given flush.  The
+sizes of the flush will vary greatly depending on the workload as
+well.  There is essentially no "right" point to choose.
+
+You may be doing too many individual invalidations if you see the
+invlpg instruction (or instructions _near_ it) show up high in
+profiles.  If you believe that individual invalidations being
+called too often, you can lower the tunable::
+
+       /sys/kernel/debug/x86/tlb_single_page_flush_ceiling
+
+This will cause us to do the global flush for more cases.
+Lowering it to 0 will disable the use of the individual flushes.
+Setting it to 1 is a very conservative setting and it should
+never need to be 0 under normal circumstances.
+
+Despite the fact that a single individual flush on x86 is
+guaranteed to flush a full 2MB [1]_, hugetlbfs always uses the full
+flushes.  THP is treated exactly the same as normal memory.
+
+You might see invlpg inside of flush_tlb_mm_range() show up in
+profiles, or you can use the trace_tlb_flush() tracepoints. to
+determine how long the flush operations are taking.
+
+Essentially, you are balancing the cycles you spend doing invlpg
+with the cycles that you spend refilling the TLB later.
+
+You can measure how expensive TLB refills are by using
+performance counters and 'perf stat', like this::
+
+  perf stat -e
+    cpu/event=0x8,umask=0x84,name=dtlb_load_misses_walk_duration/,
+    cpu/event=0x8,umask=0x82,name=dtlb_load_misses_walk_completed/,
+    cpu/event=0x49,umask=0x4,name=dtlb_store_misses_walk_duration/,
+    cpu/event=0x49,umask=0x2,name=dtlb_store_misses_walk_completed/,
+    cpu/event=0x85,umask=0x4,name=itlb_misses_walk_duration/,
+    cpu/event=0x85,umask=0x2,name=itlb_misses_walk_completed/
+
+That works on an IvyBridge-era CPU (i5-3320M).  Different CPUs
+may have differently-named counters, but they should at least
+be there in some form.  You can use pmu-tools 'ocperf list'
+(https://github.com/andikleen/pmu-tools) to find the right
+counters for a given CPU.
+
+.. [1] A footnote in Intel's SDM "4.10.4.2 Recommended Invalidation"
+   says: "One execution of INVLPG is sufficient even for a page
+   with size greater than 4 KBytes."
diff --git a/Documentation/arch/x86/topology.rst b/Documentation/arch/x86/topology.rst
new file mode 100644 (file)
index 0000000..7f58010
--- /dev/null
@@ -0,0 +1,234 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============
+x86 Topology
+============
+
+This documents and clarifies the main aspects of x86 topology modelling and
+representation in the kernel. Update/change when doing changes to the
+respective code.
+
+The architecture-agnostic topology definitions are in
+Documentation/admin-guide/cputopology.rst. This file holds x86-specific
+differences/specialities which must not necessarily apply to the generic
+definitions. Thus, the way to read up on Linux topology on x86 is to start
+with the generic one and look at this one in parallel for the x86 specifics.
+
+Needless to say, code should use the generic functions - this file is *only*
+here to *document* the inner workings of x86 topology.
+
+Started by Thomas Gleixner <tglx@linutronix.de> and Borislav Petkov <bp@alien8.de>.
+
+The main aim of the topology facilities is to present adequate interfaces to
+code which needs to know/query/use the structure of the running system wrt
+threads, cores, packages, etc.
+
+The kernel does not care about the concept of physical sockets because a
+socket has no relevance to software. It's an electromechanical component. In
+the past a socket always contained a single package (see below), but with the
+advent of Multi Chip Modules (MCM) a socket can hold more than one package. So
+there might be still references to sockets in the code, but they are of
+historical nature and should be cleaned up.
+
+The topology of a system is described in the units of:
+
+    - packages
+    - cores
+    - threads
+
+Package
+=======
+Packages contain a number of cores plus shared resources, e.g. DRAM
+controller, shared caches etc.
+
+Modern systems may also use the term 'Die' for package.
+
+AMD nomenclature for package is 'Node'.
+
+Package-related topology information in the kernel:
+
+  - cpuinfo_x86.x86_max_cores:
+
+    The number of cores in a package. This information is retrieved via CPUID.
+
+  - cpuinfo_x86.x86_max_dies:
+
+    The number of dies in a package. This information is retrieved via CPUID.
+
+  - cpuinfo_x86.cpu_die_id:
+
+    The physical ID of the die. This information is retrieved via CPUID.
+
+  - cpuinfo_x86.phys_proc_id:
+
+    The physical ID of the package. This information is retrieved via CPUID
+    and deduced from the APIC IDs of the cores in the package.
+
+    Modern systems use this value for the socket. There may be multiple
+    packages within a socket. This value may differ from cpu_die_id.
+
+  - cpuinfo_x86.logical_proc_id:
+
+    The logical ID of the package. As we do not trust BIOSes to enumerate the
+    packages in a consistent way, we introduced the concept of logical package
+    ID so we can sanely calculate the number of maximum possible packages in
+    the system and have the packages enumerated linearly.
+
+  - topology_max_packages():
+
+    The maximum possible number of packages in the system. Helpful for per
+    package facilities to preallocate per package information.
+
+  - cpu_llc_id:
+
+    A per-CPU variable containing:
+
+      - On Intel, the first APIC ID of the list of CPUs sharing the Last Level
+        Cache
+
+      - On AMD, the Node ID or Core Complex ID containing the Last Level
+        Cache. In general, it is a number identifying an LLC uniquely on the
+        system.
+
+Cores
+=====
+A core consists of 1 or more threads. It does not matter whether the threads
+are SMT- or CMT-type threads.
+
+AMDs nomenclature for a CMT core is "Compute Unit". The kernel always uses
+"core".
+
+Core-related topology information in the kernel:
+
+  - smp_num_siblings:
+
+    The number of threads in a core. The number of threads in a package can be
+    calculated by::
+
+       threads_per_package = cpuinfo_x86.x86_max_cores * smp_num_siblings
+
+
+Threads
+=======
+A thread is a single scheduling unit. It's the equivalent to a logical Linux
+CPU.
+
+AMDs nomenclature for CMT threads is "Compute Unit Core". The kernel always
+uses "thread".
+
+Thread-related topology information in the kernel:
+
+  - topology_core_cpumask():
+
+    The cpumask contains all online threads in the package to which a thread
+    belongs.
+
+    The number of online threads is also printed in /proc/cpuinfo "siblings."
+
+  - topology_sibling_cpumask():
+
+    The cpumask contains all online threads in the core to which a thread
+    belongs.
+
+  - topology_logical_package_id():
+
+    The logical package ID to which a thread belongs.
+
+  - topology_physical_package_id():
+
+    The physical package ID to which a thread belongs.
+
+  - topology_core_id();
+
+    The ID of the core to which a thread belongs. It is also printed in /proc/cpuinfo
+    "core_id."
+
+
+
+System topology examples
+========================
+
+.. note::
+  The alternative Linux CPU enumeration depends on how the BIOS enumerates the
+  threads. Many BIOSes enumerate all threads 0 first and then all threads 1.
+  That has the "advantage" that the logical Linux CPU numbers of threads 0 stay
+  the same whether threads are enabled or not. That's merely an implementation
+  detail and has no practical impact.
+
+1) Single Package, Single Core::
+
+   [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
+
+2) Single Package, Dual Core
+
+   a) One thread per core::
+
+       [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
+                   -> [core 1] -> [thread 0] -> Linux CPU 1
+
+   b) Two threads per core::
+
+       [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
+                               -> [thread 1] -> Linux CPU 1
+                   -> [core 1] -> [thread 0] -> Linux CPU 2
+                               -> [thread 1] -> Linux CPU 3
+
+      Alternative enumeration::
+
+       [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
+                               -> [thread 1] -> Linux CPU 2
+                   -> [core 1] -> [thread 0] -> Linux CPU 1
+                               -> [thread 1] -> Linux CPU 3
+
+      AMD nomenclature for CMT systems::
+
+       [node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0
+                                    -> [Compute Unit Core 1] -> Linux CPU 1
+                -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2
+                                    -> [Compute Unit Core 1] -> Linux CPU 3
+
+4) Dual Package, Dual Core
+
+   a) One thread per core::
+
+       [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
+                   -> [core 1] -> [thread 0] -> Linux CPU 1
+
+       [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2
+                   -> [core 1] -> [thread 0] -> Linux CPU 3
+
+   b) Two threads per core::
+
+       [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
+                               -> [thread 1] -> Linux CPU 1
+                   -> [core 1] -> [thread 0] -> Linux CPU 2
+                               -> [thread 1] -> Linux CPU 3
+
+       [package 1] -> [core 0] -> [thread 0] -> Linux CPU 4
+                               -> [thread 1] -> Linux CPU 5
+                   -> [core 1] -> [thread 0] -> Linux CPU 6
+                               -> [thread 1] -> Linux CPU 7
+
+      Alternative enumeration::
+
+       [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
+                               -> [thread 1] -> Linux CPU 4
+                   -> [core 1] -> [thread 0] -> Linux CPU 1
+                               -> [thread 1] -> Linux CPU 5
+
+       [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2
+                               -> [thread 1] -> Linux CPU 6
+                   -> [core 1] -> [thread 0] -> Linux CPU 3
+                               -> [thread 1] -> Linux CPU 7
+
+      AMD nomenclature for CMT systems::
+
+       [node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0
+                                    -> [Compute Unit Core 1] -> Linux CPU 1
+                -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2
+                                    -> [Compute Unit Core 1] -> Linux CPU 3
+
+       [node 1] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 4
+                                    -> [Compute Unit Core 1] -> Linux CPU 5
+                -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 6
+                                    -> [Compute Unit Core 1] -> Linux CPU 7
diff --git a/Documentation/arch/x86/tsx_async_abort.rst b/Documentation/arch/x86/tsx_async_abort.rst
new file mode 100644 (file)
index 0000000..583ddc1
--- /dev/null
@@ -0,0 +1,117 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+TSX Async Abort (TAA) mitigation
+================================
+
+.. _tsx_async_abort:
+
+Overview
+--------
+
+TSX Async Abort (TAA) is a side channel attack on internal buffers in some
+Intel processors similar to Microachitectural Data Sampling (MDS).  In this
+case certain loads may speculatively pass invalid data to dependent operations
+when an asynchronous abort condition is pending in a Transactional
+Synchronization Extensions (TSX) transaction.  This includes loads with no
+fault or assist condition. Such loads may speculatively expose stale data from
+the same uarch data structures as in MDS, with same scope of exposure i.e.
+same-thread and cross-thread. This issue affects all current processors that
+support TSX.
+
+Mitigation strategy
+-------------------
+
+a) TSX disable - one of the mitigations is to disable TSX. A new MSR
+IA32_TSX_CTRL will be available in future and current processors after
+microcode update which can be used to disable TSX. In addition, it
+controls the enumeration of the TSX feature bits (RTM and HLE) in CPUID.
+
+b) Clear CPU buffers - similar to MDS, clearing the CPU buffers mitigates this
+vulnerability. More details on this approach can be found in
+:ref:`Documentation/admin-guide/hw-vuln/mds.rst <mds>`.
+
+Kernel internal mitigation modes
+--------------------------------
+
+ =============    ============================================================
+ off              Mitigation is disabled. Either the CPU is not affected or
+                  tsx_async_abort=off is supplied on the kernel command line.
+
+ tsx disabled     Mitigation is enabled. TSX feature is disabled by default at
+                  bootup on processors that support TSX control.
+
+ verw             Mitigation is enabled. CPU is affected and MD_CLEAR is
+                  advertised in CPUID.
+
+ ucode needed     Mitigation is enabled. CPU is affected and MD_CLEAR is not
+                  advertised in CPUID. That is mainly for virtualization
+                  scenarios where the host has the updated microcode but the
+                  hypervisor does not expose MD_CLEAR in CPUID. It's a best
+                  effort approach without guarantee.
+ =============    ============================================================
+
+If the CPU is affected and the "tsx_async_abort" kernel command line parameter is
+not provided then the kernel selects an appropriate mitigation depending on the
+status of RTM and MD_CLEAR CPUID bits.
+
+Below tables indicate the impact of tsx=on|off|auto cmdline options on state of
+TAA mitigation, VERW behavior and TSX feature for various combinations of
+MSR_IA32_ARCH_CAPABILITIES bits.
+
+1. "tsx=off"
+
+=========  =========  ============  ============  ==============  ===================  ======================
+MSR_IA32_ARCH_CAPABILITIES bits     Result with cmdline tsx=off
+----------------------------------  -------------------------------------------------------------------------
+TAA_NO     MDS_NO     TSX_CTRL_MSR  TSX state     VERW can clear  TAA mitigation       TAA mitigation
+                                    after bootup  CPU buffers     tsx_async_abort=off  tsx_async_abort=full
+=========  =========  ============  ============  ==============  ===================  ======================
+    0          0           0         HW default         Yes           Same as MDS           Same as MDS
+    0          0           1        Invalid case   Invalid case       Invalid case          Invalid case
+    0          1           0         HW default         No         Need ucode update     Need ucode update
+    0          1           1          Disabled          Yes           TSX disabled          TSX disabled
+    1          X           1          Disabled           X             None needed           None needed
+=========  =========  ============  ============  ==============  ===================  ======================
+
+2. "tsx=on"
+
+=========  =========  ============  ============  ==============  ===================  ======================
+MSR_IA32_ARCH_CAPABILITIES bits     Result with cmdline tsx=on
+----------------------------------  -------------------------------------------------------------------------
+TAA_NO     MDS_NO     TSX_CTRL_MSR  TSX state     VERW can clear  TAA mitigation       TAA mitigation
+                                    after bootup  CPU buffers     tsx_async_abort=off  tsx_async_abort=full
+=========  =========  ============  ============  ==============  ===================  ======================
+    0          0           0         HW default        Yes            Same as MDS          Same as MDS
+    0          0           1        Invalid case   Invalid case       Invalid case         Invalid case
+    0          1           0         HW default        No          Need ucode update     Need ucode update
+    0          1           1          Enabled          Yes               None              Same as MDS
+    1          X           1          Enabled          X              None needed          None needed
+=========  =========  ============  ============  ==============  ===================  ======================
+
+3. "tsx=auto"
+
+=========  =========  ============  ============  ==============  ===================  ======================
+MSR_IA32_ARCH_CAPABILITIES bits     Result with cmdline tsx=auto
+----------------------------------  -------------------------------------------------------------------------
+TAA_NO     MDS_NO     TSX_CTRL_MSR  TSX state     VERW can clear  TAA mitigation       TAA mitigation
+                                    after bootup  CPU buffers     tsx_async_abort=off  tsx_async_abort=full
+=========  =========  ============  ============  ==============  ===================  ======================
+    0          0           0         HW default    Yes                Same as MDS           Same as MDS
+    0          0           1        Invalid case  Invalid case        Invalid case          Invalid case
+    0          1           0         HW default    No              Need ucode update     Need ucode update
+    0          1           1          Disabled      Yes               TSX disabled          TSX disabled
+    1          X           1          Enabled       X                 None needed           None needed
+=========  =========  ============  ============  ==============  ===================  ======================
+
+In the tables, TSX_CTRL_MSR is a new bit in MSR_IA32_ARCH_CAPABILITIES that
+indicates whether MSR_IA32_TSX_CTRL is supported.
+
+There are two control bits in IA32_TSX_CTRL MSR:
+
+      Bit 0: When set it disables the Restricted Transactional Memory (RTM)
+             sub-feature of TSX (will force all transactions to abort on the
+             XBEGIN instruction).
+
+      Bit 1: When set it disables the enumeration of the RTM and HLE feature
+             (i.e. it will make CPUID(EAX=7).EBX{bit4} and
+             CPUID(EAX=7).EBX{bit11} read as 0).
diff --git a/Documentation/arch/x86/usb-legacy-support.rst b/Documentation/arch/x86/usb-legacy-support.rst
new file mode 100644 (file)
index 0000000..e01c08b
--- /dev/null
@@ -0,0 +1,50 @@
+
+.. SPDX-License-Identifier: GPL-2.0
+
+==================
+USB Legacy support
+==================
+
+:Author: Vojtech Pavlik <vojtech@suse.cz>, January 2004
+
+
+Also known as "USB Keyboard" or "USB Mouse support" in the BIOS Setup is a
+feature that allows one to use the USB mouse and keyboard as if they were
+their classic PS/2 counterparts.  This means one can use an USB keyboard to
+type in LILO for example.
+
+It has several drawbacks, though:
+
+1) On some machines, the emulated PS/2 mouse takes over even when no USB
+   mouse is present and a real PS/2 mouse is present.  In that case the extra
+   features (wheel, extra buttons, touchpad mode) of the real PS/2 mouse may
+   not be available.
+
+2) If CONFIG_HIGHMEM64G is enabled, the PS/2 mouse emulation can cause
+   system crashes, because the SMM BIOS is not expecting to be in PAE mode.
+   The Intel E7505 is a typical machine where this happens.
+
+3) If AMD64 64-bit mode is enabled, again system crashes often happen,
+   because the SMM BIOS isn't expecting the CPU to be in 64-bit mode.  The
+   BIOS manufacturers only test with Windows, and Windows doesn't do 64-bit
+   yet.
+
+Solutions:
+
+Problem 1)
+  can be solved by loading the USB drivers prior to loading the
+  PS/2 mouse driver. Since the PS/2 mouse driver is in 2.6 compiled into
+  the kernel unconditionally, this means the USB drivers need to be
+  compiled-in, too.
+
+Problem 2)
+  can currently only be solved by either disabling HIGHMEM64G
+  in the kernel config or USB Legacy support in the BIOS. A BIOS update
+  could help, but so far no such update exists.
+
+Problem 3)
+  is usually fixed by a BIOS update. Check the board
+  manufacturers web site. If an update is not available, disable USB
+  Legacy support in the BIOS. If this alone doesn't help, try also adding
+  idle=poll on the kernel command line. The BIOS may be entering the SMM
+  on the HLT instruction as well.
diff --git a/Documentation/arch/x86/x86_64/5level-paging.rst b/Documentation/arch/x86/x86_64/5level-paging.rst
new file mode 100644 (file)
index 0000000..71f882f
--- /dev/null
@@ -0,0 +1,67 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==============
+5-level paging
+==============
+
+Overview
+========
+Original x86-64 was limited by 4-level paging to 256 TiB of virtual address
+space and 64 TiB of physical address space. We are already bumping into
+this limit: some vendors offer servers with 64 TiB of memory today.
+
+To overcome the limitation upcoming hardware will introduce support for
+5-level paging. It is a straight-forward extension of the current page
+table structure adding one more layer of translation.
+
+It bumps the limits to 128 PiB of virtual address space and 4 PiB of
+physical address space. This "ought to be enough for anybody" ©.
+
+QEMU 2.9 and later support 5-level paging.
+
+Virtual memory layout for 5-level paging is described in
+Documentation/arch/x86/x86_64/mm.rst
+
+
+Enabling 5-level paging
+=======================
+CONFIG_X86_5LEVEL=y enables the feature.
+
+Kernel with CONFIG_X86_5LEVEL=y still able to boot on 4-level hardware.
+In this case additional page table level -- p4d -- will be folded at
+runtime.
+
+User-space and large virtual address space
+==========================================
+On x86, 5-level paging enables 56-bit userspace virtual address space.
+Not all user space is ready to handle wide addresses. It's known that
+at least some JIT compilers use higher bits in pointers to encode their
+information. It collides with valid pointers with 5-level paging and
+leads to crashes.
+
+To mitigate this, we are not going to allocate virtual address space
+above 47-bit by default.
+
+But userspace can ask for allocation from full address space by
+specifying hint address (with or without MAP_FIXED) above 47-bits.
+
+If hint address set above 47-bit, but MAP_FIXED is not specified, we try
+to look for unmapped area by specified address. If it's already
+occupied, we look for unmapped area in *full* address space, rather than
+from 47-bit window.
+
+A high hint address would only affect the allocation in question, but not
+any future mmap()s.
+
+Specifying high hint address on older kernel or on machine without 5-level
+paging support is safe. The hint will be ignored and kernel will fall back
+to allocation from 47-bit address space.
+
+This approach helps to easily make application's memory allocator aware
+about large address space without manually tracking allocated virtual
+address space.
+
+One important case we need to handle here is interaction with MPX.
+MPX (without MAWA extension) cannot handle addresses above 47-bit, so we
+need to make sure that MPX cannot be enabled we already have VMA above
+the boundary and forbid creating such VMAs once MPX is enabled.
diff --git a/Documentation/arch/x86/x86_64/boot-options.rst b/Documentation/arch/x86/x86_64/boot-options.rst
new file mode 100644 (file)
index 0000000..137432d
--- /dev/null
@@ -0,0 +1,319 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===========================
+AMD64 Specific Boot Options
+===========================
+
+There are many others (usually documented in driver documentation), but
+only the AMD64 specific ones are listed here.
+
+Machine check
+=============
+Please see Documentation/arch/x86/x86_64/machinecheck.rst for sysfs runtime tunables.
+
+   mce=off
+               Disable machine check
+   mce=no_cmci
+               Disable CMCI(Corrected Machine Check Interrupt) that
+               Intel processor supports.  Usually this disablement is
+               not recommended, but it might be handy if your hardware
+               is misbehaving.
+               Note that you'll get more problems without CMCI than with
+               due to the shared banks, i.e. you might get duplicated
+               error logs.
+   mce=dont_log_ce
+               Don't make logs for corrected errors.  All events reported
+               as corrected are silently cleared by OS.
+               This option will be useful if you have no interest in any
+               of corrected errors.
+   mce=ignore_ce
+               Disable features for corrected errors, e.g. polling timer
+               and CMCI.  All events reported as corrected are not cleared
+               by OS and remained in its error banks.
+               Usually this disablement is not recommended, however if
+               there is an agent checking/clearing corrected errors
+               (e.g. BIOS or hardware monitoring applications), conflicting
+               with OS's error handling, and you cannot deactivate the agent,
+               then this option will be a help.
+   mce=no_lmce
+               Do not opt-in to Local MCE delivery. Use legacy method
+               to broadcast MCEs.
+   mce=bootlog
+               Enable logging of machine checks left over from booting.
+               Disabled by default on AMD Fam10h and older because some BIOS
+               leave bogus ones.
+               If your BIOS doesn't do that it's a good idea to enable though
+               to make sure you log even machine check events that result
+               in a reboot. On Intel systems it is enabled by default.
+   mce=nobootlog
+               Disable boot machine check logging.
+   mce=monarchtimeout (number)
+               monarchtimeout:
+               Sets the time in us to wait for other CPUs on machine checks. 0
+               to disable.
+   mce=bios_cmci_threshold
+               Don't overwrite the bios-set CMCI threshold. This boot option
+               prevents Linux from overwriting the CMCI threshold set by the
+               bios. Without this option, Linux always sets the CMCI
+               threshold to 1. Enabling this may make memory predictive failure
+               analysis less effective if the bios sets thresholds for memory
+               errors since we will not see details for all errors.
+   mce=recovery
+               Force-enable recoverable machine check code paths
+
+   nomce (for compatibility with i386)
+               same as mce=off
+
+   Everything else is in sysfs now.
+
+APICs
+=====
+
+   apic
+       Use IO-APIC. Default
+
+   noapic
+       Don't use the IO-APIC.
+
+   disableapic
+       Don't use the local APIC
+
+   nolapic
+     Don't use the local APIC (alias for i386 compatibility)
+
+   pirq=...
+       See Documentation/arch/x86/i386/IO-APIC.rst
+
+   noapictimer
+       Don't set up the APIC timer
+
+   no_timer_check
+       Don't check the IO-APIC timer. This can work around
+       problems with incorrect timer initialization on some boards.
+
+   apicpmtimer
+       Do APIC timer calibration using the pmtimer. Implies
+       apicmaintimer. Useful when your PIT timer is totally broken.
+
+Timing
+======
+
+  notsc
+    Deprecated, use tsc=unstable instead.
+
+  nohpet
+    Don't use the HPET timer.
+
+Idle loop
+=========
+
+  idle=poll
+    Don't do power saving in the idle loop using HLT, but poll for rescheduling
+    event. This will make the CPUs eat a lot more power, but may be useful
+    to get slightly better performance in multiprocessor benchmarks. It also
+    makes some profiling using performance counters more accurate.
+    Please note that on systems with MONITOR/MWAIT support (like Intel EM64T
+    CPUs) this option has no performance advantage over the normal idle loop.
+    It may also interact badly with hyperthreading.
+
+Rebooting
+=========
+
+   reboot=b[ios] | t[riple] | k[bd] | a[cpi] | e[fi] | p[ci] [, [w]arm | [c]old]
+      bios
+        Use the CPU reboot vector for warm reset
+      warm
+        Don't set the cold reboot flag
+      cold
+        Set the cold reboot flag
+      triple
+        Force a triple fault (init)
+      kbd
+        Use the keyboard controller. cold reset (default)
+      acpi
+        Use the ACPI RESET_REG in the FADT. If ACPI is not configured or
+        the ACPI reset does not work, the reboot path attempts the reset
+        using the keyboard controller.
+      efi
+        Use efi reset_system runtime service. If EFI is not configured or
+        the EFI reset does not work, the reboot path attempts the reset using
+        the keyboard controller.
+      pci
+        Use a write to the PCI config space register 0xcf9 to trigger reboot.
+
+   Using warm reset will be much faster especially on big memory
+   systems because the BIOS will not go through the memory check.
+   Disadvantage is that not all hardware will be completely reinitialized
+   on reboot so there may be boot problems on some systems.
+
+   reboot=force
+     Don't stop other CPUs on reboot. This can make reboot more reliable
+     in some cases.
+
+   reboot=default
+     There are some built-in platform specific "quirks" - you may see:
+     "reboot: <name> series board detected. Selecting <type> for reboots."
+     In the case where you think the quirk is in error (e.g. you have
+     newer BIOS, or newer board) using this option will ignore the built-in
+     quirk table, and use the generic default reboot actions.
+
+NUMA
+====
+
+  numa=off
+    Only set up a single NUMA node spanning all memory.
+
+  numa=noacpi
+    Don't parse the SRAT table for NUMA setup
+
+  numa=nohmat
+    Don't parse the HMAT table for NUMA setup, or soft-reserved memory
+    partitioning.
+
+  numa=fake=<size>[MG]
+    If given as a memory unit, fills all system RAM with nodes of
+    size interleaved over physical nodes.
+
+  numa=fake=<N>
+    If given as an integer, fills all system RAM with N fake nodes
+    interleaved over physical nodes.
+
+  numa=fake=<N>U
+    If given as an integer followed by 'U', it will divide each
+    physical node into N emulated nodes.
+
+ACPI
+====
+
+  acpi=off
+    Don't enable ACPI
+  acpi=ht
+    Use ACPI boot table parsing, but don't enable ACPI interpreter
+  acpi=force
+    Force ACPI on (currently not needed)
+  acpi=strict
+    Disable out of spec ACPI workarounds.
+  acpi_sci={edge,level,high,low}
+    Set up ACPI SCI interrupt.
+  acpi=noirq
+    Don't route interrupts
+  acpi=nocmcff
+    Disable firmware first mode for corrected errors. This
+    disables parsing the HEST CMC error source to check if
+    firmware has set the FF flag. This may result in
+    duplicate corrected error reports.
+
+PCI
+===
+
+  pci=off
+    Don't use PCI
+  pci=conf1
+    Use conf1 access.
+  pci=conf2
+    Use conf2 access.
+  pci=rom
+    Assign ROMs.
+  pci=assign-busses
+    Assign busses
+  pci=irqmask=MASK
+    Set PCI interrupt mask to MASK
+  pci=lastbus=NUMBER
+    Scan up to NUMBER busses, no matter what the mptable says.
+  pci=noacpi
+    Don't use ACPI to set up PCI interrupt routing.
+
+IOMMU (input/output memory management unit)
+===========================================
+Multiple x86-64 PCI-DMA mapping implementations exist, for example:
+
+   1. <kernel/dma/direct.c>: use no hardware/software IOMMU at all
+      (e.g. because you have < 3 GB memory).
+      Kernel boot message: "PCI-DMA: Disabling IOMMU"
+
+   2. <arch/x86/kernel/amd_gart_64.c>: AMD GART based hardware IOMMU.
+      Kernel boot message: "PCI-DMA: using GART IOMMU"
+
+   3. <arch/x86_64/kernel/pci-swiotlb.c> : Software IOMMU implementation. Used
+      e.g. if there is no hardware IOMMU in the system and it is need because
+      you have >3GB memory or told the kernel to us it (iommu=soft))
+      Kernel boot message: "PCI-DMA: Using software bounce buffering
+      for IO (SWIOTLB)"
+
+::
+
+  iommu=[<size>][,noagp][,off][,force][,noforce]
+  [,memaper[=<order>]][,merge][,fullflush][,nomerge]
+  [,noaperture]
+
+General iommu options:
+
+    off
+      Don't initialize and use any kind of IOMMU.
+    noforce
+      Don't force hardware IOMMU usage when it is not needed. (default).
+    force
+      Force the use of the hardware IOMMU even when it is
+      not actually needed (e.g. because < 3 GB memory).
+    soft
+      Use software bounce buffering (SWIOTLB) (default for
+      Intel machines). This can be used to prevent the usage
+      of an available hardware IOMMU.
+
+iommu options only relevant to the AMD GART hardware IOMMU:
+
+    <size>
+      Set the size of the remapping area in bytes.
+    allowed
+      Overwrite iommu off workarounds for specific chipsets.
+    fullflush
+      Flush IOMMU on each allocation (default).
+    nofullflush
+      Don't use IOMMU fullflush.
+    memaper[=<order>]
+      Allocate an own aperture over RAM with size 32MB<<order.
+      (default: order=1, i.e. 64MB)
+    merge
+      Do scatter-gather (SG) merging. Implies "force" (experimental).
+    nomerge
+      Don't do scatter-gather (SG) merging.
+    noaperture
+      Ask the IOMMU not to touch the aperture for AGP.
+    noagp
+      Don't initialize the AGP driver and use full aperture.
+    panic
+      Always panic when IOMMU overflows.
+
+iommu options only relevant to the software bounce buffering (SWIOTLB) IOMMU
+implementation:
+
+    swiotlb=<slots>[,force,noforce]
+      <slots>
+        Prereserve that many 2K slots for the software IO bounce buffering.
+      force
+        Force all IO through the software TLB.
+      noforce
+        Do not initialize the software TLB.
+
+
+Miscellaneous
+=============
+
+  nogbpages
+    Do not use GB pages for kernel direct mappings.
+  gbpages
+    Use GB pages for kernel direct mappings.
+
+
+AMD SEV (Secure Encrypted Virtualization)
+=========================================
+Options relating to AMD SEV, specified via the following format:
+
+::
+
+   sev=option1[,option2]
+
+The available options are:
+
+   debug
+     Enable debug messages.
diff --git a/Documentation/arch/x86/x86_64/cpu-hotplug-spec.rst b/Documentation/arch/x86/x86_64/cpu-hotplug-spec.rst
new file mode 100644 (file)
index 0000000..8d1c91f
--- /dev/null
@@ -0,0 +1,24 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===================================================
+Firmware support for CPU hotplug under Linux/x86-64
+===================================================
+
+Linux/x86-64 supports CPU hotplug now. For various reasons Linux wants to
+know in advance of boot time the maximum number of CPUs that could be plugged
+into the system. ACPI 3.0 currently has no official way to supply
+this information from the firmware to the operating system.
+
+In ACPI each CPU needs an LAPIC object in the MADT table (5.2.11.5 in the
+ACPI 3.0 specification).  ACPI already has the concept of disabled LAPIC
+objects by setting the Enabled bit in the LAPIC object to zero.
+
+For CPU hotplug Linux/x86-64 expects now that any possible future hotpluggable
+CPU is already available in the MADT. If the CPU is not available yet
+it should have its LAPIC Enabled bit set to 0. Linux will use the number
+of disabled LAPICs to compute the maximum number of future CPUs.
+
+In the worst case the user can overwrite this choice using a command line
+option (additional_cpus=...), but it is recommended to supply the correct
+number (or a reasonable approximation of it, with erring towards more not less)
+in the MADT to avoid manual configuration.
diff --git a/Documentation/arch/x86/x86_64/fake-numa-for-cpusets.rst b/Documentation/arch/x86/x86_64/fake-numa-for-cpusets.rst
new file mode 100644 (file)
index 0000000..ba74617
--- /dev/null
@@ -0,0 +1,78 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=====================
+Fake NUMA For CPUSets
+=====================
+
+:Author: David Rientjes <rientjes@cs.washington.edu>
+
+Using numa=fake and CPUSets for Resource Management
+
+This document describes how the numa=fake x86_64 command-line option can be used
+in conjunction with cpusets for coarse memory management.  Using this feature,
+you can create fake NUMA nodes that represent contiguous chunks of memory and
+assign them to cpusets and their attached tasks.  This is a way of limiting the
+amount of system memory that are available to a certain class of tasks.
+
+For more information on the features of cpusets, see
+Documentation/admin-guide/cgroup-v1/cpusets.rst.
+There are a number of different configurations you can use for your needs.  For
+more information on the numa=fake command line option and its various ways of
+configuring fake nodes, see Documentation/arch/x86/x86_64/boot-options.rst.
+
+For the purposes of this introduction, we'll assume a very primitive NUMA
+emulation setup of "numa=fake=4*512,".  This will split our system memory into
+four equal chunks of 512M each that we can now use to assign to cpusets.  As
+you become more familiar with using this combination for resource control,
+you'll determine a better setup to minimize the number of nodes you have to deal
+with.
+
+A machine may be split as follows with "numa=fake=4*512," as reported by dmesg::
+
+       Faking node 0 at 0000000000000000-0000000020000000 (512MB)
+       Faking node 1 at 0000000020000000-0000000040000000 (512MB)
+       Faking node 2 at 0000000040000000-0000000060000000 (512MB)
+       Faking node 3 at 0000000060000000-0000000080000000 (512MB)
+       ...
+       On node 0 totalpages: 130975
+       On node 1 totalpages: 131072
+       On node 2 totalpages: 131072
+       On node 3 totalpages: 131072
+
+Now following the instructions for mounting the cpusets filesystem from
+Documentation/admin-guide/cgroup-v1/cpusets.rst, you can assign fake nodes (i.e. contiguous memory
+address spaces) to individual cpusets::
+
+       [root@xroads /]# mkdir exampleset
+       [root@xroads /]# mount -t cpuset none exampleset
+       [root@xroads /]# mkdir exampleset/ddset
+       [root@xroads /]# cd exampleset/ddset
+       [root@xroads /exampleset/ddset]# echo 0-1 > cpus
+       [root@xroads /exampleset/ddset]# echo 0-1 > mems
+
+Now this cpuset, 'ddset', will only allowed access to fake nodes 0 and 1 for
+memory allocations (1G).
+
+You can now assign tasks to these cpusets to limit the memory resources
+available to them according to the fake nodes assigned as mems::
+
+       [root@xroads /exampleset/ddset]# echo $$ > tasks
+       [root@xroads /exampleset/ddset]# dd if=/dev/zero of=tmp bs=1024 count=1G
+       [1] 13425
+
+Notice the difference between the system memory usage as reported by
+/proc/meminfo between the restricted cpuset case above and the unrestricted
+case (i.e. running the same 'dd' command without assigning it to a fake NUMA
+cpuset):
+
+       ========        ============    ==========
+       Name            Unrestricted    Restricted
+       ========        ============    ==========
+       MemTotal        3091900 kB      3091900 kB
+       MemFree         42113 kB        1513236 kB
+       ========        ============    ==========
+
+This allows for coarse memory management for the tasks you assign to particular
+cpusets.  Since cpusets can form a hierarchy, you can create some pretty
+interesting combinations of use-cases for various classes of tasks for your
+memory management needs.
diff --git a/Documentation/arch/x86/x86_64/fsgs.rst b/Documentation/arch/x86/x86_64/fsgs.rst
new file mode 100644 (file)
index 0000000..50960e0
--- /dev/null
@@ -0,0 +1,199 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Using FS and GS segments in user space applications
+===================================================
+
+The x86 architecture supports segmentation. Instructions which access
+memory can use segment register based addressing mode. The following
+notation is used to address a byte within a segment:
+
+  Segment-register:Byte-address
+
+The segment base address is added to the Byte-address to compute the
+resulting virtual address which is accessed. This allows to access multiple
+instances of data with the identical Byte-address, i.e. the same code. The
+selection of a particular instance is purely based on the base-address in
+the segment register.
+
+In 32-bit mode the CPU provides 6 segments, which also support segment
+limits. The limits can be used to enforce address space protections.
+
+In 64-bit mode the CS/SS/DS/ES segments are ignored and the base address is
+always 0 to provide a full 64bit address space. The FS and GS segments are
+still functional in 64-bit mode.
+
+Common FS and GS usage
+------------------------------
+
+The FS segment is commonly used to address Thread Local Storage (TLS). FS
+is usually managed by runtime code or a threading library. Variables
+declared with the '__thread' storage class specifier are instantiated per
+thread and the compiler emits the FS: address prefix for accesses to these
+variables. Each thread has its own FS base address so common code can be
+used without complex address offset calculations to access the per thread
+instances. Applications should not use FS for other purposes when they use
+runtimes or threading libraries which manage the per thread FS.
+
+The GS segment has no common use and can be used freely by
+applications. GCC and Clang support GS based addressing via address space
+identifiers.
+
+Reading and writing the FS/GS base address
+------------------------------------------
+
+There exist two mechanisms to read and write the FS/GS base address:
+
+ - the arch_prctl() system call
+
+ - the FSGSBASE instruction family
+
+Accessing FS/GS base with arch_prctl()
+--------------------------------------
+
+ The arch_prctl(2) based mechanism is available on all 64-bit CPUs and all
+ kernel versions.
+
+ Reading the base:
+
+   arch_prctl(ARCH_GET_FS, &fsbase);
+   arch_prctl(ARCH_GET_GS, &gsbase);
+
+ Writing the base:
+
+   arch_prctl(ARCH_SET_FS, fsbase);
+   arch_prctl(ARCH_SET_GS, gsbase);
+
+ The ARCH_SET_GS prctl may be disabled depending on kernel configuration
+ and security settings.
+
+Accessing FS/GS base with the FSGSBASE instructions
+---------------------------------------------------
+
+ With the Ivy Bridge CPU generation Intel introduced a new set of
+ instructions to access the FS and GS base registers directly from user
+ space. These instructions are also supported on AMD Family 17H CPUs. The
+ following instructions are available:
+
+  =============== ===========================
+  RDFSBASE %reg   Read the FS base register
+  RDGSBASE %reg   Read the GS base register
+  WRFSBASE %reg   Write the FS base register
+  WRGSBASE %reg   Write the GS base register
+  =============== ===========================
+
+ The instructions avoid the overhead of the arch_prctl() syscall and allow
+ more flexible usage of the FS/GS addressing modes in user space
+ applications. This does not prevent conflicts between threading libraries
+ and runtimes which utilize FS and applications which want to use it for
+ their own purpose.
+
+FSGSBASE instructions enablement
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ The instructions are enumerated in CPUID leaf 7, bit 0 of EBX. If
+ available /proc/cpuinfo shows 'fsgsbase' in the flag entry of the CPUs.
+
+ The availability of the instructions does not enable them
+ automatically. The kernel has to enable them explicitly in CR4. The
+ reason for this is that older kernels make assumptions about the values in
+ the GS register and enforce them when GS base is set via
+ arch_prctl(). Allowing user space to write arbitrary values to GS base
+ would violate these assumptions and cause malfunction.
+
+ On kernels which do not enable FSGSBASE the execution of the FSGSBASE
+ instructions will fault with a #UD exception.
+
+ The kernel provides reliable information about the enabled state in the
+ ELF AUX vector. If the HWCAP2_FSGSBASE bit is set in the AUX vector, the
+ kernel has FSGSBASE instructions enabled and applications can use them.
+ The following code example shows how this detection works::
+
+   #include <sys/auxv.h>
+   #include <elf.h>
+
+   /* Will be eventually in asm/hwcap.h */
+   #ifndef HWCAP2_FSGSBASE
+   #define HWCAP2_FSGSBASE        (1 << 1)
+   #endif
+
+   ....
+
+   unsigned val = getauxval(AT_HWCAP2);
+
+   if (val & HWCAP2_FSGSBASE)
+        printf("FSGSBASE enabled\n");
+
+FSGSBASE instructions compiler support
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+GCC version 4.6.4 and newer provide instrinsics for the FSGSBASE
+instructions. Clang 5 supports them as well.
+
+  =================== ===========================
+  _readfsbase_u64()   Read the FS base register
+  _readfsbase_u64()   Read the GS base register
+  _writefsbase_u64()  Write the FS base register
+  _writegsbase_u64()  Write the GS base register
+  =================== ===========================
+
+To utilize these instrinsics <immintrin.h> must be included in the source
+code and the compiler option -mfsgsbase has to be added.
+
+Compiler support for FS/GS based addressing
+-------------------------------------------
+
+GCC version 6 and newer provide support for FS/GS based addressing via
+Named Address Spaces. GCC implements the following address space
+identifiers for x86:
+
+  ========= ====================================
+  __seg_fs  Variable is addressed relative to FS
+  __seg_gs  Variable is addressed relative to GS
+  ========= ====================================
+
+The preprocessor symbols __SEG_FS and __SEG_GS are defined when these
+address spaces are supported. Code which implements fallback modes should
+check whether these symbols are defined. Usage example::
+
+  #ifdef __SEG_GS
+
+  long data0 = 0;
+  long data1 = 1;
+
+  long __seg_gs *ptr;
+
+  /* Check whether FSGSBASE is enabled by the kernel (HWCAP2_FSGSBASE) */
+  ....
+
+  /* Set GS base to point to data0 */
+  _writegsbase_u64(&data0);
+
+  /* Access offset 0 of GS */
+  ptr = 0;
+  printf("data0 = %ld\n", *ptr);
+
+  /* Set GS base to point to data1 */
+  _writegsbase_u64(&data1);
+  /* ptr still addresses offset 0! */
+  printf("data1 = %ld\n", *ptr);
+
+
+Clang does not provide the GCC address space identifiers, but it provides
+address spaces via an attribute based mechanism in Clang 2.6 and newer
+versions:
+
+ ==================================== =====================================
+  __attribute__((address_space(256))  Variable is addressed relative to GS
+  __attribute__((address_space(257))  Variable is addressed relative to FS
+ ==================================== =====================================
+
+FS/GS based addressing with inline assembly
+-------------------------------------------
+
+In case the compiler does not support address spaces, inline assembly can
+be used for FS/GS based addressing mode::
+
+       mov %fs:offset, %reg
+       mov %gs:offset, %reg
+
+       mov %reg, %fs:offset
+       mov %reg, %gs:offset
diff --git a/Documentation/arch/x86/x86_64/index.rst b/Documentation/arch/x86/x86_64/index.rst
new file mode 100644 (file)
index 0000000..a56070f
--- /dev/null
@@ -0,0 +1,17 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==============
+x86_64 Support
+==============
+
+.. toctree::
+   :maxdepth: 2
+
+   boot-options
+   uefi
+   mm
+   5level-paging
+   fake-numa-for-cpusets
+   cpu-hotplug-spec
+   machinecheck
+   fsgs
diff --git a/Documentation/arch/x86/x86_64/machinecheck.rst b/Documentation/arch/x86/x86_64/machinecheck.rst
new file mode 100644 (file)
index 0000000..cea12ee
--- /dev/null
@@ -0,0 +1,33 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===============================================================
+Configurable sysfs parameters for the x86-64 machine check code
+===============================================================
+
+Machine checks report internal hardware error conditions detected
+by the CPU. Uncorrected errors typically cause a machine check
+(often with panic), corrected ones cause a machine check log entry.
+
+Machine checks are organized in banks (normally associated with
+a hardware subsystem) and subevents in a bank. The exact meaning
+of the banks and subevent is CPU specific.
+
+mcelog knows how to decode them.
+
+When you see the "Machine check errors logged" message in the system
+log then mcelog should run to collect and decode machine check entries
+from /dev/mcelog. Normally mcelog should be run regularly from a cronjob.
+
+Each CPU has a directory in /sys/devices/system/machinecheck/machinecheckN
+(N = CPU number).
+
+The directory contains some configurable entries. See
+Documentation/ABI/testing/sysfs-mce for more details.
+
+TBD document entries for AMD threshold interrupt configuration
+
+For more details about the x86 machine check architecture
+see the Intel and AMD architecture manuals from their developer websites.
+
+For more details about the architecture
+see http://one.firstfloor.org/~andi/mce.pdf
diff --git a/Documentation/arch/x86/x86_64/mm.rst b/Documentation/arch/x86/x86_64/mm.rst
new file mode 100644 (file)
index 0000000..35e5e18
--- /dev/null
@@ -0,0 +1,157 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=================
+Memory Management
+=================
+
+Complete virtual memory map with 4-level page tables
+====================================================
+
+.. note::
+
+ - Negative addresses such as "-23 TB" are absolute addresses in bytes, counted down
+   from the top of the 64-bit address space. It's easier to understand the layout
+   when seen both in absolute addresses and in distance-from-top notation.
+
+   For example 0xffffe90000000000 == -23 TB, it's 23 TB lower than the top of the
+   64-bit address space (ffffffffffffffff).
+
+   Note that as we get closer to the top of the address space, the notation changes
+   from TB to GB and then MB/KB.
+
+ - "16M TB" might look weird at first sight, but it's an easier way to visualize size
+   notation than "16 EB", which few will recognize at first sight as 16 exabytes.
+   It also shows it nicely how incredibly large 64-bit address space is.
+
+::
+
+  ========================================================================================================================
+      Start addr    |   Offset   |     End addr     |  Size   | VM area description
+  ========================================================================================================================
+                    |            |                  |         |
+   0000000000000000 |    0       | 00007fffffffffff |  128 TB | user-space virtual memory, different per mm
+  __________________|____________|__________________|_________|___________________________________________________________
+                    |            |                  |         |
+   0000800000000000 | +128    TB | ffff7fffffffffff | ~16M TB | ... huge, almost 64 bits wide hole of non-canonical
+                    |            |                  |         |     virtual memory addresses up to the -128 TB
+                    |            |                  |         |     starting offset of kernel mappings.
+  __________________|____________|__________________|_________|___________________________________________________________
+                                                              |
+                                                              | Kernel-space virtual memory, shared between all processes:
+  ____________________________________________________________|___________________________________________________________
+                    |            |                  |         |
+   ffff800000000000 | -128    TB | ffff87ffffffffff |    8 TB | ... guard hole, also reserved for hypervisor
+   ffff880000000000 | -120    TB | ffff887fffffffff |  0.5 TB | LDT remap for PTI
+   ffff888000000000 | -119.5  TB | ffffc87fffffffff |   64 TB | direct mapping of all physical memory (page_offset_base)
+   ffffc88000000000 |  -55.5  TB | ffffc8ffffffffff |  0.5 TB | ... unused hole
+   ffffc90000000000 |  -55    TB | ffffe8ffffffffff |   32 TB | vmalloc/ioremap space (vmalloc_base)
+   ffffe90000000000 |  -23    TB | ffffe9ffffffffff |    1 TB | ... unused hole
+   ffffea0000000000 |  -22    TB | ffffeaffffffffff |    1 TB | virtual memory map (vmemmap_base)
+   ffffeb0000000000 |  -21    TB | ffffebffffffffff |    1 TB | ... unused hole
+   ffffec0000000000 |  -20    TB | fffffbffffffffff |   16 TB | KASAN shadow memory
+  __________________|____________|__________________|_________|____________________________________________________________
+                                                              |
+                                                              | Identical layout to the 56-bit one from here on:
+  ____________________________________________________________|____________________________________________________________
+                    |            |                  |         |
+   fffffc0000000000 |   -4    TB | fffffdffffffffff |    2 TB | ... unused hole
+                    |            |                  |         | vaddr_end for KASLR
+   fffffe0000000000 |   -2    TB | fffffe7fffffffff |  0.5 TB | cpu_entry_area mapping
+   fffffe8000000000 |   -1.5  TB | fffffeffffffffff |  0.5 TB | ... unused hole
+   ffffff0000000000 |   -1    TB | ffffff7fffffffff |  0.5 TB | %esp fixup stacks
+   ffffff8000000000 | -512    GB | ffffffeeffffffff |  444 GB | ... unused hole
+   ffffffef00000000 |  -68    GB | fffffffeffffffff |   64 GB | EFI region mapping space
+   ffffffff00000000 |   -4    GB | ffffffff7fffffff |    2 GB | ... unused hole
+   ffffffff80000000 |   -2    GB | ffffffff9fffffff |  512 MB | kernel text mapping, mapped to physical address 0
+   ffffffff80000000 |-2048    MB |                  |         |
+   ffffffffa0000000 |-1536    MB | fffffffffeffffff | 1520 MB | module mapping space
+   ffffffffff000000 |  -16    MB |                  |         |
+      FIXADDR_START | ~-11    MB | ffffffffff5fffff | ~0.5 MB | kernel-internal fixmap range, variable size and offset
+   ffffffffff600000 |  -10    MB | ffffffffff600fff |    4 kB | legacy vsyscall ABI
+   ffffffffffe00000 |   -2    MB | ffffffffffffffff |    2 MB | ... unused hole
+  __________________|____________|__________________|_________|___________________________________________________________
+
+
+Complete virtual memory map with 5-level page tables
+====================================================
+
+.. note::
+
+ - With 56-bit addresses, user-space memory gets expanded by a factor of 512x,
+   from 0.125 PB to 64 PB. All kernel mappings shift down to the -64 PB starting
+   offset and many of the regions expand to support the much larger physical
+   memory supported.
+
+::
+
+  ========================================================================================================================
+      Start addr    |   Offset   |     End addr     |  Size   | VM area description
+  ========================================================================================================================
+                    |            |                  |         |
+   0000000000000000 |    0       | 00ffffffffffffff |   64 PB | user-space virtual memory, different per mm
+  __________________|____________|__________________|_________|___________________________________________________________
+                    |            |                  |         |
+   0100000000000000 |  +64    PB | feffffffffffffff | ~16K PB | ... huge, still almost 64 bits wide hole of non-canonical
+                    |            |                  |         |     virtual memory addresses up to the -64 PB
+                    |            |                  |         |     starting offset of kernel mappings.
+  __________________|____________|__________________|_________|___________________________________________________________
+                                                              |
+                                                              | Kernel-space virtual memory, shared between all processes:
+  ____________________________________________________________|___________________________________________________________
+                    |            |                  |         |
+   ff00000000000000 |  -64    PB | ff0fffffffffffff |    4 PB | ... guard hole, also reserved for hypervisor
+   ff10000000000000 |  -60    PB | ff10ffffffffffff | 0.25 PB | LDT remap for PTI
+   ff11000000000000 |  -59.75 PB | ff90ffffffffffff |   32 PB | direct mapping of all physical memory (page_offset_base)
+   ff91000000000000 |  -27.75 PB | ff9fffffffffffff | 3.75 PB | ... unused hole
+   ffa0000000000000 |  -24    PB | ffd1ffffffffffff | 12.5 PB | vmalloc/ioremap space (vmalloc_base)
+   ffd2000000000000 |  -11.5  PB | ffd3ffffffffffff |  0.5 PB | ... unused hole
+   ffd4000000000000 |  -11    PB | ffd5ffffffffffff |  0.5 PB | virtual memory map (vmemmap_base)
+   ffd6000000000000 |  -10.5  PB | ffdeffffffffffff | 2.25 PB | ... unused hole
+   ffdf000000000000 |   -8.25 PB | fffffbffffffffff |   ~8 PB | KASAN shadow memory
+  __________________|____________|__________________|_________|____________________________________________________________
+                                                              |
+                                                              | Identical layout to the 47-bit one from here on:
+  ____________________________________________________________|____________________________________________________________
+                    |            |                  |         |
+   fffffc0000000000 |   -4    TB | fffffdffffffffff |    2 TB | ... unused hole
+                    |            |                  |         | vaddr_end for KASLR
+   fffffe0000000000 |   -2    TB | fffffe7fffffffff |  0.5 TB | cpu_entry_area mapping
+   fffffe8000000000 |   -1.5  TB | fffffeffffffffff |  0.5 TB | ... unused hole
+   ffffff0000000000 |   -1    TB | ffffff7fffffffff |  0.5 TB | %esp fixup stacks
+   ffffff8000000000 | -512    GB | ffffffeeffffffff |  444 GB | ... unused hole
+   ffffffef00000000 |  -68    GB | fffffffeffffffff |   64 GB | EFI region mapping space
+   ffffffff00000000 |   -4    GB | ffffffff7fffffff |    2 GB | ... unused hole
+   ffffffff80000000 |   -2    GB | ffffffff9fffffff |  512 MB | kernel text mapping, mapped to physical address 0
+   ffffffff80000000 |-2048    MB |                  |         |
+   ffffffffa0000000 |-1536    MB | fffffffffeffffff | 1520 MB | module mapping space
+   ffffffffff000000 |  -16    MB |                  |         |
+      FIXADDR_START | ~-11    MB | ffffffffff5fffff | ~0.5 MB | kernel-internal fixmap range, variable size and offset
+   ffffffffff600000 |  -10    MB | ffffffffff600fff |    4 kB | legacy vsyscall ABI
+   ffffffffffe00000 |   -2    MB | ffffffffffffffff |    2 MB | ... unused hole
+  __________________|____________|__________________|_________|___________________________________________________________
+
+Architecture defines a 64-bit virtual address. Implementations can support
+less. Currently supported are 48- and 57-bit virtual addresses. Bits 63
+through to the most-significant implemented bit are sign extended.
+This causes hole between user space and kernel addresses if you interpret them
+as unsigned.
+
+The direct mapping covers all memory in the system up to the highest
+memory address (this means in some cases it can also include PCI memory
+holes).
+
+We map EFI runtime services in the 'efi_pgd' PGD in a 64GB large virtual
+memory window (this size is arbitrary, it can be raised later if needed).
+The mappings are not part of any other kernel PGD and are only available
+during EFI runtime calls.
+
+Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all
+physical memory, vmalloc/ioremap space and virtual memory map are randomized.
+Their order is preserved but their base will be offset early at boot time.
+
+Be very careful vs. KASLR when changing anything here. The KASLR address
+range must not overlap with anything except the KASAN shadow area, which is
+correct as KASAN disables KASLR.
+
+For both 4- and 5-level layouts, the STACKLEAK_POISON value in the last 2MB
+hole: ffffffffffff4111
diff --git a/Documentation/arch/x86/x86_64/uefi.rst b/Documentation/arch/x86/x86_64/uefi.rst
new file mode 100644 (file)
index 0000000..fbc30c9
--- /dev/null
@@ -0,0 +1,58 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=====================================
+General note on [U]EFI x86_64 support
+=====================================
+
+The nomenclature EFI and UEFI are used interchangeably in this document.
+
+Although the tools below are _not_ needed for building the kernel,
+the needed bootloader support and associated tools for x86_64 platforms
+with EFI firmware and specifications are listed below.
+
+1. UEFI specification:  http://www.uefi.org
+
+2. Booting Linux kernel on UEFI x86_64 platform requires bootloader
+   support. Elilo with x86_64 support can be used.
+
+3. x86_64 platform with EFI/UEFI firmware.
+
+Mechanics
+---------
+
+- Build the kernel with the following configuration::
+
+       CONFIG_FB_EFI=y
+       CONFIG_FRAMEBUFFER_CONSOLE=y
+
+  If EFI runtime services are expected, the following configuration should
+  be selected::
+
+       CONFIG_EFI=y
+       CONFIG_EFIVAR_FS=y or m         # optional
+
+- Create a VFAT partition on the disk
+- Copy the following to the VFAT partition:
+
+       elilo bootloader with x86_64 support, elilo configuration file,
+       kernel image built in first step and corresponding
+       initrd. Instructions on building elilo and its dependencies
+       can be found in the elilo sourceforge project.
+
+- Boot to EFI shell and invoke elilo choosing the kernel image built
+  in first step.
+- If some or all EFI runtime services don't work, you can try following
+  kernel command line parameters to turn off some or all EFI runtime
+  services.
+
+       noefi
+               turn off all EFI runtime services
+       reboot_type=k
+               turn off EFI reboot runtime service
+
+- If the EFI memory map has additional entries not in the E820 map,
+  you can include those entries in the kernels memory map of available
+  physical RAM by using the following kernel command line parameter.
+
+       add_efi_memmap
+               include EFI memory map of available physical RAM
diff --git a/Documentation/arch/x86/xstate.rst b/Documentation/arch/x86/xstate.rst
new file mode 100644 (file)
index 0000000..5cec7fb
--- /dev/null
@@ -0,0 +1,74 @@
+Using XSTATE features in user space applications
+================================================
+
+The x86 architecture supports floating-point extensions which are
+enumerated via CPUID. Applications consult CPUID and use XGETBV to
+evaluate which features have been enabled by the kernel XCR0.
+
+Up to AVX-512 and PKRU states, these features are automatically enabled by
+the kernel if available. Features like AMX TILE_DATA (XSTATE component 18)
+are enabled by XCR0 as well, but the first use of related instruction is
+trapped by the kernel because by default the required large XSTATE buffers
+are not allocated automatically.
+
+Using dynamically enabled XSTATE features in user space applications
+--------------------------------------------------------------------
+
+The kernel provides an arch_prctl(2) based mechanism for applications to
+request the usage of such features. The arch_prctl(2) options related to
+this are:
+
+-ARCH_GET_XCOMP_SUPP
+
+ arch_prctl(ARCH_GET_XCOMP_SUPP, &features);
+
+ ARCH_GET_XCOMP_SUPP stores the supported features in userspace storage of
+ type uint64_t. The second argument is a pointer to that storage.
+
+-ARCH_GET_XCOMP_PERM
+
+ arch_prctl(ARCH_GET_XCOMP_PERM, &features);
+
+ ARCH_GET_XCOMP_PERM stores the features for which the userspace process
+ has permission in userspace storage of type uint64_t. The second argument
+ is a pointer to that storage.
+
+-ARCH_REQ_XCOMP_PERM
+
+ arch_prctl(ARCH_REQ_XCOMP_PERM, feature_nr);
+
+ ARCH_REQ_XCOMP_PERM allows to request permission for a dynamically enabled
+ feature or a feature set. A feature set can be mapped to a facility, e.g.
+ AMX, and can require one or more XSTATE components to be enabled.
+
+ The feature argument is the number of the highest XSTATE component which
+ is required for a facility to work.
+
+When requesting permission for a feature, the kernel checks the
+availability. The kernel ensures that sigaltstacks in the process's tasks
+are large enough to accommodate the resulting large signal frame. It
+enforces this both during ARCH_REQ_XCOMP_SUPP and during any subsequent
+sigaltstack(2) calls. If an installed sigaltstack is smaller than the
+resulting sigframe size, ARCH_REQ_XCOMP_SUPP results in -ENOSUPP. Also,
+sigaltstack(2) results in -ENOMEM if the requested altstack is too small
+for the permitted features.
+
+Permission, when granted, is valid per process. Permissions are inherited
+on fork(2) and cleared on exec(3).
+
+The first use of an instruction related to a dynamically enabled feature is
+trapped by the kernel. The trap handler checks whether the process has
+permission to use the feature. If the process has no permission then the
+kernel sends SIGILL to the application. If the process has permission then
+the handler allocates a larger xstate buffer for the task so the large
+state can be context switched. In the unlikely cases that the allocation
+fails, the kernel sends SIGSEGV.
+
+Dynamic features in signal frames
+---------------------------------
+
+Dynamcally enabled features are not written to the signal frame upon signal
+entry if the feature is in its initial configuration.  This differs from
+non-dynamic features which are always written regardless of their
+configuration.  Signal handlers can examine the XSAVE buffer's XSTATE_BV
+field to determine if a features was written.
diff --git a/Documentation/arch/x86/zero-page.rst b/Documentation/arch/x86/zero-page.rst
new file mode 100644 (file)
index 0000000..45aa9cc
--- /dev/null
@@ -0,0 +1,47 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=========
+Zero Page
+=========
+The additional fields in struct boot_params as a part of 32-bit boot
+protocol of kernel. These should be filled by bootloader or 16-bit
+real-mode setup code of the kernel. References/settings to it mainly
+are in::
+
+  arch/x86/include/uapi/asm/bootparam.h
+
+===========    =====   ======================= =================================================
+Offset/Size    Proto   Name                    Meaning
+
+000/040                ALL     screen_info             Text mode or frame buffer information
+                                               (struct screen_info)
+040/014                ALL     apm_bios_info           APM BIOS information (struct apm_bios_info)
+058/008                ALL     tboot_addr              Physical address of tboot shared page
+060/010                ALL     ist_info                Intel SpeedStep (IST) BIOS support information
+                                               (struct ist_info)
+070/008                ALL     acpi_rsdp_addr          Physical address of ACPI RSDP table
+080/010                ALL     hd0_info                hd0 disk parameter, OBSOLETE!!
+090/010                ALL     hd1_info                hd1 disk parameter, OBSOLETE!!
+0A0/010                ALL     sys_desc_table          System description table (struct sys_desc_table),
+                                               OBSOLETE!!
+0B0/010                ALL     olpc_ofw_header         OLPC's OpenFirmware CIF and friends
+0C0/004                ALL     ext_ramdisk_image       ramdisk_image high 32bits
+0C4/004                ALL     ext_ramdisk_size        ramdisk_size high 32bits
+0C8/004                ALL     ext_cmd_line_ptr        cmd_line_ptr high 32bits
+13C/004                ALL     cc_blob_address         Physical address of Confidential Computing blob
+140/080                ALL     edid_info               Video mode setup (struct edid_info)
+1C0/020                ALL     efi_info                EFI 32 information (struct efi_info)
+1E0/004                ALL     alt_mem_k               Alternative mem check, in KB
+1E4/004                ALL     scratch                 Scratch field for the kernel setup code
+1E8/001                ALL     e820_entries            Number of entries in e820_table (below)
+1E9/001                ALL     eddbuf_entries          Number of entries in eddbuf (below)
+1EA/001                ALL     edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer
+                                               (below)
+1EB/001                ALL     kbd_status              Numlock is enabled
+1EC/001                ALL     secure_boot             Secure boot is enabled in the firmware
+1EF/001                ALL     sentinel                Used to detect broken bootloaders
+290/040                ALL     edd_mbr_sig_buffer      EDD MBR signatures
+2D0/A00                ALL     e820_table              E820 memory map table
+                                               (array of struct e820_entry)
+D00/1EC                ALL     eddbuf                  EDD data (array of struct edd_info)
+===========    =====   ======================= =================================================
diff --git a/Documentation/arch/xtensa/atomctl.rst b/Documentation/arch/xtensa/atomctl.rst
new file mode 100644 (file)
index 0000000..1ecbd0b
--- /dev/null
@@ -0,0 +1,51 @@
+===========================================
+Atomic Operation Control (ATOMCTL) Register
+===========================================
+
+We Have Atomic Operation Control (ATOMCTL) Register.
+This register determines the effect of using a S32C1I instruction
+with various combinations of:
+
+     1. With and without an Coherent Cache Controller which
+        can do Atomic Transactions to the memory internally.
+
+     2. With and without An Intelligent Memory Controller which
+        can do Atomic Transactions itself.
+
+The Core comes up with a default value of for the three types of cache ops::
+
+      0x28: (WB: Internal, WT: Internal, BY:Exception)
+
+On the FPGA Cards we typically simulate an Intelligent Memory controller
+which can implement  RCW transactions. For FPGA cards with an External
+Memory controller we let it to the atomic operations internally while
+doing a Cached (WB) transaction and use the Memory RCW for un-cached
+operations.
+
+For systems without an coherent cache controller, non-MX, we always
+use the memory controllers RCW, thought non-MX controlers likely
+support the Internal Operation.
+
+CUSTOMER-WARNING:
+   Virtually all customers buy their memory controllers from vendors that
+   don't support atomic RCW memory transactions and will likely want to
+   configure this register to not use RCW.
+
+Developers might find using RCW in Bypass mode convenient when testing
+with the cache being bypassed; for example studying cache alias problems.
+
+See Section 4.3.12.4 of ISA; Bits::
+
+                             WB     WT      BY
+                           5   4 | 3   2 | 1   0
+
+=========    ==================      ==================      ===============
+  2 Bit
+  Field
+  Values     WB - Write Back         WT - Write Thru         BY - Bypass
+=========    ==================      ==================      ===============
+    0        Exception               Exception               Exception
+    1        RCW Transaction         RCW Transaction         RCW Transaction
+    2        Internal Operation      Internal Operation      Reserved
+    3        Reserved                Reserved                Reserved
+=========    ==================      ==================      ===============
diff --git a/Documentation/arch/xtensa/booting.rst b/Documentation/arch/xtensa/booting.rst
new file mode 100644 (file)
index 0000000..e1b8370
--- /dev/null
@@ -0,0 +1,22 @@
+=====================================
+Passing boot parameters to the kernel
+=====================================
+
+Boot parameters are represented as a TLV list in the memory. Please see
+arch/xtensa/include/asm/bootparam.h for definition of the bp_tag structure and
+tag value constants. First entry in the list must have type BP_TAG_FIRST, last
+entry must have type BP_TAG_LAST. The address of the first list entry is
+passed to the kernel in the register a2. The address type depends on MMU type:
+
+- For configurations without MMU, with region protection or with MPU the
+  address must be the physical address.
+- For configurations with region translarion MMU or with MMUv3 and CONFIG_MMU=n
+  the address must be a valid address in the current mapping. The kernel will
+  not change the mapping on its own.
+- For configurations with MMUv2 the address must be a virtual address in the
+  default virtual mapping (0xd0000000..0xffffffff).
+- For configurations with MMUv3 and CONFIG_MMU=y the address may be either a
+  virtual or physical address. In either case it must be within the default
+  virtual mapping. It is considered physical if it is within the range of
+  physical addresses covered by the default KSEG mapping (XCHAL_KSEG_PADDR..
+  XCHAL_KSEG_PADDR + XCHAL_KSEG_SIZE), otherwise it is considered virtual.
diff --git a/Documentation/arch/xtensa/features.rst b/Documentation/arch/xtensa/features.rst
new file mode 100644 (file)
index 0000000..6b92c7b
--- /dev/null
@@ -0,0 +1,3 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. kernel-feat:: $srctree/Documentation/features xtensa
diff --git a/Documentation/arch/xtensa/index.rst b/Documentation/arch/xtensa/index.rst
new file mode 100644 (file)
index 0000000..6995244
--- /dev/null
@@ -0,0 +1,14 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===================
+Xtensa Architecture
+===================
+
+.. toctree::
+   :maxdepth: 1
+
+   atomctl
+   booting
+   mmu
+
+   features
diff --git a/Documentation/arch/xtensa/mmu.rst b/Documentation/arch/xtensa/mmu.rst
new file mode 100644 (file)
index 0000000..450573a
--- /dev/null
@@ -0,0 +1,198 @@
+=============================
+MMUv3 initialization sequence
+=============================
+
+The code in the initialize_mmu macro sets up MMUv3 memory mapping
+identically to MMUv2 fixed memory mapping. Depending on
+CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX symbol this code is
+located in addresses it was linked for (symbol undefined), or not
+(symbol defined), so it needs to be position-independent.
+
+The code has the following assumptions:
+
+  - This code fragment is run only on an MMU v3.
+  - TLBs are in their reset state.
+  - ITLBCFG and DTLBCFG are zero (reset state).
+  - RASID is 0x04030201 (reset state).
+  - PS.RING is zero (reset state).
+  - LITBASE is zero (reset state, PC-relative literals); required to be PIC.
+
+TLB setup proceeds along the following steps.
+
+  Legend:
+
+    - VA = virtual address (two upper nibbles of it);
+    - PA = physical address (two upper nibbles of it);
+    - pc = physical range that contains this code;
+
+After step 2, we jump to virtual address in the range 0x40000000..0x5fffffff
+or 0x00000000..0x1fffffff, depending on whether the kernel was loaded below
+0x40000000 or above. That address corresponds to next instruction to execute
+in this code. After step 4, we jump to intended (linked) address of this code.
+The scheme below assumes that the kernel is loaded below 0x40000000.
+
+ ====== =====  =====  =====  =====   ====== =====  =====
+ -      Step0  Step1  Step2  Step3          Step4  Step5
+
+   VA      PA     PA     PA     PA     VA      PA     PA
+ ====== =====  =====  =====  =====   ====== =====  =====
+ E0..FF -> E0  -> E0  -> E0          F0..FF -> F0  -> F0
+ C0..DF -> C0  -> C0  -> C0          E0..EF -> F0  -> F0
+ A0..BF -> A0  -> A0  -> A0          D8..DF -> 00  -> 00
+ 80..9F -> 80  -> 80  -> 80          D0..D7 -> 00  -> 00
+ 60..7F -> 60  -> 60  -> 60
+ 40..5F -> 40         -> pc  -> pc   40..5F -> pc
+ 20..3F -> 20  -> 20  -> 20
+ 00..1F -> 00  -> 00  -> 00
+ ====== =====  =====  =====  =====   ====== =====  =====
+
+The default location of IO peripherals is above 0xf0000000. This may be changed
+using a "ranges" property in a device tree simple-bus node. See the Devicetree
+Specification, section 4.5 for details on the syntax and semantics of
+simple-bus nodes. The following limitations apply:
+
+1. Only top level simple-bus nodes are considered
+
+2. Only one (first) simple-bus node is considered
+
+3. Empty "ranges" properties are not supported
+
+4. Only the first triplet in the "ranges" property is considered
+
+5. The parent-bus-address value is rounded down to the nearest 256MB boundary
+
+6. The IO area covers the entire 256MB segment of parent-bus-address; the
+   "ranges" triplet length field is ignored
+
+
+MMUv3 address space layouts.
+============================
+
+Default MMUv2-compatible layout::
+
+                        Symbol                   VADDR       Size
+  +------------------+
+  | Userspace        |                           0x00000000  TASK_SIZE
+  +------------------+                           0x40000000
+  +------------------+
+  | Page table       |  XCHAL_PAGE_TABLE_VADDR   0x80000000  XCHAL_PAGE_TABLE_SIZE
+  +------------------+
+  | KASAN shadow map |  KASAN_SHADOW_START       0x80400000  KASAN_SHADOW_SIZE
+  +------------------+                           0x8e400000
+  +------------------+
+  | VMALLOC area     |  VMALLOC_START            0xc0000000  128MB - 64KB
+  +------------------+  VMALLOC_END
+  +------------------+
+  | Cache aliasing   |  TLBTEMP_BASE_1           0xc8000000  DCACHE_WAY_SIZE
+  | remap area 1     |
+  +------------------+
+  | Cache aliasing   |  TLBTEMP_BASE_2                       DCACHE_WAY_SIZE
+  | remap area 2     |
+  +------------------+
+  +------------------+
+  | KMAP area        |  PKMAP_BASE                           PTRS_PER_PTE *
+  |                  |                                       DCACHE_N_COLORS *
+  |                  |                                       PAGE_SIZE
+  |                  |                                       (4MB * DCACHE_N_COLORS)
+  +------------------+
+  | Atomic KMAP area |  FIXADDR_START                        KM_TYPE_NR *
+  |                  |                                       NR_CPUS *
+  |                  |                                       DCACHE_N_COLORS *
+  |                  |                                       PAGE_SIZE
+  +------------------+  FIXADDR_TOP              0xcffff000
+  +------------------+
+  | Cached KSEG      |  XCHAL_KSEG_CACHED_VADDR  0xd0000000  128MB
+  +------------------+
+  | Uncached KSEG    |  XCHAL_KSEG_BYPASS_VADDR  0xd8000000  128MB
+  +------------------+
+  | Cached KIO       |  XCHAL_KIO_CACHED_VADDR   0xe0000000  256MB
+  +------------------+
+  | Uncached KIO     |  XCHAL_KIO_BYPASS_VADDR   0xf0000000  256MB
+  +------------------+
+
+
+256MB cached + 256MB uncached layout::
+
+                        Symbol                   VADDR       Size
+  +------------------+
+  | Userspace        |                           0x00000000  TASK_SIZE
+  +------------------+                           0x40000000
+  +------------------+
+  | Page table       |  XCHAL_PAGE_TABLE_VADDR   0x80000000  XCHAL_PAGE_TABLE_SIZE
+  +------------------+
+  | KASAN shadow map |  KASAN_SHADOW_START       0x80400000  KASAN_SHADOW_SIZE
+  +------------------+                           0x8e400000
+  +------------------+
+  | VMALLOC area     |  VMALLOC_START            0xa0000000  128MB - 64KB
+  +------------------+  VMALLOC_END
+  +------------------+
+  | Cache aliasing   |  TLBTEMP_BASE_1           0xa8000000  DCACHE_WAY_SIZE
+  | remap area 1     |
+  +------------------+
+  | Cache aliasing   |  TLBTEMP_BASE_2                       DCACHE_WAY_SIZE
+  | remap area 2     |
+  +------------------+
+  +------------------+
+  | KMAP area        |  PKMAP_BASE                           PTRS_PER_PTE *
+  |                  |                                       DCACHE_N_COLORS *
+  |                  |                                       PAGE_SIZE
+  |                  |                                       (4MB * DCACHE_N_COLORS)
+  +------------------+
+  | Atomic KMAP area |  FIXADDR_START                        KM_TYPE_NR *
+  |                  |                                       NR_CPUS *
+  |                  |                                       DCACHE_N_COLORS *
+  |                  |                                       PAGE_SIZE
+  +------------------+  FIXADDR_TOP              0xaffff000
+  +------------------+
+  | Cached KSEG      |  XCHAL_KSEG_CACHED_VADDR  0xb0000000  256MB
+  +------------------+
+  | Uncached KSEG    |  XCHAL_KSEG_BYPASS_VADDR  0xc0000000  256MB
+  +------------------+
+  +------------------+
+  | Cached KIO       |  XCHAL_KIO_CACHED_VADDR   0xe0000000  256MB
+  +------------------+
+  | Uncached KIO     |  XCHAL_KIO_BYPASS_VADDR   0xf0000000  256MB
+  +------------------+
+
+
+512MB cached + 512MB uncached layout::
+
+                        Symbol                   VADDR       Size
+  +------------------+
+  | Userspace        |                           0x00000000  TASK_SIZE
+  +------------------+                           0x40000000
+  +------------------+
+  | Page table       |  XCHAL_PAGE_TABLE_VADDR   0x80000000  XCHAL_PAGE_TABLE_SIZE
+  +------------------+
+  | KASAN shadow map |  KASAN_SHADOW_START       0x80400000  KASAN_SHADOW_SIZE
+  +------------------+                           0x8e400000
+  +------------------+
+  | VMALLOC area     |  VMALLOC_START            0x90000000  128MB - 64KB
+  +------------------+  VMALLOC_END
+  +------------------+
+  | Cache aliasing   |  TLBTEMP_BASE_1           0x98000000  DCACHE_WAY_SIZE
+  | remap area 1     |
+  +------------------+
+  | Cache aliasing   |  TLBTEMP_BASE_2                       DCACHE_WAY_SIZE
+  | remap area 2     |
+  +------------------+
+  +------------------+
+  | KMAP area        |  PKMAP_BASE                           PTRS_PER_PTE *
+  |                  |                                       DCACHE_N_COLORS *
+  |                  |                                       PAGE_SIZE
+  |                  |                                       (4MB * DCACHE_N_COLORS)
+  +------------------+
+  | Atomic KMAP area |  FIXADDR_START                        KM_TYPE_NR *
+  |                  |                                       NR_CPUS *
+  |                  |                                       DCACHE_N_COLORS *
+  |                  |                                       PAGE_SIZE
+  +------------------+  FIXADDR_TOP              0x9ffff000
+  +------------------+
+  | Cached KSEG      |  XCHAL_KSEG_CACHED_VADDR  0xa0000000  512MB
+  +------------------+
+  | Uncached KSEG    |  XCHAL_KSEG_BYPASS_VADDR  0xc0000000  512MB
+  +------------------+
+  | Cached KIO       |  XCHAL_KIO_CACHED_VADDR   0xe0000000  256MB
+  +------------------+
+  | Uncached KIO     |  XCHAL_KIO_BYPASS_VADDR   0xf0000000  256MB
+  +------------------+
index ae42fe886f0dc622787f84dde8b3d2582ecd5c63..8890ec4314c2d38be44187eb292fdbcddf494e8e 100644 (file)
@@ -69,11 +69,9 @@ SoC-specific documents
 
    spear/overview
 
-   sti/stih416-overview
    sti/stih407-overview
    sti/stih418-overview
    sti/overview
-   sti/stih415-overview
 
    vfp/release-notes
 
index 70743617a74fa9b358cfd69995311fe4d24ab6b0..ae16aced800f4949c651b030737566e0bde726e4 100644 (file)
@@ -7,22 +7,18 @@ Introduction
 
   The ST Microelectronics Multimedia and Application Processors range of
   CortexA9 System-on-Chip are supported by the 'STi' platform of
-  ARM Linux. Currently STiH415, STiH416 SOCs are supported with both
-  B2000 and B2020 Reference boards.
+  ARM Linux. Currently STiH407, STiH410 and STiH418 are supported.
 
 
 configuration
 -------------
 
-  A generic configuration is provided for both STiH415/416, and can be used as the
-  default by::
-
-       make stih41x_defconfig
+  The configuration for the STi platform is supported via the multi_v7_defconfig.
 
 Layout
 ------
 
-  All the files for multiple machine families (STiH415, STiH416, and STiG125)
+  All the files for multiple machine families (STiH407, STiH410, and STiH418)
   are located in the platform code contained in arch/arm/mach-sti
 
   There is a generic board board-dt.c in the mach folder which support
diff --git a/Documentation/arm/sti/stih415-overview.rst b/Documentation/arm/sti/stih415-overview.rst
deleted file mode 100644 (file)
index b67452d..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-================
-STiH415 Overview
-================
-
-Introduction
-------------
-
-    The STiH415 is the next generation of HD, AVC set-top box processors
-    for satellite, cable, terrestrial and IP-STB markets.
-
-    Features:
-
-    - ARM Cortex-A9 1.0 GHz, dual-core CPU
-    - SATA2x2,USB 2.0x3, PCIe, Gbit Ethernet MACx2
diff --git a/Documentation/arm/sti/stih416-overview.rst b/Documentation/arm/sti/stih416-overview.rst
deleted file mode 100644 (file)
index 93f17d7..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-================
-STiH416 Overview
-================
-
-Introduction
-------------
-
-    The STiH416 is the next generation of HD, AVC set-top box processors
-    for satellite, cable, terrestrial and IP-STB markets.
-
-    Features
-    - ARM Cortex-A9 1.2 GHz dual core CPU
-    - SATA2x2,USB 2.0x3, PCIe, Gbit Ethernet MACx2
index 03d4993eda6f055732478b6067d44cf7399ec5d0..b421d94dc9f216ab44e44f8eed0035c6e796df3f 100644 (file)
@@ -7,8 +7,8 @@ workflows related to reporting bugs, submitting patches, and queueing
 patches for stable kernels.
 
 For general information about submitting patches, please refer to
-`Documentation/process/`_. This document only describes additional specifics
-related to BPF.
+Documentation/process/submitting-patches.rst. This document only describes
+additional specifics related to BPF.
 
 .. contents::
     :local:
@@ -461,15 +461,15 @@ needed::
 
   $ sudo make run_tests
 
-See the kernels selftest `Documentation/dev-tools/kselftest.rst`_
-document for further documentation.
+See :doc:`kernel selftest documentation </dev-tools/kselftest>`
+for details.
 
 To maximize the number of tests passing, the .config of the kernel
 under test should match the config file fragment in
 tools/testing/selftests/bpf as closely as possible.
 
 Finally to ensure support for latest BPF Type Format features -
-discussed in `Documentation/bpf/btf.rst`_ - pahole version 1.16
+discussed in Documentation/bpf/btf.rst - pahole version 1.16
 is required for kernels built with CONFIG_DEBUG_INFO_BTF=y.
 pahole is delivered in the dwarves package or can be built
 from source at
@@ -684,12 +684,8 @@ when:
 
 
 .. Links
-.. _Documentation/process/: https://www.kernel.org/doc/html/latest/process/
 .. _netdev-FAQ: Documentation/process/maintainer-netdev.rst
 .. _selftests:
    https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/testing/selftests/bpf/
-.. _Documentation/dev-tools/kselftest.rst:
-   https://www.kernel.org/doc/html/latest/dev-tools/kselftest.html
-.. _Documentation/bpf/btf.rst: btf.rst
 
 Happy BPF hacking!
index db16814f182fc52563fc014b400053bcbc975a11..37314afd1ac8aa6aed755612b45c5e9ad0ecabd0 100644 (file)
@@ -343,9 +343,10 @@ sys.stderr.write("Using %s theme\n" % html_theme)
 # so a file named "default.css" will overwrite the builtin "default.css".
 html_static_path = ['sphinx-static']
 
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-html_use_smartypants = False
+# If true, Docutils "smart quotes" will be used to convert quotes and dashes
+# to typographically correct entities.  This will convert "--" to "—",
+# which is not always what we want, so disable it.
+smartquotes = False
 
 # Custom sidebar templates, maps document names to template names.
 # Note that the RTD theme ignores this
index bc514ed598870c69406663b505642987052bb632..11c96d3f9ad6d78bf212fa6224540b99f8012f3b 100644 (file)
@@ -44,7 +44,7 @@ information. In particular, on properly annotated objects, ``objtool`` can be
 run to check and fix the object if needed. Currently, ``objtool`` can report
 missing frame pointer setup/destruction in functions. It can also
 automatically generate annotations for the ORC unwinder
-(Documentation/x86/orc-unwinder.rst)
+(Documentation/arch/x86/orc-unwinder.rst)
 for most code. Both of these are especially important to support reliable
 stack traces which are in turn necessary for kernel live patching
 (Documentation/livepatch/livepatch.rst).
index 828846804e25a246d422f9df28d9df5b184f5c08..72f6cdb6be1c012f7d2b4da987cf341b5bfaad55 100644 (file)
@@ -185,7 +185,7 @@ device struct of your device is embedded in the bus-specific device struct of
 your device.  For example, &pdev->dev is a pointer to the device struct of a
 PCI device (pdev is a pointer to the PCI device struct of your device).
 
-These calls usually return zero to indicated your device can perform DMA
+These calls usually return zero to indicate your device can perform DMA
 properly on the machine given the address mask you provided, but they might
 return an error if the mask is too small to be supportable on the given
 system.  If it returns non-zero, your device cannot perform DMA properly on
index 5483fd39ef2956d51750e6ef2bce37b96f7defc1..2cb00b53339fe9830a41867becc9beb4650f216a 100644 (file)
@@ -227,7 +227,7 @@ Testing with kmemleak-test
 --------------------------
 
 To check if you have all set up to use kmemleak, you can use the kmemleak-test
-module, a module that deliberately leaks memory. Set CONFIG_DEBUG_KMEMLEAK_TEST
+module, a module that deliberately leaks memory. Set CONFIG_SAMPLE_KMEMLEAK
 as module (it can't be used as built-in) and boot the kernel with kmemleak
 enabled. Load the module and perform a scan with::
 
diff --git a/Documentation/devicetree/bindings/interrupt-controller/loongarch,cpu-interrupt-controller.yaml b/Documentation/devicetree/bindings/interrupt-controller/loongarch,cpu-interrupt-controller.yaml
deleted file mode 100644 (file)
index 2a1cf88..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/interrupt-controller/loongarch,cpu-interrupt-controller.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: LoongArch CPU Interrupt Controller
-
-maintainers:
-  - Liu Peibao <liupeibao@loongson.cn>
-
-properties:
-  compatible:
-    const: loongarch,cpu-interrupt-controller
-
-  '#interrupt-cells':
-    const: 1
-
-  interrupt-controller: true
-
-additionalProperties: false
-
-required:
-  - compatible
-  - '#interrupt-cells'
-  - interrupt-controller
-
-examples:
-  - |
-    interrupt-controller {
-      compatible = "loongarch,cpu-interrupt-controller";
-      #interrupt-cells = <1>;
-      interrupt-controller;
-    };
diff --git a/Documentation/devicetree/bindings/interrupt-controller/loongson,cpu-interrupt-controller.yaml b/Documentation/devicetree/bindings/interrupt-controller/loongson,cpu-interrupt-controller.yaml
new file mode 100644 (file)
index 0000000..adf9899
--- /dev/null
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/loongson,cpu-interrupt-controller.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: LoongArch CPU Interrupt Controller
+
+maintainers:
+  - Liu Peibao <liupeibao@loongson.cn>
+
+properties:
+  compatible:
+    const: loongson,cpu-interrupt-controller
+
+  '#interrupt-cells':
+    const: 1
+
+  interrupt-controller: true
+
+additionalProperties: false
+
+required:
+  - compatible
+  - '#interrupt-cells'
+  - interrupt-controller
+
+examples:
+  - |
+    interrupt-controller {
+      compatible = "loongson,cpu-interrupt-controller";
+      #interrupt-cells = <1>;
+      interrupt-controller;
+    };
index 3fe981b14e2cb7d3380c19de4b56fc12bf99b00e..54736362378eb5975712fccb9a6f73c058741533 100644 (file)
@@ -76,6 +76,13 @@ properties:
       If "broken-flash-reset" is present then having this property does not
       make any difference.
 
+  spi-cpol: true
+  spi-cpha: true
+
+dependencies:
+  spi-cpol: [ spi-cpha ]
+  spi-cpha: [ spi-cpol ]
+
 unevaluatedProperties: false
 
 examples:
index 5e90051ed314ae1c1f8f60db6e3ead4e5aa99d3f..8f60a9113e7a28ab7628e036d4d2445102868d1e 100644 (file)
@@ -96,9 +96,11 @@ $defs:
           2: Lower Slew rate (slower edges)
           3: Reserved (No adjustments)
 
+      bias-bus-hold: true
       bias-pull-down: true
       bias-pull-up: true
       bias-disable: true
+      input-enable: true
       output-high: true
       output-low: true
 
index 1989bd67d04e8ad923fc45b25e5dec533dc096a1..54e4f41be9b4261ba877d9b2066a632b32a3d979 100644 (file)
@@ -92,7 +92,7 @@ properties:
           - description: Error interrupt
           - description: Receive buffer full interrupt
           - description: Transmit buffer empty interrupt
-          - description: Transmit End interrupt
+          - description: Break interrupt
       - items:
           - description: Error interrupt
           - description: Receive buffer full interrupt
@@ -107,7 +107,7 @@ properties:
           - const: eri
           - const: rxi
           - const: txi
-          - const: tei
+          - const: bri
       - items:
           - const: eri
           - const: rxi
index 3cad45d14187243e71a584cb82daa8a5adb8f678..93bab5336dfda06069eea700d2830089bf3bce03 100644 (file)
@@ -258,6 +258,11 @@ clocks properly but rely on them being on from the bootloader, bypassing
 the disabling means that the driver will remain functional while the issues
 are sorted out.
 
+You can see which clocks have been disabled by booting your kernel with these
+parameters::
+
+ tp_printk trace_event=clk:clk_disable
+
 To bypass this disabling, include "clk_ignore_unused" in the bootargs to the
 kernel.
 
index 4d2baac0311c8b0a206396370de20b3a07b6778f..2c7abd234f4e2480de17eec155191ddeb6b69fbe 100644 (file)
@@ -410,7 +410,7 @@ ioremap_uc()
 
 ioremap_uc() behaves like ioremap() except that on the x86 architecture without
 'PAT' mode, it marks memory as uncached even when the MTRR has designated
-it as cacheable, see Documentation/x86/pat.rst.
+it as cacheable, see Documentation/arch/x86/pat.rst.
 
 Portable drivers should avoid the use of ioremap_uc().
 
index a360f1009fa342e57f672159120c1ae5c902bfd2..d7cb1e8f00761f600a05ad8c373e7a88b2fd8e79 100644 (file)
@@ -22,5 +22,10 @@ can use the file:
 
 * /sys/module/firmware_class/parameters/path
 
-You would echo into it your custom path and firmware requested will be
-searched for there first.
+You would echo into it your custom path and firmware requested will be searched
+for there first. Be aware that newline characters will be taken into account
+and may not produce the intended effects. For instance you might want to use:
+
+echo -n /path/to/script > /sys/module/firmware_class/parameters/path
+
+to ensure that your script is being used.
index 50b690f7f66392d5131a2410717caa0cc44cd53e..68abc089d6ddd173013b115ff65df1e84b292706 100644 (file)
@@ -242,7 +242,7 @@ group and can access them as follows::
 VFIO User API
 -------------------------------------------------------------------------------
 
-Please see include/linux/vfio.h for complete API documentation.
+Please see include/uapi/linux/vfio.h for complete API documentation.
 
 VFIO bus driver API
 -------------------------------------------------------------------------------
index a43aacf1494e778585aea093fb4c099dc4459be7..4654ee57c1d5e4ef5d59d9b34cea5651434c5b34 100644 (file)
@@ -40,8 +40,8 @@ Here are the main features of EROFS:
  - Support multiple devices to refer to external blobs, which can be used
    for container images;
 
- - 4KiB block size and 32-bit block addresses for each device, therefore
-   16TiB address space at most for now;
+ - 32-bit block addresses for each device, therefore 16TiB address space at
+   most with 4KiB block size for now;
 
  - Two inode layouts for different requirements:
 
index 46d78f860623f146915d518456d7a99991172a42..ed5a5cac6d40e15c9a6745189d0e4314913feda1 100644 (file)
@@ -105,9 +105,9 @@ descriptors. Instead, the superblock and a single block group descriptor
 block is placed at the beginning of the first, second, and last block
 groups in a meta-block group. A meta-block group is a collection of
 block groups which can be described by a single block group descriptor
-block. Since the size of the block group descriptor structure is 32
-bytes, a meta-block group contains 32 block groups for filesystems with
-a 1KB block size, and 128 block groups for filesystems with a 4KB
+block. Since the size of the block group descriptor structure is 64
+bytes, a meta-block group contains 16 block groups for filesystems with
+a 1KB block size, and 64 block groups for filesystems with a 4KB
 blocksize. Filesystems can either be created using this new block group
 descriptor layout, or existing filesystems can be resized on-line, and
 the field s_first_meta_bg in the superblock will indicate the first
index b9b31066aef2ce828f0b3288c78ced482a23b85b..ad6d216405768ea46aa28e069de233516187274a 100644 (file)
@@ -241,7 +241,7 @@ according to the filesystem's idmapping as this would give the wrong owner if
 the caller is using an idmapping.
 
 So the kernel will map the id back up in the idmapping of the caller. Let's
-assume the caller has the slighly unconventional idmapping
+assume the caller has the somewhat unconventional idmapping
 ``u3000:k20000:r10000`` then ``k21000`` would map back up to ``u4000``.
 Consequently the user would see that this file is owned by ``u4000``.
 
@@ -320,6 +320,10 @@ and equally wrong::
  from_kuid(u20000:k0:r10000, u1000) = k21000
                              ~~~~~
 
+Since userspace ids have type ``uid_t`` and ``gid_t`` and kernel ids have type
+``kuid_t`` and ``kgid_t`` the compiler will throw an error when they are
+conflated. So the two examples above would cause a compilation failure.
+
 Idmappings when creating filesystem objects
 -------------------------------------------
 
@@ -623,42 +627,105 @@ privileged users in the initial user namespace.
 However, it is perfectly possible to combine idmapped mounts with filesystems
 mountable inside user namespaces. We will touch on this further below.
 
+Filesystem types vs idmapped mount types
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+With the introduction of idmapped mounts we need to distinguish between
+filesystem ownership and mount ownership of a VFS object such as an inode. The
+owner of a inode might be different when looked at from a filesystem
+perspective than when looked at from an idmapped mount. Such fundamental
+conceptual distinctions should almost always be clearly expressed in the code.
+So, to distinguish idmapped mount ownership from filesystem ownership separate
+types have been introduced.
+
+If a uid or gid has been generated using the filesystem or caller's idmapping
+then we will use the ``kuid_t`` and ``kgid_t`` types. However, if a uid or gid
+has been generated using a mount idmapping then we will be using the dedicated
+``vfsuid_t`` and ``vfsgid_t`` types.
+
+All VFS helpers that generate or take uids and gids as arguments use the
+``vfsuid_t`` and ``vfsgid_t`` types and we will be able to rely on the compiler
+to catch errors that originate from conflating filesystem and VFS uids and gids.
+
+The ``vfsuid_t`` and ``vfsgid_t`` types are often mapped from and to ``kuid_t``
+and ``kgid_t`` types similar how ``kuid_t`` and ``kgid_t`` types are mapped
+from and to ``uid_t`` and ``gid_t`` types::
+
+ uid_t <--> kuid_t <--> vfsuid_t
+ gid_t <--> kgid_t <--> vfsgid_t
+
+Whenever we report ownership based on a ``vfsuid_t`` or ``vfsgid_t`` type,
+e.g., during ``stat()``, or store ownership information in a shared VFS object
+based on a ``vfsuid_t`` or ``vfsgid_t`` type, e.g., during ``chown()`` we can
+use the ``vfsuid_into_kuid()`` and ``vfsgid_into_kgid()`` helpers.
+
+To illustrate why this helper currently exists, consider what happens when we
+change ownership of an inode from an idmapped mount. After we generated
+a ``vfsuid_t`` or ``vfsgid_t`` based on the mount idmapping we later commit to
+this ``vfsuid_t`` or ``vfsgid_t`` to become the new filesytem wide ownership.
+Thus, we are turning the ``vfsuid_t`` or ``vfsgid_t`` into a global ``kuid_t``
+or ``kgid_t``. And this can be done by using ``vfsuid_into_kuid()`` and
+``vfsgid_into_kgid()``.
+
+Note, whenever a shared VFS object, e.g., a cached ``struct inode`` or a cached
+``struct posix_acl``, stores ownership information a filesystem or "global"
+``kuid_t`` and ``kgid_t`` must be used. Ownership expressed via ``vfsuid_t``
+and ``vfsgid_t`` is specific to an idmapped mount.
+
+We already noted that ``vfsuid_t`` and ``vfsgid_t`` types are generated based
+on mount idmappings whereas ``kuid_t`` and ``kgid_t`` types are generated based
+on filesystem idmappings. To prevent abusing filesystem idmappings to generate
+``vfsuid_t`` or ``vfsgid_t`` types or mount idmappings to generate ``kuid_t``
+or ``kgid_t`` types filesystem idmappings and mount idmappings are different
+types as well.
+
+All helpers that map to or from ``vfsuid_t`` and ``vfsgid_t`` types require
+a mount idmapping to be passed which is of type ``struct mnt_idmap``. Passing
+a filesystem or caller idmapping will cause a compilation error.
+
+Similar to how we prefix all userspace ids in this document with ``u`` and all
+kernel ids with ``k`` we will prefix all VFS ids with ``v``. So a mount
+idmapping will be written as: ``u0:v10000:r10000``.
+
 Remapping helpers
 ~~~~~~~~~~~~~~~~~
 
 Idmapping functions were added that translate between idmappings. They make use
-of the remapping algorithm we've introduced earlier. We're going to look at
-two:
+of the remapping algorithm we've introduced earlier. We're going to look at:
 
-- ``i_uid_into_mnt()`` and ``i_gid_into_mnt()``
+- ``i_uid_into_vfsuid()`` and ``i_gid_into_vfsgid()``
 
-  The ``i_*id_into_mnt()`` functions translate filesystem's kernel ids into
-  kernel ids in the mount's idmapping::
+  The ``i_*id_into_vfs*id()`` functions translate filesystem's kernel ids into
+  VFS ids in the mount's idmapping::
 
    /* Map the filesystem's kernel id up into a userspace id in the filesystem's idmapping. */
    from_kuid(filesystem, kid) = uid
 
-   /* Map the filesystem's userspace id down ito a kernel id in the mount's idmapping. */
+   /* Map the filesystem's userspace id down ito a VFS id in the mount's idmapping. */
    make_kuid(mount, uid) = kuid
 
 - ``mapped_fsuid()`` and ``mapped_fsgid()``
 
   The ``mapped_fs*id()`` functions translate the caller's kernel ids into
   kernel ids in the filesystem's idmapping. This translation is achieved by
-  remapping the caller's kernel ids using the mount's idmapping::
+  remapping the caller's VFS ids using the mount's idmapping::
 
-   /* Map the caller's kernel id up into a userspace id in the mount's idmapping. */
+   /* Map the caller's VFS id up into a userspace id in the mount's idmapping. */
    from_kuid(mount, kid) = uid
 
    /* Map the mount's userspace id down into a kernel id in the filesystem's idmapping. */
    make_kuid(filesystem, uid) = kuid
 
+- ``vfsuid_into_kuid()`` and ``vfsgid_into_kgid()``
+
+   Whenever
+
 Note that these two functions invert each other. Consider the following
 idmappings::
 
  caller idmapping:     u0:k10000:r10000
  filesystem idmapping: u0:k20000:r10000
- mount idmapping:      u0:k10000:r10000
+ mount idmapping:      u0:v10000:r10000
 
 Assume a file owned by ``u1000`` is read from disk. The filesystem maps this id
 to ``k21000`` according to its idmapping. This is what is stored in the
@@ -669,20 +736,21 @@ would usually simply use the crossmapping algorithm and map the filesystem's
 kernel id up to a userspace id in the caller's idmapping.
 
 But when the caller is accessing the file on an idmapped mount the kernel will
-first call ``i_uid_into_mnt()`` thereby translating the filesystem's kernel id
-into a kernel id in the mount's idmapping::
+first call ``i_uid_into_vfsuid()`` thereby translating the filesystem's kernel
+id into a VFS id in the mount's idmapping::
 
- i_uid_into_mnt(k21000):
+ i_uid_into_vfsuid(k21000):
    /* Map the filesystem's kernel id up into a userspace id. */
    from_kuid(u0:k20000:r10000, k21000) = u1000
 
-   /* Map the filesystem's userspace id down ito a kernel id in the mount's idmapping. */
-   make_kuid(u0:k10000:r10000, u1000) = k11000
+   /* Map the filesystem's userspace id down into a VFS id in the mount's idmapping. */
+   make_kuid(u0:v10000:r10000, u1000) = v11000
 
 Finally, when the kernel reports the owner to the caller it will turn the
-kernel id in the mount's idmapping into a userspace id in the caller's
+VFS id in the mount's idmapping into a userspace id in the caller's
 idmapping::
 
+  k11000 = vfsuid_into_kuid(v11000)
   from_kuid(u0:k10000:r10000, k11000) = u1000
 
 We can test whether this algorithm really works by verifying what happens when
@@ -696,18 +764,19 @@ fails.
 
 But when the caller is accessing the file on an idmapped mount the kernel will
 first call ``mapped_fs*id()`` thereby translating the caller's kernel id into
-a kernel id according to the mount's idmapping::
+a VFS id according to the mount's idmapping::
 
  mapped_fsuid(k11000):
     /* Map the caller's kernel id up into a userspace id in the mount's idmapping. */
     from_kuid(u0:k10000:r10000, k11000) = u1000
 
     /* Map the mount's userspace id down into a kernel id in the filesystem's idmapping. */
-    make_kuid(u0:k20000:r10000, u1000) = k21000
+    make_kuid(u0:v20000:r10000, u1000) = v21000
 
-When finally writing to disk the kernel will then map ``k21000`` up into a
+When finally writing to disk the kernel will then map ``v21000`` up into a
 userspace id in the filesystem's idmapping::
 
+   k21000 = vfsuid_into_kuid(v21000)
    from_kuid(u0:k20000:r10000, k21000) = u1000
 
 As we can see, we end up with an invertible and therefore information
@@ -725,7 +794,7 @@ Example 2 reconsidered
  caller id:            u1000
  caller idmapping:     u0:k10000:r10000
  filesystem idmapping: u0:k20000:r10000
- mount idmapping:      u0:k10000:r10000
+ mount idmapping:      u0:v10000:r10000
 
 When the caller is using a non-initial idmapping the common case is to attach
 the same idmapping to the mount. We now perform three steps:
@@ -734,12 +803,12 @@ the same idmapping to the mount. We now perform three steps:
 
     make_kuid(u0:k10000:r10000, u1000) = k11000
 
-2. Translate the caller's kernel id into a kernel id in the filesystem's
+2. Translate the caller's VFS id into a kernel id in the filesystem's
    idmapping::
 
-    mapped_fsuid(k11000):
-      /* Map the kernel id up into a userspace id in the mount's idmapping. */
-      from_kuid(u0:k10000:r10000, k11000) = u1000
+    mapped_fsuid(v11000):
+      /* Map the VFS id up into a userspace id in the mount's idmapping. */
+      from_kuid(u0:v10000:r10000, v11000) = u1000
 
       /* Map the userspace id down into a kernel id in the filesystem's idmapping. */
       make_kuid(u0:k20000:r10000, u1000) = k21000
@@ -759,7 +828,7 @@ Example 3 reconsidered
  caller id:            u1000
  caller idmapping:     u0:k10000:r10000
  filesystem idmapping: u0:k0:r4294967295
- mount idmapping:      u0:k10000:r10000
+ mount idmapping:      u0:v10000:r10000
 
 The same translation algorithm works with the third example.
 
@@ -767,12 +836,12 @@ The same translation algorithm works with the third example.
 
     make_kuid(u0:k10000:r10000, u1000) = k11000
 
-2. Translate the caller's kernel id into a kernel id in the filesystem's
+2. Translate the caller's VFS id into a kernel id in the filesystem's
    idmapping::
 
-    mapped_fsuid(k11000):
-       /* Map the kernel id up into a userspace id in the mount's idmapping. */
-       from_kuid(u0:k10000:r10000, k11000) = u1000
+    mapped_fsuid(v11000):
+       /* Map the VFS id up into a userspace id in the mount's idmapping. */
+       from_kuid(u0:v10000:r10000, v11000) = u1000
 
        /* Map the userspace id down into a kernel id in the filesystem's idmapping. */
        make_kuid(u0:k0:r4294967295, u1000) = k1000
@@ -792,7 +861,7 @@ Example 4 reconsidered
  file id:              u1000
  caller idmapping:     u0:k10000:r10000
  filesystem idmapping: u0:k0:r4294967295
- mount idmapping:      u0:k10000:r10000
+ mount idmapping:      u0:v10000:r10000
 
 In order to report ownership to userspace the kernel now does three steps using
 the translation algorithm we introduced earlier:
@@ -802,17 +871,18 @@ the translation algorithm we introduced earlier:
 
     make_kuid(u0:k0:r4294967295, u1000) = k1000
 
-2. Translate the kernel id into a kernel id in the mount's idmapping::
+2. Translate the kernel id into a VFS id in the mount's idmapping::
 
-    i_uid_into_mnt(k1000):
+    i_uid_into_vfsuid(k1000):
       /* Map the kernel id up into a userspace id in the filesystem's idmapping. */
       from_kuid(u0:k0:r4294967295, k1000) = u1000
 
-      /* Map the userspace id down into a kernel id in the mounts's idmapping. */
-      make_kuid(u0:k10000:r10000, u1000) = k11000
+      /* Map the userspace id down into a VFS id in the mounts's idmapping. */
+      make_kuid(u0:v10000:r10000, u1000) = v11000
 
-3. Map the kernel id up into a userspace id in the caller's idmapping::
+3. Map the VFS id up into a userspace id in the caller's idmapping::
 
+    k11000 = vfsuid_into_kuid(v11000)
     from_kuid(u0:k10000:r10000, k11000) = u1000
 
 Earlier, the caller's kernel id couldn't be crossmapped in the filesystems's
@@ -828,7 +898,7 @@ Example 5 reconsidered
  file id:              u1000
  caller idmapping:     u0:k10000:r10000
  filesystem idmapping: u0:k20000:r10000
- mount idmapping:      u0:k10000:r10000
+ mount idmapping:      u0:v10000:r10000
 
 Again, in order to report ownership to userspace the kernel now does three
 steps using the translation algorithm we introduced earlier:
@@ -838,17 +908,18 @@ steps using the translation algorithm we introduced earlier:
 
     make_kuid(u0:k20000:r10000, u1000) = k21000
 
-2. Translate the kernel id into a kernel id in the mount's idmapping::
+2. Translate the kernel id into a VFS id in the mount's idmapping::
 
-    i_uid_into_mnt(k21000):
+    i_uid_into_vfsuid(k21000):
       /* Map the kernel id up into a userspace id in the filesystem's idmapping. */
       from_kuid(u0:k20000:r10000, k21000) = u1000
 
-      /* Map the userspace id down into a kernel id in the mounts's idmapping. */
-      make_kuid(u0:k10000:r10000, u1000) = k11000
+      /* Map the userspace id down into a VFS id in the mounts's idmapping. */
+      make_kuid(u0:v10000:r10000, u1000) = v11000
 
-3. Map the kernel id up into a userspace id in the caller's idmapping::
+3. Map the VFS id up into a userspace id in the caller's idmapping::
 
+    k11000 = vfsuid_into_kuid(v11000)
     from_kuid(u0:k10000:r10000, k11000) = u1000
 
 Earlier, the file's kernel id couldn't be crossmapped in the filesystems's
@@ -899,23 +970,23 @@ from above:::
  caller id:            u1125
  caller idmapping:     u0:k0:r4294967295
  filesystem idmapping: u0:k0:r4294967295
- mount idmapping:      u1000:k1125:r1
+ mount idmapping:      u1000:v1125:r1
 
 1. Map the caller's userspace ids into kernel ids in the caller's idmapping::
 
     make_kuid(u0:k0:r4294967295, u1125) = k1125
 
-2. Translate the caller's kernel id into a kernel id in the filesystem's
+2. Translate the caller's VFS id into a kernel id in the filesystem's
    idmapping::
 
-    mapped_fsuid(k1125):
-      /* Map the kernel id up into a userspace id in the mount's idmapping. */
-      from_kuid(u1000:k1125:r1, k1125) = u1000
+    mapped_fsuid(v1125):
+      /* Map the VFS id up into a userspace id in the mount's idmapping. */
+      from_kuid(u1000:v1125:r1, v1125) = u1000
 
       /* Map the userspace id down into a kernel id in the filesystem's idmapping. */
       make_kuid(u0:k0:r4294967295, u1000) = k1000
 
-2. Verify that the caller's kernel ids can be mapped to userspace ids in the
+2. Verify that the caller's filesystem ids can be mapped to userspace ids in the
    filesystem's idmapping::
 
     from_kuid(u0:k0:r4294967295, k1000) = u1000
@@ -930,24 +1001,25 @@ on their work computer:
  file id:              u1000
  caller idmapping:     u0:k0:r4294967295
  filesystem idmapping: u0:k0:r4294967295
- mount idmapping:      u1000:k1125:r1
+ mount idmapping:      u1000:v1125:r1
 
 1. Map the userspace id on disk down into a kernel id in the filesystem's
    idmapping::
 
     make_kuid(u0:k0:r4294967295, u1000) = k1000
 
-2. Translate the kernel id into a kernel id in the mount's idmapping::
+2. Translate the kernel id into a VFS id in the mount's idmapping::
 
-    i_uid_into_mnt(k1000):
+    i_uid_into_vfsuid(k1000):
       /* Map the kernel id up into a userspace id in the filesystem's idmapping. */
       from_kuid(u0:k0:r4294967295, k1000) = u1000
 
-      /* Map the userspace id down into a kernel id in the mounts's idmapping. */
-      make_kuid(u1000:k1125:r1, u1000) = k1125
+      /* Map the userspace id down into a VFS id in the mounts's idmapping. */
+      make_kuid(u1000:v1125:r1, u1000) = v1125
 
-3. Map the kernel id up into a userspace id in the caller's idmapping::
+3. Map the VFS id up into a userspace id in the caller's idmapping::
 
+    k1125 = vfsuid_into_kuid(v1125)
     from_kuid(u0:k0:r4294967295, k1125) = u1125
 
 So ultimately the caller will be reported that the file belongs to ``u1125``
index 63204d2094fdf4c75ffc5c4131304f960959bdcb..9aaf6ef75eb53b1ef25f20a0641479c48823183e 100644 (file)
@@ -79,7 +79,6 @@ context.  This is represented by the fs_context structure::
                unsigned int            sb_flags;
                unsigned int            sb_flags_mask;
                unsigned int            s_iflags;
-               unsigned int            lsm_flags;
                enum fs_context_purpose purpose:8;
                ...
        };
index 9d5fd9424e8bbdc7dfa6567908282612d4d26ec0..59db0bed35e12c37786ef21c2cd42bce701bdc83 100644 (file)
@@ -85,7 +85,7 @@ contact Bodo  Bauer  at  bb@ricochet.net.  We'll  be happy to add them to this
 document.
 
 The   latest   version    of   this   document   is    available   online   at
-http://tldp.org/LDP/Linux-Filesystem-Hierarchy/html/proc.html
+https://www.kernel.org/doc/html/latest/filesystems/proc.html
 
 If  the above  direction does  not works  for you,  you could  try the  kernel
 mailing  list  at  linux-kernel@vger.kernel.org  and/or try  to  reach  me  at
@@ -232,7 +232,7 @@ asynchronous manner and the value may not be very precise. To see a precise
 snapshot of a moment, you can see /proc/<pid>/smaps file and scan page table.
 It's slow but very precise.
 
-.. table:: Table 1-2: Contents of the status files (as of 4.19)
+.. table:: Table 1-2: Contents of the status fields (as of 4.19)
 
  ==========================  ===================================================
  Field                       Content
@@ -305,7 +305,7 @@ It's slow but very precise.
  ==========================  ===================================================
 
 
-.. table:: Table 1-3: Contents of the statm files (as of 2.6.8-rc3)
+.. table:: Table 1-3: Contents of the statm fields (as of 2.6.8-rc3)
 
  ======== ===============================      ==============================
  Field    Content
@@ -323,7 +323,7 @@ It's slow but very precise.
  ======== ===============================      ==============================
 
 
-.. table:: Table 1-4: Contents of the stat files (as of 2.6.30-rc7)
+.. table:: Table 1-4: Contents of the stat fields (as of 2.6.30-rc7)
 
   ============= ===============================================================
   Field         Content
@@ -1321,9 +1321,9 @@ many times the slaves link has failed.
 1.4 SCSI info
 -------------
 
-If you  have  a  SCSI  host adapter in your system, you'll find a subdirectory
-named after  the driver for this adapter in /proc/scsi. You'll also see a list
-of all recognized SCSI devices in /proc/scsi::
+If you have a SCSI or ATA host adapter in your system, you'll find a
+subdirectory named after the driver for this adapter in /proc/scsi.
+You'll also see a list of all recognized SCSI devices in /proc/scsi::
 
   >cat /proc/scsi/scsi
   Attached devices:
@@ -1449,16 +1449,18 @@ Various pieces   of  information about  kernel activity  are  available in the
 since the system first booted.  For a quick look, simply cat the file::
 
   > cat /proc/stat
-  cpu  2255 34 2290 22625563 6290 127 456 0 0 0
-  cpu0 1132 34 1441 11311718 3675 127 438 0 0 0
-  cpu1 1123 0 849 11313845 2614 0 18 0 0 0
-  intr 114930548 113199788 3 0 5 263 0 4 [... lots more numbers ...]
-  ctxt 1990473
-  btime 1062191376
-  processes 2915
-  procs_running 1
+  cpu  237902850 368826709 106375398 1873517540 1135548 0 14507935 0 0 0
+  cpu0 60045249 91891769 26331539 468411416 495718 0 5739640 0 0 0
+  cpu1 59746288 91759249 26609887 468860630 312281 0 4384817 0 0 0
+  cpu2 59489247 92985423 26904446 467808813 171668 0 2268998 0 0 0
+  cpu3 58622065 92190267 26529524 468436680 155879 0 2114478 0 0 0
+  intr 8688370575 8 3373 0 0 0 0 0 0 1 40791 0 0 353317 0 0 0 0 224789828 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 190974333 41958554 123983334 43 0 224593 0 0 0 <more 0's deleted>
+  ctxt 22848221062
+  btime 1605316999
+  processes 746787147
+  procs_running 2
   procs_blocked 0
-  softirq 183433 0 21755 12 39 1137 231 21459 2263
+  softirq 12121874454 100099120 3938138295 127375644 2795979 187870761 0 173808342 3072582055 52608 224184354
 
 The very first  "cpu" line aggregates the  numbers in all  of the other "cpuN"
 lines.  These numbers identify the amount of time the CPU has spent performing
@@ -1520,8 +1522,8 @@ softirq.
 Information about mounted ext4 file systems can be found in
 /proc/fs/ext4.  Each mounted filesystem will have a directory in
 /proc/fs/ext4 based on its device name (i.e., /proc/fs/ext4/hdc or
-/proc/fs/ext4/dm-0).   The files in each per-device directory are shown
-in Table 1-12, below.
+/proc/fs/ext4/sda9 or /proc/fs/ext4/dm-0).   The files in each per-device
+directory are shown in Table 1-12, below.
 
 .. table:: Table 1-12: Files in /proc/fs/ext4/<devname>
 
@@ -1601,12 +1603,12 @@ can inadvertently  disrupt  your  system,  it  is  advisable  to  read  both
 documentation and  source  before actually making adjustments. In any case, be
 very careful  when  writing  to  any  of these files. The entries in /proc may
 change slightly between the 2.1.* and the 2.2 kernel, so if there is any doubt
-review the kernel documentation in the directory /usr/src/linux/Documentation.
+review the kernel documentation in the directory linux/Documentation.
 This chapter  is  heavily  based  on the documentation included in the pre 2.2
 kernels, and became part of it in version 2.2.1 of the Linux kernel.
 
-Please see: Documentation/admin-guide/sysctl/ directory for descriptions of these
-entries.
+Please see: Documentation/admin-guide/sysctl/ directory for descriptions of
+these entries.
 
 Summary
 -------
index c53f30251a660c8b143e32bac800420fb9afe057..769be5230210769b454f14cbdf640301dd034121 100644 (file)
@@ -107,7 +107,7 @@ file /proc/filesystems.
 struct file_system_type
 -----------------------
 
-This describes the filesystem.  As of kernel 2.6.39, the following
+This describes the filesystem.  The following
 members are defined:
 
 .. code-block:: c
@@ -115,14 +115,24 @@ members are defined:
        struct file_system_type {
                const char *name;
                int fs_flags;
+               int (*init_fs_context)(struct fs_context *);
+               const struct fs_parameter_spec *parameters;
                struct dentry *(*mount) (struct file_system_type *, int,
-                                        const char *, void *);
+                       const char *, void *);
                void (*kill_sb) (struct super_block *);
                struct module *owner;
                struct file_system_type * next;
-               struct list_head fs_supers;
+               struct hlist_head fs_supers;
+
                struct lock_class_key s_lock_key;
                struct lock_class_key s_umount_key;
+               struct lock_class_key s_vfs_rename_key;
+               struct lock_class_key s_writers_key[SB_FREEZE_LEVELS];
+
+               struct lock_class_key i_lock_key;
+               struct lock_class_key i_mutex_key;
+               struct lock_class_key invalidate_lock_key;
+               struct lock_class_key i_mutex_dir_key;
        };
 
 ``name``
@@ -132,6 +142,15 @@ members are defined:
 ``fs_flags``
        various flags (i.e. FS_REQUIRES_DEV, FS_NO_DCACHE, etc.)
 
+``init_fs_context``
+       Initializes 'struct fs_context' ->ops and ->fs_private fields with
+       filesystem-specific data.
+
+``parameters``
+       Pointer to the array of filesystem parameters descriptors
+       'struct fs_parameter_spec'.
+       More info in Documentation/filesystems/mount_api.rst.
+
 ``mount``
        the method to call when a new instance of this filesystem should
        be mounted
@@ -148,7 +167,11 @@ members are defined:
 ``next``
        for internal VFS use: you should initialize this to NULL
 
-  s_lock_key, s_umount_key: lockdep-specific
+``fs_supers``
+       for internal VFS use: hlist of filesystem instances (superblocks)
+
+  s_lock_key, s_umount_key, s_vfs_rename_key, s_writers_key,
+  i_lock_key, i_mutex_key, invalidate_lock_key, i_mutex_dir_key: lockdep-specific
 
 The mount() method has the following arguments:
 
@@ -222,33 +245,42 @@ struct super_operations
 -----------------------
 
 This describes how the VFS can manipulate the superblock of your
-filesystem.  As of kernel 2.6.22, the following members are defined:
+filesystem.  The following members are defined:
 
 .. code-block:: c
 
        struct super_operations {
                struct inode *(*alloc_inode)(struct super_block *sb);
                void (*destroy_inode)(struct inode *);
+               void (*free_inode)(struct inode *);
 
                void (*dirty_inode) (struct inode *, int flags);
-               int (*write_inode) (struct inode *, int);
-               void (*drop_inode) (struct inode *);
-               void (*delete_inode) (struct inode *);
+               int (*write_inode) (struct inode *, struct writeback_control *wbc);
+               int (*drop_inode) (struct inode *);
+               void (*evict_inode) (struct inode *);
                void (*put_super) (struct super_block *);
                int (*sync_fs)(struct super_block *sb, int wait);
+               int (*freeze_super) (struct super_block *);
                int (*freeze_fs) (struct super_block *);
+               int (*thaw_super) (struct super_block *);
                int (*unfreeze_fs) (struct super_block *);
                int (*statfs) (struct dentry *, struct kstatfs *);
                int (*remount_fs) (struct super_block *, int *, char *);
-               void (*clear_inode) (struct inode *);
                void (*umount_begin) (struct super_block *);
 
                int (*show_options)(struct seq_file *, struct dentry *);
+               int (*show_devname)(struct seq_file *, struct dentry *);
+               int (*show_path)(struct seq_file *, struct dentry *);
+               int (*show_stats)(struct seq_file *, struct dentry *);
 
                ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
                ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
-               int (*nr_cached_objects)(struct super_block *);
-               void (*free_cached_objects)(struct super_block *, int);
+               struct dquot **(*get_dquots)(struct inode *);
+
+               long (*nr_cached_objects)(struct super_block *,
+                                       struct shrink_control *);
+               long (*free_cached_objects)(struct super_block *,
+                                       struct shrink_control *);
        };
 
 All methods are called without any locks being held, unless otherwise
@@ -269,6 +301,11 @@ or bottom half).
        ->alloc_inode was defined and simply undoes anything done by
        ->alloc_inode.
 
+``free_inode``
+       this method is called from RCU callback. If you use call_rcu()
+       in ->destroy_inode to free 'struct inode' memory, then it's
+       better to release memory in this method.
+
 ``dirty_inode``
        this method is called by the VFS when an inode is marked dirty.
        This is specifically for the inode itself being marked dirty,
@@ -296,8 +333,12 @@ or bottom half).
        practice of using "force_delete" in the put_inode() case, but
        does not have the races that the "force_delete()" approach had.
 
-``delete_inode``
-       called when the VFS wants to delete an inode
+``evict_inode``
+       called when the VFS wants to evict an inode. Caller does
+       *not* evict the pagecache or inode-associated metadata buffers;
+       the method has to use truncate_inode_pages_final() to get rid
+       of those. Caller makes sure async writeback cannot be running for
+       the inode while (or after) ->evict_inode() is called. Optional.
 
 ``put_super``
        called when the VFS wishes to free the superblock
@@ -308,14 +349,25 @@ or bottom half).
        superblock.  The second parameter indicates whether the method
        should wait until the write out has been completed.  Optional.
 
+``freeze_super``
+       Called instead of ->freeze_fs callback if provided.
+       Main difference is that ->freeze_super is called without taking
+       down_write(&sb->s_umount). If filesystem implements it and wants
+       ->freeze_fs to be called too, then it has to call ->freeze_fs
+       explicitly from this callback. Optional.
+
 ``freeze_fs``
        called when VFS is locking a filesystem and forcing it into a
        consistent state.  This method is currently used by the Logical
-       Volume Manager (LVM).
+       Volume Manager (LVM) and ioctl(FIFREEZE). Optional.
+
+``thaw_super``
+       called when VFS is unlocking a filesystem and making it writable
+       again after ->freeze_super. Optional.
 
 ``unfreeze_fs``
        called when VFS is unlocking a filesystem and making it writable
-       again.
+       again after ->freeze_fs. Optional.
 
 ``statfs``
        called when the VFS needs to get filesystem statistics.
@@ -324,22 +376,37 @@ or bottom half).
        called when the filesystem is remounted.  This is called with
        the kernel lock held
 
-``clear_inode``
-       called then the VFS clears the inode.  Optional
-
 ``umount_begin``
        called when the VFS is unmounting a filesystem.
 
 ``show_options``
-       called by the VFS to show mount options for /proc/<pid>/mounts.
+       called by the VFS to show mount options for /proc/<pid>/mounts
+       and /proc/<pid>/mountinfo.
        (see "Mount Options" section)
 
+``show_devname``
+       Optional. Called by the VFS to show device name for
+       /proc/<pid>/{mounts,mountinfo,mountstats}. If not provided then
+       '(struct mount).mnt_devname' will be used.
+
+``show_path``
+       Optional. Called by the VFS (for /proc/<pid>/mountinfo) to show
+       the mount root dentry path relative to the filesystem root.
+
+``show_stats``
+       Optional. Called by the VFS (for /proc/<pid>/mountstats) to show
+       filesystem-specific mount statistics.
+
 ``quota_read``
        called by the VFS to read from filesystem quota file.
 
 ``quota_write``
        called by the VFS to write to filesystem quota file.
 
+``get_dquots``
+       called by quota to get 'struct dquot' array for a particular inode.
+       Optional.
+
 ``nr_cached_objects``
        called by the sb cache shrinking function for the filesystem to
        return the number of freeable cached objects it contains.
@@ -1222,7 +1289,7 @@ defined:
        return
        -ECHILD and it will be called again in ref-walk mode.
 
-``_weak_revalidate``
+``d_weak_revalidate``
        called when the VFS needs to revalidate a "jumped" dentry.  This
        is called when a path-walk ends at dentry that was not acquired
        by doing a lookup in the parent directory.  This includes "/",
index b9dc0c603f3672789a462945fad841d95d5b8307..56d9913a3370c47b2c10ebe0f8df58c6c6b4c674 100644 (file)
@@ -19,7 +19,7 @@ possible we decided to do following:
     platform devices.
 
   - Devices behind real busses where there is a connector resource
-    are represented as struct spi_device or struct i2c_device. Note
+    are represented as struct spi_device or struct i2c_client. Note
     that standard UARTs are not busses so there is no struct uart_device,
     although some of them may be represented by struct serdev_device.
 
diff --git a/Documentation/ia64/aliasing.rst b/Documentation/ia64/aliasing.rst
deleted file mode 100644 (file)
index 36a1e1d..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-==================================
-Memory Attribute Aliasing on IA-64
-==================================
-
-Bjorn Helgaas <bjorn.helgaas@hp.com>
-
-May 4, 2006
-
-
-Memory Attributes
-=================
-
-    Itanium supports several attributes for virtual memory references.
-    The attribute is part of the virtual translation, i.e., it is
-    contained in the TLB entry.  The ones of most interest to the Linux
-    kernel are:
-
-       ==              ======================
-        WB             Write-back (cacheable)
-       UC              Uncacheable
-       WC              Write-coalescing
-       ==              ======================
-
-    System memory typically uses the WB attribute.  The UC attribute is
-    used for memory-mapped I/O devices.  The WC attribute is uncacheable
-    like UC is, but writes may be delayed and combined to increase
-    performance for things like frame buffers.
-
-    The Itanium architecture requires that we avoid accessing the same
-    page with both a cacheable mapping and an uncacheable mapping[1].
-
-    The design of the chipset determines which attributes are supported
-    on which regions of the address space.  For example, some chipsets
-    support either WB or UC access to main memory, while others support
-    only WB access.
-
-Memory Map
-==========
-
-    Platform firmware describes the physical memory map and the
-    supported attributes for each region.  At boot-time, the kernel uses
-    the EFI GetMemoryMap() interface.  ACPI can also describe memory
-    devices and the attributes they support, but Linux/ia64 currently
-    doesn't use this information.
-
-    The kernel uses the efi_memmap table returned from GetMemoryMap() to
-    learn the attributes supported by each region of physical address
-    space.  Unfortunately, this table does not completely describe the
-    address space because some machines omit some or all of the MMIO
-    regions from the map.
-
-    The kernel maintains another table, kern_memmap, which describes the
-    memory Linux is actually using and the attribute for each region.
-    This contains only system memory; it does not contain MMIO space.
-
-    The kern_memmap table typically contains only a subset of the system
-    memory described by the efi_memmap.  Linux/ia64 can't use all memory
-    in the system because of constraints imposed by the identity mapping
-    scheme.
-
-    The efi_memmap table is preserved unmodified because the original
-    boot-time information is required for kexec.
-
-Kernel Identity Mappings
-========================
-
-    Linux/ia64 identity mappings are done with large pages, currently
-    either 16MB or 64MB, referred to as "granules."  Cacheable mappings
-    are speculative[2], so the processor can read any location in the
-    page at any time, independent of the programmer's intentions.  This
-    means that to avoid attribute aliasing, Linux can create a cacheable
-    identity mapping only when the entire granule supports cacheable
-    access.
-
-    Therefore, kern_memmap contains only full granule-sized regions that
-    can referenced safely by an identity mapping.
-
-    Uncacheable mappings are not speculative, so the processor will
-    generate UC accesses only to locations explicitly referenced by
-    software.  This allows UC identity mappings to cover granules that
-    are only partially populated, or populated with a combination of UC
-    and WB regions.
-
-User Mappings
-=============
-
-    User mappings are typically done with 16K or 64K pages.  The smaller
-    page size allows more flexibility because only 16K or 64K has to be
-    homogeneous with respect to memory attributes.
-
-Potential Attribute Aliasing Cases
-==================================
-
-    There are several ways the kernel creates new mappings:
-
-mmap of /dev/mem
-----------------
-
-       This uses remap_pfn_range(), which creates user mappings.  These
-       mappings may be either WB or UC.  If the region being mapped
-       happens to be in kern_memmap, meaning that it may also be mapped
-       by a kernel identity mapping, the user mapping must use the same
-       attribute as the kernel mapping.
-
-       If the region is not in kern_memmap, the user mapping should use
-       an attribute reported as being supported in the EFI memory map.
-
-       Since the EFI memory map does not describe MMIO on some
-       machines, this should use an uncacheable mapping as a fallback.
-
-mmap of /sys/class/pci_bus/.../legacy_mem
------------------------------------------
-
-       This is very similar to mmap of /dev/mem, except that legacy_mem
-       only allows mmap of the one megabyte "legacy MMIO" area for a
-       specific PCI bus.  Typically this is the first megabyte of
-       physical address space, but it may be different on machines with
-       several VGA devices.
-
-       "X" uses this to access VGA frame buffers.  Using legacy_mem
-       rather than /dev/mem allows multiple instances of X to talk to
-       different VGA cards.
-
-       The /dev/mem mmap constraints apply.
-
-mmap of /proc/bus/pci/.../??.?
-------------------------------
-
-       This is an MMIO mmap of PCI functions, which additionally may or
-       may not be requested as using the WC attribute.
-
-       If WC is requested, and the region in kern_memmap is either WC
-       or UC, and the EFI memory map designates the region as WC, then
-       the WC mapping is allowed.
-
-       Otherwise, the user mapping must use the same attribute as the
-       kernel mapping.
-
-read/write of /dev/mem
-----------------------
-
-       This uses copy_from_user(), which implicitly uses a kernel
-       identity mapping.  This is obviously safe for things in
-       kern_memmap.
-
-       There may be corner cases of things that are not in kern_memmap,
-       but could be accessed this way.  For example, registers in MMIO
-       space are not in kern_memmap, but could be accessed with a UC
-       mapping.  This would not cause attribute aliasing.  But
-       registers typically can be accessed only with four-byte or
-       eight-byte accesses, and the copy_from_user() path doesn't allow
-       any control over the access size, so this would be dangerous.
-
-ioremap()
----------
-
-       This returns a mapping for use inside the kernel.
-
-       If the region is in kern_memmap, we should use the attribute
-       specified there.
-
-       If the EFI memory map reports that the entire granule supports
-       WB, we should use that (granules that are partially reserved
-       or occupied by firmware do not appear in kern_memmap).
-
-       If the granule contains non-WB memory, but we can cover the
-       region safely with kernel page table mappings, we can use
-       ioremap_page_range() as most other architectures do.
-
-       Failing all of the above, we have to fall back to a UC mapping.
-
-Past Problem Cases
-==================
-
-mmap of various MMIO regions from /dev/mem by "X" on Intel platforms
---------------------------------------------------------------------
-
-      The EFI memory map may not report these MMIO regions.
-
-      These must be allowed so that X will work.  This means that
-      when the EFI memory map is incomplete, every /dev/mem mmap must
-      succeed.  It may create either WB or UC user mappings, depending
-      on whether the region is in kern_memmap or the EFI memory map.
-
-mmap of 0x0-0x9FFFF /dev/mem by "hwinfo" on HP sx1000 with VGA enabled
-----------------------------------------------------------------------
-
-      The EFI memory map reports the following attributes:
-
-        =============== ======= ==================
-        0x00000-0x9FFFF WB only
-        0xA0000-0xBFFFF UC only (VGA frame buffer)
-        0xC0000-0xFFFFF WB only
-        =============== ======= ==================
-
-      This mmap is done with user pages, not kernel identity mappings,
-      so it is safe to use WB mappings.
-
-      The kernel VGA driver may ioremap the VGA frame buffer at 0xA0000,
-      which uses a granule-sized UC mapping.  This granule will cover some
-      WB-only memory, but since UC is non-speculative, the processor will
-      never generate an uncacheable reference to the WB-only areas unless
-      the driver explicitly touches them.
-
-mmap of 0x0-0xFFFFF legacy_mem by "X"
--------------------------------------
-
-      If the EFI memory map reports that the entire range supports the
-      same attributes, we can allow the mmap (and we will prefer WB if
-      supported, as is the case with HP sx[12]000 machines with VGA
-      disabled).
-
-      If EFI reports the range as partly WB and partly UC (as on sx[12]000
-      machines with VGA enabled), we must fail the mmap because there's no
-      safe attribute to use.
-
-      If EFI reports some of the range but not all (as on Intel firmware
-      that doesn't report the VGA frame buffer at all), we should fail the
-      mmap and force the user to map just the specific region of interest.
-
-mmap of 0xA0000-0xBFFFF legacy_mem by "X" on HP sx1000 with VGA disabled
-------------------------------------------------------------------------
-
-      The EFI memory map reports the following attributes::
-
-        0x00000-0xFFFFF WB only (no VGA MMIO hole)
-
-      This is a special case of the previous case, and the mmap should
-      fail for the same reason as above.
-
-read of /sys/devices/.../rom
-----------------------------
-
-      For VGA devices, this may cause an ioremap() of 0xC0000.  This
-      used to be done with a UC mapping, because the VGA frame buffer
-      at 0xA0000 prevents use of a WB granule.  The UC mapping causes
-      an MCA on HP sx[12]000 chipsets.
-
-      We should use WB page table mappings to avoid covering the VGA
-      frame buffer.
-
-Notes
-=====
-
-    [1] SDM rev 2.2, vol 2, sec 4.4.1.
-    [2] SDM rev 2.2, vol 2, sec 4.4.6.
diff --git a/Documentation/ia64/efirtc.rst b/Documentation/ia64/efirtc.rst
deleted file mode 100644 (file)
index fd83284..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-==========================
-EFI Real Time Clock driver
-==========================
-
-S. Eranian <eranian@hpl.hp.com>
-
-March 2000
-
-1. Introduction
-===============
-
-This document describes the efirtc.c driver has provided for
-the IA-64 platform.
-
-The purpose of this driver is to supply an API for kernel and user applications
-to get access to the Time Service offered by EFI version 0.92.
-
-EFI provides 4 calls one can make once the OS is booted: GetTime(),
-SetTime(), GetWakeupTime(), SetWakeupTime() which are all supported by this
-driver. We describe those calls as well the design of the driver in the
-following sections.
-
-2. Design Decisions
-===================
-
-The original ideas was to provide a very simple driver to get access to,
-at first, the time of day service. This is required in order to access, in a
-portable way, the CMOS clock. A program like /sbin/hwclock uses such a clock
-to initialize the system view of the time during boot.
-
-Because we wanted to minimize the impact on existing user-level apps using
-the CMOS clock, we decided to expose an API that was very similar to the one
-used today with the legacy RTC driver (driver/char/rtc.c). However, because
-EFI provides a simpler services, not all ioctl() are available. Also
-new ioctl()s have been introduced for things that EFI provides but not the
-legacy.
-
-EFI uses a slightly different way of representing the time, noticeably
-the reference date is different. Year is the using the full 4-digit format.
-The Epoch is January 1st 1998. For backward compatibility reasons we don't
-expose this new way of representing time. Instead we use something very
-similar to the struct tm, i.e. struct rtc_time, as used by hwclock.
-One of the reasons for doing it this way is to allow for EFI to still evolve
-without necessarily impacting any of the user applications. The decoupling
-enables flexibility and permits writing wrapper code is ncase things change.
-
-The driver exposes two interfaces, one via the device file and a set of
-ioctl()s. The other is read-only via the /proc filesystem.
-
-As of today we don't offer a /proc/sys interface.
-
-To allow for a uniform interface between the legacy RTC and EFI time service,
-we have created the include/linux/rtc.h header file to contain only the
-"public" API of the two drivers.  The specifics of the legacy RTC are still
-in include/linux/mc146818rtc.h.
-
-
-3. Time of day service
-======================
-
-The part of the driver gives access to the time of day service of EFI.
-Two ioctl()s, compatible with the legacy RTC calls:
-
-       Read the CMOS clock::
-
-               ioctl(d, RTC_RD_TIME, &rtc);
-
-       Write the CMOS clock::
-
-               ioctl(d, RTC_SET_TIME, &rtc);
-
-The rtc is a pointer to a data structure defined in rtc.h which is close
-to a struct tm::
-
-  struct rtc_time {
-          int tm_sec;
-          int tm_min;
-          int tm_hour;
-          int tm_mday;
-          int tm_mon;
-          int tm_year;
-          int tm_wday;
-          int tm_yday;
-          int tm_isdst;
-  };
-
-The driver takes care of converting back an forth between the EFI time and
-this format.
-
-Those two ioctl()s can be exercised with the hwclock command:
-
-For reading::
-
-       # /sbin/hwclock --show
-       Mon Mar  6 15:32:32 2000  -0.910248 seconds
-
-For setting::
-
-       # /sbin/hwclock --systohc
-
-Root privileges are required to be able to set the time of day.
-
-4. Wakeup Alarm service
-=======================
-
-EFI provides an API by which one can program when a machine should wakeup,
-i.e. reboot. This is very different from the alarm provided by the legacy
-RTC which is some kind of interval timer alarm. For this reason we don't use
-the same ioctl()s to get access to the service. Instead we have
-introduced 2 news ioctl()s to the interface of an RTC.
-
-We have added 2 new ioctl()s that are specific to the EFI driver:
-
-       Read the current state of the alarm::
-
-               ioctl(d, RTC_WKALM_RD, &wkt)
-
-       Set the alarm or change its status::
-
-               ioctl(d, RTC_WKALM_SET, &wkt)
-
-The wkt structure encapsulates a struct rtc_time + 2 extra fields to get
-status information::
-
-  struct rtc_wkalrm {
-
-          unsigned char enabled; /* =1 if alarm is enabled */
-          unsigned char pending; /* =1 if alarm is pending  */
-
-          struct rtc_time time;
-  }
-
-As of today, none of the existing user-level apps supports this feature.
-However writing such a program should be hard by simply using those two
-ioctl().
-
-Root privileges are required to be able to set the alarm.
-
-5. References
-=============
-
-Checkout the following Web site for more information on EFI:
-
-http://developer.intel.com/technology/efi/
diff --git a/Documentation/ia64/err_inject.rst b/Documentation/ia64/err_inject.rst
deleted file mode 100644 (file)
index 900f71e..0000000
+++ /dev/null
@@ -1,1067 +0,0 @@
-========================================
-IPF Machine Check (MC) error inject tool
-========================================
-
-IPF Machine Check (MC) error inject tool is used to inject MC
-errors from Linux. The tool is a test bed for IPF MC work flow including
-hardware correctable error handling, OS recoverable error handling, MC
-event logging, etc.
-
-The tool includes two parts: a kernel driver and a user application
-sample. The driver provides interface to PAL to inject error
-and query error injection capabilities. The driver code is in
-arch/ia64/kernel/err_inject.c. The application sample (shown below)
-provides a combination of various errors and calls the driver's interface
-(sysfs interface) to inject errors or query error injection capabilities.
-
-The tool can be used to test Intel IPF machine MC handling capabilities.
-It's especially useful for people who can not access hardware MC injection
-tool to inject error. It's also very useful to integrate with other
-software test suits to do stressful testing on IPF.
-
-Below is a sample application as part of the whole tool. The sample
-can be used as a working test tool. Or it can be expanded to include
-more features. It also can be a integrated into a library or other user
-application to have more thorough test.
-
-The sample application takes err.conf as error configuration input. GCC
-compiles the code. After you install err_inject driver, you can run
-this sample application to inject errors.
-
-Errata: Itanium 2 Processors Specification Update lists some errata against
-the pal_mc_error_inject PAL procedure. The following err.conf has been tested
-on latest Montecito PAL.
-
-err.conf::
-
-  #This is configuration file for err_inject_tool.
-  #The format of the each line is:
-  #cpu, loop, interval, err_type_info, err_struct_info, err_data_buffer
-  #where
-  #    cpu: logical cpu number the error will be inject in.
-  #    loop: times the error will be injected.
-  #    interval: In second. every so often one error is injected.
-  #    err_type_info, err_struct_info: PAL parameters.
-  #
-  #Note: All values are hex w/o or w/ 0x prefix.
-
-
-  #On cpu2, inject only total 0x10 errors, interval 5 seconds
-  #corrected, data cache, hier-2, physical addr(assigned by tool code).
-  #working on Montecito latest PAL.
-  2, 10, 5, 4101, 95
-
-  #On cpu4, inject and consume total 0x10 errors, interval 5 seconds
-  #corrected, data cache, hier-2, physical addr(assigned by tool code).
-  #working on Montecito latest PAL.
-  4, 10, 5, 4109, 95
-
-  #On cpu15, inject and consume total 0x10 errors, interval 5 seconds
-  #recoverable, DTR0, hier-2.
-  #working on Montecito latest PAL.
-  0xf, 0x10, 5, 4249, 15
-
-The sample application source code:
-
-err_injection_tool.c::
-
-  /*
-   * This program is free software; you can redistribute it and/or modify
-   * it under the terms of the GNU General Public License as published by
-   * the Free Software Foundation; either version 2 of the License, or
-   * (at your option) any later version.
-   *
-   * This program is distributed in the hope that it will be useful, but
-   * WITHOUT ANY WARRANTY; without even the implied warranty of
-   * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
-   * NON INFRINGEMENT.  See the GNU General Public License for more
-   * details.
-   *
-   * You should have received a copy of the GNU General Public License
-   * along with this program; if not, write to the Free Software
-   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-   *
-   * Copyright (C) 2006 Intel Co
-   *   Fenghua Yu <fenghua.yu@intel.com>
-   *
-   */
-  #include <sys/types.h>
-  #include <sys/stat.h>
-  #include <fcntl.h>
-  #include <stdio.h>
-  #include <sched.h>
-  #include <unistd.h>
-  #include <stdlib.h>
-  #include <stdarg.h>
-  #include <string.h>
-  #include <errno.h>
-  #include <time.h>
-  #include <sys/ipc.h>
-  #include <sys/sem.h>
-  #include <sys/wait.h>
-  #include <sys/mman.h>
-  #include <sys/shm.h>
-
-  #define MAX_FN_SIZE          256
-  #define MAX_BUF_SIZE                 256
-  #define DATA_BUF_SIZE                256
-  #define NR_CPUS              512
-  #define MAX_TASK_NUM         2048
-  #define MIN_INTERVAL         5       // seconds
-  #define      ERR_DATA_BUFFER_SIZE    3       // Three 8-byte.
-  #define PARA_FIELD_NUM               5
-  #define MASK_SIZE            (NR_CPUS/64)
-  #define PATH_FORMAT "/sys/devices/system/cpu/cpu%d/err_inject/"
-
-  int sched_setaffinity(pid_t pid, unsigned int len, unsigned long *mask);
-
-  int verbose;
-  #define vbprintf if (verbose) printf
-
-  int log_info(int cpu, const char *fmt, ...)
-  {
-       FILE *log;
-       char fn[MAX_FN_SIZE];
-       char buf[MAX_BUF_SIZE];
-       va_list args;
-
-       sprintf(fn, "%d.log", cpu);
-       log=fopen(fn, "a+");
-       if (log==NULL) {
-               perror("Error open:");
-               return -1;
-       }
-
-       va_start(args, fmt);
-       vprintf(fmt, args);
-       memset(buf, 0, MAX_BUF_SIZE);
-       vsprintf(buf, fmt, args);
-       va_end(args);
-
-       fwrite(buf, sizeof(buf), 1, log);
-       fclose(log);
-
-       return 0;
-  }
-
-  typedef unsigned long u64;
-  typedef unsigned int  u32;
-
-  typedef union err_type_info_u {
-       struct {
-               u64     mode            : 3,    /* 0-2 */
-                       err_inj         : 3,    /* 3-5 */
-                       err_sev         : 2,    /* 6-7 */
-                       err_struct      : 5,    /* 8-12 */
-                       struct_hier     : 3,    /* 13-15 */
-                       reserved        : 48;   /* 16-63 */
-       } err_type_info_u;
-       u64     err_type_info;
-  } err_type_info_t;
-
-  typedef union err_struct_info_u {
-       struct {
-               u64     siv             : 1,    /* 0     */
-                       c_t             : 2,    /* 1-2   */
-                       cl_p            : 3,    /* 3-5   */
-                       cl_id           : 3,    /* 6-8   */
-                       cl_dp           : 1,    /* 9     */
-                       reserved1       : 22,   /* 10-31 */
-                       tiv             : 1,    /* 32    */
-                       trigger         : 4,    /* 33-36 */
-                       trigger_pl      : 3,    /* 37-39 */
-                       reserved2       : 24;   /* 40-63 */
-       } err_struct_info_cache;
-       struct {
-               u64     siv             : 1,    /* 0     */
-                       tt              : 2,    /* 1-2   */
-                       tc_tr           : 2,    /* 3-4   */
-                       tr_slot         : 8,    /* 5-12  */
-                       reserved1       : 19,   /* 13-31 */
-                       tiv             : 1,    /* 32    */
-                       trigger         : 4,    /* 33-36 */
-                       trigger_pl      : 3,    /* 37-39 */
-                       reserved2       : 24;   /* 40-63 */
-       } err_struct_info_tlb;
-       struct {
-               u64     siv             : 1,    /* 0     */
-                       regfile_id      : 4,    /* 1-4   */
-                       reg_num         : 7,    /* 5-11  */
-                       reserved1       : 20,   /* 12-31 */
-                       tiv             : 1,    /* 32    */
-                       trigger         : 4,    /* 33-36 */
-                       trigger_pl      : 3,    /* 37-39 */
-                       reserved2       : 24;   /* 40-63 */
-       } err_struct_info_register;
-       struct {
-               u64     reserved;
-       } err_struct_info_bus_processor_interconnect;
-       u64     err_struct_info;
-  } err_struct_info_t;
-
-  typedef union err_data_buffer_u {
-       struct {
-               u64     trigger_addr;           /* 0-63         */
-               u64     inj_addr;               /* 64-127       */
-               u64     way             : 5,    /* 128-132      */
-                       index           : 20,   /* 133-152      */
-                                       : 39;   /* 153-191      */
-       } err_data_buffer_cache;
-       struct {
-               u64     trigger_addr;           /* 0-63         */
-               u64     inj_addr;               /* 64-127       */
-               u64     way             : 5,    /* 128-132      */
-                       index           : 20,   /* 133-152      */
-                       reserved        : 39;   /* 153-191      */
-       } err_data_buffer_tlb;
-       struct {
-               u64     trigger_addr;           /* 0-63         */
-       } err_data_buffer_register;
-       struct {
-               u64     reserved;               /* 0-63         */
-       } err_data_buffer_bus_processor_interconnect;
-       u64 err_data_buffer[ERR_DATA_BUFFER_SIZE];
-  } err_data_buffer_t;
-
-  typedef union capabilities_u {
-       struct {
-               u64     i               : 1,
-                       d               : 1,
-                       rv              : 1,
-                       tag             : 1,
-                       data            : 1,
-                       mesi            : 1,
-                       dp              : 1,
-                       reserved1       : 3,
-                       pa              : 1,
-                       va              : 1,
-                       wi              : 1,
-                       reserved2       : 20,
-                       trigger         : 1,
-                       trigger_pl      : 1,
-                       reserved3       : 30;
-       } capabilities_cache;
-       struct {
-               u64     d               : 1,
-                       i               : 1,
-                       rv              : 1,
-                       tc              : 1,
-                       tr              : 1,
-                       reserved1       : 27,
-                       trigger         : 1,
-                       trigger_pl      : 1,
-                       reserved2       : 30;
-       } capabilities_tlb;
-       struct {
-               u64     gr_b0           : 1,
-                       gr_b1           : 1,
-                       fr              : 1,
-                       br              : 1,
-                       pr              : 1,
-                       ar              : 1,
-                       cr              : 1,
-                       rr              : 1,
-                       pkr             : 1,
-                       dbr             : 1,
-                       ibr             : 1,
-                       pmc             : 1,
-                       pmd             : 1,
-                       reserved1       : 3,
-                       regnum          : 1,
-                       reserved2       : 15,
-                       trigger         : 1,
-                       trigger_pl      : 1,
-                       reserved3       : 30;
-       } capabilities_register;
-       struct {
-               u64     reserved;
-       } capabilities_bus_processor_interconnect;
-  } capabilities_t;
-
-  typedef struct resources_s {
-       u64     ibr0            : 1,
-               ibr2            : 1,
-               ibr4            : 1,
-               ibr6            : 1,
-               dbr0            : 1,
-               dbr2            : 1,
-               dbr4            : 1,
-               dbr6            : 1,
-               reserved        : 48;
-  } resources_t;
-
-
-  long get_page_size(void)
-  {
-       long page_size=sysconf(_SC_PAGESIZE);
-       return page_size;
-  }
-
-  #define PAGE_SIZE (get_page_size()==-1?0x4000:get_page_size())
-  #define SHM_SIZE (2*PAGE_SIZE*NR_CPUS)
-  #define SHM_VA 0x2000000100000000
-
-  int shmid;
-  void *shmaddr;
-
-  int create_shm(void)
-  {
-       key_t key;
-       char fn[MAX_FN_SIZE];
-
-       /* cpu0 is always existing */
-       sprintf(fn, PATH_FORMAT, 0);
-       if ((key = ftok(fn, 's')) == -1) {
-               perror("ftok");
-               return -1;
-       }
-
-       shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT);
-       if (shmid == -1) {
-               if (errno==EEXIST) {
-                       shmid = shmget(key, SHM_SIZE, 0);
-                       if (shmid == -1) {
-                               perror("shmget");
-                               return -1;
-                       }
-               }
-               else {
-                       perror("shmget");
-                       return -1;
-               }
-       }
-       vbprintf("shmid=%d", shmid);
-
-       /* connect to the segment: */
-       shmaddr = shmat(shmid, (void *)SHM_VA, 0);
-       if (shmaddr == (void*)-1) {
-               perror("shmat");
-               return -1;
-       }
-
-       memset(shmaddr, 0, SHM_SIZE);
-       mlock(shmaddr, SHM_SIZE);
-
-       return 0;
-  }
-
-  int free_shm()
-  {
-       munlock(shmaddr, SHM_SIZE);
-          shmdt(shmaddr);
-       semctl(shmid, 0, IPC_RMID);
-
-       return 0;
-  }
-
-  #ifdef _SEM_SEMUN_UNDEFINED
-  union semun
-  {
-       int val;
-       struct semid_ds *buf;
-       unsigned short int *array;
-       struct seminfo *__buf;
-  };
-  #endif
-
-  u32 mode=1; /* 1: physical mode; 2: virtual mode. */
-  int one_lock=1;
-  key_t key[NR_CPUS];
-  int semid[NR_CPUS];
-
-  int create_sem(int cpu)
-  {
-       union semun arg;
-       char fn[MAX_FN_SIZE];
-       int sid;
-
-       sprintf(fn, PATH_FORMAT, cpu);
-       sprintf(fn, "%s/%s", fn, "err_type_info");
-       if ((key[cpu] = ftok(fn, 'e')) == -1) {
-               perror("ftok");
-               return -1;
-       }
-
-       if (semid[cpu]!=0)
-               return 0;
-
-       /* clear old semaphore */
-       if ((sid = semget(key[cpu], 1, 0)) != -1)
-               semctl(sid, 0, IPC_RMID);
-
-       /* get one semaphore */
-       if ((semid[cpu] = semget(key[cpu], 1, IPC_CREAT | IPC_EXCL)) == -1) {
-               perror("semget");
-               printf("Please remove semaphore with key=0x%lx, then run the tool.\n",
-                       (u64)key[cpu]);
-               return -1;
-       }
-
-       vbprintf("semid[%d]=0x%lx, key[%d]=%lx\n",cpu,(u64)semid[cpu],cpu,
-               (u64)key[cpu]);
-       /* initialize the semaphore to 1: */
-       arg.val = 1;
-       if (semctl(semid[cpu], 0, SETVAL, arg) == -1) {
-               perror("semctl");
-               return -1;
-       }
-
-       return 0;
-  }
-
-  static int lock(int cpu)
-  {
-       struct sembuf lock;
-
-       lock.sem_num = cpu;
-       lock.sem_op = 1;
-       semop(semid[cpu], &lock, 1);
-
-          return 0;
-  }
-
-  static int unlock(int cpu)
-  {
-       struct sembuf unlock;
-
-       unlock.sem_num = cpu;
-       unlock.sem_op = -1;
-       semop(semid[cpu], &unlock, 1);
-
-          return 0;
-  }
-
-  void free_sem(int cpu)
-  {
-       semctl(semid[cpu], 0, IPC_RMID);
-  }
-
-  int wr_multi(char *fn, unsigned long *data, int size)
-  {
-       int fd;
-       char buf[MAX_BUF_SIZE];
-       int ret;
-
-       if (size==1)
-               sprintf(buf, "%lx", *data);
-       else if (size==3)
-               sprintf(buf, "%lx,%lx,%lx", data[0], data[1], data[2]);
-       else {
-               fprintf(stderr,"write to file with wrong size!\n");
-               return -1;
-       }
-
-       fd=open(fn, O_RDWR);
-       if (!fd) {
-               perror("Error:");
-               return -1;
-       }
-       ret=write(fd, buf, sizeof(buf));
-       close(fd);
-       return ret;
-  }
-
-  int wr(char *fn, unsigned long data)
-  {
-       return wr_multi(fn, &data, 1);
-  }
-
-  int rd(char *fn, unsigned long *data)
-  {
-       int fd;
-       char buf[MAX_BUF_SIZE];
-
-       fd=open(fn, O_RDONLY);
-       if (fd<0) {
-               perror("Error:");
-               return -1;
-       }
-       read(fd, buf, MAX_BUF_SIZE);
-       *data=strtoul(buf, NULL, 16);
-       close(fd);
-       return 0;
-  }
-
-  int rd_status(char *path, int *status)
-  {
-       char fn[MAX_FN_SIZE];
-       sprintf(fn, "%s/status", path);
-       if (rd(fn, (u64*)status)<0) {
-               perror("status reading error.\n");
-               return -1;
-       }
-
-       return 0;
-  }
-
-  int rd_capabilities(char *path, u64 *capabilities)
-  {
-       char fn[MAX_FN_SIZE];
-       sprintf(fn, "%s/capabilities", path);
-       if (rd(fn, capabilities)<0) {
-               perror("capabilities reading error.\n");
-               return -1;
-       }
-
-       return 0;
-  }
-
-  int rd_all(char *path)
-  {
-       unsigned long err_type_info, err_struct_info, err_data_buffer;
-       int status;
-       unsigned long capabilities, resources;
-       char fn[MAX_FN_SIZE];
-
-       sprintf(fn, "%s/err_type_info", path);
-       if (rd(fn, &err_type_info)<0) {
-               perror("err_type_info reading error.\n");
-               return -1;
-       }
-       printf("err_type_info=%lx\n", err_type_info);
-
-       sprintf(fn, "%s/err_struct_info", path);
-       if (rd(fn, &err_struct_info)<0) {
-               perror("err_struct_info reading error.\n");
-               return -1;
-       }
-       printf("err_struct_info=%lx\n", err_struct_info);
-
-       sprintf(fn, "%s/err_data_buffer", path);
-       if (rd(fn, &err_data_buffer)<0) {
-               perror("err_data_buffer reading error.\n");
-               return -1;
-       }
-       printf("err_data_buffer=%lx\n", err_data_buffer);
-
-       sprintf(fn, "%s/status", path);
-       if (rd("status", (u64*)&status)<0) {
-               perror("status reading error.\n");
-               return -1;
-       }
-       printf("status=%d\n", status);
-
-       sprintf(fn, "%s/capabilities", path);
-       if (rd(fn,&capabilities)<0) {
-               perror("capabilities reading error.\n");
-               return -1;
-       }
-       printf("capabilities=%lx\n", capabilities);
-
-       sprintf(fn, "%s/resources", path);
-       if (rd(fn, &resources)<0) {
-               perror("resources reading error.\n");
-               return -1;
-       }
-       printf("resources=%lx\n", resources);
-
-       return 0;
-  }
-
-  int query_capabilities(char *path, err_type_info_t err_type_info,
-                       u64 *capabilities)
-  {
-       char fn[MAX_FN_SIZE];
-       err_struct_info_t err_struct_info;
-       err_data_buffer_t err_data_buffer;
-
-       err_struct_info.err_struct_info=0;
-       memset(err_data_buffer.err_data_buffer, -1, ERR_DATA_BUFFER_SIZE*8);
-
-       sprintf(fn, "%s/err_type_info", path);
-       wr(fn, err_type_info.err_type_info);
-       sprintf(fn, "%s/err_struct_info", path);
-       wr(fn, 0x0);
-       sprintf(fn, "%s/err_data_buffer", path);
-       wr_multi(fn, err_data_buffer.err_data_buffer, ERR_DATA_BUFFER_SIZE);
-
-       // Fire pal_mc_error_inject procedure.
-       sprintf(fn, "%s/call_start", path);
-       wr(fn, mode);
-
-       if (rd_capabilities(path, capabilities)<0)
-               return -1;
-
-       return 0;
-  }
-
-  int query_all_capabilities()
-  {
-       int status;
-       err_type_info_t err_type_info;
-       int err_sev, err_struct, struct_hier;
-       int cap=0;
-       u64 capabilities;
-       char path[MAX_FN_SIZE];
-
-       err_type_info.err_type_info=0;                  // Initial
-       err_type_info.err_type_info_u.mode=0;           // Query mode;
-       err_type_info.err_type_info_u.err_inj=0;
-
-       printf("All capabilities implemented in pal_mc_error_inject:\n");
-       sprintf(path, PATH_FORMAT ,0);
-       for (err_sev=0;err_sev<3;err_sev++)
-               for (err_struct=0;err_struct<5;err_struct++)
-                       for (struct_hier=0;struct_hier<5;struct_hier++)
-       {
-               status=-1;
-               capabilities=0;
-               err_type_info.err_type_info_u.err_sev=err_sev;
-               err_type_info.err_type_info_u.err_struct=err_struct;
-               err_type_info.err_type_info_u.struct_hier=struct_hier;
-
-               if (query_capabilities(path, err_type_info, &capabilities)<0)
-                       continue;
-
-               if (rd_status(path, &status)<0)
-                       continue;
-
-               if (status==0) {
-                       cap=1;
-                       printf("For err_sev=%d, err_struct=%d, struct_hier=%d: ",
-                               err_sev, err_struct, struct_hier);
-                       printf("capabilities 0x%lx\n", capabilities);
-               }
-       }
-       if (!cap) {
-               printf("No capabilities supported.\n");
-               return 0;
-       }
-
-       return 0;
-  }
-
-  int err_inject(int cpu, char *path, err_type_info_t err_type_info,
-               err_struct_info_t err_struct_info,
-               err_data_buffer_t err_data_buffer)
-  {
-       int status;
-       char fn[MAX_FN_SIZE];
-
-       log_info(cpu, "err_type_info=%lx, err_struct_info=%lx, ",
-               err_type_info.err_type_info,
-               err_struct_info.err_struct_info);
-       log_info(cpu,"err_data_buffer=[%lx,%lx,%lx]\n",
-               err_data_buffer.err_data_buffer[0],
-               err_data_buffer.err_data_buffer[1],
-               err_data_buffer.err_data_buffer[2]);
-       sprintf(fn, "%s/err_type_info", path);
-       wr(fn, err_type_info.err_type_info);
-       sprintf(fn, "%s/err_struct_info", path);
-       wr(fn, err_struct_info.err_struct_info);
-       sprintf(fn, "%s/err_data_buffer", path);
-       wr_multi(fn, err_data_buffer.err_data_buffer, ERR_DATA_BUFFER_SIZE);
-
-       // Fire pal_mc_error_inject procedure.
-       sprintf(fn, "%s/call_start", path);
-       wr(fn,mode);
-
-       if (rd_status(path, &status)<0) {
-               vbprintf("fail: read status\n");
-               return -100;
-       }
-
-       if (status!=0) {
-               log_info(cpu, "fail: status=%d\n", status);
-               return status;
-       }
-
-       return status;
-  }
-
-  static int construct_data_buf(char *path, err_type_info_t err_type_info,
-               err_struct_info_t err_struct_info,
-               err_data_buffer_t *err_data_buffer,
-               void *va1)
-  {
-       char fn[MAX_FN_SIZE];
-       u64 virt_addr=0, phys_addr=0;
-
-       vbprintf("va1=%lx\n", (u64)va1);
-       memset(&err_data_buffer->err_data_buffer_cache, 0, ERR_DATA_BUFFER_SIZE*8);
-
-       switch (err_type_info.err_type_info_u.err_struct) {
-               case 1: // Cache
-                       switch (err_struct_info.err_struct_info_cache.cl_id) {
-                               case 1: //Virtual addr
-                                       err_data_buffer->err_data_buffer_cache.inj_addr=(u64)va1;
-                                       break;
-                               case 2: //Phys addr
-                                       sprintf(fn, "%s/virtual_to_phys", path);
-                                       virt_addr=(u64)va1;
-                                       if (wr(fn,virt_addr)<0)
-                                               return -1;
-                                       rd(fn, &phys_addr);
-                                       err_data_buffer->err_data_buffer_cache.inj_addr=phys_addr;
-                                       break;
-                               default:
-                                       printf("Not supported cl_id\n");
-                                       break;
-                       }
-                       break;
-               case 2: //  TLB
-                       break;
-               case 3: //  Register file
-                       break;
-               case 4: //  Bus/system interconnect
-               default:
-                       printf("Not supported err_struct\n");
-                       break;
-       }
-
-       return 0;
-  }
-
-  typedef struct {
-       u64 cpu;
-       u64 loop;
-       u64 interval;
-       u64 err_type_info;
-       u64 err_struct_info;
-       u64 err_data_buffer[ERR_DATA_BUFFER_SIZE];
-  } parameters_t;
-
-  parameters_t line_para;
-  int para;
-
-  static int empty_data_buffer(u64 *err_data_buffer)
-  {
-       int empty=1;
-       int i;
-
-       for (i=0;i<ERR_DATA_BUFFER_SIZE; i++)
-          if (err_data_buffer[i]!=-1)
-               empty=0;
-
-       return empty;
-  }
-
-  int err_inj()
-  {
-       err_type_info_t err_type_info;
-       err_struct_info_t err_struct_info;
-       err_data_buffer_t err_data_buffer;
-       int count;
-       FILE *fp;
-       unsigned long cpu, loop, interval, err_type_info_conf, err_struct_info_conf;
-       u64 err_data_buffer_conf[ERR_DATA_BUFFER_SIZE];
-       int num;
-       int i;
-       char path[MAX_FN_SIZE];
-       parameters_t parameters[MAX_TASK_NUM]={};
-       pid_t child_pid[MAX_TASK_NUM];
-       time_t current_time;
-       int status;
-
-       if (!para) {
-           fp=fopen("err.conf", "r");
-           if (fp==NULL) {
-               perror("Error open err.conf");
-               return -1;
-           }
-
-           num=0;
-           while (!feof(fp)) {
-               char buf[256];
-               memset(buf,0,256);
-               fgets(buf, 256, fp);
-               count=sscanf(buf, "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx\n",
-                               &cpu, &loop, &interval,&err_type_info_conf,
-                               &err_struct_info_conf,
-                               &err_data_buffer_conf[0],
-                               &err_data_buffer_conf[1],
-                               &err_data_buffer_conf[2]);
-               if (count!=PARA_FIELD_NUM+3) {
-                       err_data_buffer_conf[0]=-1;
-                       err_data_buffer_conf[1]=-1;
-                       err_data_buffer_conf[2]=-1;
-                       count=sscanf(buf, "%lx, %lx, %lx, %lx, %lx\n",
-                               &cpu, &loop, &interval,&err_type_info_conf,
-                               &err_struct_info_conf);
-                       if (count!=PARA_FIELD_NUM)
-                               continue;
-               }
-
-               parameters[num].cpu=cpu;
-               parameters[num].loop=loop;
-               parameters[num].interval= interval>MIN_INTERVAL
-                                         ?interval:MIN_INTERVAL;
-               parameters[num].err_type_info=err_type_info_conf;
-               parameters[num].err_struct_info=err_struct_info_conf;
-               memcpy(parameters[num++].err_data_buffer,
-                       err_data_buffer_conf,ERR_DATA_BUFFER_SIZE*8) ;
-
-               if (num>=MAX_TASK_NUM)
-                       break;
-           }
-       }
-       else {
-               parameters[0].cpu=line_para.cpu;
-               parameters[0].loop=line_para.loop;
-               parameters[0].interval= line_para.interval>MIN_INTERVAL
-                                         ?line_para.interval:MIN_INTERVAL;
-               parameters[0].err_type_info=line_para.err_type_info;
-               parameters[0].err_struct_info=line_para.err_struct_info;
-               memcpy(parameters[0].err_data_buffer,
-                       line_para.err_data_buffer,ERR_DATA_BUFFER_SIZE*8) ;
-
-               num=1;
-       }
-
-       /* Create semaphore: If one_lock, one semaphore for all processors.
-          Otherwise, one semaphore for each processor. */
-       if (one_lock) {
-               if (create_sem(0)) {
-                       printf("Can not create semaphore...exit\n");
-                       free_sem(0);
-                       return -1;
-               }
-       }
-       else {
-               for (i=0;i<num;i++) {
-                  if (create_sem(parameters[i].cpu)) {
-                       printf("Can not create semaphore for cpu%d...exit\n",i);
-                       free_sem(parameters[num].cpu);
-                       return -1;
-                  }
-               }
-       }
-
-       /* Create a shm segment which will be used to inject/consume errors on.*/
-       if (create_shm()==-1) {
-               printf("Error to create shm...exit\n");
-               return -1;
-       }
-
-       for (i=0;i<num;i++) {
-               pid_t pid;
-
-               current_time=time(NULL);
-               log_info(parameters[i].cpu, "\nBegine at %s", ctime(&current_time));
-               log_info(parameters[i].cpu, "Configurations:\n");
-               log_info(parameters[i].cpu,"On cpu%ld: loop=%lx, interval=%lx(s)",
-                       parameters[i].cpu,
-                       parameters[i].loop,
-                       parameters[i].interval);
-               log_info(parameters[i].cpu," err_type_info=%lx,err_struct_info=%lx\n",
-                       parameters[i].err_type_info,
-                       parameters[i].err_struct_info);
-
-               sprintf(path, PATH_FORMAT, (int)parameters[i].cpu);
-               err_type_info.err_type_info=parameters[i].err_type_info;
-               err_struct_info.err_struct_info=parameters[i].err_struct_info;
-               memcpy(err_data_buffer.err_data_buffer,
-                       parameters[i].err_data_buffer,
-                       ERR_DATA_BUFFER_SIZE*8);
-
-               pid=fork();
-               if (pid==0) {
-                       unsigned long mask[MASK_SIZE];
-                       int j, k;
-
-                       void *va1, *va2;
-
-                       /* Allocate two memory areas va1 and va2 in shm */
-                       va1=shmaddr+parameters[i].cpu*PAGE_SIZE;
-                       va2=shmaddr+parameters[i].cpu*PAGE_SIZE+PAGE_SIZE;
-
-                       vbprintf("va1=%lx, va2=%lx\n", (u64)va1, (u64)va2);
-                       memset(va1, 0x1, PAGE_SIZE);
-                       memset(va2, 0x2, PAGE_SIZE);
-
-                       if (empty_data_buffer(err_data_buffer.err_data_buffer))
-                               /* If not specified yet, construct data buffer
-                                * with va1
-                                */
-                               construct_data_buf(path, err_type_info,
-                                       err_struct_info, &err_data_buffer,va1);
-
-                       for (j=0;j<MASK_SIZE;j++)
-                               mask[j]=0;
-
-                       cpu=parameters[i].cpu;
-                       k = cpu%64;
-                       j = cpu/64;
-                       mask[j] = 1UL << k;
-
-                       if (sched_setaffinity(0, MASK_SIZE*8, mask)==-1) {
-                               perror("Error sched_setaffinity:");
-                               return -1;
-                       }
-
-                       for (j=0; j<parameters[i].loop; j++) {
-                               log_info(parameters[i].cpu,"Injection ");
-                               log_info(parameters[i].cpu,"on cpu%ld: #%d/%ld ",
-
-                                       parameters[i].cpu,j+1, parameters[i].loop);
-
-                               /* Hold the lock */
-                               if (one_lock)
-                                       lock(0);
-                               else
-                               /* Hold lock on this cpu */
-                                       lock(parameters[i].cpu);
-
-                               if ((status=err_inject(parameters[i].cpu,
-                                          path, err_type_info,
-                                          err_struct_info, err_data_buffer))
-                                          ==0) {
-                                       /* consume the error for "inject only"*/
-                                       memcpy(va2, va1, PAGE_SIZE);
-                                       memcpy(va1, va2, PAGE_SIZE);
-                                       log_info(parameters[i].cpu,
-                                               "successful\n");
-                               }
-                               else {
-                                       log_info(parameters[i].cpu,"fail:");
-                                       log_info(parameters[i].cpu,
-                                               "status=%d\n", status);
-                                       unlock(parameters[i].cpu);
-                                       break;
-                               }
-                               if (one_lock)
-                               /* Release the lock */
-                                       unlock(0);
-                               /* Release lock on this cpu */
-                               else
-                                       unlock(parameters[i].cpu);
-
-                               if (j < parameters[i].loop-1)
-                                       sleep(parameters[i].interval);
-                       }
-                       current_time=time(NULL);
-                       log_info(parameters[i].cpu, "Done at %s", ctime(&current_time));
-                       return 0;
-               }
-               else if (pid<0) {
-                       perror("Error fork:");
-                       continue;
-               }
-               child_pid[i]=pid;
-       }
-       for (i=0;i<num;i++)
-               waitpid(child_pid[i], NULL, 0);
-
-       if (one_lock)
-               free_sem(0);
-       else
-               for (i=0;i<num;i++)
-                       free_sem(parameters[i].cpu);
-
-       printf("All done.\n");
-
-       return 0;
-  }
-
-  void help()
-  {
-       printf("err_inject_tool:\n");
-       printf("\t-q: query all capabilities. default: off\n");
-       printf("\t-m: procedure mode. 1: physical 2: virtual. default: 1\n");
-       printf("\t-i: inject errors. default: off\n");
-       printf("\t-l: one lock per cpu. default: one lock for all\n");
-       printf("\t-e: error parameters:\n");
-       printf("\t\tcpu,loop,interval,err_type_info,err_struct_info[,err_data_buffer[0],err_data_buffer[1],err_data_buffer[2]]\n");
-       printf("\t\t   cpu: logical cpu number the error will be inject in.\n");
-       printf("\t\t   loop: times the error will be injected.\n");
-       printf("\t\t   interval: In second. every so often one error is injected.\n");
-       printf("\t\t   err_type_info, err_struct_info: PAL parameters.\n");
-       printf("\t\t   err_data_buffer: PAL parameter. Optional. If not present,\n");
-       printf("\t\t                    it's constructed by tool automatically. Be\n");
-       printf("\t\t                    careful to provide err_data_buffer and make\n");
-       printf("\t\t                    sure it's working with the environment.\n");
-       printf("\t    Note:no space between error parameters.\n");
-       printf("\t    default: Take error parameters from err.conf instead of command line.\n");
-       printf("\t-v: verbose. default: off\n");
-       printf("\t-h: help\n\n");
-       printf("The tool will take err.conf file as ");
-       printf("input to inject single or multiple errors ");
-       printf("on one or multiple cpus in parallel.\n");
-  }
-
-  int main(int argc, char **argv)
-  {
-       char c;
-       int do_err_inj=0;
-       int do_query_all=0;
-       int count;
-       u32 m;
-
-       /* Default one lock for all cpu's */
-       one_lock=1;
-       while ((c = getopt(argc, argv, "m:iqvhle:")) != EOF)
-               switch (c) {
-                       case 'm':       /* Procedure mode. 1: phys 2: virt */
-                               count=sscanf(optarg, "%x", &m);
-                               if (count!=1 || (m!=1 && m!=2)) {
-                                       printf("Wrong mode number.\n");
-                                       help();
-                                       return -1;
-                               }
-                               mode=m;
-                               break;
-                       case 'i':       /* Inject errors */
-                               do_err_inj=1;
-                               break;
-                       case 'q':       /* Query */
-                               do_query_all=1;
-                               break;
-                       case 'v':       /* Verbose */
-                               verbose=1;
-                               break;
-                       case 'l':       /* One lock per cpu */
-                               one_lock=0;
-                               break;
-                       case 'e':       /* error arguments */
-                               /* Take parameters:
-                                * #cpu, loop, interval, err_type_info, err_struct_info[, err_data_buffer]
-                                * err_data_buffer is optional. Recommend not to specify
-                                * err_data_buffer. Better to use tool to generate it.
-                                */
-                               count=sscanf(optarg,
-                                       "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx\n",
-                                       &line_para.cpu,
-                                       &line_para.loop,
-                                       &line_para.interval,
-                                       &line_para.err_type_info,
-                                       &line_para.err_struct_info,
-                                       &line_para.err_data_buffer[0],
-                                       &line_para.err_data_buffer[1],
-                                       &line_para.err_data_buffer[2]);
-                               if (count!=PARA_FIELD_NUM+3) {
-                                   line_para.err_data_buffer[0]=-1,
-                                   line_para.err_data_buffer[1]=-1,
-                                   line_para.err_data_buffer[2]=-1;
-                                   count=sscanf(optarg, "%lx, %lx, %lx, %lx, %lx\n",
-                                               &line_para.cpu,
-                                               &line_para.loop,
-                                               &line_para.interval,
-                                               &line_para.err_type_info,
-                                               &line_para.err_struct_info);
-                                   if (count!=PARA_FIELD_NUM) {
-                                       printf("Wrong error arguments.\n");
-                                       help();
-                                       return -1;
-                                   }
-                               }
-                               para=1;
-                               break;
-                       continue;
-                               break;
-                       case 'h':
-                               help();
-                               return 0;
-                       default:
-                               break;
-               }
-
-       if (do_query_all)
-               query_all_capabilities();
-       if (do_err_inj)
-               err_inj();
-
-       if (!do_query_all &&  !do_err_inj)
-               help();
-
-       return 0;
-  }
diff --git a/Documentation/ia64/features.rst b/Documentation/ia64/features.rst
deleted file mode 100644 (file)
index d7226fd..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. kernel-feat:: $srctree/Documentation/features ia64
diff --git a/Documentation/ia64/fsys.rst b/Documentation/ia64/fsys.rst
deleted file mode 100644 (file)
index a702d2c..0000000
+++ /dev/null
@@ -1,303 +0,0 @@
-===================================
-Light-weight System Calls for IA-64
-===================================
-
-                       Started: 13-Jan-2003
-
-                   Last update: 27-Sep-2003
-
-                     David Mosberger-Tang
-                     <davidm@hpl.hp.com>
-
-Using the "epc" instruction effectively introduces a new mode of
-execution to the ia64 linux kernel.  We call this mode the
-"fsys-mode".  To recap, the normal states of execution are:
-
-  - kernel mode:
-       Both the register stack and the memory stack have been
-       switched over to kernel memory.  The user-level state is saved
-       in a pt-regs structure at the top of the kernel memory stack.
-
-  - user mode:
-       Both the register stack and the kernel stack are in
-       user memory.  The user-level state is contained in the
-       CPU registers.
-
-  - bank 0 interruption-handling mode:
-       This is the non-interruptible state which all
-       interruption-handlers start execution in.  The user-level
-       state remains in the CPU registers and some kernel state may
-       be stored in bank 0 of registers r16-r31.
-
-In contrast, fsys-mode has the following special properties:
-
-  - execution is at privilege level 0 (most-privileged)
-
-  - CPU registers may contain a mixture of user-level and kernel-level
-    state (it is the responsibility of the kernel to ensure that no
-    security-sensitive kernel-level state is leaked back to
-    user-level)
-
-  - execution is interruptible and preemptible (an fsys-mode handler
-    can disable interrupts and avoid all other interruption-sources
-    to avoid preemption)
-
-  - neither the memory-stack nor the register-stack can be trusted while
-    in fsys-mode (they point to the user-level stacks, which may
-    be invalid, or completely bogus addresses)
-
-In summary, fsys-mode is much more similar to running in user-mode
-than it is to running in kernel-mode.  Of course, given that the
-privilege level is at level 0, this means that fsys-mode requires some
-care (see below).
-
-
-How to tell fsys-mode
-=====================
-
-Linux operates in fsys-mode when (a) the privilege level is 0 (most
-privileged) and (b) the stacks have NOT been switched to kernel memory
-yet.  For convenience, the header file <asm-ia64/ptrace.h> provides
-three macros::
-
-       user_mode(regs)
-       user_stack(task,regs)
-       fsys_mode(task,regs)
-
-The "regs" argument is a pointer to a pt_regs structure.  The "task"
-argument is a pointer to the task structure to which the "regs"
-pointer belongs to.  user_mode() returns TRUE if the CPU state pointed
-to by "regs" was executing in user mode (privilege level 3).
-user_stack() returns TRUE if the state pointed to by "regs" was
-executing on the user-level stack(s).  Finally, fsys_mode() returns
-TRUE if the CPU state pointed to by "regs" was executing in fsys-mode.
-The fsys_mode() macro is equivalent to the expression::
-
-       !user_mode(regs) && user_stack(task,regs)
-
-How to write an fsyscall handler
-================================
-
-The file arch/ia64/kernel/fsys.S contains a table of fsyscall-handlers
-(fsyscall_table).  This table contains one entry for each system call.
-By default, a system call is handled by fsys_fallback_syscall().  This
-routine takes care of entering (full) kernel mode and calling the
-normal Linux system call handler.  For performance-critical system
-calls, it is possible to write a hand-tuned fsyscall_handler.  For
-example, fsys.S contains fsys_getpid(), which is a hand-tuned version
-of the getpid() system call.
-
-The entry and exit-state of an fsyscall handler is as follows:
-
-Machine state on entry to fsyscall handler
-------------------------------------------
-
-  ========= ===============================================================
-  r10      0
-  r11      saved ar.pfs (a user-level value)
-  r15      system call number
-  r16      "current" task pointer (in normal kernel-mode, this is in r13)
-  r32-r39   system call arguments
-  b6       return address (a user-level value)
-  ar.pfs    previous frame-state (a user-level value)
-  PSR.be    cleared to zero (i.e., little-endian byte order is in effect)
-  -         all other registers may contain values passed in from user-mode
-  ========= ===============================================================
-
-Required machine state on exit to fsyscall handler
---------------------------------------------------
-
-  ========= ===========================================================
-  r11      saved ar.pfs (as passed into the fsyscall handler)
-  r15      system call number (as passed into the fsyscall handler)
-  r32-r39   system call arguments (as passed into the fsyscall handler)
-  b6       return address (as passed into the fsyscall handler)
-  ar.pfs    previous frame-state (as passed into the fsyscall handler)
-  ========= ===========================================================
-
-Fsyscall handlers can execute with very little overhead, but with that
-speed comes a set of restrictions:
-
- * Fsyscall-handlers MUST check for any pending work in the flags
-   member of the thread-info structure and if any of the
-   TIF_ALLWORK_MASK flags are set, the handler needs to fall back on
-   doing a full system call (by calling fsys_fallback_syscall).
-
- * Fsyscall-handlers MUST preserve incoming arguments (r32-r39, r11,
-   r15, b6, and ar.pfs) because they will be needed in case of a
-   system call restart.  Of course, all "preserved" registers also
-   must be preserved, in accordance to the normal calling conventions.
-
- * Fsyscall-handlers MUST check argument registers for containing a
-   NaT value before using them in any way that could trigger a
-   NaT-consumption fault.  If a system call argument is found to
-   contain a NaT value, an fsyscall-handler may return immediately
-   with r8=EINVAL, r10=-1.
-
- * Fsyscall-handlers MUST NOT use the "alloc" instruction or perform
-   any other operation that would trigger mandatory RSE
-   (register-stack engine) traffic.
-
- * Fsyscall-handlers MUST NOT write to any stacked registers because
-   it is not safe to assume that user-level called a handler with the
-   proper number of arguments.
-
- * Fsyscall-handlers need to be careful when accessing per-CPU variables:
-   unless proper safe-guards are taken (e.g., interruptions are avoided),
-   execution may be pre-empted and resumed on another CPU at any given
-   time.
-
- * Fsyscall-handlers must be careful not to leak sensitive kernel'
-   information back to user-level.  In particular, before returning to
-   user-level, care needs to be taken to clear any scratch registers
-   that could contain sensitive information (note that the current
-   task pointer is not considered sensitive: it's already exposed
-   through ar.k6).
-
- * Fsyscall-handlers MUST NOT access user-memory without first
-   validating access-permission (this can be done typically via
-   probe.r.fault and/or probe.w.fault) and without guarding against
-   memory access exceptions (this can be done with the EX() macros
-   defined by asmmacro.h).
-
-The above restrictions may seem draconian, but remember that it's
-possible to trade off some of the restrictions by paying a slightly
-higher overhead.  For example, if an fsyscall-handler could benefit
-from the shadow register bank, it could temporarily disable PSR.i and
-PSR.ic, switch to bank 0 (bsw.0) and then use the shadow registers as
-needed.  In other words, following the above rules yields extremely
-fast system call execution (while fully preserving system call
-semantics), but there is also a lot of flexibility in handling more
-complicated cases.
-
-Signal handling
-===============
-
-The delivery of (asynchronous) signals must be delayed until fsys-mode
-is exited.  This is accomplished with the help of the lower-privilege
-transfer trap: arch/ia64/kernel/process.c:do_notify_resume_user()
-checks whether the interrupted task was in fsys-mode and, if so, sets
-PSR.lp and returns immediately.  When fsys-mode is exited via the
-"br.ret" instruction that lowers the privilege level, a trap will
-occur.  The trap handler clears PSR.lp again and returns immediately.
-The kernel exit path then checks for and delivers any pending signals.
-
-PSR Handling
-============
-
-The "epc" instruction doesn't change the contents of PSR at all.  This
-is in contrast to a regular interruption, which clears almost all
-bits.  Because of that, some care needs to be taken to ensure things
-work as expected.  The following discussion describes how each PSR bit
-is handled.
-
-======= =======================================================================
-PSR.be Cleared when entering fsys-mode.  A srlz.d instruction is used
-       to ensure the CPU is in little-endian mode before the first
-       load/store instruction is executed.  PSR.be is normally NOT
-       restored upon return from an fsys-mode handler.  In other
-       words, user-level code must not rely on PSR.be being preserved
-       across a system call.
-PSR.up Unchanged.
-PSR.ac Unchanged.
-PSR.mfl Unchanged.  Note: fsys-mode handlers must not write-registers!
-PSR.mfh        Unchanged.  Note: fsys-mode handlers must not write-registers!
-PSR.ic Unchanged.  Note: fsys-mode handlers can clear the bit, if needed.
-PSR.i  Unchanged.  Note: fsys-mode handlers can clear the bit, if needed.
-PSR.pk Unchanged.
-PSR.dt Unchanged.
-PSR.dfl        Unchanged.  Note: fsys-mode handlers must not write-registers!
-PSR.dfh        Unchanged.  Note: fsys-mode handlers must not write-registers!
-PSR.sp Unchanged.
-PSR.pp Unchanged.
-PSR.di Unchanged.
-PSR.si Unchanged.
-PSR.db Unchanged.  The kernel prevents user-level from setting a hardware
-       breakpoint that triggers at any privilege level other than
-       3 (user-mode).
-PSR.lp Unchanged.
-PSR.tb Lazy redirect.  If a taken-branch trap occurs while in
-       fsys-mode, the trap-handler modifies the saved machine state
-       such that execution resumes in the gate page at
-       syscall_via_break(), with privilege level 3.  Note: the
-       taken branch would occur on the branch invoking the
-       fsyscall-handler, at which point, by definition, a syscall
-       restart is still safe.  If the system call number is invalid,
-       the fsys-mode handler will return directly to user-level.  This
-       return will trigger a taken-branch trap, but since the trap is
-       taken _after_ restoring the privilege level, the CPU has already
-       left fsys-mode, so no special treatment is needed.
-PSR.rt Unchanged.
-PSR.cpl        Cleared to 0.
-PSR.is Unchanged (guaranteed to be 0 on entry to the gate page).
-PSR.mc Unchanged.
-PSR.it Unchanged (guaranteed to be 1).
-PSR.id Unchanged.  Note: the ia64 linux kernel never sets this bit.
-PSR.da Unchanged.  Note: the ia64 linux kernel never sets this bit.
-PSR.dd Unchanged.  Note: the ia64 linux kernel never sets this bit.
-PSR.ss Lazy redirect.  If set, "epc" will cause a Single Step Trap to
-       be taken.  The trap handler then modifies the saved machine
-       state such that execution resumes in the gate page at
-       syscall_via_break(), with privilege level 3.
-PSR.ri Unchanged.
-PSR.ed Unchanged.  Note: This bit could only have an effect if an fsys-mode
-       handler performed a speculative load that gets NaTted.  If so, this
-       would be the normal & expected behavior, so no special treatment is
-       needed.
-PSR.bn Unchanged.  Note: fsys-mode handlers may clear the bit, if needed.
-       Doing so requires clearing PSR.i and PSR.ic as well.
-PSR.ia Unchanged.  Note: the ia64 linux kernel never sets this bit.
-======= =======================================================================
-
-Using fast system calls
-=======================
-
-To use fast system calls, userspace applications need simply call
-__kernel_syscall_via_epc().  For example
-
--- example fgettimeofday() call --
-
--- fgettimeofday.S --
-
-::
-
-  #include <asm/asmmacro.h>
-
-  GLOBAL_ENTRY(fgettimeofday)
-  .prologue
-  .save ar.pfs, r11
-  mov r11 = ar.pfs
-  .body
-
-  mov r2 = 0xa000000000020660;;  // gate address
-                              // found by inspection of System.map for the
-                              // __kernel_syscall_via_epc() function.  See
-                              // below for how to do this for real.
-
-  mov b7 = r2
-  mov r15 = 1087                      // gettimeofday syscall
-  ;;
-  br.call.sptk.many b6 = b7
-  ;;
-
-  .restore sp
-
-  mov ar.pfs = r11
-  br.ret.sptk.many rp;;              // return to caller
-  END(fgettimeofday)
-
--- end fgettimeofday.S --
-
-In reality, getting the gate address is accomplished by two extra
-values passed via the ELF auxiliary vector (include/asm-ia64/elf.h)
-
- * AT_SYSINFO : is the address of __kernel_syscall_via_epc()
- * AT_SYSINFO_EHDR : is the address of the kernel gate ELF DSO
-
-The ELF DSO is a pre-linked library that is mapped in by the kernel at
-the gate page.  It is a proper ELF shared object so, with a dynamic
-loader that recognises the library, you should be able to make calls to
-the exported functions within it as with any other shared library.
-AT_SYSINFO points into the kernel DSO at the
-__kernel_syscall_via_epc() function for historical reasons (it was
-used before the kernel DSO) and as a convenience.
diff --git a/Documentation/ia64/ia64.rst b/Documentation/ia64/ia64.rst
deleted file mode 100644 (file)
index b725019..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-===========================================
-Linux kernel release for the IA-64 Platform
-===========================================
-
-   These are the release notes for Linux since version 2.4 for IA-64
-   platform.  This document provides information specific to IA-64
-   ONLY, to get additional information about the Linux kernel also
-   read the original Linux README provided with the kernel.
-
-Installing the Kernel
-=====================
-
- - IA-64 kernel installation is the same as the other platforms, see
-   original README for details.
-
-
-Software Requirements
-=====================
-
-   Compiling and running this kernel requires an IA-64 compliant GCC
-   compiler.  And various software packages also compiled with an
-   IA-64 compliant GCC compiler.
-
-
-Configuring the Kernel
-======================
-
-   Configuration is the same, see original README for details.
-
-
-Compiling the Kernel:
-
- - Compiling this kernel doesn't differ from other platform so read
-   the original README for details BUT make sure you have an IA-64
-   compliant GCC compiler.
-
-IA-64 Specifics
-===============
-
- - General issues:
-
-    * Hardly any performance tuning has been done. Obvious targets
-      include the library routines (IP checksum, etc.). Less
-      obvious targets include making sure we don't flush the TLB
-      needlessly, etc.
-
-    * SMP locks cleanup/optimization
-
-    * IA32 support.  Currently experimental.  It mostly works.
diff --git a/Documentation/ia64/index.rst b/Documentation/ia64/index.rst
deleted file mode 100644 (file)
index 761f215..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-==================
-IA-64 Architecture
-==================
-
-.. toctree::
-   :maxdepth: 1
-
-   ia64
-   aliasing
-   efirtc
-   err_inject
-   fsys
-   irq-redir
-   mca
-   serial
-
-   features
diff --git a/Documentation/ia64/irq-redir.rst b/Documentation/ia64/irq-redir.rst
deleted file mode 100644 (file)
index 6bbbbe4..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-==============================
-IRQ affinity on IA64 platforms
-==============================
-
-07.01.2002, Erich Focht <efocht@ess.nec.de>
-
-
-By writing to /proc/irq/IRQ#/smp_affinity the interrupt routing can be
-controlled. The behavior on IA64 platforms is slightly different from
-that described in Documentation/core-api/irq/irq-affinity.rst for i386 systems.
-
-Because of the usage of SAPIC mode and physical destination mode the
-IRQ target is one particular CPU and cannot be a mask of several
-CPUs. Only the first non-zero bit is taken into account.
-
-
-Usage examples
-==============
-
-The target CPU has to be specified as a hexadecimal CPU mask. The
-first non-zero bit is the selected CPU. This format has been kept for
-compatibility reasons with i386.
-
-Set the delivery mode of interrupt 41 to fixed and route the
-interrupts to CPU #3 (logical CPU number) (2^3=0x08)::
-
-     echo "8" >/proc/irq/41/smp_affinity
-
-Set the default route for IRQ number 41 to CPU 6 in lowest priority
-delivery mode (redirectable)::
-
-     echo "r 40" >/proc/irq/41/smp_affinity
-
-The output of the command::
-
-     cat /proc/irq/IRQ#/smp_affinity
-
-gives the target CPU mask for the specified interrupt vector. If the CPU
-mask is preceded by the character "r", the interrupt is redirectable
-(i.e. lowest priority mode routing is used), otherwise its route is
-fixed.
-
-
-
-Initialization and default behavior
-===================================
-
-If the platform features IRQ redirection (info provided by SAL) all
-IO-SAPIC interrupts are initialized with CPU#0 as their default target
-and the routing is the so called "lowest priority mode" (actually
-fixed SAPIC mode with hint). The XTP chipset registers are used as hints
-for the IRQ routing. Currently in Linux XTP registers can have three
-values:
-
-       - minimal for an idle task,
-       - normal if any other task runs,
-       - maximal if the CPU is going to be switched off.
-
-The IRQ is routed to the CPU with lowest XTP register value, the
-search begins at the default CPU. Therefore most of the interrupts
-will be handled by CPU #0.
-
-If the platform doesn't feature interrupt redirection IOSAPIC fixed
-routing is used. The target CPUs are distributed in a round robin
-manner. IRQs will be routed only to the selected target CPUs. Check
-with::
-
-        cat /proc/interrupts
-
-
-
-Comments
-========
-
-On large (multi-node) systems it is recommended to route the IRQs to
-the node to which the corresponding device is connected.
-For systems like the NEC AzusA we get IRQ node-affinity for free. This
-is because usually the chipsets on each node redirect the interrupts
-only to their own CPUs (as they cannot see the XTP registers on the
-other nodes).
diff --git a/Documentation/ia64/mca.rst b/Documentation/ia64/mca.rst
deleted file mode 100644 (file)
index 08270bb..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-=============================================================
-An ad-hoc collection of notes on IA64 MCA and INIT processing
-=============================================================
-
-Feel free to update it with notes about any area that is not clear.
-
----
-
-MCA/INIT are completely asynchronous.  They can occur at any time, when
-the OS is in any state.  Including when one of the cpus is already
-holding a spinlock.  Trying to get any lock from MCA/INIT state is
-asking for deadlock.  Also the state of structures that are protected
-by locks is indeterminate, including linked lists.
-
----
-
-The complicated ia64 MCA process.  All of this is mandated by Intel's
-specification for ia64 SAL, error recovery and unwind, it is not as
-if we have a choice here.
-
-* MCA occurs on one cpu, usually due to a double bit memory error.
-  This is the monarch cpu.
-
-* SAL sends an MCA rendezvous interrupt (which is a normal interrupt)
-  to all the other cpus, the slaves.
-
-* Slave cpus that receive the MCA interrupt call down into SAL, they
-  end up spinning disabled while the MCA is being serviced.
-
-* If any slave cpu was already spinning disabled when the MCA occurred
-  then it cannot service the MCA interrupt.  SAL waits ~20 seconds then
-  sends an unmaskable INIT event to the slave cpus that have not
-  already rendezvoused.
-
-* Because MCA/INIT can be delivered at any time, including when the cpu
-  is down in PAL in physical mode, the registers at the time of the
-  event are _completely_ undefined.  In particular the MCA/INIT
-  handlers cannot rely on the thread pointer, PAL physical mode can
-  (and does) modify TP.  It is allowed to do that as long as it resets
-  TP on return.  However MCA/INIT events expose us to these PAL
-  internal TP changes.  Hence curr_task().
-
-* If an MCA/INIT event occurs while the kernel was running (not user
-  space) and the kernel has called PAL then the MCA/INIT handler cannot
-  assume that the kernel stack is in a fit state to be used.  Mainly
-  because PAL may or may not maintain the stack pointer internally.
-  Because the MCA/INIT handlers cannot trust the kernel stack, they
-  have to use their own, per-cpu stacks.  The MCA/INIT stacks are
-  preformatted with just enough task state to let the relevant handlers
-  do their job.
-
-* Unlike most other architectures, the ia64 struct task is embedded in
-  the kernel stack[1].  So switching to a new kernel stack means that
-  we switch to a new task as well.  Because various bits of the kernel
-  assume that current points into the struct task, switching to a new
-  stack also means a new value for current.
-
-* Once all slaves have rendezvoused and are spinning disabled, the
-  monarch is entered.  The monarch now tries to diagnose the problem
-  and decide if it can recover or not.
-
-* Part of the monarch's job is to look at the state of all the other
-  tasks.  The only way to do that on ia64 is to call the unwinder,
-  as mandated by Intel.
-
-* The starting point for the unwind depends on whether a task is
-  running or not.  That is, whether it is on a cpu or is blocked.  The
-  monarch has to determine whether or not a task is on a cpu before it
-  knows how to start unwinding it.  The tasks that received an MCA or
-  INIT event are no longer running, they have been converted to blocked
-  tasks.  But (and its a big but), the cpus that received the MCA
-  rendezvous interrupt are still running on their normal kernel stacks!
-
-* To distinguish between these two cases, the monarch must know which
-  tasks are on a cpu and which are not.  Hence each slave cpu that
-  switches to an MCA/INIT stack, registers its new stack using
-  set_curr_task(), so the monarch can tell that the _original_ task is
-  no longer running on that cpu.  That gives us a decent chance of
-  getting a valid backtrace of the _original_ task.
-
-* MCA/INIT can be nested, to a depth of 2 on any cpu.  In the case of a
-  nested error, we want diagnostics on the MCA/INIT handler that
-  failed, not on the task that was originally running.  Again this
-  requires set_curr_task() so the MCA/INIT handlers can register their
-  own stack as running on that cpu.  Then a recursive error gets a
-  trace of the failing handler's "task".
-
-[1]
-    My (Keith Owens) original design called for ia64 to separate its
-    struct task and the kernel stacks.  Then the MCA/INIT data would be
-    chained stacks like i386 interrupt stacks.  But that required
-    radical surgery on the rest of ia64, plus extra hard wired TLB
-    entries with its associated performance degradation.  David
-    Mosberger vetoed that approach.  Which meant that separate kernel
-    stacks meant separate "tasks" for the MCA/INIT handlers.
-
----
-
-INIT is less complicated than MCA.  Pressing the nmi button or using
-the equivalent command on the management console sends INIT to all
-cpus.  SAL picks one of the cpus as the monarch and the rest are
-slaves.  All the OS INIT handlers are entered at approximately the same
-time.  The OS monarch prints the state of all tasks and returns, after
-which the slaves return and the system resumes.
-
-At least that is what is supposed to happen.  Alas there are broken
-versions of SAL out there.  Some drive all the cpus as monarchs.  Some
-drive them all as slaves.  Some drive one cpu as monarch, wait for that
-cpu to return from the OS then drive the rest as slaves.  Some versions
-of SAL cannot even cope with returning from the OS, they spin inside
-SAL on resume.  The OS INIT code has workarounds for some of these
-broken SAL symptoms, but some simply cannot be fixed from the OS side.
-
----
-
-The scheduler hooks used by ia64 (curr_task, set_curr_task) are layer
-violations.  Unfortunately MCA/INIT start off as massive layer
-violations (can occur at _any_ time) and they build from there.
-
-At least ia64 makes an attempt at recovering from hardware errors, but
-it is a difficult problem because of the asynchronous nature of these
-errors.  When processing an unmaskable interrupt we sometimes need
-special code to cope with our inability to take any locks.
-
----
-
-How is ia64 MCA/INIT different from x86 NMI?
-
-* x86 NMI typically gets delivered to one cpu.  MCA/INIT gets sent to
-  all cpus.
-
-* x86 NMI cannot be nested.  MCA/INIT can be nested, to a depth of 2
-  per cpu.
-
-* x86 has a separate struct task which points to one of multiple kernel
-  stacks.  ia64 has the struct task embedded in the single kernel
-  stack, so switching stack means switching task.
-
-* x86 does not call the BIOS so the NMI handler does not have to worry
-  about any registers having changed.  MCA/INIT can occur while the cpu
-  is in PAL in physical mode, with undefined registers and an undefined
-  kernel stack.
-
-* i386 backtrace is not very sensitive to whether a process is running
-  or not.  ia64 unwind is very, very sensitive to whether a process is
-  running or not.
-
----
-
-What happens when MCA/INIT is delivered what a cpu is running user
-space code?
-
-The user mode registers are stored in the RSE area of the MCA/INIT on
-entry to the OS and are restored from there on return to SAL, so user
-mode registers are preserved across a recoverable MCA/INIT.  Since the
-OS has no idea what unwind data is available for the user space stack,
-MCA/INIT never tries to backtrace user space.  Which means that the OS
-does not bother making the user space process look like a blocked task,
-i.e. the OS does not copy pt_regs and switch_stack to the user space
-stack.  Also the OS has no idea how big the user space RSE and memory
-stacks are, which makes it too risky to copy the saved state to a user
-mode stack.
-
----
-
-How do we get a backtrace on the tasks that were running when MCA/INIT
-was delivered?
-
-mca.c:::ia64_mca_modify_original_stack().  That identifies and
-verifies the original kernel stack, copies the dirty registers from
-the MCA/INIT stack's RSE to the original stack's RSE, copies the
-skeleton struct pt_regs and switch_stack to the original stack, fills
-in the skeleton structures from the PAL minstate area and updates the
-original stack's thread.ksp.  That makes the original stack look
-exactly like any other blocked task, i.e. it now appears to be
-sleeping.  To get a backtrace, just start with thread.ksp for the
-original task and unwind like any other sleeping task.
-
----
-
-How do we identify the tasks that were running when MCA/INIT was
-delivered?
-
-If the previous task has been verified and converted to a blocked
-state, then sos->prev_task on the MCA/INIT stack is updated to point to
-the previous task.  You can look at that field in dumps or debuggers.
-To help distinguish between the handler and the original tasks,
-handlers have _TIF_MCA_INIT set in thread_info.flags.
-
-The sos data is always in the MCA/INIT handler stack, at offset
-MCA_SOS_OFFSET.  You can get that value from mca_asm.h or calculate it
-as KERNEL_STACK_SIZE - sizeof(struct pt_regs) - sizeof(struct
-ia64_sal_os_state), with 16 byte alignment for all structures.
-
-Also the comm field of the MCA/INIT task is modified to include the pid
-of the original task, for humans to use.  For example, a comm field of
-'MCA 12159' means that pid 12159 was running when the MCA was
-delivered.
diff --git a/Documentation/ia64/serial.rst b/Documentation/ia64/serial.rst
deleted file mode 100644 (file)
index 1de70c3..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-==============
-Serial Devices
-==============
-
-Serial Device Naming
-====================
-
-    As of 2.6.10, serial devices on ia64 are named based on the
-    order of ACPI and PCI enumeration.  The first device in the
-    ACPI namespace (if any) becomes /dev/ttyS0, the second becomes
-    /dev/ttyS1, etc., and PCI devices are named sequentially
-    starting after the ACPI devices.
-
-    Prior to 2.6.10, there were confusing exceptions to this:
-
-       - Firmware on some machines (mostly from HP) provides an HCDP
-         table[1] that tells the kernel about devices that can be used
-         as a serial console.  If the user specified "console=ttyS0"
-         or the EFI ConOut path contained only UART devices, the
-         kernel registered the device described by the HCDP as
-         /dev/ttyS0.
-
-       - If there was no HCDP, we assumed there were UARTs at the
-         legacy COM port addresses (I/O ports 0x3f8 and 0x2f8), so
-         the kernel registered those as /dev/ttyS0 and /dev/ttyS1.
-
-    Any additional ACPI or PCI devices were registered sequentially
-    after /dev/ttyS0 as they were discovered.
-
-    With an HCDP, device names changed depending on EFI configuration
-    and "console=" arguments.  Without an HCDP, device names didn't
-    change, but we registered devices that might not really exist.
-
-    For example, an HP rx1600 with a single built-in serial port
-    (described in the ACPI namespace) plus an MP[2] (a PCI device) has
-    these ports:
-
-      ==========  ==========     ============    ============   =======
-      Type        MMIO           pre-2.6.10      pre-2.6.10     2.6.10+
-                 address
-                                (EFI console    (EFI console
-                                 on builtin)     on MP port)
-      ==========  ==========     ============    ============   =======
-      builtin     0xff5e0000        ttyS0           ttyS1         ttyS0
-      MP UPS      0xf8031000        ttyS1           ttyS2         ttyS1
-      MP Console  0xf8030000        ttyS2           ttyS0         ttyS2
-      MP 2        0xf8030010        ttyS3           ttyS3         ttyS3
-      MP 3        0xf8030038        ttyS4           ttyS4         ttyS4
-      ==========  ==========     ============    ============   =======
-
-Console Selection
-=================
-
-    EFI knows what your console devices are, but it doesn't tell the
-    kernel quite enough to actually locate them.  The DIG64 HCDP
-    table[1] does tell the kernel where potential serial console
-    devices are, but not all firmware supplies it.  Also, EFI supports
-    multiple simultaneous consoles and doesn't tell the kernel which
-    should be the "primary" one.
-
-    So how do you tell Linux which console device to use?
-
-       - If your firmware supplies the HCDP, it is simplest to
-         configure EFI with a single device (either a UART or a VGA
-         card) as the console.  Then you don't need to tell Linux
-         anything; the kernel will automatically use the EFI console.
-
-         (This works only in 2.6.6 or later; prior to that you had
-         to specify "console=ttyS0" to get a serial console.)
-
-       - Without an HCDP, Linux defaults to a VGA console unless you
-         specify a "console=" argument.
-
-    NOTE: Don't assume that a serial console device will be /dev/ttyS0.
-    It might be ttyS1, ttyS2, etc.  Make sure you have the appropriate
-    entries in /etc/inittab (for getty) and /etc/securetty (to allow
-    root login).
-
-Early Serial Console
-====================
-
-    The kernel can't start using a serial console until it knows where
-    the device lives.  Normally this happens when the driver enumerates
-    all the serial devices, which can happen a minute or more after the
-    kernel starts booting.
-
-    2.6.10 and later kernels have an "early uart" driver that works
-    very early in the boot process.  The kernel will automatically use
-    this if the user supplies an argument like "console=uart,io,0x3f8",
-    or if the EFI console path contains only a UART device and the
-    firmware supplies an HCDP.
-
-Troubleshooting Serial Console Problems
-=======================================
-
-    No kernel output after elilo prints "Uncompressing Linux... done":
-
-       - You specified "console=ttyS0" but Linux changed the device
-         to which ttyS0 refers.  Configure exactly one EFI console
-         device[3] and remove the "console=" option.
-
-       - The EFI console path contains both a VGA device and a UART.
-         EFI and elilo use both, but Linux defaults to VGA.  Remove
-         the VGA device from the EFI console path[3].
-
-       - Multiple UARTs selected as EFI console devices.  EFI and
-         elilo use all selected devices, but Linux uses only one.
-         Make sure only one UART is selected in the EFI console
-         path[3].
-
-       - You're connected to an HP MP port[2] but have a non-MP UART
-         selected as EFI console device.  EFI uses the MP as a
-         console device even when it isn't explicitly selected.
-         Either move the console cable to the non-MP UART, or change
-         the EFI console path[3] to the MP UART.
-
-    Long pause (60+ seconds) between "Uncompressing Linux... done" and
-    start of kernel output:
-
-       - No early console because you used "console=ttyS<n>".  Remove
-         the "console=" option if your firmware supplies an HCDP.
-
-       - If you don't have an HCDP, the kernel doesn't know where
-         your console lives until the driver discovers serial
-         devices.  Use "console=uart,io,0x3f8" (or appropriate
-         address for your machine).
-
-    Kernel and init script output works fine, but no "login:" prompt:
-
-       - Add getty entry to /etc/inittab for console tty.  Look for
-         the "Adding console on ttyS<n>" message that tells you which
-         device is the console.
-
-    "login:" prompt, but can't login as root:
-
-       - Add entry to /etc/securetty for console tty.
-
-    No ACPI serial devices found in 2.6.17 or later:
-
-       - Turn on CONFIG_PNP and CONFIG_PNPACPI.  Prior to 2.6.17, ACPI
-         serial devices were discovered by 8250_acpi.  In 2.6.17,
-         8250_acpi was replaced by the combination of 8250_pnp and
-         CONFIG_PNPACPI.
-
-
-
-[1]
-    http://www.dig64.org/specifications/agreement
-    The table was originally defined as the "HCDP" for "Headless
-    Console/Debug Port."  The current version is the "PCDP" for
-    "Primary Console and Debug Port Devices."
-
-[2]
-    The HP MP (management processor) is a PCI device that provides
-    several UARTs.  One of the UARTs is often used as a console; the
-    EFI Boot Manager identifies it as "Acpi(HWP0002,700)/Pci(...)/Uart".
-    The external connection is usually a 25-pin connector, and a
-    special dongle converts that to three 9-pin connectors, one of
-    which is labelled "Console."
-
-[3]
-    EFI console devices are configured using the EFI Boot Manager
-    "Boot option maintenance" menu.  You may have to interrupt the
-    boot sequence to use this menu, and you will have to reset the
-    box after changing console configuration.
index 76d1a3ec9be3de914aee1c301add8a43293d441e..9dfdc826618c08f5f62f81f1cea543dea3223967 100644 (file)
@@ -99,7 +99,7 @@ Architecture-specific documentation
 .. toctree::
    :maxdepth: 2
 
-   arch
+   arch/index
 
 
 Other documentation
index bfb51685073cb6c5dd09d2617d15912b49573ce9..c3851fe1900da15e47883e1d7d5292075cfaee48 100644 (file)
@@ -171,6 +171,10 @@ Getting Help
 Getting LLVM
 -------------
 
+We provide prebuilt stable versions of LLVM on `kernel.org <https://kernel.org/pub/tools/llvm/>`_.
+Below are links that may be useful for building LLVM from source or procuring
+it through a distribution's package manager.
+
 - https://releases.llvm.org/download.html
 - https://github.com/llvm/llvm-project
 - https://llvm.org/docs/GettingStarted.html
diff --git a/Documentation/kernel-hacking/false-sharing.rst b/Documentation/kernel-hacking/false-sharing.rst
new file mode 100644 (file)
index 0000000..122b0e1
--- /dev/null
@@ -0,0 +1,206 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=============
+False Sharing
+=============
+
+What is False Sharing
+=====================
+False sharing is related with cache mechanism of maintaining the data
+coherence of one cache line stored in multiple CPU's caches; then
+academic definition for it is in [1]_. Consider a struct with a
+refcount and a string::
+
+       struct foo {
+               refcount_t refcount;
+               ...
+               char name[16];
+       } ____cacheline_internodealigned_in_smp;
+
+Member 'refcount'(A) and 'name'(B) _share_ one cache line like below::
+
+                +-----------+                     +-----------+
+                |   CPU 0   |                     |   CPU 1   |
+                +-----------+                     +-----------+
+               /                                        |
+              /                                         |
+             V                                          V
+         +----------------------+             +----------------------+
+         | A      B             | Cache 0     | A       B            | Cache 1
+         +----------------------+             +----------------------+
+                             |                  |
+  ---------------------------+------------------+-----------------------------
+                             |                  |
+                           +----------------------+
+                           |                      |
+                           +----------------------+
+              Main Memory  | A       B            |
+                           +----------------------+
+
+'refcount' is modified frequently, but 'name' is set once at object
+creation time and is never modified.  When many CPUs access 'foo' at
+the same time, with 'refcount' being only bumped by one CPU frequently
+and 'name' being read by other CPUs, all those reading CPUs have to
+reload the whole cache line over and over due to the 'sharing', even
+though 'name' is never changed.
+
+There are many real-world cases of performance regressions caused by
+false sharing.  One of these is a rw_semaphore 'mmap_lock' inside
+mm_struct struct, whose cache line layout change triggered a
+regression and Linus analyzed in [2]_.
+
+There are two key factors for a harmful false sharing:
+
+* A global datum accessed (shared) by many CPUs
+* In the concurrent accesses to the data, there is at least one write
+  operation: write/write or write/read cases.
+
+The sharing could be from totally unrelated kernel components, or
+different code paths of the same kernel component.
+
+
+False Sharing Pitfalls
+======================
+Back in time when one platform had only one or a few CPUs, hot data
+members could be purposely put in the same cache line to make them
+cache hot and save cacheline/TLB, like a lock and the data protected
+by it.  But for recent large system with hundreds of CPUs, this may
+not work when the lock is heavily contended, as the lock owner CPU
+could write to the data, while other CPUs are busy spinning the lock.
+
+Looking at past cases, there are several frequently occurring patterns
+for false sharing:
+
+* lock (spinlock/mutex/semaphore) and data protected by it are
+  purposely put in one cache line.
+* global data being put together in one cache line. Some kernel
+  subsystems have many global parameters of small size (4 bytes),
+  which can easily be grouped together and put into one cache line.
+* data members of a big data structure randomly sitting together
+  without being noticed (cache line is usually 64 bytes or more),
+  like 'mem_cgroup' struct.
+
+Following 'mitigation' section provides real-world examples.
+
+False sharing could easily happen unless they are intentionally
+checked, and it is valuable to run specific tools for performance
+critical workloads to detect false sharing affecting performance case
+and optimize accordingly.
+
+
+How to detect and analyze False Sharing
+========================================
+perf record/report/stat are widely used for performance tuning, and
+once hotspots are detected, tools like 'perf-c2c' and 'pahole' can
+be further used to detect and pinpoint the possible false sharing
+data structures.  'addr2line' is also good at decoding instruction
+pointer when there are multiple layers of inline functions.
+
+perf-c2c can capture the cache lines with most false sharing hits,
+decoded functions (line number of file) accessing that cache line,
+and in-line offset of the data. Simple commands are::
+
+  $ perf c2c record -ag sleep 3
+  $ perf c2c report --call-graph none -k vmlinux
+
+When running above during testing will-it-scale's tlb_flush1 case,
+perf reports something like::
+
+  Total records                     :    1658231
+  Locked Load/Store Operations      :      89439
+  Load Operations                   :     623219
+  Load Local HITM                   :      92117
+  Load Remote HITM                  :        139
+
+  #----------------------------------------------------------------------
+      4        0     2374        0        0        0  0xff1100088366d880
+  #----------------------------------------------------------------------
+    0.00%   42.29%    0.00%    0.00%    0.00%    0x8     1       1  0xffffffff81373b7b         0       231       129     5312        64  [k] __mod_lruvec_page_state    [kernel.vmlinux]  memcontrol.h:752   1
+    0.00%   13.10%    0.00%    0.00%    0.00%    0x8     1       1  0xffffffff81374718         0       226        97     3551        64  [k] folio_lruvec_lock_irqsave  [kernel.vmlinux]  memcontrol.h:752   1
+    0.00%   11.20%    0.00%    0.00%    0.00%    0x8     1       1  0xffffffff812c29bf         0       170       136      555        64  [k] lru_add_fn                 [kernel.vmlinux]  mm_inline.h:41     1
+    0.00%    7.62%    0.00%    0.00%    0.00%    0x8     1       1  0xffffffff812c3ec5         0       175       108      632        64  [k] release_pages              [kernel.vmlinux]  mm_inline.h:41     1
+    0.00%   23.29%    0.00%    0.00%    0.00%   0x10     1       1  0xffffffff81372d0a         0       234       279     1051        64  [k] __mod_memcg_lruvec_state   [kernel.vmlinux]  memcontrol.c:736   1
+
+A nice introduction for perf-c2c is [3]_.
+
+'pahole' decodes data structure layouts delimited in cache line
+granularity.  Users can match the offset in perf-c2c output with
+pahole's decoding to locate the exact data members.  For global
+data, users can search the data address in System.map.
+
+
+Possible Mitigations
+====================
+False sharing does not always need to be mitigated.  False sharing
+mitigations should balance performance gains with complexity and
+space consumption.  Sometimes, lower performance is OK, and it's
+unnecessary to hyper-optimize every rarely used data structure or
+a cold data path.
+
+False sharing hurting performance cases are seen more frequently with
+core count increasing.  Because of these detrimental effects, many
+patches have been proposed across variety of subsystems (like
+networking and memory management) and merged.  Some common mitigations
+(with examples) are:
+
+* Separate hot global data in its own dedicated cache line, even if it
+  is just a 'short' type. The downside is more consumption of memory,
+  cache line and TLB entries.
+
+  - Commit 91b6d3256356 ("net: cache align tcp_memory_allocated, tcp_sockets_allocated")
+
+* Reorganize the data structure, separate the interfering members to
+  different cache lines.  One downside is it may introduce new false
+  sharing of other members.
+
+  - Commit 802f1d522d5f ("mm: page_counter: re-layout structure to reduce false sharing")
+
+* Replace 'write' with 'read' when possible, especially in loops.
+  Like for some global variable, use compare(read)-then-write instead
+  of unconditional write. For example, use::
+
+       if (!test_bit(XXX))
+               set_bit(XXX);
+
+  instead of directly "set_bit(XXX);", similarly for atomic_t data::
+
+       if (atomic_read(XXX) == AAA)
+               atomic_set(XXX, BBB);
+
+  - Commit 7b1002f7cfe5 ("bcache: fixup bcache_dev_sectors_dirty_add() multithreaded CPU false sharing")
+  - Commit 292648ac5cf1 ("mm: gup: allow FOLL_PIN to scale in SMP")
+
+* Turn hot global data to 'per-cpu data + global data' when possible,
+  or reasonably increase the threshold for syncing per-cpu data to
+  global data, to reduce or postpone the 'write' to that global data.
+
+  - Commit 520f897a3554 ("ext4: use percpu_counters for extent_status cache hits/misses")
+  - Commit 56f3547bfa4d ("mm: adjust vm_committed_as_batch according to vm overcommit policy")
+
+Surely, all mitigations should be carefully verified to not cause side
+effects.  To avoid introducing false sharing when coding, it's better
+to:
+
+* Be aware of cache line boundaries
+* Group mostly read-only fields together
+* Group things that are written at the same time together
+* Separate frequently read and frequently written fields on
+  different cache lines.
+
+and better add a comment stating the false sharing consideration.
+
+One note is, sometimes even after a severe false sharing is detected
+and solved, the performance may still have no obvious improvement as
+the hotspot switches to a new place.
+
+
+Miscellaneous
+=============
+One open issue is that kernel has an optional data structure
+randomization mechanism, which also randomizes the situation of cache
+line sharing of data members.
+
+
+.. [1] https://en.wikipedia.org/wiki/False_sharing
+.. [2] https://lore.kernel.org/lkml/CAHk-=whoqV=cX5VC80mmR9rr+Z+yQ6fiQZm36Fb-izsanHg23w@mail.gmail.com/
+.. [3] https://joemario.github.io/blog/2016/09/01/c2c-blog/
index f530276522904c1ddd4db4655f399c5d02ed696a..79c03bac99a294bf005041100bf15d1fd64943cc 100644 (file)
@@ -9,3 +9,4 @@ Kernel Hacking Guides
 
    hacking
    locking
+   false-sharing
index 7f5c6c3ed6c3713ca070a7705aa7b61cfd2edf19..658d37860d3974b03aea570e6c212c79a09aa491 100644 (file)
@@ -9,7 +9,7 @@ a kernel test module based on a litmus test, please see
 tools/memory-model/README.
 
 
-atomic (/atomic derectory)
+atomic (/atomic directory)
 --------------------------
 
 Atomic-RMW+mb__after_atomic-is-stronger-than-acquire.litmus
diff --git a/Documentation/litmus-tests/locking/DCL-broken.litmus b/Documentation/litmus-tests/locking/DCL-broken.litmus
new file mode 100644 (file)
index 0000000..bfb7ba4
--- /dev/null
@@ -0,0 +1,54 @@
+C DCL-broken
+
+(*
+ * Result: Sometimes
+ *
+ * This litmus test demonstrates more than just locking is required to
+ * correctly implement double-checked locking.
+ *)
+
+{
+       int flag;
+       int data;
+}
+
+P0(int *flag, int *data, spinlock_t *lck)
+{
+       int r0;
+       int r1;
+       int r2;
+
+       r0 = READ_ONCE(*flag);
+       if (r0 == 0) {
+               spin_lock(lck);
+               r1 = READ_ONCE(*flag);
+               if (r1 == 0) {
+                       WRITE_ONCE(*data, 1);
+                       WRITE_ONCE(*flag, 1);
+               }
+               spin_unlock(lck);
+       }
+       r2 = READ_ONCE(*data);
+}
+
+P1(int *flag, int *data, spinlock_t *lck)
+{
+       int r0;
+       int r1;
+       int r2;
+
+       r0 = READ_ONCE(*flag);
+       if (r0 == 0) {
+               spin_lock(lck);
+               r1 = READ_ONCE(*flag);
+               if (r1 == 0) {
+                       WRITE_ONCE(*data, 1);
+                       WRITE_ONCE(*flag, 1);
+               }
+               spin_unlock(lck);
+       }
+       r2 = READ_ONCE(*data);
+}
+
+locations [flag;data;0:r0;0:r1;1:r0;1:r1]
+exists (0:r2=0 \/ 1:r2=0)
diff --git a/Documentation/litmus-tests/locking/DCL-fixed.litmus b/Documentation/litmus-tests/locking/DCL-fixed.litmus
new file mode 100644 (file)
index 0000000..d1b60bc
--- /dev/null
@@ -0,0 +1,55 @@
+C DCL-fixed
+
+(*
+ * Result: Never
+ *
+ * This litmus test demonstrates that double-checked locking can be
+ * reliable given proper use of smp_load_acquire() and smp_store_release()
+ * in addition to the locking.
+ *)
+
+{
+       int flag;
+       int data;
+}
+
+P0(int *flag, int *data, spinlock_t *lck)
+{
+       int r0;
+       int r1;
+       int r2;
+
+       r0 = smp_load_acquire(flag);
+       if (r0 == 0) {
+               spin_lock(lck);
+               r1 = READ_ONCE(*flag);
+               if (r1 == 0) {
+                       WRITE_ONCE(*data, 1);
+                       smp_store_release(flag, 1);
+               }
+               spin_unlock(lck);
+       }
+       r2 = READ_ONCE(*data);
+}
+
+P1(int *flag, int *data, spinlock_t *lck)
+{
+       int r0;
+       int r1;
+       int r2;
+
+       r0 = smp_load_acquire(flag);
+       if (r0 == 0) {
+               spin_lock(lck);
+               r1 = READ_ONCE(*flag);
+               if (r1 == 0) {
+                       WRITE_ONCE(*data, 1);
+                       smp_store_release(flag, 1);
+               }
+               spin_unlock(lck);
+       }
+       r2 = READ_ONCE(*data);
+}
+
+locations [flag;data;0:r0;0:r1;1:r0;1:r1]
+exists (0:r2=0 \/ 1:r2=0)
diff --git a/Documentation/litmus-tests/locking/RM-broken.litmus b/Documentation/litmus-tests/locking/RM-broken.litmus
new file mode 100644 (file)
index 0000000..b7ef30c
--- /dev/null
@@ -0,0 +1,41 @@
+C RM-broken
+
+(*
+ * Result: DEADLOCK
+ *
+ * This litmus test demonstrates that the old "roach motel" approach
+ * to locking, where code can be freely moved into critical sections,
+ * cannot be used in the Linux kernel.
+ *)
+
+{
+       int x;
+       atomic_t y;
+}
+
+P0(int *x, atomic_t *y, spinlock_t *lck)
+{
+       int r2;
+
+       spin_lock(lck);
+       r2 = atomic_inc_return(y);
+       WRITE_ONCE(*x, 1);
+       spin_unlock(lck);
+}
+
+P1(int *x, atomic_t *y, spinlock_t *lck)
+{
+       int r0;
+       int r1;
+       int r2;
+
+       spin_lock(lck);
+       r0 = READ_ONCE(*x);
+       r1 = READ_ONCE(*x);
+       r2 = atomic_inc_return(y);
+       spin_unlock(lck);
+}
+
+locations [x;0:r2;1:r0;1:r1;1:r2]
+filter (1:r0=0 /\ 1:r1=1)
+exists (1:r2=1)
diff --git a/Documentation/litmus-tests/locking/RM-fixed.litmus b/Documentation/litmus-tests/locking/RM-fixed.litmus
new file mode 100644 (file)
index 0000000..b628175
--- /dev/null
@@ -0,0 +1,41 @@
+C RM-fixed
+
+(*
+ * Result: Never
+ *
+ * This litmus test demonstrates that the old "roach motel" approach
+ * to locking, where code can be freely moved into critical sections,
+ * cannot be used in the Linux kernel.
+ *)
+
+{
+       int x;
+       atomic_t y;
+}
+
+P0(int *x, atomic_t *y, spinlock_t *lck)
+{
+       int r2;
+
+       spin_lock(lck);
+       r2 = atomic_inc_return(y);
+       WRITE_ONCE(*x, 1);
+       spin_unlock(lck);
+}
+
+P1(int *x, atomic_t *y, spinlock_t *lck)
+{
+       int r0;
+       int r1;
+       int r2;
+
+       r0 = READ_ONCE(*x);
+       r1 = READ_ONCE(*x);
+       spin_lock(lck);
+       r2 = atomic_inc_return(y);
+       spin_unlock(lck);
+}
+
+locations [x;0:r2;1:r0;1:r1;1:r2]
+filter (1:r0=0 /\ 1:r1=1)
+exists (1:r2=1)
diff --git a/Documentation/m68k/buddha-driver.rst b/Documentation/m68k/buddha-driver.rst
deleted file mode 100644 (file)
index 20e4014..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-=====================================
-Amiga Buddha and Catweasel IDE Driver
-=====================================
-
-The Amiga Buddha and Catweasel IDE Driver (part of ide.c) was written by
-Geert Uytterhoeven based on the following specifications:
-
-------------------------------------------------------------------------
-
-Register map of the Buddha IDE controller and the
-Buddha-part of the Catweasel Zorro-II version
-
-The Autoconfiguration has been implemented just as Commodore
-described  in  their  manuals, no tricks have been used (for
-example leaving some address lines out of the equations...).
-If you want to configure the board yourself (for example let
-a  Linux  kernel  configure the card), look at the Commodore
-Docs.  Reading the nibbles should give this information::
-
-  Vendor number: 4626 ($1212)
-  product number: 0 (42 for Catweasel Z-II)
-  Serial number: 0
-  Rom-vector: $1000
-
-The  card  should be a Z-II board, size 64K, not for freemem
-list, Rom-Vektor is valid, no second Autoconfig-board on the
-same card, no space preference, supports "Shutup_forever".
-
-Setting  the  base address should be done in two steps, just
-as  the Amiga Kickstart does:  The lower nibble of the 8-Bit
-address is written to $4a, then the whole Byte is written to
-$48, while it doesn't matter how often you're writing to $4a
-as  long as $48 is not touched.  After $48 has been written,
-the  whole card disappears from $e8 and is mapped to the new
-address just written.  Make sure $4a is written before $48,
-otherwise your chance is only 1:16 to find the board :-).
-
-The local memory-map is even active when mapped to $e8:
-
-==============  ===========================================
-$0-$7e         Autokonfig-space, see Z-II docs.
-
-$80-$7fd       reserved
-
-$7fe           Speed-select Register: Read & Write
-               (description see further down)
-
-$800-$8ff      IDE-Select 0 (Port 0, Register set 0)
-
-$900-$9ff      IDE-Select 1 (Port 0, Register set 1)
-
-$a00-$aff      IDE-Select 2 (Port 1, Register set 0)
-
-$b00-$bff      IDE-Select 3 (Port 1, Register set 1)
-
-$c00-$cff      IDE-Select 4 (Port 2, Register set 0,
-                Catweasel only!)
-
-$d00-$dff      IDE-Select 5 (Port 3, Register set 1,
-               Catweasel only!)
-
-$e00-$eff      local expansion port, on Catweasel Z-II the
-               Catweasel registers are also mapped here.
-               Never touch, use multidisk.device!
-
-$f00           read only, Byte-access: Bit 7 shows the
-               level of the IRQ-line of IDE port 0.
-
-$f01-$f3f      mirror of $f00
-
-$f40           read only, Byte-access: Bit 7 shows the
-               level of the IRQ-line of IDE port 1.
-
-$f41-$f7f      mirror of $f40
-
-$f80           read only, Byte-access: Bit 7 shows the
-               level of the IRQ-line of IDE port 2.
-               (Catweasel only!)
-
-$f81-$fbf      mirror of $f80
-
-$fc0           write-only: Writing any value to this
-               register enables IRQs to be passed from the
-               IDE ports to the Zorro bus. This mechanism
-               has been implemented to be compatible with
-               harddisks that are either defective or have
-               a buggy firmware and pull the IRQ line up
-               while starting up. If interrupts would
-               always be passed to the bus, the computer
-               might not start up. Once enabled, this flag
-               can not be disabled again. The level of the
-               flag can not be determined by software
-               (what for? Write to me if it's necessary!).
-
-$fc1-$fff      mirror of $fc0
-
-$1000-$ffff    Buddha-Rom with offset $1000 in the rom
-               chip. The addresses $0 to $fff of the rom
-               chip cannot be read. Rom is Byte-wide and
-               mapped to even addresses.
-==============  ===========================================
-
-The  IDE ports issue an INT2.  You can read the level of the
-IRQ-lines  of  the  IDE-ports by reading from the three (two
-for  Buddha-only)  registers  $f00, $f40 and $f80.  This way
-more  than one I/O request can be handled and you can easily
-determine  what  driver  has  to serve the INT2.  Buddha and
-Catweasel  expansion  boards  can issue an INT6.  A separate
-memory  map  is available for the I/O module and the sysop's
-I/O module.
-
-The IDE ports are fed by the address lines A2 to A4, just as
-the  Amiga  1200  and  Amiga  4000  IDE ports are.  This way
-existing  drivers  can be easily ported to Buddha.  A move.l
-polls  two  words  out of the same address of IDE port since
-every  word  is  mirrored  once.  movem is not possible, but
-it's  not  necessary  either,  because  you can only speedup
-68000  systems  with  this  technique.   A 68020 system with
-fastmem is faster with move.l.
-
-If you're using the mirrored registers of the IDE-ports with
-A6=1,  the Buddha doesn't care about the speed that you have
-selected  in  the  speed  register (see further down).  With
-A6=1  (for example $840 for port 0, register set 0), a 780ns
-access  is being made.  These registers should be used for a
-command   access   to  the  harddisk/CD-Rom,  since  command
-accesses  are Byte-wide and have to be made slower according
-to the ATA-X3T9 manual.
-
-Now  for the speed-register:  The register is byte-wide, and
-only  the  upper  three  bits are used (Bits 7 to 5).  Bit 4
-must  always  be set to 1 to be compatible with later Buddha
-versions  (if  I'll  ever  update this one).  I presume that
-I'll  never use the lower four bits, but they have to be set
-to 1 by definition.
-
-The  values in this table have to be shifted 5 bits to the
-left and or'd with $1f (this sets the lower 5 bits).
-
-All  the timings have in common:  Select and IOR/IOW rise at
-the  same  time.   IOR  and  IOW have a propagation delay of
-about  30ns  to  the clocks on the Zorro bus, that's why the
-values  are no multiple of 71.  One clock-cycle is 71ns long
-(exactly 70,5 at 14,18 Mhz on PAL systems).
-
-value 0 (Default after reset)
-  497ns Select (7 clock cycles) , IOR/IOW after 172ns (2 clock cycles)
-  (same timing as the Amiga 1200 does on it's IDE port without
-  accelerator card)
-
-value 1
-  639ns Select (9 clock cycles), IOR/IOW after 243ns (3 clock cycles)
-
-value 2
-  781ns Select (11 clock cycles), IOR/IOW after 314ns (4 clock cycles)
-
-value 3
-  355ns Select (5 clock cycles), IOR/IOW after 101ns (1 clock cycle)
-
-value 4
-  355ns Select (5 clock cycles), IOR/IOW after 172ns (2 clock cycles)
-
-value 5
-  355ns Select (5 clock cycles), IOR/IOW after 243ns (3 clock cycles)
-
-value 6
-  1065ns Select (15 clock cycles), IOR/IOW after 314ns (4 clock cycles)
-
-value 7
-  355ns Select, (5 clock cycles), IOR/IOW after 101ns (1 clock cycle)
-
-When accessing IDE registers with A6=1 (for example $84x),
-the timing will always be mode 0 8-bit compatible, no matter
-what you have selected in the speed register:
-
-781ns select, IOR/IOW after 4 clock cycles (=314ns) aktive.
-
-All  the  timings with a very short select-signal (the 355ns
-fast  accesses)  depend  on the accelerator card used in the
-system:  Sometimes two more clock cycles are inserted by the
-bus  interface,  making  the  whole access 497ns long.  This
-doesn't  affect  the  reliability  of the controller nor the
-performance  of  the  card,  since  this doesn't happen very
-often.
-
-All  the  timings  are  calculated  and  only  confirmed  by
-measurements  that allowed me to count the clock cycles.  If
-the  system  is clocked by an oscillator other than 28,37516
-Mhz  (for  example  the  NTSC-frequency  28,63636 Mhz), each
-clock  cycle is shortened to a bit less than 70ns (not worth
-mentioning).   You  could think of a small performance boost
-by  overclocking  the  system,  but  you would either need a
-multisync  monitor,  or  a  graphics card, and your internal
-diskdrive would go crazy, that's why you shouldn't tune your
-Amiga this way.
-
-Giving  you  the  possibility  to  write  software  that  is
-compatible  with both the Buddha and the Catweasel Z-II, The
-Buddha  acts  just  like  a  Catweasel  Z-II  with no device
-connected  to  the  third  IDE-port.   The IRQ-register $f80
-always  shows a "no IRQ here" on the Buddha, and accesses to
-the  third  IDE  port  are  going into data's Nirwana on the
-Buddha.
-
-Jens Schönfeld february 19th, 1997
-
-updated may 27th, 1997
-
-eMail: sysop@nostlgic.tng.oche.de
diff --git a/Documentation/m68k/features.rst b/Documentation/m68k/features.rst
deleted file mode 100644 (file)
index 5107a21..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. kernel-feat:: $srctree/Documentation/features m68k
diff --git a/Documentation/m68k/index.rst b/Documentation/m68k/index.rst
deleted file mode 100644 (file)
index 0f890db..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=================
-m68k Architecture
-=================
-
-.. toctree::
-   :maxdepth: 2
-
-   kernel-options
-   buddha-driver
-
-   features
-
-.. only::  subproject and html
-
-   Indices
-   =======
-
-   * :ref:`genindex`
diff --git a/Documentation/m68k/kernel-options.rst b/Documentation/m68k/kernel-options.rst
deleted file mode 100644 (file)
index 2008a20..0000000
+++ /dev/null
@@ -1,911 +0,0 @@
-===================================
-Command Line Options for Linux/m68k
-===================================
-
-Last Update: 2 May 1999
-
-Linux/m68k version: 2.2.6
-
-Author: Roman.Hodek@informatik.uni-erlangen.de (Roman Hodek)
-
-Update: jds@kom.auc.dk (Jes Sorensen) and faq@linux-m68k.org (Chris Lawrence)
-
-0) Introduction
-===============
-
-Often I've been asked which command line options the Linux/m68k
-kernel understands, or how the exact syntax for the ... option is, or
-... about the option ... . I hope, this document supplies all the
-answers...
-
-Note that some options might be outdated, their descriptions being
-incomplete or missing. Please update the information and send in the
-patches.
-
-
-1) Overview of the Kernel's Option Processing
-=============================================
-
-The kernel knows three kinds of options on its command line:
-
-  1) kernel options
-  2) environment settings
-  3) arguments for init
-
-To which of these classes an argument belongs is determined as
-follows: If the option is known to the kernel itself, i.e. if the name
-(the part before the '=') or, in some cases, the whole argument string
-is known to the kernel, it belongs to class 1. Otherwise, if the
-argument contains an '=', it is of class 2, and the definition is put
-into init's environment. All other arguments are passed to init as
-command line options.
-
-This document describes the valid kernel options for Linux/m68k in
-the version mentioned at the start of this file. Later revisions may
-add new such options, and some may be missing in older versions.
-
-In general, the value (the part after the '=') of an option is a
-list of values separated by commas. The interpretation of these values
-is up to the driver that "owns" the option. This association of
-options with drivers is also the reason that some are further
-subdivided.
-
-
-2) General Kernel Options
-=========================
-
-2.1) root=
-----------
-
-:Syntax: root=/dev/<device>
-:or:     root=<hex_number>
-
-This tells the kernel which device it should mount as the root
-filesystem. The device must be a block device with a valid filesystem
-on it.
-
-The first syntax gives the device by name. These names are converted
-into a major/minor number internally in the kernel in an unusual way.
-Normally, this "conversion" is done by the device files in /dev, but
-this isn't possible here, because the root filesystem (with /dev)
-isn't mounted yet... So the kernel parses the name itself, with some
-hardcoded name to number mappings. The name must always be a
-combination of two or three letters, followed by a decimal number.
-Valid names are::
-
-  /dev/ram: -> 0x0100 (initial ramdisk)
-  /dev/hda: -> 0x0300 (first IDE disk)
-  /dev/hdb: -> 0x0340 (second IDE disk)
-  /dev/sda: -> 0x0800 (first SCSI disk)
-  /dev/sdb: -> 0x0810 (second SCSI disk)
-  /dev/sdc: -> 0x0820 (third SCSI disk)
-  /dev/sdd: -> 0x0830 (forth SCSI disk)
-  /dev/sde: -> 0x0840 (fifth SCSI disk)
-  /dev/fd : -> 0x0200 (floppy disk)
-
-The name must be followed by a decimal number, that stands for the
-partition number. Internally, the value of the number is just
-added to the device number mentioned in the table above. The
-exceptions are /dev/ram and /dev/fd, where /dev/ram refers to an
-initial ramdisk loaded by your bootstrap program (please consult the
-instructions for your bootstrap program to find out how to load an
-initial ramdisk). As of kernel version 2.0.18 you must specify
-/dev/ram as the root device if you want to boot from an initial
-ramdisk. For the floppy devices, /dev/fd, the number stands for the
-floppy drive number (there are no partitions on floppy disks). I.e.,
-/dev/fd0 stands for the first drive, /dev/fd1 for the second, and so
-on. Since the number is just added, you can also force the disk format
-by adding a number greater than 3. If you look into your /dev
-directory, use can see the /dev/fd0D720 has major 2 and minor 16. You
-can specify this device for the root FS by writing "root=/dev/fd16" on
-the kernel command line.
-
-[Strange and maybe uninteresting stuff ON]
-
-This unusual translation of device names has some strange
-consequences: If, for example, you have a symbolic link from /dev/fd
-to /dev/fd0D720 as an abbreviation for floppy driver #0 in DD format,
-you cannot use this name for specifying the root device, because the
-kernel cannot see this symlink before mounting the root FS and it
-isn't in the table above. If you use it, the root device will not be
-set at all, without an error message. Another example: You cannot use a
-partition on e.g. the sixth SCSI disk as the root filesystem, if you
-want to specify it by name. This is, because only the devices up to
-/dev/sde are in the table above, but not /dev/sdf. Although, you can
-use the sixth SCSI disk for the root FS, but you have to specify the
-device by number... (see below). Or, even more strange, you can use the
-fact that there is no range checking of the partition number, and your
-knowledge that each disk uses 16 minors, and write "root=/dev/sde17"
-(for /dev/sdf1).
-
-[Strange and maybe uninteresting stuff OFF]
-
-If the device containing your root partition isn't in the table
-above, you can also specify it by major and minor numbers. These are
-written in hex, with no prefix and no separator between. E.g., if you
-have a CD with contents appropriate as a root filesystem in the first
-SCSI CD-ROM drive, you boot from it by "root=0b00". Here, hex "0b" =
-decimal 11 is the major of SCSI CD-ROMs, and the minor 0 stands for
-the first of these. You can find out all valid major numbers by
-looking into include/linux/major.h.
-
-In addition to major and minor numbers, if the device containing your
-root partition uses a partition table format with unique partition
-identifiers, then you may use them.  For instance,
-"root=PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF".  It is also
-possible to reference another partition on the same device using a
-known partition UUID as the starting point.  For example,
-if partition 5 of the device has the UUID of
-00112233-4455-6677-8899-AABBCCDDEEFF then partition 3 may be found as
-follows:
-
-  PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF/PARTNROFF=-2
-
-Authoritative information can be found in
-"Documentation/admin-guide/kernel-parameters.rst".
-
-
-2.2) ro, rw
------------
-
-:Syntax: ro
-:or:     rw
-
-These two options tell the kernel whether it should mount the root
-filesystem read-only or read-write. The default is read-only, except
-for ramdisks, which default to read-write.
-
-
-2.3) debug
-----------
-
-:Syntax: debug
-
-This raises the kernel log level to 10 (the default is 7). This is the
-same level as set by the "dmesg" command, just that the maximum level
-selectable by dmesg is 8.
-
-
-2.4) debug=
------------
-
-:Syntax: debug=<device>
-
-This option causes certain kernel messages be printed to the selected
-debugging device. This can aid debugging the kernel, since the
-messages can be captured and analyzed on some other machine. Which
-devices are possible depends on the machine type. There are no checks
-for the validity of the device name. If the device isn't implemented,
-nothing happens.
-
-Messages logged this way are in general stack dumps after kernel
-memory faults or bad kernel traps, and kernel panics. To be exact: all
-messages of level 0 (panic messages) and all messages printed while
-the log level is 8 or more (their level doesn't matter). Before stack
-dumps, the kernel sets the log level to 10 automatically. A level of
-at least 8 can also be set by the "debug" command line option (see
-2.3) and at run time with "dmesg -n 8".
-
-Devices possible for Amiga:
-
- - "ser":
-         built-in serial port; parameters: 9600bps, 8N1
- - "mem":
-         Save the messages to a reserved area in chip mem. After
-          rebooting, they can be read under AmigaOS with the tool
-          'dmesg'.
-
-Devices possible for Atari:
-
- - "ser1":
-          ST-MFP serial port ("Modem1"); parameters: 9600bps, 8N1
- - "ser2":
-          SCC channel B serial port ("Modem2"); parameters: 9600bps, 8N1
- - "ser" :
-          default serial port
-           This is "ser2" for a Falcon, and "ser1" for any other machine
- - "midi":
-          The MIDI port; parameters: 31250bps, 8N1
- - "par" :
-          parallel port
-
-           The printing routine for this implements a timeout for the
-           case there's no printer connected (else the kernel would
-           lock up). The timeout is not exact, but usually a few
-           seconds.
-
-
-2.6) ramdisk_size=
-------------------
-
-:Syntax: ramdisk_size=<size>
-
-This option instructs the kernel to set up a ramdisk of the given
-size in KBytes. Do not use this option if the ramdisk contents are
-passed by bootstrap! In this case, the size is selected automatically
-and should not be overwritten.
-
-The only application is for root filesystems on floppy disks, that
-should be loaded into memory. To do that, select the corresponding
-size of the disk as ramdisk size, and set the root device to the disk
-drive (with "root=").
-
-
-2.7) swap=
-
-  I can't find any sign of this option in 2.2.6.
-
-2.8) buff=
------------
-
-  I can't find any sign of this option in 2.2.6.
-
-
-3) General Device Options (Amiga and Atari)
-===========================================
-
-3.1) ether=
------------
-
-:Syntax: ether=[<irq>[,<base_addr>[,<mem_start>[,<mem_end>]]]],<dev-name>
-
-<dev-name> is the name of a net driver, as specified in
-drivers/net/Space.c in the Linux source. Most prominent are eth0, ...
-eth3, sl0, ... sl3, ppp0, ..., ppp3, dummy, and lo.
-
-The non-ethernet drivers (sl, ppp, dummy, lo) obviously ignore the
-settings by this options. Also, the existing ethernet drivers for
-Linux/m68k (ariadne, a2065, hydra) don't use them because Zorro boards
-are really Plug-'n-Play, so the "ether=" option is useless altogether
-for Linux/m68k.
-
-
-3.2) hd=
---------
-
-:Syntax: hd=<cylinders>,<heads>,<sectors>
-
-This option sets the disk geometry of an IDE disk. The first hd=
-option is for the first IDE disk, the second for the second one.
-(I.e., you can give this option twice.) In most cases, you won't have
-to use this option, since the kernel can obtain the geometry data
-itself. It exists just for the case that this fails for one of your
-disks.
-
-
-3.3) max_scsi_luns=
--------------------
-
-:Syntax: max_scsi_luns=<n>
-
-Sets the maximum number of LUNs (logical units) of SCSI devices to
-be scanned. Valid values for <n> are between 1 and 8. Default is 8 if
-"Probe all LUNs on each SCSI device" was selected during the kernel
-configuration, else 1.
-
-
-3.4) st=
---------
-
-:Syntax: st=<buffer_size>,[<write_thres>,[<max_buffers>]]
-
-Sets several parameters of the SCSI tape driver. <buffer_size> is
-the number of 512-byte buffers reserved for tape operations for each
-device. <write_thres> sets the number of blocks which must be filled
-to start an actual write operation to the tape. Maximum value is the
-total number of buffers. <max_buffer> limits the total number of
-buffers allocated for all tape devices.
-
-
-3.5) dmasound=
---------------
-
-:Syntax: dmasound=[<buffers>,<buffer-size>[,<catch-radius>]]
-
-This option controls some configurations of the Linux/m68k DMA sound
-driver (Amiga and Atari): <buffers> is the number of buffers you want
-to use (minimum 4, default 4), <buffer-size> is the size of each
-buffer in kilobytes (minimum 4, default 32) and <catch-radius> says
-how much percent of error will be tolerated when setting a frequency
-(maximum 10, default 0). For example with 3% you can play 8000Hz
-AU-Files on the Falcon with its hardware frequency of 8195Hz and thus
-don't need to expand the sound.
-
-
-
-4) Options for Atari Only
-=========================
-
-4.1) video=
------------
-
-:Syntax: video=<fbname>:<sub-options...>
-
-The <fbname> parameter specifies the name of the frame buffer,
-eg. most atari users will want to specify `atafb` here. The
-<sub-options> is a comma-separated list of the sub-options listed
-below.
-
-NB:
-    Please notice that this option was renamed from `atavideo` to
-    `video` during the development of the 1.3.x kernels, thus you
-    might need to update your boot-scripts if upgrading to 2.x from
-    an 1.2.x kernel.
-
-NBB:
-    The behavior of video= was changed in 2.1.57 so the recommended
-    option is to specify the name of the frame buffer.
-
-4.1.1) Video Mode
------------------
-
-This sub-option may be any of the predefined video modes, as listed
-in atari/atafb.c in the Linux/m68k source tree. The kernel will
-activate the given video mode at boot time and make it the default
-mode, if the hardware allows. Currently defined names are:
-
- - stlow           : 320x200x4
- - stmid, default5 : 640x200x2
- - sthigh, default4: 640x400x1
- - ttlow           : 320x480x8, TT only
- - ttmid, default1 : 640x480x4, TT only
- - tthigh, default2: 1280x960x1, TT only
- - vga2            : 640x480x1, Falcon only
- - vga4            : 640x480x2, Falcon only
- - vga16, default3 : 640x480x4, Falcon only
- - vga256          : 640x480x8, Falcon only
- - falh2           : 896x608x1, Falcon only
- - falh16          : 896x608x4, Falcon only
-
-If no video mode is given on the command line, the kernel tries the
-modes names "default<n>" in turn, until one is possible with the
-hardware in use.
-
-A video mode setting doesn't make sense, if the external driver is
-activated by a "external:" sub-option.
-
-4.1.2) inverse
---------------
-
-Invert the display. This affects only text consoles.
-Usually, the background is chosen to be black. With this
-option, you can make the background white.
-
-4.1.3) font
------------
-
-:Syntax: font:<fontname>
-
-Specify the font to use in text modes. Currently you can choose only
-between `VGA8x8`, `VGA8x16` and `PEARL8x8`. `VGA8x8` is default, if the
-vertical size of the display is less than 400 pixel rows. Otherwise, the
-`VGA8x16` font is the default.
-
-4.1.4) `hwscroll_`
-------------------
-
-:Syntax: `hwscroll_<n>`
-
-The number of additional lines of video memory to reserve for
-speeding up the scrolling ("hardware scrolling"). Hardware scrolling
-is possible only if the kernel can set the video base address in steps
-fine enough. This is true for STE, MegaSTE, TT, and Falcon. It is not
-possible with plain STs and graphics cards (The former because the
-base address must be on a 256 byte boundary there, the latter because
-the kernel doesn't know how to set the base address at all.)
-
-By default, <n> is set to the number of visible text lines on the
-display. Thus, the amount of video memory is doubled, compared to no
-hardware scrolling. You can turn off the hardware scrolling altogether
-by setting <n> to 0.
-
-4.1.5) internal:
-----------------
-
-:Syntax: internal:<xres>;<yres>[;<xres_max>;<yres_max>;<offset>]
-
-This option specifies the capabilities of some extended internal video
-hardware, like e.g. OverScan. <xres> and <yres> give the (extended)
-dimensions of the screen.
-
-If your OverScan needs a black border, you have to write the last
-three arguments of the "internal:". <xres_max> is the maximum line
-length the hardware allows, <yres_max> the maximum number of lines.
-<offset> is the offset of the visible part of the screen memory to its
-physical start, in bytes.
-
-Often, extended interval video hardware has to be activated somehow.
-For this, see the "sw_*" options below.
-
-4.1.6) external:
-----------------
-
-:Syntax:
-  external:<xres>;<yres>;<depth>;<org>;<scrmem>[;<scrlen>[;<vgabase>
-  [;<colw>[;<coltype>[;<xres_virtual>]]]]]
-
-.. I had to break this line...
-
-This is probably the most complicated parameter... It specifies that
-you have some external video hardware (a graphics board), and how to
-use it under Linux/m68k. The kernel cannot know more about the hardware
-than you tell it here! The kernel also is unable to set or change any
-video modes, since it doesn't know about any board internal. So, you
-have to switch to that video mode before you start Linux, and cannot
-switch to another mode once Linux has started.
-
-The first 3 parameters of this sub-option should be obvious: <xres>,
-<yres> and <depth> give the dimensions of the screen and the number of
-planes (depth). The depth is the logarithm to base 2 of the number
-of colors possible. (Or, the other way round: The number of colors is
-2^depth).
-
-You have to tell the kernel furthermore how the video memory is
-organized. This is done by a letter as <org> parameter:
-
- 'n':
-      "normal planes", i.e. one whole plane after another
- 'i':
-      "interleaved planes", i.e. 16 bit of the first plane, than 16 bit
-      of the next, and so on... This mode is used only with the
-      built-in Atari video modes, I think there is no card that
-      supports this mode.
- 'p':
-      "packed pixels", i.e. <depth> consecutive bits stand for all
-      planes of one pixel; this is the most common mode for 8 planes
-      (256 colors) on graphic cards
- 't':
-      "true color" (more or less packed pixels, but without a color
-      lookup table); usually depth is 24
-
-For monochrome modes (i.e., <depth> is 1), the <org> letter has a
-different meaning:
-
- 'n':
-      normal colors, i.e. 0=white, 1=black
- 'i':
-      inverted colors, i.e. 0=black, 1=white
-
-The next important information about the video hardware is the base
-address of the video memory. That is given in the <scrmem> parameter,
-as a hexadecimal number with a "0x" prefix. You have to find out this
-address in the documentation of your hardware.
-
-The next parameter, <scrlen>, tells the kernel about the size of the
-video memory. If it's missing, the size is calculated from <xres>,
-<yres>, and <depth>. For now, it is not useful to write a value here.
-It would be used only for hardware scrolling (which isn't possible
-with the external driver, because the kernel cannot set the video base
-address), or for virtual resolutions under X (which the X server
-doesn't support yet). So, it's currently best to leave this field
-empty, either by ending the "external:" after the video address or by
-writing two consecutive semicolons, if you want to give a <vgabase>
-(it is allowed to leave this parameter empty).
-
-The <vgabase> parameter is optional. If it is not given, the kernel
-cannot read or write any color registers of the video hardware, and
-thus you have to set appropriate colors before you start Linux. But if
-your card is somehow VGA compatible, you can tell the kernel the base
-address of the VGA register set, so it can change the color lookup
-table. You have to look up this address in your board's documentation.
-To avoid misunderstandings: <vgabase> is the _base_ address, i.e. a 4k
-aligned address. For read/writing the color registers, the kernel
-uses the addresses vgabase+0x3c7...vgabase+0x3c9. The <vgabase>
-parameter is written in hexadecimal with a "0x" prefix, just as
-<scrmem>.
-
-<colw> is meaningful only if <vgabase> is specified. It tells the
-kernel how wide each of the color register is, i.e. the number of bits
-per single color (red/green/blue). Default is 6, another quite usual
-value is 8.
-
-Also <coltype> is used together with <vgabase>. It tells the kernel
-about the color register model of your gfx board. Currently, the types
-"vga" (which is also the default) and "mv300" (SANG MV300) are
-implemented.
-
-Parameter <xres_virtual> is required for ProMST or ET4000 cards where
-the physical linelength differs from the visible length. With ProMST,
-xres_virtual must be set to 2048. For ET4000, xres_virtual depends on the
-initialisation of the video-card.
-If you're missing a corresponding yres_virtual: the external part is legacy,
-therefore we don't support hardware-dependent functions like hardware-scroll,
-panning or blanking.
-
-4.1.7) eclock:
---------------
-
-The external pixel clock attached to the Falcon VIDEL shifter. This
-currently works only with the ScreenWonder!
-
-4.1.8) monitorcap:
--------------------
-
-:Syntax: monitorcap:<vmin>;<vmax>;<hmin>;<hmax>
-
-This describes the capabilities of a multisync monitor. Don't use it
-with a fixed-frequency monitor! For now, only the Falcon frame buffer
-uses the settings of "monitorcap:".
-
-<vmin> and <vmax> are the minimum and maximum, resp., vertical frequencies
-your monitor can work with, in Hz. <hmin> and <hmax> are the same for
-the horizontal frequency, in kHz.
-
-  The defaults are 58;62;31;32 (VGA compatible).
-
-  The defaults for TV/SC1224/SC1435 cover both PAL and NTSC standards.
-
-4.1.9) keep
-------------
-
-If this option is given, the framebuffer device doesn't do any video
-mode calculations and settings on its own. The only Atari fb device
-that does this currently is the Falcon.
-
-What you reach with this: Settings for unknown video extensions
-aren't overridden by the driver, so you can still use the mode found
-when booting, when the driver doesn't know to set this mode itself.
-But this also means, that you can't switch video modes anymore...
-
-An example where you may want to use "keep" is the ScreenBlaster for
-the Falcon.
-
-
-4.2) atamouse=
---------------
-
-:Syntax: atamouse=<x-threshold>,[<y-threshold>]
-
-With this option, you can set the mouse movement reporting threshold.
-This is the number of pixels of mouse movement that have to accumulate
-before the IKBD sends a new mouse packet to the kernel. Higher values
-reduce the mouse interrupt load and thus reduce the chance of keyboard
-overruns. Lower values give a slightly faster mouse responses and
-slightly better mouse tracking.
-
-You can set the threshold in x and y separately, but usually this is
-of little practical use. If there's just one number in the option, it
-is used for both dimensions. The default value is 2 for both
-thresholds.
-
-
-4.3) ataflop=
--------------
-
-:Syntax: ataflop=<drive type>[,<trackbuffering>[,<steprateA>[,<steprateB>]]]
-
-   The drive type may be 0, 1, or 2, for DD, HD, and ED, resp. This
-   setting affects how many buffers are reserved and which formats are
-   probed (see also below). The default is 1 (HD). Only one drive type
-   can be selected. If you have two disk drives, select the "better"
-   type.
-
-   The second parameter <trackbuffer> tells the kernel whether to use
-   track buffering (1) or not (0). The default is machine-dependent:
-   no for the Medusa and yes for all others.
-
-   With the two following parameters, you can change the default
-   steprate used for drive A and B, resp.
-
-
-4.4) atascsi=
--------------
-
-:Syntax: atascsi=<can_queue>[,<cmd_per_lun>[,<scat-gat>[,<host-id>[,<tagged>]]]]
-
-This option sets some parameters for the Atari native SCSI driver.
-Generally, any number of arguments can be omitted from the end. And
-for each of the numbers, a negative value means "use default". The
-defaults depend on whether TT-style or Falcon-style SCSI is used.
-Below, defaults are noted as n/m, where the first value refers to
-TT-SCSI and the latter to Falcon-SCSI. If an illegal value is given
-for one parameter, an error message is printed and that one setting is
-ignored (others aren't affected).
-
-  <can_queue>:
-    This is the maximum number of SCSI commands queued internally to the
-    Atari SCSI driver. A value of 1 effectively turns off the driver
-    internal multitasking (if it causes problems). Legal values are >=
-    1. <can_queue> can be as high as you like, but values greater than
-    <cmd_per_lun> times the number of SCSI targets (LUNs) you have
-    don't make sense. Default: 16/8.
-
-  <cmd_per_lun>:
-    Maximum number of SCSI commands issued to the driver for one
-    logical unit (LUN, usually one SCSI target). Legal values start
-    from 1. If tagged queuing (see below) is not used, values greater
-    than 2 don't make sense, but waste memory. Otherwise, the maximum
-    is the number of command tags available to the driver (currently
-    32). Default: 8/1. (Note: Values > 1 seem to cause problems on a
-    Falcon, cause not yet known.)
-
-    The <cmd_per_lun> value at a great part determines the amount of
-    memory SCSI reserves for itself. The formula is rather
-    complicated, but I can give you some hints:
-
-      no scatter-gather:
-       cmd_per_lun * 232 bytes
-      full scatter-gather:
-       cmd_per_lun * approx. 17 Kbytes
-
-  <scat-gat>:
-    Size of the scatter-gather table, i.e. the number of requests
-    consecutive on the disk that can be merged into one SCSI command.
-    Legal values are between 0 and 255. Default: 255/0. Note: This
-    value is forced to 0 on a Falcon, since scatter-gather isn't
-    possible with the ST-DMA. Not using scatter-gather hurts
-    performance significantly.
-
-  <host-id>:
-    The SCSI ID to be used by the initiator (your Atari). This is
-    usually 7, the highest possible ID. Every ID on the SCSI bus must
-    be unique. Default: determined at run time: If the NV-RAM checksum
-    is valid, and bit 7 in byte 30 of the NV-RAM is set, the lower 3
-    bits of this byte are used as the host ID. (This method is defined
-    by Atari and also used by some TOS HD drivers.) If the above
-    isn't given, the default ID is 7. (both, TT and Falcon).
-
-  <tagged>:
-    0 means turn off tagged queuing support, all other values > 0 mean
-    use tagged queuing for targets that support it. Default: currently
-    off, but this may change when tagged queuing handling has been
-    proved to be reliable.
-
-    Tagged queuing means that more than one command can be issued to
-    one LUN, and the SCSI device itself orders the requests so they
-    can be performed in optimal order. Not all SCSI devices support
-    tagged queuing (:-().
-
-4.5 switches=
--------------
-
-:Syntax: switches=<list of switches>
-
-With this option you can switch some hardware lines that are often
-used to enable/disable certain hardware extensions. Examples are
-OverScan, overclocking, ...
-
-The <list of switches> is a comma-separated list of the following
-items:
-
-  ikbd:
-       set RTS of the keyboard ACIA high
-  midi:
-       set RTS of the MIDI ACIA high
-  snd6:
-       set bit 6 of the PSG port A
-  snd7:
-       set bit 6 of the PSG port A
-
-It doesn't make sense to mention a switch more than once (no
-difference to only once), but you can give as many switches as you
-want to enable different features. The switch lines are set as early
-as possible during kernel initialization (even before determining the
-present hardware.)
-
-All of the items can also be prefixed with `ov_`, i.e. `ov_ikbd`,
-`ov_midi`, ... These options are meant for switching on an OverScan
-video extension. The difference to the bare option is that the
-switch-on is done after video initialization, and somehow synchronized
-to the HBLANK. A speciality is that ov_ikbd and ov_midi are switched
-off before rebooting, so that OverScan is disabled and TOS boots
-correctly.
-
-If you give an option both, with and without the `ov_` prefix, the
-earlier initialization (`ov_`-less) takes precedence. But the
-switching-off on reset still happens in this case.
-
-5) Options for Amiga Only:
-==========================
-
-5.1) video=
------------
-
-:Syntax: video=<fbname>:<sub-options...>
-
-The <fbname> parameter specifies the name of the frame buffer, valid
-options are `amifb`, `cyber`, 'virge', `retz3` and `clgen`, provided
-that the respective frame buffer devices have been compiled into the
-kernel (or compiled as loadable modules). The behavior of the <fbname>
-option was changed in 2.1.57 so it is now recommended to specify this
-option.
-
-The <sub-options> is a comma-separated list of the sub-options listed
-below. This option is organized similar to the Atari version of the
-"video"-option (4.1), but knows fewer sub-options.
-
-5.1.1) video mode
------------------
-
-Again, similar to the video mode for the Atari (see 4.1.1). Predefined
-modes depend on the used frame buffer device.
-
-OCS, ECS and AGA machines all use the color frame buffer. The following
-predefined video modes are available:
-
-NTSC modes:
- - ntsc            : 640x200, 15 kHz, 60 Hz
- - ntsc-lace       : 640x400, 15 kHz, 60 Hz interlaced
-
-PAL modes:
- - pal             : 640x256, 15 kHz, 50 Hz
- - pal-lace        : 640x512, 15 kHz, 50 Hz interlaced
-
-ECS modes:
- - multiscan       : 640x480, 29 kHz, 57 Hz
- - multiscan-lace  : 640x960, 29 kHz, 57 Hz interlaced
- - euro36          : 640x200, 15 kHz, 72 Hz
- - euro36-lace     : 640x400, 15 kHz, 72 Hz interlaced
- - euro72          : 640x400, 29 kHz, 68 Hz
- - euro72-lace     : 640x800, 29 kHz, 68 Hz interlaced
- - super72         : 800x300, 23 kHz, 70 Hz
- - super72-lace    : 800x600, 23 kHz, 70 Hz interlaced
- - dblntsc-ff      : 640x400, 27 kHz, 57 Hz
- - dblntsc-lace    : 640x800, 27 kHz, 57 Hz interlaced
- - dblpal-ff       : 640x512, 27 kHz, 47 Hz
- - dblpal-lace     : 640x1024, 27 kHz, 47 Hz interlaced
- - dblntsc         : 640x200, 27 kHz, 57 Hz doublescan
- - dblpal          : 640x256, 27 kHz, 47 Hz doublescan
-
-VGA modes:
- - vga             : 640x480, 31 kHz, 60 Hz
- - vga70           : 640x400, 31 kHz, 70 Hz
-
-Please notice that the ECS and VGA modes require either an ECS or AGA
-chipset, and that these modes are limited to 2-bit color for the ECS
-chipset and 8-bit color for the AGA chipset.
-
-5.1.2) depth
-------------
-
-:Syntax: depth:<nr. of bit-planes>
-
-Specify the number of bit-planes for the selected video-mode.
-
-5.1.3) inverse
---------------
-
-Use inverted display (black on white). Functionally the same as the
-"inverse" sub-option for the Atari.
-
-5.1.4) font
------------
-
-:Syntax: font:<fontname>
-
-Specify the font to use in text modes. Functionally the same as the
-"font" sub-option for the Atari, except that `PEARL8x8` is used instead
-of `VGA8x8` if the vertical size of the display is less than 400 pixel
-rows.
-
-5.1.5) monitorcap:
--------------------
-
-:Syntax: monitorcap:<vmin>;<vmax>;<hmin>;<hmax>
-
-This describes the capabilities of a multisync monitor. For now, only
-the color frame buffer uses the settings of "monitorcap:".
-
-<vmin> and <vmax> are the minimum and maximum, resp., vertical frequencies
-your monitor can work with, in Hz. <hmin> and <hmax> are the same for
-the horizontal frequency, in kHz.
-
-The defaults are 50;90;15;38 (Generic Amiga multisync monitor).
-
-
-5.2) fd_def_df0=
-----------------
-
-:Syntax: fd_def_df0=<value>
-
-Sets the df0 value for "silent" floppy drives. The value should be in
-hexadecimal with "0x" prefix.
-
-
-5.3) wd33c93=
--------------
-
-:Syntax: wd33c93=<sub-options...>
-
-These options affect the A590/A2091, A3000 and GVP Series II SCSI
-controllers.
-
-The <sub-options> is a comma-separated list of the sub-options listed
-below.
-
-5.3.1) nosync
--------------
-
-:Syntax: nosync:bitmask
-
-bitmask is a byte where the 1st 7 bits correspond with the 7
-possible SCSI devices. Set a bit to prevent sync negotiation on that
-device. To maintain backwards compatibility, a command-line such as
-"wd33c93=255" will be automatically translated to
-"wd33c93=nosync:0xff". The default is to disable sync negotiation for
-all devices, eg. nosync:0xff.
-
-5.3.2) period
--------------
-
-:Syntax: period:ns
-
-`ns` is the minimum # of nanoseconds in a SCSI data transfer
-period. Default is 500; acceptable values are 250 - 1000.
-
-5.3.3) disconnect
------------------
-
-:Syntax: disconnect:x
-
-Specify x = 0 to never allow disconnects, 2 to always allow them.
-x = 1 does 'adaptive' disconnects, which is the default and generally
-the best choice.
-
-5.3.4) debug
-------------
-
-:Syntax: debug:x
-
-If `DEBUGGING_ON` is defined, x is a bit mask that causes various
-types of debug output to printed - see the DB_xxx defines in
-wd33c93.h.
-
-5.3.5) clock
-------------
-
-:Syntax: clock:x
-
-x = clock input in MHz for WD33c93 chip. Normal values would be from
-8 through 20. The default value depends on your hostadapter(s),
-default for the A3000 internal controller is 14, for the A2091 it's 8
-and for the GVP hostadapters it's either 8 or 14, depending on the
-hostadapter and the SCSI-clock jumper present on some GVP
-hostadapters.
-
-5.3.6) next
------------
-
-No argument. Used to separate blocks of keywords when there's more
-than one wd33c93-based host adapter in the system.
-
-5.3.7) nodma
-------------
-
-:Syntax: nodma:x
-
-If x is 1 (or if the option is just written as "nodma"), the WD33c93
-controller will not use DMA (= direct memory access) to access the
-Amiga's memory.  This is useful for some systems (like A3000's and
-A4000's with the A3640 accelerator, revision 3.0) that have problems
-using DMA to chip memory.  The default is 0, i.e. to use DMA if
-possible.
-
-
-5.4) gvp11=
------------
-
-:Syntax: gvp11=<addr-mask>
-
-The earlier versions of the GVP driver did not handle DMA
-address-mask settings correctly which made it necessary for some
-people to use this option, in order to get their GVP controller
-running under Linux. These problems have hopefully been solved and the
-use of this option is now highly unrecommended!
-
-Incorrect use can lead to unpredictable behavior, so please only use
-this option if you *know* what you are doing and have a reason to do
-so. In any case if you experience problems and need to use this
-option, please inform us about it by mailing to the Linux/68k kernel
-mailing list.
-
-The address mask set by this option specifies which addresses are
-valid for DMA with the GVP Series II SCSI controller. An address is
-valid, if no bits are set except the bits that are set in the mask,
-too.
-
-Some versions of the GVP can only DMA into a 24 bit address range,
-some can address a 25 bit address range while others can use the whole
-32 bit address range for DMA. The correct setting depends on your
-controller and should be autodetected by the driver. An example is the
-24 bit region which is specified by a mask of 0x00fffffe.
index 09f988e7fa719e62a598e1846f112db002a851eb..85800ce95ae5fccc4452626a1fada16d8961b84a 100644 (file)
@@ -213,11 +213,7 @@ point rather than some random spot.  If your upstream-bound branch has
 emptied entirely into the mainline during the merge window, you can pull it
 forward with a command like::
 
-  git merge v5.2-rc1^0
-
-The "^0" will cause Git to do a fast-forward merge (which should be
-possible in this situation), thus avoiding the addition of a spurious merge
-commit.
+  git merge --ff-only v5.2-rc1
 
 The guidelines laid out above are just that: guidelines.  There will always
 be situations that call out for a different solution, and these guidelines
index 3d05d64de9b463ac1caa68c5d1d46487ab9f75bc..d9c2b0f01dcd0fc1a71c029c98ecdbbd9c790311 100644 (file)
@@ -5,10 +5,10 @@ Hugetlbfs Reservation
 Overview
 ========
 
-Huge pages as described at Documentation/mm/hugetlbpage.rst are typically
-preallocated for application use.  These huge pages are instantiated in a
-task's address space at page fault time if the VMA indicates huge pages are
-to be used.  If no huge page exists at page fault time, the task is sent
+Huge pages as described at Documentation/admin-guide/mm/hugetlbpage.rst are
+typically preallocated for application use.  These huge pages are instantiated
+in a task's address space at page fault time if the VMA indicates huge pages
+are to be used.  If no huge page exists at page fault time, the task is sent
 a SIGBUS and often dies an unhappy death.  Shortly after huge page support
 was added, it was determined that it would be better to detect a shortage
 of huge pages at mmap() time.  The idea is that if there were not enough
index f9d7ea4b9dca7fd6b81fba0d653186e88d0c607b..531e73b003ddd0f33275eebe522efa72d5e41655 100644 (file)
@@ -19,7 +19,7 @@ a bank of memory very suitable for DMA near peripheral devices.
 
 Each bank is called a node and the concept is represented under Linux by a
 ``struct pglist_data`` even if the architecture is UMA. This structure is
-always referenced to by it's typedef ``pg_data_t``. ``A pg_data_t`` structure
+always referenced by its typedef ``pg_data_t``. A ``pg_data_t`` structure
 for a particular node can be referenced by ``NODE_DATA(nid)`` macro where
 ``nid`` is the ID of that node.
 
@@ -66,7 +66,7 @@ one of the types described below.
   also populated on boot using one of ``kernelcore``, ``movablecore`` and
   ``movable_node`` kernel command line parameters. See
   Documentation/mm/page_migration.rst and
-  Documentation/admin-guide/mm/memory_hotplug.rst for additional details.
+  Documentation/admin-guide/mm/memory-hotplug.rst for additional details.
 
 * ``ZONE_DEVICE`` represents memory residing on devices such as PMEM and GPU.
   It has different characteristics than RAM zone types and it exists to provide
@@ -114,6 +114,25 @@ RAM equally split between two nodes, there will be ``ZONE_DMA32``,
   |  DMA32  |  NORMAL  |  MOVABLE  | |   NORMAL   |   MOVABLE   |
   +---------+----------+-----------+ +------------+-------------+
 
+
+Memory banks may belong to interleaving nodes. In the example below an x86
+machine has 16 Gbytes of RAM in 4 memory banks, even banks belong to node 0
+and odd banks belong to node 1::
+
+
+  0              4G              8G             12G            16G
+  +-------------+ +-------------+ +-------------+ +-------------+
+  |    node 0   | |    node 1   | |    node 0   | |    node 1   |
+  +-------------+ +-------------+ +-------------+ +-------------+
+
+  0   16M      4G
+  +-----+-------+ +-------------+ +-------------+ +-------------+
+  | DMA | DMA32 | |    NORMAL   | |    NORMAL   | |    NORMAL   |
+  +-----+-------+ +-------------+ +-------------+ +-------------+
+
+In this case node 0 will span from 0 to 12 Gbytes and node 1 will span from
+4 to 16 Gbytes.
+
 .. _nodes:
 
 Nodes
index 64d127bfc221fe243bbfb6e6758a547c6877585a..a3c26d587752fe04f34739f266c5f5416d431c9b 100644 (file)
@@ -39,13 +39,12 @@ With CONFIG_ZSMALLOC_STAT, we could see zsmalloc internal information via
 
  # cat /sys/kernel/debug/zsmalloc/zram0/classes
 
- class  size almost_full almost_empty obj_allocated   obj_used pages_used pages_per_zspage
+ class  size       10%       20%       30%       40%       50%       60%       70%       80%       90%       99%      100% obj_allocated   obj_used pages_used pages_per_zspage freeable
     ...
     ...
-     9   176           0            1           186        129          8                4
-    10   192           1            0          2880       2872        135                3
-    11   208           0            1           819        795         42                2
-    12   224           0            1           219        159         12                4
+    30   512         0        12         4         1         0         1         0         0         1         0       414          3464       3346        433                1       14
+    31   528         2         7         2         2         1         0         1         0         0         2       117          4154       3793        536                4       44
+    32   544         6         3         4         1         2         1         0         0         0         1       260          4170       3965        556                2       26
     ...
     ...
 
@@ -54,10 +53,28 @@ class
        index
 size
        object size zspage stores
-almost_empty
-       the number of ZS_ALMOST_EMPTY zspages(see below)
-almost_full
-       the number of ZS_ALMOST_FULL zspages(see below)
+10%
+       the number of zspages with usage ratio less than 10% (see below)
+20%
+       the number of zspages with usage ratio between 10% and 20%
+30%
+       the number of zspages with usage ratio between 20% and 30%
+40%
+       the number of zspages with usage ratio between 30% and 40%
+50%
+       the number of zspages with usage ratio between 40% and 50%
+60%
+       the number of zspages with usage ratio between 50% and 60%
+70%
+       the number of zspages with usage ratio between 60% and 70%
+80%
+       the number of zspages with usage ratio between 70% and 80%
+90%
+       the number of zspages with usage ratio between 80% and 90%
+99%
+       the number of zspages with usage ratio between 90% and 99%
+100%
+       the number of zspages with usage ratio 100%
 obj_allocated
        the number of objects allocated
 obj_used
@@ -66,19 +83,14 @@ pages_used
        the number of pages allocated for the class
 pages_per_zspage
        the number of 0-order pages to make a zspage
+freeable
+       the approximate number of pages class compaction can free
 
-We assign a zspage to ZS_ALMOST_EMPTY fullness group when n <= N / f, where
-
-* n = number of allocated objects
-* N = total number of objects zspage can store
-* f = fullness_threshold_frac(ie, 4 at the moment)
-
-Similarly, we assign zspage to:
-
-* ZS_ALMOST_FULL  when n > N / f
-* ZS_EMPTY        when n == 0
-* ZS_FULL         when n == N
-
+Each zspage maintains inuse counter which keeps track of the number of
+objects stored in the zspage.  The inuse counter determines the zspage's
+"fullness group" which is calculated as the ratio of the "inuse" objects to
+the total number of objects the zspage can hold (objs_per_zspage). The
+closer the inuse counter is to objs_per_zspage, the better.
 
 Internals
 =========
@@ -94,10 +106,10 @@ of objects that each zspage can store.
 
 For instance, consider the following size classes:::
 
-  class  size almost_full almost_empty obj_allocated   obj_used pages_used pages_per_zspage freeable
+  class  size       10%   ....    100% obj_allocated   obj_used pages_used pages_per_zspage freeable
   ...
-     94  1536           0            0             0          0          0                3        0
-    100  1632           0            0             0          0          0                2        0
+     94  1536        0    ....       0             0          0          0                3        0
+    100  1632        0    ....       0             0          0          0                2        0
   ...
 
 
@@ -134,10 +146,11 @@ reduces memory wastage.
 
 Let's take a closer look at the bottom of `/sys/kernel/debug/zsmalloc/zramX/classes`:::
 
-  class  size almost_full almost_empty obj_allocated   obj_used pages_used pages_per_zspage freeable
+  class  size       10%   ....    100% obj_allocated   obj_used pages_used pages_per_zspage freeable
+
   ...
-    202  3264           0            0             0          0          0                4        0
-    254  4096           0            0             0          0          0                1        0
+    202  3264         0   ..         0             0          0          0                4        0
+    254  4096         0   ..         0             0          0          0                1        0
   ...
 
 Size class #202 stores objects of size 3264 bytes and has a maximum of 4 pages
@@ -151,40 +164,42 @@ efficient storage of large objects.
 
 For zspage chain size of 8, huge class watermark becomes 3632 bytes:::
 
-  class  size almost_full almost_empty obj_allocated   obj_used pages_used pages_per_zspage freeable
+  class  size       10%   ....    100% obj_allocated   obj_used pages_used pages_per_zspage freeable
+
   ...
-    202  3264           0            0             0          0          0                4        0
-    211  3408           0            0             0          0          0                5        0
-    217  3504           0            0             0          0          0                6        0
-    222  3584           0            0             0          0          0                7        0
-    225  3632           0            0             0          0          0                8        0
-    254  4096           0            0             0          0          0                1        0
+    202  3264         0   ..         0             0          0          0                4        0
+    211  3408         0   ..         0             0          0          0                5        0
+    217  3504         0   ..         0             0          0          0                6        0
+    222  3584         0   ..         0             0          0          0                7        0
+    225  3632         0   ..         0             0          0          0                8        0
+    254  4096         0   ..         0             0          0          0                1        0
   ...
 
 For zspage chain size of 16, huge class watermark becomes 3840 bytes:::
 
-  class  size almost_full almost_empty obj_allocated   obj_used pages_used pages_per_zspage freeable
+  class  size       10%   ....    100% obj_allocated   obj_used pages_used pages_per_zspage freeable
+
   ...
-    202  3264           0            0             0          0          0                4        0
-    206  3328           0            0             0          0          0               13        0
-    207  3344           0            0             0          0          0                9        0
-    208  3360           0            0             0          0          0               14        0
-    211  3408           0            0             0          0          0                5        0
-    212  3424           0            0             0          0          0               16        0
-    214  3456           0            0             0          0          0               11        0
-    217  3504           0            0             0          0          0                6        0
-    219  3536           0            0             0          0          0               13        0
-    222  3584           0            0             0          0          0                7        0
-    223  3600           0            0             0          0          0               15        0
-    225  3632           0            0             0          0          0                8        0
-    228  3680           0            0             0          0          0                9        0
-    230  3712           0            0             0          0          0               10        0
-    232  3744           0            0             0          0          0               11        0
-    234  3776           0            0             0          0          0               12        0
-    235  3792           0            0             0          0          0               13        0
-    236  3808           0            0             0          0          0               14        0
-    238  3840           0            0             0          0          0               15        0
-    254  4096           0            0             0          0          0                1        0
+    202  3264         0   ..         0             0          0          0                4        0
+    206  3328         0   ..         0             0          0          0               13        0
+    207  3344         0   ..         0             0          0          0                9        0
+    208  3360         0   ..         0             0          0          0               14        0
+    211  3408         0   ..         0             0          0          0                5        0
+    212  3424         0   ..         0             0          0          0               16        0
+    214  3456         0   ..         0             0          0          0               11        0
+    217  3504         0   ..         0             0          0          0                6        0
+    219  3536         0   ..         0             0          0          0               13        0
+    222  3584         0   ..         0             0          0          0                7        0
+    223  3600         0   ..         0             0          0          0               15        0
+    225  3632         0   ..         0             0          0          0                8        0
+    228  3680         0   ..         0             0          0          0                9        0
+    230  3712         0   ..         0             0          0          0               10        0
+    232  3744         0   ..         0             0          0          0               11        0
+    234  3776         0   ..         0             0          0          0               12        0
+    235  3792         0   ..         0             0          0          0               13        0
+    236  3808         0   ..         0             0          0          0               14        0
+    238  3840         0   ..         0             0          0          0               15        0
+    254  4096         0   ..         0             0          0          0                1        0
   ...
 
 Overall the combined zspage chain size effect on zsmalloc pool configuration:::
@@ -214,9 +229,10 @@ zram as a build artifacts storage (Linux kernel compilation).
 
   zsmalloc classes stats:::
 
-    class  size almost_full almost_empty obj_allocated   obj_used pages_used pages_per_zspage freeable
+    class  size       10%   ....    100% obj_allocated   obj_used pages_used pages_per_zspage freeable
+
     ...
-    Total                13           51        413836     412973     159955                         3
+    Total              13   ..        51        413836     412973     159955                         3
 
   zram mm_stat:::
 
@@ -227,9 +243,10 @@ zram as a build artifacts storage (Linux kernel compilation).
 
   zsmalloc classes stats:::
 
-    class  size almost_full almost_empty obj_allocated   obj_used pages_used pages_per_zspage freeable
+    class  size       10%   ....    100% obj_allocated   obj_used pages_used pages_per_zspage freeable
+
     ...
-    Total                18           87        414852     412978     156666                         0
+    Total              18   ..        87        414852     412978     156666                         0
 
   zram mm_stat:::
 
index bbcfa2472b047662af0ff2a7a9b415f1b90fd17e..5c3642b3f802df5363d453350f421a37cc23ad25 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0
+# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
 %YAML 1.2
 ---
 $id: http://kernel.org/schemas/netlink/genetlink-c.yaml#
index 5642925c4ceb1afc64c675292bbf362c58b9ac72..5e98c6d2b9aae89e9a6b8f0111552e65709ab7ef 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0
+# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
 %YAML 1.2
 ---
 $id: http://kernel.org/schemas/netlink/genetlink-legacy.yaml#
index 62a922755ce2d518e53a0ce92fcf719a427ca3ff..d35dcd6f8d82a784414e3521945cff3b42644a49 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0
+# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
 %YAML 1.2
 ---
 $id: http://kernel.org/schemas/netlink/genetlink-legacy.yaml#
index 08b776908d152131699eaa338fe964c63d3001be..4727c067e2ba361ef1271a5afaac0307b10e744f 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
+
 name: ethtool
 
 protocol: genetlink-legacy
@@ -11,7 +13,6 @@ attribute-sets:
       -
         name: dev-index
         type: u32
-        value: 1
       -
         name: dev-name
         type: string
@@ -25,7 +26,6 @@ attribute-sets:
       -
         name: index
         type: u32
-        value: 1
       -
         name: name
         type: string
@@ -39,14 +39,12 @@ attribute-sets:
         name: bit
         type: nest
         nested-attributes: bitset-bit
-        value: 1
   -
     name: bitset
     attributes:
       -
         name: nomask
         type: flag
-        value: 1
       -
         name: size
         type: u32
@@ -61,7 +59,6 @@ attribute-sets:
       -
         name: index
         type: u32
-        value: 1
       -
         name: value
         type: string
@@ -71,7 +68,6 @@ attribute-sets:
       -
         name: string
         type: nest
-        value: 1
         multi-attr: true
         nested-attributes: string
   -
@@ -80,7 +76,6 @@ attribute-sets:
       -
         name: id
         type: u32
-        value: 1
       -
         name: count
         type: u32
@@ -96,14 +91,12 @@ attribute-sets:
         name: stringset
         type: nest
         multi-attr: true
-        value: 1
         nested-attributes: stringset
   -
     name: strset
     attributes:
       -
         name: header
-        value: 1
         type: nest
         nested-attributes: header
       -
@@ -119,7 +112,6 @@ attribute-sets:
     attributes:
       -
         name: header
-        value: 1
         type: nest
         nested-attributes: header
       -
@@ -132,7 +124,6 @@ attribute-sets:
     attributes:
       -
         name: header
-        value: 1
         type: nest
         nested-attributes: header
       -
@@ -180,7 +171,6 @@ attribute-sets:
     attributes:
       -
         name: pad
-        value: 1
         type: pad
       -
         name: reassembly-errors
@@ -205,7 +195,6 @@ attribute-sets:
     attributes:
       -
         name: header
-        value: 1
         type: nest
         nested-attributes: header
       -
@@ -251,13 +240,11 @@ operations:
 
       do: &strset-get-op
         request:
-          value: 1
           attributes:
             - header
             - stringsets
             - counts-only
         reply:
-          value: 1
           attributes:
             - header
             - stringsets
index 266c386eedf3a08949b503a855e76db5ff333ff3..3e13826a3fdf18c746c59ae35f9c48af434488de 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
+
 name: fou
 
 protocol: genetlink-legacy
@@ -26,6 +28,7 @@ attribute-sets:
       -
         name: unspec
         type: unused
+        value: 0
       -
         name: port
         type: u16
@@ -71,6 +74,7 @@ operations:
     -
       name: unspec
       doc: unused
+      value: 0
 
     -
       name: add
index cffef09729f1562e870cfcd557bc1bff1b83c2d9..b99e7ffef7a1578f837e96047ddd0e4967adbed8 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
+
 name: netdev
 
 doc:
@@ -7,6 +9,7 @@ definitions:
   -
     type: flags
     name: xdp-act
+    render-max: true
     entries:
       -
         name: basic
@@ -48,7 +51,6 @@ attribute-sets:
         name: ifindex
         doc: netdev ifindex
         type: u32
-        value: 1
         checks:
           min: 1
       -
@@ -66,7 +68,6 @@ operations:
     -
       name: dev-get
       doc: Get / dump information about a netdev.
-      value: 1
       attribute-set: dev
       do:
         request:
index 10f282c2117c6ca122ad509ba672976386b42fd4..2f60e34ab9267bca2b8c217399e205bcce91cea3 100644 (file)
@@ -7,6 +7,21 @@ ice devlink support
 This document describes the devlink features implemented by the ``ice``
 device driver.
 
+Parameters
+==========
+
+.. list-table:: Generic parameters implemented
+
+   * - Name
+     - Mode
+     - Notes
+   * - ``enable_roce``
+     - runtime
+     - mutually exclusive with ``enable_iwarp``
+   * - ``enable_iwarp``
+     - runtime
+     - mutually exclusive with ``enable_roce``
+
 Info versions
 =============
 
index 87dd1c5283e61c03b9508a2d3e77bd82722ed176..58a78a3166978bd6957e043511e95e455e018f1d 100644 (file)
@@ -340,6 +340,8 @@ tcp_app_win - INTEGER
        Reserve max(window/2^tcp_app_win, mss) of window for application
        buffer. Value 0 is special, it means that nothing is reserved.
 
+       Possible values are [0, 31], inclusive.
+
        Default: 31
 
 tcp_autocorking - BOOLEAN
index aac63fc2d08bd104634315d422d33f24717de4aa..25ce72af81c216322edfe56da3195fdd13a47db8 100644 (file)
@@ -23,10 +23,13 @@ metadata is supported, this set will grow:
 An XDP program can use these kfuncs to read the metadata into stack
 variables for its own consumption. Or, to pass the metadata on to other
 consumers, an XDP program can store it into the metadata area carried
-ahead of the packet.
+ahead of the packet. Not all packets will necessary have the requested
+metadata available in which case the driver returns ``-ENODATA``.
 
 Not all kfuncs have to be implemented by the device driver; when not
-implemented, the default ones that return ``-EOPNOTSUPP`` will be used.
+implemented, the default ones that return ``-EOPNOTSUPP`` will be used
+to indicate the device driver have not implemented this kfunc.
+
 
 Within an XDP frame, the metadata layout (accessed via ``xdp_buff``) is
 as follows::
diff --git a/Documentation/nios2/features.rst b/Documentation/nios2/features.rst
deleted file mode 100644 (file)
index 8449e63..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. kernel-feat:: $srctree/Documentation/features nios2
diff --git a/Documentation/nios2/index.rst b/Documentation/nios2/index.rst
deleted file mode 100644 (file)
index 4468fe1..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-==============================
-Nios II Specific Documentation
-==============================
-
-.. toctree::
-   :maxdepth: 2
-   :numbered:
-
-   nios2
-   features
diff --git a/Documentation/nios2/nios2.rst b/Documentation/nios2/nios2.rst
deleted file mode 100644 (file)
index 43da3f7..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-=================================
-Linux on the Nios II architecture
-=================================
-
-This is a port of Linux to Nios II (nios2) processor.
-
-In order to compile for Nios II, you need a version of GCC with support for the generic
-system call ABI. Please see this link for more information on how compiling and booting
-software for the Nios II platform:
-http://www.rocketboards.org/foswiki/Documentation/NiosIILinuxUserManual
-
-For reference, please see the following link:
-http://www.altera.com/literature/lit-nio2.jsp
-
-What is Nios II?
-================
-Nios II is a 32-bit embedded-processor architecture designed specifically for the
-Altera family of FPGAs. In order to support Linux, Nios II needs to be configured
-with MMU and hardware multiplier enabled.
-
-Nios II ABI
-===========
-Please refer to chapter "Application Binary Interface" in Nios II Processor Reference
-Handbook.
diff --git a/Documentation/openrisc/features.rst b/Documentation/openrisc/features.rst
deleted file mode 100644 (file)
index 3f7c40d..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. kernel-feat:: $srctree/Documentation/features openrisc
diff --git a/Documentation/openrisc/index.rst b/Documentation/openrisc/index.rst
deleted file mode 100644 (file)
index 6879f99..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=====================
-OpenRISC Architecture
-=====================
-
-.. toctree::
-   :maxdepth: 2
-
-   openrisc_port
-   todo
-
-   features
-
-.. only::  subproject and html
-
-   Indices
-   =======
-
-   * :ref:`genindex`
diff --git a/Documentation/openrisc/openrisc_port.rst b/Documentation/openrisc/openrisc_port.rst
deleted file mode 100644 (file)
index 657ac4a..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-==============
-OpenRISC Linux
-==============
-
-This is a port of Linux to the OpenRISC class of microprocessors; the initial
-target architecture, specifically, is the 32-bit OpenRISC 1000 family (or1k).
-
-For information about OpenRISC processors and ongoing development:
-
-       =======         =============================
-       website         https://openrisc.io
-       email           openrisc@lists.librecores.org
-       =======         =============================
-
----------------------------------------------------------------------
-
-Build instructions for OpenRISC toolchain and Linux
-===================================================
-
-In order to build and run Linux for OpenRISC, you'll need at least a basic
-toolchain and, perhaps, the architectural simulator.  Steps to get these bits
-in place are outlined here.
-
-1) Toolchain
-
-Toolchain binaries can be obtained from openrisc.io or our github releases page.
-Instructions for building the different toolchains can be found on openrisc.io
-or Stafford's toolchain build and release scripts.
-
-       ==========      =================================================
-       binaries        https://github.com/openrisc/or1k-gcc/releases
-       toolchains      https://openrisc.io/software
-       building        https://github.com/stffrdhrn/or1k-toolchain-build
-       ==========      =================================================
-
-2) Building
-
-Build the Linux kernel as usual::
-
-       make ARCH=openrisc CROSS_COMPILE="or1k-linux-" defconfig
-       make ARCH=openrisc CROSS_COMPILE="or1k-linux-"
-
-3) Running on FPGA (optional)
-
-The OpenRISC community typically uses FuseSoC to manage building and programming
-an SoC into an FPGA.  The below is an example of programming a De0 Nano
-development board with the OpenRISC SoC.  During the build FPGA RTL is code
-downloaded from the FuseSoC IP cores repository and built using the FPGA vendor
-tools.  Binaries are loaded onto the board with openocd.
-
-::
-
-       git clone https://github.com/olofk/fusesoc
-       cd fusesoc
-       sudo pip install -e .
-
-       fusesoc init
-       fusesoc build de0_nano
-       fusesoc pgm de0_nano
-
-       openocd -f interface/altera-usb-blaster.cfg \
-               -f board/or1k_generic.cfg
-
-       telnet localhost 4444
-       > init
-       > halt; load_image vmlinux ; reset
-
-4) Running on a Simulator (optional)
-
-QEMU is a processor emulator which we recommend for simulating the OpenRISC
-platform.  Please follow the OpenRISC instructions on the QEMU website to get
-Linux running on QEMU.  You can build QEMU yourself, but your Linux distribution
-likely provides binary packages to support OpenRISC.
-
-       =============   ======================================================
-       qemu openrisc   https://wiki.qemu.org/Documentation/Platforms/OpenRISC
-       =============   ======================================================
-
----------------------------------------------------------------------
-
-Terminology
-===========
-
-In the code, the following particles are used on symbols to limit the scope
-to more or less specific processor implementations:
-
-========= =======================================
-openrisc: the OpenRISC class of processors
-or1k:     the OpenRISC 1000 family of processors
-or1200:   the OpenRISC 1200 processor
-========= =======================================
-
----------------------------------------------------------------------
-
-History
-========
-
-18-11-2003     Matjaz Breskvar (phoenix@bsemi.com)
-       initial port of linux to OpenRISC/or32 architecture.
-        all the core stuff is implemented and seams usable.
-
-08-12-2003     Matjaz Breskvar (phoenix@bsemi.com)
-       complete change of TLB miss handling.
-       rewrite of exceptions handling.
-       fully functional sash-3.6 in default initrd.
-       a much improved version with changes all around.
-
-10-04-2004     Matjaz Breskvar (phoenix@bsemi.com)
-       alot of bugfixes all over.
-       ethernet support, functional http and telnet servers.
-       running many standard linux apps.
-
-26-06-2004     Matjaz Breskvar (phoenix@bsemi.com)
-       port to 2.6.x
-
-30-11-2004     Matjaz Breskvar (phoenix@bsemi.com)
-       lots of bugfixes and enhancments.
-       added opencores framebuffer driver.
-
-09-10-2010    Jonas Bonn (jonas@southpole.se)
-       major rewrite to bring up to par with upstream Linux 2.6.36
diff --git a/Documentation/openrisc/todo.rst b/Documentation/openrisc/todo.rst
deleted file mode 100644 (file)
index 420b18b..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-====
-TODO
-====
-
-The OpenRISC Linux port is fully functional and has been tracking upstream
-since 2.6.35.  There are, however, remaining items to be completed within
-the coming months.  Here's a list of known-to-be-less-than-stellar items
-that are due for investigation shortly, i.e. our TODO list:
-
--  Implement the rest of the DMA API... dma_map_sg, etc.
-
--  Finish the renaming cleanup... there are references to or32 in the code
-   which was an older name for the architecture.  The name we've settled on is
-   or1k and this change is slowly trickling through the stack.  For the time
-   being, or32 is equivalent to or1k.
diff --git a/Documentation/parisc/debugging.rst b/Documentation/parisc/debugging.rst
deleted file mode 100644 (file)
index de1b604..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-=================
-PA-RISC Debugging
-=================
-
-okay, here are some hints for debugging the lower-level parts of
-linux/parisc.
-
-
-1. Absolute addresses
-=====================
-
-A lot of the assembly code currently runs in real mode, which means
-absolute addresses are used instead of virtual addresses as in the
-rest of the kernel.  To translate an absolute address to a virtual
-address you can lookup in System.map, add __PAGE_OFFSET (0x10000000
-currently).
-
-
-2. HPMCs
-========
-
-When real-mode code tries to access non-existent memory, you'll get
-an HPMC instead of a kernel oops.  To debug an HPMC, try to find
-the System Responder/Requestor addresses.  The System Requestor
-address should match (one of the) processor HPAs (high addresses in
-the I/O range); the System Responder address is the address real-mode
-code tried to access.
-
-Typical values for the System Responder address are addresses larger
-than __PAGE_OFFSET (0x10000000) which mean a virtual address didn't
-get translated to a physical address before real-mode code tried to
-access it.
-
-
-3. Q bit fun
-============
-
-Certain, very critical code has to clear the Q bit in the PSW.  What
-happens when the Q bit is cleared is the CPU does not update the
-registers interruption handlers read to find out where the machine
-was interrupted - so if you get an interruption between the instruction
-that clears the Q bit and the RFI that sets it again you don't know
-where exactly it happened.  If you're lucky the IAOQ will point to the
-instruction that cleared the Q bit, if you're not it points anywhere
-at all.  Usually Q bit problems will show themselves in unexplainable
-system hangs or running off the end of physical memory.
diff --git a/Documentation/parisc/features.rst b/Documentation/parisc/features.rst
deleted file mode 100644 (file)
index 501d7c4..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. kernel-feat:: $srctree/Documentation/features parisc
diff --git a/Documentation/parisc/index.rst b/Documentation/parisc/index.rst
deleted file mode 100644 (file)
index 2406857..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-====================
-PA-RISC Architecture
-====================
-
-.. toctree::
-   :maxdepth: 2
-
-   debugging
-   registers
-
-   features
-
-.. only::  subproject and html
-
-   Indices
-   =======
-
-   * :ref:`genindex`
diff --git a/Documentation/parisc/registers.rst b/Documentation/parisc/registers.rst
deleted file mode 100644 (file)
index 59c8ecf..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-================================
-Register Usage for Linux/PA-RISC
-================================
-
-[ an asterisk is used for planned usage which is currently unimplemented ]
-
-General Registers as specified by ABI
-=====================================
-
-Control Registers
------------------
-
-===============================        ===============================================
-CR 0 (Recovery Counter)                used for ptrace
-CR 1-CR 7(undefined)           unused
-CR 8 (Protection ID)           per-process value*
-CR 9, 12, 13 (PIDS)            unused
-CR10 (CCR)                     lazy FPU saving*
-CR11                           as specified by ABI (SAR)
-CR14 (interruption vector)     initialized to fault_vector
-CR15 (EIEM)                    initialized to all ones*
-CR16 (Interval Timer)          read for cycle count/write starts Interval Tmr
-CR17-CR22                      interruption parameters
-CR19                           Interrupt Instruction Register
-CR20                           Interrupt Space Register
-CR21                           Interrupt Offset Register
-CR22                           Interrupt PSW
-CR23 (EIRR)                    read for pending interrupts/write clears bits
-CR24 (TR 0)                    Kernel Space Page Directory Pointer
-CR25 (TR 1)                    User   Space Page Directory Pointer
-CR26 (TR 2)                    not used
-CR27 (TR 3)                    Thread descriptor pointer
-CR28 (TR 4)                    not used
-CR29 (TR 5)                    not used
-CR30 (TR 6)                    current / 0
-CR31 (TR 7)                    Temporary register, used in various places
-===============================        ===============================================
-
-Space Registers (kernel mode)
------------------------------
-
-===============================        ===============================================
-SR0                            temporary space register
-SR4-SR7                        set to 0
-SR1                            temporary space register
-SR2                            kernel should not clobber this
-SR3                            used for userspace accesses (current process)
-===============================        ===============================================
-
-Space Registers (user mode)
----------------------------
-
-===============================        ===============================================
-SR0                            temporary space register
-SR1                             temporary space register
-SR2                             holds space of linux gateway page
-SR3                             holds user address space value while in kernel
-SR4-SR7                         Defines short address space for user/kernel
-===============================        ===============================================
-
-
-Processor Status Word
----------------------
-
-===============================        ===============================================
-W (64-bit addresses)           0
-E (Little-endian)              0
-S (Secure Interval Timer)      0
-T (Taken Branch Trap)          0
-H (Higher-privilege trap)      0
-L (Lower-privilege trap)       0
-N (Nullify next instruction)   used by C code
-X (Data memory break disable)  0
-B (Taken Branch)               used by C code
-C (code address translation)   1, 0 while executing real-mode code
-V (divide step correction)     used by C code
-M (HPMC mask)                  0, 1 while executing HPMC handler*
-C/B (carry/borrow bits)                used by C code
-O (ordered references)         1*
-F (performance monitor)                0
-R (Recovery Counter trap)      0
-Q (collect interruption state) 1 (0 in code directly preceding an rfi)
-P (Protection Identifiers)     1*
-D (Data address translation)   1, 0 while executing real-mode code
-I (external interrupt mask)    used by cli()/sti() macros
-===============================        ===============================================
-
-"Invisible" Registers
----------------------
-
-===============================        ===============================================
-PSW default W value            0
-PSW default E value            0
-Shadow Registers               used by interruption handler code
-TOC enable bit                 1
-===============================        ===============================================
-
--------------------------------------------------------------------------
-
-The PA-RISC architecture defines 7 registers as "shadow registers".
-Those are used in RETURN FROM INTERRUPTION AND RESTORE instruction to reduce
-the state save and restore time by eliminating the need for general register
-(GR) saves and restores in interruption handlers.
-Shadow registers are the GRs 1, 8, 9, 16, 17, 24, and 25.
-
--------------------------------------------------------------------------
-
-Register usage notes, originally from John Marvin, with some additional
-notes from Randolph Chung.
-
-For the general registers:
-
-r1,r2,r19-r26,r28,r29 & r31 can be used without saving them first. And of
-course, you need to save them if you care about them, before calling
-another procedure. Some of the above registers do have special meanings
-that you should be aware of:
-
-    r1:
-       The addil instruction is hardwired to place its result in r1,
-       so if you use that instruction be aware of that.
-
-    r2:
-       This is the return pointer. In general you don't want to
-       use this, since you need the pointer to get back to your
-       caller. However, it is grouped with this set of registers
-       since the caller can't rely on the value being the same
-       when you return, i.e. you can copy r2 to another register
-       and return through that register after trashing r2, and
-       that should not cause a problem for the calling routine.
-
-    r19-r22:
-       these are generally regarded as temporary registers.
-       Note that in 64 bit they are arg7-arg4.
-
-    r23-r26:
-       these are arg3-arg0, i.e. you can use them if you
-       don't care about the values that were passed in anymore.
-
-    r28,r29:
-       are ret0 and ret1. They are what you pass return values
-       in. r28 is the primary return. When returning small structures
-       r29 may also be used to pass data back to the caller.
-
-    r30:
-       stack pointer
-
-    r31:
-       the ble instruction puts the return pointer in here.
-
-
-    r3-r18,r27,r30 need to be saved and restored. r3-r18 are just
-    general purpose registers. r27 is the data pointer, and is
-    used to make references to global variables easier. r30 is
-    the stack pointer.
index 007e49ef6cec773e4231f543e47341a573e5ed6f..6db37a46d3059ee8e3fe6c3ee80711b6bff26e0d 100644 (file)
@@ -1267,5 +1267,5 @@ gcc internals and indent, all available from https://www.gnu.org/manual/
 WG14 is the international standardization working group for the programming
 language C, URL: http://www.open-std.org/JTC1/SC22/WG14/
 
-Kernel :ref:`process/coding-style.rst <codingstyle>`, by greg@kroah.com at OLS 2002:
+Kernel CodingStyle, by greg@kroah.com at OLS 2002:
 http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/
diff --git a/Documentation/process/contribution-maturity-model.rst b/Documentation/process/contribution-maturity-model.rst
new file mode 100644 (file)
index 0000000..b87ab34
--- /dev/null
@@ -0,0 +1,109 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+========================================
+Linux Kernel Contribution Maturity Model
+========================================
+
+
+Background
+==========
+
+As a part of the 2021 Linux Kernel Maintainers’ Summit, there was a
+`discussion <https://lwn.net/Articles/870581/>`_ about the challenges in
+recruiting kernel maintainers as well as maintainer succession.  Some of
+the conclusions from that discussion included that companies which are a
+part of the Linux Kernel community need to allow engineers to be
+maintainers as part of their job, so they can grow into becoming
+respected leaders and eventually, kernel maintainers.  To support a
+strong talent pipeline, developers should be allowed and encouraged to
+take on upstream contributions such as reviewing other people’s patches,
+refactoring kernel infrastructure, and writing documentation.
+
+To that end, the Linux Foundation Technical Advisory Board (TAB)
+proposes this Linux Kernel Contribution Maturity Model. These common
+expectations for upstream community engagement aim to increase the
+influence of individual developers, increase the collaboration of
+organizations, and improve the overall health of the Linux Kernel
+ecosystem.
+
+The TAB urges organizations to continuously evaluate their Open Source
+maturity model and commit to improvements to align with this model.  To
+be effective, this evaluation should incorporate feedback from across
+the organization, including management and developers at all seniority
+levels.  In the spirit of Open Source, we encourage organizations to
+publish their evaluations and plans to improve their engagement with the
+upstream community.
+
+Level 0
+=======
+
+* Software Engineers are not allowed to contribute patches to the Linux
+  kernel.
+
+
+Level 1
+=======
+
+* Software Engineers are allowed to contribute patches to the Linux
+  kernel, either as part of their job responsibilities or on their own
+  time.
+
+Level 2
+=======
+
+* Software Engineers are expected to contribute to the Linux Kernel as
+  part of their job responsibilities.
+* Software Engineers will be supported to attend Linux-related
+  conferences as a part of their job.
+* A Software Engineer’s upstream code contributions will be considered
+  in promotion and performance reviews.
+
+Level 3
+=======
+
+* Software Engineers are expected to review patches (including patches
+  authored by engineers from other companies) as part of their job
+  responsibilities
+* Contributing presentations or papers to Linux-related or academic
+  conferences (such those organized by the Linux Foundation, Usenix,
+  ACM, etc.), are considered part of an engineer’s work.
+* A Software Engineer’s community contributions will be considered in
+  promotion and performance reviews.
+* Organizations will regularly report metrics of their open source
+  contributions and track these metrics over time.  These metrics may be
+  published only internally within the organization, or at the
+  organization’s discretion, some or all may be published externally.
+  Metrics that are strongly suggested include:
+
+  * The number of upstream kernel contributions by team or organization
+    (e.g., all people reporting up to a manager, director, or VP).
+  * The percentage of kernel developers who have made upstream
+    contributions relative to the total kernel developers in the
+    organization.
+  * The time interval between kernels used in the organization’s servers
+    and/or products, and the publication date of the upstream kernel
+    upon which the internal kernel is based.
+  * The number of out-of-tree commits present in internal kernels.
+
+Level 4
+=======
+
+* Software Engineers are encouraged to spend a portion of their work
+  time focused on Upstream Work, which is defined as reviewing patches,
+  serving on program committees, improving core project infrastructure
+  such as writing or maintaining tests, upstream tech debt reduction,
+  writing documentation, etc.
+* Software Engineers are supported in helping to organize Linux-related
+  conferences.
+* Organizations will consider community member feedback in official
+  performance reviews.
+
+Level 5
+=======
+
+* Upstream kernel development is considered a formal job position, with
+  at least a third of the engineer’s time spent doing Upstream Work.
+* Organizations will actively seek out community member feedback as a
+  factor in official performance reviews.
+* Organizations will regularly report internally on the ratio of
+  Upstream Work to work focused on directly pursuing business goals.
index cb6abcb2b6d07728a2de3cf9031d1825a76e067e..deb8235e20ff1df44138670983fb324b7f4282d6 100644 (file)
@@ -138,7 +138,7 @@ required reading:
     philosophy and is very important for people moving to Linux from
     development on other Operating Systems.
 
-  :ref:`Documentation/admin-guide/security-bugs.rst <securitybugs>`
+  :ref:`Documentation/process/security-bugs.rst <securitybugs>`
     If you feel you have found a security problem in the Linux kernel,
     please follow the steps in this document to help notify the kernel
     developers, and help solve the issue.
index d4b6217472b0a047a81c7e306fcaf2f54f5a2d46..b501cd977053fa37c765e8a33541a8613ebddab7 100644 (file)
@@ -35,6 +35,14 @@ Below are the essential guides that every developer should read.
    kernel-enforcement-statement
    kernel-driver-statement
 
+For security issues, see:
+
+.. toctree::
+   :maxdepth: 1
+
+   security-bugs
+   embargoed-hardware-issues
+
 Other guides to the community that are of interest to most developers are:
 
 .. toctree::
@@ -47,9 +55,9 @@ Other guides to the community that are of interest to most developers are:
    submit-checklist
    kernel-docs
    deprecated
-   embargoed-hardware-issues
    maintainers
    researcher-guidelines
+   contribution-maturity-model
 
 These are some overall technical guides that have been put here for now for
 lack of a better place.
index 1c6e2ab92f4e7f2714269078a5039907614d2484..46f927aae6ebcfc6a97ad231a1c720e5478255ad 100644 (file)
@@ -75,13 +75,39 @@ On-line docs
 Published books
 ---------------
 
+    * Title: **Linux Kernel Debugging: Leverage proven tools and advanced techniques to effectively debug Linux kernels and kernel modules**
+
+      :Author: Kaiwan N Billimoria
+      :Publisher: Packt Publishing Ltd
+      :Date: August, 2022
+      :Pages: 638
+      :ISBN: 978-1801075039
+      :Notes: Debugging book
+
     * Title: **Linux Kernel Programming: A Comprehensive Guide to Kernel Internals, Writing Kernel Modules, and Kernel Synchronization**
 
-          :Author: Kaiwan N. Billimoria
-          :Publisher: Packt Publishing Ltd
-          :Date: 2021
-          :Pages: 754
-          :ISBN: 978-1789953435
+      :Author: Kaiwan N Billimoria
+      :Publisher: Packt Publishing Ltd
+      :Date: March, 2021
+      :Pages: 754
+      :ISBN: 978-1789953435
+
+    * Title: **Linux Kernel Programming Part 2 - Char Device Drivers and Kernel Synchronization: Create user-kernel interfaces, work with peripheral I/O, and handle hardware interrupts**
+
+      :Author: Kaiwan N Billimoria
+      :Publisher: Packt Publishing Ltd
+      :Date: March, 2021
+      :Pages: 452
+      :ISBN: 978-1801079518
+
+    * Title: **Linux System Programming: Talking Directly to the Kernel and C Library**
+
+      :Author: Robert Love
+      :Publisher: O'Reilly Media
+      :Date: June, 2013
+      :Pages: 456
+      :ISBN: 978-1449339531
+      :Notes: Foundational book
 
     * Title: **Linux Kernel Development, 3rd Edition**
 
index 572a3289c9cbf3b893404b01fe372403ee6010c7..178c95fd17dcaded7f5d598987307d01b9eaa165 100644 (file)
@@ -128,8 +128,8 @@ uppercase letter and should be written in imperative tone.
 Changelog
 ^^^^^^^^^
 
-The general rules about changelogs in the process documentation, see
-:ref:`Documentation/process/ <submittingpatches>`, apply.
+The general rules about changelogs in the :ref:`Submitting patches guide
+<describe_changes>`, apply.
 
 The tip tree maintainers set value on following these rules, especially on
 the request to write changelogs in imperative mood and not impersonating
index 5fc9160ca1fa5b3054887d59e7336941d51d3a5e..bc56dee6d0bcb1c5ad558d88a97ae0a9ede718ad 100644 (file)
@@ -12,10 +12,6 @@ under ``-std=gnu11`` [gcc-c-dialect-options]_: the GNU dialect of ISO C11.
 This dialect contains many extensions to the language [gnu-extensions]_,
 and many of them are used within the kernel as a matter of course.
 
-There is some support for compiling the kernel with ``icc`` [icc]_ for several
-of the architectures, although at the time of writing it is not completed,
-requiring third-party patches.
-
 Attributes
 ----------
 
@@ -35,12 +31,28 @@ in order to feature detect which ones can be used and/or to shorten the code.
 
 Please refer to ``include/linux/compiler_attributes.h`` for more information.
 
+Rust
+----
+
+The kernel has experimental support for the Rust programming language
+[rust-language]_ under ``CONFIG_RUST``. It is compiled with ``rustc`` [rustc]_
+under ``--edition=2021`` [rust-editions]_. Editions are a way to introduce
+small changes to the language that are not backwards compatible.
+
+On top of that, some unstable features [rust-unstable-features]_ are used in
+the kernel. Unstable features may change in the future, thus it is an important
+goal to reach a point where only stable features are used.
+
+Please refer to Documentation/rust/index.rst for more information.
+
 .. [c-language] http://www.open-std.org/jtc1/sc22/wg14/www/standards
 .. [gcc] https://gcc.gnu.org
 .. [clang] https://clang.llvm.org
-.. [icc] https://software.intel.com/en-us/c-compilers
 .. [gcc-c-dialect-options] https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html
 .. [gnu-extensions] https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html
 .. [gcc-attribute-syntax] https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html
 .. [n2049] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2049.pdf
-
+.. [rust-language] https://www.rust-lang.org
+.. [rustc] https://doc.rust-lang.org/rustc/
+.. [rust-editions] https://doc.rust-lang.org/edition-guide/editions/
+.. [rust-unstable-features] https://github.com/Rust-for-Linux/linux/issues/2
index afc944e0e8986c1e8262a28894f4cc95a7c46e53..9fcfed3c350befc25dfafefd760a35d82657c207 100644 (file)
@@ -68,7 +68,7 @@ Before contributing, carefully read the appropriate documentation:
 * Documentation/process/development-process.rst
 * Documentation/process/submitting-patches.rst
 * Documentation/admin-guide/reporting-issues.rst
-* Documentation/admin-guide/security-bugs.rst
+* Documentation/process/security-bugs.rst
 
 Then send a patch (including a commit log with all the details listed
 below) and follow up on any feedback from other developers.
diff --git a/Documentation/process/security-bugs.rst b/Documentation/process/security-bugs.rst
new file mode 100644 (file)
index 0000000..82e2983
--- /dev/null
@@ -0,0 +1,96 @@
+.. _securitybugs:
+
+Security bugs
+=============
+
+Linux kernel developers take security very seriously.  As such, we'd
+like to know when a security bug is found so that it can be fixed and
+disclosed as quickly as possible.  Please report security bugs to the
+Linux kernel security team.
+
+Contact
+-------
+
+The Linux kernel security team can be contacted by email at
+<security@kernel.org>.  This is a private list of security officers
+who will help verify the bug report and develop and release a fix.
+If you already have a fix, please include it with your report, as
+that can speed up the process considerably.  It is possible that the
+security team will bring in extra help from area maintainers to
+understand and fix the security vulnerability.
+
+As it is with any bug, the more information provided the easier it
+will be to diagnose and fix.  Please review the procedure outlined in
+'Documentation/admin-guide/reporting-issues.rst' if you are unclear about what
+information is helpful.  Any exploit code is very helpful and will not
+be released without consent from the reporter unless it has already been
+made public.
+
+Please send plain text emails without attachments where possible.
+It is much harder to have a context-quoted discussion about a complex
+issue if all the details are hidden away in attachments.  Think of it like a
+:doc:`regular patch submission <../process/submitting-patches>`
+(even if you don't have a patch yet): describe the problem and impact, list
+reproduction steps, and follow it with a proposed fix, all in plain text.
+
+Disclosure and embargoed information
+------------------------------------
+
+The security list is not a disclosure channel.  For that, see Coordination
+below.
+
+Once a robust fix has been developed, the release process starts.  Fixes
+for publicly known bugs are released immediately.
+
+Although our preference is to release fixes for publicly undisclosed bugs
+as soon as they become available, this may be postponed at the request of
+the reporter or an affected party for up to 7 calendar days from the start
+of the release process, with an exceptional extension to 14 calendar days
+if it is agreed that the criticality of the bug requires more time.  The
+only valid reason for deferring the publication of a fix is to accommodate
+the logistics of QA and large scale rollouts which require release
+coordination.
+
+While embargoed information may be shared with trusted individuals in
+order to develop a fix, such information will not be published alongside
+the fix or on any other disclosure channel without the permission of the
+reporter.  This includes but is not limited to the original bug report
+and followup discussions (if any), exploits, CVE information or the
+identity of the reporter.
+
+In other words our only interest is in getting bugs fixed.  All other
+information submitted to the security list and any followup discussions
+of the report are treated confidentially even after the embargo has been
+lifted, in perpetuity.
+
+Coordination
+------------
+
+Fixes for sensitive bugs, such as those that might lead to privilege
+escalations, may need to be coordinated with the private
+<linux-distros@vs.openwall.org> mailing list so that distribution vendors
+are well prepared to issue a fixed kernel upon public disclosure of the
+upstream fix. Distros will need some time to test the proposed patch and
+will generally request at least a few days of embargo, and vendor update
+publication prefers to happen Tuesday through Thursday. When appropriate,
+the security team can assist with this coordination, or the reporter can
+include linux-distros from the start. In this case, remember to prefix
+the email Subject line with "[vs]" as described in the linux-distros wiki:
+<http://oss-security.openwall.org/wiki/mailing-lists/distros#how-to-use-the-lists>
+
+CVE assignment
+--------------
+
+The security team does not normally assign CVEs, nor do we require them
+for reports or fixes, as this can needlessly complicate the process and
+may delay the bug handling. If a reporter wishes to have a CVE identifier
+assigned ahead of public disclosure, they will need to contact the private
+linux-distros list, described above. When such a CVE identifier is known
+before a patch is provided, it is desirable to mention it in the commit
+message if the reporter agrees.
+
+Non-disclosure agreements
+-------------------------
+
+The Linux kernel security team is not a formal body and therefore unable
+to enter any non-disclosure agreements.
index 2fd8aa593a285173785241b0c21954cb8c75aa0c..51df1197d5abd47075552c92daa2d75489e2cd2c 100644 (file)
@@ -39,7 +39,7 @@ Procedure for submitting patches to the -stable tree
 
    Security patches should not be handled (solely) by the -stable review
    process but should follow the procedures in
-   :ref:`Documentation/admin-guide/security-bugs.rst <securitybugs>`.
+   :ref:`Documentation/process/security-bugs.rst <securitybugs>`.
 
 For all other submissions, choose one of the following procedures
 -----------------------------------------------------------------
index eac7167dce83d0fd7665a874aceaa4c9fa5d9e83..7a5619fecb384e442d7f020a43e97a8d42759939 100644 (file)
@@ -223,20 +223,17 @@ patch.
 Select the recipients for your patch
 ------------------------------------
 
-You should always copy the appropriate subsystem maintainer(s) on any patch
-to code that they maintain; look through the MAINTAINERS file and the
-source code revision history to see who those maintainers are.  The
-script scripts/get_maintainer.pl can be very useful at this step (pass paths to
-your patches as arguments to scripts/get_maintainer.pl).  If you cannot find a
+You should always copy the appropriate subsystem maintainer(s) and list(s) on
+any patch to code that they maintain; look through the MAINTAINERS file and the
+source code revision history to see who those maintainers are.  The script
+scripts/get_maintainer.pl can be very useful at this step (pass paths to your
+patches as arguments to scripts/get_maintainer.pl).  If you cannot find a
 maintainer for the subsystem you are working on, Andrew Morton
 (akpm@linux-foundation.org) serves as a maintainer of last resort.
 
-You should also normally choose at least one mailing list to receive a copy
-of your patch set.  linux-kernel@vger.kernel.org should be used by default
-for all patches, but the volume on that list has caused a number of
-developers to tune it out.  Look in the MAINTAINERS file for a
-subsystem-specific list; your patch will probably get more attention there.
-Please do not spam unrelated lists, though.
+linux-kernel@vger.kernel.org should be used by default for all patches, but the
+volume on that list has caused a number of developers to tune it out.  Please
+do not spam unrelated lists and unrelated people, though.
 
 Many kernel-related lists are hosted on vger.kernel.org; you can find a
 list of them at http://vger.kernel.org/vger-lists.html.  There are
@@ -254,7 +251,7 @@ If you have a patch that fixes an exploitable security bug, send that patch
 to security@kernel.org.  For severe bugs, a short embargo may be considered
 to allow distributors to get the patch out to users; in such cases,
 obviously, the patch should not be sent to any public lists. See also
-Documentation/admin-guide/security-bugs.rst.
+Documentation/process/security-bugs.rst.
 
 Patches that fix a severe bug in a released kernel should be directed
 toward the stable maintainers by putting a line like this::
@@ -320,7 +317,7 @@ for their time.  Code review is a tiring and time-consuming process, and
 reviewers sometimes get grumpy.  Even in that case, though, respond
 politely and address the problems they have pointed out.  When sending a next
 version, add a ``patch changelog`` to the cover letter or to individual patches
-explaining difference aganst previous submission (see
+explaining difference against previous submission (see
 :ref:`the_canonical_patch_format`).
 
 See Documentation/process/email-clients.rst for recommendations on email
index 3be44e74ec5d6b81006e2d0e9d3011e0ce464d2d..5462c84f4723ff0836ba62f44775280f13e45e8f 100644 (file)
@@ -47,7 +47,7 @@ RISC-V Linux Kernel SV39
                                                               | Kernel-space virtual memory, shared between all processes:
   ____________________________________________________________|___________________________________________________________
                     |            |                  |         |
-   ffffffc6fee00000 | -228    GB | ffffffc6feffffff |    2 MB | fixmap
+   ffffffc6fea00000 | -228    GB | ffffffc6feffffff |    6 MB | fixmap
    ffffffc6ff000000 | -228    GB | ffffffc6ffffffff |   16 MB | PCI io
    ffffffc700000000 | -228    GB | ffffffc7ffffffff |    4 GB | vmemmap
    ffffffc800000000 | -224    GB | ffffffd7ffffffff |   64 GB | vmalloc/ioremap space
@@ -83,7 +83,7 @@ RISC-V Linux Kernel SV48
                                                               | Kernel-space virtual memory, shared between all processes:
   ____________________________________________________________|___________________________________________________________
                     |            |                  |         |
-   ffff8d7ffee00000 |  -114.5 TB | ffff8d7ffeffffff |    2 MB | fixmap
+   ffff8d7ffea00000 |  -114.5 TB | ffff8d7ffeffffff |    6 MB | fixmap
    ffff8d7fff000000 |  -114.5 TB | ffff8d7fffffffff |   16 MB | PCI io
    ffff8d8000000000 |  -114.5 TB | ffff8f7fffffffff |    2 TB | vmemmap
    ffff8f8000000000 |  -112.5 TB | ffffaf7fffffffff |   32 TB | vmalloc/ioremap space
@@ -119,7 +119,7 @@ RISC-V Linux Kernel SV57
                                                               | Kernel-space virtual memory, shared between all processes:
   ____________________________________________________________|___________________________________________________________
                     |            |                  |         |
-   ff1bfffffee00000 | -57     PB | ff1bfffffeffffff |    2 MB | fixmap
+   ff1bfffffea00000 | -57     PB | ff1bfffffeffffff |    6 MB | fixmap
    ff1bffffff000000 | -57     PB | ff1bffffffffffff |   16 MB | PCI io
    ff1c000000000000 | -57     PB | ff1fffffffffffff |    1 PB | vmemmap
    ff20000000000000 | -56     PB | ff5fffffffffffff |   16 PB | vmalloc/ioremap space
index ed7f4f5b3cf157d12484a289f2efa2d3b9f228f8..b91e9ef4d0c21e45a4beb27eb8ac9f32a4d6669a 100644 (file)
@@ -15,7 +15,7 @@ support corresponds to ``S`` values in the ``MAINTAINERS`` file.
 ============  ================  ==============================================
 Architecture  Level of support  Constraints
 ============  ================  ==============================================
-``x86``       Maintained        ``x86_64`` only.
 ``um``        Maintained        ``x86_64`` only.
+``x86``       Maintained        ``x86_64`` only.
 ============  ================  ==============================================
 
index 8e2b8538bc2b7414d99a0f1726cec6af89fe1065..e2c1cf7431588e6bba3bf5b6fd489c85f652d7ec 100644 (file)
@@ -258,7 +258,7 @@ Linux cannot currently figure out CPU capacity on its own, this information thus
 needs to be handed to it. Architectures must define arch_scale_cpu_capacity()
 for that purpose.
 
-The arm and arm64 architectures directly map this to the arch_topology driver
+The arm, arm64, and RISC-V architectures directly map this to the arch_topology driver
 CPU scaling data, which is derived from the capacity-dmips-mhz CPU binding; see
 Documentation/devicetree/bindings/cpu/cpu-capacity.txt.
 
diff --git a/Documentation/sh/booting.rst b/Documentation/sh/booting.rst
deleted file mode 100644 (file)
index d851c49..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-DeviceTree Booting
-------------------
-
-  Device-tree compatible SH bootloaders are expected to provide the physical
-  address of the device tree blob in r4. Since legacy bootloaders did not
-  guarantee any particular initial register state, kernels built to
-  inter-operate with old bootloaders must either use a builtin DTB or
-  select a legacy board option (something other than CONFIG_SH_DEVICE_TREE)
-  that does not use device tree. Support for the latter is being phased out
-  in favor of device tree.
diff --git a/Documentation/sh/features.rst b/Documentation/sh/features.rst
deleted file mode 100644 (file)
index f722af3..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. kernel-feat:: $srctree/Documentation/features sh
diff --git a/Documentation/sh/index.rst b/Documentation/sh/index.rst
deleted file mode 100644 (file)
index c647767..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-=======================
-SuperH Interfaces Guide
-=======================
-
-:Author: Paul Mundt
-
-.. toctree::
-    :maxdepth: 1
-
-    booting
-    new-machine
-    register-banks
-
-    features
-
-Memory Management
-=================
-
-SH-4
-----
-
-Store Queue API
-~~~~~~~~~~~~~~~
-
-.. kernel-doc:: arch/sh/kernel/cpu/sh4/sq.c
-   :export:
-
-Machine Specific Interfaces
-===========================
-
-mach-dreamcast
---------------
-
-.. kernel-doc:: arch/sh/boards/mach-dreamcast/rtc.c
-   :internal:
-
-mach-x3proto
-------------
-
-.. kernel-doc:: arch/sh/boards/mach-x3proto/ilsel.c
-   :export:
-
-Busses
-======
-
-SuperHyway
-----------
-
-.. kernel-doc:: drivers/sh/superhyway/superhyway.c
-   :export:
-
-Maple
------
-
-.. kernel-doc:: drivers/sh/maple/maple.c
-   :export:
diff --git a/Documentation/sh/new-machine.rst b/Documentation/sh/new-machine.rst
deleted file mode 100644 (file)
index e501c52..0000000
+++ /dev/null
@@ -1,277 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=============================
-Adding a new board to LinuxSH
-=============================
-
-               Paul Mundt <lethal@linux-sh.org>
-
-This document attempts to outline what steps are necessary to add support
-for new boards to the LinuxSH port under the new 2.5 and 2.6 kernels. This
-also attempts to outline some of the noticeable changes between the 2.4
-and the 2.5/2.6 SH backend.
-
-1. New Directory Structure
-==========================
-
-The first thing to note is the new directory structure. Under 2.4, most
-of the board-specific code (with the exception of stboards) ended up
-in arch/sh/kernel/ directly, with board-specific headers ending up in
-include/asm-sh/. For the new kernel, things are broken out by board type,
-companion chip type, and CPU type. Looking at a tree view of this directory
-hierarchy looks like the following:
-
-Board-specific code::
-
-    .
-    |-- arch
-    |   `-- sh
-    |       `-- boards
-    |           |-- adx
-    |           |   `-- board-specific files
-    |           |-- bigsur
-    |           |   `-- board-specific files
-    |           |
-    |           ... more boards here ...
-    |
-    `-- include
-       `-- asm-sh
-           |-- adx
-           |   `-- board-specific headers
-           |-- bigsur
-           |   `-- board-specific headers
-           |
-           .. more boards here ...
-
-Next, for companion chips::
-
-    .
-    `-- arch
-       `-- sh
-           `-- cchips
-               `-- hd6446x
-                   `-- hd64461
-                       `-- cchip-specific files
-
-... and so on. Headers for the companion chips are treated the same way as
-board-specific headers. Thus, include/asm-sh/hd64461 is home to all of the
-hd64461-specific headers.
-
-Finally, CPU family support is also abstracted::
-
-    .
-    |-- arch
-    |   `-- sh
-    |       |-- kernel
-    |       |   `-- cpu
-    |       |       |-- sh2
-    |       |       |   `-- SH-2 generic files
-    |       |       |-- sh3
-    |       |       |   `-- SH-3 generic files
-    |       |       `-- sh4
-    |       |           `-- SH-4 generic files
-    |       `-- mm
-    |           `-- This is also broken out per CPU family, so each family can
-    |               have their own set of cache/tlb functions.
-    |
-    `-- include
-       `-- asm-sh
-           |-- cpu-sh2
-           |   `-- SH-2 specific headers
-           |-- cpu-sh3
-           |   `-- SH-3 specific headers
-           `-- cpu-sh4
-               `-- SH-4 specific headers
-
-It should be noted that CPU subtypes are _not_ abstracted. Thus, these still
-need to be dealt with by the CPU family specific code.
-
-2. Adding a New Board
-=====================
-
-The first thing to determine is whether the board you are adding will be
-isolated, or whether it will be part of a family of boards that can mostly
-share the same board-specific code with minor differences.
-
-In the first case, this is just a matter of making a directory for your
-board in arch/sh/boards/ and adding rules to hook your board in with the
-build system (more on this in the next section). However, for board families
-it makes more sense to have a common top-level arch/sh/boards/ directory
-and then populate that with sub-directories for each member of the family.
-Both the Solution Engine and the hp6xx boards are an example of this.
-
-After you have setup your new arch/sh/boards/ directory, remember that you
-should also add a directory in include/asm-sh for headers localized to this
-board (if there are going to be more than one). In order to interoperate
-seamlessly with the build system, it's best to have this directory the same
-as the arch/sh/boards/ directory name, though if your board is again part of
-a family, the build system has ways of dealing with this (via incdir-y
-overloading), and you can feel free to name the directory after the family
-member itself.
-
-There are a few things that each board is required to have, both in the
-arch/sh/boards and the include/asm-sh/ hierarchy. In order to better
-explain this, we use some examples for adding an imaginary board. For
-setup code, we're required at the very least to provide definitions for
-get_system_type() and platform_setup(). For our imaginary board, this
-might look something like::
-
-    /*
-    * arch/sh/boards/vapor/setup.c - Setup code for imaginary board
-    */
-    #include <linux/init.h>
-
-    const char *get_system_type(void)
-    {
-           return "FooTech Vaporboard";
-    }
-
-    int __init platform_setup(void)
-    {
-           /*
-           * If our hardware actually existed, we would do real
-           * setup here. Though it's also sane to leave this empty
-           * if there's no real init work that has to be done for
-           * this board.
-           */
-
-           /* Start-up imaginary PCI ... */
-
-           /* And whatever else ... */
-
-           return 0;
-    }
-
-Our new imaginary board will also have to tie into the machvec in order for it
-to be of any use.
-
-machvec functions fall into a number of categories:
-
- - I/O functions to IO memory (inb etc) and PCI/main memory (readb etc).
- - I/O mapping functions (ioport_map, ioport_unmap, etc).
- - a 'heartbeat' function.
- - PCI and IRQ initialization routines.
- - Consistent allocators (for boards that need special allocators,
-   particularly for allocating out of some board-specific SRAM for DMA
-   handles).
-
-There are machvec functions added and removed over time, so always be sure to
-consult include/asm-sh/machvec.h for the current state of the machvec.
-
-The kernel will automatically wrap in generic routines for undefined function
-pointers in the machvec at boot time, as machvec functions are referenced
-unconditionally throughout most of the tree. Some boards have incredibly
-sparse machvecs (such as the dreamcast and sh03), whereas others must define
-virtually everything (rts7751r2d).
-
-Adding a new machine is relatively trivial (using vapor as an example):
-
-If the board-specific definitions are quite minimalistic, as is the case for
-the vast majority of boards, simply having a single board-specific header is
-sufficient.
-
- - add a new file include/asm-sh/vapor.h which contains prototypes for
-   any machine specific IO functions prefixed with the machine name, for
-   example vapor_inb. These will be needed when filling out the machine
-   vector.
-
-   Note that these prototypes are generated automatically by setting
-   __IO_PREFIX to something sensible. A typical example would be::
-
-       #define __IO_PREFIX vapor
-       #include <asm/io_generic.h>
-
-   somewhere in the board-specific header. Any boards being ported that still
-   have a legacy io.h should remove it entirely and switch to the new model.
-
- - Add machine vector definitions to the board's setup.c. At a bare minimum,
-   this must be defined as something like::
-
-       struct sh_machine_vector mv_vapor __initmv = {
-               .mv_name = "vapor",
-       };
-       ALIAS_MV(vapor)
-
- - finally add a file arch/sh/boards/vapor/io.c, which contains definitions of
-   the machine specific io functions (if there are enough to warrant it).
-
-3. Hooking into the Build System
-================================
-
-Now that we have the corresponding directories setup, and all of the
-board-specific code is in place, it's time to look at how to get the
-whole mess to fit into the build system.
-
-Large portions of the build system are now entirely dynamic, and merely
-require the proper entry here and there in order to get things done.
-
-The first thing to do is to add an entry to arch/sh/Kconfig, under the
-"System type" menu::
-
-    config SH_VAPOR
-           bool "Vapor"
-           help
-           select Vapor if configuring for a FooTech Vaporboard.
-
-next, this has to be added into arch/sh/Makefile. All boards require a
-machdir-y entry in order to be built. This entry needs to be the name of
-the board directory as it appears in arch/sh/boards, even if it is in a
-sub-directory (in which case, all parent directories below arch/sh/boards/
-need to be listed). For our new board, this entry can look like::
-
-    machdir-$(CONFIG_SH_VAPOR) += vapor
-
-provided that we've placed everything in the arch/sh/boards/vapor/ directory.
-
-Next, the build system assumes that your include/asm-sh directory will also
-be named the same. If this is not the case (as is the case with multiple
-boards belonging to a common family), then the directory name needs to be
-implicitly appended to incdir-y. The existing code manages this for the
-Solution Engine and hp6xx boards, so see these for an example.
-
-Once that is taken care of, it's time to add an entry for the mach type.
-This is done by adding an entry to the end of the arch/sh/tools/mach-types
-list. The method for doing this is self explanatory, and so we won't waste
-space restating it here. After this is done, you will be able to use
-implicit checks for your board if you need this somewhere throughout the
-common code, such as::
-
-       /* Make sure we're on the FooTech Vaporboard */
-       if (!mach_is_vapor())
-               return -ENODEV;
-
-also note that the mach_is_boardname() check will be implicitly forced to
-lowercase, regardless of the fact that the mach-types entries are all
-uppercase. You can read the script if you really care, but it's pretty ugly,
-so you probably don't want to do that.
-
-Now all that's left to do is providing a defconfig for your new board. This
-way, other people who end up with this board can simply use this config
-for reference instead of trying to guess what settings are supposed to be
-used on it.
-
-Also, as soon as you have copied over a sample .config for your new board
-(assume arch/sh/configs/vapor_defconfig), you can also use this directly as a
-build target, and it will be implicitly listed as such in the help text.
-
-Looking at the 'make help' output, you should now see something like:
-
-Architecture specific targets (sh):
-
-  =======================   =============================================
-  zImage                    Compressed kernel image (arch/sh/boot/zImage)
-  adx_defconfig             Build for adx
-  cqreek_defconfig          Build for cqreek
-  dreamcast_defconfig       Build for dreamcast
-  ...
-  vapor_defconfig           Build for vapor
-  =======================   =============================================
-
-which then allows you to do::
-
-    $ make ARCH=sh CROSS_COMPILE=sh4-linux- vapor_defconfig vmlinux
-
-which will in turn copy the defconfig for this board, run it through
-oldconfig (prompting you for any new options since the time of creation),
-and start you on your way to having a functional kernel for your new
-board.
diff --git a/Documentation/sh/register-banks.rst b/Documentation/sh/register-banks.rst
deleted file mode 100644 (file)
index 2bef5c8..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-==========================================
-Notes on register bank usage in the kernel
-==========================================
-
-Introduction
-------------
-
-The SH-3 and SH-4 CPU families traditionally include a single partial register
-bank (selected by SR.RB, only r0 ... r7 are banked), whereas other families
-may have more full-featured banking or simply no such capabilities at all.
-
-SR.RB banking
--------------
-
-In the case of this type of banking, banked registers are mapped directly to
-r0 ... r7 if SR.RB is set to the bank we are interested in, otherwise ldc/stc
-can still be used to reference the banked registers (as r0_bank ... r7_bank)
-when in the context of another bank. The developer must keep the SR.RB value
-in mind when writing code that utilizes these banked registers, for obvious
-reasons. Userspace is also not able to poke at the bank1 values, so these can
-be used rather effectively as scratch registers by the kernel.
-
-Presently the kernel uses several of these registers.
-
-       - r0_bank, r1_bank (referenced as k0 and k1, used for scratch
-         registers when doing exception handling).
-
-       - r2_bank (used to track the EXPEVT/INTEVT code)
-
-               - Used by do_IRQ() and friends for doing irq mapping based off
-                 of the interrupt exception vector jump table offset
-
-       - r6_bank (global interrupt mask)
-
-               - The SR.IMASK interrupt handler makes use of this to set the
-                 interrupt priority level (used by local_irq_enable())
-
-       - r7_bank (current)
index 9b52f50a68542b932879f054bdd6b436ee7658a1..1204304500147637407240907078f17029999614 100644 (file)
@@ -704,7 +704,7 @@ ref
 no-jd
     BIOS setup but without jack-detection
 intel
-    Intel DG45* mobos
+    Intel D*45* mobos
 dell-m6-amic
     Dell desktops/laptops with analog mics
 dell-m6-dmic
diff --git a/Documentation/sparc/adi.rst b/Documentation/sparc/adi.rst
deleted file mode 100644 (file)
index dbcd8b6..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-================================
-Application Data Integrity (ADI)
-================================
-
-SPARC M7 processor adds the Application Data Integrity (ADI) feature.
-ADI allows a task to set version tags on any subset of its address
-space. Once ADI is enabled and version tags are set for ranges of
-address space of a task, the processor will compare the tag in pointers
-to memory in these ranges to the version set by the application
-previously. Access to memory is granted only if the tag in given pointer
-matches the tag set by the application. In case of mismatch, processor
-raises an exception.
-
-Following steps must be taken by a task to enable ADI fully:
-
-1. Set the user mode PSTATE.mcde bit. This acts as master switch for
-   the task's entire address space to enable/disable ADI for the task.
-
-2. Set TTE.mcd bit on any TLB entries that correspond to the range of
-   addresses ADI is being enabled on. MMU checks the version tag only
-   on the pages that have TTE.mcd bit set.
-
-3. Set the version tag for virtual addresses using stxa instruction
-   and one of the MCD specific ASIs. Each stxa instruction sets the
-   given tag for one ADI block size number of bytes. This step must
-   be repeated for entire page to set tags for entire page.
-
-ADI block size for the platform is provided by the hypervisor to kernel
-in machine description tables. Hypervisor also provides the number of
-top bits in the virtual address that specify the version tag.  Once
-version tag has been set for a memory location, the tag is stored in the
-physical memory and the same tag must be present in the ADI version tag
-bits of the virtual address being presented to the MMU. For example on
-SPARC M7 processor, MMU uses bits 63-60 for version tags and ADI block
-size is same as cacheline size which is 64 bytes. A task that sets ADI
-version to, say 10, on a range of memory, must access that memory using
-virtual addresses that contain 0xa in bits 63-60.
-
-ADI is enabled on a set of pages using mprotect() with PROT_ADI flag.
-When ADI is enabled on a set of pages by a task for the first time,
-kernel sets the PSTATE.mcde bit for the task. Version tags for memory
-addresses are set with an stxa instruction on the addresses using
-ASI_MCD_PRIMARY or ASI_MCD_ST_BLKINIT_PRIMARY. ADI block size is
-provided by the hypervisor to the kernel.  Kernel returns the value of
-ADI block size to userspace using auxiliary vector along with other ADI
-info. Following auxiliary vectors are provided by the kernel:
-
-       ============    ===========================================
-       AT_ADI_BLKSZ    ADI block size. This is the granularity and
-                       alignment, in bytes, of ADI versioning.
-       AT_ADI_NBITS    Number of ADI version bits in the VA
-       ============    ===========================================
-
-
-IMPORTANT NOTES
-===============
-
-- Version tag values of 0x0 and 0xf are reserved. These values match any
-  tag in virtual address and never generate a mismatch exception.
-
-- Version tags are set on virtual addresses from userspace even though
-  tags are stored in physical memory. Tags are set on a physical page
-  after it has been allocated to a task and a pte has been created for
-  it.
-
-- When a task frees a memory page it had set version tags on, the page
-  goes back to free page pool. When this page is re-allocated to a task,
-  kernel clears the page using block initialization ASI which clears the
-  version tags as well for the page. If a page allocated to a task is
-  freed and allocated back to the same task, old version tags set by the
-  task on that page will no longer be present.
-
-- ADI tag mismatches are not detected for non-faulting loads.
-
-- Kernel does not set any tags for user pages and it is entirely a
-  task's responsibility to set any version tags. Kernel does ensure the
-  version tags are preserved if a page is swapped out to the disk and
-  swapped back in. It also preserves that version tags if a page is
-  migrated.
-
-- ADI works for any size pages. A userspace task need not be aware of
-  page size when using ADI. It can simply select a virtual address
-  range, enable ADI on the range using mprotect() and set version tags
-  for the entire range. mprotect() ensures range is aligned to page size
-  and is a multiple of page size.
-
-- ADI tags can only be set on writable memory. For example, ADI tags can
-  not be set on read-only mappings.
-
-
-
-ADI related traps
-=================
-
-With ADI enabled, following new traps may occur:
-
-Disrupting memory corruption
-----------------------------
-
-       When a store accesses a memory location that has TTE.mcd=1,
-       the task is running with ADI enabled (PSTATE.mcde=1), and the ADI
-       tag in the address used (bits 63:60) does not match the tag set on
-       the corresponding cacheline, a memory corruption trap occurs. By
-       default, it is a disrupting trap and is sent to the hypervisor
-       first. Hypervisor creates a sun4v error report and sends a
-       resumable error (TT=0x7e) trap to the kernel. The kernel sends
-       a SIGSEGV to the task that resulted in this trap with the following
-       info::
-
-               siginfo.si_signo = SIGSEGV;
-               siginfo.errno = 0;
-               siginfo.si_code = SEGV_ADIDERR;
-               siginfo.si_addr = addr; /* PC where first mismatch occurred */
-               siginfo.si_trapno = 0;
-
-
-Precise memory corruption
--------------------------
-
-       When a store accesses a memory location that has TTE.mcd=1,
-       the task is running with ADI enabled (PSTATE.mcde=1), and the ADI
-       tag in the address used (bits 63:60) does not match the tag set on
-       the corresponding cacheline, a memory corruption trap occurs. If
-       MCD precise exception is enabled (MCDPERR=1), a precise
-       exception is sent to the kernel with TT=0x1a. The kernel sends
-       a SIGSEGV to the task that resulted in this trap with the following
-       info::
-
-               siginfo.si_signo = SIGSEGV;
-               siginfo.errno = 0;
-               siginfo.si_code = SEGV_ADIPERR;
-               siginfo.si_addr = addr; /* address that caused trap */
-               siginfo.si_trapno = 0;
-
-       NOTE:
-               ADI tag mismatch on a load always results in precise trap.
-
-
-MCD disabled
-------------
-
-       When a task has not enabled ADI and attempts to set ADI version
-       on a memory address, processor sends an MCD disabled trap. This
-       trap is handled by hypervisor first and the hypervisor vectors this
-       trap through to the kernel as Data Access Exception trap with
-       fault type set to 0xa (invalid ASI). When this occurs, the kernel
-       sends the task SIGSEGV signal with following info::
-
-               siginfo.si_signo = SIGSEGV;
-               siginfo.errno = 0;
-               siginfo.si_code = SEGV_ACCADI;
-               siginfo.si_addr = addr; /* address that caused trap */
-               siginfo.si_trapno = 0;
-
-
-Sample program to use ADI
--------------------------
-
-Following sample program is meant to illustrate how to use the ADI
-functionality::
-
-  #include <unistd.h>
-  #include <stdio.h>
-  #include <stdlib.h>
-  #include <elf.h>
-  #include <sys/ipc.h>
-  #include <sys/shm.h>
-  #include <sys/mman.h>
-  #include <asm/asi.h>
-
-  #ifndef AT_ADI_BLKSZ
-  #define AT_ADI_BLKSZ 48
-  #endif
-  #ifndef AT_ADI_NBITS
-  #define AT_ADI_NBITS 49
-  #endif
-
-  #ifndef PROT_ADI
-  #define PROT_ADI     0x10
-  #endif
-
-  #define BUFFER_SIZE     32*1024*1024UL
-
-  main(int argc, char* argv[], char* envp[])
-  {
-          unsigned long i, mcde, adi_blksz, adi_nbits;
-          char *shmaddr, *tmp_addr, *end, *veraddr, *clraddr;
-          int shmid, version;
-       Elf64_auxv_t *auxv;
-
-       adi_blksz = 0;
-
-       while(*envp++ != NULL);
-       for (auxv = (Elf64_auxv_t *)envp; auxv->a_type != AT_NULL; auxv++) {
-               switch (auxv->a_type) {
-               case AT_ADI_BLKSZ:
-                       adi_blksz = auxv->a_un.a_val;
-                       break;
-               case AT_ADI_NBITS:
-                       adi_nbits = auxv->a_un.a_val;
-                       break;
-               }
-       }
-       if (adi_blksz == 0) {
-               fprintf(stderr, "Oops! ADI is not supported\n");
-               exit(1);
-       }
-
-       printf("ADI capabilities:\n");
-       printf("\tBlock size = %ld\n", adi_blksz);
-       printf("\tNumber of bits = %ld\n", adi_nbits);
-
-          if ((shmid = shmget(2, BUFFER_SIZE,
-                                  IPC_CREAT | SHM_R | SHM_W)) < 0) {
-                  perror("shmget failed");
-                  exit(1);
-          }
-
-          shmaddr = shmat(shmid, NULL, 0);
-          if (shmaddr == (char *)-1) {
-                  perror("shm attach failed");
-                  shmctl(shmid, IPC_RMID, NULL);
-                  exit(1);
-          }
-
-       if (mprotect(shmaddr, BUFFER_SIZE, PROT_READ|PROT_WRITE|PROT_ADI)) {
-               perror("mprotect failed");
-               goto err_out;
-       }
-
-          /* Set the ADI version tag on the shm segment
-           */
-          version = 10;
-          tmp_addr = shmaddr;
-          end = shmaddr + BUFFER_SIZE;
-          while (tmp_addr < end) {
-                  asm volatile(
-                          "stxa %1, [%0]0x90\n\t"
-                          :
-                          : "r" (tmp_addr), "r" (version));
-                  tmp_addr += adi_blksz;
-          }
-       asm volatile("membar #Sync\n\t");
-
-          /* Create a versioned address from the normal address by placing
-        * version tag in the upper adi_nbits bits
-           */
-          tmp_addr = (void *) ((unsigned long)shmaddr << adi_nbits);
-          tmp_addr = (void *) ((unsigned long)tmp_addr >> adi_nbits);
-          veraddr = (void *) (((unsigned long)version << (64-adi_nbits))
-                          | (unsigned long)tmp_addr);
-
-          printf("Starting the writes:\n");
-          for (i = 0; i < BUFFER_SIZE; i++) {
-                  veraddr[i] = (char)(i);
-                  if (!(i % (1024 * 1024)))
-                          printf(".");
-          }
-          printf("\n");
-
-          printf("Verifying data...");
-       fflush(stdout);
-          for (i = 0; i < BUFFER_SIZE; i++)
-                  if (veraddr[i] != (char)i)
-                          printf("\nIndex %lu mismatched\n", i);
-          printf("Done.\n");
-
-          /* Disable ADI and clean up
-           */
-       if (mprotect(shmaddr, BUFFER_SIZE, PROT_READ|PROT_WRITE)) {
-               perror("mprotect failed");
-               goto err_out;
-       }
-
-          if (shmdt((const void *)shmaddr) != 0)
-                  perror("Detach failure");
-          shmctl(shmid, IPC_RMID, NULL);
-
-          exit(0);
-
-  err_out:
-          if (shmdt((const void *)shmaddr) != 0)
-                  perror("Detach failure");
-          shmctl(shmid, IPC_RMID, NULL);
-          exit(1);
-  }
diff --git a/Documentation/sparc/console.rst b/Documentation/sparc/console.rst
deleted file mode 100644 (file)
index 73132db..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-Steps for sending 'break' on sunhv console
-==========================================
-
-On Baremetal:
-   1. press   Esc + 'B'
-
-On LDOM:
-   1. press    Ctrl + ']'
-   2. telnet> send  break
diff --git a/Documentation/sparc/features.rst b/Documentation/sparc/features.rst
deleted file mode 100644 (file)
index c0c9246..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. kernel-feat:: $srctree/Documentation/features sparc
diff --git a/Documentation/sparc/index.rst b/Documentation/sparc/index.rst
deleted file mode 100644 (file)
index ae88422..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-==================
-Sparc Architecture
-==================
-
-.. toctree::
-   :maxdepth: 1
-
-   console
-   adi
-
-   oradax/oracle-dax
-
-   features
diff --git a/Documentation/sparc/oradax/dax-hv-api.txt b/Documentation/sparc/oradax/dax-hv-api.txt
deleted file mode 100644 (file)
index 7ecd0bf..0000000
+++ /dev/null
@@ -1,1433 +0,0 @@
-Excerpt from UltraSPARC Virtual Machine Specification
-Compiled from version 3.0.20+15
-Publication date 2017-09-25 08:21
-Copyright © 2008, 2015 Oracle and/or its affiliates. All rights reserved.
-Extracted via "pdftotext -f 547 -l 572 -layout sun4v_20170925.pdf"
-Authors:
-        Charles Kunzman
-        Sam Glidden
-        Mark Cianchetti
-
-
-Chapter 36. Coprocessor services
-        The following APIs provide access via the Hypervisor to hardware assisted data processing functionality.
-        These APIs may only be provided by certain platforms, and may not be available to all virtual machines
-        even on supported platforms. Restrictions on the use of these APIs may be imposed in order to support
-        live-migration and other system management activities.
-
-36.1. Data Analytics Accelerator
-        The Data Analytics Accelerator (DAX) functionality is a collection of hardware coprocessors that provide
-        high speed processoring of database-centric operations. The coprocessors may support one or more of
-        the following data query operations: search, extraction, compression, decompression, and translation. The
-        functionality offered may vary by virtual machine implementation.
-
-        The DAX is a virtual device to sun4v guests, with supported data operations indicated by the virtual device
-        compatibility property. Functionality is accessed through the submission of Command Control Blocks
-        (CCBs) via the ccb_submit API function. The operations are processed asynchronously, with the status
-        of the submitted operations reported through a Completion Area linked to each CCB. Each CCB has a
-        separate Completion Area and, unless execution order is specifically restricted through the use of serial-
-        conditional flags, the execution order of submitted CCBs is arbitrary. Likewise, the time to completion
-        for a given CCB is never guaranteed.
-
-        Guest software may implement a software timeout on CCB operations, and if the timeout is exceeded, the
-        operation may be cancelled or killed via the ccb_kill API function. It is recommended for guest software
-        to implement a software timeout to account for certain RAS errors which may result in lost CCBs. It is
-        recommended such implementation use the ccb_info API function to check the status of a CCB prior to
-        killing it in order to determine if the CCB is still in queue, or may have been lost due to a RAS error.
-
-        There is no fixed limit on the number of outstanding CCBs guest software may have queued in the virtual
-        machine, however, internal resource limitations within the virtual machine can cause CCB submissions
-        to be temporarily rejected with EWOULDBLOCK. In such cases, guests should continue to attempt
-        submissions until they succeed; waiting for an outstanding CCB to complete is not necessary, and would
-        not be a guarantee that a future submission would succeed.
-
-        The availablility of DAX coprocessor command service is indicated by the presence of the DAX virtual
-        device node in the guest MD (Section 8.24.17, “Database Analytics Accelerators (DAX) virtual-device
-        node”).
-
-36.1.1. DAX Compatibility Property
-        The query functionality may vary based on the compatibility property of the virtual device:
-
-36.1.1.1. "ORCL,sun4v-dax" Device Compatibility
-        Available CCB commands:
-
-        • No-op/Sync
-
-        • Extract
-
-        • Scan Value
-
-        • Inverted Scan Value
-
-        • Scan Range
-
-
-                                                     509
-\f                                             Coprocessor services
-
-
-        • Inverted Scan Range
-
-        • Translate
-
-        • Inverted Translate
-
-        • Select
-
-        See Section 36.2.1, “Query CCB Command Formats” for the corresponding CCB input and output formats.
-
-        Only version 0 CCBs are available.
-
-36.1.1.2. "ORCL,sun4v-dax-fc" Device Compatibility
-        "ORCL,sun4v-dax-fc" is compatible with the "ORCL,sun4v-dax" interface, and includes additional CCB
-        bit fields and controls.
-
-36.1.1.3. "ORCL,sun4v-dax2" Device Compatibility
-        Available CCB commands:
-
-        • No-op/Sync
-
-        • Extract
-
-        • Scan Value
-
-        • Inverted Scan Value
-
-        • Scan Range
-
-        • Inverted Scan Range
-
-        • Translate
-
-        • Inverted Translate
-
-        • Select
-
-        See Section 36.2.1, “Query CCB Command Formats” for the corresponding CCB input and output formats.
-
-        Version 0 and 1 CCBs are available. Only version 0 CCBs may use Huffman encoded data, whereas only
-        version 1 CCBs may use OZIP.
-
-36.1.2. DAX Virtual Device Interrupts
-        The DAX virtual device has multiple interrupts associated with it which may be used by the guest if
-        desired. The number of device interrupts available to the guest is indicated in the virtual device node of the
-        guest MD (Section 8.24.17, “Database Analytics Accelerators (DAX) virtual-device node”). If the device
-        node indicates N interrupts available, the guest may use any value from 0 to N - 1 (inclusive) in a CCB
-        interrupt number field. Using values outside this range will result in the CCB being rejected for an invalid
-        field value.
-
-        The interrupts may be bound and managed using the standard sun4v device interrupts API (Chapter 16,
-        Device interrupt services). Sysino interrupts are not available for DAX devices.
-
-36.2. Coprocessor Control Block (CCB)
-        CCBs are either 64 or 128 bytes long, depending on the operation type. The exact contents of the CCB
-        are command specific, but all CCBs contain at least one memory buffer address. All memory locations
-
-
-                                                      510
-\f                                    Coprocessor services
-
-
-referenced by a CCB must be pinned in memory until the CCB either completes execution or is killed
-via the ccb_kill API call. Changes in virtual address mappings occurring after CCB submission are not
-guaranteed to be visible, and as such all virtual address updates need to be synchronized with CCB
-execution.
-
-All CCBs begin with a common 32-bit header.
-
-Table 36.1. CCB Header Format
-Bits          Field Description
-[31:28]       CCB version. For API version 2.0: set to 1 if CCB uses OZIP encoding; set to 0 if the CCB
-              uses Huffman encoding; otherwise either 0 or 1. For API version 1.0: always set to 0.
-[27]          When API version 2.0 is negotiated, this is the Pipeline Flag [512]. It is reserved in
-              API version 1.0
-[26]          Long CCB flag [512]
-[25]          Conditional synchronization flag [512]
-[24]          Serial synchronization flag
-[23:16]       CCB operation code:
-               0x00        No Operation (No-op) or Sync
-               0x01        Extract
-               0x02        Scan Value
-               0x12        Inverted Scan Value
-               0x03        Scan Range
-               0x13        Inverted Scan Range
-               0x04        Translate
-               0x14        Inverted Translate
-               0x05        Select
-[15:13]       Reserved
-[12:11]       Table address type
-               0b'00       No address
-               0b'01       Alternate context virtual address
-               0b'10       Real address
-               0b'11       Primary context virtual address
-[10:8]        Output/Destination address type
-               0b'000      No address
-               0b'001      Alternate context virtual address
-               0b'010      Real address
-               0b'011      Primary context virtual address
-               0b'100      Reserved
-               0b'101      Reserved
-               0b'110      Reserved
-               0b'111      Reserved
-[7:5]         Secondary source address type
-
-
-                                            511
-\f                                    Coprocessor services
-
-
-Bits           Field Description
-                0b'000       No address
-                0b'001       Alternate context virtual address
-                0b'010       Real address
-                0b'011       Primary context virtual address
-                0b'100       Reserved
-                0b'101       Reserved
-                0b'110       Reserved
-                0b'111       Reserved
-[4:2]          Primary source address type
-                0b'000       No address
-                0b'001       Alternate context virtual address
-                0b'010       Real address
-                0b'011       Primary context virtual address
-                0b'100       Reserved
-                0b'101       Reserved
-                0b'110       Reserved
-                0b'111       Reserved
-[1:0]          Completion area address type
-                0b'00        No address
-                0b'01        Alternate context virtual address
-                0b'10        Real address
-                0b'11        Primary context virtual address
-
-The Long CCB flag indicates whether the submitted CCB is 64 or 128 bytes long; value is 0 for 64 bytes
-and 1 for 128 bytes.
-
-The Serial and Conditional flags allow simple relative ordering between CCBs. Any CCB with the Serial
-flag set will execute sequentially relative to any previous CCB that is also marked as Serial in the same
-CCB submission. CCBs without the Serial flag set execute independently, even if they are between CCBs
-with the Serial flag set. CCBs marked solely with the Serial flag will execute upon the completion of the
-previous Serial CCB, regardless of the completion status of that CCB. The Conditional flag allows CCBs
-to conditionally execute based on the successful execution of the closest CCB marked with the Serial flag.
-A CCB may only be conditional on exactly one CCB, however, a CCB may be marked both Conditional
-and Serial to allow execution chaining. The flags do NOT allow fan-out chaining, where multiple CCBs
-execute in parallel based on the completion of another CCB.
-
-The Pipeline flag is an optimization that directs the output of one CCB (the "source" CCB) directly to
-the input of the next CCB (the "target" CCB). The target CCB thus does not need to read the input from
-memory. The Pipeline flag is advisory and may be dropped.
-
-Both the Pipeline and Serial bits must be set in the source CCB. The Conditional bit must be set in the
-target CCB. Exactly one CCB must be made conditional on the source CCB; either 0 or 2 target CCBs
-is invalid. However, Pipelines can be extended beyond two CCBs: the sequence would start with a CCB
-with both the Pipeline and Serial bits set, proceed through CCBs with the Pipeline, Serial, and Conditional
-bits set, and terminate at a CCB that has the Conditional bit set, but not the Pipeline bit.
-
-
-                                             512
-\f                                               Coprocessor services
-
-
-          The input of the target CCB must start within 64 bytes of the output of the source CCB or the pipeline flag
-          will be ignored. All CCBs in a pipeline must be submitted in the same call to ccb_submit.
-
-          The various address type fields indicate how the various address values used in the CCB should be
-          interpreted by the virtual machine. Not all of the types specified are used by every CCB format. Types
-          which are not applicable to the given CCB command should be indicated as type 0 (No address). Virtual
-          addresses used in the CCB must have translation entries present in either the TLB or a configured TSB
-          for the submitting virtual processor. Virtual addresses which cannot be translated by the virtual machine
-          will result in the CCB submission being rejected, with the causal virtual address indicated. The CCB
-          may be resubmitted after inserting the translation, or the address may be translated by guest software and
-          resubmitted using the real address translation.
-
-36.2.1. Query CCB Command Formats
-36.2.1.1. Supported Data Formats, Elements Sizes and Offsets
-          Data for query commands may be encoded in multiple possible formats. The data query commands use a
-          common set of values to indicate the encoding formats of the data being processed. Some encoding formats
-          require multiple data streams for processing, requiring the specification of both primary data formats (the
-          encoded data) and secondary data streams (meta-data for the encoded data).
-
-36.2.1.1.1. Primary Input Format
-
-          The primary input format code is a 4-bit field when it is used. There are 10 primary input formats available.
-          The packed formats are not endian neutral. Code values not listed below are reserved.
-
-          Code        Format                              Description
-          0x0         Fixed width byte packed             Up to 16 bytes
-          0x1         Fixed width bit packed              Up to 15 bits (CCB version 0) or 23 bits (CCB version
-                                                          1); bits are read most significant bit to least significant bit
-                                                          within a byte
-          0x2         Variable width byte packed          Data stream of lengths must be provided as a secondary
-                                                          input
-          0x4         Fixed width byte packed with run Up to 16 bytes; data stream of run lengths must be
-                      length encoding                  provided as a secondary input
-          0x5         Fixed width bit packed with run Up to 15 bits (CCB version 0) or 23 bits (CCB version
-                      length encoding                 1); bits are read most significant bit to least significant bit
-                                                      within a byte; data stream of run lengths must be provided
-                                                      as a secondary input
-          0x8         Fixed width byte packed with Up to 16 bytes before the encoding; compressed stream
-                      Huffman (CCB version 0) or bits are read most significant bit to least significant bit
-                      OZIP (CCB version 1) encoding within a byte; pointer to the encoding table must be
-                                                    provided
-          0x9         Fixed width bit packed with Up to 15 bits (CCB version 0) or 23 bits (CCB version
-                      Huffman (CCB version 0) or 1); compressed stream bits are read most significant bit to
-                      OZIP (CCB version 1) encoding least significant bit within a byte; pointer to the encoding
-                                                    table must be provided
-          0xA         Variable width byte packed with Up to 16 bytes before the encoding; compressed stream
-                      Huffman (CCB version 0) or bits are read most significant bit to least significant bit
-                      OZIP (CCB version 1) encoding within a byte; data stream of lengths must be provided as
-                                                      a secondary input; pointer to the encoding table must be
-                                                      provided
-
-
-                                                        513
-\f                                               Coprocessor services
-
-
-          Code        Format                              Description
-          0xC         Fixed width byte packed with        Up to 16 bytes before the encoding; compressed stream
-                      run length encoding, followed by    bits are read most significant bit to least significant bit
-                      Huffman (CCB version 0) or          within a byte; data stream of run lengths must be provided
-                      OZIP (CCB version 1) encoding       as a secondary input; pointer to the encoding table must
-                                                          be provided
-          0xD         Fixed width bit packed with         Up to 15 bits (CCB version 0) or 23 bits(CCB version 1)
-                      run length encoding, followed by    before the encoding; compressed stream bits are read most
-                      Huffman (CCB version 0) or          significant bit to least significant bit within a byte; data
-                      OZIP (CCB version 1) encoding       stream of run lengths must be provided as a secondary
-                                                          input; pointer to the encoding table must be provided
-
-          If OZIP encoding is used, there must be no reserved bytes in the table.
-
-36.2.1.1.2. Primary Input Element Size
-
-          For primary input data streams with fixed size elements, the element size must be indicated in the CCB
-          command. The size is encoded as the number of bits or bytes, minus one. The valid value range for this
-          field depends on the input format selected, as listed in the table above.
-
-36.2.1.1.3. Secondary Input Format
-
-          For primary input data streams which require a secondary input stream, the secondary input stream is
-          always encoded in a fixed width, bit-packed format. The bits are read from most significant bit to least
-          significant bit within a byte. There are two encoding options for the secondary input stream data elements,
-          depending on whether the value of 0 is needed:
-
-          Secondary           Input Description
-          Format Code
-          0                          Element is stored as value minus 1 (0 evaluates to 1, 1 evaluates
-                                     to 2, etc)
-          1                          Element is stored as value
-
-36.2.1.1.4. Secondary Input Element Size
-
-          Secondary input element size is encoded as a two bit field:
-
-          Secondary Input Size Description
-          Code
-          0x0                        1 bit
-          0x1                        2 bits
-          0x2                        4 bits
-          0x3                        8 bits
-
-36.2.1.1.5. Input Element Offsets
-
-          Bit-wise input data streams may have any alignment within the base addressed byte. The offset, specified
-          from most significant bit to least significant bit, is provided as a fixed 3 bit field for each input type. A
-          value of 0 indicates that the first input element begins at the most significant bit in the first byte, and a
-          value of 7 indicates it begins with the least significant bit.
-
-          This field should be zero for any byte-wise primary input data streams.
-
-
-                                                        514
-\f                                              Coprocessor services
-
-
-36.2.1.1.6. Output Format
-
-          Query commands support multiple sizes and encodings for output data streams. There are four possible
-          output encodings, and up to four supported element sizes per encoding. Not all output encodings are
-          supported for every command. The format is indicated by a 4-bit field in the CCB:
-
-           Output Format Code        Description
-           0x0                       Byte aligned, 1 byte elements
-           0x1                       Byte aligned, 2 byte elements
-           0x2                       Byte aligned, 4 byte elements
-           0x3                       Byte aligned, 8 byte elements
-           0x4                       16 byte aligned, 16 byte elements
-           0x5                       Reserved
-           0x6                       Reserved
-           0x7                       Reserved
-           0x8                       Packed vector of single bit elements
-           0x9                       Reserved
-           0xA                       Reserved
-           0xB                       Reserved
-           0xC                       Reserved
-           0xD                       2 byte elements where each element is the index value of a bit,
-                                     from an bit vector, which was 1.
-           0xE                       4 byte elements where each element is the index value of a bit,
-                                     from an bit vector, which was 1.
-           0xF                       Reserved
-
-36.2.1.1.7. Application Data Integrity (ADI)
-
-          On platforms which support ADI, the ADI version number may be specified for each separate memory
-          access type used in the CCB command. ADI checking only occurs when reading data. When writing data,
-          the specified ADI version number overwrites any existing ADI value in memory.
-
-          An ADI version value of 0 or 0xF indicates the ADI checking is disabled for that data access, even if it is
-          enabled in memory. By setting the appropriate flag in CCB_SUBMIT (Section 36.3.1, “ccb_submit”) it is
-          also an option to disable ADI checking for all inputs accessed via virtual address for all CCBs submitted
-          during that hypercall invocation.
-
-          The ADI value is only guaranteed to be checked on the first 64 bytes of each data access. Mismatches on
-          subsequent data chunks may not be detected, so guest software should be careful to use page size checking
-          to protect against buffer overruns.
-
-36.2.1.1.8. Page size checking
-
-          All data accesses used in CCB commands must be bounded within a single memory page. When addresses
-          are provided using a virtual address, the page size for checking is extracted from the TTE for that virtual
-          address. When using real addresses, the guest must supply the page size in the same field as the address
-          value. The page size must be one of the sizes supported by the underlying virtual machine. Using a value
-          that is not supported may result in the CCB submission being rejected or the generation of a CCB parsing
-          error in the completion area.
-
-
-                                                       515
-\f                                               Coprocessor services
-
-
-36.2.1.2. Extract command
-
-        Converts an input vector in one format to an output vector in another format. All input format types are
-        supported.
-
-        The only supported output format is a padded, byte-aligned output stream, using output codes 0x0 - 0x4.
-        When the specified output element size is larger than the extracted input element size, zeros are padded to
-        the extracted input element. First, if the decompressed input size is not a whole number of bytes, 0 bits are
-        padded to the most significant bit side till the next byte boundary. Next, if the output element size is larger
-        than the byte padded input element, bytes of value 0 are added based on the Padding Direction bit in the
-        CCB. If the output element size is smaller than the byte-padded input element size, the input element is
-        truncated by dropped from the least significant byte side until the selected output size is reached.
-
-        The return value of the CCB completion area is invalid. The “number of elements processed” field in the
-        CCB completion area will be valid.
-
-        The extract CCB is a 64-byte “short format” CCB.
-
-        The extract CCB command format can be specified by the following packed C structure for a big-endian
-        machine:
-
-
-                  struct extract_ccb {
-                         uint32_t header;
-                         uint32_t control;
-                         uint64_t completion;
-                         uint64_t primary_input;
-                         uint64_t data_access_control;
-                         uint64_t secondary_input;
-                         uint64_t reserved;
-                         uint64_t output;
-                         uint64_t table;
-                  };
-
-
-        The exact field offsets, sizes, and composition are as follows:
-
-         Offset         Size            Field Description
-         0              4               CCB header (Table 36.1, “CCB Header Format”)
-         4              4               Command control
-                                        Bits        Field Description
-                                        [31:28]     Primary Input Format (see Section 36.2.1.1.1, “Primary Input
-                                                    Format”)
-                                        [27:23]     Primary Input Element Size (see Section 36.2.1.1.2, “Primary
-                                                    Input Element Size”)
-                                        [22:20]     Primary Input Starting Offset (see Section 36.2.1.1.5, “Input
-                                                    Element Offsets”)
-                                        [19]        Secondary Input Format (see Section 36.2.1.1.3, “Secondary
-                                                    Input Format”)
-                                        [18:16]     Secondary Input Starting Offset (see Section 36.2.1.1.5, “Input
-                                                    Element Offsets”)
-
-
-                                                       516
-\f                        Coprocessor services
-
-
-Offset   Size   Field Description
-                Bits         Field Description
-                [15:14]      Secondary Input Element Size (see Section 36.2.1.1.4,
-                             “Secondary Input Element Size”
-                [13:10]      Output Format (see Section 36.2.1.1.6, “Output Format”)
-                [9]          Padding Direction selector: A value of 1 causes padding bytes
-                             to be added to the left side of output elements. A value of 0
-                             causes padding bytes to be added to the right side of output
-                             elements.
-                [8:0]        Reserved
-8        8      Completion
-                Bits         Field Description
-                [63:60]      ADI version (see Section 36.2.1.1.7, “Application Data
-                             Integrity (ADI)”)
-                [59]         If set to 1, a virtual device interrupt will be generated using
-                             the device interrupt number specified in the lower bits of this
-                             completion word. If 0, the lower bits of this completion word
-                             are ignored.
-                [58:6]       Completion area address bits [58:6]. Address type is
-                             determined by CCB header.
-                [5:0]        Virtual device interrupt number for completion interrupt, if
-                             enabled.
-16       8      Primary Input
-                Bits         Field Description
-                [63:60]      ADI version (see Section 36.2.1.1.7, “Application Data
-                             Integrity (ADI)”)
-                [59:56]      If using real address, these bits should be filled in with the
-                             page size code for the page boundary checking the guest wants
-                             the virtual machine to use when accessing this data stream
-                             (checking is only guaranteed to be performed when using API
-                             version 1.1 and later). If using a virtual address, this field will
-                             be used as as primary input address bits [59:56].
-                [55:0]       Primary input address bits [55:0]. Address type is determined
-                             by CCB header.
-24       8      Data Access Control
-                Bits         Field Description
-                [63:62]      Flow Control
-                             Value      Description
-                             0b'00      Disable flow control
-                             0b'01      Enable flow control (only valid with "ORCL,sun4v-
-                                        dax-fc" compatible virtual device variants)
-                             0b'10      Reserved
-                             0b'11      Reserved
-                [61:60]      Reserved (API 1.0)
-
-
-                                517
-\f                       Coprocessor services
-
-
-Offset   Size   Field Description
-                Bits        Field Description
-                            Pipeline target (API 2.0)
-                            Value      Description
-                            0b'00      Connect to primary input
-                            0b'01      Connect to secondary input
-                            0b'10      Reserved
-                            0b'11      Reserved
-                [59:40]     Output buffer size given in units of 64 bytes, minus 1. Value of
-                            0 means 64 bytes, value of 1 means 128 bytes, etc. Buffer size is
-                            only enforced if flow control is enabled in Flow Control field.
-                [39:32]     Reserved
-                [31:30]     Output Data Cache Allocation
-                            Value      Description
-                            0b'00      Do not allocate cache lines for output data stream.
-                            0b'01      Force cache lines for output data stream to be
-                                       allocated in the cache that is local to the submitting
-                                       virtual cpu.
-                            0b'10      Allocate cache lines for output data stream, but allow
-                                       existing cache lines associated with the data to remain
-                                       in their current cache instance. Any memory not
-                                       already in cache will be allocated in the cache local
-                                       to the submitting virtual cpu.
-                            0b'11      Reserved
-                [29:26]     Reserved
-                [25:24]     Primary Input Length Format
-                            Value      Description
-                            0b'00      Number of primary symbols
-                            0b'01      Number of primary bytes
-                            0b'10      Number of primary bits
-                            0b'11      Reserved
-                [23:0]      Primary Input Length
-                            Format                      Field Value
-                            # of primary symbols        Number of input elements to process,
-                                                        minus 1. Command execution stops
-                                                        once count is reached.
-                            # of primary bytes          Number of input bytes to process,
-                                                        minus 1. Command execution stops
-                                                        once count is reached. The count is
-                                                        done before any decompression or
-                                                        decoding.
-                            # of primary bits           Number of input bits to process,
-                                                        minus 1. Command execution stops
-
-
-
-                               518
-\f                                                Coprocessor services
-
-
-        Offset          Size           Field Description
-                                        Bits         Field Description
-                                                     Format                     Field Value
-                                                                                once count is reached. The count is
-                                                                                done before any decompression or
-                                                                                decoding, and does not include any
-                                                                                bits skipped by the Primary Input
-                                                                                Offset field value of the command
-                                                                                control word.
-        32              8              Secondary Input, if used by Primary Input Format. Same fields as Primary
-                                       Input.
-        40              8              Reserved
-        48              8              Output (same fields as Primary Input)
-        56              8              Symbol Table (if used by Primary Input)
-                                        Bits         Field Description
-                                        [63:60]      ADI version (see Section 36.2.1.1.7, “Application Data
-                                                     Integrity (ADI)”)
-                                        [59:56]      If using real address, these bits should be filled in with the
-                                                     page size code for the page boundary checking the guest wants
-                                                     the virtual machine to use when accessing this data stream
-                                                     (checking is only guaranteed to be performed when using API
-                                                     version 1.1 and later). If using a virtual address, this field will
-                                                     be used as as symbol table address bits [59:56].
-                                        [55:4]       Symbol table address bits [55:4]. Address type is determined
-                                                     by CCB header.
-                                        [3:0]        Symbol table version
-                                                     Value     Description
-                                                     0         Huffman encoding. Must use 64 byte aligned table
-                                                               address. (Only available when using version 0 CCBs)
-                                                     1         OZIP encoding. Must use 16 byte aligned table
-                                                               address. (Only available when using version 1 CCBs)
-
-
-36.2.1.3. Scan commands
-
-        The scan commands search a stream of input data elements for values which match the selection criteria.
-        All the input format types are supported. There are multiple formats for the scan commands, allowing the
-        scan to search for exact matches to one value, exact matches to either of two values, or any value within
-        a specified range. The specific type of scan is indicated by the command code in the CCB header. For the
-        scan range commands, the boundary conditions can be specified as greater-than-or-equal-to a value, less-
-        than-or-equal-to a value, or both by using two boundary values.
-
-        There are two supported formats for the output stream: the bit vector and index array formats (codes 0x8,
-        0xD, and 0xE). For the standard scan command using the bit vector output, for each input element there
-        exists one bit in the vector that is set if the input element matched the scan criteria, or clear if not. The
-        inverted scan command inverts the polarity of the bits in the output. The most significant bit of the first
-        byte of the output stream corresponds to the first element in the input stream. The standard index array
-        output format contains one array entry for each input element that matched the scan criteria. Each array
-
-
-
-                                                         519
-\f                                       Coprocessor services
-
-
-entry is the index of an input element that matched the scan criteria. An inverted scan command produces
-a similar array, but of all the input elements which did NOT match the scan criteria.
-
-The return value of the CCB completion area contains the number of input elements found which match
-the scan criteria (or number that did not match for the inverted scans). The “number of elements processed”
-field in the CCB completion area will be valid, indicating the number of input elements processed.
-
-These commands are 128-byte “long format” CCBs.
-
-The scan CCB command format can be specified by the following packed C structure for a big-endian
-machine:
-
-
-         struct scan_ccb         {
-                uint32_t         header;
-                uint32_t         control;
-                uint64_t         completion;
-                uint64_t         primary_input;
-                uint64_t         data_access_control;
-                uint64_t         secondary_input;
-                uint64_t         match_criteria0;
-                uint64_t         output;
-                uint64_t         table;
-                uint64_t         match_criteria1;
-                uint64_t         match_criteria2;
-                uint64_t         match_criteria3;
-                uint64_t         reserved[5];
-         };
-
-
-The exact field offsets, sizes, and composition are as follows:
-
-Offset         Size            Field Description
-0              4               CCB header (Table 36.1, “CCB Header Format”)
-4              4               Command control
-                               Bits         Field Description
-                               [31:28]      Primary Input Format (see Section 36.2.1.1.1, “Primary Input
-                                            Format”)
-                               [27:23]      Primary Input Element Size (see Section 36.2.1.1.2, “Primary
-                                            Input Element Size”)
-                               [22:20]      Primary Input Starting Offset (see Section 36.2.1.1.5, “Input
-                                            Element Offsets”)
-                               [19]         Secondary Input Format (see Section 36.2.1.1.3, “Secondary
-                                            Input Format”)
-                               [18:16]      Secondary Input Starting Offset (see Section 36.2.1.1.5, “Input
-                                            Element Offsets”)
-                               [15:14]      Secondary Input Element Size (see Section 36.2.1.1.4,
-                                            “Secondary Input Element Size”
-                               [13:10]      Output Format (see Section 36.2.1.1.6, “Output Format”)
-                               [9:5]        Operand size for first scan criteria value. In a scan value
-                                            operation, this is one of two potential exact match values.
-                                            In a scan range operation, this is the size of the upper range
-
-
-                                               520
-\f                        Coprocessor services
-
-
-Offset   Size   Field Description
-                Bits         Field Description
-                             boundary. The value of this field is the number of bytes in the
-                             operand, minus 1. Values 0xF-0x1E are reserved. A value of
-                             0x1F indicates this operand is not in use for this scan operation.
-                [4:0]        Operand size for second scan criteria value. In a scan value
-                             operation, this is one of two potential exact match values.
-                             In a scan range operation, this is the size of the lower range
-                             boundary. The value of this field is the number of bytes in the
-                             operand, minus 1. Values 0xF-0x1E are reserved. A value of
-                             0x1F indicates this operand is not in use for this scan operation.
-8        8      Completion (same fields as Section 36.2.1.2, “Extract command”)
-16       8      Primary Input (same fields as Section 36.2.1.2, “Extract command”)
-24       8      Data Access Control (same fields as Section 36.2.1.2, “Extract command”)
-32       8      Secondary Input, if used by Primary Input Format. Same fields as Primary
-                Input.
-40       4      Most significant 4 bytes of first scan criteria operand. If first operand is less
-                than 4 bytes, the value is left-aligned to the lowest address bytes.
-44       4      Most significant 4 bytes of second scan criteria operand. If second operand
-                is less than 4 bytes, the value is left-aligned to the lowest address bytes.
-48       8      Output (same fields as Primary Input)
-56       8      Symbol Table (if used by Primary Input). Same fields as Section 36.2.1.2,
-                “Extract command”
-64       4      Next 4 most significant bytes of first scan criteria operand occurring after the
-                bytes specified at offset 40, if needed by the operand size. If first operand
-                is less than 8 bytes, the valid bytes are left-aligned to the lowest address.
-68       4      Next 4 most significant bytes of second scan criteria operand occurring after
-                the bytes specified at offset 44, if needed by the operand size. If second
-                operand is less than 8 bytes, the valid bytes are left-aligned to the lowest
-                address.
-72       4      Next 4 most significant bytes of first scan criteria operand occurring after the
-                bytes specified at offset 64, if needed by the operand size. If first operand
-                is less than 12 bytes, the valid bytes are left-aligned to the lowest address.
-76       4      Next 4 most significant bytes of second scan criteria operand occurring after
-                the bytes specified at offset 68, if needed by the operand size. If second
-                operand is less than 12 bytes, the valid bytes are left-aligned to the lowest
-                address.
-80       4      Next 4 most significant bytes of first scan criteria operand occurring after the
-                bytes specified at offset 72, if needed by the operand size. If first operand
-                is less than 16 bytes, the valid bytes are left-aligned to the lowest address.
-84       4      Next 4 most significant bytes of second scan criteria operand occurring after
-                the bytes specified at offset 76, if needed by the operand size. If second
-                operand is less than 16 bytes, the valid bytes are left-aligned to the lowest
-                address.
-
-
-
-
-                                521
-\f                                               Coprocessor services
-
-
-36.2.1.4. Translate commands
-
-        The translate commands takes an input array of indices, and a table of single bit values indexed by those
-        indices, and outputs a bit vector or index array created by reading the tables bit value at each index in
-        the input array. The output should therefore contain exactly one bit per index in the input data stream,
-        when outputting as a bit vector. When outputting as an index array, the number of elements depends on the
-        values read in the bit table, but will always be less than, or equal to, the number of input elements. Only
-        a restricted subset of the possible input format types are supported. No variable width or Huffman/OZIP
-        encoded input streams are allowed. The primary input data element size must be 3 bytes or less.
-
-        The maximum table index size allowed is 15 bits, however, larger input elements may be used to provide
-        additional processing of the output values. If 2 or 3 byte values are used, the least significant 15 bits are
-        used as an index into the bit table. The most significant 9 bits (when using 3-byte input elements) or single
-        bit (when using 2-byte input elements) are compared against a fixed 9-bit test value provided in the CCB.
-        If the values match, the value from the bit table is used as the output element value. If the values do not
-        match, the output data element value is forced to 0.
-
-        In the inverted translate operation, the bit value read from bit table is inverted prior to its use. The additional
-        additional processing based on any additional non-index bits remains unchanged, and still forces the output
-        element value to 0 on a mismatch. The specific type of translate command is indicated by the command
-        code in the CCB header.
-
-        There are two supported formats for the output stream: the bit vector and index array formats (codes 0x8,
-        0xD, and 0xE). The index array format is an array of indices of bits which would have been set if the
-        output format was a bit array.
-
-        The return value of the CCB completion area contains the number of bits set in the output bit vector,
-        or number of elements in the output index array. The “number of elements processed” field in the CCB
-        completion area will be valid, indicating the number of input elements processed.
-
-        These commands are 64-byte “short format” CCBs.
-
-        The translate CCB command format can be specified by the following packed C structure for a big-endian
-        machine:
-
-
-                 struct translate_ccb {
-                        uint32_t header;
-                        uint32_t control;
-                        uint64_t completion;
-                        uint64_t primary_input;
-                        uint64_t data_access_control;
-                        uint64_t secondary_input;
-                        uint64_t reserved;
-                        uint64_t output;
-                        uint64_t table;
-                 };
-
-
-        The exact field offsets, sizes, and composition are as follows:
-
-
-        Offset          Size             Field Description
-        0               4                CCB header (Table 36.1, “CCB Header Format”)
-
-
-                                                        522
-\f                        Coprocessor services
-
-
-Offset   Size   Field Description
-4        4      Command control
-                Bits         Field Description
-                [31:28]      Primary Input Format (see Section 36.2.1.1.1, “Primary Input
-                             Format”)
-                [27:23]      Primary Input Element Size (see Section 36.2.1.1.2, “Primary
-                             Input Element Size”)
-                [22:20]      Primary Input Starting Offset (see Section 36.2.1.1.5, “Input
-                             Element Offsets”)
-                [19]         Secondary Input Format (see Section 36.2.1.1.3, “Secondary
-                             Input Format”)
-                [18:16]      Secondary Input Starting Offset (see Section 36.2.1.1.5, “Input
-                             Element Offsets”)
-                [15:14]      Secondary Input Element Size (see Section 36.2.1.1.4,
-                             “Secondary Input Element Size”
-                [13:10]      Output Format (see Section 36.2.1.1.6, “Output Format”)
-                [9]          Reserved
-                [8:0]        Test value used for comparison against the most significant bits
-                             in the input values, when using 2 or 3 byte input elements.
-8        8      Completion (same fields as Section 36.2.1.2, “Extract command”
-16       8      Primary Input (same fields as Section 36.2.1.2, “Extract command”
-24       8      Data Access Control (same fields as Section 36.2.1.2, “Extract command”,
-                except Primary Input Length Format may not use the 0x0 value)
-32       8      Secondary Input, if used by Primary Input Format. Same fields as Primary
-                Input.
-40       8      Reserved
-48       8      Output (same fields as Primary Input)
-56       8      Bit Table
-                Bits         Field Description
-                [63:60]      ADI version (see Section 36.2.1.1.7, “Application Data
-                             Integrity (ADI)”)
-                [59:56]      If using real address, these bits should be filled in with the
-                             page size code for the page boundary checking the guest wants
-                             the virtual machine to use when accessing this data stream
-                             (checking is only guaranteed to be performed when using API
-                             version 1.1 and later). If using a virtual address, this field will
-                             be used as as bit table address bits [59:56]
-                [55:4]       Bit table address bits [55:4]. Address type is determined by
-                             CCB header. Address must be 64-byte aligned (CCB version
-                             0) or 16-byte aligned (CCB version 1).
-                [3:0]        Bit table version
-                             Value      Description
-                             0          4KB table size
-                             1          8KB table size
-
-
-
-                                 523
-\f                                              Coprocessor services
-
-
-36.2.1.5. Select command
-        The select command filters the primary input data stream by using a secondary input bit vector to determine
-        which input elements to include in the output. For each bit set at a given index N within the bit vector,
-        the Nth input element is included in the output. If the bit is not set, the element is not included. Only a
-        restricted subset of the possible input format types are supported. No variable width or run length encoded
-        input streams are allowed, since the secondary input stream is used for the filtering bit vector.
-
-        The only supported output format is a padded, byte-aligned output stream. The stream follows the same
-        rules and restrictions as padded output stream described in Section 36.2.1.2, “Extract command”.
-
-        The return value of the CCB completion area contains the number of bits set in the input bit vector. The
-        "number of elements processed" field in the CCB completion area will be valid, indicating the number
-        of input elements processed.
-
-        The select CCB is a 64-byte “short format” CCB.
-
-        The select CCB command format can be specified by the following packed C structure for a big-endian
-        machine:
-
-
-                  struct select_ccb {
-                         uint32_t header;
-                         uint32_t control;
-                         uint64_t completion;
-                         uint64_t primary_input;
-                         uint64_t data_access_control;
-                         uint64_t secondary_input;
-                         uint64_t reserved;
-                         uint64_t output;
-                         uint64_t table;
-                  };
-
-
-        The exact field offsets, sizes, and composition are as follows:
-
-         Offset        Size            Field Description
-         0             4               CCB header (Table 36.1, “CCB Header Format”)
-         4             4               Command control
-                                       Bits        Field Description
-                                       [31:28]     Primary Input Format (see Section 36.2.1.1.1, “Primary Input
-                                                   Format”)
-                                       [27:23]     Primary Input Element Size (see Section 36.2.1.1.2, “Primary
-                                                   Input Element Size”)
-                                       [22:20]     Primary Input Starting Offset (see Section 36.2.1.1.5, “Input
-                                                   Element Offsets”)
-                                       [19]        Secondary Input Format (see Section 36.2.1.1.3, “Secondary
-                                                   Input Format”)
-                                       [18:16]     Secondary Input Starting Offset (see Section 36.2.1.1.5, “Input
-                                                   Element Offsets”)
-                                       [15:14]     Secondary Input Element Size (see Section 36.2.1.1.4,
-                                                   “Secondary Input Element Size”
-
-
-                                                      524
-\f                                               Coprocessor services
-
-
-        Offset         Size            Field Description
-                                       Bits         Field Description
-                                       [13:10]      Output Format (see Section 36.2.1.1.6, “Output Format”)
-                                       [9]          Padding Direction selector: A value of 1 causes padding bytes
-                                                    to be added to the left side of output elements. A value of 0
-                                                    causes padding bytes to be added to the right side of output
-                                                    elements.
-                                       [8:0]        Reserved
-        8              8               Completion (same fields as Section 36.2.1.2, “Extract command”
-        16             8               Primary Input (same fields as Section 36.2.1.2, “Extract command”
-        24             8               Data Access Control (same fields as Section 36.2.1.2, “Extract command”)
-        32             8               Secondary Bit Vector Input. Same fields as Primary Input.
-        40             8               Reserved
-        48             8               Output (same fields as Primary Input)
-        56             8               Symbol Table (if used by Primary Input). Same fields as Section 36.2.1.2,
-                                       “Extract command”
-
-36.2.1.6. No-op and Sync commands
-        The no-op (no operation) command is a CCB which has no processing effect. The CCB, when processed
-        by the virtual machine, simply updates the completion area with its execution status. The CCB may have
-        the serial-conditional flags set in order to restrict when it executes.
-
-        The sync command is a variant of the no-op command which with restricted execution timing. A sync
-        command CCB will only execute when all previous commands submitted in the same request have
-        completed. This is stronger than the conditional flag sequencing, which is only dependent on a single
-        previous serial CCB. While the relative ordering is guaranteed, virtual machine implementations with
-        shared hardware resources may cause the sync command to wait for longer than the minimum required
-        time.
-
-        The return value of the CCB completion area is invalid for these CCBs. The “number of elements
-        processed” field is also invalid for these CCBs.
-
-        These commands are 64-byte “short format” CCBs.
-
-        The no-op CCB command format can be specified by the following packed C structure for a big-endian
-        machine:
-
-
-                 struct nop_ccb {
-                        uint32_t header;
-                        uint32_t control;
-                        uint64_t completion;
-                        uint64_t reserved[6];
-                 };
-
-
-        The exact field offsets, sizes, and composition are as follows:
-
-        Offset         Size            Field Description
-        0              4               CCB header (Table 36.1, “CCB Header Format”)
-
-
-                                                       525
-\f                                          Coprocessor services
-
-
-       Offset        Size          Field Description
-       4             4             Command control
-                                   Bits        Field Description
-                                   [31]        If set, this CCB functions as a Sync command. If clear, this
-                                               CCB functions as a No-op command.
-                                   [30:0]      Reserved
-       8             8             Completion (same fields as Section 36.2.1.2, “Extract command”
-       16            46            Reserved
-
-36.2.2. CCB Completion Area
-       All CCB commands use a common 128-byte Completion Area format, which can be specified by the
-       following packed C structure for a big-endian machine:
-
-
-                struct completion_area {
-                       uint8_t status_flag;
-                       uint8_t error_note;
-                       uint8_t rsvd0[2];
-                       uint32_t error_values;
-                       uint32_t output_size;
-                       uint32_t rsvd1;
-                       uint64_t run_time;
-                       uint64_t run_stats;
-                       uint32_t elements;
-                       uint8_t rsvd2[20];
-                       uint64_t return_value;
-                       uint64_t extra_return_value[8];
-                };
-
-
-       The Completion Area must be a 128-byte aligned memory location. The exact layout can be described
-       using byte offsets and sizes relative to the memory base:
-
-       Offset        Size          Field Description
-       0             1             CCB execution status
-                                   0x0                  Command not yet completed
-                                   0x1                  Command ran and succeeded
-                                   0x2                  Command ran and failed (partial results may be been
-                                                        produced)
-                                   0x3                  Command ran and was killed (partial execution may
-                                                        have occurred)
-                                   0x4                  Command was not run
-                                   0x5-0xF              Reserved
-       1             1             Error reason code
-                                   0x0                  Reserved
-                                   0x1                  Buffer overflow
-
-
-                                                  526
-\f                                      Coprocessor services
-
-
-Offset          Size           Field Description
-                                0x2                 CCB decoding error
-                                0x3                 Page overflow
-                                0x4-0x6             Reserved
-                                0x7                 Command was killed
-                                0x8                 Command execution timeout
-                                0x9                 ADI miscompare error
-                                0xA                 Data format error
-                                0xB-0xD             Reserved
-                                0xE                 Unexpected hardware error (Do not retry)
-                                0xF                 Unexpected hardware error (Retry is ok)
-                                0x10-0x7F           Reserved
-                                0x80                Partial Symbol Warning
-                                0x81-0xFF           Reserved
-2               2              Reserved
-4               4              If a partial symbol warning was generated, this field contains the number
-                               of remaining bits which were not decoded.
-8               4              Number of bytes of output produced
-12              4              Reserved
-16              8              Runtime of command (unspecified time units)
-24              8              Reserved
-32              4              Number of elements processed
-36              20             Reserved
-56              8              Return value
-64              64             Extended return value
-
-The CCB completion area should be treated as read-only by guest software. The CCB execution status
-byte will be cleared by the Hypervisor to reflect the pending execution status when the CCB is submitted
-successfully. All other fields are considered invalid upon CCB submission until the CCB execution status
-byte becomes non-zero.
-
-CCBs which complete with status 0x2 or 0x3 may produce partial results and/or side effects due to partial
-execution of the CCB command. Some valid data may be accessible depending on the fault type, however,
-it is recommended that guest software treat the destination buffer as being in an unknown state. If a CCB
-completes with a status byte of 0x2, the error reason code byte can be read to determine what corrective
-action should be taken.
-
-A buffer overflow indicates that the results of the operation exceeded the size of the output buffer indicated
-in the CCB. The operation can be retried by resubmitting the CCB with a larger output buffer.
-
-A CCB decoding error indicates that the CCB contained some invalid field values. It may be also be
-triggered if the CCB output is directed at a non-existent secondary input and the pipelining hint is followed.
-
-A page overflow error indicates that the operation required accessing a memory location beyond the page
-size associated with a given address. No data will have been read or written past the page boundary, but
-partial results may have been written to the destination buffer. The CCB can be resubmitted with a larger
-page size memory allocation to complete the operation.
-
-
-                                              527
-\f                                            Coprocessor services
-
-
-       In the case of pipelined CCBs, a page overflow error will be triggered if the output from the pipeline source
-       CCB ends before the input of the pipeline target CCB. Page boundaries are ignored when the pipeline
-       hint is followed.
-
-       Command kill indicates that the CCB execution was halted or prevented by use of the ccb_kill API call.
-
-       Command timeout indicates that the CCB execution began, but did not complete within a pre-determined
-       limit set by the virtual machine. The command may have produced some or no output. The CCB may be
-       resubmitted with no alterations.
-
-       ADI miscompare indicates that the memory buffer version specified in the CCB did not match the value
-       in memory when accessed by the virtual machine. Guest software should not attempt to resubmit the CCB
-       without determining the cause of the version mismatch.
-
-       A data format error indicates that the input data stream did not follow the specified data input formatting
-       selected in the CCB.
-
-       Some CCBs which encounter hardware errors may be resubmitted without change. Persistent hardware
-       errors may result in multiple failures until RAS software can identify and isolate the faulty component.
-
-       The output size field indicates the number of bytes of valid output in the destination buffer. This field is
-       not valid for all possible CCB commands.
-
-       The runtime field indicates the execution time of the CCB command once it leaves the internal virtual
-       machine queue. The time units are fixed, but unspecified, allowing only relative timing comparisons
-       by guest software. The time units may also vary by hardware platform, and should not be construed to
-       represent any absolute time value.
-
-       Some data query commands process data in units of elements. If applicable to the command, the number of
-       elements processed is indicated in the listed field. This field is not valid for all possible CCB commands.
-
-       The return value and extended return value fields are output locations for commands which do not use
-       a destination output buffer, or have secondary return results. The field is not valid for all possible CCB
-       commands.
-
-36.3. Hypervisor API Functions
-36.3.1. ccb_submit
-       trap#             FAST_TRAP
-       function#         CCB_SUBMIT
-       arg0              address
-       arg1              length
-       arg2              flags
-       arg3              reserved
-       ret0              status
-       ret1              length
-       ret2              status data
-       ret3              reserved
-
-       Submit one or more coprocessor control blocks (CCBs) for evaluation and processing by the virtual
-       machine. The CCBs are passed in a linear array indicated by address. length indicates the size of
-       the array in bytes.
-
-
-                                                     528
-\f                                      Coprocessor services
-
-
-The address should be aligned to the size indicated by length, rounded up to the nearest power of
-two. Virtual machines implementations may reject submissions which do not adhere to that alignment.
-length must be a multiple of 64 bytes. If length is zero, the maximum supported array length will be
-returned as length in ret1. In all other cases, the length value in ret1 will reflect the number of bytes
-successfully consumed from the input CCB array.
-
-      Implementation note
-      Virtual machines should never reject submissions based on the alignment of address if the
-      entire array is contained within a single memory page of the smallest page size supported by the
-      virtual machine.
-
-A guest may choose to submit addresses used in this API function, including the CCB array address,
-as either a real or virtual addresses, with the type of each address indicated in flags. Virtual addresses
-must be present in either the TLB or an active TSB to be processed. The translation context for virtual
-addresses is determined by a combination of CCB contents and the flags argument.
-
-The flags argument is divided into multiple fields defined as follows:
-
-
-Bits            Field Description
-[63:16]         Reserved
-[15]            Disable ADI for VA reads (in API 2.0)
-                Reserved (in API 1.0)
-[14]            Virtual addresses within CCBs are translated in privileged context
-[13:12]         Alternate translation context for virtual addresses within CCBs:
-                 0b'00        CCBs requesting alternate context are rejected
-                 0b'01        Reserved
-                 0b'10        CCBs requesting alternate context use secondary context
-                 0b'11        CCBs requesting alternate context use nucleus context
-[11:9]          Reserved
-[8]             Queue info flag
-[7]             All-or-nothing flag
-[6]             If address is a virtual address, treat its translation context as privileged
-[5:4]           Address type of address:
-                 0b'00        Real address
-                 0b'01        Virtual address in primary context
-                 0b'10        Virtual address in secondary context
-                 0b'11        Virtual address in nucleus context
-[3:2]           Reserved
-[1:0]           CCB command type:
-                 0b'00        Reserved
-                 0b'01        Reserved
-                 0b'10        Query command
-                 0b'11        Reserved
-
-
-
-                                              529
-\f                                             Coprocessor services
-
-
-         The CCB submission type and address type for the CCB array must be provided in the flags argument.
-         All other fields are optional values which change the default behavior of the CCB processing.
-
-         When set to one, the "Disable ADI for VA reads" bit will turn off ADI checking when using a virtual
-         address to load data. ADI checking will still be done when loading real-addressed memory. This bit is only
-         available when using major version 2 of the coprocessor API group; at major version 1 it is reserved. For
-         more information about using ADI and DAX, see Section 36.2.1.1.7, “Application Data Integrity (ADI)”.
-
-         By default, all virtual addresses are treated as user addresses. If the virtual address translations are
-         privileged, they must be marked as such in the appropriate flags field. The virtual addresses used within
-         the submitted CCBs must all be translated with the same privilege level.
-
-         By default, all virtual addresses used within the submitted CCBs are translated using the primary context
-         active at the time of the submission. The address type field within a CCB allows each address to request
-         translation in an alternate address context. The address context used when the alternate address context is
-         requested is selected in the flags argument.
-
-         The all-or-nothing flag specifies whether the virtual machine should allow partial submissions of the
-         input CCB array. When using CCBs with serial-conditional flags, it is strongly recommended to use
-         the all-or-nothing flag to avoid broken conditional chains. Using long CCB chains on a machine under
-         high coprocessor load may make this impractical, however, and require submitting without the flag.
-         When submitting serial-conditional CCBs without the all-or-nothing flag, guest software must manually
-         implement the serial-conditional behavior at any point where the chain was not submitted in a single API
-         call, and resubmission of the remaining CCBs should clear any conditional flag that might be set in the
-         first remaining CCB. Failure to do so will produce indeterminate CCB execution status and ordering.
-
-         When the all-or-nothing flag is not specified, callers should check the value of length in ret1 to determine
-         how many CCBs from the array were successfully submitted. Any remaining CCBs can be resubmitted
-         without modifications.
-
-         The value of length in ret1 is also valid when the API call returns an error, and callers should always
-         check its value to determine which CCBs in the array were already processed. This will additionally
-         identify which CCB encountered the processing error, and was not submitted successfully.
-
-         If the queue info flag is used during submission, and at least one CCB was successfully submitted, the
-         length value in ret1 will be a multi-field value defined as follows:
-          Bits          Field Description
-          [63:48]       DAX unit instance identifier
-          [47:32]       DAX queue instance identifier
-          [31:16]       Reserved
-          [15:0]        Number of CCB bytes successfully submitted
-
-         The value of status data depends on the status value. See error status code descriptions for details.
-         The value is undefined for status values that do not specifically list a value for the status data.
-
-         The API has a reserved input and output register which will be used in subsequent minor versions of this
-         API function. Guest software implementations should treat that register as voltile across the function call
-         in order to maintain forward compatibility.
-
-36.3.1.1. Errors
-          EOK                       One or more CCBs have been accepted and enqueued in the virtual machine
-                                    and no errors were been encountered during submission. Some submitted
-                                    CCBs may not have been enqueued due to internal virtual machine limitations,
-                                    and may be resubmitted without changes.
-
-
-                                                       530
-\f                        Coprocessor services
-
-
-EWOULDBLOCK    An internal resource conflict within the virtual machine has prevented it from
-               being able to complete the CCB submissions sufficiently quickly, requiring
-               it to abandon processing before it was complete. Some CCBs may have been
-               successfully enqueued prior to the block, and all remaining CCBs may be
-               resubmitted without changes.
-EBADALIGN      CCB array is not on a 64-byte boundary, or the array length is not a multiple
-               of 64 bytes.
-ENORADDR       A real address used either for the CCB array, or within one of the submitted
-               CCBs, is not valid for the guest. Some CCBs may have been enqueued prior
-               to the error being detected.
-ENOMAP         A virtual address used either for the CCB array, or within one of the submitted
-               CCBs, could not be translated by the virtual machine using either the TLB
-               or TSB contents. The submission may be retried after adding the required
-               mapping, or by converting the virtual address into a real address. Due to the
-               shared nature of address translation resources, there is no theoretical limit on
-               the number of times the translation may fail, and it is recommended all guests
-               implement some real address based backup. The virtual address which failed
-               translation is returned as status data in ret2. Some CCBs may have been
-               enqueued prior to the error being detected.
-EINVAL         The virtual machine detected an invalid CCB during submission, or invalid
-               input arguments, such as bad flag values. Note that not all invalid CCB values
-               will be detected during submission, and some may be reported as errors in the
-               completion area instead. Some CCBs may have been enqueued prior to the
-               error being detected. This error may be returned if the CCB version is invalid.
-ETOOMANY       The request was submitted with the all-or-nothing flag set, and the array size is
-               greater than the virtual machine can support in a single request. The maximum
-               supported size for the current virtual machine can be queried by submitting a
-               request with a zero length array, as described above.
-ENOACCESS      The guest does not have permission to submit CCBs, or an address used in a
-               CCBs lacks sufficient permissions to perform the required operation (no write
-               permission on the destination buffer address, for example). A virtual address
-               which fails permission checking is returned as status data in ret2. Some
-               CCBs may have been enqueued prior to the error being detected.
-EUNAVAILABLE   The requested CCB operation could not be performed at this time. The
-               restricted operation availability may apply only to the first unsuccessfully
-               submitted CCB, or may apply to a larger scope. The status should not be
-               interpreted as permanent, and the guest should attempt to submit CCBs in
-               the future which had previously been unable to be performed. The status
-               data provides additional information about scope of the restricted availability
-               as follows:
-               Value       Description
-               0           Processing for the exact CCB instance submitted was unavailable,
-                           and it is recommended the guest emulate the operation. The
-                           guest should continue to submit all other CCBs, and assume no
-                           restrictions beyond this exact CCB instance.
-               1           Processing is unavailable for all CCBs using the requested opcode,
-                           and it is recommended the guest emulate the operation. The
-                           guest should continue to submit all other CCBs that use different
-                           opcodes, but can expect continued rejections of CCBs using the
-                           same opcode in the near future.
-
-
-                                 531
-\f                                              Coprocessor services
-
-
-                                      Value     Description
-                                      2         Processing is unavailable for all CCBs using the requested CCB
-                                                version, and it is recommended the guest emulate the operation.
-                                                The guest should continue to submit all other CCBs that use
-                                                different CCB versions, but can expect continued rejections of
-                                                CCBs using the same CCB version in the near future.
-                                      3         Processing is unavailable for all CCBs on the submitting vcpu,
-                                                and it is recommended the guest emulate the operation or resubmit
-                                                the CCB on a different vcpu. The guest should continue to submit
-                                                CCBs on all other vcpus but can expect continued rejections of all
-                                                CCBs on this vcpu in the near future.
-                                      4         Processing is unavailable for all CCBs, and it is recommended
-                                                the guest emulate the operation. The guest should expect all CCB
-                                                submissions to be similarly rejected in the near future.
-
-
-36.3.2. ccb_info
-
-        trap#               FAST_TRAP
-        function#           CCB_INFO
-        arg0                address
-        ret0                status
-        ret1                CCB state
-        ret2                position
-        ret3                dax
-        ret4                queue
-
-       Requests status information on a previously submitted CCB. The previously submitted CCB is identified
-       by the 64-byte aligned real address of the CCBs completion area.
-
-       A CCB can be in one of 4 states:
-
-
-        State                     Value       Description
-        COMPLETED                 0           The CCB has been fetched and executed, and is no longer active in
-                                              the virtual machine.
-        ENQUEUED                  1           The requested CCB is current in a queue awaiting execution.
-        INPROGRESS                2           The CCB has been fetched and is currently being executed. It may still
-                                              be possible to stop the execution using the ccb_kill hypercall.
-        NOTFOUND                  3           The CCB could not be located in the virtual machine, and does not
-                                              appear to have been executed. This may occur if the CCB was lost
-                                              due to a hardware error, or the CCB may not have been successfully
-                                              submitted to the virtual machine in the first place.
-
-               Implementation note
-               Some platforms may not be able to report CCBs that are currently being processed, and therefore
-               guest software should invoke the ccb_kill hypercall prior to assuming the request CCB will never
-               be executed because it was in the NOTFOUND state.
-
-
-                                                       532
-\f                                             Coprocessor services
-
-
-         The position return value is only valid when the state is ENQUEUED. The value returned is the number
-         of other CCBs ahead of the requested CCB, to provide a relative estimate of when the CCB may execute.
-
-         The dax return value is only valid when the state is ENQUEUED. The value returned is the DAX unit
-         instance identifier for the DAX unit processing the queue where the requested CCB is located. The value
-         matches the value that would have been, or was, returned by ccb_submit using the queue info flag.
-
-         The queue return value is only valid when the state is ENQUEUED. The value returned is the DAX
-         queue instance identifier for the DAX unit processing the queue where the requested CCB is located. The
-         value matches the value that would have been, or was, returned by ccb_submit using the queue info flag.
-
-36.3.2.1. Errors
-
-          EOK                       The request was processed and the CCB state is valid.
-          EBADALIGN                 address is not on a 64-byte aligned.
-          ENORADDR                  The real address provided for address is not valid.
-          EINVAL                    The CCB completion area contents are not valid.
-          EWOULDBLOCK               Internal resource constraints prevented the CCB state from being queried at this
-                                    time. The guest should retry the request.
-          ENOACCESS                 The guest does not have permission to access the coprocessor virtual device
-                                    functionality.
-
-36.3.3. ccb_kill
-
-          trap#           FAST_TRAP
-          function#       CCB_KILL
-          arg0            address
-          ret0            status
-          ret1            result
-
-         Request to stop execution of a previously submitted CCB. The previously submitted CCB is identified by
-         the 64-byte aligned real address of the CCBs completion area.
-
-         The kill attempt can produce one of several values in the result return value, reflecting the CCB state
-         and actions taken by the Hypervisor:
-
-          Result                Value       Description
-          COMPLETED             0           The CCB has been fetched and executed, and is no longer active in
-                                            the virtual machine. It could not be killed and no action was taken.
-          DEQUEUED              1           The requested CCB was still enqueued when the kill request was
-                                            submitted, and has been removed from the queue. Since the CCB
-                                            never began execution, no memory modifications were produced by
-                                            it, and the completion area will never be updated. The same CCB may
-                                            be submitted again, if desired, with no modifications required.
-          KILLED                2           The CCB had been fetched and was being executed when the kill
-                                            request was submitted. The CCB execution was stopped, and the CCB
-                                            is no longer active in the virtual machine. The CCB completion area
-                                            will reflect the killed status, with the subsequent implications that
-                                            partial results may have been produced. Partial results may include full
-
-
-                                                      533
-\f                                              Coprocessor services
-
-
-          Result                 Value       Description
-                                             command execution if the command was stopped just prior to writing
-                                             to the completion area.
-          NOTFOUND               3           The CCB could not be located in the virtual machine, and does not
-                                             appear to have been executed. This may occur if the CCB was lost
-                                             due to a hardware error, or the CCB may not have been successfully
-                                             submitted to the virtual machine in the first place. CCBs in the state
-                                             are guaranteed to never execute in the future unless resubmitted.
-
-36.3.3.1. Interactions with Pipelined CCBs
-
-         If the pipeline target CCB is killed but the pipeline source CCB was skipped, the completion area of the
-         target CCB may contain status (4,0) "Command was skipped" instead of (3,7) "Command was killed".
-
-         If the pipeline source CCB is killed, the pipeline target CCB's completion status may read (1,0) "Success".
-         This does not mean the target CCB was processed; since the source CCB was killed, there was no
-         meaningful output on which the target CCB could operate.
-
-36.3.3.2. Errors
-
-          EOK                        The request was processed and the result is valid.
-          EBADALIGN                  address is not on a 64-byte aligned.
-          ENORADDR                   The real address provided for address is not valid.
-          EINVAL                     The CCB completion area contents are not valid.
-          EWOULDBLOCK                Internal resource constraints prevented the CCB from being killed at this time.
-                                     The guest should retry the request.
-          ENOACCESS                  The guest does not have permission to access the coprocessor virtual device
-                                     functionality.
-
-36.3.4. dax_info
-          trap#            FAST_TRAP
-          function#        DAX_INFO
-          ret0             status
-          ret1             Number of enabled DAX units
-          ret2             Number of disabled DAX units
-
-         Returns the number of DAX units that are enabled for the calling guest to submit CCBs. The number of
-         DAX units that are disabled for the calling guest are also returned. A disabled DAX unit would have been
-         available for CCB submission to the calling guest had it not been offlined.
-
-36.3.4.1. Errors
-
-          EOK                        The request was processed and the number of enabled/disabled DAX units
-                                     are valid.
-
-
-
-
-                                                       534
-\f
diff --git a/Documentation/sparc/oradax/oracle-dax.rst b/Documentation/sparc/oradax/oracle-dax.rst
deleted file mode 100644 (file)
index d1e14d5..0000000
+++ /dev/null
@@ -1,445 +0,0 @@
-=======================================
-Oracle Data Analytics Accelerator (DAX)
-=======================================
-
-DAX is a coprocessor which resides on the SPARC M7 (DAX1) and M8
-(DAX2) processor chips, and has direct access to the CPU's L3 caches
-as well as physical memory. It can perform several operations on data
-streams with various input and output formats.  A driver provides a
-transport mechanism and has limited knowledge of the various opcodes
-and data formats. A user space library provides high level services
-and translates these into low level commands which are then passed
-into the driver and subsequently the Hypervisor and the coprocessor.
-The library is the recommended way for applications to use the
-coprocessor, and the driver interface is not intended for general use.
-This document describes the general flow of the driver, its
-structures, and its programmatic interface. It also provides example
-code sufficient to write user or kernel applications that use DAX
-functionality.
-
-The user library is open source and available at:
-
-    https://oss.oracle.com/git/gitweb.cgi?p=libdax.git
-
-The Hypervisor interface to the coprocessor is described in detail in
-the accompanying document, dax-hv-api.txt, which is a plain text
-excerpt of the (Oracle internal) "UltraSPARC Virtual Machine
-Specification" version 3.0.20+15, dated 2017-09-25.
-
-
-High Level Overview
-===================
-
-A coprocessor request is described by a Command Control Block
-(CCB). The CCB contains an opcode and various parameters. The opcode
-specifies what operation is to be done, and the parameters specify
-options, flags, sizes, and addresses.  The CCB (or an array of CCBs)
-is passed to the Hypervisor, which handles queueing and scheduling of
-requests to the available coprocessor execution units. A status code
-returned indicates if the request was submitted successfully or if
-there was an error.  One of the addresses given in each CCB is a
-pointer to a "completion area", which is a 128 byte memory block that
-is written by the coprocessor to provide execution status. No
-interrupt is generated upon completion; the completion area must be
-polled by software to find out when a transaction has finished, but
-the M7 and later processors provide a mechanism to pause the virtual
-processor until the completion status has been updated by the
-coprocessor. This is done using the monitored load and mwait
-instructions, which are described in more detail later.  The DAX
-coprocessor was designed so that after a request is submitted, the
-kernel is no longer involved in the processing of it.  The polling is
-done at the user level, which results in almost zero latency between
-completion of a request and resumption of execution of the requesting
-thread.
-
-
-Addressing Memory
-=================
-
-The kernel does not have access to physical memory in the Sun4v
-architecture, as there is an additional level of memory virtualization
-present. This intermediate level is called "real" memory, and the
-kernel treats this as if it were physical.  The Hypervisor handles the
-translations between real memory and physical so that each logical
-domain (LDOM) can have a partition of physical memory that is isolated
-from that of other LDOMs.  When the kernel sets up a virtual mapping,
-it specifies a virtual address and the real address to which it should
-be mapped.
-
-The DAX coprocessor can only operate on physical memory, so before a
-request can be fed to the coprocessor, all the addresses in a CCB must
-be converted into physical addresses. The kernel cannot do this since
-it has no visibility into physical addresses. So a CCB may contain
-either the virtual or real addresses of the buffers or a combination
-of them. An "address type" field is available for each address that
-may be given in the CCB. In all cases, the Hypervisor will translate
-all the addresses to physical before dispatching to hardware. Address
-translations are performed using the context of the process initiating
-the request.
-
-
-The Driver API
-==============
-
-An application makes requests to the driver via the write() system
-call, and gets results (if any) via read(). The completion areas are
-made accessible via mmap(), and are read-only for the application.
-
-The request may either be an immediate command or an array of CCBs to
-be submitted to the hardware.
-
-Each open instance of the device is exclusive to the thread that
-opened it, and must be used by that thread for all subsequent
-operations. The driver open function creates a new context for the
-thread and initializes it for use.  This context contains pointers and
-values used internally by the driver to keep track of submitted
-requests. The completion area buffer is also allocated, and this is
-large enough to contain the completion areas for many concurrent
-requests.  When the device is closed, any outstanding transactions are
-flushed and the context is cleaned up.
-
-On a DAX1 system (M7), the device will be called "oradax1", while on a
-DAX2 system (M8) it will be "oradax2". If an application requires one
-or the other, it should simply attempt to open the appropriate
-device. Only one of the devices will exist on any given system, so the
-name can be used to determine what the platform supports.
-
-The immediate commands are CCB_DEQUEUE, CCB_KILL, and CCB_INFO. For
-all of these, success is indicated by a return value from write()
-equal to the number of bytes given in the call. Otherwise -1 is
-returned and errno is set.
-
-CCB_DEQUEUE
------------
-
-Tells the driver to clean up resources associated with past
-requests. Since no interrupt is generated upon the completion of a
-request, the driver must be told when it may reclaim resources.  No
-further status information is returned, so the user should not
-subsequently call read().
-
-CCB_KILL
---------
-
-Kills a CCB during execution. The CCB is guaranteed to not continue
-executing once this call returns successfully. On success, read() must
-be called to retrieve the result of the action.
-
-CCB_INFO
---------
-
-Retrieves information about a currently executing CCB. Note that some
-Hypervisors might return 'notfound' when the CCB is in 'inprogress'
-state. To ensure a CCB in the 'notfound' state will never be executed,
-CCB_KILL must be invoked on that CCB. Upon success, read() must be
-called to retrieve the details of the action.
-
-Submission of an array of CCBs for execution
----------------------------------------------
-
-A write() whose length is a multiple of the CCB size is treated as a
-submit operation. The file offset is treated as the index of the
-completion area to use, and may be set via lseek() or using the
-pwrite() system call. If -1 is returned then errno is set to indicate
-the error. Otherwise, the return value is the length of the array that
-was actually accepted by the coprocessor. If the accepted length is
-equal to the requested length, then the submission was completely
-successful and there is no further status needed; hence, the user
-should not subsequently call read(). Partial acceptance of the CCB
-array is indicated by a return value less than the requested length,
-and read() must be called to retrieve further status information.  The
-status will reflect the error caused by the first CCB that was not
-accepted, and status_data will provide additional data in some cases.
-
-MMAP
-----
-
-The mmap() function provides access to the completion area allocated
-in the driver.  Note that the completion area is not writeable by the
-user process, and the mmap call must not specify PROT_WRITE.
-
-
-Completion of a Request
-=======================
-
-The first byte in each completion area is the command status which is
-updated by the coprocessor hardware. Software may take advantage of
-new M7/M8 processor capabilities to efficiently poll this status byte.
-First, a "monitored load" is achieved via a Load from Alternate Space
-(ldxa, lduba, etc.) with ASI 0x84 (ASI_MONITOR_PRIMARY).  Second, a
-"monitored wait" is achieved via the mwait instruction (a write to
-%asr28). This instruction is like pause in that it suspends execution
-of the virtual processor for the given number of nanoseconds, but in
-addition will terminate early when one of several events occur. If the
-block of data containing the monitored location is modified, then the
-mwait terminates. This causes software to resume execution immediately
-(without a context switch or kernel to user transition) after a
-transaction completes. Thus the latency between transaction completion
-and resumption of execution may be just a few nanoseconds.
-
-
-Application Life Cycle of a DAX Submission
-==========================================
-
- - open dax device
- - call mmap() to get the completion area address
- - allocate a CCB and fill in the opcode, flags, parameters, addresses, etc.
- - submit CCB via write() or pwrite()
- - go into a loop executing monitored load + monitored wait and
-   terminate when the command status indicates the request is complete
-   (CCB_KILL or CCB_INFO may be used any time as necessary)
- - perform a CCB_DEQUEUE
- - call munmap() for completion area
- - close the dax device
-
-
-Memory Constraints
-==================
-
-The DAX hardware operates only on physical addresses. Therefore, it is
-not aware of virtual memory mappings and the discontiguities that may
-exist in the physical memory that a virtual buffer maps to. There is
-no I/O TLB or any scatter/gather mechanism. All buffers, whether input
-or output, must reside in a physically contiguous region of memory.
-
-The Hypervisor translates all addresses within a CCB to physical
-before handing off the CCB to DAX. The Hypervisor determines the
-virtual page size for each virtual address given, and uses this to
-program a size limit for each address. This prevents the coprocessor
-from reading or writing beyond the bound of the virtual page, even
-though it is accessing physical memory directly. A simpler way of
-saying this is that a DAX operation will never "cross" a virtual page
-boundary. If an 8k virtual page is used, then the data is strictly
-limited to 8k. If a user's buffer is larger than 8k, then a larger
-page size must be used, or the transaction size will be truncated to
-8k.
-
-Huge pages. A user may allocate huge pages using standard interfaces.
-Memory buffers residing on huge pages may be used to achieve much
-larger DAX transaction sizes, but the rules must still be followed,
-and no transaction will cross a page boundary, even a huge page.  A
-major caveat is that Linux on Sparc presents 8Mb as one of the huge
-page sizes. Sparc does not actually provide a 8Mb hardware page size,
-and this size is synthesized by pasting together two 4Mb pages. The
-reasons for this are historical, and it creates an issue because only
-half of this 8Mb page can actually be used for any given buffer in a
-DAX request, and it must be either the first half or the second half;
-it cannot be a 4Mb chunk in the middle, since that crosses a
-(hardware) page boundary. Note that this entire issue may be hidden by
-higher level libraries.
-
-
-CCB Structure
--------------
-A CCB is an array of 8 64-bit words. Several of these words provide
-command opcodes, parameters, flags, etc., and the rest are addresses
-for the completion area, output buffer, and various inputs::
-
-   struct ccb {
-       u64   control;
-       u64   completion;
-       u64   input0;
-       u64   access;
-       u64   input1;
-       u64   op_data;
-       u64   output;
-       u64   table;
-   };
-
-See libdax/common/sys/dax1/dax1_ccb.h for a detailed description of
-each of these fields, and see dax-hv-api.txt for a complete description
-of the Hypervisor API available to the guest OS (ie, Linux kernel).
-
-The first word (control) is examined by the driver for the following:
- - CCB version, which must be consistent with hardware version
- - Opcode, which must be one of the documented allowable commands
- - Address types, which must be set to "virtual" for all the addresses
-   given by the user, thereby ensuring that the application can
-   only access memory that it owns
-
-
-Example Code
-============
-
-The DAX is accessible to both user and kernel code.  The kernel code
-can make hypercalls directly while the user code must use wrappers
-provided by the driver. The setup of the CCB is nearly identical for
-both; the only difference is in preparation of the completion area. An
-example of user code is given now, with kernel code afterwards.
-
-In order to program using the driver API, the file
-arch/sparc/include/uapi/asm/oradax.h must be included.
-
-First, the proper device must be opened. For M7 it will be
-/dev/oradax1 and for M8 it will be /dev/oradax2. The simplest
-procedure is to attempt to open both, as only one will succeed::
-
-       fd = open("/dev/oradax1", O_RDWR);
-       if (fd < 0)
-               fd = open("/dev/oradax2", O_RDWR);
-       if (fd < 0)
-              /* No DAX found */
-
-Next, the completion area must be mapped::
-
-      completion_area = mmap(NULL, DAX_MMAP_LEN, PROT_READ, MAP_SHARED, fd, 0);
-
-All input and output buffers must be fully contained in one hardware
-page, since as explained above, the DAX is strictly constrained by
-virtual page boundaries.  In addition, the output buffer must be
-64-byte aligned and its size must be a multiple of 64 bytes because
-the coprocessor writes in units of cache lines.
-
-This example demonstrates the DAX Scan command, which takes as input a
-vector and a match value, and produces a bitmap as the output. For
-each input element that matches the value, the corresponding bit is
-set in the output.
-
-In this example, the input vector consists of a series of single bits,
-and the match value is 0. So each 0 bit in the input will produce a 1
-in the output, and vice versa, which produces an output bitmap which
-is the input bitmap inverted.
-
-For details of all the parameters and bits used in this CCB, please
-refer to section 36.2.1.3 of the DAX Hypervisor API document, which
-describes the Scan command in detail::
-
-       ccb->control =       /* Table 36.1, CCB Header Format */
-                 (2L << 48)     /* command = Scan Value */
-               | (3L << 40)     /* output address type = primary virtual */
-               | (3L << 34)     /* primary input address type = primary virtual */
-                            /* Section 36.2.1, Query CCB Command Formats */
-               | (1 << 28)     /* 36.2.1.1.1 primary input format = fixed width bit packed */
-               | (0 << 23)     /* 36.2.1.1.2 primary input element size = 0 (1 bit) */
-               | (8 << 10)     /* 36.2.1.1.6 output format = bit vector */
-               | (0 <<  5)     /* 36.2.1.3 First scan criteria size = 0 (1 byte) */
-               | (31 << 0);    /* 36.2.1.3 Disable second scan criteria */
-
-       ccb->completion = 0;    /* Completion area address, to be filled in by driver */
-
-       ccb->input0 = (unsigned long) input; /* primary input address */
-
-       ccb->access =       /* Section 36.2.1.2, Data Access Control */
-                 (2 << 24)    /* Primary input length format = bits */
-               | (nbits - 1); /* number of bits in primary input stream, minus 1 */
-
-       ccb->input1 = 0;       /* secondary input address, unused */
-
-       ccb->op_data = 0;      /* scan criteria (value to be matched) */
-
-       ccb->output = (unsigned long) output;   /* output address */
-
-       ccb->table = 0;        /* table address, unused */
-
-The CCB submission is a write() or pwrite() system call to the
-driver. If the call fails, then a read() must be used to retrieve the
-status::
-
-       if (pwrite(fd, ccb, 64, 0) != 64) {
-               struct ccb_exec_result status;
-               read(fd, &status, sizeof(status));
-               /* bail out */
-       }
-
-After a successful submission of the CCB, the completion area may be
-polled to determine when the DAX is finished. Detailed information on
-the contents of the completion area can be found in section 36.2.2 of
-the DAX HV API document::
-
-       while (1) {
-               /* Monitored Load */
-               __asm__ __volatile__("lduba [%1] 0x84, %0\n"
-                                    : "=r" (status)
-                                    : "r"  (completion_area));
-
-               if (status)          /* 0 indicates command in progress */
-                       break;
-
-               /* MWAIT */
-               __asm__ __volatile__("wr %%g0, 1000, %%asr28\n" ::);    /* 1000 ns */
-       }
-
-A completion area status of 1 indicates successful completion of the
-CCB and validity of the output bitmap, which may be used immediately.
-All other non-zero values indicate error conditions which are
-described in section 36.2.2::
-
-       if (completion_area[0] != 1) {  /* section 36.2.2, 1 = command ran and succeeded */
-               /* completion_area[0] contains the completion status */
-               /* completion_area[1] contains an error code, see 36.2.2 */
-       }
-
-After the completion area has been processed, the driver must be
-notified that it can release any resources associated with the
-request. This is done via the dequeue operation::
-
-       struct dax_command cmd;
-       cmd.command = CCB_DEQUEUE;
-       if (write(fd, &cmd, sizeof(cmd)) != sizeof(cmd)) {
-               /* bail out */
-       }
-
-Finally, normal program cleanup should be done, i.e., unmapping
-completion area, closing the dax device, freeing memory etc.
-
-Kernel example
---------------
-
-The only difference in using the DAX in kernel code is the treatment
-of the completion area. Unlike user applications which mmap the
-completion area allocated by the driver, kernel code must allocate its
-own memory to use for the completion area, and this address and its
-type must be given in the CCB::
-
-       ccb->control |=      /* Table 36.1, CCB Header Format */
-               (3L << 32);     /* completion area address type = primary virtual */
-
-       ccb->completion = (unsigned long) completion_area;   /* Completion area address */
-
-The dax submit hypercall is made directly. The flags used in the
-ccb_submit call are documented in the DAX HV API in section 36.3.1/
-
-::
-
-  #include <asm/hypervisor.h>
-
-       hv_rv = sun4v_ccb_submit((unsigned long)ccb, 64,
-                                HV_CCB_QUERY_CMD |
-                                HV_CCB_ARG0_PRIVILEGED | HV_CCB_ARG0_TYPE_PRIMARY |
-                                HV_CCB_VA_PRIVILEGED,
-                                0, &bytes_accepted, &status_data);
-
-       if (hv_rv != HV_EOK) {
-               /* hv_rv is an error code, status_data contains */
-               /* potential additional status, see 36.3.1.1 */
-       }
-
-After the submission, the completion area polling code is identical to
-that in user land::
-
-       while (1) {
-               /* Monitored Load */
-               __asm__ __volatile__("lduba [%1] 0x84, %0\n"
-                                    : "=r" (status)
-                                    : "r"  (completion_area));
-
-               if (status)          /* 0 indicates command in progress */
-                       break;
-
-               /* MWAIT */
-               __asm__ __volatile__("wr %%g0, 1000, %%asr28\n" ::);    /* 1000 ns */
-       }
-
-       if (completion_area[0] != 1) {  /* section 36.2.2, 1 = command ran and succeeded */
-               /* completion_area[0] contains the completion status */
-               /* completion_area[1] contains an error code, see 36.2.2 */
-       }
-
-The output bitmap is ready for consumption immediately after the
-completion status indicates success.
-
-Excer[t from UltraSPARC Virtual Machine Specification
-=====================================================
-
- .. include:: dax-hv-api.txt
-    :literal:
index b927fb2b94dc43eb2ac062f16f470e6a736fa385..e8bca5fea7ccc9d33d222cb7a3d182eacda9e731 100644 (file)
@@ -3510,7 +3510,7 @@ directories, the rmdir will fail with EBUSY.
 Stack trace
 -----------
 Since the kernel has a fixed sized stack, it is important not to
-waste it in functions. A kernel developer must be conscience of
+waste it in functions. A kernel developer must be conscious of
 what they allocate on the stack. If they add too much, the system
 can be in danger of a stack overflow, and corruption will occur,
 usually leading to a system panic.
index 18a5822c7d9a85be55502990ebe6b2690e4fae52..20994f4bfa31e9417686bc3153c084a086e80539 100644 (file)
@@ -1,6 +1,6 @@
 .. include:: ../disclaimer-ita.rst
 
-:Original: :ref:`Documentation/admin-guide/security-bugs.rst <securitybugs>`
+:Original: :ref:`Documentation/process/security-bugs.rst <securitybugs>`
 
 .. _it_securitybugs:
 
index 0f6898860d6d1ece70c9efb9e76011007c693668..17abc25ee4c1e4ad581bb737cb70f3f20ec32b8e 100644 (file)
@@ -1,7 +1,6 @@
 .. include:: ../disclaimer-ita.rst
 
-:Original: :doc:`../../../core-api/symbol-namespaces`
-:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
+:Original: Documentation/core-api/symbol-namespaces.rst
 
 ===========================
 Spazio dei nomi dei simboli
index 993d549ee2b809fc2c4977803239fcb789fd122f..c7076a21667a64471019addf568ec1fd7999e6a1 100644 (file)
@@ -1,7 +1,6 @@
 .. include:: ../disclaimer-ita.rst
 
-.. note:: Per leggere la documentazione originale in inglese:
-         :ref:`Documentation/doc-guide/index.rst <doc_guide>`
+:Original: Documentation/doc-guide/index.rst
 
 =========================================
 Includere gli i file di intestazione uAPI
@@ -190,7 +189,7 @@ COPYRIGHT
 
 Copyright (c) 2016 by Mauro Carvalho Chehab <mchehab@s-opensource.com>.
 
-Licenza GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>.
+Licenza GPLv2: GNU GPL version 2 <https://gnu.org/licenses/gpl.html>.
 
 Questo è software libero: siete liberi di cambiarlo e ridistribuirlo.
 Non c'è alcuna garanzia, nei limiti permessi dalla legge.
index fc5f39814e831ea215aedd3ee6a9abb7049977b9..b95dfa1ded0484cb61359a22443c8526f1058703 100644 (file)
@@ -2,9 +2,9 @@
 
 .. _it_linux_doc:
 
-===================
-Traduzione italiana
-===================
+==================================
+La documentazione del kernel Linux
+==================================
 
 .. raw:: latex
 
@@ -12,6 +12,18 @@ Traduzione italiana
 
 :manutentore: Federico Vaga <federico.vaga@vaga.pv.it>
 
+Questo è il livello principale della documentazione del kernel in
+lingua italiana. La traduzione è incompleta, noterete degli avvisi
+che vi segnaleranno la mancanza di una traduzione o di un gruppo di
+traduzioni.
+
+Più in generale, la documentazione, come il kernel stesso, sono in
+costante sviluppo; particolarmente vero in quanto stiamo lavorando
+alla riorganizzazione della documentazione in modo più coerente.
+I miglioramenti alla documentazione sono sempre i benvenuti; per cui,
+se vuoi aiutare, iscriviti alla lista di discussione linux-doc presso
+vger.kernel.org.
+
 .. _it_disclaimer:
 
 Avvertenze
@@ -54,23 +66,8 @@ Se avete bisogno d'aiuto per comunicare con la comunità Linux ma non vi sentite
 a vostro agio nello scrivere in inglese, potete chiedere aiuto al manutentore
 della traduzione.
 
-La documentazione del kernel Linux
-==================================
-
-Questo è il livello principale della documentazione del kernel in
-lingua italiana. La traduzione è incompleta, noterete degli avvisi
-che vi segnaleranno la mancanza di una traduzione o di un gruppo di
-traduzioni.
-
-Più in generale, la documentazione, come il kernel stesso, sono in
-costante sviluppo; particolarmente vero in quanto stiamo lavorando
-alla riorganizzazione della documentazione in modo più coerente.
-I miglioramenti alla documentazione sono sempre i benvenuti; per cui,
-se vuoi aiutare, iscriviti alla lista di discussione linux-doc presso
-vger.kernel.org.
-
 Lavorare con la comunità di sviluppo
-------------------------------------
+====================================
 
 Le guide fondamentali per l'interazione con la comunità di sviluppo del kernel e
 su come vedere il proprio lavoro integrato.
@@ -85,7 +82,7 @@ su come vedere il proprio lavoro integrato.
 
 
 Manuali sull'API interna
-------------------------
+========================
 
 Di seguito una serie di manuali per gli sviluppatori che hanno bisogno di
 interfacciarsi con il resto del kernel.
@@ -96,7 +93,7 @@ interfacciarsi con il resto del kernel.
    core-api/index
 
 Strumenti e processi per lo sviluppo
-------------------------------------
+====================================
 
 Di seguito una serie di manuali contenenti informazioni utili a tutti gli
 sviluppatori del kernel.
@@ -109,7 +106,7 @@ sviluppatori del kernel.
    kernel-hacking/index
 
 Documentazione per gli utenti
------------------------------
+=============================
 
 Di seguito una serie di manuali per gli *utenti* del kernel - ovvero coloro che
 stanno cercando di farlo funzionare al meglio per un dato sistema, ma anche
@@ -120,16 +117,16 @@ Consultate anche `Linux man pages <https://www.kernel.org/doc/man-pages/>`_, che
 vengono mantenuti separatamente dalla documentazione del kernel Linux
 
 Documentazione relativa ai firmware
------------------------------------
+===================================
 Di seguito informazioni sulle aspettative del kernel circa i firmware.
 
 
 Documentazione specifica per architettura
------------------------------------------
+=========================================
 
 
 Documentazione varia
---------------------
+====================
 
 Ci sono documenti che sono difficili da inserire nell'attuale organizzazione
 della documentazione; altri hanno bisogno di essere migliorati e/o convertiti
index 05d362b16bf0b2af3b7c9049f1b5b022bc949589..a9e781d2e323021a6c2af16d1e7429e324a99527 100644 (file)
@@ -1029,6 +1029,11 @@ Dato che questo è un problema abbastanza comune con una propensione
 alle corse critiche, dovreste usare timer_delete_sync()
 (``include/linux/timer.h``) per gestire questo caso.
 
+Prima di rilasciare un temporizzatore dovreste chiamare la funzione
+timer_shutdown() o timer_shutdown_sync() di modo che non venga più ricarmato.
+Ogni successivo tentativo di riarmare il temporizzatore verrà silenziosamente
+ignorato.
+
 Velocità della sincronizzazione
 ===============================
 
index cf92a16ed7e5e274de9f934ce9cc25453bb2dfa4..a7e2a3238415b11e5a6f5197598a811ff260ec01 100644 (file)
@@ -265,15 +265,18 @@ Le etichette in uso più comuni sono:
    :ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`
 
  - Reported-by: menziona l'utente che ha riportato il problema corretto da
-   questa patch; quest'etichetta viene usata per dare credito alle persone
-   che hanno verificato il codice e ci hanno fatto sapere quando le cose non
-   funzionavano correttamente.
+   questa patch; quest'etichetta viene usata per dare credito alle persone che
+   hanno verificato il codice e ci hanno fatto sapere quando le cose non
+   funzionavano correttamente. Se esiste un rapporto disponibile sul web, allora
+   L'etichetta dovrebbe essere seguita da un collegamento al suddetto rapporto.
 
  - Cc: la persona menzionata ha ricevuto una copia della patch ed ha avuto
    l'opportunità di commentarla.
 
-State attenti ad aggiungere queste etichette alla vostra patch: solo
-"Cc:" può essere aggiunta senza il permesso esplicito della persona menzionata.
+State attenti ad aggiungere queste etichette alla vostra patch: solo "Cc:" può
+essere aggiunta senza il permesso esplicito della persona menzionata. Il più
+delle volte anche Reported-by: va bene, ma è sempre meglio chiedere specialmente
+se il baco è stato riportato in una comunicazione privata.
 
 Inviare la modifica
 -------------------
index 473ec2cc558e48f5e55b22b11e84dfe6bd31873c..f37c53f8b5242638aa18a70d54028428c3f02905 100644 (file)
@@ -36,7 +36,7 @@ GNU C                  5.1                gcc --version
 Clang/LLVM (optional)  11.0.0             clang --version
 GNU make               3.81               make --version
 bash                   4.2                bash --version
-binutils               2.23               ld -v
+binutils               2.25               ld -v
 flex                   2.5.35             flex --version
 bison                  2.0                bison --version
 pahole                 1.16               pahole --version
@@ -97,7 +97,7 @@ Questo richiede bash 4.2 o successivo.
 Binutils
 --------
 
-Per generare il kernel è necessario avere Binutils 2.23 o superiore.
+Per generare il kernel è necessario avere Binutils 2.25 o superiore.
 
 pkg-config
 ----------
index 77eac809a63929feeb68205f7ebcfc8ee3376b67..29f83c198025c6d3ce7d2866f785c60d6f06f200 100644 (file)
@@ -40,7 +40,7 @@ Linux più popolari. Cercate ``clang-format`` nel vostro repositorio.
 Altrimenti, potete scaricare una versione pre-generata dei binari di LLVM/clang
 oppure generarlo dai codici sorgenti:
 
-    http://releases.llvm.org/download.html
+    https://releases.llvm.org/download.html
 
 Troverete più informazioni ai seguenti indirizzi:
 
index a393ee4182af4544f9dab5230e3561c463e17145..5f244e16f51148d49c89178b3757652d54f54878 100644 (file)
@@ -1204,10 +1204,10 @@ ISBN 0-201-61586-X.
 
 Manuali GNU - nei casi in cui sono compatibili con K&R e questo documento -
 per indent, cpp, gcc e i suoi dettagli interni, tutto disponibile qui
-http://www.gnu.org/manual/
+https://www.gnu.org/manual/
 
 WG14 è il gruppo internazionale di standardizzazione per il linguaggio C,
-URL: http://www.open-std.org/JTC1/SC22/WG14/
+URL: https://www.open-std.org/JTC1/SC22/WG14/
 
-Kernel process/coding-style.rst, by greg@kroah.com at OLS 2002:
+Kernel CodingStyle, by greg@kroah.com at OLS 2002:
 http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/
index febf838977835a2589d30f66b5824a11fa07ee13..57b501f0dfa4811564e035a837f26562d01ce1e3 100644 (file)
@@ -332,7 +332,7 @@ zero come risultato::
 
 Il valore di ``size`` nell'ultima riga sarà ``zero``, quando uno
 invece si aspetterebbe che il suo valore sia la dimensione totale in
-byte dell'allocazione dynamica che abbiamo appena fatto per l'array
+byte dell'allocazione dinamica che abbiamo appena fatto per l'array
 ``items``. Qui un paio di esempi reali del problema: `collegamento 1
 <https://git.kernel.org/linus/f2cd32a443da694ac4e28fbf4ac6f9d5cc63a539>`_,
 `collegamento 2
@@ -381,4 +381,29 @@ combinazione con struct_size() e flex_array_size()::
         instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
         instance->count = count;
 
-       memcpy(instance->items, source, flex_array_size(instance, items, instance->count));
+        memcpy(instance->items, source, flex_array_size(instance, items, instance->count));
+
+Ci sono due casi speciali dove è necessario usare la macro DECLARE_FLEX_ARRAY()
+(da notare che la stessa macro è chiamata __DECLARE_FLEX_ARRAY() nei file di
+intestazione UAPI). Uno è quando l'array flessibile è l'unico elemento di una
+struttura, e l'altro è quando è parti un unione. Per motivi non tecnici, entrambi
+i casi d'uso non sono permessi dalla specifica C99. Per esempio, per
+convertire il seguente codice::
+
+    struct something {
+        ...
+        union {
+            struct type1 one[0];
+            struct type2 two[0];
+        };
+    };
+
+La macro di supporto dev'essere usata::
+
+    struct something {
+        ...
+        union {
+            DECLARE_FLEX_ARRAY(struct type1, one);
+            DECLARE_FLEX_ARRAY(struct type2, two);
+        };
+    };
index 970671cd91af353c4d37a7b010c19e1eaf9af73c..76ca3226c8cd7a691aaa5bb4fd1c06e92088b3e9 100644 (file)
@@ -364,3 +364,28 @@ un editor esterno.
 
 Un altro problema è che Gmail usa la codifica base64 per tutti quei messaggi
 che contengono caratteri non ASCII. Questo include cose tipo i nomi europei.
+
+Proton Mail
+***********
+
+Il servizio Proton Mail ha una funzionalità che cripta tutti i messaggi verso
+ogni destinatario per cui è possibile trovare una chiave usando il *Web Key
+Directory* (WKD). Il servizio kernel.org pubblica il WKD per ogni sviluppatore
+in possesso di un conto kernel.org. Di conseguenza, tutti i messaggi inviati
+usando Proton Mail verso indirizzi kernel.org verranno criptati.
+
+Proton Mail non fornisce alcun meccanismo per disabilitare questa funzionalità
+perché verrebbe considerato un problema per la riservatezza. Questa funzionalità
+è attiva anche quando si inviano messaggi usando il Proton Mail Bridge. Dunque
+tutta la posta in uscita verrà criptata, incluse le patch inviate con ``git
+send-email``.
+
+I messaggi criptati sono una fonte di problemi; altri sviluppatori potrebbero
+non aver configurato i loro programmi, o strumenti, per gestire messaggi
+criptati; inoltre, alcuni programmi di posta elettronica potrebbero criptare le
+risposte a messaggi criptati per tutti i partecipanti alla discussione, inclusa
+la lista di discussione stessa.
+
+A meno che non venga introdotta una maniera per disabilitare questa
+funzionalità, non è consigliato usare Proton Mail per contribuire allo sviluppo
+del kernel.
index 25602c1a97d1724f8fc2bc3eb9bedcb4b91d4594..cd7977905fb880acc63fb7f8cc128d9929ef30f5 100644 (file)
@@ -10,6 +10,7 @@
 
 .. _it_process_index:
 
+===============================================
 Lavorare con la comunità di sviluppo del kernel
 ===============================================
 
index 5526bcabeb0aac5d480f1cd222700312353837bb..cdc43c4a9b0b0d0c8491a804c7475c416e05dd92 100644 (file)
@@ -68,42 +68,24 @@ stesso.
 Strumenti PGP
 =============
 
-Usare GnuPG v2
---------------
+Usare GnuPG 2.2 o successivo
+----------------------------
 
 La vostra distribuzione potrebbe avere già installato GnuPG, dovete solo
-verificare che stia utilizzando la versione 2.x e non la serie 1.4 --
-molte distribuzioni forniscono entrambe, di base il comando ''gpg''
-invoca GnuPG v.1. Per controllate usate::
+verificare che stia utilizzando la versione abbastanza recente. Per controllate
+usate::
 
     $ gpg --version | head -n1
 
-Se visualizzate ``gpg (GnuPG) 1.4.x``, allora state usando GnuPG v.1.
-Provate il comando ``gpg2`` (se non lo avete, potreste aver bisogno
-di installare il pacchetto gnupg2)::
-
-    $ gpg2 --version | head -n1
-
-Se visualizzate  ``gpg (GnuPG) 2.x.x``, allora siete pronti a partire.
-Questa guida assume che abbiate la versione 2.2.(o successiva) di GnuPG.
-Se state usando la versione 2.0, alcuni dei comandi indicati qui non
-funzioneranno, in questo caso considerate un aggiornamento all'ultima versione,
-la 2.2. Versioni di gnupg-2.1.11 e successive dovrebbero essere compatibili
-per gli obiettivi di questa guida.
-
-Se avete entrambi i comandi: ``gpg`` e ``gpg2``, assicuratevi di utilizzare
-sempre la versione V2, e non quella vecchia. Per evitare errori potreste creare
-un alias::
-
-    $ alias gpg=gpg2
-
-Potete mettere questa opzione nel vostro  ``.bashrc`` in modo da essere sicuri.
+Se state utilizzando la version 2.2 o successiva, allora siete pronti a partire.
+Se invece state usando una versione precedente, allora alcuni comandi elencati
+in questa guida potrebbero non funzionare.
 
 Configurare le opzioni di gpg-agent
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 L'agente GnuPG è uno strumento di aiuto che partirà automaticamente ogni volta
-che userete il comando ``gpg`` e funzionerà in background con l'obiettivo di
+che userete il comando ``gpg`` e funzionerà in *background* con l'obiettivo di
 individuare la passphrase. Ci sono due opzioni che dovreste conoscere
 per personalizzare la scadenza della passphrase nella cache:
 
@@ -131,19 +113,7 @@ valori::
     riguarda vecchie le versioni di GnuPG, poiché potrebbero non svolgere più
     bene il loro compito.
 
-Impostare un *refresh* con cronjob
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Potreste aver bisogno di rinfrescare regolarmente il vostro portachiavi in
-modo aggiornare le chiavi pubbliche di altre persone, lavoro che è svolto
-al meglio con un cronjob giornaliero::
-
-    @daily /usr/bin/gpg2 --refresh >/dev/null 2>&1
-
-Controllate il percorso assoluto del vostro comando ``gpg`` o ``gpg2`` e usate
-il comando ``gpg2`` se per voi ``gpg`` corrisponde alla versione GnuPG v.1.
-
-.. _it_master_key:
+.. _it_protect_your_key:
 
 Proteggere la vostra chiave PGP primaria
 ========================================
@@ -155,55 +125,62 @@ al documento "`Protecting Code Integrity`_" che abbiamo menzionato prima.
 Dovreste inoltre creare una nuova chiave se quella attuale è inferiore a 2048
 bit (RSA).
 
-Chiave principale o sottochiavi
--------------------------------
-
-Le sottochiavi sono chiavi PGP totalmente indipendenti, e sono collegate alla
-chiave principale attraverso firme certificate. È quindi importante
-comprendere i seguenti punti:
-
-1. Non ci sono differenze tecniche tra la chiave principale e la sottochiave.
-2. In fase di creazione, assegniamo limitazioni funzionali ad ogni chiave
-   assegnando capacità specifiche.
-3. Una chiave PGP può avere 4 capacità:
+Le sottochiavi PGP
+------------------
 
-   - **[S]** può essere usata per firmare
-   - **[E]** può essere usata per criptare
-   - **[A]** può essere usata per autenticare
-   - **[C]** può essere usata per certificare altre chiavi
+Raramente le chiavi PGP sono composte da una singola coppia -- solitamente, sono
+una collezione di sottochiavi indipendenti usate per diversi scopi in funzione
+delle capacità assegnate al momento della creazione. Una chiave PGP può avere
+quattro capacità:
+
+- **[S]** può essere usata per firmare
+- **[E]** può essere usata per criptare
+- **[A]** può essere usata per autenticare
+- **[C]** può essere usata per certificare altre chiavi
+
+La chiave con la capacità **[C]** viene spesso chiamata chiave "passepartout"
+(*master key*), ma è una terminologia fuorviante perché lascia intendere che la
+chiave di certificato possa essere usate in sostituzione delle altre (proprio
+come le vere chiavi passpartout in grado di aprire diverse serrature). Dato che
+questo non è il caso, per evitare fraintendimenti, in questa guida ci riferiremo
+a questa chiave chiamandola "La chiave di certificazione".
+
+I seguenti punti sono molto importanti:
+
+1. Tutte le sottochiavi sono indipendenti. Se perdete una sottochiave privata
+   non potrete recuperarla usando le altre.
+2. Ad eccezione della chiave di certificazione, ci possono essere più
+   sottochiavi con le stesse capacità (per esempio, potete avere 2 sottochiavi
+   per criptare, 3 per firmare, ma solo una per una sola per certificare). Tutte
+   le sottochiavi sono indipendenti -- un messaggio criptato usando una chiave
+   **[E]** non può essere decriptato usano altre sottochiavi **[E]**.
+3. Una sottochiave può avere più capacità (per esempio, la chiave **[C]** può
+   anche essere una chiave **[S]**).
+
+La chiave con capacità **[C]** (certificazione) è la sola che può essere usata
+per indicare relazioni fra chiavi. Solo la chiave **[C]** può essere usata per:
+
+- aggiungere o revocare altre chiavi (sottochiavi) che hanno capacità S/E/A;
+- aggiungere, modificare o eliminare le identità (unids) associate alla chiave;
+- aggiungere o modificare la propria data di scadenza o delle sottochiavi;
+- firmare le chiavi di altre persone a scopo di creare una rete di fiducia.
 
-4. Una singola chiave può avere più capacità
-5. Una sottochiave è completamente indipendente dalla chiave principale.
-   Un messaggio criptato con la sottochiave non può essere decrittato con
-   quella principale. Se perdete la vostra sottochiave privata, non può
-   essere rigenerata in nessun modo da quella principale.
+Di base, alla creazione di nuove chiavi, GnuPG genera quanto segue:
 
-La chiave con capacità **[C]** (certify) è identificata come la chiave
-principale perché è l'unica che può essere usata per indicare la relazione
-con altre chiavi. Solo la chiave **[C]** può essere usata per:
+- Una chiave la capacità di certificazione che quella di firma (**[SC]**)
+- Una sottochiave separata con capacità di criptare (**[E]**)
 
-- Aggiungere o revocare altre chiavi (sottochiavi) che hanno capacità S/E/A
-- Aggiungere, modificare o eliminare le identità (unids) associate alla chiave
-- Aggiungere o modificare la data di termine di sé stessa o di ogni sottochiave
-- Firmare le chiavi di altre persone a scopo di creare una rete di fiducia
 
-Di base, alla creazione di nuove chiavi, GnuPG genera quanto segue:
 
-- Una chiave madre che porta sia la capacità di certificazione che quella
-  di firma (**[SC]**)
-- Una sottochiave separata con capacità di criptaggio (**[E]**)
 
-Se avete usato i parametri di base per generare la vostra chiave, quello
+Se avete usato i parametri predefiniti per generare la vostra chiave, quello
 sarà il risultato. Potete verificarlo utilizzando ``gpg --list-secret-keys``,
 per esempio::
 
-    sec   rsa2048 2018-01-23 [SC] [expires: 2020-01-23]
+    sec   ed25519 2022-12-20 [SC] [expires: 2024-12-19]
           000000000000000000000000AAAABBBBCCCCDDDD
     uid           [ultimate] Alice Dev <adev@kernel.org>
-    ssb   rsa2048 2018-01-23 [E] [expires: 2020-01-23]
-
-Qualsiasi chiave che abbia la capacità **[C]** è la vostra chiave madre,
-indipendentemente da quali altre capacità potreste averle assegnato.
+    ssb   cv25519 2022-12-20 [E] [expires: 2024-12-19]
 
 La lunga riga sotto la voce ``sec`` è la vostra impronta digitale --
 negli esempi che seguono, quando vedere ``[fpr]`` ci si riferisce a questa
@@ -238,20 +215,10 @@ possano ricevere la vostra nuova sottochiave::
     $ gpg --send-key [fpr]
 
 .. note:: Supporto ECC in GnuPG
-    GnuPG 2.1 e successivi supportano pienamente *Elliptic Curve Cryptography*,
-    con la possibilità di combinare sottochiavi ECC con le tradizionali chiavi
-    primarie RSA. Il principale vantaggio della crittografia ECC è che è molto
-    più veloce da calcolare e crea firme più piccole se confrontate byte per
-    byte con le chiavi RSA a più di 2048 bit. A meno che non pensiate di
-    utilizzare un dispositivo smartcard che non supporta le operazioni ECC, vi
-    raccomandiamo ti creare sottochiavi di firma ECC per il vostro lavoro col
-    kernel.
-
-    Se per qualche ragione preferite rimanere con sottochiavi RSA, nel comando
-    precedente, sostituite "ed25519" con "rsa2048". In aggiunta, se avete
-    intenzione di usare un dispositivo hardware che non supporta le chiavi
-    ED25519 ECC, come la Nitrokey Pro o la Yubikey, allora dovreste usare
-    "nistp256" al posto di "ed25519".
+
+   Tenete presente che se avete intenzione di usare un dispositivo che non
+   supporta chiavi ED25519 ECC, allora dovreste usare "nistp256" al posto di
+   "ed25519". Più avanti ci sono alcune raccomandazioni per i dispositivi.
 
 Copia di riserva della chiave primaria per gestire il recupero da disastro
 --------------------------------------------------------------------------
@@ -360,13 +327,13 @@ Per prima cosa, identificate il keygrip della vostra chiave primaria::
 
 L'output assomiglierà a questo::
 
-    pub   rsa2048 2018-01-24 [SC] [expires: 2020-01-24]
+    pub   ed25519 2022-12-20 [SC] [expires: 2022-12-19]
           000000000000000000000000AAAABBBBCCCCDDDD
           Keygrip = 1111000000000000000000000000000000000000
     uid           [ultimate] Alice Dev <adev@kernel.org>
-    sub   rsa2048 2018-01-24 [E] [expires: 2020-01-24]
+    sub   cv25519 2022-12-20 [E] [expires: 2022-12-19]
           Keygrip = 2222000000000000000000000000000000000000
-    sub   ed25519 2018-01-24 [S]
+    sub   ed25519 2022-12-20 [S]
           Keygrip = 3333000000000000000000000000000000000000
 
 Trovate la voce keygrid che si trova sotto alla riga ``pub`` (appena sotto
@@ -389,11 +356,11 @@ Ora, se eseguite il comando ``--list-secret-keys``, vedrete che la chiave
 primaria non compare più (il simbolo ``#`` indica che non è disponibile)::
 
     $ gpg --list-secret-keys
-    sec#  rsa2048 2018-01-24 [SC] [expires: 2020-01-24]
+    sec#  ed25519 2022-12-20 [SC] [expires: 2024-12-19]
           000000000000000000000000AAAABBBBCCCCDDDD
     uid           [ultimate] Alice Dev <adev@kernel.org>
-    ssb   rsa2048 2018-01-24 [E] [expires: 2020-01-24]
-    ssb   ed25519 2018-01-24 [S]
+    ssb   cv25519 2022-12-20 [E] [expires: 2024-12-19]
+    ssb   ed25519 2022-12-20 [S]
 
 Dovreste rimuovere anche i file ``secring.gpg`` che si trovano nella cartella
 ``~/.gnupg``, in quanto rimasugli delle versioni precedenti di GnuPG.
@@ -461,18 +428,20 @@ soluzioni disponibili:
   computer portatili più recenti. In aggiunta, offre altre funzionalità di
   sicurezza come FIDO, U2F, e ora supporta anche le chiavi ECC (NISTP)
 
-`Su LWN c'è una buona recensione`_ dei modelli elencati qui sopra e altri.
-La scelta dipenderà dal costo, dalla disponibilità nella vostra area
-geografica e vostre considerazioni sull'hardware aperto/proprietario.
+La vostra scelta dipenderà dal costo, la disponibilità nella vostra regione, e
+sulla scelta fra dispositivi aperti e proprietari.
 
-Se volete usare chiavi ECC, la vostra migliore scelta sul mercato è la
-Nitrokey Start.
+.. note::
+
+    Se siete nella lista MAINTAINERS o avete un profilo su kernel.org, allora
+    `potrete avere gratuitamente una Nitrokey Start`_ grazie alla fondazione
+    Linux.
 
 .. _`Nitrokey Start`: https://shop.nitrokey.com/shop/product/nitrokey-start-6
 .. _`Nitrokey Pro 2`: https://shop.nitrokey.com/shop/product/nitrokey-pro-2-3
 .. _`Yubikey 5`: https://www.yubico.com/product/yubikey-5-overview/
-.. _Gnuk: http://www.fsij.org/doc-gnuk/
-.. _`Su LWN c'è una buona recensione`: https://lwn.net/Articles/736231/
+.. _Gnuk: https://www.fsij.org/doc-gnuk/
+.. _`potrete avere gratuitamente una Nitrokey Start`: https://www.kernel.org/nitrokey-digital-tokens-for-kernel-developers.html
 
 Configurare il vostro dispositivo smartcard
 -------------------------------------------
@@ -513,6 +482,12 @@ altre informazioni sulla carta che potrebbero trapelare in caso di smarrimento.
     A dispetto del nome "PIN", né il PIN utente né quello dell'amministratore
     devono essere esclusivamente numerici.
 
+.. warning::
+
+    Alcuni dispositivi richiedono la presenza delle sottochiavi nel dispositivo
+    stesso prima che possiate cambiare la passphare. Verificate la
+    documentazione del produttore.
+
 Spostare le sottochiavi sulla smartcard
 ---------------------------------------
 
@@ -525,11 +500,11 @@ dell'amministratore::
 
     Secret subkeys are available.
 
-    pub  rsa2048/AAAABBBBCCCCDDDD
-         created: 2018-01-23  expires: 2020-01-23  usage: SC
+    pub  ed25519/AAAABBBBCCCCDDDD
+         created: 2022-12-20  expires: 2024-12-19  usage: SC
          trust: ultimate      validity: ultimate
-    ssb  rsa2048/1111222233334444
-         created: 2018-01-23  expires: never       usage: E
+    ssb  cv25519/1111222233334444
+         created: 2022-12-20  expires: never       usage: E
     ssb  ed25519/5555666677778888
          created: 2017-12-07  expires: never       usage: S
     [ultimate] (1). Alice Dev <adev@kernel.org>
@@ -594,11 +569,11 @@ Ora, se doveste usare l'opzione ``--list-secret-keys``, vedrete una
 sottile differenza nell'output::
 
     $ gpg --list-secret-keys
-    sec#  rsa2048 2018-01-24 [SC] [expires: 2020-01-24]
+    sec#  ed25519 2022-12-20 [SC] [expires: 2024-12-19]
           000000000000000000000000AAAABBBBCCCCDDDD
     uid           [ultimate] Alice Dev <adev@kernel.org>
-    ssb>  rsa2048 2018-01-24 [E] [expires: 2020-01-24]
-    ssb>  ed25519 2018-01-24 [S]
+    ssb>  cv25519 2022-12-20 [E] [expires: 2024-12-19]
+    ssb>  ed25519 2022-12-20 [S]
 
 Il simbolo ``>`` in ``ssb>`` indica che la sottochiave è disponibile solo
 nella smartcard. Se tornate nella vostra cartella delle chiavi segrete e
@@ -661,7 +636,7 @@ eseguite::
 Se per voi è più facile da memorizzare, potete anche utilizzare una data
 specifica (per esempio, il vostro compleanno o capodanno)::
 
-    $ gpg --quick-set-expire [fpr] 2020-07-01
+    $ gpg --quick-set-expire [fpr] 2025-07-01
 
 Ricordatevi di inviare l'aggiornamento ai keyserver::
 
@@ -676,6 +651,21 @@ dovreste importarle nella vostra cartella di lavoro abituale::
     $ gpg --export | gpg --homedir ~/.gnupg --import
     $ unset GNUPGHOME
 
+Usare gpg-agent con ssh
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Se dovete firmare tag o commit su un sistema remoto, potete ridirezionare il
+vostro gpg-agent attraverso ssh. Consultate le istruzioni disponibili nella wiki
+GnuPG:
+
+- `Agent Forwarding over SSH`_
+
+Funziona senza troppi intoppi se avete la possibilità di modificare le
+impostazioni di sshd sul sistema remoto.
+
+.. _`Agent Forwarding over SSH`: https://wiki.gnupg.org/AgentForwarding
+
+.. _it_pgp_with_git:
 
 Usare PGP con Git
 =================
@@ -709,11 +699,6 @@ avere più chiavi segrete, potete dire a git quale dovrebbe usare (``[fpg]``
 
     $ git config --global user.signingKey [fpr]
 
-**IMPORTANTE**: se avete una comando dedicato per ``gpg2``, allora dovreste
-dire a git di usare sempre quello piuttosto che il vecchio comando ``gpg``::
-
-    $ git config --global gpg.program gpg2
-
 Come firmare i tag
 ------------------
 
@@ -812,6 +797,61 @@ Potete dire a git di firmare sempre i commit::
 
 .. _it_verify_identities:
 
+Come lavorare con patch firmate
+-------------------------------
+
+Esiste la possibilità di usare la vostra chiave PGP per firmare le patch che
+invierete alla liste di discussione del kernel. I meccanismi esistenti per la
+firma delle email (PGP-Mime o PGP-inline) tendono a causare problemi
+nell'attività di revisione del codice. Si suggerisce, invece, di utilizare lo
+strumento sviluppato da kernel.org che mette nell'intestazione del messaggio
+un'attestazione delle firme crittografiche (tipo DKIM):
+
+- `Patatt Patch Attestation`_
+
+.. _`Patatt Patch Attestation`: https://pypi.org/project/patatt/
+
+Installare e configurate patatt
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Lo strumento patatt è disponibile per diverse distribuzioni, dunque cercatelo
+prima lì. Oppure potete installarlo usano pypi "``pip install patatt``"
+
+Se avete già configurato git con la vostra chiave PGP (usando
+``user.signingKey``), allora patatt non ha bisogno di alcuna configurazione
+aggiuntiva. Potete iniziare a firmare le vostre patch aggiungendo un aggancio a
+git-send-email nel vostro repositorio::
+
+    patatt install-hook
+
+Ora, qualsiasi patch che invierete con ``git send-email`` verrà automaticamente
+firmata usando la vostra firma crittografica.
+
+Verificare le firme di patatt
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Se usate ``b4`` per verificare ed applicare le patch, allora tenterà
+automaticamente di verificare tutte le firme DKIM e patatt disponibili. Per
+esempio::
+
+    $ b4 am 20220720205013.890942-1-broonie@kernel.org
+    [...]
+    Checking attestation on all messages, may take a moment...
+    ---
+      ✓ [PATCH v1 1/3] kselftest/arm64: Correct buffer allocation for SVE Z registers
+      ✓ [PATCH v1 2/3] arm64/sve: Document our actual ABI for clearing registers on syscall
+      ✓ [PATCH v1 3/3] kselftest/arm64: Enforce actual ABI for SVE syscalls
+      ---
+      ✓ Signed: openpgp/broonie@kernel.org
+      ✓ Signed: DKIM/kernel.org
+
+.. note::
+
+   Lo sviluppo di patatt e b4 è piuttosto attivo. Si consiglia di verificare la
+   documentazione più recente.
+
+.. _it_kernel_identities:
+
 Come verificare l'identità degli sviluppatori del kernel
 ========================================================
 
@@ -884,64 +924,18 @@ di base di GnuPG v2). Per farlo, aggiungete (o modificate) l'impostazione
 
     trust-model tofu+pgp
 
-Come usare i keyserver in sicurezza
------------------------------------
-Se ottenete l'errore "No public key" quando cercate di validate il tag di
-qualcuno, allora dovreste cercare quella chiave usando un keyserver. È
-importante tenere bene a mente che non c'è alcuna garanzia che la chiave
-che avete recuperato da un keyserver PGP appartenga davvero alla persona
-reale -- è progettato così. Dovreste usare il Web of Trust per assicurarvi
-che la chiave sia valida.
-
-Come mantenere il Web of Trust va oltre gli scopi di questo documento,
-semplicemente perché farlo come si deve richiede sia sforzi che perseveranza
-che tendono ad andare oltre al livello di interesse della maggior parte degli
-esseri umani. Qui di seguito alcuni rapidi suggerimenti per aiutarvi a ridurre
-il rischio di importare chiavi maligne.
-
-Primo, diciamo che avete provato ad eseguire ``git verify-tag`` ma restituisce
-un errore dicendo che la chiave non è stata trovata::
-
-    $ git verify-tag sunxi-fixes-for-4.15-2
-    gpg: Signature made Sun 07 Jan 2018 10:51:55 PM EST
-    gpg:                using RSA key DA73759BF8619E484E5A3B47389A54219C0F2430
-    gpg:                issuer "wens@...org"
-    gpg: Can't check signature: No public key
-
-Cerchiamo nel keyserver per maggiori informazioni sull'impronta digitale
-della chiave (l'impronta digitale, probabilmente, appartiene ad una
-sottochiave, dunque non possiamo usarla direttamente senza trovare prima
-l'ID della chiave primaria associata ad essa)::
-
-    $ gpg --search DA73759BF8619E484E5A3B47389A54219C0F2430
-    gpg: data source: hkp://keys.gnupg.net
-    (1) Chen-Yu Tsai <wens@...org>
-          4096 bit RSA key C94035C21B4F2AEB, created: 2017-03-14, expires: 2019-03-15
-    Keys 1-1 of 1 for "DA73759BF8619E484E5A3B47389A54219C0F2430".  Enter number(s), N)ext, or Q)uit > q
-
-Localizzate l'ID della chiave primaria, nel nostro esempio
-``C94035C21B4F2AEB``. Ora visualizzate le chiavi di Linus Torvalds
-che avete nel vostro portachiavi::
-
-    $ gpg --list-key torvalds@kernel.org
-    pub   rsa2048 2011-09-20 [SC]
-          ABAF11C65A2970B130ABE3C479BE3E4300411886
-    uid           [ unknown] Linus Torvalds <torvalds@kernel.org>
-    sub   rsa2048 2011-09-20 [E]
-
-Poi, cercate un percorso affidabile da Linux Torvalds alla chiave che avete
-trovato con ``gpg --search`` usando la chiave sconosciuta.Per farlo potete usare
-diversi strumenti come https://github.com/mricon/wotmate,
-https://git.kernel.org/pub/scm/docs/kernel/pgpkeys.git/tree/graphs, e
-https://the.earth.li/~noodles/pathfind.html.
-
-Se trovate un paio di percorsi affidabili è un buon segno circa la validità
-della chiave. Ora, potete aggiungerla al vostro portachiavi dal keyserver::
-
-    $ gpg --recv-key C94035C21B4F2AEB
-
-Questa procedura non è perfetta, e ovviamente state riponendo la vostra
-fiducia nell'amministratore del servizio *PGP Pathfinder* sperando che non
-sia malintenzionato (infatti, questo va contro :ref:`it_devs_not_infra`).
-Tuttavia, se mantenete con cura la vostra rete di fiducia sarà un deciso
-miglioramento rispetto alla cieca fiducia nei keyserver.
+Usare il repositorio kernel.org per il web of trust
+---------------------------------------------------
+
+Il progetto kernel.org mantiene un repositorio git con le chiavi pubbliche degli sviluppatori in alternativa alla replica dei server di chiavi che negli ultimi anni sono spariti. La documentazione completa su come impostare il repositorio come vostra sorgente di chiavi pubbliche può essere trovato qui:
+
+- `Kernel developer PGP Keyring`_
+
+Se siete uno sviluppatore del kernel, per favore valutate l'idea di inviare la
+vostra chiave per l'inclusione in quel portachiavi.
+
+
+If you are a kernel developer, please consider submitting your key for
+inclusion into that keyring.
+
+.. _`Kernel developer PGP Keyring`: https://korg.docs.kernel.org/pgpkeys.html
index c1a9b481a6f9989a060a72c1e760e820777ac043..5bc5b9d42f31881735d83d72a06d09de4211683f 100644 (file)
@@ -18,10 +18,6 @@ Linux supporta anche ``clang`` [it-clang]_, leggete la documentazione
 Questo dialetto contiene diverse estensioni al linguaggio [it-gnu-extensions]_,
 e molte di queste vengono usate sistematicamente dal kernel.
 
-Il kernel offre un certo livello di supporto per la compilazione con
-``icc`` [it-icc]_ su diverse architetture, tuttavia in questo momento
-il supporto non è completo e richiede delle patch aggiuntive.
-
 Attributi
 ---------
 
@@ -43,11 +39,30 @@ possono usare e/o per accorciare il codice.
 Per maggiori informazioni consultate il file d'intestazione
 ``include/linux/compiler_attributes.h``.
 
+Rust
+----
+
+Il kernel supporta sperimentalmente il linguaggio di programmazione Rust
+[it-rust-language]_ abilitando l'opzione di configurazione ``CONFIG_RUST``. Il
+codice verrà compilato usando ``rustc`` [it-rustc]_ con l'opzione
+``--edition=2021`` [it-rust-editions]_. Le edizioni Rust sono un modo per
+introdurre piccole modifiche senza compatibilità all'indietro._
+
+In aggiunta, nel kernel vengono utilizzate alcune funzionalità considerate
+instabili [it-rust-unstable-features]_. Queste funzionalità potrebbero cambiare
+in futuro, dunque è un'obiettivo importante è quello di far uso solo di
+funzionalità stabili.
+
+Per maggiori informazioni fate riferimento a Documentation/rust/index.rst .
+
 .. [it-c-language] http://www.open-std.org/jtc1/sc22/wg14/www/standards
 .. [it-gcc] https://gcc.gnu.org
 .. [it-clang] https://clang.llvm.org
-.. [it-icc] https://software.intel.com/en-us/c-compilers
 .. [it-gcc-c-dialect-options] https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html
 .. [it-gnu-extensions] https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html
 .. [it-gcc-attribute-syntax] https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html
 .. [it-n2049] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2049.pdf
+.. [it-rust-language] https://www.rust-lang.org
+.. [it-rustc] https://doc.rust-lang.org/rustc/
+.. [it-rust-editions] https://doc.rust-lang.org/edition-guide/editions/
+.. [it-rust-unstable-features] https://github.com/Rust-for-Linux/linux/issues/2
index 0be675b0319931b9c514f76f43a2738379306635..248bf1e4b171b49631d09953713531e3b9423b34 100644 (file)
@@ -106,6 +106,12 @@ al messaggio della patch, così:
 
     commit <sha1> upstream.
 
+o in alternativa:
+
+.. code-block:: none
+
+    [ Upstream commit <sha1>  ]
+
 In aggiunta, alcune patch inviate attraverso l':ref:`it_option_1` potrebbero
 dipendere da altre che devo essere incluse. Questa situazione può essere
 indicata nel seguente modo nell'area dedicata alle firme:
index c2cfa0948b2bc2994db7a497eb14b3f6dc7a64c4..447b18792e61a29ab9ed3faa362adbab70eebf18 100644 (file)
@@ -272,7 +272,7 @@ embargo potrebbe essere preso in considerazione per dare il tempo alle
 distribuzioni di prendere la patch e renderla disponibile ai loro utenti;
 in questo caso, ovviamente, la patch non dovrebbe essere inviata su alcuna
 lista di discussione pubblica. Leggete anche
-Documentation/admin-guide/security-bugs.rst.
+Documentation/process/security-bugs.rst.
 
 Patch che correggono bachi importanti su un kernel già rilasciato, dovrebbero
 essere inviate ai manutentori dei kernel stabili aggiungendo la seguente riga::
@@ -429,7 +429,7 @@ poi dovete solo aggiungere una riga che dice::
 
        Signed-off-by: Random J Developer <random@developer.example.org>
 
-usando il vostro vero nome (spiacenti, non si accettano pseudonimi o
+usando il vostro vero nome (spiacenti, non si accettano
 contributi anonimi). Questo verrà fatto automaticamente se usate
 ``git commit -s``. Anche il ripristino di uno stato precedente dovrebbe
 includere "Signed-off-by", se usate ``git revert -s`` questo verrà
@@ -785,7 +785,7 @@ Riferimenti
 -----------
 
 Andrew Morton, "La patch perfetta" (tpp).
-  <http://www.ozlabs.org/~akpm/stuff/tpp.txt>
+  <https://www.ozlabs.org/~akpm/stuff/tpp.txt>
 
 Jeff Garzik, "Formato per la sottomissione di patch per il kernel Linux"
   <https://web.archive.org/web/20180829112450/http://linux.yyz.us/patch-format.html>
index efc640cac596ebeaec08d31c111418b15b428bca..4fff9a59b5482f83b765d03c86781162fdf45538 100644 (file)
@@ -119,9 +119,9 @@ concorrenza siano stati opportunamente considerati.
 Riferimenti
 ===========
 
-[1] http://lwn.net/Articles/233481/
+[1] https://lwn.net/Articles/233481/
 
-[2] http://lwn.net/Articles/233482/
+[2] https://lwn.net/Articles/233482/
 
 Crediti
 =======
index 9b0b3436dfcf785161727fc1dace32fdf9179831..8d856ebe873c65162c213eba423dcd054c52366f 100644 (file)
@@ -167,7 +167,7 @@ linux-api@vger.kernel.org に送ることを勧めます。
     このドキュメントは Linux 開発の思想を理解するのに非常に重要です。
     そして、他のOSでの開発者が Linux に移る時にとても重要です。
 
-  :ref:`Documentation/admin-guide/security-bugs.rst <securitybugs>`
+  :ref:`Documentation/process/security-bugs.rst <securitybugs>`
     もし Linux カーネルでセキュリティ問題を発見したように思ったら、こ
     のドキュメントのステップに従ってカーネル開発者に連絡し、問題解決を
     支援してください。
index 969e91a95bb0ca970dcf4b2035fb5cc706468357..34f14899c1559d125b6b2559ec1844931178fff8 100644 (file)
@@ -157,7 +157,7 @@ mtk.manpages@gmail.com의 메인테이너에게 보낼 것을 권장한다.
     리눅스로 전향하는 사람들에게는 매우 중요하다.
 
 
-  :ref:`Documentation/admin-guide/security-bugs.rst <securitybugs>`
+  :ref:`Documentation/process/security-bugs.rst <securitybugs>`
     여러분들이 리눅스 커널의 보안 문제를 발견했다고 생각한다면 이 문서에
     나온 단계에 따라서 커널 개발자들에게 알리고 그 문제를 해결할 수 있도록
     도와 달라.
index f9818d687b540b3e744782e87a12b2c449d1938c..f1629738b49d034be2201592180d9210488360fa 100644 (file)
@@ -135,7 +135,7 @@ de obligada lectura:
      de Linux y es muy importante para las personas que se mudan a Linux
      tras desarrollar otros sistemas operativos.
 
-  :ref:`Documentation/admin-guide/security-bugs.rst <securitybugs>`
+  :ref:`Documentation/process/security-bugs.rst <securitybugs>`
     Si cree que ha encontrado un problema de seguridad en el kernel de
     Linux, siga los pasos de este documento para ayudar a notificar a los
     desarrolladores del kernel y ayudar a resolver el problema.
index f62bd797216dd97a272e00de03a8f6452569aaea..27097a808c8840e6f89b4032927f702081ac296e 100644 (file)
@@ -604,7 +604,7 @@ READ_ONCE() para DEC Alpha, lo que significa que las únicas personas que
 necesitan prestar atención a esta sección son aquellas que trabajan en el
 código específico de la arquitectura DEC Alpha y aquellas que trabajan en
 READ_ONCE() por dentro. Para aquellos que lo necesitan, y para aquellos que
-estén interesados ​​desde un punto de vista histórico, aquí está la historia
+estén interesados desde un punto de vista histórico, aquí está la historia
 de las barreras de dependencia de dirección.
 
 [!] Si bien las dependencias de direcciones se observan tanto en carga a
diff --git a/Documentation/translations/sp_SP/process/deprecated.rst b/Documentation/translations/sp_SP/process/deprecated.rst
new file mode 100644 (file)
index 0000000..d52120e
--- /dev/null
@@ -0,0 +1,381 @@
+.. include:: ../disclaimer-sp.rst
+
+:Original: :ref:`Documentation/process/deprecated.rst <deprecated>`
+:Translator: Sergio Gonzalez <sergio.collado@gmail.com>
+
+.. _sp_deprecated:
+
+============================================================================
+Interfaces obsoletos, Características del lenguaje, Atributos y Convenciones
+============================================================================
+
+En un mundo perfecto, sería posible convertir todas las instancias de
+alguna API obsoleta en una nueva API y quitar la API anterior en un
+único ciclo de desarrollo. Desafortunadamente, debido al tamaño del kernel,
+la jerarquía de mantenimiento, y el tiempo, no siempre es posible hacer
+estos cambios de una única vez. Esto significa que las nuevas instancias
+han de ir creándose en el kernel, mientras que las antiguas se quitan,
+haciendo que la cantidad de trabajo para limpiar las APIs crezca. Para
+informar a los desarrolladores sobre qué ha sido declarado obsoleto y por
+qué, ha sido creada esta lista como un lugar donde indicar cuando los usos
+obsoletos son propuestos para incluir en el kernel.
+
+__deprecated
+------------
+Mientras que este atributo señala visualmente que un interface ha sido
+declarado obsoleto, este `no produce más avisos durante las compilaciones
+<https://git.kernel.org/linus/771c035372a036f83353eef46dbb829780330234>`_
+porque uno de los objetivos del kernel es que compile sin avisos, y
+nadie ha hecho nada para quitar estos interfaces obsoletos. Mientras
+que usar `__deprecated` es sencillo para anotar una API obsoleta en
+un archivo de cabecera, no es la solución completa. Dichos interfaces
+deben o bien ser quitados por completo, o añadidos a este archivo para
+desanimar a otros a usarla en el futuro.
+
+BUG() y BUG_ON()
+----------------
+Use WARN() y WARN_ON() en su lugar, y gestione las condiciones de error
+"imposibles" tan elegantemente como se pueda. Mientras que la familia de
+funciones BUG() fueron originalmente diseñadas para actuar como una
+"situación imposible", confirmar y disponer de un hilo del kernel de forma
+"segura", estas funciones han resultado ser demasiado arriesgadas. (e.g.
+"¿en qué orden se necesitan liberar los locks? ¿Se han restaurado sus
+estados?). La popular función BUG() desestabilizará el sistema o lo romperá
+totalmente, lo cual hace imposible depurarlo o incluso generar reportes de
+crash. Linus tiene una `opinión muy fuerte
+<https://lore.kernel.org/lkml/CA+55aFy6jNLsywVYdGp83AMrXBo_P-pkjkphPGrO=82SPKCpLQ@mail.gmail.com/>`_
+y sentimientos `sobre esto
+<https://lore.kernel.org/lkml/CAHk-=whDHsbK3HTOpTF=ue_o04onRwTEaK_ZoJp_fjbqq4+=Jw@mail.gmail.com/>`_.
+
+Nótese que la familia de funciones WARN() únicamente debería ser usada
+en situaciones que se "esperan no sean alcanzables". Si se quiere
+avisar sobre situaciones "alcanzables pero no deseadas", úsese la familia
+de funciones pr_warn(). Los responsables del sistema pueden haber definido
+*panic_on_warn* sysctl para asegurarse que sus sistemas no continúan
+ejecutándose en presencia del condiciones "no alcanzables". (Por ejemplo,
+véase commits como `este
+<https://git.kernel.org/linus/d4689846881d160a4d12a514e991a740bcb5d65a>`_.)
+
+Operaciones aritméticas en los argumentos de reserva de memoria
+---------------------------------------------------------------
+Los cálculos dinámicos de tamaño (especialmente multiplicaciones) no
+deberían realizarse en los argumentos de reserva de memoria (o similares)
+debido al riesgo de desbordamiento. Esto puede llevar a valores rotando y
+que se realicen reservas de memoria menores que las que se esperaban. El
+uso de esas reservas puede llevar a desbordamientos en el 'heap' de memoria
+y otros funcionamientos incorrectos. (Una excepción a esto son los valores
+literales donde el compilador si puede avisar si estos puede desbordarse.
+De todos modos, el método recomendado en estos caso es reescribir el código
+como se sugiere a continuación para evitar las operaciones aritméticas en
+la reserva de memoria.)
+
+Por ejemplo, no utilice `count * size`` como argumento, como en::
+
+    foo = kmalloc(count * size, GFP_KERNEL);
+
+En vez de eso, utilice la reserva con dos argumentos::
+
+       foo = kmalloc_array(count, size, GFP_KERNEL);
+
+Específicamente, kmalloc() puede ser sustituido con kmalloc_array(),
+kzalloc() puede ser sustituido con kcalloc().
+
+Si no existen funciones con dos argumentos, utilice las funciones que se
+saturan, en caso de desbordamiento::
+
+       bar = vmalloc(array_size(count, size));
+
+Otro caso común a evitar es calcular el tamaño de una estructura com
+la suma de otras estructuras, como en::
+
+    header = kzalloc(sizeof(*header) + count * sizeof(*header->item),
+                 GFP_KERNEL);
+
+En vez de eso emplee::
+
+    header = kzalloc(struct_size(header, item, count), GFP_KERNEL);
+
+.. note:: Si se usa struct_size() en una estructura que contiene un elemento
+       de longitud cero o un array de un único elemento como un array miembro,
+       por favor reescribir ese uso y cambiar a un `miembro array flexible
+       <#zero-length-and-one-element-arrays>`_
+
+
+Para otros cálculos, por favor use las funciones de ayuda: size_mul(),
+size_add(), and size_sub(). Por ejemplo, en el caso de::
+
+    foo = krealloc(current_size + chunk_size * (count - 3), GFP_KERNEL);
+
+Re-escríbase, como::
+
+    foo = krealloc(size_add(current_size,
+                        size_mul(chunk_size,
+                                 size_sub(count, 3))), GFP_KERNEL);
+
+Para más detalles, mire también array3_size() y flex_array_size(),
+como también la familia de funciones relacionadas check_mul_overflow(),
+check_add_overflow(), check_sub_overflow(), y check_shl_overflow().
+
+
+simple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull()
+----------------------------------------------------------------------
+Las funciones: simple_strtol(), simple_strtoll(), simple_strtoul(), y
+simple_strtoull() explícitamente ignoran los desbordamientos, lo que puede
+llevar a resultados inesperados por las funciones que las llaman. Las
+funciones respectivas kstrtol(), kstrtoll(), kstrtoul(), y kstrtoull()
+tienden a ser reemplazos correctos, aunque nótese que necesitarán que la
+cadena de caracteres termine en NUL o en el carácter de línea nueva.
+
+
+strcpy()
+--------
+strcpy() no realiza verificaciones de los límites del buffer de destino.
+Esto puede resultar en desbordamientos lineals más allá del fin del buffer,
+causando todo tipo de errores. Mientras `CONFIG_FORTIFY_SOURCE=y` otras
+varias opciones de compilación reducen el riesgo de usar esta función, no
+hay ninguna buena razón para añadir nuevos usos de esta. El remplazo seguro
+es la función strscpy(), aunque se ha de tener cuidado con cualquier caso
+en el el valor retornado por strcpy() sea usado, ya que strscpy() no
+devuelve un puntero a el destino, sino el número de caracteres no nulos
+compilados (o el valor negativo de errno cuando se trunca la cadena de
+caracteres).
+
+strncpy() en cadenas de caracteres terminadas en NUL
+----------------------------------------------------
+El uso de strncpy() no garantiza que el buffer de destino esté terminado en
+NUL. Esto puede causar varios errores de desbordamiento en lectura y otros
+tipos de funcionamiento erróneo debido a que falta la terminación en NUL.
+Esta función también termina la cadena de caracteres en NUL en el buffer de
+destino si la cadena de origen es más corta que el buffer de destino, lo
+cual puede ser una penalización innecesaria para funciones usen esta
+función con cadenas de caracteres que sí están terminadas en NUL.
+
+Cuando se necesita que la cadena de destino sea terminada en NUL,
+el mejor reemplazo es usar la función strscpy(), aunque se ha de tener
+cuidado en los casos en los que el valor de strncpy() fuera usado, ya que
+strscpy() no devuelve un puntero al destino, sino el número de
+caracteres no nulos copiados (o el valor negativo de errno cuando se trunca
+la cadena de caracteres). Cualquier caso restante que necesitase todavía
+ser terminado en el caracter nulo, debería usar strscpy_pad().
+
+Si una función usa cadenas de caracteres que no necesitan terminar en NUL,
+debería usarse strtomem(), y el destino debería señalarse con el atributo
+`__nonstring
+<https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html>`_
+para evitar avisos futuros en el compilador. Para casos que todavía
+necesitan cadenas de caracteres que se rellenen al final con el
+caracter NUL, usar strtomem_pad().
+
+strlcpy()
+---------
+strlcpy() primero lee por completo el buffer de origen (ya que el valor
+devuelto intenta ser el mismo que el de strlen()). Esta lectura puede
+sobrepasar el límite de tamaño del destino. Esto ineficiente y puede causar
+desbordamientos de lectura si la cadena de origen no está terminada en el
+carácter NUL. El reemplazo seguro de esta función es strscpy(), pero se ha
+de tener cuidado que en los casos en lso que se usase el valor devuelto de
+strlcpy(), ya que strscpy() devolverá valores negativos de erno cuando se
+produzcan truncados.
+
+Especificación de formato %p
+----------------------------
+Tradicionalmente,el uso de "%p" en el formato de cadenas de caracteres
+resultaría en exponer esas direcciones en dmesg, proc, sysfs, etc. En vez
+de dejar que sean una vulnerabilidad, todos los "%p" que se usan en el
+kernel se imprimen como un hash, haciéndolos efectivamente inutilizables
+para usarlos como direcciones de memoria. Nuevos usos de "%p" no deberían
+ser añadidos al kernel. Para textos de direcciones, usar "%pS" es
+mejor, ya que resulta en el nombre del símbolo. Para prácticamente el
+resto de casos, mejor no usar "%p" en absoluto.
+
+Parafraseando las actuales `direcciones de Linus <https://lore.kernel.org/lkml/CA+55aFwQEd_d40g4mUCSsVRZzrFPUJt74vc6PPpb675hYNXcKw@mail.gmail.com/>`_:
+
+- Si el valor "hasheado" "%p" no tienen ninguna finalidad, preguntarse si el
+  puntero es realmente importante. ¿Quizás se podría quitar totalmente?
+- Si realmente se piensa que el valor del puntero es importante, ¿porqué
+  algún estado del sistema o nivel de privilegio de usuario es considerado
+  "especial"? Si piensa que puede justificarse (en comentarios y mensajes
+  del commit), de forma suficiente como para pasar el escrutinio de Linux,
+  quizás pueda usar el "%p", a la vez que se asegura que tiene los permisos
+  correspondientes.
+
+Si está depurando algo donde el "%p" hasheado está causando problemas,
+se puede arrancar temporalmente con la opción de depuración "`no_hash_pointers
+<https://git.kernel.org/linus/5ead723a20e0447bc7db33dc3070b420e5f80aa6>`_".
+
+
+Arrays de longitud variable (VLAs)
+----------------------------------
+Usando VLA en la pila (stack) produce un código mucho peor que los arrays
+de tamaño estático. Mientras que estos errores no triviales de `rendimiento
+<https://git.kernel.org/linus/02361bc77888>`_  son razón suficiente
+para no usar VLAs, esto además son un riesgo de seguridad. El crecimiento
+dinámico del array en la pila, puede exceder la memoria restante en
+el segmento de la pila. Esto podría llevara a un fallo, posible sobre-escritura
+de contenido al final de la pila (cuando se construye sin
+`CONFIG_THREAD_INFO_IN_TASK=y`), o sobre-escritura de la memoria adyacente
+a la pila (cuando se construye sin `CONFIG_VMAP_STACK=y`).
+
+
+Switch case fall-through implícito
+----------------------------------
+El lenguaje C permite a las sentencias 'switch' saltar de un caso al
+siguiente caso cuando la sentencia de ruptura "break" no aparece al final
+del caso. Esto, introduce ambigüedad en el código, ya que no siempre está
+claro si el 'break' que falta es intencionado o un olvido. Por ejemplo, no
+es obvio solamente mirando al código si `STATE_ONE` está escrito para
+intencionadamente saltar en `STATE_TWO`::
+
+    switch (value) {
+    case STATE_ONE:
+        do_something();
+    case STATE_TWO:
+        do_other();
+        break;
+    default:
+        WARN("unknown state");
+    }
+
+Ya que ha habido una larga lista de defectos `debidos a declaraciones de "break"
+que faltan <https://cwe.mitre.org/data/definitions/484.html>`_, no se
+permiten 'fall-through' implícitos. Para identificar 'fall-through'
+intencionados, se ha adoptado la pseudo-palabra-clave macro "falltrhrough",
+que expande las extensiones de gcc `__attribute__((__fallthrough__))
+<https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html>`_.
+(Cuando la sintaxis de C17/c18 `[[fallthrough]]` sea más comúnmente
+soportadas por los compiladores de C, analizadores estáticos, e IDEs,
+se puede cambiar a usar esa sintaxis para esa pseudo-palabra-clave.
+
+Todos los bloques switch/case deben acabar en uno de:
+
+* break;
+* fallthrough;
+* continue;
+* goto <label>;
+* return [expression];
+
+
+Arrays de longitud cero y un elemento
+-------------------------------------
+Hay una necesidad habitual en el kernel de proveer una forma para declarar
+un grupo de elementos consecutivos de tamaño dinámico en una estructura.
+El código del kernel debería usar siempre `"miembros array flexible" <https://en.wikipedia.org/wiki/Flexible_array_member>`_
+en estos casos. El estilo anterior de arrays de un elemento o de longitud
+cero, no deben usarse más.
+
+En el código C más antiguo, los elementos finales de tamaño dinámico se
+obtenían especificando un array de un elemento al final de una estructura::
+
+       struct something {
+               size_t count;
+               struct foo items[1];
+       };
+
+En código C más antiguo, elementos seguidos de tamaño dinámico eran creados
+especificando una array de un único elemento al final de una estructura::
+
+       struct something {
+               size_t count;
+               struct foo items[1];
+       };
+
+Esto llevó a resultados incorrectos en los cálculos de tamaño mediante
+sizeof() (el cual hubiera necesitado eliminar el tamaño del último elemento
+para tener un tamaño correcto de la "cabecera"). Una `extensión de GNU C
+<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_ se empezó a usar
+para permitir los arrays de longitud cero, para evitar estos tipos de
+problemas de tamaño::
+
+       struct something {
+               size_t count;
+               struct foo items[0];
+       };
+
+Pero esto llevó a otros problemas, y no solucionó algunos otros problemas
+compartidos por ambos estilos, como no ser capaz de detectar cuando ese array
+accidentalmente _no_ es usado al final de la estructura (lo que podía pasar
+directamente, o cuando dicha estructura era usada en uniones, estructuras
+de estructuras, etc).
+
+C99 introdujo "los arrays miembros flexibles", los cuales carecen de un
+tamaño numérico en su declaración del array::
+
+       struct something {
+               size_t count;
+               struct foo items[];
+       };
+
+Esta es la forma en la que el kernel espera que se declaren los elementos
+de tamaño dinámico concatenados. Esto permite al compilador generar
+errores, cuando el array flexible no es declarado en el último lugar de la
+estructura, lo que ayuda a prevenir errores en él código del tipo
+`comportamiento indefinido <https://git.kernel.org/linus/76497732932f15e7323dc805e8ea8dc11bb587cf>`_.
+Esto también permite al compilador analizar correctamente los tamaños de
+los arrays (via sizeof(), `CONFIG_FORTIFY_SOURCE`, y `CONFIG_UBSAN_BOUNDS`).
+Por ejemplo, si no hay un mecanismo que avise que el siguiente uso de
+sizeof() en un array de longitud cero, siempre resulta en cero::
+
+        struct something {
+                size_t count;
+                struct foo items[0];
+        };
+
+        struct something *instance;
+
+        instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
+        instance->count = count;
+
+        size = sizeof(instance->items) * instance->count;
+        memcpy(instance->items, source, size);
+
+En la última línea del código anterior, ``zero`` vale ``cero``, cuando uno
+podría esperar que representa el tamaño total en bytes de la memoria dinámica
+reservada para el array consecutivo ``items``. Aquí hay un par de ejemplos
+más sobre este tema:  `link 1
+<https://git.kernel.org/linus/f2cd32a443da694ac4e28fbf4ac6f9d5cc63a539>`_,
+`link 2
+<https://git.kernel.org/linus/ab91c2a89f86be2898cee208d492816ec238b2cf>`_.
+Sin embargo, los array de miembros flexibles tienen un type incompleto, y
+no se ha de aplicar el operador sizeof()<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_,
+así cualquier mal uso de dichos operadores será detectado inmediatamente en
+el momento de compilación.
+
+Con respecto a los arrays de un único elemento, se ha de ser consciente de
+que dichos arrays ocupan al menos tanto espacio como un único objeto del
+tipo https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_, de ahí que
+estos contribuyan al tamaño de la estructura que los contiene. Esto es
+proclive a errores cada vez que se quiere calcular el tamaño total de la
+memoria dinámica para reservar una estructura que contenga un array de este
+tipo como su miembro::
+
+        struct something {
+                size_t count;
+                struct foo items[1];
+        };
+
+        struct something *instance;
+
+        instance = kmalloc(struct_size(instance, items, count - 1), GFP_KERNEL);
+        instance->count = count;
+
+        size = sizeof(instance->items) * instance->count;
+        memcpy(instance->items, source, size);
+
+En el ejemplo anterior, hemos de recordar calcular ``count - 1``, cuando se
+usa la función de ayuda struct_size(), de otro modo estaríamos
+--desintencionadamente--reservando memoria para un  ``items`` de más. La
+forma más clara y menos proclive a errores es implementar esto mediante el
+uso de `array miembro flexible`, junto con las funciones de ayuda:
+struct_size() y flex_array_size()::
+
+        struct something {
+                size_t count;
+                struct foo items[];
+        };
+
+        struct something *instance;
+
+        instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
+        instance->count = count;
+
+        memcpy(instance->items, source, flex_array_size(instance, items, instance->count));
index 0f1e131b3bb14d049aedc1e33be046ae5bdcbdb6..3b0c3259372684fb2e61b9f5278c78b883aaa29f 100644 (file)
@@ -18,3 +18,4 @@
    email-clients
    magic-number
    programming-language
+   deprecated
index bf95ceb5e865a15372cd73d080d78a94b17d03f6..c2757d9ab2168e3900913d970642ec8885d94c97 100644 (file)
@@ -276,7 +276,7 @@ parche a security@kernel.org. Para errores graves, se debe mantener un
 poco de discreción y permitir que los distribuidores entreguen el parche a
 los usuarios; en esos casos, obviamente, el parche no debe enviarse a
 ninguna lista pública. Revise también
-Documentation/admin-guide/security-bugs.rst.
+Documentation/process/security-bugs.rst.
 
 Los parches que corrigen un error grave en un kernel en uso deben dirigirse
 hacia los maintainers estables poniendo una línea como esta::
index 812ef315c8f69b13b8a18b5a808029a15c22833c..03d33c710604c93402707d46ed2fcd6aa12fe63d 100644 (file)
@@ -250,7 +250,7 @@ LRU的优先级的提升,同时降低那些超过120秒无人访问的内存
 理被限制在最多1%的CPU以避免DAMON_LRU_SORT消费过多CPU时间。在系统空闲内存超过50%
 时DAMON_LRU_SORT停止工作,并在低于40%时重新开始工作。如果DAMON_RECLAIM没有取得
 进展且空闲内存低于20%,再次让DAMON_LRU_SORT停止工作,以此回退到以LRU链表为基础
-以页面为单位的内存回收上。
+以页面为单位的内存回收上。 ::
 
     # cd /sys/modules/damon_lru_sort/parameters
     # echo 500 > hot_thres_access_freq
index b8120391755d46a4198181ddf53d02f6d3f3ff76..d6b8f8a4e7f63de2d7e01cce2c5dce550ac3cc07 100644 (file)
@@ -1,6 +1,6 @@
 .. include:: ../disclaimer-zh_CN.rst
 
-:Original: :doc:`../../../admin-guide/security-bugs`
+:Original: :doc:`../../../process/security-bugs`
 
 :译者:
 
diff --git a/Documentation/translations/zh_CN/arch.rst b/Documentation/translations/zh_CN/arch.rst
deleted file mode 100644 (file)
index 690e173..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-处理器体系结构
-==============
-
-以下文档提供了具体架构实现的编程细节。
-
-.. toctree::
-   :maxdepth: 2
-
-   mips/index
-   arm64/index
-   riscv/index
-   openrisc/index
-   parisc/index
-   loongarch/index
-
-TODOList:
-
-* arm/index
-* ia64/index
-* m68k/index
-* nios2/index
-* powerpc/index
-* s390/index
-* sh/index
-* sparc/index
-* x86/index
-* xtensa/index
diff --git a/Documentation/translations/zh_CN/arch/index.rst b/Documentation/translations/zh_CN/arch/index.rst
new file mode 100644 (file)
index 0000000..908ea13
--- /dev/null
@@ -0,0 +1,29 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+处理器体系结构
+==============
+
+以下文档提供了具体架构实现的编程细节。
+
+.. toctree::
+   :maxdepth: 2
+
+   ../mips/index
+   ../arm64/index
+   ../riscv/index
+   openrisc/index
+   parisc/index
+   ../loongarch/index
+
+TODOList:
+
+* arm/index
+* ia64/index
+* m68k/index
+* nios2/index
+* powerpc/index
+* s390/index
+* sh/index
+* sparc/index
+* x86/index
+* xtensa/index
diff --git a/Documentation/translations/zh_CN/arch/openrisc/index.rst b/Documentation/translations/zh_CN/arch/openrisc/index.rst
new file mode 100644 (file)
index 0000000..da21f8a
--- /dev/null
@@ -0,0 +1,32 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../disclaimer-zh_CN.rst
+
+:Original: Documentation/arch/openrisc/index.rst
+
+:翻译:
+
+ 司延腾 Yanteng Si <siyanteng@loongson.cn>
+
+.. _cn_openrisc_index:
+
+=================
+OpenRISC 体系架构
+=================
+
+.. toctree::
+   :maxdepth: 2
+
+   openrisc_port
+   todo
+
+Todolist:
+    features
+
+
+.. only::  subproject and html
+
+   Indices
+   =======
+
+   * :ref:`genindex`
diff --git a/Documentation/translations/zh_CN/arch/openrisc/openrisc_port.rst b/Documentation/translations/zh_CN/arch/openrisc/openrisc_port.rst
new file mode 100644 (file)
index 0000000..cadc580
--- /dev/null
@@ -0,0 +1,127 @@
+.. include:: ../../disclaimer-zh_CN.rst
+
+:Original: Documentation/arch/openrisc/openrisc_port.rst
+
+:翻译:
+
+ 司延腾 Yanteng Si <siyanteng@loongson.cn>
+
+.. _cn_openrisc_port:
+
+==============
+OpenRISC Linux
+==============
+
+这是Linux对OpenRISC类微处理器的移植;具体来说,最早移植目标是32位
+OpenRISC 1000系列(或1k)。
+
+关于OpenRISC处理器和正在进行中的开发的信息:
+
+       =======         =============================
+       网站          https://openrisc.io
+       邮箱          openrisc@lists.librecores.org
+       =======         =============================
+
+---------------------------------------------------------------------
+
+OpenRISC工具链和Linux的构建指南
+===============================
+
+为了构建和运行Linux for OpenRISC,你至少需要一个基本的工具链,或许
+还需要架构模拟器。 这里概述了准备就位这些部分的步骤。
+
+1) 工具链
+
+工具链二进制文件可以从openrisc.io或我们的github发布页面获得。不同
+工具链的构建指南可以在openrisc.io或Stafford的工具链构建和发布脚本
+中找到。
+
+       ======      =================================================
+       二进制      https://github.com/openrisc/or1k-gcc/releases
+       工具链      https://openrisc.io/software
+       构建        https://github.com/stffrdhrn/or1k-toolchain-build
+       ======      =================================================
+
+2) 构建
+
+像往常一样构建Linux内核::
+
+       make ARCH=openrisc CROSS_COMPILE="or1k-linux-" defconfig
+       make ARCH=openrisc CROSS_COMPILE="or1k-linux-"
+
+3) 在FPGA上运行(可选)
+
+OpenRISC社区通常使用FuseSoC来管理构建和编程SoC到FPGA中。 下面是用
+OpenRISC SoC对De0 Nano开发板进行编程的一个例子。 在构建过程中,
+FPGA RTL是从FuseSoC IP核库中下载的代码,并使用FPGA供应商工具构建。
+二进制文件用openocd加载到电路板上。
+
+::
+
+       git clone https://github.com/olofk/fusesoc
+       cd fusesoc
+       sudo pip install -e .
+
+       fusesoc init
+       fusesoc build de0_nano
+       fusesoc pgm de0_nano
+
+       openocd -f interface/altera-usb-blaster.cfg \
+               -f board/or1k_generic.cfg
+
+       telnet localhost 4444
+       > init
+       > halt; load_image vmlinux ; reset
+
+4) 在模拟器上运行(可选)
+
+QEMU是一个处理器仿真器,我们推荐它来模拟OpenRISC平台。 请按照QEMU网
+站上的OpenRISC说明,让Linux在QEMU上运行。 你可以自己构建QEMU,但你的
+Linux发行版可能提供了支持OpenRISC的二进制包。
+
+       =============   ======================================================
+       qemu openrisc   https://wiki.qemu.org/Documentation/Platforms/OpenRISC
+       =============   ======================================================
+
+---------------------------------------------------------------------
+
+术语表
+======
+
+代码中使用了以下符号约定以将范围限制在几个特定处理器实现上:
+
+========= =======================
+openrisc: OpenRISC类型处理器
+or1k:     OpenRISC 1000系列处理器
+or1200:   OpenRISC 1200处理器
+========= =======================
+
+---------------------------------------------------------------------
+
+历史
+====
+
+2003-11-18     Matjaz Breskvar (phoenix@bsemi.com)
+   将linux初步移植到OpenRISC或32架构。
+       所有的核心功能都实现了,并且可以使用。
+
+2003-12-08     Matjaz Breskvar (phoenix@bsemi.com)
+   彻底改变TLB失误处理。
+   重写异常处理。
+   在默认的initrd中实现了sash-3.6的所有功能。
+   大幅改进的版本。
+
+2004-04-10     Matjaz Breskvar (phoenix@bsemi.com)
+   大量的bug修复。
+   支持以太网,http和telnet服务器功能。
+   可以运行许多标准的linux应用程序。
+
+2004-06-26     Matjaz Breskvar (phoenix@bsemi.com)
+   移植到2.6.x。
+
+2004-11-30     Matjaz Breskvar (phoenix@bsemi.com)
+   大量的bug修复和增强功能。
+   增加了opencores framebuffer驱动。
+
+2010-10-09    Jonas Bonn (jonas@southpole.se)
+   重大重写,使其与上游的Linux 2.6.36看齐。
diff --git a/Documentation/translations/zh_CN/arch/openrisc/todo.rst b/Documentation/translations/zh_CN/arch/openrisc/todo.rst
new file mode 100644 (file)
index 0000000..1f6f956
--- /dev/null
@@ -0,0 +1,23 @@
+.. include:: ../../disclaimer-zh_CN.rst
+
+:Original: Documentation/arch/openrisc/todo.rst
+
+:翻译:
+
+ 司延腾 Yanteng Si <siyanteng@loongson.cn>
+
+.. _cn_openrisc_todo.rst:
+
+========
+待办事项
+========
+
+OpenRISC Linux的移植已经完全投入使用,并且从 2.6.35 开始就一直在上游同步。
+然而,还有一些剩余的项目需要在未来几个月内完成。 下面是一个即将进行调查的已知
+不尽完美的项目列表,即我们的待办事项列表。
+
+-   实现其余的DMA API……dma_map_sg等。
+
+-   完成重命名清理工作……代码中提到了or32,这是架构的一个老名字。 我们
+    已经确定的名字是or1k,这个改变正在以缓慢积累的方式进行。 目前,or32相当
+    于or1k。
diff --git a/Documentation/translations/zh_CN/arch/parisc/debugging.rst b/Documentation/translations/zh_CN/arch/parisc/debugging.rst
new file mode 100644 (file)
index 0000000..c6b9de6
--- /dev/null
@@ -0,0 +1,45 @@
+.. include:: ../../disclaimer-zh_CN.rst
+
+:Original: Documentation/arch/parisc/debugging.rst
+
+:翻译:
+
+ 司延腾 Yanteng Si <siyanteng@loongson.cn>
+
+.. _cn_parisc_debugging:
+
+=================
+调试PA-RISC
+=================
+
+好吧,这里有一些关于调试linux/parisc的较底层部分的信息。
+
+
+1. 绝对地址
+=====================
+
+很多汇编代码目前运行在实模式下,这意味着会使用绝对地址,而不是像内核其他
+部分那样使用虚拟地址。要将绝对地址转换为虚拟地址,你可以在System.map中查
+找,添加__PAGE_OFFSET(目前是0x10000000)。
+
+
+2. HPMCs
+========
+
+当实模式的代码试图访问不存在的内存时,会出现HPMC(high priority machine
+check)而不是内核oops。若要调试HPMC,请尝试找到系统响应程序/请求程序地址。
+系统请求程序地址应该与(某)处理器的HPA(I/O范围内的高地址)相匹配;系统响应程
+序地址是实模式代码试图访问的地址。
+
+系统响应程序地址的典型值是大于__PAGE_OFFSET (0x10000000)的地址,这意味着
+在实模式试图访问它之前,虚拟地址没有被翻译成物理地址。
+
+
+3. 有趣的Q位
+============
+
+某些非常关键的代码必须清除PSW中的Q位。当Q位被清除时,CPU不会更新中断处理
+程序所读取的寄存器,以找出机器被中断的位置——所以如果你在清除Q位的指令和再
+次设置Q位的RFI之间遇到中断,你不知道它到底发生在哪里。如果你幸运的话,IAOQ
+会指向清除Q位的指令,如果你不幸运的话,它会指向任何地方。通常Q位的问题会
+表现为无法解释的系统挂起或物理内存越界。
diff --git a/Documentation/translations/zh_CN/arch/parisc/index.rst b/Documentation/translations/zh_CN/arch/parisc/index.rst
new file mode 100644 (file)
index 0000000..9f69283
--- /dev/null
@@ -0,0 +1,31 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../../disclaimer-zh_CN.rst
+
+:Original: Documentation/arch/parisc/index.rst
+
+:翻译:
+
+ 司延腾 Yanteng Si <siyanteng@loongson.cn>
+
+.. _cn_parisc_index:
+
+====================
+PA-RISC体系架构
+====================
+
+.. toctree::
+   :maxdepth: 2
+
+   debugging
+   registers
+
+Todolist:
+
+   features
+
+.. only::  subproject and html
+
+   Indices
+   =======
+
+   * :ref:`genindex`
diff --git a/Documentation/translations/zh_CN/arch/parisc/registers.rst b/Documentation/translations/zh_CN/arch/parisc/registers.rst
new file mode 100644 (file)
index 0000000..a55250a
--- /dev/null
@@ -0,0 +1,156 @@
+.. include:: ../../disclaimer-zh_CN.rst
+
+:Original: Documentation/arch/parisc/registers.rst
+
+:翻译:
+
+ 司延腾 Yanteng Si <siyanteng@loongson.cn>
+
+.. _cn_parisc_registers:
+
+=========================
+Linux/PA-RISC的寄存器用法
+=========================
+
+[ 用星号表示目前尚未实现的计划用途。 ]
+
+ABI约定的通用寄存器
+===================
+
+控制寄存器
+----------
+
+============================    =================================
+CR 0 (恢复计数器)               用于ptrace
+CR 1-CR 7(无定义)               未使用
+CR 8 (Protection ID)            每进程值*
+CR 9, 12, 13 (PIDS)             未使用
+CR10 (CCR)                      FPU延迟保存*
+CR11                            按照ABI的规定(SAR)
+CR14 (中断向量)                 初始化为 fault_vector
+CR15 (EIEM)                     所有位初始化为1*
+CR16 (间隔计时器)               读取周期数/写入开始时间间隔计时器
+CR17-CR22                       中断参数
+CR19                            中断指令寄存器
+CR20                            中断空间寄存器
+CR21                            中断偏移量寄存器
+CR22                            中断 PSW
+CR23 (EIRR)                     读取未决中断/写入清除位
+CR24 (TR 0)                     内核空间页目录指针
+CR25 (TR 1)                     用户空间页目录指针
+CR26 (TR 2)                     不使用
+CR27 (TR 3)                     线程描述符指针
+CR28 (TR 4)                     不使用
+CR29 (TR 5)                     不使用
+CR30 (TR 6)                     当前 / 0
+CR31 (TR 7)                     临时寄存器,在不同地方使用
+============================    =================================
+
+空间寄存器(内核模式)
+----------------------
+
+========                        ==============================
+SR0                             临时空间寄存器
+SR4-SR7                         设置为0
+SR1                             临时空间寄存器
+SR2                             内核不应该破坏它
+SR3                             用于用户空间访问(当前进程)
+========                        ==============================
+
+空间寄存器(用户模式)
+----------------------
+
+========                        ============================
+SR0                             临时空间寄存器
+SR1                             临时空间寄存器
+SR2                             保存Linux gateway page的空间
+SR3                             在内核中保存用户地址空间的值
+SR4-SR7                         定义了用户/内核的短地址空间
+========                        ============================
+
+
+处理器状态字
+------------
+
+======================          ================================================
+W (64位地址)                  0
+E (小尾端)                    0
+S (安全间隔计时器)            0
+T (产生分支陷阱)              0
+H (高特权级陷阱)              0
+L (低特权级陷阱)              0
+N (撤销下一条指令)            被C代码使用
+X (数据存储中断禁用)          0
+B (产生分支)                  被C代码使用
+C (代码地址转译)              1, 在执行实模式代码时为0
+V (除法步长校正)              被C代码使用
+M (HPMC 掩码)                 0, 在执行HPMC操作*时为1
+C/B (进/借 位)                被C代码使用
+O (有序引用)                  1*
+F (性能监视器)                0
+R (回收计数器陷阱)            0
+Q (收集中断状态)              1 (在rfi之前的代码中为0)
+P (保护标识符)                1*
+D (数据地址转译)              1, 在执行实模式代码时为0
+I (外部中断掩码)              由cli()/sti()宏使用。
+======================          ================================================
+
+“隐形”寄存器(影子寄存器)
+---------------------------
+
+=============                   ===================
+PSW W 默认值                    0
+PSW E 默认值                    0
+影子寄存器                      被中断处理代码使用
+TOC启用位                       1
+=============                   ===================
+
+----------------------------------------------------------
+
+PA-RISC架构定义了7个寄存器作为“影子寄存器”。这些寄存器在
+RETURN FROM INTERRUPTION AND RESTORE指令中使用,通过消
+除中断处理程序中对一般寄存器(GR)的保存和恢复的需要来减
+少状态保存和恢复时间。影子寄存器是GRs 1, 8, 9, 16, 17,
+24和25。
+
+-------------------------------------------------------------------------
+
+寄存器使用说明,最初由John Marvin提供,并由Randolph Chung提供一些补充说明。
+
+对于通用寄存器:
+
+r1,r2,r19-r26,r28,r29 & r31可以在不保存它们的情况下被使用。当然,如果你
+关心它们,在调用另一个程序之前,你也需要保存它们。上面的一些寄存器确实
+有特殊的含义,你应该注意一下:
+
+    r1:
+       addil指令是硬性规定将其结果放在r1中,所以如果你使用这条指令要
+       注意这点。
+
+    r2:
+       这就是返回指针。一般来说,你不想使用它,因为你需要这个指针来返
+       回给你的调用者。然而,它与这组寄存器组合在一起,因为调用者不能
+       依赖你返回时的值是相同的,也就是说,你可以将r2复制到另一个寄存
+       器,并在作废r2后通过该寄存器返回,这应该不会给调用程序带来问题。
+
+    r19-r22:
+       这些通常被认为是临时寄存器。
+       请注意,在64位中它们是arg7-arg4。
+
+    r23-r26:
+       这些是arg3-arg0,也就是说,如果你不再关心传入的值,你可以使用
+       它们。
+
+    r28,r29:
+       这俩是ret0和ret1。它们是你传入返回值的地方。r28是主返回值。当返回
+       小结构体时,r29也可以用来将数据传回给调用程序。
+
+    r30:
+       栈指针
+
+    r31:
+       ble指令将返回指针放在这里。
+
+
+    r3-r18,r27,r30需要被保存和恢复。r3-r18只是一般用途的寄存器。
+    r27是数据指针,用来使对全局变量的引用更容易。r30是栈指针。
index 7c3216845b71fe72cc6620552e539f9daaac601e..299704c0818dbcf7d30b15ee9d84947cdbb48b75 100644 (file)
@@ -120,7 +120,7 @@ TODOList:
 .. toctree::
    :maxdepth: 2
 
-   arch
+   arch/index
 
 其他文档
 --------
index c1fa35315d8b2238892d1ff7661873a532088388..b7a0544224ad1aa70213b37c7c68aece4f8dfb5f 100644 (file)
@@ -15,7 +15,8 @@ Hugetlbfs 预留
 概述
 ====
 
-Documentation/mm/hugetlbpage.rst 中描述的巨页通常是预先分配给应用程序使用的。如果VMA指
+Documentation/admin-guide/mm/hugetlbpage.rst
+中描述的巨页通常是预先分配给应用程序使用的 。如果VMA指
 示要使用巨页,这些巨页会在缺页异常时被实例化到任务的地址空间。如果在缺页异常
 时没有巨页存在,任务就会被发送一个SIGBUS,并经常不高兴地死去。在加入巨页支
 持后不久,人们决定,在mmap()时检测巨页的短缺情况会更好。这个想法是,如果
diff --git a/Documentation/translations/zh_CN/openrisc/index.rst b/Documentation/translations/zh_CN/openrisc/index.rst
deleted file mode 100644 (file)
index 9ad6cc6..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. include:: ../disclaimer-zh_CN.rst
-
-:Original: Documentation/openrisc/index.rst
-
-:翻译:
-
- 司延腾 Yanteng Si <siyanteng@loongson.cn>
-
-.. _cn_openrisc_index:
-
-=================
-OpenRISC 体系架构
-=================
-
-.. toctree::
-   :maxdepth: 2
-
-   openrisc_port
-   todo
-
-Todolist:
-    features
-
-
-.. only::  subproject and html
-
-   Indices
-   =======
-
-   * :ref:`genindex`
diff --git a/Documentation/translations/zh_CN/openrisc/openrisc_port.rst b/Documentation/translations/zh_CN/openrisc/openrisc_port.rst
deleted file mode 100644 (file)
index b8a6767..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-.. include:: ../disclaimer-zh_CN.rst
-
-:Original: Documentation/openrisc/openrisc_port.rst
-
-:翻译:
-
- 司延腾 Yanteng Si <siyanteng@loongson.cn>
-
-.. _cn_openrisc_port:
-
-==============
-OpenRISC Linux
-==============
-
-这是Linux对OpenRISC类微处理器的移植;具体来说,最早移植目标是32位
-OpenRISC 1000系列(或1k)。
-
-关于OpenRISC处理器和正在进行中的开发的信息:
-
-       =======         =============================
-       网站          https://openrisc.io
-       邮箱          openrisc@lists.librecores.org
-       =======         =============================
-
----------------------------------------------------------------------
-
-OpenRISC工具链和Linux的构建指南
-===============================
-
-为了构建和运行Linux for OpenRISC,你至少需要一个基本的工具链,或许
-还需要架构模拟器。 这里概述了准备就位这些部分的步骤。
-
-1) 工具链
-
-工具链二进制文件可以从openrisc.io或我们的github发布页面获得。不同
-工具链的构建指南可以在openrisc.io或Stafford的工具链构建和发布脚本
-中找到。
-
-       ======      =================================================
-       二进制      https://github.com/openrisc/or1k-gcc/releases
-       工具链      https://openrisc.io/software
-       构建        https://github.com/stffrdhrn/or1k-toolchain-build
-       ======      =================================================
-
-2) 构建
-
-像往常一样构建Linux内核::
-
-       make ARCH=openrisc CROSS_COMPILE="or1k-linux-" defconfig
-       make ARCH=openrisc CROSS_COMPILE="or1k-linux-"
-
-3) 在FPGA上运行(可选)
-
-OpenRISC社区通常使用FuseSoC来管理构建和编程SoC到FPGA中。 下面是用
-OpenRISC SoC对De0 Nano开发板进行编程的一个例子。 在构建过程中,
-FPGA RTL是从FuseSoC IP核库中下载的代码,并使用FPGA供应商工具构建。
-二进制文件用openocd加载到电路板上。
-
-::
-
-       git clone https://github.com/olofk/fusesoc
-       cd fusesoc
-       sudo pip install -e .
-
-       fusesoc init
-       fusesoc build de0_nano
-       fusesoc pgm de0_nano
-
-       openocd -f interface/altera-usb-blaster.cfg \
-               -f board/or1k_generic.cfg
-
-       telnet localhost 4444
-       > init
-       > halt; load_image vmlinux ; reset
-
-4) 在模拟器上运行(可选)
-
-QEMU是一个处理器仿真器,我们推荐它来模拟OpenRISC平台。 请按照QEMU网
-站上的OpenRISC说明,让Linux在QEMU上运行。 你可以自己构建QEMU,但你的
-Linux发行版可能提供了支持OpenRISC的二进制包。
-
-       =============   ======================================================
-       qemu openrisc   https://wiki.qemu.org/Documentation/Platforms/OpenRISC
-       =============   ======================================================
-
----------------------------------------------------------------------
-
-术语表
-======
-
-代码中使用了以下符号约定以将范围限制在几个特定处理器实现上:
-
-========= =======================
-openrisc: OpenRISC类型处理器
-or1k:     OpenRISC 1000系列处理器
-or1200:   OpenRISC 1200处理器
-========= =======================
-
----------------------------------------------------------------------
-
-历史
-====
-
-2003-11-18     Matjaz Breskvar (phoenix@bsemi.com)
-   将linux初步移植到OpenRISC或32架构。
-       所有的核心功能都实现了,并且可以使用。
-
-2003-12-08     Matjaz Breskvar (phoenix@bsemi.com)
-   彻底改变TLB失误处理。
-   重写异常处理。
-   在默认的initrd中实现了sash-3.6的所有功能。
-   大幅改进的版本。
-
-2004-04-10     Matjaz Breskvar (phoenix@bsemi.com)
-   大量的bug修复。
-   支持以太网,http和telnet服务器功能。
-   可以运行许多标准的linux应用程序。
-
-2004-06-26     Matjaz Breskvar (phoenix@bsemi.com)
-   移植到2.6.x。
-
-2004-11-30     Matjaz Breskvar (phoenix@bsemi.com)
-   大量的bug修复和增强功能。
-   增加了opencores framebuffer驱动。
-
-2010-10-09    Jonas Bonn (jonas@southpole.se)
-   重大重写,使其与上游的Linux 2.6.36看齐。
diff --git a/Documentation/translations/zh_CN/openrisc/todo.rst b/Documentation/translations/zh_CN/openrisc/todo.rst
deleted file mode 100644 (file)
index 63c3871..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-.. include:: ../disclaimer-zh_CN.rst
-
-:Original: Documentation/openrisc/todo.rst
-
-:翻译:
-
- 司延腾 Yanteng Si <siyanteng@loongson.cn>
-
-.. _cn_openrisc_todo.rst:
-
-========
-待办事项
-========
-
-OpenRISC Linux的移植已经完全投入使用,并且从 2.6.35 开始就一直在上游同步。
-然而,还有一些剩余的项目需要在未来几个月内完成。 下面是一个即将进行调查的已知
-不尽完美的项目列表,即我们的待办事项列表。
-
--   实现其余的DMA API……dma_map_sg等。
-
--   完成重命名清理工作……代码中提到了or32,这是架构的一个老名字。 我们
-    已经确定的名字是or1k,这个改变正在以缓慢积累的方式进行。 目前,or32相当
-    于or1k。
diff --git a/Documentation/translations/zh_CN/parisc/debugging.rst b/Documentation/translations/zh_CN/parisc/debugging.rst
deleted file mode 100644 (file)
index 68b73eb..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-.. include:: ../disclaimer-zh_CN.rst
-
-:Original: Documentation/parisc/debugging.rst
-
-:翻译:
-
- 司延腾 Yanteng Si <siyanteng@loongson.cn>
-
-.. _cn_parisc_debugging:
-
-=================
-调试PA-RISC
-=================
-
-好吧,这里有一些关于调试linux/parisc的较底层部分的信息。
-
-
-1. 绝对地址
-=====================
-
-很多汇编代码目前运行在实模式下,这意味着会使用绝对地址,而不是像内核其他
-部分那样使用虚拟地址。要将绝对地址转换为虚拟地址,你可以在System.map中查
-找,添加__PAGE_OFFSET(目前是0x10000000)。
-
-
-2. HPMCs
-========
-
-当实模式的代码试图访问不存在的内存时,会出现HPMC(high priority machine
-check)而不是内核oops。若要调试HPMC,请尝试找到系统响应程序/请求程序地址。
-系统请求程序地址应该与(某)处理器的HPA(I/O范围内的高地址)相匹配;系统响应程
-序地址是实模式代码试图访问的地址。
-
-系统响应程序地址的典型值是大于__PAGE_OFFSET (0x10000000)的地址,这意味着
-在实模式试图访问它之前,虚拟地址没有被翻译成物理地址。
-
-
-3. 有趣的Q位
-============
-
-某些非常关键的代码必须清除PSW中的Q位。当Q位被清除时,CPU不会更新中断处理
-程序所读取的寄存器,以找出机器被中断的位置——所以如果你在清除Q位的指令和再
-次设置Q位的RFI之间遇到中断,你不知道它到底发生在哪里。如果你幸运的话,IAOQ
-会指向清除Q位的指令,如果你不幸运的话,它会指向任何地方。通常Q位的问题会
-表现为无法解释的系统挂起或物理内存越界。
diff --git a/Documentation/translations/zh_CN/parisc/index.rst b/Documentation/translations/zh_CN/parisc/index.rst
deleted file mode 100644 (file)
index 0cc553f..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-.. include:: ../disclaimer-zh_CN.rst
-
-:Original: Documentation/parisc/index.rst
-
-:翻译:
-
- 司延腾 Yanteng Si <siyanteng@loongson.cn>
-
-.. _cn_parisc_index:
-
-====================
-PA-RISC体系架构
-====================
-
-.. toctree::
-   :maxdepth: 2
-
-   debugging
-   registers
-
-Todolist:
-
-   features
-
-.. only::  subproject and html
-
-   Indices
-   =======
-
-   * :ref:`genindex`
diff --git a/Documentation/translations/zh_CN/parisc/registers.rst b/Documentation/translations/zh_CN/parisc/registers.rst
deleted file mode 100644 (file)
index d2ab187..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-.. include:: ../disclaimer-zh_CN.rst
-
-:Original: Documentation/parisc/registers.rst
-
-:翻译:
-
- 司延腾 Yanteng Si <siyanteng@loongson.cn>
-
-.. _cn_parisc_registers:
-
-=========================
-Linux/PA-RISC的寄存器用法
-=========================
-
-[ 用星号表示目前尚未实现的计划用途。 ]
-
-ABI约定的通用寄存器
-===================
-
-控制寄存器
-----------
-
-============================    =================================
-CR 0 (恢复计数器)               用于ptrace
-CR 1-CR 7(无定义)               未使用
-CR 8 (Protection ID)            每进程值*
-CR 9, 12, 13 (PIDS)             未使用
-CR10 (CCR)                      FPU延迟保存*
-CR11                            按照ABI的规定(SAR)
-CR14 (中断向量)                 初始化为 fault_vector
-CR15 (EIEM)                     所有位初始化为1*
-CR16 (间隔计时器)               读取周期数/写入开始时间间隔计时器
-CR17-CR22                       中断参数
-CR19                            中断指令寄存器
-CR20                            中断空间寄存器
-CR21                            中断偏移量寄存器
-CR22                            中断 PSW
-CR23 (EIRR)                     读取未决中断/写入清除位
-CR24 (TR 0)                     内核空间页目录指针
-CR25 (TR 1)                     用户空间页目录指针
-CR26 (TR 2)                     不使用
-CR27 (TR 3)                     线程描述符指针
-CR28 (TR 4)                     不使用
-CR29 (TR 5)                     不使用
-CR30 (TR 6)                     当前 / 0
-CR31 (TR 7)                     临时寄存器,在不同地方使用
-============================    =================================
-
-空间寄存器(内核模式)
-----------------------
-
-========                        ==============================
-SR0                             临时空间寄存器
-SR4-SR7                         设置为0
-SR1                             临时空间寄存器
-SR2                             内核不应该破坏它
-SR3                             用于用户空间访问(当前进程)
-========                        ==============================
-
-空间寄存器(用户模式)
-----------------------
-
-========                        ============================
-SR0                             临时空间寄存器
-SR1                             临时空间寄存器
-SR2                             保存Linux gateway page的空间
-SR3                             在内核中保存用户地址空间的值
-SR4-SR7                         定义了用户/内核的短地址空间
-========                        ============================
-
-
-处理器状态字
-------------
-
-======================          ================================================
-W (64位地址)                  0
-E (小尾端)                    0
-S (安全间隔计时器)            0
-T (产生分支陷阱)              0
-H (高特权级陷阱)              0
-L (低特权级陷阱)              0
-N (撤销下一条指令)            被C代码使用
-X (数据存储中断禁用)          0
-B (产生分支)                  被C代码使用
-C (代码地址转译)              1, 在执行实模式代码时为0
-V (除法步长校正)              被C代码使用
-M (HPMC 掩码)                 0, 在执行HPMC操作*时为1
-C/B (进/借 位)                被C代码使用
-O (有序引用)                  1*
-F (性能监视器)                0
-R (回收计数器陷阱)            0
-Q (收集中断状态)              1 (在rfi之前的代码中为0)
-P (保护标识符)                1*
-D (数据地址转译)              1, 在执行实模式代码时为0
-I (外部中断掩码)              由cli()/sti()宏使用。
-======================          ================================================
-
-“隐形”寄存器(影子寄存器)
----------------------------
-
-=============                   ===================
-PSW W 默认值                    0
-PSW E 默认值                    0
-影子寄存器                      被中断处理代码使用
-TOC启用位                       1
-=============                   ===================
-
-----------------------------------------------------------
-
-PA-RISC架构定义了7个寄存器作为“影子寄存器”。这些寄存器在
-RETURN FROM INTERRUPTION AND RESTORE指令中使用,通过消
-除中断处理程序中对一般寄存器(GR)的保存和恢复的需要来减
-少状态保存和恢复时间。影子寄存器是GRs 1, 8, 9, 16, 17,
-24和25。
-
--------------------------------------------------------------------------
-
-寄存器使用说明,最初由John Marvin提供,并由Randolph Chung提供一些补充说明。
-
-对于通用寄存器:
-
-r1,r2,r19-r26,r28,r29 & r31可以在不保存它们的情况下被使用。当然,如果你
-关心它们,在调用另一个程序之前,你也需要保存它们。上面的一些寄存器确实
-有特殊的含义,你应该注意一下:
-
-    r1:
-       addil指令是硬性规定将其结果放在r1中,所以如果你使用这条指令要
-       注意这点。
-
-    r2:
-       这就是返回指针。一般来说,你不想使用它,因为你需要这个指针来返
-       回给你的调用者。然而,它与这组寄存器组合在一起,因为调用者不能
-       依赖你返回时的值是相同的,也就是说,你可以将r2复制到另一个寄存
-       器,并在作废r2后通过该寄存器返回,这应该不会给调用程序带来问题。
-
-    r19-r22:
-       这些通常被认为是临时寄存器。
-       请注意,在64位中它们是arg7-arg4。
-
-    r23-r26:
-       这些是arg3-arg0,也就是说,如果你不再关心传入的值,你可以使用
-       它们。
-
-    r28,r29:
-       这俩是ret0和ret1。它们是你传入返回值的地方。r28是主返回值。当返回
-       小结构体时,r29也可以用来将数据传回给调用程序。
-
-    r30:
-       栈指针
-
-    r31:
-       ble指令将返回指针放在这里。
-
-
-    r3-r18,r27,r30需要被保存和恢复。r3-r18只是一般用途的寄存器。
-    r27是数据指针,用来使对全局变量的引用更容易。r30是栈指针。
index 10254751df6a25457d5526995371a1c58213c7bd..cc47be356dd323956f6d6d24a62fad1ac3052d06 100644 (file)
@@ -125,7 +125,7 @@ Linux内核代码中包含有大量的文档。这些文档对于学习如何与
     这篇文档对于理解Linux的开发哲学至关重要。对于将开发平台从其他操作系
     统转移到Linux的人来说也很重要。
 
-  :ref:`Documentation/admin-guide/security-bugs.rst <securitybugs>`
+  :ref:`Documentation/process/security-bugs.rst <securitybugs>`
     如果你认为自己发现了Linux内核的安全性问题,请根据这篇文档中的步骤来
     提醒其他内核开发者并帮助解决这个问题。
 
index e07ffdd391d32d97b0dda5c37b32da13b0d682c7..8cba135dcd1a6b4aa718f8cc215d8a84ed33f919 100644 (file)
@@ -231,7 +231,7 @@ CFS调度类基于实体负载跟踪机制(Per-Entity Load Tracking, PELT)
 当前,Linux无法凭自身算出CPU算力,因此必须要有把这个信息传递给Linux的方式。每个架构必须为此
 定义arch_scale_cpu_capacity()函数。
 
-arm和arm64架构直接把这个信息映射到arch_topology驱动的CPU scaling数据中(译注:参考
+arm、arm64和RISC-V架构直接把这个信息映射到arch_topology驱动的CPU scaling数据中(译注:参考
 arch_topology.h的percpu变量cpu_scale),它是从capacity-dmips-mhz CPU binding中衍生计算
 出来的。参见Documentation/devicetree/bindings/cpu/cpu-capacity.txt。
 
index eed260ef0c373a450f49b538d8e90793c35bc803..15f8e900507180c9a8dc2c1f012636ec8f6649aa 100644 (file)
@@ -2,7 +2,7 @@
 
 .. include:: ../disclaimer-zh_TW.rst
 
-:Original: :doc:`../../../admin-guide/security-bugs`
+:Original: :doc:`../../../process/security-bugs`
 
 :譯者:
 
index 8fb8edcaee66525d4cd140a6259d083ad2a65279..ea2f468d3e587df699abf8ca0abf322cc05c09a4 100644 (file)
@@ -128,7 +128,7 @@ Linux內核代碼中包含有大量的文檔。這些文檔對於學習如何與
     這篇文檔對於理解Linux的開發哲學至關重要。對於將開發平台從其他操作系
     統轉移到Linux的人來說也很重要。
 
-  :ref:`Documentation/admin-guide/security-bugs.rst <securitybugs>`
+  :ref:`Documentation/process/security-bugs.rst <securitybugs>`
     如果你認爲自己發現了Linux內核的安全性問題,請根據這篇文檔中的步驟來
     提醒其他內核開發者並幫助解決這個問題。
 
diff --git a/Documentation/usb/gadget_uvc.rst b/Documentation/usb/gadget_uvc.rst
new file mode 100644 (file)
index 0000000..6d22fac
--- /dev/null
@@ -0,0 +1,352 @@
+=======================
+Linux UVC Gadget Driver
+=======================
+
+Overview
+--------
+The UVC Gadget driver is a driver for hardware on the *device* side of a USB
+connection. It is intended to run on a Linux system that has USB device-side
+hardware such as boards with an OTG port.
+
+On the device system, once the driver is bound it appears as a V4L2 device with
+the output capability.
+
+On the host side (once connected via USB cable), a device running the UVC Gadget
+driver *and controlled by an appropriate userspace program* should appear as a UVC
+specification compliant camera, and function appropriately with any program
+designed to handle them. The userspace program running on the device system can
+queue image buffers from a variety of sources to be transmitted via the USB
+connection. Typically this would mean forwarding the buffers from a camera sensor
+peripheral, but the source of the buffer is entirely dependent on the userspace
+companion program.
+
+Configuring the device kernel
+-----------------------------
+The Kconfig options USB_CONFIGFS, USB_LIBCOMPOSITE, USB_CONFIGFS_F_UVC and
+USB_F_UVC must be selected to enable support for the UVC gadget.
+
+Configuring the gadget through configfs
+---------------------------------------
+The UVC Gadget expects to be configured through configfs using the UVC function.
+This allows a significant degree of flexibility, as many of a UVC device's
+settings can be controlled this way.
+
+Not all of the available attributes are described here. For a complete enumeration
+see Documentation/ABI/testing/configfs-usb-gadget-uvc
+
+Assumptions
+~~~~~~~~~~~
+This section assumes that you have mounted configfs at `/sys/kernel/config` and
+created a gadget as `/sys/kernel/config/usb_gadget/g1`.
+
+The UVC Function
+~~~~~~~~~~~~~~~~
+
+The first step is to create the UVC function:
+
+.. code-block:: bash
+
+       # These variables will be assumed throughout the rest of the document
+       CONFIGFS="/sys/kernel/config"
+       GADGET="$CONFIGFS/usb_gadget/g1"
+       FUNCTION="$GADGET/functions/uvc.0"
+
+       mkdir -p $FUNCTION
+
+Formats and Frames
+~~~~~~~~~~~~~~~~~~
+
+You must configure the gadget by telling it which formats you support, as well
+as the frame sizes and frame intervals that are supported for each format. In
+the current implementation there is no way for the gadget to refuse to set a
+format that the host instructs it to set, so it is important that this step is
+completed *accurately* to ensure that the host never asks for a format that
+can't be provided.
+
+Formats are created under the streaming/uncompressed and streaming/mjpeg configfs
+groups, with the framesizes created under the formats in the following
+structure:
+
+::
+
+       uvc.0 +
+             |
+             + streaming +
+                         |
+                         + mjpeg +
+                         |       |
+                         |       + mjpeg +
+                         |            |
+                         |            + 720p
+                         |            |
+                         |            + 1080p
+                         |
+                         + uncompressed +
+                                        |
+                                        + yuyv +
+                                               |
+                                               + 720p
+                                               |
+                                               + 1080p
+
+Each frame can then be configured with a width and height, plus the maximum
+buffer size required to store a single frame, and finally with the supported
+frame intervals for that format and framesize. Width and height are enumerated in
+units of pixels, frame interval in units of 100ns. To create the structure
+above with 2, 15 and 100 fps frameintervals for each framesize for example you
+might do:
+
+.. code-block:: bash
+
+       create_frame() {
+               # Example usage:
+               # create_frame <width> <height> <group> <format name>
+
+               WIDTH=$1
+               HEIGHT=$2
+               FORMAT=$3
+               NAME=$4
+
+               wdir=$FUNCTION/streaming/$FORMAT/$NAME/${HEIGHT}p
+
+               mkdir -p $wdir
+               echo $WIDTH > $wdir/wWidth
+               echo $HEIGHT > $wdir/wHeight
+               echo $(( $WIDTH * $HEIGHT * 2 )) > $wdir/dwMaxVideoFrameBufferSize
+               cat <<EOF > $wdir/dwFrameInterval
+       666666
+       100000
+       5000000
+       EOF
+       }
+
+       create_frame 1280 720 mjpeg mjpeg
+       create_frame 1920 1080 mjpeg mjpeg
+       create_frame 1280 720 uncompressed yuyv
+       create_frame 1920 1080 uncompressed yuyv
+
+The only uncompressed format currently supported is YUYV, which is detailed at
+Documentation/userspace-api/media/v4l/pixfmt-packed.yuv.rst.
+
+Color Matching Descriptors
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+It's possible to specify some colometry information for each format you create.
+This step is optional, and default information will be included if this step is
+skipped; those default values follow those defined in the Color Matching Descriptor
+section of the UVC specification.
+
+To create a Color Matching Descriptor, create a configfs item and set its three
+attributes to your desired settings and then link to it from the format you wish
+it to be associated with:
+
+.. code-block:: bash
+
+       # Create a new Color Matching Descriptor
+
+       mkdir $FUNCTION/streaming/color_matching/yuyv
+       pushd $FUNCTION/streaming/color_matching/yuyv
+
+       echo 1 > bColorPrimaries
+       echo 1 > bTransferCharacteristics
+       echo 4 > bMatrixCoefficients
+
+       popd
+
+       # Create a symlink to the Color Matching Descriptor from the format's config item
+       ln -s $FUNCTION/streaming/color_matching/yuyv $FUNCTION/streaming/uncompressed/yuyv
+
+For details about the valid values, consult the UVC specification. Note that a
+default color matching descriptor exists and is used by any format which does
+not have a link to a different Color Matching Descriptor. It's possible to
+change the attribute settings for the default descriptor, so bear in mind that if
+you do that you are altering the defaults for any format that does not link to
+a different one.
+
+
+Header linking
+~~~~~~~~~~~~~~
+
+The UVC specification requires that Format and Frame descriptors be preceded by
+Headers detailing things such as the number and cumulative size of the different
+Format descriptors that follow. This and similar operations are acheived in
+configfs by linking between the configfs item representing the header and the
+config items representing those other descriptors, in this manner:
+
+.. code-block:: bash
+
+       mkdir $FUNCTION/streaming/header/h
+
+       # This section links the format descriptors and their associated frames
+       # to the header
+       cd $FUNCTION/streaming/header/h
+       ln -s ../../uncompressed/yuyv
+       ln -s ../../mjpeg/mjpeg
+
+       # This section ensures that the header will be transmitted for each
+       # speed's set of descriptors. If support for a particular speed is not
+       # needed then it can be skipped here.
+       cd ../../class/fs
+       ln -s ../../header/h
+       cd ../../class/hs
+       ln -s ../../header/h
+       cd ../../class/ss
+       ln -s ../../header/h
+       cd ../../../control
+       mkdir header/h
+       ln -s header/h class/fs
+       ln -s header/h class/ss
+
+
+Extension Unit Support
+~~~~~~~~~~~~~~~~~~~~~~
+
+A UVC Extension Unit (XU) basically provides a distinct unit to which control set
+and get requests can be addressed. The meaning of those control requests is
+entirely implementation dependent, but may be used to control settings outside
+of the UVC specification (for example enabling or disabling video effects). An
+XU can be inserted into the UVC unit chain or left free-hanging.
+
+Configuring an extension unit involves creating an entry in the appropriate
+directory and setting its attributes appropriately, like so:
+
+.. code-block:: bash
+
+       mkdir $FUNCTION/control/extensions/xu.0
+       pushd $FUNCTION/control/extensions/xu.0
+
+       # Set the bUnitID of the Processing Unit as the source for this
+       # Extension Unit
+       echo 2 > baSourceID
+
+       # Set this XU as the source of the default output terminal. This inserts
+       # the XU into the UVC chain between the PU and OT such that the final
+       # chain is IT > PU > XU.0 > OT
+       cat bUnitID > ../../terminal/output/default/baSourceID
+
+       # Flag some controls as being available for use. The bmControl field is
+       # a bitmap with each bit denoting the availability of a particular
+       # control. For example to flag the 0th, 2nd and 3rd controls available:
+       echo 0x0d > bmControls
+
+       # Set the GUID; this is a vendor-specific code identifying the XU.
+       echo -e -n "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" > guidExtensionCode
+
+       popd
+
+The bmControls attribute and the baSourceID attribute are multi-value attributes.
+This means that you may write multiple newline separated values to them. For
+example to flag the 1st, 2nd, 9th and 10th controls as being available you would
+need to write two values to bmControls, like so:
+
+.. code-block:: bash
+
+       cat << EOF > bmControls
+       0x03
+       0x03
+       EOF
+
+The multi-value nature of the baSourceID attribute belies the fact that XUs can
+be multiple-input, though note that this currently has no significant effect.
+
+The bControlSize attribute reflects the size of the bmControls attribute, and
+similarly bNrInPins reflects the size of the baSourceID attributes. Both
+attributes are automatically increased / decreased as you set bmControls and
+baSourceID. It is also possible to manually increase or decrease bControlSize
+which has the effect of truncating entries to the new size, or padding entries
+out with 0x00, for example:
+
+::
+
+       $ cat bmControls
+       0x03
+       0x05
+
+       $ cat bControlSize
+       2
+
+       $ echo 1 > bControlSize
+       $ cat bmControls
+       0x03
+
+       $ echo 2 > bControlSize
+       $ cat bmControls
+       0x03
+       0x00
+
+bNrInPins and baSourceID function in the same way.
+
+Custom Strings Support
+~~~~~~~~~~~~~~~~~~~~~~
+
+String descriptors that provide a textual description for various parts of a
+USB device can be defined in the usual place within USB configfs, and may then
+be linked to from the UVC function root or from Extension Unit directories to
+assign those strings as descriptors:
+
+.. code-block:: bash
+
+       # Create a string descriptor in us-EN and link to it from the function
+       # root. The name of the link is significant here, as it declares this
+       # descriptor to be intended for the Interface Association Descriptor.
+       # Other significant link names at function root are vs0_desc and vs1_desc
+       # For the VideoStreaming Interface 0/1 Descriptors.
+
+       mkdir -p $GADGET/strings/0x409/iad_desc
+       echo -n "Interface Associaton Descriptor" > $GADGET/strings/0x409/iad_desc/s
+       ln -s $GADGET/strings/0x409/iad_desc $FUNCTION/iad_desc
+
+       # Because the link to a String Descriptor from an Extension Unit clearly
+       # associates the two, the name of this link is not significant and may
+       # be set freely.
+
+       mkdir -p $GADGET/strings/0x409/xu.0
+       echo -n "A Very Useful Extension Unit" > $GADGET/strings/0x409/xu.0/s
+       ln -s $GADGET/strings/0x409/xu.0 $FUNCTION/control/extensions/xu.0
+
+The interrupt endpoint
+~~~~~~~~~~~~~~~~~~~~~~
+
+The VideoControl interface has an optional interrupt endpoint which is by default
+disabled. This is intended to support delayed response control set requests for
+UVC (which should respond through the interrupt endpoint rather than tying up
+endpoint 0). At present support for sending data through this endpoint is missing
+and so it is left disabled to avoid confusion. If you wish to enable it you can
+do so through the configfs attribute:
+
+.. code-block:: bash
+
+       echo 1 > $FUNCTION/control/enable_interrupt_ep
+
+Bandwidth configuration
+~~~~~~~~~~~~~~~~~~~~~~~
+
+There are three attributes which control the bandwidth of the USB connection.
+These live in the function root and can be set within limits:
+
+.. code-block:: bash
+
+       # streaming_interval sets bInterval. Values range from 1..255
+       echo 1 > $FUNCTION/streaming_interval
+
+       # streaming_maxpacket sets wMaxPacketSize. Valid values are 1024/2048/3072
+       echo 3072 > $FUNCTION/streaming_maxpacket
+
+       # streaming_maxburst sets bMaxBurst. Valid values are 1..15
+       echo 1 > $FUNCTION/streaming_maxburst
+
+
+The values passed here will be clamped to valid values according to the UVC
+specification (which depend on the speed of the USB connection). To understand
+how the settings influence bandwidth you should consult the UVC specifications,
+but a rule of thumb is that increasing the streaming_maxpacket setting will
+improve bandwidth (and thus the maximum possible framerate), whilst the same is
+true for streaming_maxburst provided the USB connection is running at SuperSpeed.
+Increasing streaming_interval will reduce bandwidth and framerate.
+
+The userspace application
+-------------------------
+By itself, the UVC Gadget driver cannot do anything particularly interesting. It
+must be paired with a userspace program that responds to UVC control requests and
+fills buffers to be queued to the V4L2 device that the driver creates. How those
+things are achieved is implementation dependent and beyond the scope of this
+document, but a reference application can be found at https://gitlab.freedesktop.org/camera/uvc-gadget
index b656c9be23ed230af5b499ef68689a9bfdfa5094..27955dad95e12403fbae8dda7c64dd9771fec3bd 100644 (file)
@@ -16,6 +16,7 @@ USB support
     gadget_multi
     gadget_printer
     gadget_serial
+    gadget_uvc
     gadget-testing
     iuu_phoenix
     mass-storage
diff --git a/Documentation/userspace-api/ELF.rst b/Documentation/userspace-api/ELF.rst
new file mode 100644 (file)
index 0000000..ac8aeac
--- /dev/null
@@ -0,0 +1,34 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=================================
+Linux-specific ELF idiosyncrasies
+=================================
+
+Definitions
+===========
+
+"First" program header is the one with the smallest offset in the file:
+e_phoff.
+
+"Last" program header is the one with the biggest offset in the file:
+e_phoff + (e_phnum - 1) * sizeof(Elf_Phdr).
+
+PT_INTERP
+=========
+
+First PT_INTERP program header is used to locate the filename of ELF
+interpreter. Other PT_INTERP headers are ignored (since Linux 2.4.11).
+
+PT_GNU_STACK
+============
+
+Last PT_GNU_STACK program header defines userspace stack executability
+(since Linux 2.6.6). Other PT_GNU_STACK headers are ignored.
+
+PT_GNU_PROPERTY
+===============
+
+ELF interpreter's last PT_GNU_PROPERTY program header is used (since
+Linux 5.8). If interpreter doesn't have one, then the last PT_GNU_PROPERTY
+program header of an executable is used. Other PT_GNU_PROPERTY headers
+are ignored.
index f16337bdb8520fac879bc4aee481bf7cfe8b0ce4..72a65db0c498898749d6e182e2e277ebd7647291 100644 (file)
@@ -23,6 +23,7 @@ place where this information is gathered.
    spec_ctrl
    accelerators/ocxl
    ebpf/index
+   ELF
    ioctl/index
    iommu
    iommufd
index d330aeb4d3ebf74af6e931d839c70fabf8e832d2..d9d7b7621d8cef4fb597122c30e7a4f856151fb9 100644 (file)
@@ -778,7 +778,7 @@ number of bits for each component.
     \tiny
     \setlength{\tabcolsep}{2pt}
 
-.. tabularcolumns:: |p{2.8cm}|p{2.0cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
+.. tabularcolumns:: |p{3.2cm}|p{0.8cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
 
 
 .. flat-table:: RGB Formats 10 Bits Per Color Component
@@ -868,7 +868,6 @@ number of bits for each component.
       - r\ :sub:`4`
       - r\ :sub:`3`
       - r\ :sub:`2`
-      -
     * .. _V4L2-PIX-FMT-RGBA1010102:
 
       - ``V4L2_PIX_FMT_RGBA1010102``
@@ -909,7 +908,6 @@ number of bits for each component.
       - r\ :sub:`4`
       - r\ :sub:`3`
       - r\ :sub:`2`
-      -
     * .. _V4L2-PIX-FMT-ARGB2101010:
 
       - ``V4L2_PIX_FMT_ARGB2101010``
@@ -950,7 +948,6 @@ number of bits for each component.
       - r\ :sub:`6`
       - r\ :sub:`5`
       - r\ :sub:`4`
-      -
 
 .. raw:: latex
 
index 6ffe8137cd9021605bb83f7a05f60f6e4311c537..a22442ba1d30bb4bfeae33bf85a71458d235f7ba 100644 (file)
@@ -24,6 +24,10 @@ YAML specifications can be found under ``Documentation/netlink/specs/``
 This document describes details of the schema.
 See :doc:`intro-specs` for a practical starting guide.
 
+All specs must be licensed under
+``((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)``
+to allow for easy adoption in user space code.
+
 Compatibility levels
 ====================
 
@@ -197,9 +201,15 @@ value
 Numerical attribute ID, used in serialized Netlink messages.
 The ``value`` property can be skipped, in which case the attribute ID
 will be the value of the previous attribute plus one (recursively)
-and ``0`` for the first attribute in the attribute set.
+and ``1`` for the first attribute in the attribute set.
+
+Attributes (and operations) use ``1`` as the default value for the first
+entry (unlike enums in definitions which start from ``0``) because
+entry ``0`` is almost always reserved as undefined. Spec can explicitly
+set value to ``0`` if needed.
 
-Note that the ``value`` of an attribute is defined only in its main set.
+Note that the ``value`` of an attribute is defined only in its main set
+(not in subsets).
 
 enum
 ~~~~
index 62de0768d6aa5991a1054813eedc2e37b6e6ad1e..841e9d1987bde6f5132306cbe54722634b296433 100644 (file)
@@ -7456,7 +7456,7 @@ system fingerprint.  To prevent userspace from circumventing such restrictions
 by running an enclave in a VM, KVM prevents access to privileged attributes by
 default.
 
-See Documentation/x86/sgx.rst for more details.
+See Documentation/arch/x86/sgx.rst for more details.
 
 7.26 KVM_CAP_PPC_RPT_INVALIDATE
 -------------------------------
@@ -8296,11 +8296,11 @@ ENOSYS for the others.
 8.35 KVM_CAP_PMU_CAPABILITY
 ---------------------------
 
-:Capability KVM_CAP_PMU_CAPABILITY
+:Capability: KVM_CAP_PMU_CAPABILITY
 :Architectures: x86
 :Type: vm
 :Parameters: arg[0] is bitmask of PMU virtualization capabilities.
-:Returns 0 on success, -EINVAL when arg[0] contains invalid bits
+:Returns: 0 on success, -EINVAL when arg[0] contains invalid bits
 
 This capability alters PMU virtualization in KVM.
 
diff --git a/Documentation/x86/amd-memory-encryption.rst b/Documentation/x86/amd-memory-encryption.rst
deleted file mode 100644 (file)
index 934310c..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=====================
-AMD Memory Encryption
-=====================
-
-Secure Memory Encryption (SME) and Secure Encrypted Virtualization (SEV) are
-features found on AMD processors.
-
-SME provides the ability to mark individual pages of memory as encrypted using
-the standard x86 page tables.  A page that is marked encrypted will be
-automatically decrypted when read from DRAM and encrypted when written to
-DRAM.  SME can therefore be used to protect the contents of DRAM from physical
-attacks on the system.
-
-SEV enables running encrypted virtual machines (VMs) in which the code and data
-of the guest VM are secured so that a decrypted version is available only
-within the VM itself. SEV guest VMs have the concept of private and shared
-memory. Private memory is encrypted with the guest-specific key, while shared
-memory may be encrypted with hypervisor key. When SME is enabled, the hypervisor
-key is the same key which is used in SME.
-
-A page is encrypted when a page table entry has the encryption bit set (see
-below on how to determine its position).  The encryption bit can also be
-specified in the cr3 register, allowing the PGD table to be encrypted. Each
-successive level of page tables can also be encrypted by setting the encryption
-bit in the page table entry that points to the next table. This allows the full
-page table hierarchy to be encrypted. Note, this means that just because the
-encryption bit is set in cr3, doesn't imply the full hierarchy is encrypted.
-Each page table entry in the hierarchy needs to have the encryption bit set to
-achieve that. So, theoretically, you could have the encryption bit set in cr3
-so that the PGD is encrypted, but not set the encryption bit in the PGD entry
-for a PUD which results in the PUD pointed to by that entry to not be
-encrypted.
-
-When SEV is enabled, instruction pages and guest page tables are always treated
-as private. All the DMA operations inside the guest must be performed on shared
-memory. Since the memory encryption bit is controlled by the guest OS when it
-is operating in 64-bit or 32-bit PAE mode, in all other modes the SEV hardware
-forces the memory encryption bit to 1.
-
-Support for SME and SEV can be determined through the CPUID instruction. The
-CPUID function 0x8000001f reports information related to SME::
-
-       0x8000001f[eax]:
-               Bit[0] indicates support for SME
-               Bit[1] indicates support for SEV
-       0x8000001f[ebx]:
-               Bits[5:0]  pagetable bit number used to activate memory
-                          encryption
-               Bits[11:6] reduction in physical address space, in bits, when
-                          memory encryption is enabled (this only affects
-                          system physical addresses, not guest physical
-                          addresses)
-
-If support for SME is present, MSR 0xc00100010 (MSR_AMD64_SYSCFG) can be used to
-determine if SME is enabled and/or to enable memory encryption::
-
-       0xc0010010:
-               Bit[23]   0 = memory encryption features are disabled
-                         1 = memory encryption features are enabled
-
-If SEV is supported, MSR 0xc0010131 (MSR_AMD64_SEV) can be used to determine if
-SEV is active::
-
-       0xc0010131:
-               Bit[0]    0 = memory encryption is not active
-                         1 = memory encryption is active
-
-Linux relies on BIOS to set this bit if BIOS has determined that the reduction
-in the physical address space as a result of enabling memory encryption (see
-CPUID information above) will not conflict with the address space resource
-requirements for the system.  If this bit is not set upon Linux startup then
-Linux itself will not set it and memory encryption will not be possible.
-
-The state of SME in the Linux kernel can be documented as follows:
-
-       - Supported:
-         The CPU supports SME (determined through CPUID instruction).
-
-       - Enabled:
-         Supported and bit 23 of MSR_AMD64_SYSCFG is set.
-
-       - Active:
-         Supported, Enabled and the Linux kernel is actively applying
-         the encryption bit to page table entries (the SME mask in the
-         kernel is non-zero).
-
-SME can also be enabled and activated in the BIOS. If SME is enabled and
-activated in the BIOS, then all memory accesses will be encrypted and it will
-not be necessary to activate the Linux memory encryption support.  If the BIOS
-merely enables SME (sets bit 23 of the MSR_AMD64_SYSCFG), then Linux can activate
-memory encryption by default (CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT=y) or
-by supplying mem_encrypt=on on the kernel command line.  However, if BIOS does
-not enable SME, then Linux will not be able to activate memory encryption, even
-if configured to do so by default or the mem_encrypt=on command line parameter
-is specified.
-
-Secure Nested Paging (SNP)
-==========================
-
-SEV-SNP introduces new features (SEV_FEATURES[1:63]) which can be enabled
-by the hypervisor for security enhancements. Some of these features need
-guest side implementation to function correctly. The below table lists the
-expected guest behavior with various possible scenarios of guest/hypervisor
-SNP feature support.
-
-+-----------------+---------------+---------------+------------------+
-| Feature Enabled | Guest needs   | Guest has     | Guest boot       |
-| by the HV       | implementation| implementation| behaviour        |
-+=================+===============+===============+==================+
-|      No         |      No       |      No       |     Boot         |
-|                 |               |               |                  |
-+-----------------+---------------+---------------+------------------+
-|      No         |      Yes      |      No       |     Boot         |
-|                 |               |               |                  |
-+-----------------+---------------+---------------+------------------+
-|      No         |      Yes      |      Yes      |     Boot         |
-|                 |               |               |                  |
-+-----------------+---------------+---------------+------------------+
-|      Yes        |      No       |      No       | Boot with        |
-|                 |               |               | feature enabled  |
-+-----------------+---------------+---------------+------------------+
-|      Yes        |      Yes      |      No       | Graceful boot    |
-|                 |               |               | failure          |
-+-----------------+---------------+---------------+------------------+
-|      Yes        |      Yes      |      Yes      | Boot with        |
-|                 |               |               | feature enabled  |
-+-----------------+---------------+---------------+------------------+
-
-More details in AMD64 APM[1] Vol 2: 15.34.10 SEV_STATUS MSR
-
-[1] https://www.amd.com/system/files/TechDocs/40332.pdf
diff --git a/Documentation/x86/amd_hsmp.rst b/Documentation/x86/amd_hsmp.rst
deleted file mode 100644 (file)
index 440e4b6..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-============================================
-AMD HSMP interface
-============================================
-
-Newer Fam19h EPYC server line of processors from AMD support system
-management functionality via HSMP (Host System Management Port).
-
-The Host System Management Port (HSMP) is an interface to provide
-OS-level software with access to system management functions via a
-set of mailbox registers.
-
-More details on the interface can be found in chapter
-"7 Host System Management Port (HSMP)" of the family/model PPR
-Eg: https://www.amd.com/system/files/TechDocs/55898_B1_pub_0.50.zip
-
-HSMP interface is supported on EPYC server CPU models only.
-
-
-HSMP device
-============================================
-
-amd_hsmp driver under the drivers/platforms/x86/ creates miscdevice
-/dev/hsmp to let user space programs run hsmp mailbox commands.
-
-$ ls -al /dev/hsmp
-crw-r--r-- 1 root root 10, 123 Jan 21 21:41 /dev/hsmp
-
-Characteristics of the dev node:
- * Write mode is used for running set/configure commands
- * Read mode is used for running get/status monitor commands
-
-Access restrictions:
- * Only root user is allowed to open the file in write mode.
- * The file can be opened in read mode by all the users.
-
-In-kernel integration:
- * Other subsystems in the kernel can use the exported transport
-   function hsmp_send_message().
- * Locking across callers is taken care by the driver.
-
-
-An example
-==========
-
-To access hsmp device from a C program.
-First, you need to include the headers::
-
-  #include <linux/amd_hsmp.h>
-
-Which defines the supported messages/message IDs.
-
-Next thing, open the device file, as follows::
-
-  int file;
-
-  file = open("/dev/hsmp", O_RDWR);
-  if (file < 0) {
-    /* ERROR HANDLING; you can check errno to see what went wrong */
-    exit(1);
-  }
-
-The following IOCTL is defined:
-
-``ioctl(file, HSMP_IOCTL_CMD, struct hsmp_message *msg)``
-  The argument is a pointer to a::
-
-    struct hsmp_message {
-       __u32   msg_id;                         /* Message ID */
-       __u16   num_args;                       /* Number of input argument words in message */
-       __u16   response_sz;                    /* Number of expected output/response words */
-       __u32   args[HSMP_MAX_MSG_LEN];         /* argument/response buffer */
-       __u16   sock_ind;                       /* socket number */
-    };
-
-The ioctl would return a non-zero on failure; you can read errno to see
-what happened. The transaction returns 0 on success.
-
-More details on the interface and message definitions can be found in chapter
-"7 Host System Management Port (HSMP)" of the respective family/model PPR
-eg: https://www.amd.com/system/files/TechDocs/55898_B1_pub_0.50.zip
-
-User space C-APIs are made available by linking against the esmi library,
-which is provided by the E-SMS project https://developer.amd.com/e-sms/.
-See: https://github.com/amd/esmi_ib_library
diff --git a/Documentation/x86/boot.rst b/Documentation/x86/boot.rst
deleted file mode 100644 (file)
index 240d084..0000000
+++ /dev/null
@@ -1,1443 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-===========================
-The Linux/x86 Boot Protocol
-===========================
-
-On the x86 platform, the Linux kernel uses a rather complicated boot
-convention.  This has evolved partially due to historical aspects, as
-well as the desire in the early days to have the kernel itself be a
-bootable image, the complicated PC memory model and due to changed
-expectations in the PC industry caused by the effective demise of
-real-mode DOS as a mainstream operating system.
-
-Currently, the following versions of the Linux/x86 boot protocol exist.
-
-=============  ============================================================
-Old kernels    zImage/Image support only.  Some very early kernels
-               may not even support a command line.
-
-Protocol 2.00  (Kernel 1.3.73) Added bzImage and initrd support, as
-               well as a formalized way to communicate between the
-               boot loader and the kernel.  setup.S made relocatable,
-               although the traditional setup area still assumed
-               writable.
-
-Protocol 2.01  (Kernel 1.3.76) Added a heap overrun warning.
-
-Protocol 2.02  (Kernel 2.4.0-test3-pre3) New command line protocol.
-               Lower the conventional memory ceiling.  No overwrite
-               of the traditional setup area, thus making booting
-               safe for systems which use the EBDA from SMM or 32-bit
-               BIOS entry points.  zImage deprecated but still
-               supported.
-
-Protocol 2.03  (Kernel 2.4.18-pre1) Explicitly makes the highest possible
-               initrd address available to the bootloader.
-
-Protocol 2.04  (Kernel 2.6.14) Extend the syssize field to four bytes.
-
-Protocol 2.05  (Kernel 2.6.20) Make protected mode kernel relocatable.
-               Introduce relocatable_kernel and kernel_alignment fields.
-
-Protocol 2.06  (Kernel 2.6.22) Added a field that contains the size of
-               the boot command line.
-
-Protocol 2.07  (Kernel 2.6.24) Added paravirtualised boot protocol.
-               Introduced hardware_subarch and hardware_subarch_data
-               and KEEP_SEGMENTS flag in load_flags.
-
-Protocol 2.08  (Kernel 2.6.26) Added crc32 checksum and ELF format
-               payload. Introduced payload_offset and payload_length
-               fields to aid in locating the payload.
-
-Protocol 2.09  (Kernel 2.6.26) Added a field of 64-bit physical
-               pointer to single linked list of struct setup_data.
-
-Protocol 2.10  (Kernel 2.6.31) Added a protocol for relaxed alignment
-               beyond the kernel_alignment added, new init_size and
-               pref_address fields.  Added extended boot loader IDs.
-
-Protocol 2.11  (Kernel 3.6) Added a field for offset of EFI handover
-               protocol entry point.
-
-Protocol 2.12  (Kernel 3.8) Added the xloadflags field and extension fields
-               to struct boot_params for loading bzImage and ramdisk
-               above 4G in 64bit.
-
-Protocol 2.13  (Kernel 3.14) Support 32- and 64-bit flags being set in
-               xloadflags to support booting a 64-bit kernel from 32-bit
-               EFI
-
-Protocol 2.14  BURNT BY INCORRECT COMMIT
-                ae7e1238e68f2a472a125673ab506d49158c1889
-               (x86/boot: Add ACPI RSDP address to setup_header)
-               DO NOT USE!!! ASSUME SAME AS 2.13.
-
-Protocol 2.15  (Kernel 5.5) Added the kernel_info and kernel_info.setup_type_max.
-=============  ============================================================
-
-.. note::
-     The protocol version number should be changed only if the setup header
-     is changed. There is no need to update the version number if boot_params
-     or kernel_info are changed. Additionally, it is recommended to use
-     xloadflags (in this case the protocol version number should not be
-     updated either) or kernel_info to communicate supported Linux kernel
-     features to the boot loader. Due to very limited space available in
-     the original setup header every update to it should be considered
-     with great care. Starting from the protocol 2.15 the primary way to
-     communicate things to the boot loader is the kernel_info.
-
-
-Memory Layout
-=============
-
-The traditional memory map for the kernel loader, used for Image or
-zImage kernels, typically looks like::
-
-               |                        |
-       0A0000  +------------------------+
-               |  Reserved for BIOS     |      Do not use.  Reserved for BIOS EBDA.
-       09A000  +------------------------+
-               |  Command line          |
-               |  Stack/heap            |      For use by the kernel real-mode code.
-       098000  +------------------------+
-               |  Kernel setup          |      The kernel real-mode code.
-       090200  +------------------------+
-               |  Kernel boot sector    |      The kernel legacy boot sector.
-       090000  +------------------------+
-               |  Protected-mode kernel |      The bulk of the kernel image.
-       010000  +------------------------+
-               |  Boot loader           |      <- Boot sector entry point 0000:7C00
-       001000  +------------------------+
-               |  Reserved for MBR/BIOS |
-       000800  +------------------------+
-               |  Typically used by MBR |
-       000600  +------------------------+
-               |  BIOS use only         |
-       000000  +------------------------+
-
-When using bzImage, the protected-mode kernel was relocated to
-0x100000 ("high memory"), and the kernel real-mode block (boot sector,
-setup, and stack/heap) was made relocatable to any address between
-0x10000 and end of low memory. Unfortunately, in protocols 2.00 and
-2.01 the 0x90000+ memory range is still used internally by the kernel;
-the 2.02 protocol resolves that problem.
-
-It is desirable to keep the "memory ceiling" -- the highest point in
-low memory touched by the boot loader -- as low as possible, since
-some newer BIOSes have begun to allocate some rather large amounts of
-memory, called the Extended BIOS Data Area, near the top of low
-memory.         The boot loader should use the "INT 12h" BIOS call to verify
-how much low memory is available.
-
-Unfortunately, if INT 12h reports that the amount of memory is too
-low, there is usually nothing the boot loader can do but to report an
-error to the user.  The boot loader should therefore be designed to
-take up as little space in low memory as it reasonably can.  For
-zImage or old bzImage kernels, which need data written into the
-0x90000 segment, the boot loader should make sure not to use memory
-above the 0x9A000 point; too many BIOSes will break above that point.
-
-For a modern bzImage kernel with boot protocol version >= 2.02, a
-memory layout like the following is suggested::
-
-               ~                        ~
-               |  Protected-mode kernel |
-       100000  +------------------------+
-               |  I/O memory hole       |
-       0A0000  +------------------------+
-               |  Reserved for BIOS     |      Leave as much as possible unused
-               ~                        ~
-               |  Command line          |      (Can also be below the X+10000 mark)
-       X+10000 +------------------------+
-               |  Stack/heap            |      For use by the kernel real-mode code.
-       X+08000 +------------------------+
-               |  Kernel setup          |      The kernel real-mode code.
-               |  Kernel boot sector    |      The kernel legacy boot sector.
-       X       +------------------------+
-               |  Boot loader           |      <- Boot sector entry point 0000:7C00
-       001000  +------------------------+
-               |  Reserved for MBR/BIOS |
-       000800  +------------------------+
-               |  Typically used by MBR |
-       000600  +------------------------+
-               |  BIOS use only         |
-       000000  +------------------------+
-
-  ... where the address X is as low as the design of the boot loader permits.
-
-
-The Real-Mode Kernel Header
-===========================
-
-In the following text, and anywhere in the kernel boot sequence, "a
-sector" refers to 512 bytes.  It is independent of the actual sector
-size of the underlying medium.
-
-The first step in loading a Linux kernel should be to load the
-real-mode code (boot sector and setup code) and then examine the
-following header at offset 0x01f1.  The real-mode code can total up to
-32K, although the boot loader may choose to load only the first two
-sectors (1K) and then examine the bootup sector size.
-
-The header looks like:
-
-===========    ========        =====================   ============================================
-Offset/Size    Proto           Name                    Meaning
-===========    ========        =====================   ============================================
-01F1/1         ALL(1)          setup_sects             The size of the setup in sectors
-01F2/2         ALL             root_flags              If set, the root is mounted readonly
-01F4/4         2.04+(2)        syssize                 The size of the 32-bit code in 16-byte paras
-01F8/2         ALL             ram_size                DO NOT USE - for bootsect.S use only
-01FA/2         ALL             vid_mode                Video mode control
-01FC/2         ALL             root_dev                Default root device number
-01FE/2         ALL             boot_flag               0xAA55 magic number
-0200/2         2.00+           jump                    Jump instruction
-0202/4         2.00+           header                  Magic signature "HdrS"
-0206/2         2.00+           version                 Boot protocol version supported
-0208/4         2.00+           realmode_swtch          Boot loader hook (see below)
-020C/2         2.00+           start_sys_seg           The load-low segment (0x1000) (obsolete)
-020E/2         2.00+           kernel_version          Pointer to kernel version string
-0210/1         2.00+           type_of_loader          Boot loader identifier
-0211/1         2.00+           loadflags               Boot protocol option flags
-0212/2         2.00+           setup_move_size         Move to high memory size (used with hooks)
-0214/4         2.00+           code32_start            Boot loader hook (see below)
-0218/4         2.00+           ramdisk_image           initrd load address (set by boot loader)
-021C/4         2.00+           ramdisk_size            initrd size (set by boot loader)
-0220/4         2.00+           bootsect_kludge         DO NOT USE - for bootsect.S use only
-0224/2         2.01+           heap_end_ptr            Free memory after setup end
-0226/1         2.02+(3)        ext_loader_ver          Extended boot loader version
-0227/1         2.02+(3)        ext_loader_type         Extended boot loader ID
-0228/4         2.02+           cmd_line_ptr            32-bit pointer to the kernel command line
-022C/4         2.03+           initrd_addr_max         Highest legal initrd address
-0230/4         2.05+           kernel_alignment        Physical addr alignment required for kernel
-0234/1         2.05+           relocatable_kernel      Whether kernel is relocatable or not
-0235/1         2.10+           min_alignment           Minimum alignment, as a power of two
-0236/2         2.12+           xloadflags              Boot protocol option flags
-0238/4         2.06+           cmdline_size            Maximum size of the kernel command line
-023C/4         2.07+           hardware_subarch        Hardware subarchitecture
-0240/8         2.07+           hardware_subarch_data   Subarchitecture-specific data
-0248/4         2.08+           payload_offset          Offset of kernel payload
-024C/4         2.08+           payload_length          Length of kernel payload
-0250/8         2.09+           setup_data              64-bit physical pointer to linked list
-                                                       of struct setup_data
-0258/8         2.10+           pref_address            Preferred loading address
-0260/4         2.10+           init_size               Linear memory required during initialization
-0264/4         2.11+           handover_offset         Offset of handover entry point
-0268/4         2.15+           kernel_info_offset      Offset of the kernel_info
-===========    ========        =====================   ============================================
-
-.. note::
-  (1) For backwards compatibility, if the setup_sects field contains 0, the
-      real value is 4.
-
-  (2) For boot protocol prior to 2.04, the upper two bytes of the syssize
-      field are unusable, which means the size of a bzImage kernel
-      cannot be determined.
-
-  (3) Ignored, but safe to set, for boot protocols 2.02-2.09.
-
-If the "HdrS" (0x53726448) magic number is not found at offset 0x202,
-the boot protocol version is "old".  Loading an old kernel, the
-following parameters should be assumed::
-
-       Image type = zImage
-       initrd not supported
-       Real-mode kernel must be located at 0x90000.
-
-Otherwise, the "version" field contains the protocol version,
-e.g. protocol version 2.01 will contain 0x0201 in this field.  When
-setting fields in the header, you must make sure only to set fields
-supported by the protocol version in use.
-
-
-Details of Header Fields
-========================
-
-For each field, some are information from the kernel to the bootloader
-("read"), some are expected to be filled out by the bootloader
-("write"), and some are expected to be read and modified by the
-bootloader ("modify").
-
-All general purpose boot loaders should write the fields marked
-(obligatory).  Boot loaders who want to load the kernel at a
-nonstandard address should fill in the fields marked (reloc); other
-boot loaders can ignore those fields.
-
-The byte order of all fields is littleendian (this is x86, after all.)
-
-============   ===========
-Field name:    setup_sects
-Type:          read
-Offset/size:   0x1f1/1
-Protocol:      ALL
-============   ===========
-
-  The size of the setup code in 512-byte sectors.  If this field is
-  0, the real value is 4.  The real-mode code consists of the boot
-  sector (always one 512-byte sector) plus the setup code.
-
-============   =================
-Field name:    root_flags
-Type:          modify (optional)
-Offset/size:   0x1f2/2
-Protocol:      ALL
-============   =================
-
-  If this field is nonzero, the root defaults to readonly.  The use of
-  this field is deprecated; use the "ro" or "rw" options on the
-  command line instead.
-
-============   ===============================================
-Field name:    syssize
-Type:          read
-Offset/size:   0x1f4/4 (protocol 2.04+) 0x1f4/2 (protocol ALL)
-Protocol:      2.04+
-============   ===============================================
-
-  The size of the protected-mode code in units of 16-byte paragraphs.
-  For protocol versions older than 2.04 this field is only two bytes
-  wide, and therefore cannot be trusted for the size of a kernel if
-  the LOAD_HIGH flag is set.
-
-============   ===============
-Field name:    ram_size
-Type:          kernel internal
-Offset/size:   0x1f8/2
-Protocol:      ALL
-============   ===============
-
-  This field is obsolete.
-
-============   ===================
-Field name:    vid_mode
-Type:          modify (obligatory)
-Offset/size:   0x1fa/2
-============   ===================
-
-  Please see the section on SPECIAL COMMAND LINE OPTIONS.
-
-============   =================
-Field name:    root_dev
-Type:          modify (optional)
-Offset/size:   0x1fc/2
-Protocol:      ALL
-============   =================
-
-  The default root device device number.  The use of this field is
-  deprecated, use the "root=" option on the command line instead.
-
-============   =========
-Field name:    boot_flag
-Type:          read
-Offset/size:   0x1fe/2
-Protocol:      ALL
-============   =========
-
-  Contains 0xAA55.  This is the closest thing old Linux kernels have
-  to a magic number.
-
-============   =======
-Field name:    jump
-Type:          read
-Offset/size:   0x200/2
-Protocol:      2.00+
-============   =======
-
-  Contains an x86 jump instruction, 0xEB followed by a signed offset
-  relative to byte 0x202.  This can be used to determine the size of
-  the header.
-
-============   =======
-Field name:    header
-Type:          read
-Offset/size:   0x202/4
-Protocol:      2.00+
-============   =======
-
-  Contains the magic number "HdrS" (0x53726448).
-
-============   =======
-Field name:    version
-Type:          read
-Offset/size:   0x206/2
-Protocol:      2.00+
-============   =======
-
-  Contains the boot protocol version, in (major << 8)+minor format,
-  e.g. 0x0204 for version 2.04, and 0x0a11 for a hypothetical version
-  10.17.
-
-============   =================
-Field name:    realmode_swtch
-Type:          modify (optional)
-Offset/size:   0x208/4
-Protocol:      2.00+
-============   =================
-
-  Boot loader hook (see ADVANCED BOOT LOADER HOOKS below.)
-
-============   =============
-Field name:    start_sys_seg
-Type:          read
-Offset/size:   0x20c/2
-Protocol:      2.00+
-============   =============
-
-  The load low segment (0x1000).  Obsolete.
-
-============   ==============
-Field name:    kernel_version
-Type:          read
-Offset/size:   0x20e/2
-Protocol:      2.00+
-============   ==============
-
-  If set to a nonzero value, contains a pointer to a NUL-terminated
-  human-readable kernel version number string, less 0x200.  This can
-  be used to display the kernel version to the user.  This value
-  should be less than (0x200*setup_sects).
-
-  For example, if this value is set to 0x1c00, the kernel version
-  number string can be found at offset 0x1e00 in the kernel file.
-  This is a valid value if and only if the "setup_sects" field
-  contains the value 15 or higher, as::
-
-       0x1c00  < 15*0x200 (= 0x1e00) but
-       0x1c00 >= 14*0x200 (= 0x1c00)
-
-       0x1c00 >> 9 = 14, So the minimum value for setup_secs is 15.
-
-============   ==================
-Field name:    type_of_loader
-Type:          write (obligatory)
-Offset/size:   0x210/1
-Protocol:      2.00+
-============   ==================
-
-  If your boot loader has an assigned id (see table below), enter
-  0xTV here, where T is an identifier for the boot loader and V is
-  a version number.  Otherwise, enter 0xFF here.
-
-  For boot loader IDs above T = 0xD, write T = 0xE to this field and
-  write the extended ID minus 0x10 to the ext_loader_type field.
-  Similarly, the ext_loader_ver field can be used to provide more than
-  four bits for the bootloader version.
-
-  For example, for T = 0x15, V = 0x234, write::
-
-       type_of_loader  <- 0xE4
-       ext_loader_type <- 0x05
-       ext_loader_ver  <- 0x23
-
-  Assigned boot loader ids (hexadecimal):
-
-       == =======================================
-       0  LILO
-          (0x00 reserved for pre-2.00 bootloader)
-       1  Loadlin
-       2  bootsect-loader
-          (0x20, all other values reserved)
-       3  Syslinux
-       4  Etherboot/gPXE/iPXE
-       5  ELILO
-       7  GRUB
-       8  U-Boot
-       9  Xen
-       A  Gujin
-       B  Qemu
-       C  Arcturus Networks uCbootloader
-       D  kexec-tools
-       E  Extended (see ext_loader_type)
-       F  Special (0xFF = undefined)
-       10 Reserved
-       11 Minimal Linux Bootloader
-          <http://sebastian-plotz.blogspot.de>
-       12 OVMF UEFI virtualization stack
-       13 barebox
-       == =======================================
-
-  Please contact <hpa@zytor.com> if you need a bootloader ID value assigned.
-
-============   ===================
-Field name:    loadflags
-Type:          modify (obligatory)
-Offset/size:   0x211/1
-Protocol:      2.00+
-============   ===================
-
-  This field is a bitmask.
-
-  Bit 0 (read):        LOADED_HIGH
-
-       - If 0, the protected-mode code is loaded at 0x10000.
-       - If 1, the protected-mode code is loaded at 0x100000.
-
-  Bit 1 (kernel internal): KASLR_FLAG
-
-       - Used internally by the compressed kernel to communicate
-         KASLR status to kernel proper.
-
-           - If 1, KASLR enabled.
-           - If 0, KASLR disabled.
-
-  Bit 5 (write): QUIET_FLAG
-
-       - If 0, print early messages.
-       - If 1, suppress early messages.
-
-               This requests to the kernel (decompressor and early
-               kernel) to not write early messages that require
-               accessing the display hardware directly.
-
-  Bit 6 (obsolete): KEEP_SEGMENTS
-
-       Protocol: 2.07+
-
-        - This flag is obsolete.
-
-  Bit 7 (write): CAN_USE_HEAP
-
-       Set this bit to 1 to indicate that the value entered in the
-       heap_end_ptr is valid.  If this field is clear, some setup code
-       functionality will be disabled.
-
-
-============   ===================
-Field name:    setup_move_size
-Type:          modify (obligatory)
-Offset/size:   0x212/2
-Protocol:      2.00-2.01
-============   ===================
-
-  When using protocol 2.00 or 2.01, if the real mode kernel is not
-  loaded at 0x90000, it gets moved there later in the loading
-  sequence.  Fill in this field if you want additional data (such as
-  the kernel command line) moved in addition to the real-mode kernel
-  itself.
-
-  The unit is bytes starting with the beginning of the boot sector.
-
-  This field is can be ignored when the protocol is 2.02 or higher, or
-  if the real-mode code is loaded at 0x90000.
-
-============   ========================
-Field name:    code32_start
-Type:          modify (optional, reloc)
-Offset/size:   0x214/4
-Protocol:      2.00+
-============   ========================
-
-  The address to jump to in protected mode.  This defaults to the load
-  address of the kernel, and can be used by the boot loader to
-  determine the proper load address.
-
-  This field can be modified for two purposes:
-
-    1. as a boot loader hook (see Advanced Boot Loader Hooks below.)
-
-    2. if a bootloader which does not install a hook loads a
-       relocatable kernel at a nonstandard address it will have to modify
-       this field to point to the load address.
-
-============   ==================
-Field name:    ramdisk_image
-Type:          write (obligatory)
-Offset/size:   0x218/4
-Protocol:      2.00+
-============   ==================
-
-  The 32-bit linear address of the initial ramdisk or ramfs.  Leave at
-  zero if there is no initial ramdisk/ramfs.
-
-============   ==================
-Field name:    ramdisk_size
-Type:          write (obligatory)
-Offset/size:   0x21c/4
-Protocol:      2.00+
-============   ==================
-
-  Size of the initial ramdisk or ramfs.  Leave at zero if there is no
-  initial ramdisk/ramfs.
-
-============   ===============
-Field name:    bootsect_kludge
-Type:          kernel internal
-Offset/size:   0x220/4
-Protocol:      2.00+
-============   ===============
-
-  This field is obsolete.
-
-============   ==================
-Field name:    heap_end_ptr
-Type:          write (obligatory)
-Offset/size:   0x224/2
-Protocol:      2.01+
-============   ==================
-
-  Set this field to the offset (from the beginning of the real-mode
-  code) of the end of the setup stack/heap, minus 0x0200.
-
-============   ================
-Field name:    ext_loader_ver
-Type:          write (optional)
-Offset/size:   0x226/1
-Protocol:      2.02+
-============   ================
-
-  This field is used as an extension of the version number in the
-  type_of_loader field.  The total version number is considered to be
-  (type_of_loader & 0x0f) + (ext_loader_ver << 4).
-
-  The use of this field is boot loader specific.  If not written, it
-  is zero.
-
-  Kernels prior to 2.6.31 did not recognize this field, but it is safe
-  to write for protocol version 2.02 or higher.
-
-============   =====================================================
-Field name:    ext_loader_type
-Type:          write (obligatory if (type_of_loader & 0xf0) == 0xe0)
-Offset/size:   0x227/1
-Protocol:      2.02+
-============   =====================================================
-
-  This field is used as an extension of the type number in
-  type_of_loader field.  If the type in type_of_loader is 0xE, then
-  the actual type is (ext_loader_type + 0x10).
-
-  This field is ignored if the type in type_of_loader is not 0xE.
-
-  Kernels prior to 2.6.31 did not recognize this field, but it is safe
-  to write for protocol version 2.02 or higher.
-
-============   ==================
-Field name:    cmd_line_ptr
-Type:          write (obligatory)
-Offset/size:   0x228/4
-Protocol:      2.02+
-============   ==================
-
-  Set this field to the linear address of the kernel command line.
-  The kernel command line can be located anywhere between the end of
-  the setup heap and 0xA0000; it does not have to be located in the
-  same 64K segment as the real-mode code itself.
-
-  Fill in this field even if your boot loader does not support a
-  command line, in which case you can point this to an empty string
-  (or better yet, to the string "auto".)  If this field is left at
-  zero, the kernel will assume that your boot loader does not support
-  the 2.02+ protocol.
-
-============   ===============
-Field name:    initrd_addr_max
-Type:          read
-Offset/size:   0x22c/4
-Protocol:      2.03+
-============   ===============
-
-  The maximum address that may be occupied by the initial
-  ramdisk/ramfs contents.  For boot protocols 2.02 or earlier, this
-  field is not present, and the maximum address is 0x37FFFFFF.  (This
-  address is defined as the address of the highest safe byte, so if
-  your ramdisk is exactly 131072 bytes long and this field is
-  0x37FFFFFF, you can start your ramdisk at 0x37FE0000.)
-
-============   ============================
-Field name:    kernel_alignment
-Type:          read/modify (reloc)
-Offset/size:   0x230/4
-Protocol:      2.05+ (read), 2.10+ (modify)
-============   ============================
-
-  Alignment unit required by the kernel (if relocatable_kernel is
-  true.)  A relocatable kernel that is loaded at an alignment
-  incompatible with the value in this field will be realigned during
-  kernel initialization.
-
-  Starting with protocol version 2.10, this reflects the kernel
-  alignment preferred for optimal performance; it is possible for the
-  loader to modify this field to permit a lesser alignment.  See the
-  min_alignment and pref_address field below.
-
-============   ==================
-Field name:    relocatable_kernel
-Type:          read (reloc)
-Offset/size:   0x234/1
-Protocol:      2.05+
-============   ==================
-
-  If this field is nonzero, the protected-mode part of the kernel can
-  be loaded at any address that satisfies the kernel_alignment field.
-  After loading, the boot loader must set the code32_start field to
-  point to the loaded code, or to a boot loader hook.
-
-============   =============
-Field name:    min_alignment
-Type:          read (reloc)
-Offset/size:   0x235/1
-Protocol:      2.10+
-============   =============
-
-  This field, if nonzero, indicates as a power of two the minimum
-  alignment required, as opposed to preferred, by the kernel to boot.
-  If a boot loader makes use of this field, it should update the
-  kernel_alignment field with the alignment unit desired; typically::
-
-       kernel_alignment = 1 << min_alignment
-
-  There may be a considerable performance cost with an excessively
-  misaligned kernel.  Therefore, a loader should typically try each
-  power-of-two alignment from kernel_alignment down to this alignment.
-
-============   ==========
-Field name:    xloadflags
-Type:          read
-Offset/size:   0x236/2
-Protocol:      2.12+
-============   ==========
-
-  This field is a bitmask.
-
-  Bit 0 (read):        XLF_KERNEL_64
-
-       - If 1, this kernel has the legacy 64-bit entry point at 0x200.
-
-  Bit 1 (read): XLF_CAN_BE_LOADED_ABOVE_4G
-
-        - If 1, kernel/boot_params/cmdline/ramdisk can be above 4G.
-
-  Bit 2 (read):        XLF_EFI_HANDOVER_32
-
-       - If 1, the kernel supports the 32-bit EFI handoff entry point
-          given at handover_offset.
-
-  Bit 3 (read): XLF_EFI_HANDOVER_64
-
-       - If 1, the kernel supports the 64-bit EFI handoff entry point
-          given at handover_offset + 0x200.
-
-  Bit 4 (read): XLF_EFI_KEXEC
-
-       - If 1, the kernel supports kexec EFI boot with EFI runtime support.
-
-
-============   ============
-Field name:    cmdline_size
-Type:          read
-Offset/size:   0x238/4
-Protocol:      2.06+
-============   ============
-
-  The maximum size of the command line without the terminating
-  zero. This means that the command line can contain at most
-  cmdline_size characters. With protocol version 2.05 and earlier, the
-  maximum size was 255.
-
-============   ====================================
-Field name:    hardware_subarch
-Type:          write (optional, defaults to x86/PC)
-Offset/size:   0x23c/4
-Protocol:      2.07+
-============   ====================================
-
-  In a paravirtualized environment the hardware low level architectural
-  pieces such as interrupt handling, page table handling, and
-  accessing process control registers needs to be done differently.
-
-  This field allows the bootloader to inform the kernel we are in one
-  one of those environments.
-
-  ==========   ==============================
-  0x00000000   The default x86/PC environment
-  0x00000001   lguest
-  0x00000002   Xen
-  0x00000003   Moorestown MID
-  0x00000004   CE4100 TV Platform
-  ==========   ==============================
-
-============   =========================
-Field name:    hardware_subarch_data
-Type:          write (subarch-dependent)
-Offset/size:   0x240/8
-Protocol:      2.07+
-============   =========================
-
-  A pointer to data that is specific to hardware subarch
-  This field is currently unused for the default x86/PC environment,
-  do not modify.
-
-============   ==============
-Field name:    payload_offset
-Type:          read
-Offset/size:   0x248/4
-Protocol:      2.08+
-============   ==============
-
-  If non-zero then this field contains the offset from the beginning
-  of the protected-mode code to the payload.
-
-  The payload may be compressed. The format of both the compressed and
-  uncompressed data should be determined using the standard magic
-  numbers.  The currently supported compression formats are gzip
-  (magic numbers 1F 8B or 1F 9E), bzip2 (magic number 42 5A), LZMA
-  (magic number 5D 00), XZ (magic number FD 37), LZ4 (magic number
-  02 21) and ZSTD (magic number 28 B5). The uncompressed payload is
-  currently always ELF (magic number 7F 45 4C 46).
-
-============   ==============
-Field name:    payload_length
-Type:          read
-Offset/size:   0x24c/4
-Protocol:      2.08+
-============   ==============
-
-  The length of the payload.
-
-============   ===============
-Field name:    setup_data
-Type:          write (special)
-Offset/size:   0x250/8
-Protocol:      2.09+
-============   ===============
-
-  The 64-bit physical pointer to NULL terminated single linked list of
-  struct setup_data. This is used to define a more extensible boot
-  parameters passing mechanism. The definition of struct setup_data is
-  as follow::
-
-       struct setup_data {
-               u64 next;
-               u32 type;
-               u32 len;
-               u8  data[0];
-       };
-
-  Where, the next is a 64-bit physical pointer to the next node of
-  linked list, the next field of the last node is 0; the type is used
-  to identify the contents of data; the len is the length of data
-  field; the data holds the real payload.
-
-  This list may be modified at a number of points during the bootup
-  process.  Therefore, when modifying this list one should always make
-  sure to consider the case where the linked list already contains
-  entries.
-
-  The setup_data is a bit awkward to use for extremely large data objects,
-  both because the setup_data header has to be adjacent to the data object
-  and because it has a 32-bit length field. However, it is important that
-  intermediate stages of the boot process have a way to identify which
-  chunks of memory are occupied by kernel data.
-
-  Thus setup_indirect struct and SETUP_INDIRECT type were introduced in
-  protocol 2.15::
-
-    struct setup_indirect {
-      __u32 type;
-      __u32 reserved;  /* Reserved, must be set to zero. */
-      __u64 len;
-      __u64 addr;
-    };
-
-  The type member is a SETUP_INDIRECT | SETUP_* type. However, it cannot be
-  SETUP_INDIRECT itself since making the setup_indirect a tree structure
-  could require a lot of stack space in something that needs to parse it
-  and stack space can be limited in boot contexts.
-
-  Let's give an example how to point to SETUP_E820_EXT data using setup_indirect.
-  In this case setup_data and setup_indirect will look like this::
-
-    struct setup_data {
-      __u64 next = 0 or <addr_of_next_setup_data_struct>;
-      __u32 type = SETUP_INDIRECT;
-      __u32 len = sizeof(setup_indirect);
-      __u8 data[sizeof(setup_indirect)] = struct setup_indirect {
-        __u32 type = SETUP_INDIRECT | SETUP_E820_EXT;
-        __u32 reserved = 0;
-        __u64 len = <len_of_SETUP_E820_EXT_data>;
-        __u64 addr = <addr_of_SETUP_E820_EXT_data>;
-      }
-    }
-
-.. note::
-     SETUP_INDIRECT | SETUP_NONE objects cannot be properly distinguished
-     from SETUP_INDIRECT itself. So, this kind of objects cannot be provided
-     by the bootloaders.
-
-============   ============
-Field name:    pref_address
-Type:          read (reloc)
-Offset/size:   0x258/8
-Protocol:      2.10+
-============   ============
-
-  This field, if nonzero, represents a preferred load address for the
-  kernel.  A relocating bootloader should attempt to load at this
-  address if possible.
-
-  A non-relocatable kernel will unconditionally move itself and to run
-  at this address.
-
-============   =======
-Field name:    init_size
-Type:          read
-Offset/size:   0x260/4
-============   =======
-
-  This field indicates the amount of linear contiguous memory starting
-  at the kernel runtime start address that the kernel needs before it
-  is capable of examining its memory map.  This is not the same thing
-  as the total amount of memory the kernel needs to boot, but it can
-  be used by a relocating boot loader to help select a safe load
-  address for the kernel.
-
-  The kernel runtime start address is determined by the following algorithm::
-
-       if (relocatable_kernel)
-       runtime_start = align_up(load_address, kernel_alignment)
-       else
-       runtime_start = pref_address
-
-============   ===============
-Field name:    handover_offset
-Type:          read
-Offset/size:   0x264/4
-============   ===============
-
-  This field is the offset from the beginning of the kernel image to
-  the EFI handover protocol entry point. Boot loaders using the EFI
-  handover protocol to boot the kernel should jump to this offset.
-
-  See EFI HANDOVER PROTOCOL below for more details.
-
-============   ==================
-Field name:    kernel_info_offset
-Type:          read
-Offset/size:   0x268/4
-Protocol:      2.15+
-============   ==================
-
-  This field is the offset from the beginning of the kernel image to the
-  kernel_info. The kernel_info structure is embedded in the Linux image
-  in the uncompressed protected mode region.
-
-
-The kernel_info
-===============
-
-The relationships between the headers are analogous to the various data
-sections:
-
-  setup_header = .data
-  boot_params/setup_data = .bss
-
-What is missing from the above list? That's right:
-
-  kernel_info = .rodata
-
-We have been (ab)using .data for things that could go into .rodata or .bss for
-a long time, for lack of alternatives and -- especially early on -- inertia.
-Also, the BIOS stub is responsible for creating boot_params, so it isn't
-available to a BIOS-based loader (setup_data is, though).
-
-setup_header is permanently limited to 144 bytes due to the reach of the
-2-byte jump field, which doubles as a length field for the structure, combined
-with the size of the "hole" in struct boot_params that a protected-mode loader
-or the BIOS stub has to copy it into. It is currently 119 bytes long, which
-leaves us with 25 very precious bytes. This isn't something that can be fixed
-without revising the boot protocol entirely, breaking backwards compatibility.
-
-boot_params proper is limited to 4096 bytes, but can be arbitrarily extended
-by adding setup_data entries. It cannot be used to communicate properties of
-the kernel image, because it is .bss and has no image-provided content.
-
-kernel_info solves this by providing an extensible place for information about
-the kernel image. It is readonly, because the kernel cannot rely on a
-bootloader copying its contents anywhere, but that is OK; if it becomes
-necessary it can still contain data items that an enabled bootloader would be
-expected to copy into a setup_data chunk.
-
-All kernel_info data should be part of this structure. Fixed size data have to
-be put before kernel_info_var_len_data label. Variable size data have to be put
-after kernel_info_var_len_data label. Each chunk of variable size data has to
-be prefixed with header/magic and its size, e.g.::
-
-  kernel_info:
-          .ascii  "LToP"          /* Header, Linux top (structure). */
-          .long   kernel_info_var_len_data - kernel_info
-          .long   kernel_info_end - kernel_info
-          .long   0x01234567      /* Some fixed size data for the bootloaders. */
-  kernel_info_var_len_data:
-  example_struct:                 /* Some variable size data for the bootloaders. */
-          .ascii  "0123"          /* Header/Magic. */
-          .long   example_struct_end - example_struct
-          .ascii  "Struct"
-          .long   0x89012345
-  example_struct_end:
-  example_strings:                /* Some variable size data for the bootloaders. */
-          .ascii  "ABCD"          /* Header/Magic. */
-          .long   example_strings_end - example_strings
-          .asciz  "String_0"
-          .asciz  "String_1"
-  example_strings_end:
-  kernel_info_end:
-
-This way the kernel_info is self-contained blob.
-
-.. note::
-     Each variable size data header/magic can be any 4-character string,
-     without \0 at the end of the string, which does not collide with
-     existing variable length data headers/magics.
-
-
-Details of the kernel_info Fields
-=================================
-
-============   ========
-Field name:    header
-Offset/size:   0x0000/4
-============   ========
-
-  Contains the magic number "LToP" (0x506f544c).
-
-============   ========
-Field name:    size
-Offset/size:   0x0004/4
-============   ========
-
-  This field contains the size of the kernel_info including kernel_info.header.
-  It does not count kernel_info.kernel_info_var_len_data size. This field should be
-  used by the bootloaders to detect supported fixed size fields in the kernel_info
-  and beginning of kernel_info.kernel_info_var_len_data.
-
-============   ========
-Field name:    size_total
-Offset/size:   0x0008/4
-============   ========
-
-  This field contains the size of the kernel_info including kernel_info.header
-  and kernel_info.kernel_info_var_len_data.
-
-============   ==============
-Field name:    setup_type_max
-Offset/size:   0x000c/4
-============   ==============
-
-  This field contains maximal allowed type for setup_data and setup_indirect structs.
-
-
-The Image Checksum
-==================
-
-From boot protocol version 2.08 onwards the CRC-32 is calculated over
-the entire file using the characteristic polynomial 0x04C11DB7 and an
-initial remainder of 0xffffffff.  The checksum is appended to the
-file; therefore the CRC of the file up to the limit specified in the
-syssize field of the header is always 0.
-
-
-The Kernel Command Line
-=======================
-
-The kernel command line has become an important way for the boot
-loader to communicate with the kernel.  Some of its options are also
-relevant to the boot loader itself, see "special command line options"
-below.
-
-The kernel command line is a null-terminated string. The maximum
-length can be retrieved from the field cmdline_size.  Before protocol
-version 2.06, the maximum was 255 characters.  A string that is too
-long will be automatically truncated by the kernel.
-
-If the boot protocol version is 2.02 or later, the address of the
-kernel command line is given by the header field cmd_line_ptr (see
-above.)  This address can be anywhere between the end of the setup
-heap and 0xA0000.
-
-If the protocol version is *not* 2.02 or higher, the kernel
-command line is entered using the following protocol:
-
-  - At offset 0x0020 (word), "cmd_line_magic", enter the magic
-    number 0xA33F.
-
-  - At offset 0x0022 (word), "cmd_line_offset", enter the offset
-    of the kernel command line (relative to the start of the
-    real-mode kernel).
-
-  - The kernel command line *must* be within the memory region
-    covered by setup_move_size, so you may need to adjust this
-    field.
-
-
-Memory Layout of The Real-Mode Code
-===================================
-
-The real-mode code requires a stack/heap to be set up, as well as
-memory allocated for the kernel command line.  This needs to be done
-in the real-mode accessible memory in bottom megabyte.
-
-It should be noted that modern machines often have a sizable Extended
-BIOS Data Area (EBDA).  As a result, it is advisable to use as little
-of the low megabyte as possible.
-
-Unfortunately, under the following circumstances the 0x90000 memory
-segment has to be used:
-
-       - When loading a zImage kernel ((loadflags & 0x01) == 0).
-       - When loading a 2.01 or earlier boot protocol kernel.
-
-.. note::
-     For the 2.00 and 2.01 boot protocols, the real-mode code
-     can be loaded at another address, but it is internally
-     relocated to 0x90000.  For the "old" protocol, the
-     real-mode code must be loaded at 0x90000.
-
-When loading at 0x90000, avoid using memory above 0x9a000.
-
-For boot protocol 2.02 or higher, the command line does not have to be
-located in the same 64K segment as the real-mode setup code; it is
-thus permitted to give the stack/heap the full 64K segment and locate
-the command line above it.
-
-The kernel command line should not be located below the real-mode
-code, nor should it be located in high memory.
-
-
-Sample Boot Configuartion
-=========================
-
-As a sample configuration, assume the following layout of the real
-mode segment.
-
-    When loading below 0x90000, use the entire segment:
-
-        =============  ===================
-       0x0000-0x7fff   Real mode kernel
-       0x8000-0xdfff   Stack and heap
-       0xe000-0xffff   Kernel command line
-       =============   ===================
-
-    When loading at 0x90000 OR the protocol version is 2.01 or earlier:
-
-       =============   ===================
-       0x0000-0x7fff   Real mode kernel
-       0x8000-0x97ff   Stack and heap
-       0x9800-0x9fff   Kernel command line
-       =============   ===================
-
-Such a boot loader should enter the following fields in the header::
-
-       unsigned long base_ptr; /* base address for real-mode segment */
-
-       if ( setup_sects == 0 ) {
-               setup_sects = 4;
-       }
-
-       if ( protocol >= 0x0200 ) {
-               type_of_loader = <type code>;
-               if ( loading_initrd ) {
-                       ramdisk_image = <initrd_address>;
-                       ramdisk_size = <initrd_size>;
-               }
-
-               if ( protocol >= 0x0202 && loadflags & 0x01 )
-                       heap_end = 0xe000;
-               else
-                       heap_end = 0x9800;
-
-               if ( protocol >= 0x0201 ) {
-                       heap_end_ptr = heap_end - 0x200;
-                       loadflags |= 0x80; /* CAN_USE_HEAP */
-               }
-
-               if ( protocol >= 0x0202 ) {
-                       cmd_line_ptr = base_ptr + heap_end;
-                       strcpy(cmd_line_ptr, cmdline);
-               } else {
-                       cmd_line_magic  = 0xA33F;
-                       cmd_line_offset = heap_end;
-                       setup_move_size = heap_end + strlen(cmdline)+1;
-                       strcpy(base_ptr+cmd_line_offset, cmdline);
-               }
-       } else {
-               /* Very old kernel */
-
-               heap_end = 0x9800;
-
-               cmd_line_magic  = 0xA33F;
-               cmd_line_offset = heap_end;
-
-               /* A very old kernel MUST have its real-mode code
-                  loaded at 0x90000 */
-
-               if ( base_ptr != 0x90000 ) {
-                       /* Copy the real-mode kernel */
-                       memcpy(0x90000, base_ptr, (setup_sects+1)*512);
-                       base_ptr = 0x90000;              /* Relocated */
-               }
-
-               strcpy(0x90000+cmd_line_offset, cmdline);
-
-               /* It is recommended to clear memory up to the 32K mark */
-               memset(0x90000 + (setup_sects+1)*512, 0,
-                      (64-(setup_sects+1))*512);
-       }
-
-
-Loading The Rest of The Kernel
-==============================
-
-The 32-bit (non-real-mode) kernel starts at offset (setup_sects+1)*512
-in the kernel file (again, if setup_sects == 0 the real value is 4.)
-It should be loaded at address 0x10000 for Image/zImage kernels and
-0x100000 for bzImage kernels.
-
-The kernel is a bzImage kernel if the protocol >= 2.00 and the 0x01
-bit (LOAD_HIGH) in the loadflags field is set::
-
-       is_bzImage = (protocol >= 0x0200) && (loadflags & 0x01);
-       load_address = is_bzImage ? 0x100000 : 0x10000;
-
-Note that Image/zImage kernels can be up to 512K in size, and thus use
-the entire 0x10000-0x90000 range of memory.  This means it is pretty
-much a requirement for these kernels to load the real-mode part at
-0x90000.  bzImage kernels allow much more flexibility.
-
-Special Command Line Options
-============================
-
-If the command line provided by the boot loader is entered by the
-user, the user may expect the following command line options to work.
-They should normally not be deleted from the kernel command line even
-though not all of them are actually meaningful to the kernel.  Boot
-loader authors who need additional command line options for the boot
-loader itself should get them registered in
-Documentation/admin-guide/kernel-parameters.rst to make sure they will not
-conflict with actual kernel options now or in the future.
-
-  vga=<mode>
-       <mode> here is either an integer (in C notation, either
-       decimal, octal, or hexadecimal) or one of the strings
-       "normal" (meaning 0xFFFF), "ext" (meaning 0xFFFE) or "ask"
-       (meaning 0xFFFD).  This value should be entered into the
-       vid_mode field, as it is used by the kernel before the command
-       line is parsed.
-
-  mem=<size>
-       <size> is an integer in C notation optionally followed by
-       (case insensitive) K, M, G, T, P or E (meaning << 10, << 20,
-       << 30, << 40, << 50 or << 60).  This specifies the end of
-       memory to the kernel. This affects the possible placement of
-       an initrd, since an initrd should be placed near end of
-       memory.  Note that this is an option to *both* the kernel and
-       the bootloader!
-
-  initrd=<file>
-       An initrd should be loaded.  The meaning of <file> is
-       obviously bootloader-dependent, and some boot loaders
-       (e.g. LILO) do not have such a command.
-
-In addition, some boot loaders add the following options to the
-user-specified command line:
-
-  BOOT_IMAGE=<file>
-       The boot image which was loaded.  Again, the meaning of <file>
-       is obviously bootloader-dependent.
-
-  auto
-       The kernel was booted without explicit user intervention.
-
-If these options are added by the boot loader, it is highly
-recommended that they are located *first*, before the user-specified
-or configuration-specified command line.  Otherwise, "init=/bin/sh"
-gets confused by the "auto" option.
-
-
-Running the Kernel
-==================
-
-The kernel is started by jumping to the kernel entry point, which is
-located at *segment* offset 0x20 from the start of the real mode
-kernel.  This means that if you loaded your real-mode kernel code at
-0x90000, the kernel entry point is 9020:0000.
-
-At entry, ds = es = ss should point to the start of the real-mode
-kernel code (0x9000 if the code is loaded at 0x90000), sp should be
-set up properly, normally pointing to the top of the heap, and
-interrupts should be disabled.  Furthermore, to guard against bugs in
-the kernel, it is recommended that the boot loader sets fs = gs = ds =
-es = ss.
-
-In our example from above, we would do::
-
-       /* Note: in the case of the "old" kernel protocol, base_ptr must
-          be == 0x90000 at this point; see the previous sample code */
-
-       seg = base_ptr >> 4;
-
-       cli();  /* Enter with interrupts disabled! */
-
-       /* Set up the real-mode kernel stack */
-       _SS = seg;
-       _SP = heap_end;
-
-       _DS = _ES = _FS = _GS = seg;
-       jmp_far(seg+0x20, 0);   /* Run the kernel */
-
-If your boot sector accesses a floppy drive, it is recommended to
-switch off the floppy motor before running the kernel, since the
-kernel boot leaves interrupts off and thus the motor will not be
-switched off, especially if the loaded kernel has the floppy driver as
-a demand-loaded module!
-
-
-Advanced Boot Loader Hooks
-==========================
-
-If the boot loader runs in a particularly hostile environment (such as
-LOADLIN, which runs under DOS) it may be impossible to follow the
-standard memory location requirements.  Such a boot loader may use the
-following hooks that, if set, are invoked by the kernel at the
-appropriate time.  The use of these hooks should probably be
-considered an absolutely last resort!
-
-IMPORTANT: All the hooks are required to preserve %esp, %ebp, %esi and
-%edi across invocation.
-
-  realmode_swtch:
-       A 16-bit real mode far subroutine invoked immediately before
-       entering protected mode.  The default routine disables NMI, so
-       your routine should probably do so, too.
-
-  code32_start:
-       A 32-bit flat-mode routine *jumped* to immediately after the
-       transition to protected mode, but before the kernel is
-       uncompressed.  No segments, except CS, are guaranteed to be
-       set up (current kernels do, but older ones do not); you should
-       set them up to BOOT_DS (0x18) yourself.
-
-       After completing your hook, you should jump to the address
-       that was in this field before your boot loader overwrote it
-       (relocated, if appropriate.)
-
-
-32-bit Boot Protocol
-====================
-
-For machine with some new BIOS other than legacy BIOS, such as EFI,
-LinuxBIOS, etc, and kexec, the 16-bit real mode setup code in kernel
-based on legacy BIOS can not be used, so a 32-bit boot protocol needs
-to be defined.
-
-In 32-bit boot protocol, the first step in loading a Linux kernel
-should be to setup the boot parameters (struct boot_params,
-traditionally known as "zero page"). The memory for struct boot_params
-should be allocated and initialized to all zero. Then the setup header
-from offset 0x01f1 of kernel image on should be loaded into struct
-boot_params and examined. The end of setup header can be calculated as
-follow::
-
-       0x0202 + byte value at offset 0x0201
-
-In addition to read/modify/write the setup header of the struct
-boot_params as that of 16-bit boot protocol, the boot loader should
-also fill the additional fields of the struct boot_params as
-described in chapter Documentation/x86/zero-page.rst.
-
-After setting up the struct boot_params, the boot loader can load the
-32/64-bit kernel in the same way as that of 16-bit boot protocol.
-
-In 32-bit boot protocol, the kernel is started by jumping to the
-32-bit kernel entry point, which is the start address of loaded
-32/64-bit kernel.
-
-At entry, the CPU must be in 32-bit protected mode with paging
-disabled; a GDT must be loaded with the descriptors for selectors
-__BOOT_CS(0x10) and __BOOT_DS(0x18); both descriptors must be 4G flat
-segment; __BOOT_CS must have execute/read permission, and __BOOT_DS
-must have read/write permission; CS must be __BOOT_CS and DS, ES, SS
-must be __BOOT_DS; interrupt must be disabled; %esi must hold the base
-address of the struct boot_params; %ebp, %edi and %ebx must be zero.
-
-64-bit Boot Protocol
-====================
-
-For machine with 64bit cpus and 64bit kernel, we could use 64bit bootloader
-and we need a 64-bit boot protocol.
-
-In 64-bit boot protocol, the first step in loading a Linux kernel
-should be to setup the boot parameters (struct boot_params,
-traditionally known as "zero page"). The memory for struct boot_params
-could be allocated anywhere (even above 4G) and initialized to all zero.
-Then, the setup header at offset 0x01f1 of kernel image on should be
-loaded into struct boot_params and examined. The end of setup header
-can be calculated as follows::
-
-       0x0202 + byte value at offset 0x0201
-
-In addition to read/modify/write the setup header of the struct
-boot_params as that of 16-bit boot protocol, the boot loader should
-also fill the additional fields of the struct boot_params as described
-in chapter Documentation/x86/zero-page.rst.
-
-After setting up the struct boot_params, the boot loader can load
-64-bit kernel in the same way as that of 16-bit boot protocol, but
-kernel could be loaded above 4G.
-
-In 64-bit boot protocol, the kernel is started by jumping to the
-64-bit kernel entry point, which is the start address of loaded
-64-bit kernel plus 0x200.
-
-At entry, the CPU must be in 64-bit mode with paging enabled.
-The range with setup_header.init_size from start address of loaded
-kernel and zero page and command line buffer get ident mapping;
-a GDT must be loaded with the descriptors for selectors
-__BOOT_CS(0x10) and __BOOT_DS(0x18); both descriptors must be 4G flat
-segment; __BOOT_CS must have execute/read permission, and __BOOT_DS
-must have read/write permission; CS must be __BOOT_CS and DS, ES, SS
-must be __BOOT_DS; interrupt must be disabled; %rsi must hold the base
-address of the struct boot_params.
-
-EFI Handover Protocol (deprecated)
-==================================
-
-This protocol allows boot loaders to defer initialisation to the EFI
-boot stub. The boot loader is required to load the kernel/initrd(s)
-from the boot media and jump to the EFI handover protocol entry point
-which is hdr->handover_offset bytes from the beginning of
-startup_{32,64}.
-
-The boot loader MUST respect the kernel's PE/COFF metadata when it comes
-to section alignment, the memory footprint of the executable image beyond
-the size of the file itself, and any other aspect of the PE/COFF header
-that may affect correct operation of the image as a PE/COFF binary in the
-execution context provided by the EFI firmware.
-
-The function prototype for the handover entry point looks like this::
-
-    efi_main(void *handle, efi_system_table_t *table, struct boot_params *bp)
-
-'handle' is the EFI image handle passed to the boot loader by the EFI
-firmware, 'table' is the EFI system table - these are the first two
-arguments of the "handoff state" as described in section 2.3 of the
-UEFI specification. 'bp' is the boot loader-allocated boot params.
-
-The boot loader *must* fill out the following fields in bp::
-
-  - hdr.cmd_line_ptr
-  - hdr.ramdisk_image (if applicable)
-  - hdr.ramdisk_size  (if applicable)
-
-All other fields should be zero.
-
-NOTE: The EFI Handover Protocol is deprecated in favour of the ordinary PE/COFF
-      entry point, combined with the LINUX_EFI_INITRD_MEDIA_GUID based initrd
-      loading protocol (refer to [0] for an example of the bootloader side of
-      this), which removes the need for any knowledge on the part of the EFI
-      bootloader regarding the internal representation of boot_params or any
-      requirements/limitations regarding the placement of the command line
-      and ramdisk in memory, or the placement of the kernel image itself.
-
-[0] https://github.com/u-boot/u-boot/commit/ec80b4735a593961fe701cc3a5d717d4739b0fd0
diff --git a/Documentation/x86/booting-dt.rst b/Documentation/x86/booting-dt.rst
deleted file mode 100644 (file)
index 965a374..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-DeviceTree Booting
-------------------
-
-  There is one single 32bit entry point to the kernel at code32_start,
-  the decompressor (the real mode entry point goes to the same  32bit
-  entry point once it switched into protected mode). That entry point
-  supports one calling convention which is documented in
-  Documentation/x86/boot.rst
-  The physical pointer to the device-tree block is passed via setup_data
-  which requires at least boot protocol 2.09.
-  The type filed is defined as
-
-  #define SETUP_DTB                      2
-
-  This device-tree is used as an extension to the "boot page". As such it
-  does not parse / consider data which is already covered by the boot
-  page. This includes memory size, reserved ranges, command line arguments
-  or initrd address. It simply holds information which can not be retrieved
-  otherwise like interrupt routing or a list of devices behind an I2C bus.
diff --git a/Documentation/x86/buslock.rst b/Documentation/x86/buslock.rst
deleted file mode 100644 (file)
index 7c051e7..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. include:: <isonum.txt>
-
-===============================
-Bus lock detection and handling
-===============================
-
-:Copyright: |copy| 2021 Intel Corporation
-:Authors: - Fenghua Yu <fenghua.yu@intel.com>
-          - Tony Luck <tony.luck@intel.com>
-
-Problem
-=======
-
-A split lock is any atomic operation whose operand crosses two cache lines.
-Since the operand spans two cache lines and the operation must be atomic,
-the system locks the bus while the CPU accesses the two cache lines.
-
-A bus lock is acquired through either split locked access to writeback (WB)
-memory or any locked access to non-WB memory. This is typically thousands of
-cycles slower than an atomic operation within a cache line. It also disrupts
-performance on other cores and brings the whole system to its knees.
-
-Detection
-=========
-
-Intel processors may support either or both of the following hardware
-mechanisms to detect split locks and bus locks.
-
-#AC exception for split lock detection
---------------------------------------
-
-Beginning with the Tremont Atom CPU split lock operations may raise an
-Alignment Check (#AC) exception when a split lock operation is attemped.
-
-#DB exception for bus lock detection
-------------------------------------
-
-Some CPUs have the ability to notify the kernel by an #DB trap after a user
-instruction acquires a bus lock and is executed. This allows the kernel to
-terminate the application or to enforce throttling.
-
-Software handling
-=================
-
-The kernel #AC and #DB handlers handle bus lock based on the kernel
-parameter "split_lock_detect". Here is a summary of different options:
-
-+------------------+----------------------------+-----------------------+
-|split_lock_detect=|#AC for split lock         |#DB for bus lock       |
-+------------------+----------------------------+-----------------------+
-|off              |Do nothing                  |Do nothing             |
-+------------------+----------------------------+-----------------------+
-|warn             |Kernel OOPs                 |Warn once per task and |
-|(default)        |Warn once per task and      |and continues to run.  |
-|                 |disable future checking     |                       |
-|                 |When both features are      |                       |
-|                 |supported, warn in #AC      |                       |
-+------------------+----------------------------+-----------------------+
-|fatal            |Kernel OOPs                 |Send SIGBUS to user.   |
-|                 |Send SIGBUS to user         |                       |
-|                 |When both features are      |                       |
-|                 |supported, fatal in #AC     |                       |
-+------------------+----------------------------+-----------------------+
-|ratelimit:N      |Do nothing                  |Limit bus lock rate to |
-|(0 < N <= 1000)   |                           |N bus locks per second |
-|                 |                            |system wide and warn on|
-|                 |                            |bus locks.             |
-+------------------+----------------------------+-----------------------+
-
-Usages
-======
-
-Detecting and handling bus lock may find usages in various areas:
-
-It is critical for real time system designers who build consolidated real
-time systems. These systems run hard real time code on some cores and run
-"untrusted" user processes on other cores. The hard real time cannot afford
-to have any bus lock from the untrusted processes to hurt real time
-performance. To date the designers have been unable to deploy these
-solutions as they have no way to prevent the "untrusted" user code from
-generating split lock and bus lock to block the hard real time code to
-access memory during bus locking.
-
-It's also useful for general computing to prevent guests or user
-applications from slowing down the overall system by executing instructions
-with bus lock.
-
-
-Guidance
-========
-off
----
-
-Disable checking for split lock and bus lock. This option can be useful if
-there are legacy applications that trigger these events at a low rate so
-that mitigation is not needed.
-
-warn
-----
-
-A warning is emitted when a bus lock is detected which allows to identify
-the offending application. This is the default behavior.
-
-fatal
------
-
-In this case, the bus lock is not tolerated and the process is killed.
-
-ratelimit
----------
-
-A system wide bus lock rate limit N is specified where 0 < N <= 1000. This
-allows a bus lock rate up to N bus locks per second. When the bus lock rate
-is exceeded then any task which is caught via the buslock #DB exception is
-throttled by enforced sleeps until the rate goes under the limit again.
-
-This is an effective mitigation in cases where a minimal impact can be
-tolerated, but an eventual Denial of Service attack has to be prevented. It
-allows to identify the offending processes and analyze whether they are
-malicious or just badly written.
-
-Selecting a rate limit of 1000 allows the bus to be locked for up to about
-seven million cycles each second (assuming 7000 cycles for each bus
-lock). On a 2 GHz processor that would be about 0.35% system slowdown.
diff --git a/Documentation/x86/cpuinfo.rst b/Documentation/x86/cpuinfo.rst
deleted file mode 100644 (file)
index 08246e8..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=================
-x86 Feature Flags
-=================
-
-Introduction
-============
-
-On x86, flags appearing in /proc/cpuinfo have an X86_FEATURE definition
-in arch/x86/include/asm/cpufeatures.h. If the kernel cares about a feature
-or KVM want to expose the feature to a KVM guest, it can and should have
-an X86_FEATURE_* defined. These flags represent hardware features as
-well as software features.
-
-If users want to know if a feature is available on a given system, they
-try to find the flag in /proc/cpuinfo. If a given flag is present, it
-means that the kernel supports it and is currently making it available.
-If such flag represents a hardware feature, it also means that the
-hardware supports it.
-
-If the expected flag does not appear in /proc/cpuinfo, things are murkier.
-Users need to find out the reason why the flag is missing and find the way
-how to enable it, which is not always easy. There are several factors that
-can explain missing flags: the expected feature failed to enable, the feature
-is missing in hardware, platform firmware did not enable it, the feature is
-disabled at build or run time, an old kernel is in use, or the kernel does
-not support the feature and thus has not enabled it. In general, /proc/cpuinfo
-shows features which the kernel supports. For a full list of CPUID flags
-which the CPU supports, use tools/arch/x86/kcpuid.
-
-How are feature flags created?
-==============================
-
-a: Feature flags can be derived from the contents of CPUID leaves.
-------------------------------------------------------------------
-These feature definitions are organized mirroring the layout of CPUID
-leaves and grouped in words with offsets as mapped in enum cpuid_leafs
-in cpufeatures.h (see arch/x86/include/asm/cpufeatures.h for details).
-If a feature is defined with a X86_FEATURE_<name> definition in
-cpufeatures.h, and if it is detected at run time, the flags will be
-displayed accordingly in /proc/cpuinfo. For example, the flag "avx2"
-comes from X86_FEATURE_AVX2 in cpufeatures.h.
-
-b: Flags can be from scattered CPUID-based features.
-----------------------------------------------------
-Hardware features enumerated in sparsely populated CPUID leaves get
-software-defined values. Still, CPUID needs to be queried to determine
-if a given feature is present. This is done in init_scattered_cpuid_features().
-For instance, X86_FEATURE_CQM_LLC is defined as 11*32 + 0 and its presence is
-checked at runtime in the respective CPUID leaf [EAX=f, ECX=0] bit EDX[1].
-
-The intent of scattering CPUID leaves is to not bloat struct
-cpuinfo_x86.x86_capability[] unnecessarily. For instance, the CPUID leaf
-[EAX=7, ECX=0] has 30 features and is dense, but the CPUID leaf [EAX=7, EAX=1]
-has only one feature and would waste 31 bits of space in the x86_capability[]
-array. Since there is a struct cpuinfo_x86 for each possible CPU, the wasted
-memory is not trivial.
-
-c: Flags can be created synthetically under certain conditions for hardware features.
--------------------------------------------------------------------------------------
-Examples of conditions include whether certain features are present in
-MSR_IA32_CORE_CAPS or specific CPU models are identified. If the needed
-conditions are met, the features are enabled by the set_cpu_cap or
-setup_force_cpu_cap macros. For example, if bit 5 is set in MSR_IA32_CORE_CAPS,
-the feature X86_FEATURE_SPLIT_LOCK_DETECT will be enabled and
-"split_lock_detect" will be displayed. The flag "ring3mwait" will be
-displayed only when running on INTEL_FAM6_XEON_PHI_[KNL|KNM] processors.
-
-d: Flags can represent purely software features.
-------------------------------------------------
-These flags do not represent hardware features. Instead, they represent a
-software feature implemented in the kernel. For example, Kernel Page Table
-Isolation is purely software feature and its feature flag X86_FEATURE_PTI is
-also defined in cpufeatures.h.
-
-Naming of Flags
-===============
-
-The script arch/x86/kernel/cpu/mkcapflags.sh processes the
-#define X86_FEATURE_<name> from cpufeatures.h and generates the
-x86_cap/bug_flags[] arrays in kernel/cpu/capflags.c. The names in the
-resulting x86_cap/bug_flags[] are used to populate /proc/cpuinfo. The naming
-of flags in the x86_cap/bug_flags[] are as follows:
-
-a: The name of the flag is from the string in X86_FEATURE_<name> by default.
-----------------------------------------------------------------------------
-By default, the flag <name> in /proc/cpuinfo is extracted from the respective
-X86_FEATURE_<name> in cpufeatures.h. For example, the flag "avx2" is from
-X86_FEATURE_AVX2.
-
-b: The naming can be overridden.
---------------------------------
-If the comment on the line for the #define X86_FEATURE_* starts with a
-double-quote character (""), the string inside the double-quote characters
-will be the name of the flags. For example, the flag "sse4_1" comes from
-the comment "sse4_1" following the X86_FEATURE_XMM4_1 definition.
-
-There are situations in which overriding the displayed name of the flag is
-needed. For instance, /proc/cpuinfo is a userspace interface and must remain
-constant. If, for some reason, the naming of X86_FEATURE_<name> changes, one
-shall override the new naming with the name already used in /proc/cpuinfo.
-
-c: The naming override can be "", which means it will not appear in /proc/cpuinfo.
-----------------------------------------------------------------------------------
-The feature shall be omitted from /proc/cpuinfo if it does not make sense for
-the feature to be exposed to userspace. For example, X86_FEATURE_ALWAYS is
-defined in cpufeatures.h but that flag is an internal kernel feature used
-in the alternative runtime patching functionality. So, its name is overridden
-with "". Its flag will not appear in /proc/cpuinfo.
-
-Flags are missing when one or more of these happen
-==================================================
-
-a: The hardware does not enumerate support for it.
---------------------------------------------------
-For example, when a new kernel is running on old hardware or the feature is
-not enabled by boot firmware. Even if the hardware is new, there might be a
-problem enabling the feature at run time, the flag will not be displayed.
-
-b: The kernel does not know about the flag.
--------------------------------------------
-For example, when an old kernel is running on new hardware.
-
-c: The kernel disabled support for it at compile-time.
-------------------------------------------------------
-For example, if 5-level-paging is not enabled when building (i.e.,
-CONFIG_X86_5LEVEL is not selected) the flag "la57" will not show up [#f1]_.
-Even though the feature will still be detected via CPUID, the kernel disables
-it by clearing via setup_clear_cpu_cap(X86_FEATURE_LA57).
-
-d: The feature is disabled at boot-time.
-----------------------------------------
-A feature can be disabled either using a command-line parameter or because
-it failed to be enabled. The command-line parameter clearcpuid= can be used
-to disable features using the feature number as defined in
-/arch/x86/include/asm/cpufeatures.h. For instance, User Mode Instruction
-Protection can be disabled using clearcpuid=514. The number 514 is calculated
-from #define X86_FEATURE_UMIP (16*32 + 2).
-
-In addition, there exists a variety of custom command-line parameters that
-disable specific features. The list of parameters includes, but is not limited
-to, nofsgsbase, nosgx, noxsave, etc. 5-level paging can also be disabled using
-"no5lvl".
-
-e: The feature was known to be non-functional.
-----------------------------------------------
-The feature was known to be non-functional because a dependency was
-missing at runtime. For example, AVX flags will not show up if XSAVE feature
-is disabled since they depend on XSAVE feature. Another example would be broken
-CPUs and them missing microcode patches. Due to that, the kernel decides not to
-enable a feature.
-
-.. [#f1] 5-level paging uses linear address of 57 bits.
diff --git a/Documentation/x86/earlyprintk.rst b/Documentation/x86/earlyprintk.rst
deleted file mode 100644 (file)
index 51ef11e..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-============
-Early Printk
-============
-
-Mini-HOWTO for using the earlyprintk=dbgp boot option with a
-USB2 Debug port key and a debug cable, on x86 systems.
-
-You need two computers, the 'USB debug key' special gadget and
-two USB cables, connected like this::
-
-  [host/target] <-------> [USB debug key] <-------> [client/console]
-
-Hardware requirements
-=====================
-
-  a) Host/target system needs to have USB debug port capability.
-
-     You can check this capability by looking at a 'Debug port' bit in
-     the lspci -vvv output::
-
-       # lspci -vvv
-       ...
-       00:1d.7 USB Controller: Intel Corporation 82801H (ICH8 Family) USB2 EHCI Controller #1 (rev 03) (prog-if 20 [EHCI])
-               Subsystem: Lenovo ThinkPad T61
-               Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
-               Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
-               Latency: 0
-               Interrupt: pin D routed to IRQ 19
-               Region 0: Memory at fe227000 (32-bit, non-prefetchable) [size=1K]
-               Capabilities: [50] Power Management version 2
-                       Flags: PMEClk- DSI- D1- D2- AuxCurrent=375mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
-                       Status: D0 PME-Enable- DSel=0 DScale=0 PME+
-               Capabilities: [58] Debug port: BAR=1 offset=00a0
-                            ^^^^^^^^^^^ <==================== [ HERE ]
-               Kernel driver in use: ehci_hcd
-               Kernel modules: ehci-hcd
-       ...
-
-     .. note::
-       If your system does not list a debug port capability then you probably
-       won't be able to use the USB debug key.
-
-  b) You also need a NetChip USB debug cable/key:
-
-        http://www.plxtech.com/products/NET2000/NET20DC/default.asp
-
-     This is a small blue plastic connector with two USB connections;
-     it draws power from its USB connections.
-
-  c) You need a second client/console system with a high speed USB 2.0 port.
-
-  d) The NetChip device must be plugged directly into the physical
-     debug port on the "host/target" system. You cannot use a USB hub in
-     between the physical debug port and the "host/target" system.
-
-     The EHCI debug controller is bound to a specific physical USB
-     port and the NetChip device will only work as an early printk
-     device in this port.  The EHCI host controllers are electrically
-     wired such that the EHCI debug controller is hooked up to the
-     first physical port and there is no way to change this via software.
-     You can find the physical port through experimentation by trying
-     each physical port on the system and rebooting.  Or you can try
-     and use lsusb or look at the kernel info messages emitted by the
-     usb stack when you plug a usb device into various ports on the
-     "host/target" system.
-
-     Some hardware vendors do not expose the usb debug port with a
-     physical connector and if you find such a device send a complaint
-     to the hardware vendor, because there is no reason not to wire
-     this port into one of the physically accessible ports.
-
-  e) It is also important to note, that many versions of the NetChip
-     device require the "client/console" system to be plugged into the
-     right hand side of the device (with the product logo facing up and
-     readable left to right).  The reason being is that the 5 volt
-     power supply is taken from only one side of the device and it
-     must be the side that does not get rebooted.
-
-Software requirements
-=====================
-
-  a) On the host/target system:
-
-    You need to enable the following kernel config option::
-
-      CONFIG_EARLY_PRINTK_DBGP=y
-
-    And you need to add the boot command line: "earlyprintk=dbgp".
-
-    .. note::
-      If you are using Grub, append it to the 'kernel' line in
-      /etc/grub.conf.  If you are using Grub2 on a BIOS firmware system,
-      append it to the 'linux' line in /boot/grub2/grub.cfg. If you are
-      using Grub2 on an EFI firmware system, append it to the 'linux'
-      or 'linuxefi' line in /boot/grub2/grub.cfg or
-      /boot/efi/EFI/<distro>/grub.cfg.
-
-    On systems with more than one EHCI debug controller you must
-    specify the correct EHCI debug controller number.  The ordering
-    comes from the PCI bus enumeration of the EHCI controllers.  The
-    default with no number argument is "0" or the first EHCI debug
-    controller.  To use the second EHCI debug controller, you would
-    use the command line: "earlyprintk=dbgp1"
-
-    .. note::
-      normally earlyprintk console gets turned off once the
-      regular console is alive - use "earlyprintk=dbgp,keep" to keep
-      this channel open beyond early bootup. This can be useful for
-      debugging crashes under Xorg, etc.
-
-  b) On the client/console system:
-
-    You should enable the following kernel config option::
-
-      CONFIG_USB_SERIAL_DEBUG=y
-
-    On the next bootup with the modified kernel you should
-    get a /dev/ttyUSBx device(s).
-
-    Now this channel of kernel messages is ready to be used: start
-    your favorite terminal emulator (minicom, etc.) and set
-    it up to use /dev/ttyUSB0 - or use a raw 'cat /dev/ttyUSBx' to
-    see the raw output.
-
-  c) On Nvidia Southbridge based systems: the kernel will try to probe
-     and find out which port has a debug device connected.
-
-Testing
-=======
-
-You can test the output by using earlyprintk=dbgp,keep and provoking
-kernel messages on the host/target system. You can provoke a harmless
-kernel message by for example doing::
-
-     echo h > /proc/sysrq-trigger
-
-On the host/target system you should see this help line in "dmesg" output::
-
-     SysRq : HELP : loglevel(0-9) reBoot Crashdump terminate-all-tasks(E) memory-full-oom-kill(F) kill-all-tasks(I) saK show-backtrace-all-active-cpus(L) show-memory-usage(M) nice-all-RT-tasks(N) powerOff show-registers(P) show-all-timers(Q) unRaw Sync show-task-states(T) Unmount show-blocked-tasks(W) dump-ftrace-buffer(Z)
-
-On the client/console system do::
-
-       cat /dev/ttyUSB0
-
-And you should see the help line above displayed shortly after you've
-provoked it on the host system.
-
-If it does not work then please ask about it on the linux-kernel@vger.kernel.org
-mailing list or contact the x86 maintainers.
diff --git a/Documentation/x86/elf_auxvec.rst b/Documentation/x86/elf_auxvec.rst
deleted file mode 100644 (file)
index 18e4744..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-==================================
-x86-specific ELF Auxiliary Vectors
-==================================
-
-This document describes the semantics of the x86 auxiliary vectors.
-
-Introduction
-============
-
-ELF Auxiliary vectors enable the kernel to efficiently provide
-configuration-specific parameters to userspace. In this example, a program
-allocates an alternate stack based on the kernel-provided size::
-
-   #include <sys/auxv.h>
-   #include <elf.h>
-   #include <signal.h>
-   #include <stdlib.h>
-   #include <assert.h>
-   #include <err.h>
-
-   #ifndef AT_MINSIGSTKSZ
-   #define AT_MINSIGSTKSZ      51
-   #endif
-
-   ....
-   stack_t ss;
-
-   ss.ss_sp = malloc(ss.ss_size);
-   assert(ss.ss_sp);
-
-   ss.ss_size = getauxval(AT_MINSIGSTKSZ) + SIGSTKSZ;
-   ss.ss_flags = 0;
-
-   if (sigaltstack(&ss, NULL))
-        err(1, "sigaltstack");
-
-
-The exposed auxiliary vectors
-=============================
-
-AT_SYSINFO is used for locating the vsyscall entry point.  It is not
-exported on 64-bit mode.
-
-AT_SYSINFO_EHDR is the start address of the page containing the vDSO.
-
-AT_MINSIGSTKSZ denotes the minimum stack size required by the kernel to
-deliver a signal to user-space.  AT_MINSIGSTKSZ comprehends the space
-consumed by the kernel to accommodate the user context for the current
-hardware configuration.  It does not comprehend subsequent user-space stack
-consumption, which must be added by the user.  (e.g. Above, user-space adds
-SIGSTKSZ to AT_MINSIGSTKSZ.)
diff --git a/Documentation/x86/entry_64.rst b/Documentation/x86/entry_64.rst
deleted file mode 100644 (file)
index 0afdce3..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-==============
-Kernel Entries
-==============
-
-This file documents some of the kernel entries in
-arch/x86/entry/entry_64.S.  A lot of this explanation is adapted from
-an email from Ingo Molnar:
-
-https://lore.kernel.org/r/20110529191055.GC9835%40elte.hu
-
-The x86 architecture has quite a few different ways to jump into
-kernel code.  Most of these entry points are registered in
-arch/x86/kernel/traps.c and implemented in arch/x86/entry/entry_64.S
-for 64-bit, arch/x86/entry/entry_32.S for 32-bit and finally
-arch/x86/entry/entry_64_compat.S which implements the 32-bit compatibility
-syscall entry points and thus provides for 32-bit processes the
-ability to execute syscalls when running on 64-bit kernels.
-
-The IDT vector assignments are listed in arch/x86/include/asm/irq_vectors.h.
-
-Some of these entries are:
-
- - system_call: syscall instruction from 64-bit code.
-
- - entry_INT80_compat: int 0x80 from 32-bit or 64-bit code; compat syscall
-   either way.
-
- - entry_INT80_compat, ia32_sysenter: syscall and sysenter from 32-bit
-   code
-
- - interrupt: An array of entries.  Every IDT vector that doesn't
-   explicitly point somewhere else gets set to the corresponding
-   value in interrupts.  These point to a whole array of
-   magically-generated functions that make their way to common_interrupt()
-   with the interrupt number as a parameter.
-
- - APIC interrupts: Various special-purpose interrupts for things
-   like TLB shootdown.
-
- - Architecturally-defined exceptions like divide_error.
-
-There are a few complexities here.  The different x86-64 entries
-have different calling conventions.  The syscall and sysenter
-instructions have their own peculiar calling conventions.  Some of
-the IDT entries push an error code onto the stack; others don't.
-IDT entries using the IST alternative stack mechanism need their own
-magic to get the stack frames right.  (You can find some
-documentation in the AMD APM, Volume 2, Chapter 8 and the Intel SDM,
-Volume 3, Chapter 6.)
-
-Dealing with the swapgs instruction is especially tricky.  Swapgs
-toggles whether gs is the kernel gs or the user gs.  The swapgs
-instruction is rather fragile: it must nest perfectly and only in
-single depth, it should only be used if entering from user mode to
-kernel mode and then when returning to user-space, and precisely
-so. If we mess that up even slightly, we crash.
-
-So when we have a secondary entry, already in kernel mode, we *must
-not* use SWAPGS blindly - nor must we forget doing a SWAPGS when it's
-not switched/swapped yet.
-
-Now, there's a secondary complication: there's a cheap way to test
-which mode the CPU is in and an expensive way.
-
-The cheap way is to pick this info off the entry frame on the kernel
-stack, from the CS of the ptregs area of the kernel stack::
-
-       xorl %ebx,%ebx
-       testl $3,CS+8(%rsp)
-       je error_kernelspace
-       SWAPGS
-
-The expensive (paranoid) way is to read back the MSR_GS_BASE value
-(which is what SWAPGS modifies)::
-
-       movl $1,%ebx
-       movl $MSR_GS_BASE,%ecx
-       rdmsr
-       testl %edx,%edx
-       js 1f   /* negative -> in kernel */
-       SWAPGS
-       xorl %ebx,%ebx
-  1:   ret
-
-If we are at an interrupt or user-trap/gate-alike boundary then we can
-use the faster check: the stack will be a reliable indicator of
-whether SWAPGS was already done: if we see that we are a secondary
-entry interrupting kernel mode execution, then we know that the GS
-base has already been switched. If it says that we interrupted
-user-space execution then we must do the SWAPGS.
-
-But if we are in an NMI/MCE/DEBUG/whatever super-atomic entry context,
-which might have triggered right after a normal entry wrote CS to the
-stack but before we executed SWAPGS, then the only safe way to check
-for GS is the slower method: the RDMSR.
-
-Therefore, super-atomic entries (except NMI, which is handled separately)
-must use idtentry with paranoid=1 to handle gsbase correctly.  This
-triggers three main behavior changes:
-
- - Interrupt entry will use the slower gsbase check.
- - Interrupt entry from user mode will switch off the IST stack.
- - Interrupt exit to kernel mode will not attempt to reschedule.
-
-We try to only use IST entries and the paranoid entry code for vectors
-that absolutely need the more expensive check for the GS base - and we
-generate all 'normal' entry points with the regular (faster) paranoid=0
-variant.
diff --git a/Documentation/x86/exception-tables.rst b/Documentation/x86/exception-tables.rst
deleted file mode 100644 (file)
index efde1fe..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-===============================
-Kernel level exception handling
-===============================
-
-Commentary by Joerg Pommnitz <joerg@raleigh.ibm.com>
-
-When a process runs in kernel mode, it often has to access user
-mode memory whose address has been passed by an untrusted program.
-To protect itself the kernel has to verify this address.
-
-In older versions of Linux this was done with the
-int verify_area(int type, const void * addr, unsigned long size)
-function (which has since been replaced by access_ok()).
-
-This function verified that the memory area starting at address
-'addr' and of size 'size' was accessible for the operation specified
-in type (read or write). To do this, verify_read had to look up the
-virtual memory area (vma) that contained the address addr. In the
-normal case (correctly working program), this test was successful.
-It only failed for a few buggy programs. In some kernel profiling
-tests, this normally unneeded verification used up a considerable
-amount of time.
-
-To overcome this situation, Linus decided to let the virtual memory
-hardware present in every Linux-capable CPU handle this test.
-
-How does this work?
-
-Whenever the kernel tries to access an address that is currently not
-accessible, the CPU generates a page fault exception and calls the
-page fault handler::
-
-  void exc_page_fault(struct pt_regs *regs, unsigned long error_code)
-
-in arch/x86/mm/fault.c. The parameters on the stack are set up by
-the low level assembly glue in arch/x86/entry/entry_32.S. The parameter
-regs is a pointer to the saved registers on the stack, error_code
-contains a reason code for the exception.
-
-exc_page_fault() first obtains the inaccessible address from the CPU
-control register CR2. If the address is within the virtual address
-space of the process, the fault probably occurred, because the page
-was not swapped in, write protected or something similar. However,
-we are interested in the other case: the address is not valid, there
-is no vma that contains this address. In this case, the kernel jumps
-to the bad_area label.
-
-There it uses the address of the instruction that caused the exception
-(i.e. regs->eip) to find an address where the execution can continue
-(fixup). If this search is successful, the fault handler modifies the
-return address (again regs->eip) and returns. The execution will
-continue at the address in fixup.
-
-Where does fixup point to?
-
-Since we jump to the contents of fixup, fixup obviously points
-to executable code. This code is hidden inside the user access macros.
-I have picked the get_user() macro defined in arch/x86/include/asm/uaccess.h
-as an example. The definition is somewhat hard to follow, so let's peek at
-the code generated by the preprocessor and the compiler. I selected
-the get_user() call in drivers/char/sysrq.c for a detailed examination.
-
-The original code in sysrq.c line 587::
-
-        get_user(c, buf);
-
-The preprocessor output (edited to become somewhat readable)::
-
-  (
-    {
-      long __gu_err = - 14 , __gu_val = 0;
-      const __typeof__(*( (  buf ) )) *__gu_addr = ((buf));
-      if (((((0 + current_set[0])->tss.segment) == 0x18 )  ||
-        (((sizeof(*(buf))) <= 0xC0000000UL) &&
-        ((unsigned long)(__gu_addr ) <= 0xC0000000UL - (sizeof(*(buf)))))))
-        do {
-          __gu_err  = 0;
-          switch ((sizeof(*(buf)))) {
-            case 1:
-              __asm__ __volatile__(
-                "1:      mov" "b" " %2,%" "b" "1\n"
-                "2:\n"
-                ".section .fixup,\"ax\"\n"
-                "3:      movl %3,%0\n"
-                "        xor" "b" " %" "b" "1,%" "b" "1\n"
-                "        jmp 2b\n"
-                ".section __ex_table,\"a\"\n"
-                "        .align 4\n"
-                "        .long 1b,3b\n"
-                ".text"        : "=r"(__gu_err), "=q" (__gu_val): "m"((*(struct __large_struct *)
-                              (   __gu_addr   )) ), "i"(- 14 ), "0"(  __gu_err  )) ;
-                break;
-            case 2:
-              __asm__ __volatile__(
-                "1:      mov" "w" " %2,%" "w" "1\n"
-                "2:\n"
-                ".section .fixup,\"ax\"\n"
-                "3:      movl %3,%0\n"
-                "        xor" "w" " %" "w" "1,%" "w" "1\n"
-                "        jmp 2b\n"
-                ".section __ex_table,\"a\"\n"
-                "        .align 4\n"
-                "        .long 1b,3b\n"
-                ".text"        : "=r"(__gu_err), "=r" (__gu_val) : "m"((*(struct __large_struct *)
-                              (   __gu_addr   )) ), "i"(- 14 ), "0"(  __gu_err  ));
-                break;
-            case 4:
-              __asm__ __volatile__(
-                "1:      mov" "l" " %2,%" "" "1\n"
-                "2:\n"
-                ".section .fixup,\"ax\"\n"
-                "3:      movl %3,%0\n"
-                "        xor" "l" " %" "" "1,%" "" "1\n"
-                "        jmp 2b\n"
-                ".section __ex_table,\"a\"\n"
-                "        .align 4\n"        "        .long 1b,3b\n"
-                ".text"        : "=r"(__gu_err), "=r" (__gu_val) : "m"((*(struct __large_struct *)
-                              (   __gu_addr   )) ), "i"(- 14 ), "0"(__gu_err));
-                break;
-            default:
-              (__gu_val) = __get_user_bad();
-          }
-        } while (0) ;
-      ((c)) = (__typeof__(*((buf))))__gu_val;
-      __gu_err;
-    }
-  );
-
-WOW! Black GCC/assembly magic. This is impossible to follow, so let's
-see what code gcc generates::
-
- >         xorl %edx,%edx
- >         movl current_set,%eax
- >         cmpl $24,788(%eax)
- >         je .L1424
- >         cmpl $-1073741825,64(%esp)
- >         ja .L1423
- > .L1424:
- >         movl %edx,%eax
- >         movl 64(%esp),%ebx
- > #APP
- > 1:      movb (%ebx),%dl                /* this is the actual user access */
- > 2:
- > .section .fixup,"ax"
- > 3:      movl $-14,%eax
- >         xorb %dl,%dl
- >         jmp 2b
- > .section __ex_table,"a"
- >         .align 4
- >         .long 1b,3b
- > .text
- > #NO_APP
- > .L1423:
- >         movzbl %dl,%esi
-
-The optimizer does a good job and gives us something we can actually
-understand. Can we? The actual user access is quite obvious. Thanks
-to the unified address space we can just access the address in user
-memory. But what does the .section stuff do?????
-
-To understand this we have to look at the final kernel::
-
- > objdump --section-headers vmlinux
- >
- > vmlinux:     file format elf32-i386
- >
- > Sections:
- > Idx Name          Size      VMA       LMA       File off  Algn
- >   0 .text         00098f40  c0100000  c0100000  00001000  2**4
- >                   CONTENTS, ALLOC, LOAD, READONLY, CODE
- >   1 .fixup        000016bc  c0198f40  c0198f40  00099f40  2**0
- >                   CONTENTS, ALLOC, LOAD, READONLY, CODE
- >   2 .rodata       0000f127  c019a5fc  c019a5fc  0009b5fc  2**2
- >                   CONTENTS, ALLOC, LOAD, READONLY, DATA
- >   3 __ex_table    000015c0  c01a9724  c01a9724  000aa724  2**2
- >                   CONTENTS, ALLOC, LOAD, READONLY, DATA
- >   4 .data         0000ea58  c01abcf0  c01abcf0  000abcf0  2**4
- >                   CONTENTS, ALLOC, LOAD, DATA
- >   5 .bss          00018e21  c01ba748  c01ba748  000ba748  2**2
- >                   ALLOC
- >   6 .comment      00000ec4  00000000  00000000  000ba748  2**0
- >                   CONTENTS, READONLY
- >   7 .note         00001068  00000ec4  00000ec4  000bb60c  2**0
- >                   CONTENTS, READONLY
-
-There are obviously 2 non standard ELF sections in the generated object
-file. But first we want to find out what happened to our code in the
-final kernel executable::
-
- > objdump --disassemble --section=.text vmlinux
- >
- > c017e785 <do_con_write+c1> xorl   %edx,%edx
- > c017e787 <do_con_write+c3> movl   0xc01c7bec,%eax
- > c017e78c <do_con_write+c8> cmpl   $0x18,0x314(%eax)
- > c017e793 <do_con_write+cf> je     c017e79f <do_con_write+db>
- > c017e795 <do_con_write+d1> cmpl   $0xbfffffff,0x40(%esp,1)
- > c017e79d <do_con_write+d9> ja     c017e7a7 <do_con_write+e3>
- > c017e79f <do_con_write+db> movl   %edx,%eax
- > c017e7a1 <do_con_write+dd> movl   0x40(%esp,1),%ebx
- > c017e7a5 <do_con_write+e1> movb   (%ebx),%dl
- > c017e7a7 <do_con_write+e3> movzbl %dl,%esi
-
-The whole user memory access is reduced to 10 x86 machine instructions.
-The instructions bracketed in the .section directives are no longer
-in the normal execution path. They are located in a different section
-of the executable file::
-
- > objdump --disassemble --section=.fixup vmlinux
- >
- > c0199ff5 <.fixup+10b5> movl   $0xfffffff2,%eax
- > c0199ffa <.fixup+10ba> xorb   %dl,%dl
- > c0199ffc <.fixup+10bc> jmp    c017e7a7 <do_con_write+e3>
-
-And finally::
-
- > objdump --full-contents --section=__ex_table vmlinux
- >
- >  c01aa7c4 93c017c0 e09f19c0 97c017c0 99c017c0  ................
- >  c01aa7d4 f6c217c0 e99f19c0 a5e717c0 f59f19c0  ................
- >  c01aa7e4 080a18c0 01a019c0 0a0a18c0 04a019c0  ................
-
-or in human readable byte order::
-
- >  c01aa7c4 c017c093 c0199fe0 c017c097 c017c099  ................
- >  c01aa7d4 c017c2f6 c0199fe9 c017e7a5 c0199ff5  ................
-                               ^^^^^^^^^^^^^^^^^
-                               this is the interesting part!
- >  c01aa7e4 c0180a08 c019a001 c0180a0a c019a004  ................
-
-What happened? The assembly directives::
-
-  .section .fixup,"ax"
-  .section __ex_table,"a"
-
-told the assembler to move the following code to the specified
-sections in the ELF object file. So the instructions::
-
-  3:      movl $-14,%eax
-          xorb %dl,%dl
-          jmp 2b
-
-ended up in the .fixup section of the object file and the addresses::
-
-        .long 1b,3b
-
-ended up in the __ex_table section of the object file. 1b and 3b
-are local labels. The local label 1b (1b stands for next label 1
-backward) is the address of the instruction that might fault, i.e.
-in our case the address of the label 1 is c017e7a5:
-the original assembly code: > 1:      movb (%ebx),%dl
-and linked in vmlinux     : > c017e7a5 <do_con_write+e1> movb   (%ebx),%dl
-
-The local label 3 (backwards again) is the address of the code to handle
-the fault, in our case the actual value is c0199ff5:
-the original assembly code: > 3:      movl $-14,%eax
-and linked in vmlinux     : > c0199ff5 <.fixup+10b5> movl   $0xfffffff2,%eax
-
-If the fixup was able to handle the exception, control flow may be returned
-to the instruction after the one that triggered the fault, ie. local label 2b.
-
-The assembly code::
-
- > .section __ex_table,"a"
- >         .align 4
- >         .long 1b,3b
-
-becomes the value pair::
-
- >  c01aa7d4 c017c2f6 c0199fe9 c017e7a5 c0199ff5  ................
-                               ^this is ^this is
-                               1b       3b
-
-c017e7a5,c0199ff5 in the exception table of the kernel.
-
-So, what actually happens if a fault from kernel mode with no suitable
-vma occurs?
-
-#. access to invalid address::
-
-    > c017e7a5 <do_con_write+e1> movb   (%ebx),%dl
-#. MMU generates exception
-#. CPU calls exc_page_fault()
-#. exc_page_fault() calls do_user_addr_fault()
-#. do_user_addr_fault() calls kernelmode_fixup_or_oops()
-#. kernelmode_fixup_or_oops() calls fixup_exception() (regs->eip == c017e7a5);
-#. fixup_exception() calls search_exception_tables()
-#. search_exception_tables() looks up the address c017e7a5 in the
-   exception table (i.e. the contents of the ELF section __ex_table)
-   and returns the address of the associated fault handle code c0199ff5.
-#. fixup_exception() modifies its own return address to point to the fault
-   handle code and returns.
-#. execution continues in the fault handling code.
-#. a) EAX becomes -EFAULT (== -14)
-   b) DL  becomes zero (the value we "read" from user space)
-   c) execution continues at local label 2 (address of the
-      instruction immediately after the faulting user access).
-
-The steps 8a to 8c in a certain way emulate the faulting instruction.
-
-That's it, mostly. If you look at our example, you might ask why
-we set EAX to -EFAULT in the exception handler code. Well, the
-get_user() macro actually returns a value: 0, if the user access was
-successful, -EFAULT on failure. Our original code did not test this
-return value, however the inline assembly code in get_user() tries to
-return -EFAULT. GCC selected EAX to return this value.
-
-NOTE:
-Due to the way that the exception table is built and needs to be ordered,
-only use exceptions for code in the .text section.  Any other section
-will cause the exception table to not be sorted correctly, and the
-exceptions will fail.
-
-Things changed when 64-bit support was added to x86 Linux. Rather than
-double the size of the exception table by expanding the two entries
-from 32-bits to 64 bits, a clever trick was used to store addresses
-as relative offsets from the table itself. The assembly code changed
-from::
-
-    .long 1b,3b
-  to:
-          .long (from) - .
-          .long (to) - .
-
-and the C-code that uses these values converts back to absolute addresses
-like this::
-
-       ex_insn_addr(const struct exception_table_entry *x)
-       {
-               return (unsigned long)&x->insn + x->insn;
-       }
-
-In v4.6 the exception table entry was expanded with a new field "handler".
-This is also 32-bits wide and contains a third relative function
-pointer which points to one of:
-
-1) ``int ex_handler_default(const struct exception_table_entry *fixup)``
-     This is legacy case that just jumps to the fixup code
-
-2) ``int ex_handler_fault(const struct exception_table_entry *fixup)``
-     This case provides the fault number of the trap that occurred at
-     entry->insn. It is used to distinguish page faults from machine
-     check.
-
-More functions can easily be added.
-
-CONFIG_BUILDTIME_TABLE_SORT allows the __ex_table section to be sorted post
-link of the kernel image, via a host utility scripts/sorttable. It will set the
-symbol main_extable_sort_needed to 0, avoiding sorting the __ex_table section
-at boot time. With the exception table sorted, at runtime when an exception
-occurs we can quickly lookup the __ex_table entry via binary search.
-
-This is not just a boot time optimization, some architectures require this
-table to be sorted in order to handle exceptions relatively early in the boot
-process. For example, i386 makes use of this form of exception handling before
-paging support is even enabled!
diff --git a/Documentation/x86/features.rst b/Documentation/x86/features.rst
deleted file mode 100644 (file)
index b663f15..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. kernel-feat:: $srctree/Documentation/features x86
diff --git a/Documentation/x86/i386/IO-APIC.rst b/Documentation/x86/i386/IO-APIC.rst
deleted file mode 100644 (file)
index ce4d8df..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=======
-IO-APIC
-=======
-
-:Author: Ingo Molnar <mingo@kernel.org>
-
-Most (all) Intel-MP compliant SMP boards have the so-called 'IO-APIC',
-which is an enhanced interrupt controller. It enables us to route
-hardware interrupts to multiple CPUs, or to CPU groups. Without an
-IO-APIC, interrupts from hardware will be delivered only to the
-CPU which boots the operating system (usually CPU#0).
-
-Linux supports all variants of compliant SMP boards, including ones with
-multiple IO-APICs. Multiple IO-APICs are used in high-end servers to
-distribute IRQ load further.
-
-There are (a few) known breakages in certain older boards, such bugs are
-usually worked around by the kernel. If your MP-compliant SMP board does
-not boot Linux, then consult the linux-smp mailing list archives first.
-
-If your box boots fine with enabled IO-APIC IRQs, then your
-/proc/interrupts will look like this one::
-
-  hell:~> cat /proc/interrupts
-             CPU0
-    0:    1360293    IO-APIC-edge  timer
-    1:          4    IO-APIC-edge  keyboard
-    2:          0          XT-PIC  cascade
-   13:          1          XT-PIC  fpu
-   14:       1448    IO-APIC-edge  ide0
-   16:      28232   IO-APIC-level  Intel EtherExpress Pro 10/100 Ethernet
-   17:      51304   IO-APIC-level  eth0
-  NMI:          0
-  ERR:          0
-  hell:~>
-
-Some interrupts are still listed as 'XT PIC', but this is not a problem;
-none of those IRQ sources is performance-critical.
-
-
-In the unlikely case that your board does not create a working mp-table,
-you can use the pirq= boot parameter to 'hand-construct' IRQ entries. This
-is non-trivial though and cannot be automated. One sample /etc/lilo.conf
-entry::
-
-       append="pirq=15,11,10"
-
-The actual numbers depend on your system, on your PCI cards and on their
-PCI slot position. Usually PCI slots are 'daisy chained' before they are
-connected to the PCI chipset IRQ routing facility (the incoming PIRQ1-4
-lines)::
-
-               ,-.        ,-.        ,-.        ,-.        ,-.
-     PIRQ4 ----| |-.    ,-| |-.    ,-| |-.    ,-| |--------| |
-               |S|  \  /  |S|  \  /  |S|  \  /  |S|        |S|
-     PIRQ3 ----|l|-. `/---|l|-. `/---|l|-. `/---|l|--------|l|
-               |o|  \/    |o|  \/    |o|  \/    |o|        |o|
-     PIRQ2 ----|t|-./`----|t|-./`----|t|-./`----|t|--------|t|
-               |1| /\     |2| /\     |3| /\     |4|        |5|
-     PIRQ1 ----| |-  `----| |-  `----| |-  `----| |--------| |
-               `-'        `-'        `-'        `-'        `-'
-
-Every PCI card emits a PCI IRQ, which can be INTA, INTB, INTC or INTD::
-
-                               ,-.
-                         INTD--| |
-                               |S|
-                         INTC--|l|
-                               |o|
-                         INTB--|t|
-                               |x|
-                         INTA--| |
-                               `-'
-
-These INTA-D PCI IRQs are always 'local to the card', their real meaning
-depends on which slot they are in. If you look at the daisy chaining diagram,
-a card in slot4, issuing INTA IRQ, it will end up as a signal on PIRQ4 of
-the PCI chipset. Most cards issue INTA, this creates optimal distribution
-between the PIRQ lines. (distributing IRQ sources properly is not a
-necessity, PCI IRQs can be shared at will, but it's a good for performance
-to have non shared interrupts). Slot5 should be used for videocards, they
-do not use interrupts normally, thus they are not daisy chained either.
-
-so if you have your SCSI card (IRQ11) in Slot1, Tulip card (IRQ9) in
-Slot2, then you'll have to specify this pirq= line::
-
-       append="pirq=11,9"
-
-the following script tries to figure out such a default pirq= line from
-your PCI configuration::
-
-       echo -n pirq=; echo `scanpci | grep T_L | cut -c56-` | sed 's/ /,/g'
-
-note that this script won't work if you have skipped a few slots or if your
-board does not do default daisy-chaining. (or the IO-APIC has the PIRQ pins
-connected in some strange way). E.g. if in the above case you have your SCSI
-card (IRQ11) in Slot3, and have Slot1 empty::
-
-       append="pirq=0,9,11"
-
-[value '0' is a generic 'placeholder', reserved for empty (or non-IRQ emitting)
-slots.]
-
-Generally, it's always possible to find out the correct pirq= settings, just
-permute all IRQ numbers properly ... it will take some time though. An
-'incorrect' pirq line will cause the booting process to hang, or a device
-won't function properly (e.g. if it's inserted as a module).
-
-If you have 2 PCI buses, then you can use up to 8 pirq values, although such
-boards tend to have a good configuration.
-
-Be prepared that it might happen that you need some strange pirq line::
-
-       append="pirq=0,0,0,0,0,0,9,11"
-
-Use smart trial-and-error techniques to find out the correct pirq line ...
-
-Good luck and mail to linux-smp@vger.kernel.org or
-linux-kernel@vger.kernel.org if you have any problems that are not covered
-by this document.
-
diff --git a/Documentation/x86/i386/index.rst b/Documentation/x86/i386/index.rst
deleted file mode 100644 (file)
index 8747cf5..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-============
-i386 Support
-============
-
-.. toctree::
-   :maxdepth: 2
-
-   IO-APIC
diff --git a/Documentation/x86/ifs.rst b/Documentation/x86/ifs.rst
deleted file mode 100644 (file)
index 97abb69..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-.. kernel-doc:: drivers/platform/x86/intel/ifs/ifs.h
diff --git a/Documentation/x86/index.rst b/Documentation/x86/index.rst
deleted file mode 100644 (file)
index c73d133..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-==========================
-x86-specific Documentation
-==========================
-
-.. toctree::
-   :maxdepth: 2
-   :numbered:
-
-   boot
-   booting-dt
-   cpuinfo
-   topology
-   exception-tables
-   kernel-stacks
-   entry_64
-   earlyprintk
-   orc-unwinder
-   zero-page
-   tlb
-   mtrr
-   pat
-   intel-hfi
-   iommu
-   intel_txt
-   amd-memory-encryption
-   amd_hsmp
-   tdx
-   pti
-   mds
-   microcode
-   resctrl
-   tsx_async_abort
-   buslock
-   usb-legacy-support
-   i386/index
-   x86_64/index
-   ifs
-   sva
-   sgx
-   features
-   elf_auxvec
-   xstate
diff --git a/Documentation/x86/intel-hfi.rst b/Documentation/x86/intel-hfi.rst
deleted file mode 100644 (file)
index 49dea58..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-============================================================
-Hardware-Feedback Interface for scheduling on Intel Hardware
-============================================================
-
-Overview
---------
-
-Intel has described the Hardware Feedback Interface (HFI) in the Intel 64 and
-IA-32 Architectures Software Developer's Manual (Intel SDM) Volume 3 Section
-14.6 [1]_.
-
-The HFI gives the operating system a performance and energy efficiency
-capability data for each CPU in the system. Linux can use the information from
-the HFI to influence task placement decisions.
-
-The Hardware Feedback Interface
--------------------------------
-
-The Hardware Feedback Interface provides to the operating system information
-about the performance and energy efficiency of each CPU in the system. Each
-capability is given as a unit-less quantity in the range [0-255]. Higher values
-indicate higher capability. Energy efficiency and performance are reported in
-separate capabilities. Even though on some systems these two metrics may be
-related, they are specified as independent capabilities in the Intel SDM.
-
-These capabilities may change at runtime as a result of changes in the
-operating conditions of the system or the action of external factors. The rate
-at which these capabilities are updated is specific to each processor model. On
-some models, capabilities are set at boot time and never change. On others,
-capabilities may change every tens of milliseconds. For instance, a remote
-mechanism may be used to lower Thermal Design Power. Such change can be
-reflected in the HFI. Likewise, if the system needs to be throttled due to
-excessive heat, the HFI may reflect reduced performance on specific CPUs.
-
-The kernel or a userspace policy daemon can use these capabilities to modify
-task placement decisions. For instance, if either the performance or energy
-capabilities of a given logical processor becomes zero, it is an indication that
-the hardware recommends to the operating system to not schedule any tasks on
-that processor for performance or energy efficiency reasons, respectively.
-
-Implementation details for Linux
---------------------------------
-
-The infrastructure to handle thermal event interrupts has two parts. In the
-Local Vector Table of a CPU's local APIC, there exists a register for the
-Thermal Monitor Register. This register controls how interrupts are delivered
-to a CPU when the thermal monitor generates and interrupt. Further details
-can be found in the Intel SDM Vol. 3 Section 10.5 [1]_.
-
-The thermal monitor may generate interrupts per CPU or per package. The HFI
-generates package-level interrupts. This monitor is configured and initialized
-via a set of machine-specific registers. Specifically, the HFI interrupt and
-status are controlled via designated bits in the IA32_PACKAGE_THERM_INTERRUPT
-and IA32_PACKAGE_THERM_STATUS registers, respectively. There exists one HFI
-table per package. Further details can be found in the Intel SDM Vol. 3
-Section 14.9 [1]_.
-
-The hardware issues an HFI interrupt after updating the HFI table and is ready
-for the operating system to consume it. CPUs receive such interrupt via the
-thermal entry in the Local APIC's Local Vector Table.
-
-When servicing such interrupt, the HFI driver parses the updated table and
-relays the update to userspace using the thermal notification framework. Given
-that there may be many HFI updates every second, the updates relayed to
-userspace are throttled at a rate of CONFIG_HZ jiffies.
-
-References
-----------
-
-.. [1] https://www.intel.com/sdm
diff --git a/Documentation/x86/intel_txt.rst b/Documentation/x86/intel_txt.rst
deleted file mode 100644 (file)
index d83c1a2..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-=====================
-Intel(R) TXT Overview
-=====================
-
-Intel's technology for safer computing, Intel(R) Trusted Execution
-Technology (Intel(R) TXT), defines platform-level enhancements that
-provide the building blocks for creating trusted platforms.
-
-Intel TXT was formerly known by the code name LaGrande Technology (LT).
-
-Intel TXT in Brief:
-
--  Provides dynamic root of trust for measurement (DRTM)
--  Data protection in case of improper shutdown
--  Measurement and verification of launched environment
-
-Intel TXT is part of the vPro(TM) brand and is also available some
-non-vPro systems.  It is currently available on desktop systems
-based on the Q35, X38, Q45, and Q43 Express chipsets (e.g. Dell
-Optiplex 755, HP dc7800, etc.) and mobile systems based on the GM45,
-PM45, and GS45 Express chipsets.
-
-For more information, see http://www.intel.com/technology/security/.
-This site also has a link to the Intel TXT MLE Developers Manual,
-which has been updated for the new released platforms.
-
-Intel TXT has been presented at various events over the past few
-years, some of which are:
-
-      - LinuxTAG 2008:
-          http://www.linuxtag.org/2008/en/conf/events/vp-donnerstag.html
-
-      - TRUST2008:
-          http://www.trust-conference.eu/downloads/Keynote-Speakers/
-          3_David-Grawrock_The-Front-Door-of-Trusted-Computing.pdf
-
-      - IDF, Shanghai:
-          http://www.prcidf.com.cn/index_en.html
-
-      - IDFs 2006, 2007
-         (I'm not sure if/where they are online)
-
-Trusted Boot Project Overview
-=============================
-
-Trusted Boot (tboot) is an open source, pre-kernel/VMM module that
-uses Intel TXT to perform a measured and verified launch of an OS
-kernel/VMM.
-
-It is hosted on SourceForge at http://sourceforge.net/projects/tboot.
-The mercurial source repo is available at http://www.bughost.org/
-repos.hg/tboot.hg.
-
-Tboot currently supports launching Xen (open source VMM/hypervisor
-w/ TXT support since v3.2), and now Linux kernels.
-
-
-Value Proposition for Linux or "Why should you care?"
-=====================================================
-
-While there are many products and technologies that attempt to
-measure or protect the integrity of a running kernel, they all
-assume the kernel is "good" to begin with.  The Integrity
-Measurement Architecture (IMA) and Linux Integrity Module interface
-are examples of such solutions.
-
-To get trust in the initial kernel without using Intel TXT, a
-static root of trust must be used.  This bases trust in BIOS
-starting at system reset and requires measurement of all code
-executed between system reset through the completion of the kernel
-boot as well as data objects used by that code.  In the case of a
-Linux kernel, this means all of BIOS, any option ROMs, the
-bootloader and the boot config.  In practice, this is a lot of
-code/data, much of which is subject to change from boot to boot
-(e.g. changing NICs may change option ROMs).  Without reference
-hashes, these measurement changes are difficult to assess or
-confirm as benign.  This process also does not provide DMA
-protection, memory configuration/alias checks and locks, crash
-protection, or policy support.
-
-By using the hardware-based root of trust that Intel TXT provides,
-many of these issues can be mitigated.  Specifically: many
-pre-launch components can be removed from the trust chain, DMA
-protection is provided to all launched components, a large number
-of platform configuration checks are performed and values locked,
-protection is provided for any data in the event of an improper
-shutdown, and there is support for policy-based execution/verification.
-This provides a more stable measurement and a higher assurance of
-system configuration and initial state than would be otherwise
-possible.  Since the tboot project is open source, source code for
-almost all parts of the trust chain is available (excepting SMM and
-Intel-provided firmware).
-
-How Does it Work?
-=================
-
--  Tboot is an executable that is launched by the bootloader as
-   the "kernel" (the binary the bootloader executes).
--  It performs all of the work necessary to determine if the
-   platform supports Intel TXT and, if so, executes the GETSEC[SENTER]
-   processor instruction that initiates the dynamic root of trust.
-
-   -  If tboot determines that the system does not support Intel TXT
-      or is not configured correctly (e.g. the SINIT AC Module was
-      incorrect), it will directly launch the kernel with no changes
-      to any state.
-   -  Tboot will output various information about its progress to the
-      terminal, serial port, and/or an in-memory log; the output
-      locations can be configured with a command line switch.
-
--  The GETSEC[SENTER] instruction will return control to tboot and
-   tboot then verifies certain aspects of the environment (e.g. TPM NV
-   lock, e820 table does not have invalid entries, etc.).
--  It will wake the APs from the special sleep state the GETSEC[SENTER]
-   instruction had put them in and place them into a wait-for-SIPI
-   state.
-
-   -  Because the processors will not respond to an INIT or SIPI when
-      in the TXT environment, it is necessary to create a small VT-x
-      guest for the APs.  When they run in this guest, they will
-      simply wait for the INIT-SIPI-SIPI sequence, which will cause
-      VMEXITs, and then disable VT and jump to the SIPI vector.  This
-      approach seemed like a better choice than having to insert
-      special code into the kernel's MP wakeup sequence.
-
--  Tboot then applies an (optional) user-defined launch policy to
-   verify the kernel and initrd.
-
-   -  This policy is rooted in TPM NV and is described in the tboot
-      project.  The tboot project also contains code for tools to
-      create and provision the policy.
-   -  Policies are completely under user control and if not present
-      then any kernel will be launched.
-   -  Policy action is flexible and can include halting on failures
-      or simply logging them and continuing.
-
--  Tboot adjusts the e820 table provided by the bootloader to reserve
-   its own location in memory as well as to reserve certain other
-   TXT-related regions.
--  As part of its launch, tboot DMA protects all of RAM (using the
-   VT-d PMRs).  Thus, the kernel must be booted with 'intel_iommu=on'
-   in order to remove this blanket protection and use VT-d's
-   page-level protection.
--  Tboot will populate a shared page with some data about itself and
-   pass this to the Linux kernel as it transfers control.
-
-   -  The location of the shared page is passed via the boot_params
-      struct as a physical address.
-
--  The kernel will look for the tboot shared page address and, if it
-   exists, map it.
--  As one of the checks/protections provided by TXT, it makes a copy
-   of the VT-d DMARs in a DMA-protected region of memory and verifies
-   them for correctness.  The VT-d code will detect if the kernel was
-   launched with tboot and use this copy instead of the one in the
-   ACPI table.
--  At this point, tboot and TXT are out of the picture until a
-   shutdown (S<n>)
--  In order to put a system into any of the sleep states after a TXT
-   launch, TXT must first be exited.  This is to prevent attacks that
-   attempt to crash the system to gain control on reboot and steal
-   data left in memory.
-
-   -  The kernel will perform all of its sleep preparation and
-      populate the shared page with the ACPI data needed to put the
-      platform in the desired sleep state.
-   -  Then the kernel jumps into tboot via the vector specified in the
-      shared page.
-   -  Tboot will clean up the environment and disable TXT, then use the
-      kernel-provided ACPI information to actually place the platform
-      into the desired sleep state.
-   -  In the case of S3, tboot will also register itself as the resume
-      vector.  This is necessary because it must re-establish the
-      measured environment upon resume.  Once the TXT environment
-      has been restored, it will restore the TPM PCRs and then
-      transfer control back to the kernel's S3 resume vector.
-      In order to preserve system integrity across S3, the kernel
-      provides tboot with a set of memory ranges (RAM and RESERVED_KERN
-      in the e820 table, but not any memory that BIOS might alter over
-      the S3 transition) that tboot will calculate a MAC (message
-      authentication code) over and then seal with the TPM. On resume
-      and once the measured environment has been re-established, tboot
-      will re-calculate the MAC and verify it against the sealed value.
-      Tboot's policy determines what happens if the verification fails.
-      Note that the c/s 194 of tboot which has the new MAC code supports
-      this.
-
-That's pretty much it for TXT support.
-
-
-Configuring the System
-======================
-
-This code works with 32bit, 32bit PAE, and 64bit (x86_64) kernels.
-
-In BIOS, the user must enable:  TPM, TXT, VT-x, VT-d.  Not all BIOSes
-allow these to be individually enabled/disabled and the screens in
-which to find them are BIOS-specific.
-
-grub.conf needs to be modified as follows::
-
-        title Linux 2.6.29-tip w/ tboot
-          root (hd0,0)
-                kernel /tboot.gz logging=serial,vga,memory
-                module /vmlinuz-2.6.29-tip intel_iommu=on ro
-                       root=LABEL=/ rhgb console=ttyS0,115200 3
-                module /initrd-2.6.29-tip.img
-                module /Q35_SINIT_17.BIN
-
-The kernel option for enabling Intel TXT support is found under the
-Security top-level menu and is called "Enable Intel(R) Trusted
-Execution Technology (TXT)".  It is considered EXPERIMENTAL and
-depends on the generic x86 support (to allow maximum flexibility in
-kernel build options), since the tboot code will detect whether the
-platform actually supports Intel TXT and thus whether any of the
-kernel code is executed.
-
-The Q35_SINIT_17.BIN file is what Intel TXT refers to as an
-Authenticated Code Module.  It is specific to the chipset in the
-system and can also be found on the Trusted Boot site.  It is an
-(unencrypted) module signed by Intel that is used as part of the
-DRTM process to verify and configure the system.  It is signed
-because it operates at a higher privilege level in the system than
-any other macrocode and its correct operation is critical to the
-establishment of the DRTM.  The process for determining the correct
-SINIT ACM for a system is documented in the SINIT-guide.txt file
-that is on the tboot SourceForge site under the SINIT ACM downloads.
diff --git a/Documentation/x86/iommu.rst b/Documentation/x86/iommu.rst
deleted file mode 100644 (file)
index 42c7a6f..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-=================
-x86 IOMMU Support
-=================
-
-The architecture specs can be obtained from the below locations.
-
-- Intel: http://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/vt-directed-io-spec.pdf
-- AMD: https://www.amd.com/system/files/TechDocs/48882_IOMMU.pdf
-
-This guide gives a quick cheat sheet for some basic understanding.
-
-Basic stuff
------------
-
-ACPI enumerates and lists the different IOMMUs on the platform, and
-device scope relationships between devices and which IOMMU controls
-them.
-
-Some ACPI Keywords:
-
-- DMAR - Intel DMA Remapping table
-- DRHD - Intel DMA Remapping Hardware Unit Definition
-- RMRR - Intel Reserved Memory Region Reporting Structure
-- IVRS - AMD I/O Virtualization Reporting Structure
-- IVDB - AMD I/O Virtualization Definition Block
-- IVHD - AMD I/O Virtualization Hardware Definition
-
-What is Intel RMRR?
-^^^^^^^^^^^^^^^^^^^
-
-There are some devices the BIOS controls, for e.g USB devices to perform
-PS2 emulation. The regions of memory used for these devices are marked
-reserved in the e820 map. When we turn on DMA translation, DMA to those
-regions will fail. Hence BIOS uses RMRR to specify these regions along with
-devices that need to access these regions. OS is expected to setup
-unity mappings for these regions for these devices to access these regions.
-
-What is AMD IVRS?
-^^^^^^^^^^^^^^^^^
-
-The architecture defines an ACPI-compatible data structure called an I/O
-Virtualization Reporting Structure (IVRS) that is used to convey information
-related to I/O virtualization to system software.  The IVRS describes the
-configuration and capabilities of the IOMMUs contained in the platform as
-well as information about the devices that each IOMMU virtualizes.
-
-The IVRS provides information about the following:
-
-- IOMMUs present in the platform including their capabilities and proper configuration
-- System I/O topology relevant to each IOMMU
-- Peripheral devices that cannot be otherwise enumerated
-- Memory regions used by SMI/SMM, platform firmware, and platform hardware. These are generally exclusion ranges to be configured by system software.
-
-How is an I/O Virtual Address (IOVA) generated?
------------------------------------------------
-
-Well behaved drivers call dma_map_*() calls before sending command to device
-that needs to perform DMA. Once DMA is completed and mapping is no longer
-required, driver performs dma_unmap_*() calls to unmap the region.
-
-Intel Specific Notes
---------------------
-
-Graphics Problems?
-^^^^^^^^^^^^^^^^^^
-
-If you encounter issues with graphics devices, you can try adding
-option intel_iommu=igfx_off to turn off the integrated graphics engine.
-If this fixes anything, please ensure you file a bug reporting the problem.
-
-Some exceptions to IOVA
-^^^^^^^^^^^^^^^^^^^^^^^
-
-Interrupt ranges are not address translated, (0xfee00000 - 0xfeefffff).
-The same is true for peer to peer transactions. Hence we reserve the
-address from PCI MMIO ranges so they are not allocated for IOVA addresses.
-
-AMD Specific Notes
-------------------
-
-Graphics Problems?
-^^^^^^^^^^^^^^^^^^
-
-If you encounter issues with integrated graphics devices, you can try adding
-option iommu=pt to the kernel command line use a 1:1 mapping for the IOMMU.  If
-this fixes anything, please ensure you file a bug reporting the problem.
-
-Fault reporting
----------------
-When errors are reported, the IOMMU signals via an interrupt. The fault
-reason and device that caused it is printed on the console.
-
-
-Kernel Log Samples
-------------------
-
-Intel Boot Messages
-^^^^^^^^^^^^^^^^^^^
-
-Something like this gets printed indicating presence of DMAR tables
-in ACPI:
-
-::
-
-       ACPI: DMAR (v001 A M I  OEMDMAR  0x00000001 MSFT 0x00000097) @ 0x000000007f5b5ef0
-
-When DMAR is being processed and initialized by ACPI, prints DMAR locations
-and any RMRR's processed:
-
-::
-
-       ACPI DMAR:Host address width 36
-       ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed90000
-       ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed91000
-       ACPI DMAR:DRHD (flags: 0x00000001)base: 0x00000000fed93000
-       ACPI DMAR:RMRR base: 0x00000000000ed000 end: 0x00000000000effff
-       ACPI DMAR:RMRR base: 0x000000007f600000 end: 0x000000007fffffff
-
-When DMAR is enabled for use, you will notice:
-
-::
-
-       PCI-DMA: Using DMAR IOMMU
-
-Intel Fault reporting
-^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-       DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
-       DMAR:[fault reason 05] PTE Write access is not set
-       DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
-       DMAR:[fault reason 05] PTE Write access is not set
-
-AMD Boot Messages
-^^^^^^^^^^^^^^^^^
-
-Something like this gets printed indicating presence of the IOMMU:
-
-::
-
-       iommu: Default domain type: Translated
-       iommu: DMA domain TLB invalidation policy: lazy mode
-
-AMD Fault reporting
-^^^^^^^^^^^^^^^^^^^
-
-::
-
-       AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0007 address=0xffffc02000 flags=0x0000]
-       AMD-Vi: Event logged [IO_PAGE_FAULT device=07:00.0 domain=0x0007 address=0xffffc02000 flags=0x0000]
diff --git a/Documentation/x86/kernel-stacks.rst b/Documentation/x86/kernel-stacks.rst
deleted file mode 100644 (file)
index 6b0bcf0..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=============
-Kernel Stacks
-=============
-
-Kernel stacks on x86-64 bit
-===========================
-
-Most of the text from Keith Owens, hacked by AK
-
-x86_64 page size (PAGE_SIZE) is 4K.
-
-Like all other architectures, x86_64 has a kernel stack for every
-active thread.  These thread stacks are THREAD_SIZE (2*PAGE_SIZE) big.
-These stacks contain useful data as long as a thread is alive or a
-zombie. While the thread is in user space the kernel stack is empty
-except for the thread_info structure at the bottom.
-
-In addition to the per thread stacks, there are specialized stacks
-associated with each CPU.  These stacks are only used while the kernel
-is in control on that CPU; when a CPU returns to user space the
-specialized stacks contain no useful data.  The main CPU stacks are:
-
-* Interrupt stack.  IRQ_STACK_SIZE
-
-  Used for external hardware interrupts.  If this is the first external
-  hardware interrupt (i.e. not a nested hardware interrupt) then the
-  kernel switches from the current task to the interrupt stack.  Like
-  the split thread and interrupt stacks on i386, this gives more room
-  for kernel interrupt processing without having to increase the size
-  of every per thread stack.
-
-  The interrupt stack is also used when processing a softirq.
-
-Switching to the kernel interrupt stack is done by software based on a
-per CPU interrupt nest counter. This is needed because x86-64 "IST"
-hardware stacks cannot nest without races.
-
-x86_64 also has a feature which is not available on i386, the ability
-to automatically switch to a new stack for designated events such as
-double fault or NMI, which makes it easier to handle these unusual
-events on x86_64.  This feature is called the Interrupt Stack Table
-(IST).  There can be up to 7 IST entries per CPU. The IST code is an
-index into the Task State Segment (TSS). The IST entries in the TSS
-point to dedicated stacks; each stack can be a different size.
-
-An IST is selected by a non-zero value in the IST field of an
-interrupt-gate descriptor.  When an interrupt occurs and the hardware
-loads such a descriptor, the hardware automatically sets the new stack
-pointer based on the IST value, then invokes the interrupt handler.  If
-the interrupt came from user mode, then the interrupt handler prologue
-will switch back to the per-thread stack.  If software wants to allow
-nested IST interrupts then the handler must adjust the IST values on
-entry to and exit from the interrupt handler.  (This is occasionally
-done, e.g. for debug exceptions.)
-
-Events with different IST codes (i.e. with different stacks) can be
-nested.  For example, a debug interrupt can safely be interrupted by an
-NMI.  arch/x86_64/kernel/entry.S::paranoidentry adjusts the stack
-pointers on entry to and exit from all IST events, in theory allowing
-IST events with the same code to be nested.  However in most cases, the
-stack size allocated to an IST assumes no nesting for the same code.
-If that assumption is ever broken then the stacks will become corrupt.
-
-The currently assigned IST stacks are:
-
-* ESTACK_DF.  EXCEPTION_STKSZ (PAGE_SIZE).
-
-  Used for interrupt 8 - Double Fault Exception (#DF).
-
-  Invoked when handling one exception causes another exception. Happens
-  when the kernel is very confused (e.g. kernel stack pointer corrupt).
-  Using a separate stack allows the kernel to recover from it well enough
-  in many cases to still output an oops.
-
-* ESTACK_NMI.  EXCEPTION_STKSZ (PAGE_SIZE).
-
-  Used for non-maskable interrupts (NMI).
-
-  NMI can be delivered at any time, including when the kernel is in the
-  middle of switching stacks.  Using IST for NMI events avoids making
-  assumptions about the previous state of the kernel stack.
-
-* ESTACK_DB.  EXCEPTION_STKSZ (PAGE_SIZE).
-
-  Used for hardware debug interrupts (interrupt 1) and for software
-  debug interrupts (INT3).
-
-  When debugging a kernel, debug interrupts (both hardware and
-  software) can occur at any time.  Using IST for these interrupts
-  avoids making assumptions about the previous state of the kernel
-  stack.
-
-  To handle nested #DB correctly there exist two instances of DB stacks. On
-  #DB entry the IST stackpointer for #DB is switched to the second instance
-  so a nested #DB starts from a clean stack. The nested #DB switches
-  the IST stackpointer to a guard hole to catch triple nesting.
-
-* ESTACK_MCE.  EXCEPTION_STKSZ (PAGE_SIZE).
-
-  Used for interrupt 18 - Machine Check Exception (#MC).
-
-  MCE can be delivered at any time, including when the kernel is in the
-  middle of switching stacks.  Using IST for MCE events avoids making
-  assumptions about the previous state of the kernel stack.
-
-For more details see the Intel IA32 or AMD AMD64 architecture manuals.
-
-
-Printing backtraces on x86
-==========================
-
-The question about the '?' preceding function names in an x86 stacktrace
-keeps popping up, here's an indepth explanation. It helps if the reader
-stares at print_context_stack() and the whole machinery in and around
-arch/x86/kernel/dumpstack.c.
-
-Adapted from Ingo's mail, Message-ID: <20150521101614.GA10889@gmail.com>:
-
-We always scan the full kernel stack for return addresses stored on
-the kernel stack(s) [1]_, from stack top to stack bottom, and print out
-anything that 'looks like' a kernel text address.
-
-If it fits into the frame pointer chain, we print it without a question
-mark, knowing that it's part of the real backtrace.
-
-If the address does not fit into our expected frame pointer chain we
-still print it, but we print a '?'. It can mean two things:
-
- - either the address is not part of the call chain: it's just stale
-   values on the kernel stack, from earlier function calls. This is
-   the common case.
-
- - or it is part of the call chain, but the frame pointer was not set
-   up properly within the function, so we don't recognize it.
-
-This way we will always print out the real call chain (plus a few more
-entries), regardless of whether the frame pointer was set up correctly
-or not - but in most cases we'll get the call chain right as well. The
-entries printed are strictly in stack order, so you can deduce more
-information from that as well.
-
-The most important property of this method is that we _never_ lose
-information: we always strive to print _all_ addresses on the stack(s)
-that look like kernel text addresses, so if debug information is wrong,
-we still print out the real call chain as well - just with more question
-marks than ideal.
-
-.. [1] For things like IRQ and IST stacks, we also scan those stacks, in
-       the right order, and try to cross from one stack into another
-       reconstructing the call chain. This works most of the time.
diff --git a/Documentation/x86/mds.rst b/Documentation/x86/mds.rst
deleted file mode 100644 (file)
index 5d4330b..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-Microarchitectural Data Sampling (MDS) mitigation
-=================================================
-
-.. _mds:
-
-Overview
---------
-
-Microarchitectural Data Sampling (MDS) is a family of side channel attacks
-on internal buffers in Intel CPUs. The variants are:
-
- - Microarchitectural Store Buffer Data Sampling (MSBDS) (CVE-2018-12126)
- - Microarchitectural Fill Buffer Data Sampling (MFBDS) (CVE-2018-12130)
- - Microarchitectural Load Port Data Sampling (MLPDS) (CVE-2018-12127)
- - Microarchitectural Data Sampling Uncacheable Memory (MDSUM) (CVE-2019-11091)
-
-MSBDS leaks Store Buffer Entries which can be speculatively forwarded to a
-dependent load (store-to-load forwarding) as an optimization. The forward
-can also happen to a faulting or assisting load operation for a different
-memory address, which can be exploited under certain conditions. Store
-buffers are partitioned between Hyper-Threads so cross thread forwarding is
-not possible. But if a thread enters or exits a sleep state the store
-buffer is repartitioned which can expose data from one thread to the other.
-
-MFBDS leaks Fill Buffer Entries. Fill buffers are used internally to manage
-L1 miss situations and to hold data which is returned or sent in response
-to a memory or I/O operation. Fill buffers can forward data to a load
-operation and also write data to the cache. When the fill buffer is
-deallocated it can retain the stale data of the preceding operations which
-can then be forwarded to a faulting or assisting load operation, which can
-be exploited under certain conditions. Fill buffers are shared between
-Hyper-Threads so cross thread leakage is possible.
-
-MLPDS leaks Load Port Data. Load ports are used to perform load operations
-from memory or I/O. The received data is then forwarded to the register
-file or a subsequent operation. In some implementations the Load Port can
-contain stale data from a previous operation which can be forwarded to
-faulting or assisting loads under certain conditions, which again can be
-exploited eventually. Load ports are shared between Hyper-Threads so cross
-thread leakage is possible.
-
-MDSUM is a special case of MSBDS, MFBDS and MLPDS. An uncacheable load from
-memory that takes a fault or assist can leave data in a microarchitectural
-structure that may later be observed using one of the same methods used by
-MSBDS, MFBDS or MLPDS.
-
-Exposure assumptions
---------------------
-
-It is assumed that attack code resides in user space or in a guest with one
-exception. The rationale behind this assumption is that the code construct
-needed for exploiting MDS requires:
-
- - to control the load to trigger a fault or assist
-
- - to have a disclosure gadget which exposes the speculatively accessed
-   data for consumption through a side channel.
-
- - to control the pointer through which the disclosure gadget exposes the
-   data
-
-The existence of such a construct in the kernel cannot be excluded with
-100% certainty, but the complexity involved makes it extremly unlikely.
-
-There is one exception, which is untrusted BPF. The functionality of
-untrusted BPF is limited, but it needs to be thoroughly investigated
-whether it can be used to create such a construct.
-
-
-Mitigation strategy
--------------------
-
-All variants have the same mitigation strategy at least for the single CPU
-thread case (SMT off): Force the CPU to clear the affected buffers.
-
-This is achieved by using the otherwise unused and obsolete VERW
-instruction in combination with a microcode update. The microcode clears
-the affected CPU buffers when the VERW instruction is executed.
-
-For virtualization there are two ways to achieve CPU buffer
-clearing. Either the modified VERW instruction or via the L1D Flush
-command. The latter is issued when L1TF mitigation is enabled so the extra
-VERW can be avoided. If the CPU is not affected by L1TF then VERW needs to
-be issued.
-
-If the VERW instruction with the supplied segment selector argument is
-executed on a CPU without the microcode update there is no side effect
-other than a small number of pointlessly wasted CPU cycles.
-
-This does not protect against cross Hyper-Thread attacks except for MSBDS
-which is only exploitable cross Hyper-thread when one of the Hyper-Threads
-enters a C-state.
-
-The kernel provides a function to invoke the buffer clearing:
-
-    mds_clear_cpu_buffers()
-
-The mitigation is invoked on kernel/userspace, hypervisor/guest and C-state
-(idle) transitions.
-
-As a special quirk to address virtualization scenarios where the host has
-the microcode updated, but the hypervisor does not (yet) expose the
-MD_CLEAR CPUID bit to guests, the kernel issues the VERW instruction in the
-hope that it might actually clear the buffers. The state is reflected
-accordingly.
-
-According to current knowledge additional mitigations inside the kernel
-itself are not required because the necessary gadgets to expose the leaked
-data cannot be controlled in a way which allows exploitation from malicious
-user space or VM guests.
-
-Kernel internal mitigation modes
---------------------------------
-
- ======= ============================================================
- off      Mitigation is disabled. Either the CPU is not affected or
-          mds=off is supplied on the kernel command line
-
- full     Mitigation is enabled. CPU is affected and MD_CLEAR is
-          advertised in CPUID.
-
- vmwerv          Mitigation is enabled. CPU is affected and MD_CLEAR is not
-         advertised in CPUID. That is mainly for virtualization
-         scenarios where the host has the updated microcode but the
-         hypervisor does not expose MD_CLEAR in CPUID. It's a best
-         effort approach without guarantee.
- ======= ============================================================
-
-If the CPU is affected and mds=off is not supplied on the kernel command
-line then the kernel selects the appropriate mitigation mode depending on
-the availability of the MD_CLEAR CPUID bit.
-
-Mitigation points
------------------
-
-1. Return to user space
-^^^^^^^^^^^^^^^^^^^^^^^
-
-   When transitioning from kernel to user space the CPU buffers are flushed
-   on affected CPUs when the mitigation is not disabled on the kernel
-   command line. The migitation is enabled through the static key
-   mds_user_clear.
-
-   The mitigation is invoked in prepare_exit_to_usermode() which covers
-   all but one of the kernel to user space transitions.  The exception
-   is when we return from a Non Maskable Interrupt (NMI), which is
-   handled directly in do_nmi().
-
-   (The reason that NMI is special is that prepare_exit_to_usermode() can
-    enable IRQs.  In NMI context, NMIs are blocked, and we don't want to
-    enable IRQs with NMIs blocked.)
-
-
-2. C-State transition
-^^^^^^^^^^^^^^^^^^^^^
-
-   When a CPU goes idle and enters a C-State the CPU buffers need to be
-   cleared on affected CPUs when SMT is active. This addresses the
-   repartitioning of the store buffer when one of the Hyper-Threads enters
-   a C-State.
-
-   When SMT is inactive, i.e. either the CPU does not support it or all
-   sibling threads are offline CPU buffer clearing is not required.
-
-   The idle clearing is enabled on CPUs which are only affected by MSBDS
-   and not by any other MDS variant. The other MDS variants cannot be
-   protected against cross Hyper-Thread attacks because the Fill Buffer and
-   the Load Ports are shared. So on CPUs affected by other variants, the
-   idle clearing would be a window dressing exercise and is therefore not
-   activated.
-
-   The invocation is controlled by the static key mds_idle_clear which is
-   switched depending on the chosen mitigation mode and the SMT state of
-   the system.
-
-   The buffer clear is only invoked before entering the C-State to prevent
-   that stale data from the idling CPU from spilling to the Hyper-Thread
-   sibling after the store buffer got repartitioned and all entries are
-   available to the non idle sibling.
-
-   When coming out of idle the store buffer is partitioned again so each
-   sibling has half of it available. The back from idle CPU could be then
-   speculatively exposed to contents of the sibling. The buffers are
-   flushed either on exit to user space or on VMENTER so malicious code
-   in user space or the guest cannot speculatively access them.
-
-   The mitigation is hooked into all variants of halt()/mwait(), but does
-   not cover the legacy ACPI IO-Port mechanism because the ACPI idle driver
-   has been superseded by the intel_idle driver around 2010 and is
-   preferred on all affected CPUs which are expected to gain the MD_CLEAR
-   functionality in microcode. Aside of that the IO-Port mechanism is a
-   legacy interface which is only used on older systems which are either
-   not affected or do not receive microcode updates anymore.
diff --git a/Documentation/x86/microcode.rst b/Documentation/x86/microcode.rst
deleted file mode 100644 (file)
index b627c6f..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-==========================
-The Linux Microcode Loader
-==========================
-
-:Authors: - Fenghua Yu <fenghua.yu@intel.com>
-          - Borislav Petkov <bp@suse.de>
-         - Ashok Raj <ashok.raj@intel.com>
-
-The kernel has a x86 microcode loading facility which is supposed to
-provide microcode loading methods in the OS. Potential use cases are
-updating the microcode on platforms beyond the OEM End-Of-Life support,
-and updating the microcode on long-running systems without rebooting.
-
-The loader supports three loading methods:
-
-Early load microcode
-====================
-
-The kernel can update microcode very early during boot. Loading
-microcode early can fix CPU issues before they are observed during
-kernel boot time.
-
-The microcode is stored in an initrd file. During boot, it is read from
-it and loaded into the CPU cores.
-
-The format of the combined initrd image is microcode in (uncompressed)
-cpio format followed by the (possibly compressed) initrd image. The
-loader parses the combined initrd image during boot.
-
-The microcode files in cpio name space are:
-
-on Intel:
-  kernel/x86/microcode/GenuineIntel.bin
-on AMD  :
-  kernel/x86/microcode/AuthenticAMD.bin
-
-During BSP (BootStrapping Processor) boot (pre-SMP), the kernel
-scans the microcode file in the initrd. If microcode matching the
-CPU is found, it will be applied in the BSP and later on in all APs
-(Application Processors).
-
-The loader also saves the matching microcode for the CPU in memory.
-Thus, the cached microcode patch is applied when CPUs resume from a
-sleep state.
-
-Here's a crude example how to prepare an initrd with microcode (this is
-normally done automatically by the distribution, when recreating the
-initrd, so you don't really have to do it yourself. It is documented
-here for future reference only).
-::
-
-  #!/bin/bash
-
-  if [ -z "$1" ]; then
-      echo "You need to supply an initrd file"
-      exit 1
-  fi
-
-  INITRD="$1"
-
-  DSTDIR=kernel/x86/microcode
-  TMPDIR=/tmp/initrd
-
-  rm -rf $TMPDIR
-
-  mkdir $TMPDIR
-  cd $TMPDIR
-  mkdir -p $DSTDIR
-
-  if [ -d /lib/firmware/amd-ucode ]; then
-          cat /lib/firmware/amd-ucode/microcode_amd*.bin > $DSTDIR/AuthenticAMD.bin
-  fi
-
-  if [ -d /lib/firmware/intel-ucode ]; then
-          cat /lib/firmware/intel-ucode/* > $DSTDIR/GenuineIntel.bin
-  fi
-
-  find . | cpio -o -H newc >../ucode.cpio
-  cd ..
-  mv $INITRD $INITRD.orig
-  cat ucode.cpio $INITRD.orig > $INITRD
-
-  rm -rf $TMPDIR
-
-
-The system needs to have the microcode packages installed into
-/lib/firmware or you need to fixup the paths above if yours are
-somewhere else and/or you've downloaded them directly from the processor
-vendor's site.
-
-Late loading
-============
-
-You simply install the microcode packages your distro supplies and
-run::
-
-  # echo 1 > /sys/devices/system/cpu/microcode/reload
-
-as root.
-
-The loading mechanism looks for microcode blobs in
-/lib/firmware/{intel-ucode,amd-ucode}. The default distro installation
-packages already put them there.
-
-Since kernel 5.19, late loading is not enabled by default.
-
-The /dev/cpu/microcode method has been removed in 5.19.
-
-Why is late loading dangerous?
-==============================
-
-Synchronizing all CPUs
-----------------------
-
-The microcode engine which receives the microcode update is shared
-between the two logical threads in a SMT system. Therefore, when
-the update is executed on one SMT thread of the core, the sibling
-"automatically" gets the update.
-
-Since the microcode can "simulate" MSRs too, while the microcode update
-is in progress, those simulated MSRs transiently cease to exist. This
-can result in unpredictable results if the SMT sibling thread happens to
-be in the middle of an access to such an MSR. The usual observation is
-that such MSR accesses cause #GPs to be raised to signal that former are
-not present.
-
-The disappearing MSRs are just one common issue which is being observed.
-Any other instruction that's being patched and gets concurrently
-executed by the other SMT sibling, can also result in similar,
-unpredictable behavior.
-
-To eliminate this case, a stop_machine()-based CPU synchronization was
-introduced as a way to guarantee that all logical CPUs will not execute
-any code but just wait in a spin loop, polling an atomic variable.
-
-While this took care of device or external interrupts, IPIs including
-LVT ones, such as CMCI etc, it cannot address other special interrupts
-that can't be shut off. Those are Machine Check (#MC), System Management
-(#SMI) and Non-Maskable interrupts (#NMI).
-
-Machine Checks
---------------
-
-Machine Checks (#MC) are non-maskable. There are two kinds of MCEs.
-Fatal un-recoverable MCEs and recoverable MCEs. While un-recoverable
-errors are fatal, recoverable errors can also happen in kernel context
-are also treated as fatal by the kernel.
-
-On certain Intel machines, MCEs are also broadcast to all threads in a
-system. If one thread is in the middle of executing WRMSR, a MCE will be
-taken at the end of the flow. Either way, they will wait for the thread
-performing the wrmsr(0x79) to rendezvous in the MCE handler and shutdown
-eventually if any of the threads in the system fail to check in to the
-MCE rendezvous.
-
-To be paranoid and get predictable behavior, the OS can choose to set
-MCG_STATUS.MCIP. Since MCEs can be at most one in a system, if an
-MCE was signaled, the above condition will promote to a system reset
-automatically. OS can turn off MCIP at the end of the update for that
-core.
-
-System Management Interrupt
----------------------------
-
-SMIs are also broadcast to all CPUs in the platform. Microcode update
-requests exclusive access to the core before writing to MSR 0x79. So if
-it does happen such that, one thread is in WRMSR flow, and the 2nd got
-an SMI, that thread will be stopped in the first instruction in the SMI
-handler.
-
-Since the secondary thread is stopped in the first instruction in SMI,
-there is very little chance that it would be in the middle of executing
-an instruction being patched. Plus OS has no way to stop SMIs from
-happening.
-
-Non-Maskable Interrupts
------------------------
-
-When thread0 of a core is doing the microcode update, if thread1 is
-pulled into NMI, that can cause unpredictable behavior due to the
-reasons above.
-
-OS can choose a variety of methods to avoid running into this situation.
-
-
-Is the microcode suitable for late loading?
--------------------------------------------
-
-Late loading is done when the system is fully operational and running
-real workloads. Late loading behavior depends on what the base patch on
-the CPU is before upgrading to the new patch.
-
-This is true for Intel CPUs.
-
-Consider, for example, a CPU has patch level 1 and the update is to
-patch level 3.
-
-Between patch1 and patch3, patch2 might have deprecated a software-visible
-feature.
-
-This is unacceptable if software is even potentially using that feature.
-For instance, say MSR_X is no longer available after an update,
-accessing that MSR will cause a #GP fault.
-
-Basically there is no way to declare a new microcode update suitable
-for late-loading. This is another one of the problems that caused late
-loading to be not enabled by default.
-
-Builtin microcode
-=================
-
-The loader supports also loading of a builtin microcode supplied through
-the regular builtin firmware method CONFIG_EXTRA_FIRMWARE. Only 64-bit is
-currently supported.
-
-Here's an example::
-
-  CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin"
-  CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware"
-
-This basically means, you have the following tree structure locally::
-
-  /lib/firmware/
-  |-- amd-ucode
-  ...
-  |   |-- microcode_amd_fam15h.bin
-  ...
-  |-- intel-ucode
-  ...
-  |   |-- 06-3a-09
-  ...
-
-so that the build system can find those files and integrate them into
-the final kernel image. The early loader finds them and applies them.
-
-Needless to say, this method is not the most flexible one because it
-requires rebuilding the kernel each time updated microcode from the CPU
-vendor is available.
diff --git a/Documentation/x86/mtrr.rst b/Documentation/x86/mtrr.rst
deleted file mode 100644 (file)
index 9f0b185..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=========================================
-MTRR (Memory Type Range Register) control
-=========================================
-
-:Authors: - Richard Gooch <rgooch@atnf.csiro.au> - 3 Jun 1999
-          - Luis R. Rodriguez <mcgrof@do-not-panic.com> - April 9, 2015
-
-
-Phasing out MTRR use
-====================
-
-MTRR use is replaced on modern x86 hardware with PAT. Direct MTRR use by
-drivers on Linux is now completely phased out, device drivers should use
-arch_phys_wc_add() in combination with ioremap_wc() to make MTRR effective on
-non-PAT systems while a no-op but equally effective on PAT enabled systems.
-
-Even if Linux does not use MTRRs directly, some x86 platform firmware may still
-set up MTRRs early before booting the OS. They do this as some platform
-firmware may still have implemented access to MTRRs which would be controlled
-and handled by the platform firmware directly. An example of platform use of
-MTRRs is through the use of SMI handlers, one case could be for fan control,
-the platform code would need uncachable access to some of its fan control
-registers. Such platform access does not need any Operating System MTRR code in
-place other than mtrr_type_lookup() to ensure any OS specific mapping requests
-are aligned with platform MTRR setup. If MTRRs are only set up by the platform
-firmware code though and the OS does not make any specific MTRR mapping
-requests mtrr_type_lookup() should always return MTRR_TYPE_INVALID.
-
-For details refer to Documentation/x86/pat.rst.
-
-.. tip::
-  On Intel P6 family processors (Pentium Pro, Pentium II and later)
-  the Memory Type Range Registers (MTRRs) may be used to control
-  processor access to memory ranges. This is most useful when you have
-  a video (VGA) card on a PCI or AGP bus. Enabling write-combining
-  allows bus write transfers to be combined into a larger transfer
-  before bursting over the PCI/AGP bus. This can increase performance
-  of image write operations 2.5 times or more.
-
-  The Cyrix 6x86, 6x86MX and M II processors have Address Range
-  Registers (ARRs) which provide a similar functionality to MTRRs. For
-  these, the ARRs are used to emulate the MTRRs.
-
-  The AMD K6-2 (stepping 8 and above) and K6-3 processors have two
-  MTRRs. These are supported.  The AMD Athlon family provide 8 Intel
-  style MTRRs.
-
-  The Centaur C6 (WinChip) has 8 MCRs, allowing write-combining. These
-  are supported.
-
-  The VIA Cyrix III and VIA C3 CPUs offer 8 Intel style MTRRs.
-
-  The CONFIG_MTRR option creates a /proc/mtrr file which may be used
-  to manipulate your MTRRs. Typically the X server should use
-  this. This should have a reasonably generic interface so that
-  similar control registers on other processors can be easily
-  supported.
-
-There are two interfaces to /proc/mtrr: one is an ASCII interface
-which allows you to read and write. The other is an ioctl()
-interface. The ASCII interface is meant for administration. The
-ioctl() interface is meant for C programs (i.e. the X server). The
-interfaces are described below, with sample commands and C code.
-
-
-Reading MTRRs from the shell
-============================
-::
-
-  % cat /proc/mtrr
-  reg00: base=0x00000000 (   0MB), size= 128MB: write-back, count=1
-  reg01: base=0x08000000 ( 128MB), size=  64MB: write-back, count=1
-
-Creating MTRRs from the C-shell::
-
-  # echo "base=0xf8000000 size=0x400000 type=write-combining" >! /proc/mtrr
-
-or if you use bash::
-
-  # echo "base=0xf8000000 size=0x400000 type=write-combining" >| /proc/mtrr
-
-And the result thereof::
-
-  % cat /proc/mtrr
-  reg00: base=0x00000000 (   0MB), size= 128MB: write-back, count=1
-  reg01: base=0x08000000 ( 128MB), size=  64MB: write-back, count=1
-  reg02: base=0xf8000000 (3968MB), size=   4MB: write-combining, count=1
-
-This is for video RAM at base address 0xf8000000 and size 4 megabytes. To
-find out your base address, you need to look at the output of your X
-server, which tells you where the linear framebuffer address is. A
-typical line that you may get is::
-
-  (--) S3: PCI: 968 rev 0, Linear FB @ 0xf8000000
-
-Note that you should only use the value from the X server, as it may
-move the framebuffer base address, so the only value you can trust is
-that reported by the X server.
-
-To find out the size of your framebuffer (what, you don't actually
-know?), the following line will tell you::
-
-  (--) S3: videoram:  4096k
-
-That's 4 megabytes, which is 0x400000 bytes (in hexadecimal).
-A patch is being written for XFree86 which will make this automatic:
-in other words the X server will manipulate /proc/mtrr using the
-ioctl() interface, so users won't have to do anything. If you use a
-commercial X server, lobby your vendor to add support for MTRRs.
-
-
-Creating overlapping MTRRs
-==========================
-::
-
-  %echo "base=0xfb000000 size=0x1000000 type=write-combining" >/proc/mtrr
-  %echo "base=0xfb000000 size=0x1000 type=uncachable" >/proc/mtrr
-
-And the results::
-
-  % cat /proc/mtrr
-  reg00: base=0x00000000 (   0MB), size=  64MB: write-back, count=1
-  reg01: base=0xfb000000 (4016MB), size=  16MB: write-combining, count=1
-  reg02: base=0xfb000000 (4016MB), size=   4kB: uncachable, count=1
-
-Some cards (especially Voodoo Graphics boards) need this 4 kB area
-excluded from the beginning of the region because it is used for
-registers.
-
-NOTE: You can only create type=uncachable region, if the first
-region that you created is type=write-combining.
-
-
-Removing MTRRs from the C-shel
-==============================
-::
-
-  % echo "disable=2" >! /proc/mtrr
-
-or using bash::
-
-  % echo "disable=2" >| /proc/mtrr
-
-
-Reading MTRRs from a C program using ioctl()'s
-==============================================
-::
-
-  /*  mtrr-show.c
-
-      Source file for mtrr-show (example program to show MTRRs using ioctl()'s)
-
-      Copyright (C) 1997-1998  Richard Gooch
-
-      This program is free software; you can redistribute it and/or modify
-      it under the terms of the GNU General Public License as published by
-      the Free Software Foundation; either version 2 of the License, or
-      (at your option) any later version.
-
-      This program is distributed in the hope that it will be useful,
-      but WITHOUT ANY WARRANTY; without even the implied warranty of
-      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-      GNU General Public License for more details.
-
-      You should have received a copy of the GNU General Public License
-      along with this program; if not, write to the Free Software
-      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-      Richard Gooch may be reached by email at  rgooch@atnf.csiro.au
-      The postal address is:
-        Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
-  */
-
-  /*
-      This program will use an ioctl() on /proc/mtrr to show the current MTRR
-      settings. This is an alternative to reading /proc/mtrr.
-
-
-      Written by      Richard Gooch   17-DEC-1997
-
-      Last updated by Richard Gooch   2-MAY-1998
-
-
-  */
-  #include <stdio.h>
-  #include <stdlib.h>
-  #include <string.h>
-  #include <sys/types.h>
-  #include <sys/stat.h>
-  #include <fcntl.h>
-  #include <sys/ioctl.h>
-  #include <errno.h>
-  #include <asm/mtrr.h>
-
-  #define TRUE 1
-  #define FALSE 0
-  #define ERRSTRING strerror (errno)
-
-  static char *mtrr_strings[MTRR_NUM_TYPES] =
-  {
-      "uncachable",               /* 0 */
-      "write-combining",          /* 1 */
-      "?",                        /* 2 */
-      "?",                        /* 3 */
-      "write-through",            /* 4 */
-      "write-protect",            /* 5 */
-      "write-back",               /* 6 */
-  };
-
-  int main ()
-  {
-      int fd;
-      struct mtrr_gentry gentry;
-
-      if ( ( fd = open ("/proc/mtrr", O_RDONLY, 0) ) == -1 )
-      {
-    if (errno == ENOENT)
-    {
-        fputs ("/proc/mtrr not found: not supported or you don't have a PPro?\n",
-        stderr);
-        exit (1);
-    }
-    fprintf (stderr, "Error opening /proc/mtrr\t%s\n", ERRSTRING);
-    exit (2);
-      }
-      for (gentry.regnum = 0; ioctl (fd, MTRRIOC_GET_ENTRY, &gentry) == 0;
-    ++gentry.regnum)
-      {
-    if (gentry.size < 1)
-    {
-        fprintf (stderr, "Register: %u disabled\n", gentry.regnum);
-        continue;
-    }
-    fprintf (stderr, "Register: %u base: 0x%lx size: 0x%lx type: %s\n",
-      gentry.regnum, gentry.base, gentry.size,
-      mtrr_strings[gentry.type]);
-      }
-      if (errno == EINVAL) exit (0);
-      fprintf (stderr, "Error doing ioctl(2) on /dev/mtrr\t%s\n", ERRSTRING);
-      exit (3);
-  }   /*  End Function main  */
-
-
-Creating MTRRs from a C programme using ioctl()'s
-=================================================
-::
-
-  /*  mtrr-add.c
-
-      Source file for mtrr-add (example programme to add an MTRRs using ioctl())
-
-      Copyright (C) 1997-1998  Richard Gooch
-
-      This program is free software; you can redistribute it and/or modify
-      it under the terms of the GNU General Public License as published by
-      the Free Software Foundation; either version 2 of the License, or
-      (at your option) any later version.
-
-      This program is distributed in the hope that it will be useful,
-      but WITHOUT ANY WARRANTY; without even the implied warranty of
-      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-      GNU General Public License for more details.
-
-      You should have received a copy of the GNU General Public License
-      along with this program; if not, write to the Free Software
-      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-      Richard Gooch may be reached by email at  rgooch@atnf.csiro.au
-      The postal address is:
-        Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
-  */
-
-  /*
-      This programme will use an ioctl() on /proc/mtrr to add an entry. The first
-      available mtrr is used. This is an alternative to writing /proc/mtrr.
-
-
-      Written by      Richard Gooch   17-DEC-1997
-
-      Last updated by Richard Gooch   2-MAY-1998
-
-
-  */
-  #include <stdio.h>
-  #include <string.h>
-  #include <stdlib.h>
-  #include <unistd.h>
-  #include <sys/types.h>
-  #include <sys/stat.h>
-  #include <fcntl.h>
-  #include <sys/ioctl.h>
-  #include <errno.h>
-  #include <asm/mtrr.h>
-
-  #define TRUE 1
-  #define FALSE 0
-  #define ERRSTRING strerror (errno)
-
-  static char *mtrr_strings[MTRR_NUM_TYPES] =
-  {
-      "uncachable",               /* 0 */
-      "write-combining",          /* 1 */
-      "?",                        /* 2 */
-      "?",                        /* 3 */
-      "write-through",            /* 4 */
-      "write-protect",            /* 5 */
-      "write-back",               /* 6 */
-  };
-
-  int main (int argc, char **argv)
-  {
-      int fd;
-      struct mtrr_sentry sentry;
-
-      if (argc != 4)
-      {
-    fprintf (stderr, "Usage:\tmtrr-add base size type\n");
-    exit (1);
-      }
-      sentry.base = strtoul (argv[1], NULL, 0);
-      sentry.size = strtoul (argv[2], NULL, 0);
-      for (sentry.type = 0; sentry.type < MTRR_NUM_TYPES; ++sentry.type)
-      {
-    if (strcmp (argv[3], mtrr_strings[sentry.type]) == 0) break;
-      }
-      if (sentry.type >= MTRR_NUM_TYPES)
-      {
-    fprintf (stderr, "Illegal type: \"%s\"\n", argv[3]);
-    exit (2);
-      }
-      if ( ( fd = open ("/proc/mtrr", O_WRONLY, 0) ) == -1 )
-      {
-    if (errno == ENOENT)
-    {
-        fputs ("/proc/mtrr not found: not supported or you don't have a PPro?\n",
-        stderr);
-        exit (3);
-    }
-    fprintf (stderr, "Error opening /proc/mtrr\t%s\n", ERRSTRING);
-    exit (4);
-      }
-      if (ioctl (fd, MTRRIOC_ADD_ENTRY, &sentry) == -1)
-      {
-    fprintf (stderr, "Error doing ioctl(2) on /dev/mtrr\t%s\n", ERRSTRING);
-    exit (5);
-      }
-      fprintf (stderr, "Sleeping for 5 seconds so you can see the new entry\n");
-      sleep (5);
-      close (fd);
-      fputs ("I've just closed /proc/mtrr so now the new entry should be gone\n",
-      stderr);
-  }   /*  End Function main  */
diff --git a/Documentation/x86/orc-unwinder.rst b/Documentation/x86/orc-unwinder.rst
deleted file mode 100644 (file)
index cdb2570..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-============
-ORC unwinder
-============
-
-Overview
-========
-
-The kernel CONFIG_UNWINDER_ORC option enables the ORC unwinder, which is
-similar in concept to a DWARF unwinder.  The difference is that the
-format of the ORC data is much simpler than DWARF, which in turn allows
-the ORC unwinder to be much simpler and faster.
-
-The ORC data consists of unwind tables which are generated by objtool.
-They contain out-of-band data which is used by the in-kernel ORC
-unwinder.  Objtool generates the ORC data by first doing compile-time
-stack metadata validation (CONFIG_STACK_VALIDATION).  After analyzing
-all the code paths of a .o file, it determines information about the
-stack state at each instruction address in the file and outputs that
-information to the .orc_unwind and .orc_unwind_ip sections.
-
-The per-object ORC sections are combined at link time and are sorted and
-post-processed at boot time.  The unwinder uses the resulting data to
-correlate instruction addresses with their stack states at run time.
-
-
-ORC vs frame pointers
-=====================
-
-With frame pointers enabled, GCC adds instrumentation code to every
-function in the kernel.  The kernel's .text size increases by about
-3.2%, resulting in a broad kernel-wide slowdown.  Measurements by Mel
-Gorman [1]_ have shown a slowdown of 5-10% for some workloads.
-
-In contrast, the ORC unwinder has no effect on text size or runtime
-performance, because the debuginfo is out of band.  So if you disable
-frame pointers and enable the ORC unwinder, you get a nice performance
-improvement across the board, and still have reliable stack traces.
-
-Ingo Molnar says:
-
-  "Note that it's not just a performance improvement, but also an
-  instruction cache locality improvement: 3.2% .text savings almost
-  directly transform into a similarly sized reduction in cache
-  footprint. That can transform to even higher speedups for workloads
-  whose cache locality is borderline."
-
-Another benefit of ORC compared to frame pointers is that it can
-reliably unwind across interrupts and exceptions.  Frame pointer based
-unwinds can sometimes skip the caller of the interrupted function, if it
-was a leaf function or if the interrupt hit before the frame pointer was
-saved.
-
-The main disadvantage of the ORC unwinder compared to frame pointers is
-that it needs more memory to store the ORC unwind tables: roughly 2-4MB
-depending on the kernel config.
-
-
-ORC vs DWARF
-============
-
-ORC debuginfo's advantage over DWARF itself is that it's much simpler.
-It gets rid of the complex DWARF CFI state machine and also gets rid of
-the tracking of unnecessary registers.  This allows the unwinder to be
-much simpler, meaning fewer bugs, which is especially important for
-mission critical oops code.
-
-The simpler debuginfo format also enables the unwinder to be much faster
-than DWARF, which is important for perf and lockdep.  In a basic
-performance test by Jiri Slaby [2]_, the ORC unwinder was about 20x
-faster than an out-of-tree DWARF unwinder.  (Note: That measurement was
-taken before some performance tweaks were added, which doubled
-performance, so the speedup over DWARF may be closer to 40x.)
-
-The ORC data format does have a few downsides compared to DWARF.  ORC
-unwind tables take up ~50% more RAM (+1.3MB on an x86 defconfig kernel)
-than DWARF-based eh_frame tables.
-
-Another potential downside is that, as GCC evolves, it's conceivable
-that the ORC data may end up being *too* simple to describe the state of
-the stack for certain optimizations.  But IMO this is unlikely because
-GCC saves the frame pointer for any unusual stack adjustments it does,
-so I suspect we'll really only ever need to keep track of the stack
-pointer and the frame pointer between call frames.  But even if we do
-end up having to track all the registers DWARF tracks, at least we will
-still be able to control the format, e.g. no complex state machines.
-
-
-ORC unwind table generation
-===========================
-
-The ORC data is generated by objtool.  With the existing compile-time
-stack metadata validation feature, objtool already follows all code
-paths, and so it already has all the information it needs to be able to
-generate ORC data from scratch.  So it's an easy step to go from stack
-validation to ORC data generation.
-
-It should be possible to instead generate the ORC data with a simple
-tool which converts DWARF to ORC data.  However, such a solution would
-be incomplete due to the kernel's extensive use of asm, inline asm, and
-special sections like exception tables.
-
-That could be rectified by manually annotating those special code paths
-using GNU assembler .cfi annotations in .S files, and homegrown
-annotations for inline asm in .c files.  But asm annotations were tried
-in the past and were found to be unmaintainable.  They were often
-incorrect/incomplete and made the code harder to read and keep updated.
-And based on looking at glibc code, annotating inline asm in .c files
-might be even worse.
-
-Objtool still needs a few annotations, but only in code which does
-unusual things to the stack like entry code.  And even then, far fewer
-annotations are needed than what DWARF would need, so they're much more
-maintainable than DWARF CFI annotations.
-
-So the advantages of using objtool to generate ORC data are that it
-gives more accurate debuginfo, with very few annotations.  It also
-insulates the kernel from toolchain bugs which can be very painful to
-deal with in the kernel since we often have to workaround issues in
-older versions of the toolchain for years.
-
-The downside is that the unwinder now becomes dependent on objtool's
-ability to reverse engineer GCC code flow.  If GCC optimizations become
-too complicated for objtool to follow, the ORC data generation might
-stop working or become incomplete.  (It's worth noting that livepatch
-already has such a dependency on objtool's ability to follow GCC code
-flow.)
-
-If newer versions of GCC come up with some optimizations which break
-objtool, we may need to revisit the current implementation.  Some
-possible solutions would be asking GCC to make the optimizations more
-palatable, or having objtool use DWARF as an additional input, or
-creating a GCC plugin to assist objtool with its analysis.  But for now,
-objtool follows GCC code quite well.
-
-
-Unwinder implementation details
-===============================
-
-Objtool generates the ORC data by integrating with the compile-time
-stack metadata validation feature, which is described in detail in
-tools/objtool/Documentation/objtool.txt.  After analyzing all
-the code paths of a .o file, it creates an array of orc_entry structs,
-and a parallel array of instruction addresses associated with those
-structs, and writes them to the .orc_unwind and .orc_unwind_ip sections
-respectively.
-
-The ORC data is split into the two arrays for performance reasons, to
-make the searchable part of the data (.orc_unwind_ip) more compact.  The
-arrays are sorted in parallel at boot time.
-
-Performance is further improved by the use of a fast lookup table which
-is created at runtime.  The fast lookup table associates a given address
-with a range of indices for the .orc_unwind table, so that only a small
-subset of the table needs to be searched.
-
-
-Etymology
-=========
-
-Orcs, fearsome creatures of medieval folklore, are the Dwarves' natural
-enemies.  Similarly, the ORC unwinder was created in opposition to the
-complexity and slowness of DWARF.
-
-"Although Orcs rarely consider multiple solutions to a problem, they do
-excel at getting things done because they are creatures of action, not
-thought." [3]_  Similarly, unlike the esoteric DWARF unwinder, the
-veracious ORC unwinder wastes no time or siloconic effort decoding
-variable-length zero-extended unsigned-integer byte-coded
-state-machine-based debug information entries.
-
-Similar to how Orcs frequently unravel the well-intentioned plans of
-their adversaries, the ORC unwinder frequently unravels stacks with
-brutal, unyielding efficiency.
-
-ORC stands for Oops Rewind Capability.
-
-
-.. [1] https://lore.kernel.org/r/20170602104048.jkkzssljsompjdwy@suse.de
-.. [2] https://lore.kernel.org/r/d2ca5435-6386-29b8-db87-7f227c2b713a@suse.cz
-.. [3] http://dustin.wikidot.com/half-orcs-and-orcs
diff --git a/Documentation/x86/pat.rst b/Documentation/x86/pat.rst
deleted file mode 100644 (file)
index 5d90177..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-==========================
-PAT (Page Attribute Table)
-==========================
-
-x86 Page Attribute Table (PAT) allows for setting the memory attribute at the
-page level granularity. PAT is complementary to the MTRR settings which allows
-for setting of memory types over physical address ranges. However, PAT is
-more flexible than MTRR due to its capability to set attributes at page level
-and also due to the fact that there are no hardware limitations on number of
-such attribute settings allowed. Added flexibility comes with guidelines for
-not having memory type aliasing for the same physical memory with multiple
-virtual addresses.
-
-PAT allows for different types of memory attributes. The most commonly used
-ones that will be supported at this time are:
-
-===  ==============
-WB   Write-back
-UC   Uncached
-WC   Write-combined
-WT   Write-through
-UC-  Uncached Minus
-===  ==============
-
-
-PAT APIs
-========
-
-There are many different APIs in the kernel that allows setting of memory
-attributes at the page level. In order to avoid aliasing, these interfaces
-should be used thoughtfully. Below is a table of interfaces available,
-their intended usage and their memory attribute relationships. Internally,
-these APIs use a reserve_memtype()/free_memtype() interface on the physical
-address range to avoid any aliasing.
-
-+------------------------+----------+--------------+------------------+
-| API                    |    RAM   |  ACPI,...    |  Reserved/Holes  |
-+------------------------+----------+--------------+------------------+
-| ioremap                |    --    |    UC-       |       UC-        |
-+------------------------+----------+--------------+------------------+
-| ioremap_cache          |    --    |    WB        |       WB         |
-+------------------------+----------+--------------+------------------+
-| ioremap_uc             |    --    |    UC        |       UC         |
-+------------------------+----------+--------------+------------------+
-| ioremap_wc             |    --    |    --        |       WC         |
-+------------------------+----------+--------------+------------------+
-| ioremap_wt             |    --    |    --        |       WT         |
-+------------------------+----------+--------------+------------------+
-| set_memory_uc,         |    UC-   |    --        |       --         |
-| set_memory_wb          |          |              |                  |
-+------------------------+----------+--------------+------------------+
-| set_memory_wc,         |    WC    |    --        |       --         |
-| set_memory_wb          |          |              |                  |
-+------------------------+----------+--------------+------------------+
-| set_memory_wt,         |    WT    |    --        |       --         |
-| set_memory_wb          |          |              |                  |
-+------------------------+----------+--------------+------------------+
-| pci sysfs resource     |    --    |    --        |       UC-        |
-+------------------------+----------+--------------+------------------+
-| pci sysfs resource_wc  |    --    |    --        |       WC         |
-| is IORESOURCE_PREFETCH |          |              |                  |
-+------------------------+----------+--------------+------------------+
-| pci proc               |    --    |    --        |       UC-        |
-| !PCIIOC_WRITE_COMBINE  |          |              |                  |
-+------------------------+----------+--------------+------------------+
-| pci proc               |    --    |    --        |       WC         |
-| PCIIOC_WRITE_COMBINE   |          |              |                  |
-+------------------------+----------+--------------+------------------+
-| /dev/mem               |    --    |   WB/WC/UC-  |    WB/WC/UC-     |
-| read-write             |          |              |                  |
-+------------------------+----------+--------------+------------------+
-| /dev/mem               |    --    |    UC-       |       UC-        |
-| mmap SYNC flag         |          |              |                  |
-+------------------------+----------+--------------+------------------+
-| /dev/mem               |    --    |   WB/WC/UC-  |  WB/WC/UC-       |
-| mmap !SYNC flag        |          |              |                  |
-| and                    |          |(from existing|  (from existing  |
-| any alias to this area |          |alias)        |  alias)          |
-+------------------------+----------+--------------+------------------+
-| /dev/mem               |    --    |    WB        |       WB         |
-| mmap !SYNC flag        |          |              |                  |
-| no alias to this area  |          |              |                  |
-| and                    |          |              |                  |
-| MTRR says WB           |          |              |                  |
-+------------------------+----------+--------------+------------------+
-| /dev/mem               |    --    |    --        |       UC-        |
-| mmap !SYNC flag        |          |              |                  |
-| no alias to this area  |          |              |                  |
-| and                    |          |              |                  |
-| MTRR says !WB          |          |              |                  |
-+------------------------+----------+--------------+------------------+
-
-
-Advanced APIs for drivers
-=========================
-
-A. Exporting pages to users with remap_pfn_range, io_remap_pfn_range,
-vmf_insert_pfn.
-
-Drivers wanting to export some pages to userspace do it by using mmap
-interface and a combination of:
-
-  1) pgprot_noncached()
-  2) io_remap_pfn_range() or remap_pfn_range() or vmf_insert_pfn()
-
-With PAT support, a new API pgprot_writecombine is being added. So, drivers can
-continue to use the above sequence, with either pgprot_noncached() or
-pgprot_writecombine() in step 1, followed by step 2.
-
-In addition, step 2 internally tracks the region as UC or WC in memtype
-list in order to ensure no conflicting mapping.
-
-Note that this set of APIs only works with IO (non RAM) regions. If driver
-wants to export a RAM region, it has to do set_memory_uc() or set_memory_wc()
-as step 0 above and also track the usage of those pages and use set_memory_wb()
-before the page is freed to free pool.
-
-MTRR effects on PAT / non-PAT systems
-=====================================
-
-The following table provides the effects of using write-combining MTRRs when
-using ioremap*() calls on x86 for both non-PAT and PAT systems. Ideally
-mtrr_add() usage will be phased out in favor of arch_phys_wc_add() which will
-be a no-op on PAT enabled systems. The region over which a arch_phys_wc_add()
-is made, should already have been ioremapped with WC attributes or PAT entries,
-this can be done by using ioremap_wc() / set_memory_wc().  Devices which
-combine areas of IO memory desired to remain uncacheable with areas where
-write-combining is desirable should consider use of ioremap_uc() followed by
-set_memory_wc() to white-list effective write-combined areas.  Such use is
-nevertheless discouraged as the effective memory type is considered
-implementation defined, yet this strategy can be used as last resort on devices
-with size-constrained regions where otherwise MTRR write-combining would
-otherwise not be effective.
-::
-
-  ====  =======  ===  =========================  =====================
-  MTRR  Non-PAT  PAT  Linux ioremap value        Effective memory type
-  ====  =======  ===  =========================  =====================
-        PAT                                        Non-PAT |  PAT
-        |PCD                                               |
-        ||PWT                                              |
-        |||                                                |
-  WC    000      WB   _PAGE_CACHE_MODE_WB             WC   |   WC
-  WC    001      WC   _PAGE_CACHE_MODE_WC             WC*  |   WC
-  WC    010      UC-  _PAGE_CACHE_MODE_UC_MINUS       WC*  |   UC
-  WC    011      UC   _PAGE_CACHE_MODE_UC             UC   |   UC
-  ====  =======  ===  =========================  =====================
-
-  (*) denotes implementation defined and is discouraged
-
-.. note:: -- in the above table mean "Not suggested usage for the API". Some
-  of the --'s are strictly enforced by the kernel. Some others are not really
-  enforced today, but may be enforced in future.
-
-For ioremap and pci access through /sys or /proc - The actual type returned
-can be more restrictive, in case of any existing aliasing for that address.
-For example: If there is an existing uncached mapping, a new ioremap_wc can
-return uncached mapping in place of write-combine requested.
-
-set_memory_[uc|wc|wt] and set_memory_wb should be used in pairs, where driver
-will first make a region uc, wc or wt and switch it back to wb after use.
-
-Over time writes to /proc/mtrr will be deprecated in favor of using PAT based
-interfaces. Users writing to /proc/mtrr are suggested to use above interfaces.
-
-Drivers should use ioremap_[uc|wc] to access PCI BARs with [uc|wc] access
-types.
-
-Drivers should use set_memory_[uc|wc|wt] to set access type for RAM ranges.
-
-
-PAT debugging
-=============
-
-With CONFIG_DEBUG_FS enabled, PAT memtype list can be examined by::
-
-  # mount -t debugfs debugfs /sys/kernel/debug
-  # cat /sys/kernel/debug/x86/pat_memtype_list
-  PAT memtype list:
-  uncached-minus @ 0x7fadf000-0x7fae0000
-  uncached-minus @ 0x7fb19000-0x7fb1a000
-  uncached-minus @ 0x7fb1a000-0x7fb1b000
-  uncached-minus @ 0x7fb1b000-0x7fb1c000
-  uncached-minus @ 0x7fb1c000-0x7fb1d000
-  uncached-minus @ 0x7fb1d000-0x7fb1e000
-  uncached-minus @ 0x7fb1e000-0x7fb25000
-  uncached-minus @ 0x7fb25000-0x7fb26000
-  uncached-minus @ 0x7fb26000-0x7fb27000
-  uncached-minus @ 0x7fb27000-0x7fb28000
-  uncached-minus @ 0x7fb28000-0x7fb2e000
-  uncached-minus @ 0x7fb2e000-0x7fb2f000
-  uncached-minus @ 0x7fb2f000-0x7fb30000
-  uncached-minus @ 0x7fb31000-0x7fb32000
-  uncached-minus @ 0x80000000-0x90000000
-
-This list shows physical address ranges and various PAT settings used to
-access those physical address ranges.
-
-Another, more verbose way of getting PAT related debug messages is with
-"debugpat" boot parameter. With this parameter, various debug messages are
-printed to dmesg log.
-
-PAT Initialization
-==================
-
-The following table describes how PAT is initialized under various
-configurations. The PAT MSR must be updated by Linux in order to support WC
-and WT attributes. Otherwise, the PAT MSR has the value programmed in it
-by the firmware. Note, Xen enables WC attribute in the PAT MSR for guests.
-
- ==== ===== ==========================  =========  =======
- MTRR PAT   Call Sequence               PAT State  PAT MSR
- ==== ===== ==========================  =========  =======
- E    E     MTRR -> PAT init            Enabled    OS
- E    D     MTRR -> PAT init            Disabled    -
- D    E     MTRR -> PAT disable         Disabled   BIOS
- D    D     MTRR -> PAT disable         Disabled    -
- -    np/E  PAT  -> PAT disable         Disabled   BIOS
- -    np/D  PAT  -> PAT disable         Disabled    -
- E    !P/E  MTRR -> PAT init            Disabled   BIOS
- D    !P/E  MTRR -> PAT disable         Disabled   BIOS
- !M   !P/E  MTRR stub -> PAT disable    Disabled   BIOS
- ==== ===== ==========================  =========  =======
-
-  Legend
-
- ========= =======================================
- E         Feature enabled in CPU
- D        Feature disabled/unsupported in CPU
- np       "nopat" boot option specified
- !P       CONFIG_X86_PAT option unset
- !M       CONFIG_MTRR option unset
- Enabled   PAT state set to enabled
- Disabled  PAT state set to disabled
- OS        PAT initializes PAT MSR with OS setting
- BIOS      PAT keeps PAT MSR with BIOS setting
- ========= =======================================
-
diff --git a/Documentation/x86/pti.rst b/Documentation/x86/pti.rst
deleted file mode 100644 (file)
index 4b858a9..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-==========================
-Page Table Isolation (PTI)
-==========================
-
-Overview
-========
-
-Page Table Isolation (pti, previously known as KAISER [1]_) is a
-countermeasure against attacks on the shared user/kernel address
-space such as the "Meltdown" approach [2]_.
-
-To mitigate this class of attacks, we create an independent set of
-page tables for use only when running userspace applications.  When
-the kernel is entered via syscalls, interrupts or exceptions, the
-page tables are switched to the full "kernel" copy.  When the system
-switches back to user mode, the user copy is used again.
-
-The userspace page tables contain only a minimal amount of kernel
-data: only what is needed to enter/exit the kernel such as the
-entry/exit functions themselves and the interrupt descriptor table
-(IDT).  There are a few strictly unnecessary things that get mapped
-such as the first C function when entering an interrupt (see
-comments in pti.c).
-
-This approach helps to ensure that side-channel attacks leveraging
-the paging structures do not function when PTI is enabled.  It can be
-enabled by setting CONFIG_PAGE_TABLE_ISOLATION=y at compile time.
-Once enabled at compile-time, it can be disabled at boot with the
-'nopti' or 'pti=' kernel parameters (see kernel-parameters.txt).
-
-Page Table Management
-=====================
-
-When PTI is enabled, the kernel manages two sets of page tables.
-The first set is very similar to the single set which is present in
-kernels without PTI.  This includes a complete mapping of userspace
-that the kernel can use for things like copy_to_user().
-
-Although _complete_, the user portion of the kernel page tables is
-crippled by setting the NX bit in the top level.  This ensures
-that any missed kernel->user CR3 switch will immediately crash
-userspace upon executing its first instruction.
-
-The userspace page tables map only the kernel data needed to enter
-and exit the kernel.  This data is entirely contained in the 'struct
-cpu_entry_area' structure which is placed in the fixmap which gives
-each CPU's copy of the area a compile-time-fixed virtual address.
-
-For new userspace mappings, the kernel makes the entries in its
-page tables like normal.  The only difference is when the kernel
-makes entries in the top (PGD) level.  In addition to setting the
-entry in the main kernel PGD, a copy of the entry is made in the
-userspace page tables' PGD.
-
-This sharing at the PGD level also inherently shares all the lower
-layers of the page tables.  This leaves a single, shared set of
-userspace page tables to manage.  One PTE to lock, one set of
-accessed bits, dirty bits, etc...
-
-Overhead
-========
-
-Protection against side-channel attacks is important.  But,
-this protection comes at a cost:
-
-1. Increased Memory Use
-
-  a. Each process now needs an order-1 PGD instead of order-0.
-     (Consumes an additional 4k per process).
-  b. The 'cpu_entry_area' structure must be 2MB in size and 2MB
-     aligned so that it can be mapped by setting a single PMD
-     entry.  This consumes nearly 2MB of RAM once the kernel
-     is decompressed, but no space in the kernel image itself.
-
-2. Runtime Cost
-
-  a. CR3 manipulation to switch between the page table copies
-     must be done at interrupt, syscall, and exception entry
-     and exit (it can be skipped when the kernel is interrupted,
-     though.)  Moves to CR3 are on the order of a hundred
-     cycles, and are required at every entry and exit.
-  b. A "trampoline" must be used for SYSCALL entry.  This
-     trampoline depends on a smaller set of resources than the
-     non-PTI SYSCALL entry code, so requires mapping fewer
-     things into the userspace page tables.  The downside is
-     that stacks must be switched at entry time.
-  c. Global pages are disabled for all kernel structures not
-     mapped into both kernel and userspace page tables.  This
-     feature of the MMU allows different processes to share TLB
-     entries mapping the kernel.  Losing the feature means more
-     TLB misses after a context switch.  The actual loss of
-     performance is very small, however, never exceeding 1%.
-  d. Process Context IDentifiers (PCID) is a CPU feature that
-     allows us to skip flushing the entire TLB when switching page
-     tables by setting a special bit in CR3 when the page tables
-     are changed.  This makes switching the page tables (at context
-     switch, or kernel entry/exit) cheaper.  But, on systems with
-     PCID support, the context switch code must flush both the user
-     and kernel entries out of the TLB.  The user PCID TLB flush is
-     deferred until the exit to userspace, minimizing the cost.
-     See intel.com/sdm for the gory PCID/INVPCID details.
-  e. The userspace page tables must be populated for each new
-     process.  Even without PTI, the shared kernel mappings
-     are created by copying top-level (PGD) entries into each
-     new process.  But, with PTI, there are now *two* kernel
-     mappings: one in the kernel page tables that maps everything
-     and one for the entry/exit structures.  At fork(), we need to
-     copy both.
-  f. In addition to the fork()-time copying, there must also
-     be an update to the userspace PGD any time a set_pgd() is done
-     on a PGD used to map userspace.  This ensures that the kernel
-     and userspace copies always map the same userspace
-     memory.
-  g. On systems without PCID support, each CR3 write flushes
-     the entire TLB.  That means that each syscall, interrupt
-     or exception flushes the TLB.
-  h. INVPCID is a TLB-flushing instruction which allows flushing
-     of TLB entries for non-current PCIDs.  Some systems support
-     PCIDs, but do not support INVPCID.  On these systems, addresses
-     can only be flushed from the TLB for the current PCID.  When
-     flushing a kernel address, we need to flush all PCIDs, so a
-     single kernel address flush will require a TLB-flushing CR3
-     write upon the next use of every PCID.
-
-Possible Future Work
-====================
-1. We can be more careful about not actually writing to CR3
-   unless its value is actually changed.
-2. Allow PTI to be enabled/disabled at runtime in addition to the
-   boot-time switching.
-
-Testing
-========
-
-To test stability of PTI, the following test procedure is recommended,
-ideally doing all of these in parallel:
-
-1. Set CONFIG_DEBUG_ENTRY=y
-2. Run several copies of all of the tools/testing/selftests/x86/ tests
-   (excluding MPX and protection_keys) in a loop on multiple CPUs for
-   several minutes.  These tests frequently uncover corner cases in the
-   kernel entry code.  In general, old kernels might cause these tests
-   themselves to crash, but they should never crash the kernel.
-3. Run the 'perf' tool in a mode (top or record) that generates many
-   frequent performance monitoring non-maskable interrupts (see "NMI"
-   in /proc/interrupts).  This exercises the NMI entry/exit code which
-   is known to trigger bugs in code paths that did not expect to be
-   interrupted, including nested NMIs.  Using "-c" boosts the rate of
-   NMIs, and using two -c with separate counters encourages nested NMIs
-   and less deterministic behavior.
-   ::
-
-       while true; do perf record -c 10000 -e instructions,cycles -a sleep 10; done
-
-4. Launch a KVM virtual machine.
-5. Run 32-bit binaries on systems supporting the SYSCALL instruction.
-   This has been a lightly-tested code path and needs extra scrutiny.
-
-Debugging
-=========
-
-Bugs in PTI cause a few different signatures of crashes
-that are worth noting here.
-
- * Failures of the selftests/x86 code.  Usually a bug in one of the
-   more obscure corners of entry_64.S
- * Crashes in early boot, especially around CPU bringup.  Bugs
-   in the trampoline code or mappings cause these.
- * Crashes at the first interrupt.  Caused by bugs in entry_64.S,
-   like screwing up a page table switch.  Also caused by
-   incorrectly mapping the IRQ handler entry code.
- * Crashes at the first NMI.  The NMI code is separate from main
-   interrupt handlers and can have bugs that do not affect
-   normal interrupts.  Also caused by incorrectly mapping NMI
-   code.  NMIs that interrupt the entry code must be very
-   careful and can be the cause of crashes that show up when
-   running perf.
- * Kernel crashes at the first exit to userspace.  entry_64.S
-   bugs, or failing to map some of the exit code.
- * Crashes at first interrupt that interrupts userspace. The paths
-   in entry_64.S that return to userspace are sometimes separate
-   from the ones that return to the kernel.
- * Double faults: overflowing the kernel stack because of page
-   faults upon page faults.  Caused by touching non-pti-mapped
-   data in the entry code, or forgetting to switch to kernel
-   CR3 before calling into C functions which are not pti-mapped.
- * Userspace segfaults early in boot, sometimes manifesting
-   as mount(8) failing to mount the rootfs.  These have
-   tended to be TLB invalidation issues.  Usually invalidating
-   the wrong PCID, or otherwise missing an invalidation.
-
-.. [1] https://gruss.cc/files/kaiser.pdf
-.. [2] https://meltdownattack.com/meltdown.pdf
diff --git a/Documentation/x86/resctrl.rst b/Documentation/x86/resctrl.rst
deleted file mode 100644 (file)
index 387ccbc..0000000
+++ /dev/null
@@ -1,1447 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-.. include:: <isonum.txt>
-
-===========================================
-User Interface for Resource Control feature
-===========================================
-
-:Copyright: |copy| 2016 Intel Corporation
-:Authors: - Fenghua Yu <fenghua.yu@intel.com>
-          - Tony Luck <tony.luck@intel.com>
-          - Vikas Shivappa <vikas.shivappa@intel.com>
-
-
-Intel refers to this feature as Intel Resource Director Technology(Intel(R) RDT).
-AMD refers to this feature as AMD Platform Quality of Service(AMD QoS).
-
-This feature is enabled by the CONFIG_X86_CPU_RESCTRL and the x86 /proc/cpuinfo
-flag bits:
-
-===============================================        ================================
-RDT (Resource Director Technology) Allocation  "rdt_a"
-CAT (Cache Allocation Technology)              "cat_l3", "cat_l2"
-CDP (Code and Data Prioritization)             "cdp_l3", "cdp_l2"
-CQM (Cache QoS Monitoring)                     "cqm_llc", "cqm_occup_llc"
-MBM (Memory Bandwidth Monitoring)              "cqm_mbm_total", "cqm_mbm_local"
-MBA (Memory Bandwidth Allocation)              "mba"
-SMBA (Slow Memory Bandwidth Allocation)         ""
-BMEC (Bandwidth Monitoring Event Configuration) ""
-===============================================        ================================
-
-Historically, new features were made visible by default in /proc/cpuinfo. This
-resulted in the feature flags becoming hard to parse by humans. Adding a new
-flag to /proc/cpuinfo should be avoided if user space can obtain information
-about the feature from resctrl's info directory.
-
-To use the feature mount the file system::
-
- # mount -t resctrl resctrl [-o cdp[,cdpl2][,mba_MBps]] /sys/fs/resctrl
-
-mount options are:
-
-"cdp":
-       Enable code/data prioritization in L3 cache allocations.
-"cdpl2":
-       Enable code/data prioritization in L2 cache allocations.
-"mba_MBps":
-       Enable the MBA Software Controller(mba_sc) to specify MBA
-       bandwidth in MBps
-
-L2 and L3 CDP are controlled separately.
-
-RDT features are orthogonal. A particular system may support only
-monitoring, only control, or both monitoring and control.  Cache
-pseudo-locking is a unique way of using cache control to "pin" or
-"lock" data in the cache. Details can be found in
-"Cache Pseudo-Locking".
-
-
-The mount succeeds if either of allocation or monitoring is present, but
-only those files and directories supported by the system will be created.
-For more details on the behavior of the interface during monitoring
-and allocation, see the "Resource alloc and monitor groups" section.
-
-Info directory
-==============
-
-The 'info' directory contains information about the enabled
-resources. Each resource has its own subdirectory. The subdirectory
-names reflect the resource names.
-
-Each subdirectory contains the following files with respect to
-allocation:
-
-Cache resource(L3/L2)  subdirectory contains the following files
-related to allocation:
-
-"num_closids":
-               The number of CLOSIDs which are valid for this
-               resource. The kernel uses the smallest number of
-               CLOSIDs of all enabled resources as limit.
-"cbm_mask":
-               The bitmask which is valid for this resource.
-               This mask is equivalent to 100%.
-"min_cbm_bits":
-               The minimum number of consecutive bits which
-               must be set when writing a mask.
-
-"shareable_bits":
-               Bitmask of shareable resource with other executing
-               entities (e.g. I/O). User can use this when
-               setting up exclusive cache partitions. Note that
-               some platforms support devices that have their
-               own settings for cache use which can over-ride
-               these bits.
-"bit_usage":
-               Annotated capacity bitmasks showing how all
-               instances of the resource are used. The legend is:
-
-                       "0":
-                             Corresponding region is unused. When the system's
-                             resources have been allocated and a "0" is found
-                             in "bit_usage" it is a sign that resources are
-                             wasted.
-
-                       "H":
-                             Corresponding region is used by hardware only
-                             but available for software use. If a resource
-                             has bits set in "shareable_bits" but not all
-                             of these bits appear in the resource groups'
-                             schematas then the bits appearing in
-                             "shareable_bits" but no resource group will
-                             be marked as "H".
-                       "X":
-                             Corresponding region is available for sharing and
-                             used by hardware and software. These are the
-                             bits that appear in "shareable_bits" as
-                             well as a resource group's allocation.
-                       "S":
-                             Corresponding region is used by software
-                             and available for sharing.
-                       "E":
-                             Corresponding region is used exclusively by
-                             one resource group. No sharing allowed.
-                       "P":
-                             Corresponding region is pseudo-locked. No
-                             sharing allowed.
-
-Memory bandwidth(MB) subdirectory contains the following files
-with respect to allocation:
-
-"min_bandwidth":
-               The minimum memory bandwidth percentage which
-               user can request.
-
-"bandwidth_gran":
-               The granularity in which the memory bandwidth
-               percentage is allocated. The allocated
-               b/w percentage is rounded off to the next
-               control step available on the hardware. The
-               available bandwidth control steps are:
-               min_bandwidth + N * bandwidth_gran.
-
-"delay_linear":
-               Indicates if the delay scale is linear or
-               non-linear. This field is purely informational
-               only.
-
-"thread_throttle_mode":
-               Indicator on Intel systems of how tasks running on threads
-               of a physical core are throttled in cases where they
-               request different memory bandwidth percentages:
-
-               "max":
-                       the smallest percentage is applied
-                       to all threads
-               "per-thread":
-                       bandwidth percentages are directly applied to
-                       the threads running on the core
-
-If RDT monitoring is available there will be an "L3_MON" directory
-with the following files:
-
-"num_rmids":
-               The number of RMIDs available. This is the
-               upper bound for how many "CTRL_MON" + "MON"
-               groups can be created.
-
-"mon_features":
-               Lists the monitoring events if
-               monitoring is enabled for the resource.
-               Example::
-
-                       # cat /sys/fs/resctrl/info/L3_MON/mon_features
-                       llc_occupancy
-                       mbm_total_bytes
-                       mbm_local_bytes
-
-               If the system supports Bandwidth Monitoring Event
-               Configuration (BMEC), then the bandwidth events will
-               be configurable. The output will be::
-
-                       # cat /sys/fs/resctrl/info/L3_MON/mon_features
-                       llc_occupancy
-                       mbm_total_bytes
-                       mbm_total_bytes_config
-                       mbm_local_bytes
-                       mbm_local_bytes_config
-
-"mbm_total_bytes_config", "mbm_local_bytes_config":
-       Read/write files containing the configuration for the mbm_total_bytes
-       and mbm_local_bytes events, respectively, when the Bandwidth
-       Monitoring Event Configuration (BMEC) feature is supported.
-       The event configuration settings are domain specific and affect
-       all the CPUs in the domain. When either event configuration is
-       changed, the bandwidth counters for all RMIDs of both events
-       (mbm_total_bytes as well as mbm_local_bytes) are cleared for that
-       domain. The next read for every RMID will report "Unavailable"
-       and subsequent reads will report the valid value.
-
-       Following are the types of events supported:
-
-       ====    ========================================================
-       Bits    Description
-       ====    ========================================================
-       6       Dirty Victims from the QOS domain to all types of memory
-       5       Reads to slow memory in the non-local NUMA domain
-       4       Reads to slow memory in the local NUMA domain
-       3       Non-temporal writes to non-local NUMA domain
-       2       Non-temporal writes to local NUMA domain
-       1       Reads to memory in the non-local NUMA domain
-       0       Reads to memory in the local NUMA domain
-       ====    ========================================================
-
-       By default, the mbm_total_bytes configuration is set to 0x7f to count
-       all the event types and the mbm_local_bytes configuration is set to
-       0x15 to count all the local memory events.
-
-       Examples:
-
-       * To view the current configuration::
-         ::
-
-           # cat /sys/fs/resctrl/info/L3_MON/mbm_total_bytes_config
-           0=0x7f;1=0x7f;2=0x7f;3=0x7f
-
-           # cat /sys/fs/resctrl/info/L3_MON/mbm_local_bytes_config
-           0=0x15;1=0x15;3=0x15;4=0x15
-
-       * To change the mbm_total_bytes to count only reads on domain 0,
-         the bits 0, 1, 4 and 5 needs to be set, which is 110011b in binary
-         (in hexadecimal 0x33):
-         ::
-
-           # echo  "0=0x33" > /sys/fs/resctrl/info/L3_MON/mbm_total_bytes_config
-
-           # cat /sys/fs/resctrl/info/L3_MON/mbm_total_bytes_config
-           0=0x33;1=0x7f;2=0x7f;3=0x7f
-
-       * To change the mbm_local_bytes to count all the slow memory reads on
-         domain 0 and 1, the bits 4 and 5 needs to be set, which is 110000b
-         in binary (in hexadecimal 0x30):
-         ::
-
-           # echo  "0=0x30;1=0x30" > /sys/fs/resctrl/info/L3_MON/mbm_local_bytes_config
-
-           # cat /sys/fs/resctrl/info/L3_MON/mbm_local_bytes_config
-           0=0x30;1=0x30;3=0x15;4=0x15
-
-"max_threshold_occupancy":
-               Read/write file provides the largest value (in
-               bytes) at which a previously used LLC_occupancy
-               counter can be considered for re-use.
-
-Finally, in the top level of the "info" directory there is a file
-named "last_cmd_status". This is reset with every "command" issued
-via the file system (making new directories or writing to any of the
-control files). If the command was successful, it will read as "ok".
-If the command failed, it will provide more information that can be
-conveyed in the error returns from file operations. E.g.
-::
-
-       # echo L3:0=f7 > schemata
-       bash: echo: write error: Invalid argument
-       # cat info/last_cmd_status
-       mask f7 has non-consecutive 1-bits
-
-Resource alloc and monitor groups
-=================================
-
-Resource groups are represented as directories in the resctrl file
-system.  The default group is the root directory which, immediately
-after mounting, owns all the tasks and cpus in the system and can make
-full use of all resources.
-
-On a system with RDT control features additional directories can be
-created in the root directory that specify different amounts of each
-resource (see "schemata" below). The root and these additional top level
-directories are referred to as "CTRL_MON" groups below.
-
-On a system with RDT monitoring the root directory and other top level
-directories contain a directory named "mon_groups" in which additional
-directories can be created to monitor subsets of tasks in the CTRL_MON
-group that is their ancestor. These are called "MON" groups in the rest
-of this document.
-
-Removing a directory will move all tasks and cpus owned by the group it
-represents to the parent. Removing one of the created CTRL_MON groups
-will automatically remove all MON groups below it.
-
-All groups contain the following files:
-
-"tasks":
-       Reading this file shows the list of all tasks that belong to
-       this group. Writing a task id to the file will add a task to the
-       group. If the group is a CTRL_MON group the task is removed from
-       whichever previous CTRL_MON group owned the task and also from
-       any MON group that owned the task. If the group is a MON group,
-       then the task must already belong to the CTRL_MON parent of this
-       group. The task is removed from any previous MON group.
-
-
-"cpus":
-       Reading this file shows a bitmask of the logical CPUs owned by
-       this group. Writing a mask to this file will add and remove
-       CPUs to/from this group. As with the tasks file a hierarchy is
-       maintained where MON groups may only include CPUs owned by the
-       parent CTRL_MON group.
-       When the resource group is in pseudo-locked mode this file will
-       only be readable, reflecting the CPUs associated with the
-       pseudo-locked region.
-
-
-"cpus_list":
-       Just like "cpus", only using ranges of CPUs instead of bitmasks.
-
-
-When control is enabled all CTRL_MON groups will also contain:
-
-"schemata":
-       A list of all the resources available to this group.
-       Each resource has its own line and format - see below for details.
-
-"size":
-       Mirrors the display of the "schemata" file to display the size in
-       bytes of each allocation instead of the bits representing the
-       allocation.
-
-"mode":
-       The "mode" of the resource group dictates the sharing of its
-       allocations. A "shareable" resource group allows sharing of its
-       allocations while an "exclusive" resource group does not. A
-       cache pseudo-locked region is created by first writing
-       "pseudo-locksetup" to the "mode" file before writing the cache
-       pseudo-locked region's schemata to the resource group's "schemata"
-       file. On successful pseudo-locked region creation the mode will
-       automatically change to "pseudo-locked".
-
-When monitoring is enabled all MON groups will also contain:
-
-"mon_data":
-       This contains a set of files organized by L3 domain and by
-       RDT event. E.g. on a system with two L3 domains there will
-       be subdirectories "mon_L3_00" and "mon_L3_01".  Each of these
-       directories have one file per event (e.g. "llc_occupancy",
-       "mbm_total_bytes", and "mbm_local_bytes"). In a MON group these
-       files provide a read out of the current value of the event for
-       all tasks in the group. In CTRL_MON groups these files provide
-       the sum for all tasks in the CTRL_MON group and all tasks in
-       MON groups. Please see example section for more details on usage.
-
-Resource allocation rules
--------------------------
-
-When a task is running the following rules define which resources are
-available to it:
-
-1) If the task is a member of a non-default group, then the schemata
-   for that group is used.
-
-2) Else if the task belongs to the default group, but is running on a
-   CPU that is assigned to some specific group, then the schemata for the
-   CPU's group is used.
-
-3) Otherwise the schemata for the default group is used.
-
-Resource monitoring rules
--------------------------
-1) If a task is a member of a MON group, or non-default CTRL_MON group
-   then RDT events for the task will be reported in that group.
-
-2) If a task is a member of the default CTRL_MON group, but is running
-   on a CPU that is assigned to some specific group, then the RDT events
-   for the task will be reported in that group.
-
-3) Otherwise RDT events for the task will be reported in the root level
-   "mon_data" group.
-
-
-Notes on cache occupancy monitoring and control
-===============================================
-When moving a task from one group to another you should remember that
-this only affects *new* cache allocations by the task. E.g. you may have
-a task in a monitor group showing 3 MB of cache occupancy. If you move
-to a new group and immediately check the occupancy of the old and new
-groups you will likely see that the old group is still showing 3 MB and
-the new group zero. When the task accesses locations still in cache from
-before the move, the h/w does not update any counters. On a busy system
-you will likely see the occupancy in the old group go down as cache lines
-are evicted and re-used while the occupancy in the new group rises as
-the task accesses memory and loads into the cache are counted based on
-membership in the new group.
-
-The same applies to cache allocation control. Moving a task to a group
-with a smaller cache partition will not evict any cache lines. The
-process may continue to use them from the old partition.
-
-Hardware uses CLOSid(Class of service ID) and an RMID(Resource monitoring ID)
-to identify a control group and a monitoring group respectively. Each of
-the resource groups are mapped to these IDs based on the kind of group. The
-number of CLOSid and RMID are limited by the hardware and hence the creation of
-a "CTRL_MON" directory may fail if we run out of either CLOSID or RMID
-and creation of "MON" group may fail if we run out of RMIDs.
-
-max_threshold_occupancy - generic concepts
-------------------------------------------
-
-Note that an RMID once freed may not be immediately available for use as
-the RMID is still tagged the cache lines of the previous user of RMID.
-Hence such RMIDs are placed on limbo list and checked back if the cache
-occupancy has gone down. If there is a time when system has a lot of
-limbo RMIDs but which are not ready to be used, user may see an -EBUSY
-during mkdir.
-
-max_threshold_occupancy is a user configurable value to determine the
-occupancy at which an RMID can be freed.
-
-Schemata files - general concepts
----------------------------------
-Each line in the file describes one resource. The line starts with
-the name of the resource, followed by specific values to be applied
-in each of the instances of that resource on the system.
-
-Cache IDs
----------
-On current generation systems there is one L3 cache per socket and L2
-caches are generally just shared by the hyperthreads on a core, but this
-isn't an architectural requirement. We could have multiple separate L3
-caches on a socket, multiple cores could share an L2 cache. So instead
-of using "socket" or "core" to define the set of logical cpus sharing
-a resource we use a "Cache ID". At a given cache level this will be a
-unique number across the whole system (but it isn't guaranteed to be a
-contiguous sequence, there may be gaps).  To find the ID for each logical
-CPU look in /sys/devices/system/cpu/cpu*/cache/index*/id
-
-Cache Bit Masks (CBM)
----------------------
-For cache resources we describe the portion of the cache that is available
-for allocation using a bitmask. The maximum value of the mask is defined
-by each cpu model (and may be different for different cache levels). It
-is found using CPUID, but is also provided in the "info" directory of
-the resctrl file system in "info/{resource}/cbm_mask". Intel hardware
-requires that these masks have all the '1' bits in a contiguous block. So
-0x3, 0x6 and 0xC are legal 4-bit masks with two bits set, but 0x5, 0x9
-and 0xA are not.  On a system with a 20-bit mask each bit represents 5%
-of the capacity of the cache. You could partition the cache into four
-equal parts with masks: 0x1f, 0x3e0, 0x7c00, 0xf8000.
-
-Memory bandwidth Allocation and monitoring
-==========================================
-
-For Memory bandwidth resource, by default the user controls the resource
-by indicating the percentage of total memory bandwidth.
-
-The minimum bandwidth percentage value for each cpu model is predefined
-and can be looked up through "info/MB/min_bandwidth". The bandwidth
-granularity that is allocated is also dependent on the cpu model and can
-be looked up at "info/MB/bandwidth_gran". The available bandwidth
-control steps are: min_bw + N * bw_gran. Intermediate values are rounded
-to the next control step available on the hardware.
-
-The bandwidth throttling is a core specific mechanism on some of Intel
-SKUs. Using a high bandwidth and a low bandwidth setting on two threads
-sharing a core may result in both threads being throttled to use the
-low bandwidth (see "thread_throttle_mode").
-
-The fact that Memory bandwidth allocation(MBA) may be a core
-specific mechanism where as memory bandwidth monitoring(MBM) is done at
-the package level may lead to confusion when users try to apply control
-via the MBA and then monitor the bandwidth to see if the controls are
-effective. Below are such scenarios:
-
-1. User may *not* see increase in actual bandwidth when percentage
-   values are increased:
-
-This can occur when aggregate L2 external bandwidth is more than L3
-external bandwidth. Consider an SKL SKU with 24 cores on a package and
-where L2 external  is 10GBps (hence aggregate L2 external bandwidth is
-240GBps) and L3 external bandwidth is 100GBps. Now a workload with '20
-threads, having 50% bandwidth, each consuming 5GBps' consumes the max L3
-bandwidth of 100GBps although the percentage value specified is only 50%
-<< 100%. Hence increasing the bandwidth percentage will not yield any
-more bandwidth. This is because although the L2 external bandwidth still
-has capacity, the L3 external bandwidth is fully used. Also note that
-this would be dependent on number of cores the benchmark is run on.
-
-2. Same bandwidth percentage may mean different actual bandwidth
-   depending on # of threads:
-
-For the same SKU in #1, a 'single thread, with 10% bandwidth' and '4
-thread, with 10% bandwidth' can consume upto 10GBps and 40GBps although
-they have same percentage bandwidth of 10%. This is simply because as
-threads start using more cores in an rdtgroup, the actual bandwidth may
-increase or vary although user specified bandwidth percentage is same.
-
-In order to mitigate this and make the interface more user friendly,
-resctrl added support for specifying the bandwidth in MBps as well.  The
-kernel underneath would use a software feedback mechanism or a "Software
-Controller(mba_sc)" which reads the actual bandwidth using MBM counters
-and adjust the memory bandwidth percentages to ensure::
-
-       "actual bandwidth < user specified bandwidth".
-
-By default, the schemata would take the bandwidth percentage values
-where as user can switch to the "MBA software controller" mode using
-a mount option 'mba_MBps'. The schemata format is specified in the below
-sections.
-
-L3 schemata file details (code and data prioritization disabled)
-----------------------------------------------------------------
-With CDP disabled the L3 schemata format is::
-
-       L3:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
-
-L3 schemata file details (CDP enabled via mount option to resctrl)
-------------------------------------------------------------------
-When CDP is enabled L3 control is split into two separate resources
-so you can specify independent masks for code and data like this::
-
-       L3DATA:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
-       L3CODE:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
-
-L2 schemata file details
-------------------------
-CDP is supported at L2 using the 'cdpl2' mount option. The schemata
-format is either::
-
-       L2:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
-
-or
-
-       L2DATA:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
-       L2CODE:<cache_id0>=<cbm>;<cache_id1>=<cbm>;...
-
-
-Memory bandwidth Allocation (default mode)
-------------------------------------------
-
-Memory b/w domain is L3 cache.
-::
-
-       MB:<cache_id0>=bandwidth0;<cache_id1>=bandwidth1;...
-
-Memory bandwidth Allocation specified in MBps
----------------------------------------------
-
-Memory bandwidth domain is L3 cache.
-::
-
-       MB:<cache_id0>=bw_MBps0;<cache_id1>=bw_MBps1;...
-
-Slow Memory Bandwidth Allocation (SMBA)
----------------------------------------
-AMD hardware supports Slow Memory Bandwidth Allocation (SMBA).
-CXL.memory is the only supported "slow" memory device. With the
-support of SMBA, the hardware enables bandwidth allocation on
-the slow memory devices. If there are multiple such devices in
-the system, the throttling logic groups all the slow sources
-together and applies the limit on them as a whole.
-
-The presence of SMBA (with CXL.memory) is independent of slow memory
-devices presence. If there are no such devices on the system, then
-configuring SMBA will have no impact on the performance of the system.
-
-The bandwidth domain for slow memory is L3 cache. Its schemata file
-is formatted as:
-::
-
-       SMBA:<cache_id0>=bandwidth0;<cache_id1>=bandwidth1;...
-
-Reading/writing the schemata file
----------------------------------
-Reading the schemata file will show the state of all resources
-on all domains. When writing you only need to specify those values
-which you wish to change.  E.g.
-::
-
-  # cat schemata
-  L3DATA:0=fffff;1=fffff;2=fffff;3=fffff
-  L3CODE:0=fffff;1=fffff;2=fffff;3=fffff
-  # echo "L3DATA:2=3c0;" > schemata
-  # cat schemata
-  L3DATA:0=fffff;1=fffff;2=3c0;3=fffff
-  L3CODE:0=fffff;1=fffff;2=fffff;3=fffff
-
-Reading/writing the schemata file (on AMD systems)
---------------------------------------------------
-Reading the schemata file will show the current bandwidth limit on all
-domains. The allocated resources are in multiples of one eighth GB/s.
-When writing to the file, you need to specify what cache id you wish to
-configure the bandwidth limit.
-
-For example, to allocate 2GB/s limit on the first cache id:
-
-::
-
-  # cat schemata
-    MB:0=2048;1=2048;2=2048;3=2048
-    L3:0=ffff;1=ffff;2=ffff;3=ffff
-
-  # echo "MB:1=16" > schemata
-  # cat schemata
-    MB:0=2048;1=  16;2=2048;3=2048
-    L3:0=ffff;1=ffff;2=ffff;3=ffff
-
-Reading/writing the schemata file (on AMD systems) with SMBA feature
---------------------------------------------------------------------
-Reading and writing the schemata file is the same as without SMBA in
-above section.
-
-For example, to allocate 8GB/s limit on the first cache id:
-
-::
-
-  # cat schemata
-    SMBA:0=2048;1=2048;2=2048;3=2048
-      MB:0=2048;1=2048;2=2048;3=2048
-      L3:0=ffff;1=ffff;2=ffff;3=ffff
-
-  # echo "SMBA:1=64" > schemata
-  # cat schemata
-    SMBA:0=2048;1=  64;2=2048;3=2048
-      MB:0=2048;1=2048;2=2048;3=2048
-      L3:0=ffff;1=ffff;2=ffff;3=ffff
-
-Cache Pseudo-Locking
-====================
-CAT enables a user to specify the amount of cache space that an
-application can fill. Cache pseudo-locking builds on the fact that a
-CPU can still read and write data pre-allocated outside its current
-allocated area on a cache hit. With cache pseudo-locking, data can be
-preloaded into a reserved portion of cache that no application can
-fill, and from that point on will only serve cache hits. The cache
-pseudo-locked memory is made accessible to user space where an
-application can map it into its virtual address space and thus have
-a region of memory with reduced average read latency.
-
-The creation of a cache pseudo-locked region is triggered by a request
-from the user to do so that is accompanied by a schemata of the region
-to be pseudo-locked. The cache pseudo-locked region is created as follows:
-
-- Create a CAT allocation CLOSNEW with a CBM matching the schemata
-  from the user of the cache region that will contain the pseudo-locked
-  memory. This region must not overlap with any current CAT allocation/CLOS
-  on the system and no future overlap with this cache region is allowed
-  while the pseudo-locked region exists.
-- Create a contiguous region of memory of the same size as the cache
-  region.
-- Flush the cache, disable hardware prefetchers, disable preemption.
-- Make CLOSNEW the active CLOS and touch the allocated memory to load
-  it into the cache.
-- Set the previous CLOS as active.
-- At this point the closid CLOSNEW can be released - the cache
-  pseudo-locked region is protected as long as its CBM does not appear in
-  any CAT allocation. Even though the cache pseudo-locked region will from
-  this point on not appear in any CBM of any CLOS an application running with
-  any CLOS will be able to access the memory in the pseudo-locked region since
-  the region continues to serve cache hits.
-- The contiguous region of memory loaded into the cache is exposed to
-  user-space as a character device.
-
-Cache pseudo-locking increases the probability that data will remain
-in the cache via carefully configuring the CAT feature and controlling
-application behavior. There is no guarantee that data is placed in
-cache. Instructions like INVD, WBINVD, CLFLUSH, etc. can still evict
-“locked” data from cache. Power management C-states may shrink or
-power off cache. Deeper C-states will automatically be restricted on
-pseudo-locked region creation.
-
-It is required that an application using a pseudo-locked region runs
-with affinity to the cores (or a subset of the cores) associated
-with the cache on which the pseudo-locked region resides. A sanity check
-within the code will not allow an application to map pseudo-locked memory
-unless it runs with affinity to cores associated with the cache on which the
-pseudo-locked region resides. The sanity check is only done during the
-initial mmap() handling, there is no enforcement afterwards and the
-application self needs to ensure it remains affine to the correct cores.
-
-Pseudo-locking is accomplished in two stages:
-
-1) During the first stage the system administrator allocates a portion
-   of cache that should be dedicated to pseudo-locking. At this time an
-   equivalent portion of memory is allocated, loaded into allocated
-   cache portion, and exposed as a character device.
-2) During the second stage a user-space application maps (mmap()) the
-   pseudo-locked memory into its address space.
-
-Cache Pseudo-Locking Interface
-------------------------------
-A pseudo-locked region is created using the resctrl interface as follows:
-
-1) Create a new resource group by creating a new directory in /sys/fs/resctrl.
-2) Change the new resource group's mode to "pseudo-locksetup" by writing
-   "pseudo-locksetup" to the "mode" file.
-3) Write the schemata of the pseudo-locked region to the "schemata" file. All
-   bits within the schemata should be "unused" according to the "bit_usage"
-   file.
-
-On successful pseudo-locked region creation the "mode" file will contain
-"pseudo-locked" and a new character device with the same name as the resource
-group will exist in /dev/pseudo_lock. This character device can be mmap()'ed
-by user space in order to obtain access to the pseudo-locked memory region.
-
-An example of cache pseudo-locked region creation and usage can be found below.
-
-Cache Pseudo-Locking Debugging Interface
-----------------------------------------
-The pseudo-locking debugging interface is enabled by default (if
-CONFIG_DEBUG_FS is enabled) and can be found in /sys/kernel/debug/resctrl.
-
-There is no explicit way for the kernel to test if a provided memory
-location is present in the cache. The pseudo-locking debugging interface uses
-the tracing infrastructure to provide two ways to measure cache residency of
-the pseudo-locked region:
-
-1) Memory access latency using the pseudo_lock_mem_latency tracepoint. Data
-   from these measurements are best visualized using a hist trigger (see
-   example below). In this test the pseudo-locked region is traversed at
-   a stride of 32 bytes while hardware prefetchers and preemption
-   are disabled. This also provides a substitute visualization of cache
-   hits and misses.
-2) Cache hit and miss measurements using model specific precision counters if
-   available. Depending on the levels of cache on the system the pseudo_lock_l2
-   and pseudo_lock_l3 tracepoints are available.
-
-When a pseudo-locked region is created a new debugfs directory is created for
-it in debugfs as /sys/kernel/debug/resctrl/<newdir>. A single
-write-only file, pseudo_lock_measure, is present in this directory. The
-measurement of the pseudo-locked region depends on the number written to this
-debugfs file:
-
-1:
-     writing "1" to the pseudo_lock_measure file will trigger the latency
-     measurement captured in the pseudo_lock_mem_latency tracepoint. See
-     example below.
-2:
-     writing "2" to the pseudo_lock_measure file will trigger the L2 cache
-     residency (cache hits and misses) measurement captured in the
-     pseudo_lock_l2 tracepoint. See example below.
-3:
-     writing "3" to the pseudo_lock_measure file will trigger the L3 cache
-     residency (cache hits and misses) measurement captured in the
-     pseudo_lock_l3 tracepoint.
-
-All measurements are recorded with the tracing infrastructure. This requires
-the relevant tracepoints to be enabled before the measurement is triggered.
-
-Example of latency debugging interface
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-In this example a pseudo-locked region named "newlock" was created. Here is
-how we can measure the latency in cycles of reading from this region and
-visualize this data with a histogram that is available if CONFIG_HIST_TRIGGERS
-is set::
-
-  # :> /sys/kernel/tracing/trace
-  # echo 'hist:keys=latency' > /sys/kernel/tracing/events/resctrl/pseudo_lock_mem_latency/trigger
-  # echo 1 > /sys/kernel/tracing/events/resctrl/pseudo_lock_mem_latency/enable
-  # echo 1 > /sys/kernel/debug/resctrl/newlock/pseudo_lock_measure
-  # echo 0 > /sys/kernel/tracing/events/resctrl/pseudo_lock_mem_latency/enable
-  # cat /sys/kernel/tracing/events/resctrl/pseudo_lock_mem_latency/hist
-
-  # event histogram
-  #
-  # trigger info: hist:keys=latency:vals=hitcount:sort=hitcount:size=2048 [active]
-  #
-
-  { latency:        456 } hitcount:          1
-  { latency:         50 } hitcount:         83
-  { latency:         36 } hitcount:         96
-  { latency:         44 } hitcount:        174
-  { latency:         48 } hitcount:        195
-  { latency:         46 } hitcount:        262
-  { latency:         42 } hitcount:        693
-  { latency:         40 } hitcount:       3204
-  { latency:         38 } hitcount:       3484
-
-  Totals:
-      Hits: 8192
-      Entries: 9
-    Dropped: 0
-
-Example of cache hits/misses debugging
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-In this example a pseudo-locked region named "newlock" was created on the L2
-cache of a platform. Here is how we can obtain details of the cache hits
-and misses using the platform's precision counters.
-::
-
-  # :> /sys/kernel/tracing/trace
-  # echo 1 > /sys/kernel/tracing/events/resctrl/pseudo_lock_l2/enable
-  # echo 2 > /sys/kernel/debug/resctrl/newlock/pseudo_lock_measure
-  # echo 0 > /sys/kernel/tracing/events/resctrl/pseudo_lock_l2/enable
-  # cat /sys/kernel/tracing/trace
-
-  # tracer: nop
-  #
-  #                              _-----=> irqs-off
-  #                             / _----=> need-resched
-  #                            | / _---=> hardirq/softirq
-  #                            || / _--=> preempt-depth
-  #                            ||| /     delay
-  #           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
-  #              | |       |   ||||       |         |
-  pseudo_lock_mea-1672  [002] ....  3132.860500: pseudo_lock_l2: hits=4097 miss=0
-
-
-Examples for RDT allocation usage
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-1) Example 1
-
-On a two socket machine (one L3 cache per socket) with just four bits
-for cache bit masks, minimum b/w of 10% with a memory bandwidth
-granularity of 10%.
-::
-
-  # mount -t resctrl resctrl /sys/fs/resctrl
-  # cd /sys/fs/resctrl
-  # mkdir p0 p1
-  # echo "L3:0=3;1=c\nMB:0=50;1=50" > /sys/fs/resctrl/p0/schemata
-  # echo "L3:0=3;1=3\nMB:0=50;1=50" > /sys/fs/resctrl/p1/schemata
-
-The default resource group is unmodified, so we have access to all parts
-of all caches (its schemata file reads "L3:0=f;1=f").
-
-Tasks that are under the control of group "p0" may only allocate from the
-"lower" 50% on cache ID 0, and the "upper" 50% of cache ID 1.
-Tasks in group "p1" use the "lower" 50% of cache on both sockets.
-
-Similarly, tasks that are under the control of group "p0" may use a
-maximum memory b/w of 50% on socket0 and 50% on socket 1.
-Tasks in group "p1" may also use 50% memory b/w on both sockets.
-Note that unlike cache masks, memory b/w cannot specify whether these
-allocations can overlap or not. The allocations specifies the maximum
-b/w that the group may be able to use and the system admin can configure
-the b/w accordingly.
-
-If resctrl is using the software controller (mba_sc) then user can enter the
-max b/w in MB rather than the percentage values.
-::
-
-  # echo "L3:0=3;1=c\nMB:0=1024;1=500" > /sys/fs/resctrl/p0/schemata
-  # echo "L3:0=3;1=3\nMB:0=1024;1=500" > /sys/fs/resctrl/p1/schemata
-
-In the above example the tasks in "p1" and "p0" on socket 0 would use a max b/w
-of 1024MB where as on socket 1 they would use 500MB.
-
-2) Example 2
-
-Again two sockets, but this time with a more realistic 20-bit mask.
-
-Two real time tasks pid=1234 running on processor 0 and pid=5678 running on
-processor 1 on socket 0 on a 2-socket and dual core machine. To avoid noisy
-neighbors, each of the two real-time tasks exclusively occupies one quarter
-of L3 cache on socket 0.
-::
-
-  # mount -t resctrl resctrl /sys/fs/resctrl
-  # cd /sys/fs/resctrl
-
-First we reset the schemata for the default group so that the "upper"
-50% of the L3 cache on socket 0 and 50% of memory b/w cannot be used by
-ordinary tasks::
-
-  # echo "L3:0=3ff;1=fffff\nMB:0=50;1=100" > schemata
-
-Next we make a resource group for our first real time task and give
-it access to the "top" 25% of the cache on socket 0.
-::
-
-  # mkdir p0
-  # echo "L3:0=f8000;1=fffff" > p0/schemata
-
-Finally we move our first real time task into this resource group. We
-also use taskset(1) to ensure the task always runs on a dedicated CPU
-on socket 0. Most uses of resource groups will also constrain which
-processors tasks run on.
-::
-
-  # echo 1234 > p0/tasks
-  # taskset -cp 1 1234
-
-Ditto for the second real time task (with the remaining 25% of cache)::
-
-  # mkdir p1
-  # echo "L3:0=7c00;1=fffff" > p1/schemata
-  # echo 5678 > p1/tasks
-  # taskset -cp 2 5678
-
-For the same 2 socket system with memory b/w resource and CAT L3 the
-schemata would look like(Assume min_bandwidth 10 and bandwidth_gran is
-10):
-
-For our first real time task this would request 20% memory b/w on socket 0.
-::
-
-  # echo -e "L3:0=f8000;1=fffff\nMB:0=20;1=100" > p0/schemata
-
-For our second real time task this would request an other 20% memory b/w
-on socket 0.
-::
-
-  # echo -e "L3:0=f8000;1=fffff\nMB:0=20;1=100" > p0/schemata
-
-3) Example 3
-
-A single socket system which has real-time tasks running on core 4-7 and
-non real-time workload assigned to core 0-3. The real-time tasks share text
-and data, so a per task association is not required and due to interaction
-with the kernel it's desired that the kernel on these cores shares L3 with
-the tasks.
-::
-
-  # mount -t resctrl resctrl /sys/fs/resctrl
-  # cd /sys/fs/resctrl
-
-First we reset the schemata for the default group so that the "upper"
-50% of the L3 cache on socket 0, and 50% of memory bandwidth on socket 0
-cannot be used by ordinary tasks::
-
-  # echo "L3:0=3ff\nMB:0=50" > schemata
-
-Next we make a resource group for our real time cores and give it access
-to the "top" 50% of the cache on socket 0 and 50% of memory bandwidth on
-socket 0.
-::
-
-  # mkdir p0
-  # echo "L3:0=ffc00\nMB:0=50" > p0/schemata
-
-Finally we move core 4-7 over to the new group and make sure that the
-kernel and the tasks running there get 50% of the cache. They should
-also get 50% of memory bandwidth assuming that the cores 4-7 are SMT
-siblings and only the real time threads are scheduled on the cores 4-7.
-::
-
-  # echo F0 > p0/cpus
-
-4) Example 4
-
-The resource groups in previous examples were all in the default "shareable"
-mode allowing sharing of their cache allocations. If one resource group
-configures a cache allocation then nothing prevents another resource group
-to overlap with that allocation.
-
-In this example a new exclusive resource group will be created on a L2 CAT
-system with two L2 cache instances that can be configured with an 8-bit
-capacity bitmask. The new exclusive resource group will be configured to use
-25% of each cache instance.
-::
-
-  # mount -t resctrl resctrl /sys/fs/resctrl/
-  # cd /sys/fs/resctrl
-
-First, we observe that the default group is configured to allocate to all L2
-cache::
-
-  # cat schemata
-  L2:0=ff;1=ff
-
-We could attempt to create the new resource group at this point, but it will
-fail because of the overlap with the schemata of the default group::
-
-  # mkdir p0
-  # echo 'L2:0=0x3;1=0x3' > p0/schemata
-  # cat p0/mode
-  shareable
-  # echo exclusive > p0/mode
-  -sh: echo: write error: Invalid argument
-  # cat info/last_cmd_status
-  schemata overlaps
-
-To ensure that there is no overlap with another resource group the default
-resource group's schemata has to change, making it possible for the new
-resource group to become exclusive.
-::
-
-  # echo 'L2:0=0xfc;1=0xfc' > schemata
-  # echo exclusive > p0/mode
-  # grep . p0/*
-  p0/cpus:0
-  p0/mode:exclusive
-  p0/schemata:L2:0=03;1=03
-  p0/size:L2:0=262144;1=262144
-
-A new resource group will on creation not overlap with an exclusive resource
-group::
-
-  # mkdir p1
-  # grep . p1/*
-  p1/cpus:0
-  p1/mode:shareable
-  p1/schemata:L2:0=fc;1=fc
-  p1/size:L2:0=786432;1=786432
-
-The bit_usage will reflect how the cache is used::
-
-  # cat info/L2/bit_usage
-  0=SSSSSSEE;1=SSSSSSEE
-
-A resource group cannot be forced to overlap with an exclusive resource group::
-
-  # echo 'L2:0=0x1;1=0x1' > p1/schemata
-  -sh: echo: write error: Invalid argument
-  # cat info/last_cmd_status
-  overlaps with exclusive group
-
-Example of Cache Pseudo-Locking
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Lock portion of L2 cache from cache id 1 using CBM 0x3. Pseudo-locked
-region is exposed at /dev/pseudo_lock/newlock that can be provided to
-application for argument to mmap().
-::
-
-  # mount -t resctrl resctrl /sys/fs/resctrl/
-  # cd /sys/fs/resctrl
-
-Ensure that there are bits available that can be pseudo-locked, since only
-unused bits can be pseudo-locked the bits to be pseudo-locked needs to be
-removed from the default resource group's schemata::
-
-  # cat info/L2/bit_usage
-  0=SSSSSSSS;1=SSSSSSSS
-  # echo 'L2:1=0xfc' > schemata
-  # cat info/L2/bit_usage
-  0=SSSSSSSS;1=SSSSSS00
-
-Create a new resource group that will be associated with the pseudo-locked
-region, indicate that it will be used for a pseudo-locked region, and
-configure the requested pseudo-locked region capacity bitmask::
-
-  # mkdir newlock
-  # echo pseudo-locksetup > newlock/mode
-  # echo 'L2:1=0x3' > newlock/schemata
-
-On success the resource group's mode will change to pseudo-locked, the
-bit_usage will reflect the pseudo-locked region, and the character device
-exposing the pseudo-locked region will exist::
-
-  # cat newlock/mode
-  pseudo-locked
-  # cat info/L2/bit_usage
-  0=SSSSSSSS;1=SSSSSSPP
-  # ls -l /dev/pseudo_lock/newlock
-  crw------- 1 root root 243, 0 Apr  3 05:01 /dev/pseudo_lock/newlock
-
-::
-
-  /*
-  * Example code to access one page of pseudo-locked cache region
-  * from user space.
-  */
-  #define _GNU_SOURCE
-  #include <fcntl.h>
-  #include <sched.h>
-  #include <stdio.h>
-  #include <stdlib.h>
-  #include <unistd.h>
-  #include <sys/mman.h>
-
-  /*
-  * It is required that the application runs with affinity to only
-  * cores associated with the pseudo-locked region. Here the cpu
-  * is hardcoded for convenience of example.
-  */
-  static int cpuid = 2;
-
-  int main(int argc, char *argv[])
-  {
-    cpu_set_t cpuset;
-    long page_size;
-    void *mapping;
-    int dev_fd;
-    int ret;
-
-    page_size = sysconf(_SC_PAGESIZE);
-
-    CPU_ZERO(&cpuset);
-    CPU_SET(cpuid, &cpuset);
-    ret = sched_setaffinity(0, sizeof(cpuset), &cpuset);
-    if (ret < 0) {
-      perror("sched_setaffinity");
-      exit(EXIT_FAILURE);
-    }
-
-    dev_fd = open("/dev/pseudo_lock/newlock", O_RDWR);
-    if (dev_fd < 0) {
-      perror("open");
-      exit(EXIT_FAILURE);
-    }
-
-    mapping = mmap(0, page_size, PROT_READ | PROT_WRITE, MAP_SHARED,
-            dev_fd, 0);
-    if (mapping == MAP_FAILED) {
-      perror("mmap");
-      close(dev_fd);
-      exit(EXIT_FAILURE);
-    }
-
-    /* Application interacts with pseudo-locked memory @mapping */
-
-    ret = munmap(mapping, page_size);
-    if (ret < 0) {
-      perror("munmap");
-      close(dev_fd);
-      exit(EXIT_FAILURE);
-    }
-
-    close(dev_fd);
-    exit(EXIT_SUCCESS);
-  }
-
-Locking between applications
-----------------------------
-
-Certain operations on the resctrl filesystem, composed of read/writes
-to/from multiple files, must be atomic.
-
-As an example, the allocation of an exclusive reservation of L3 cache
-involves:
-
-  1. Read the cbmmasks from each directory or the per-resource "bit_usage"
-  2. Find a contiguous set of bits in the global CBM bitmask that is clear
-     in any of the directory cbmmasks
-  3. Create a new directory
-  4. Set the bits found in step 2 to the new directory "schemata" file
-
-If two applications attempt to allocate space concurrently then they can
-end up allocating the same bits so the reservations are shared instead of
-exclusive.
-
-To coordinate atomic operations on the resctrlfs and to avoid the problem
-above, the following locking procedure is recommended:
-
-Locking is based on flock, which is available in libc and also as a shell
-script command
-
-Write lock:
-
- A) Take flock(LOCK_EX) on /sys/fs/resctrl
- B) Read/write the directory structure.
- C) funlock
-
-Read lock:
-
- A) Take flock(LOCK_SH) on /sys/fs/resctrl
- B) If success read the directory structure.
- C) funlock
-
-Example with bash::
-
-  # Atomically read directory structure
-  $ flock -s /sys/fs/resctrl/ find /sys/fs/resctrl
-
-  # Read directory contents and create new subdirectory
-
-  $ cat create-dir.sh
-  find /sys/fs/resctrl/ > output.txt
-  mask = function-of(output.txt)
-  mkdir /sys/fs/resctrl/newres/
-  echo mask > /sys/fs/resctrl/newres/schemata
-
-  $ flock /sys/fs/resctrl/ ./create-dir.sh
-
-Example with C::
-
-  /*
-  * Example code do take advisory locks
-  * before accessing resctrl filesystem
-  */
-  #include <sys/file.h>
-  #include <stdlib.h>
-
-  void resctrl_take_shared_lock(int fd)
-  {
-    int ret;
-
-    /* take shared lock on resctrl filesystem */
-    ret = flock(fd, LOCK_SH);
-    if (ret) {
-      perror("flock");
-      exit(-1);
-    }
-  }
-
-  void resctrl_take_exclusive_lock(int fd)
-  {
-    int ret;
-
-    /* release lock on resctrl filesystem */
-    ret = flock(fd, LOCK_EX);
-    if (ret) {
-      perror("flock");
-      exit(-1);
-    }
-  }
-
-  void resctrl_release_lock(int fd)
-  {
-    int ret;
-
-    /* take shared lock on resctrl filesystem */
-    ret = flock(fd, LOCK_UN);
-    if (ret) {
-      perror("flock");
-      exit(-1);
-    }
-  }
-
-  void main(void)
-  {
-    int fd, ret;
-
-    fd = open("/sys/fs/resctrl", O_DIRECTORY);
-    if (fd == -1) {
-      perror("open");
-      exit(-1);
-    }
-    resctrl_take_shared_lock(fd);
-    /* code to read directory contents */
-    resctrl_release_lock(fd);
-
-    resctrl_take_exclusive_lock(fd);
-    /* code to read and write directory contents */
-    resctrl_release_lock(fd);
-  }
-
-Examples for RDT Monitoring along with allocation usage
-=======================================================
-Reading monitored data
-----------------------
-Reading an event file (for ex: mon_data/mon_L3_00/llc_occupancy) would
-show the current snapshot of LLC occupancy of the corresponding MON
-group or CTRL_MON group.
-
-
-Example 1 (Monitor CTRL_MON group and subset of tasks in CTRL_MON group)
-------------------------------------------------------------------------
-On a two socket machine (one L3 cache per socket) with just four bits
-for cache bit masks::
-
-  # mount -t resctrl resctrl /sys/fs/resctrl
-  # cd /sys/fs/resctrl
-  # mkdir p0 p1
-  # echo "L3:0=3;1=c" > /sys/fs/resctrl/p0/schemata
-  # echo "L3:0=3;1=3" > /sys/fs/resctrl/p1/schemata
-  # echo 5678 > p1/tasks
-  # echo 5679 > p1/tasks
-
-The default resource group is unmodified, so we have access to all parts
-of all caches (its schemata file reads "L3:0=f;1=f").
-
-Tasks that are under the control of group "p0" may only allocate from the
-"lower" 50% on cache ID 0, and the "upper" 50% of cache ID 1.
-Tasks in group "p1" use the "lower" 50% of cache on both sockets.
-
-Create monitor groups and assign a subset of tasks to each monitor group.
-::
-
-  # cd /sys/fs/resctrl/p1/mon_groups
-  # mkdir m11 m12
-  # echo 5678 > m11/tasks
-  # echo 5679 > m12/tasks
-
-fetch data (data shown in bytes)
-::
-
-  # cat m11/mon_data/mon_L3_00/llc_occupancy
-  16234000
-  # cat m11/mon_data/mon_L3_01/llc_occupancy
-  14789000
-  # cat m12/mon_data/mon_L3_00/llc_occupancy
-  16789000
-
-The parent ctrl_mon group shows the aggregated data.
-::
-
-  # cat /sys/fs/resctrl/p1/mon_data/mon_l3_00/llc_occupancy
-  31234000
-
-Example 2 (Monitor a task from its creation)
---------------------------------------------
-On a two socket machine (one L3 cache per socket)::
-
-  # mount -t resctrl resctrl /sys/fs/resctrl
-  # cd /sys/fs/resctrl
-  # mkdir p0 p1
-
-An RMID is allocated to the group once its created and hence the <cmd>
-below is monitored from its creation.
-::
-
-  # echo $$ > /sys/fs/resctrl/p1/tasks
-  # <cmd>
-
-Fetch the data::
-
-  # cat /sys/fs/resctrl/p1/mon_data/mon_l3_00/llc_occupancy
-  31789000
-
-Example 3 (Monitor without CAT support or before creating CAT groups)
----------------------------------------------------------------------
-
-Assume a system like HSW has only CQM and no CAT support. In this case
-the resctrl will still mount but cannot create CTRL_MON directories.
-But user can create different MON groups within the root group thereby
-able to monitor all tasks including kernel threads.
-
-This can also be used to profile jobs cache size footprint before being
-able to allocate them to different allocation groups.
-::
-
-  # mount -t resctrl resctrl /sys/fs/resctrl
-  # cd /sys/fs/resctrl
-  # mkdir mon_groups/m01
-  # mkdir mon_groups/m02
-
-  # echo 3478 > /sys/fs/resctrl/mon_groups/m01/tasks
-  # echo 2467 > /sys/fs/resctrl/mon_groups/m02/tasks
-
-Monitor the groups separately and also get per domain data. From the
-below its apparent that the tasks are mostly doing work on
-domain(socket) 0.
-::
-
-  # cat /sys/fs/resctrl/mon_groups/m01/mon_L3_00/llc_occupancy
-  31234000
-  # cat /sys/fs/resctrl/mon_groups/m01/mon_L3_01/llc_occupancy
-  34555
-  # cat /sys/fs/resctrl/mon_groups/m02/mon_L3_00/llc_occupancy
-  31234000
-  # cat /sys/fs/resctrl/mon_groups/m02/mon_L3_01/llc_occupancy
-  32789
-
-
-Example 4 (Monitor real time tasks)
------------------------------------
-
-A single socket system which has real time tasks running on cores 4-7
-and non real time tasks on other cpus. We want to monitor the cache
-occupancy of the real time threads on these cores.
-::
-
-  # mount -t resctrl resctrl /sys/fs/resctrl
-  # cd /sys/fs/resctrl
-  # mkdir p1
-
-Move the cpus 4-7 over to p1::
-
-  # echo f0 > p1/cpus
-
-View the llc occupancy snapshot::
-
-  # cat /sys/fs/resctrl/p1/mon_data/mon_L3_00/llc_occupancy
-  11234000
-
-Intel RDT Errata
-================
-
-Intel MBM Counters May Report System Memory Bandwidth Incorrectly
------------------------------------------------------------------
-
-Errata SKX99 for Skylake server and BDF102 for Broadwell server.
-
-Problem: Intel Memory Bandwidth Monitoring (MBM) counters track metrics
-according to the assigned Resource Monitor ID (RMID) for that logical
-core. The IA32_QM_CTR register (MSR 0xC8E), used to report these
-metrics, may report incorrect system bandwidth for certain RMID values.
-
-Implication: Due to the errata, system memory bandwidth may not match
-what is reported.
-
-Workaround: MBM total and local readings are corrected according to the
-following correction factor table:
-
-+---------------+---------------+---------------+-----------------+
-|core count    |rmid count     |rmid threshold |correction factor|
-+---------------+---------------+---------------+-----------------+
-|1             |8              |0              |1.000000         |
-+---------------+---------------+---------------+-----------------+
-|2             |16             |0              |1.000000         |
-+---------------+---------------+---------------+-----------------+
-|3             |24             |15             |0.969650         |
-+---------------+---------------+---------------+-----------------+
-|4             |32             |0              |1.000000         |
-+---------------+---------------+---------------+-----------------+
-|6             |48             |31             |0.969650         |
-+---------------+---------------+---------------+-----------------+
-|7             |56             |47             |1.142857         |
-+---------------+---------------+---------------+-----------------+
-|8             |64             |0              |1.000000         |
-+---------------+---------------+---------------+-----------------+
-|9             |72             |63             |1.185115         |
-+---------------+---------------+---------------+-----------------+
-|10            |80             |63             |1.066553         |
-+---------------+---------------+---------------+-----------------+
-|11            |88             |79             |1.454545         |
-+---------------+---------------+---------------+-----------------+
-|12            |96             |0              |1.000000         |
-+---------------+---------------+---------------+-----------------+
-|13            |104            |95             |1.230769         |
-+---------------+---------------+---------------+-----------------+
-|14            |112            |95             |1.142857         |
-+---------------+---------------+---------------+-----------------+
-|15            |120            |95             |1.066667         |
-+---------------+---------------+---------------+-----------------+
-|16            |128            |0              |1.000000         |
-+---------------+---------------+---------------+-----------------+
-|17            |136            |127            |1.254863         |
-+---------------+---------------+---------------+-----------------+
-|18            |144            |127            |1.185255         |
-+---------------+---------------+---------------+-----------------+
-|19            |152            |0              |1.000000         |
-+---------------+---------------+---------------+-----------------+
-|20            |160            |127            |1.066667         |
-+---------------+---------------+---------------+-----------------+
-|21            |168            |0              |1.000000         |
-+---------------+---------------+---------------+-----------------+
-|22            |176            |159            |1.454334         |
-+---------------+---------------+---------------+-----------------+
-|23            |184            |0              |1.000000         |
-+---------------+---------------+---------------+-----------------+
-|24            |192            |127            |0.969744         |
-+---------------+---------------+---------------+-----------------+
-|25            |200            |191            |1.280246         |
-+---------------+---------------+---------------+-----------------+
-|26            |208            |191            |1.230921         |
-+---------------+---------------+---------------+-----------------+
-|27            |216            |0              |1.000000         |
-+---------------+---------------+---------------+-----------------+
-|28            |224            |191            |1.143118         |
-+---------------+---------------+---------------+-----------------+
-
-If rmid > rmid threshold, MBM total and local values should be multiplied
-by the correction factor.
-
-See:
-
-1. Erratum SKX99 in Intel Xeon Processor Scalable Family Specification Update:
-http://web.archive.org/web/20200716124958/https://www.intel.com/content/www/us/en/processors/xeon/scalable/xeon-scalable-spec-update.html
-
-2. Erratum BDF102 in Intel Xeon E5-2600 v4 Processor Product Family Specification Update:
-http://web.archive.org/web/20191125200531/https://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/xeon-e5-v4-spec-update.pdf
-
-3. The errata in Intel Resource Director Technology (Intel RDT) on 2nd Generation Intel Xeon Scalable Processors Reference Manual:
-https://software.intel.com/content/www/us/en/develop/articles/intel-resource-director-technology-rdt-reference-manual.html
-
-for further information.
diff --git a/Documentation/x86/sgx.rst b/Documentation/x86/sgx.rst
deleted file mode 100644 (file)
index 2bcbffa..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-===============================
-Software Guard eXtensions (SGX)
-===============================
-
-Overview
-========
-
-Software Guard eXtensions (SGX) hardware enables for user space applications
-to set aside private memory regions of code and data:
-
-* Privileged (ring-0) ENCLS functions orchestrate the construction of the
-  regions.
-* Unprivileged (ring-3) ENCLU functions allow an application to enter and
-  execute inside the regions.
-
-These memory regions are called enclaves. An enclave can be only entered at a
-fixed set of entry points. Each entry point can hold a single hardware thread
-at a time.  While the enclave is loaded from a regular binary file by using
-ENCLS functions, only the threads inside the enclave can access its memory. The
-region is denied from outside access by the CPU, and encrypted before it leaves
-from LLC.
-
-The support can be determined by
-
-       ``grep sgx /proc/cpuinfo``
-
-SGX must both be supported in the processor and enabled by the BIOS.  If SGX
-appears to be unsupported on a system which has hardware support, ensure
-support is enabled in the BIOS.  If a BIOS presents a choice between "Enabled"
-and "Software Enabled" modes for SGX, choose "Enabled".
-
-Enclave Page Cache
-==================
-
-SGX utilizes an *Enclave Page Cache (EPC)* to store pages that are associated
-with an enclave. It is contained in a BIOS-reserved region of physical memory.
-Unlike pages used for regular memory, pages can only be accessed from outside of
-the enclave during enclave construction with special, limited SGX instructions.
-
-Only a CPU executing inside an enclave can directly access enclave memory.
-However, a CPU executing inside an enclave may access normal memory outside the
-enclave.
-
-The kernel manages enclave memory similar to how it treats device memory.
-
-Enclave Page Types
-------------------
-
-**SGX Enclave Control Structure (SECS)**
-   Enclave's address range, attributes and other global data are defined
-   by this structure.
-
-**Regular (REG)**
-   Regular EPC pages contain the code and data of an enclave.
-
-**Thread Control Structure (TCS)**
-   Thread Control Structure pages define the entry points to an enclave and
-   track the execution state of an enclave thread.
-
-**Version Array (VA)**
-   Version Array pages contain 512 slots, each of which can contain a version
-   number for a page evicted from the EPC.
-
-Enclave Page Cache Map
-----------------------
-
-The processor tracks EPC pages in a hardware metadata structure called the
-*Enclave Page Cache Map (EPCM)*.  The EPCM contains an entry for each EPC page
-which describes the owning enclave, access rights and page type among the other
-things.
-
-EPCM permissions are separate from the normal page tables.  This prevents the
-kernel from, for instance, allowing writes to data which an enclave wishes to
-remain read-only.  EPCM permissions may only impose additional restrictions on
-top of normal x86 page permissions.
-
-For all intents and purposes, the SGX architecture allows the processor to
-invalidate all EPCM entries at will.  This requires that software be prepared to
-handle an EPCM fault at any time.  In practice, this can happen on events like
-power transitions when the ephemeral key that encrypts enclave memory is lost.
-
-Application interface
-=====================
-
-Enclave build functions
------------------------
-
-In addition to the traditional compiler and linker build process, SGX has a
-separate enclave “build” process.  Enclaves must be built before they can be
-executed (entered). The first step in building an enclave is opening the
-**/dev/sgx_enclave** device.  Since enclave memory is protected from direct
-access, special privileged instructions are then used to copy data into enclave
-pages and establish enclave page permissions.
-
-.. kernel-doc:: arch/x86/kernel/cpu/sgx/ioctl.c
-   :functions: sgx_ioc_enclave_create
-               sgx_ioc_enclave_add_pages
-               sgx_ioc_enclave_init
-               sgx_ioc_enclave_provision
-
-Enclave runtime management
---------------------------
-
-Systems supporting SGX2 additionally support changes to initialized
-enclaves: modifying enclave page permissions and type, and dynamically
-adding and removing of enclave pages. When an enclave accesses an address
-within its address range that does not have a backing page then a new
-regular page will be dynamically added to the enclave. The enclave is
-still required to run EACCEPT on the new page before it can be used.
-
-.. kernel-doc:: arch/x86/kernel/cpu/sgx/ioctl.c
-   :functions: sgx_ioc_enclave_restrict_permissions
-               sgx_ioc_enclave_modify_types
-               sgx_ioc_enclave_remove_pages
-
-Enclave vDSO
-------------
-
-Entering an enclave can only be done through SGX-specific EENTER and ERESUME
-functions, and is a non-trivial process.  Because of the complexity of
-transitioning to and from an enclave, enclaves typically utilize a library to
-handle the actual transitions.  This is roughly analogous to how glibc
-implementations are used by most applications to wrap system calls.
-
-Another crucial characteristic of enclaves is that they can generate exceptions
-as part of their normal operation that need to be handled in the enclave or are
-unique to SGX.
-
-Instead of the traditional signal mechanism to handle these exceptions, SGX
-can leverage special exception fixup provided by the vDSO.  The kernel-provided
-vDSO function wraps low-level transitions to/from the enclave like EENTER and
-ERESUME.  The vDSO function intercepts exceptions that would otherwise generate
-a signal and return the fault information directly to its caller.  This avoids
-the need to juggle signal handlers.
-
-.. kernel-doc:: arch/x86/include/uapi/asm/sgx.h
-   :functions: vdso_sgx_enter_enclave_t
-
-ksgxd
-=====
-
-SGX support includes a kernel thread called *ksgxd*.
-
-EPC sanitization
-----------------
-
-ksgxd is started when SGX initializes.  Enclave memory is typically ready
-for use when the processor powers on or resets.  However, if SGX has been in
-use since the reset, enclave pages may be in an inconsistent state.  This might
-occur after a crash and kexec() cycle, for instance.  At boot, ksgxd
-reinitializes all enclave pages so that they can be allocated and re-used.
-
-The sanitization is done by going through EPC address space and applying the
-EREMOVE function to each physical page. Some enclave pages like SECS pages have
-hardware dependencies on other pages which prevents EREMOVE from functioning.
-Executing two EREMOVE passes removes the dependencies.
-
-Page reclaimer
---------------
-
-Similar to the core kswapd, ksgxd, is responsible for managing the
-overcommitment of enclave memory.  If the system runs out of enclave memory,
-*ksgxd* “swaps” enclave memory to normal memory.
-
-Launch Control
-==============
-
-SGX provides a launch control mechanism. After all enclave pages have been
-copied, kernel executes EINIT function, which initializes the enclave. Only after
-this the CPU can execute inside the enclave.
-
-EINIT function takes an RSA-3072 signature of the enclave measurement.  The function
-checks that the measurement is correct and signature is signed with the key
-hashed to the four **IA32_SGXLEPUBKEYHASH{0, 1, 2, 3}** MSRs representing the
-SHA256 of a public key.
-
-Those MSRs can be configured by the BIOS to be either readable or writable.
-Linux supports only writable configuration in order to give full control to the
-kernel on launch control policy. Before calling EINIT function, the driver sets
-the MSRs to match the enclave's signing key.
-
-Encryption engines
-==================
-
-In order to conceal the enclave data while it is out of the CPU package, the
-memory controller has an encryption engine to transparently encrypt and decrypt
-enclave memory.
-
-In CPUs prior to Ice Lake, the Memory Encryption Engine (MEE) is used to
-encrypt pages leaving the CPU caches. MEE uses a n-ary Merkle tree with root in
-SRAM to maintain integrity of the encrypted data. This provides integrity and
-anti-replay protection but does not scale to large memory sizes because the time
-required to update the Merkle tree grows logarithmically in relation to the
-memory size.
-
-CPUs starting from Icelake use Total Memory Encryption (TME) in the place of
-MEE. TME-based SGX implementations do not have an integrity Merkle tree, which
-means integrity and replay-attacks are not mitigated.  B, it includes
-additional changes to prevent cipher text from being returned and SW memory
-aliases from being created.
-
-DMA to enclave memory is blocked by range registers on both MEE and TME systems
-(SDM section 41.10).
-
-Usage Models
-============
-
-Shared Library
---------------
-
-Sensitive data and the code that acts on it is partitioned from the application
-into a separate library. The library is then linked as a DSO which can be loaded
-into an enclave. The application can then make individual function calls into
-the enclave through special SGX instructions. A run-time within the enclave is
-configured to marshal function parameters into and out of the enclave and to
-call the correct library function.
-
-Application Container
----------------------
-
-An application may be loaded into a container enclave which is specially
-configured with a library OS and run-time which permits the application to run.
-The enclave run-time and library OS work together to execute the application
-when a thread enters the enclave.
-
-Impact of Potential Kernel SGX Bugs
-===================================
-
-EPC leaks
----------
-
-When EPC page leaks happen, a WARNING like this is shown in dmesg:
-
-"EREMOVE returned ... and an EPC page was leaked.  SGX may become unusable..."
-
-This is effectively a kernel use-after-free of an EPC page, and due
-to the way SGX works, the bug is detected at freeing. Rather than
-adding the page back to the pool of available EPC pages, the kernel
-intentionally leaks the page to avoid additional errors in the future.
-
-When this happens, the kernel will likely soon leak more EPC pages, and
-SGX will likely become unusable because the memory available to SGX is
-limited. However, while this may be fatal to SGX, the rest of the kernel
-is unlikely to be impacted and should continue to work.
-
-As a result, when this happpens, user should stop running any new
-SGX workloads, (or just any new workloads), and migrate all valuable
-workloads. Although a machine reboot can recover all EPC memory, the bug
-should be reported to Linux developers.
-
-
-Virtual EPC
-===========
-
-The implementation has also a virtual EPC driver to support SGX enclaves
-in guests. Unlike the SGX driver, an EPC page allocated by the virtual
-EPC driver doesn't have a specific enclave associated with it. This is
-because KVM doesn't track how a guest uses EPC pages.
-
-As a result, the SGX core page reclaimer doesn't support reclaiming EPC
-pages allocated to KVM guests through the virtual EPC driver. If the
-user wants to deploy SGX applications both on the host and in guests
-on the same machine, the user should reserve enough EPC (by taking out
-total virtual EPC size of all SGX VMs from the physical EPC size) for
-host SGX applications so they can run with acceptable performance.
-
-Architectural behavior is to restore all EPC pages to an uninitialized
-state also after a guest reboot.  Because this state can be reached only
-through the privileged ``ENCLS[EREMOVE]`` instruction, ``/dev/sgx_vepc``
-provides the ``SGX_IOC_VEPC_REMOVE_ALL`` ioctl to execute the instruction
-on all pages in the virtual EPC.
-
-``EREMOVE`` can fail for three reasons.  Userspace must pay attention
-to expected failures and handle them as follows:
-
-1. Page removal will always fail when any thread is running in the
-   enclave to which the page belongs.  In this case the ioctl will
-   return ``EBUSY`` independent of whether it has successfully removed
-   some pages; userspace can avoid these failures by preventing execution
-   of any vcpu which maps the virtual EPC.
-
-2. Page removal will cause a general protection fault if two calls to
-   ``EREMOVE`` happen concurrently for pages that refer to the same
-   "SECS" metadata pages.  This can happen if there are concurrent
-   invocations to ``SGX_IOC_VEPC_REMOVE_ALL``, or if a ``/dev/sgx_vepc``
-   file descriptor in the guest is closed at the same time as
-   ``SGX_IOC_VEPC_REMOVE_ALL``; it will also be reported as ``EBUSY``.
-   This can be avoided in userspace by serializing calls to the ioctl()
-   and to close(), but in general it should not be a problem.
-
-3. Finally, page removal will fail for SECS metadata pages which still
-   have child pages.  Child pages can be removed by executing
-   ``SGX_IOC_VEPC_REMOVE_ALL`` on all ``/dev/sgx_vepc`` file descriptors
-   mapped into the guest.  This means that the ioctl() must be called
-   twice: an initial set of calls to remove child pages and a subsequent
-   set of calls to remove SECS pages.  The second set of calls is only
-   required for those mappings that returned a nonzero value from the
-   first call.  It indicates a bug in the kernel or the userspace client
-   if any of the second round of ``SGX_IOC_VEPC_REMOVE_ALL`` calls has
-   a return code other than 0.
diff --git a/Documentation/x86/sva.rst b/Documentation/x86/sva.rst
deleted file mode 100644 (file)
index 2e9b8b0..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-===========================================
-Shared Virtual Addressing (SVA) with ENQCMD
-===========================================
-
-Background
-==========
-
-Shared Virtual Addressing (SVA) allows the processor and device to use the
-same virtual addresses avoiding the need for software to translate virtual
-addresses to physical addresses. SVA is what PCIe calls Shared Virtual
-Memory (SVM).
-
-In addition to the convenience of using application virtual addresses
-by the device, it also doesn't require pinning pages for DMA.
-PCIe Address Translation Services (ATS) along with Page Request Interface
-(PRI) allow devices to function much the same way as the CPU handling
-application page-faults. For more information please refer to the PCIe
-specification Chapter 10: ATS Specification.
-
-Use of SVA requires IOMMU support in the platform. IOMMU is also
-required to support the PCIe features ATS and PRI. ATS allows devices
-to cache translations for virtual addresses. The IOMMU driver uses the
-mmu_notifier() support to keep the device TLB cache and the CPU cache in
-sync. When an ATS lookup fails for a virtual address, the device should
-use the PRI in order to request the virtual address to be paged into the
-CPU page tables. The device must use ATS again in order the fetch the
-translation before use.
-
-Shared Hardware Workqueues
-==========================
-
-Unlike Single Root I/O Virtualization (SR-IOV), Scalable IOV (SIOV) permits
-the use of Shared Work Queues (SWQ) by both applications and Virtual
-Machines (VM's). This allows better hardware utilization vs. hard
-partitioning resources that could result in under utilization. In order to
-allow the hardware to distinguish the context for which work is being
-executed in the hardware by SWQ interface, SIOV uses Process Address Space
-ID (PASID), which is a 20-bit number defined by the PCIe SIG.
-
-PASID value is encoded in all transactions from the device. This allows the
-IOMMU to track I/O on a per-PASID granularity in addition to using the PCIe
-Resource Identifier (RID) which is the Bus/Device/Function.
-
-
-ENQCMD
-======
-
-ENQCMD is a new instruction on Intel platforms that atomically submits a
-work descriptor to a device. The descriptor includes the operation to be
-performed, virtual addresses of all parameters, virtual address of a completion
-record, and the PASID (process address space ID) of the current process.
-
-ENQCMD works with non-posted semantics and carries a status back if the
-command was accepted by hardware. This allows the submitter to know if the
-submission needs to be retried or other device specific mechanisms to
-implement fairness or ensure forward progress should be provided.
-
-ENQCMD is the glue that ensures applications can directly submit commands
-to the hardware and also permits hardware to be aware of application context
-to perform I/O operations via use of PASID.
-
-Process Address Space Tagging
-=============================
-
-A new thread-scoped MSR (IA32_PASID) provides the connection between
-user processes and the rest of the hardware. When an application first
-accesses an SVA-capable device, this MSR is initialized with a newly
-allocated PASID. The driver for the device calls an IOMMU-specific API
-that sets up the routing for DMA and page-requests.
-
-For example, the Intel Data Streaming Accelerator (DSA) uses
-iommu_sva_bind_device(), which will do the following:
-
-- Allocate the PASID, and program the process page-table (%cr3 register) in the
-  PASID context entries.
-- Register for mmu_notifier() to track any page-table invalidations to keep
-  the device TLB in sync. For example, when a page-table entry is invalidated,
-  the IOMMU propagates the invalidation to the device TLB. This will force any
-  future access by the device to this virtual address to participate in
-  ATS. If the IOMMU responds with proper response that a page is not
-  present, the device would request the page to be paged in via the PCIe PRI
-  protocol before performing I/O.
-
-This MSR is managed with the XSAVE feature set as "supervisor state" to
-ensure the MSR is updated during context switch.
-
-PASID Management
-================
-
-The kernel must allocate a PASID on behalf of each process which will use
-ENQCMD and program it into the new MSR to communicate the process identity to
-platform hardware.  ENQCMD uses the PASID stored in this MSR to tag requests
-from this process.  When a user submits a work descriptor to a device using the
-ENQCMD instruction, the PASID field in the descriptor is auto-filled with the
-value from MSR_IA32_PASID. Requests for DMA from the device are also tagged
-with the same PASID. The platform IOMMU uses the PASID in the transaction to
-perform address translation. The IOMMU APIs setup the corresponding PASID
-entry in IOMMU with the process address used by the CPU (e.g. %cr3 register in
-x86).
-
-The MSR must be configured on each logical CPU before any application
-thread can interact with a device. Threads that belong to the same
-process share the same page tables, thus the same MSR value.
-
-PASID Life Cycle Management
-===========================
-
-PASID is initialized as INVALID_IOASID (-1) when a process is created.
-
-Only processes that access SVA-capable devices need to have a PASID
-allocated. This allocation happens when a process opens/binds an SVA-capable
-device but finds no PASID for this process. Subsequent binds of the same, or
-other devices will share the same PASID.
-
-Although the PASID is allocated to the process by opening a device,
-it is not active in any of the threads of that process. It's loaded to the
-IA32_PASID MSR lazily when a thread tries to submit a work descriptor
-to a device using the ENQCMD.
-
-That first access will trigger a #GP fault because the IA32_PASID MSR
-has not been initialized with the PASID value assigned to the process
-when the device was opened. The Linux #GP handler notes that a PASID has
-been allocated for the process, and so initializes the IA32_PASID MSR
-and returns so that the ENQCMD instruction is re-executed.
-
-On fork(2) or exec(2) the PASID is removed from the process as it no
-longer has the same address space that it had when the device was opened.
-
-On clone(2) the new task shares the same address space, so will be
-able to use the PASID allocated to the process. The IA32_PASID is not
-preemptively initialized as the PASID value might not be allocated yet or
-the kernel does not know whether this thread is going to access the device
-and the cleared IA32_PASID MSR reduces context switch overhead by xstate
-init optimization. Since #GP faults have to be handled on any threads that
-were created before the PASID was assigned to the mm of the process, newly
-created threads might as well be treated in a consistent way.
-
-Due to complexity of freeing the PASID and clearing all IA32_PASID MSRs in
-all threads in unbind, free the PASID lazily only on mm exit.
-
-If a process does a close(2) of the device file descriptor and munmap(2)
-of the device MMIO portal, then the driver will unbind the device. The
-PASID is still marked VALID in the PASID_MSR for any threads in the
-process that accessed the device. But this is harmless as without the
-MMIO portal they cannot submit new work to the device.
-
-Relationships
-=============
-
- * Each process has many threads, but only one PASID.
- * Devices have a limited number (~10's to 1000's) of hardware workqueues.
-   The device driver manages allocating hardware workqueues.
- * A single mmap() maps a single hardware workqueue as a "portal" and
-   each portal maps down to a single workqueue.
- * For each device with which a process interacts, there must be
-   one or more mmap()'d portals.
- * Many threads within a process can share a single portal to access
-   a single device.
- * Multiple processes can separately mmap() the same portal, in
-   which case they still share one device hardware workqueue.
- * The single process-wide PASID is used by all threads to interact
-   with all devices.  There is not, for instance, a PASID for each
-   thread or each thread<->device pair.
-
-FAQ
-===
-
-* What is SVA/SVM?
-
-Shared Virtual Addressing (SVA) permits I/O hardware and the processor to
-work in the same address space, i.e., to share it. Some call it Shared
-Virtual Memory (SVM), but Linux community wanted to avoid confusing it with
-POSIX Shared Memory and Secure Virtual Machines which were terms already in
-circulation.
-
-* What is a PASID?
-
-A Process Address Space ID (PASID) is a PCIe-defined Transaction Layer Packet
-(TLP) prefix. A PASID is a 20-bit number allocated and managed by the OS.
-PASID is included in all transactions between the platform and the device.
-
-* How are shared workqueues different?
-
-Traditionally, in order for userspace applications to interact with hardware,
-there is a separate hardware instance required per process. For example,
-consider doorbells as a mechanism of informing hardware about work to process.
-Each doorbell is required to be spaced 4k (or page-size) apart for process
-isolation. This requires hardware to provision that space and reserve it in
-MMIO. This doesn't scale as the number of threads becomes quite large. The
-hardware also manages the queue depth for Shared Work Queues (SWQ), and
-consumers don't need to track queue depth. If there is no space to accept
-a command, the device will return an error indicating retry.
-
-A user should check Deferrable Memory Write (DMWr) capability on the device
-and only submits ENQCMD when the device supports it. In the new DMWr PCIe
-terminology, devices need to support DMWr completer capability. In addition,
-it requires all switch ports to support DMWr routing and must be enabled by
-the PCIe subsystem, much like how PCIe atomic operations are managed for
-instance.
-
-SWQ allows hardware to provision just a single address in the device. When
-used with ENQCMD to submit work, the device can distinguish the process
-submitting the work since it will include the PASID assigned to that
-process. This helps the device scale to a large number of processes.
-
-* Is this the same as a user space device driver?
-
-Communicating with the device via the shared workqueue is much simpler
-than a full blown user space driver. The kernel driver does all the
-initialization of the hardware. User space only needs to worry about
-submitting work and processing completions.
-
-* Is this the same as SR-IOV?
-
-Single Root I/O Virtualization (SR-IOV) focuses on providing independent
-hardware interfaces for virtualizing hardware. Hence, it's required to be
-almost fully functional interface to software supporting the traditional
-BARs, space for interrupts via MSI-X, its own register layout.
-Virtual Functions (VFs) are assisted by the Physical Function (PF)
-driver.
-
-Scalable I/O Virtualization builds on the PASID concept to create device
-instances for virtualization. SIOV requires host software to assist in
-creating virtual devices; each virtual device is represented by a PASID
-along with the bus/device/function of the device.  This allows device
-hardware to optimize device resource creation and can grow dynamically on
-demand. SR-IOV creation and management is very static in nature. Consult
-references below for more details.
-
-* Why not just create a virtual function for each app?
-
-Creating PCIe SR-IOV type Virtual Functions (VF) is expensive. VFs require
-duplicated hardware for PCI config space and interrupts such as MSI-X.
-Resources such as interrupts have to be hard partitioned between VFs at
-creation time, and cannot scale dynamically on demand. The VFs are not
-completely independent from the Physical Function (PF). Most VFs require
-some communication and assistance from the PF driver. SIOV, in contrast,
-creates a software-defined device where all the configuration and control
-aspects are mediated via the slow path. The work submission and completion
-happen without any mediation.
-
-* Does this support virtualization?
-
-ENQCMD can be used from within a guest VM. In these cases, the VMM helps
-with setting up a translation table to translate from Guest PASID to Host
-PASID. Please consult the ENQCMD instruction set reference for more
-details.
-
-* Does memory need to be pinned?
-
-When devices support SVA along with platform hardware such as IOMMU
-supporting such devices, there is no need to pin memory for DMA purposes.
-Devices that support SVA also support other PCIe features that remove the
-pinning requirement for memory.
-
-Device TLB support - Device requests the IOMMU to lookup an address before
-use via Address Translation Service (ATS) requests.  If the mapping exists
-but there is no page allocated by the OS, IOMMU hardware returns that no
-mapping exists.
-
-Device requests the virtual address to be mapped via Page Request
-Interface (PRI). Once the OS has successfully completed the mapping, it
-returns the response back to the device. The device requests again for
-a translation and continues.
-
-IOMMU works with the OS in managing consistency of page-tables with the
-device. When removing pages, it interacts with the device to remove any
-device TLB entry that might have been cached before removing the mappings from
-the OS.
-
-References
-==========
-
-VT-D:
-https://01.org/blogs/ashokraj/2018/recent-enhancements-intel-virtualization-technology-directed-i/o-intel-vt-d
-
-SIOV:
-https://01.org/blogs/2019/assignable-interfaces-intel-scalable-i/o-virtualization-linux
-
-ENQCMD in ISE:
-https://software.intel.com/sites/default/files/managed/c5/15/architecture-instruction-set-extensions-programming-reference.pdf
-
-DSA spec:
-https://software.intel.com/sites/default/files/341204-intel-data-streaming-accelerator-spec.pdf
diff --git a/Documentation/x86/tdx.rst b/Documentation/x86/tdx.rst
deleted file mode 100644 (file)
index dc8d9fd..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=====================================
-Intel Trust Domain Extensions (TDX)
-=====================================
-
-Intel's Trust Domain Extensions (TDX) protect confidential guest VMs from
-the host and physical attacks by isolating the guest register state and by
-encrypting the guest memory. In TDX, a special module running in a special
-mode sits between the host and the guest and manages the guest/host
-separation.
-
-Since the host cannot directly access guest registers or memory, much
-normal functionality of a hypervisor must be moved into the guest. This is
-implemented using a Virtualization Exception (#VE) that is handled by the
-guest kernel. A #VE is handled entirely inside the guest kernel, but some
-require the hypervisor to be consulted.
-
-TDX includes new hypercall-like mechanisms for communicating from the
-guest to the hypervisor or the TDX module.
-
-New TDX Exceptions
-==================
-
-TDX guests behave differently from bare-metal and traditional VMX guests.
-In TDX guests, otherwise normal instructions or memory accesses can cause
-#VE or #GP exceptions.
-
-Instructions marked with an '*' conditionally cause exceptions.  The
-details for these instructions are discussed below.
-
-Instruction-based #VE
----------------------
-
-- Port I/O (INS, OUTS, IN, OUT)
-- HLT
-- MONITOR, MWAIT
-- WBINVD, INVD
-- VMCALL
-- RDMSR*,WRMSR*
-- CPUID*
-
-Instruction-based #GP
----------------------
-
-- All VMX instructions: INVEPT, INVVPID, VMCLEAR, VMFUNC, VMLAUNCH,
-  VMPTRLD, VMPTRST, VMREAD, VMRESUME, VMWRITE, VMXOFF, VMXON
-- ENCLS, ENCLU
-- GETSEC
-- RSM
-- ENQCMD
-- RDMSR*,WRMSR*
-
-RDMSR/WRMSR Behavior
---------------------
-
-MSR access behavior falls into three categories:
-
-- #GP generated
-- #VE generated
-- "Just works"
-
-In general, the #GP MSRs should not be used in guests.  Their use likely
-indicates a bug in the guest.  The guest may try to handle the #GP with a
-hypercall but it is unlikely to succeed.
-
-The #VE MSRs are typically able to be handled by the hypervisor.  Guests
-can make a hypercall to the hypervisor to handle the #VE.
-
-The "just works" MSRs do not need any special guest handling.  They might
-be implemented by directly passing through the MSR to the hardware or by
-trapping and handling in the TDX module.  Other than possibly being slow,
-these MSRs appear to function just as they would on bare metal.
-
-CPUID Behavior
---------------
-
-For some CPUID leaves and sub-leaves, the virtualized bit fields of CPUID
-return values (in guest EAX/EBX/ECX/EDX) are configurable by the
-hypervisor. For such cases, the Intel TDX module architecture defines two
-virtualization types:
-
-- Bit fields for which the hypervisor controls the value seen by the guest
-  TD.
-
-- Bit fields for which the hypervisor configures the value such that the
-  guest TD either sees their native value or a value of 0.  For these bit
-  fields, the hypervisor can mask off the native values, but it can not
-  turn *on* values.
-
-A #VE is generated for CPUID leaves and sub-leaves that the TDX module does
-not know how to handle. The guest kernel may ask the hypervisor for the
-value with a hypercall.
-
-#VE on Memory Accesses
-======================
-
-There are essentially two classes of TDX memory: private and shared.
-Private memory receives full TDX protections.  Its content is protected
-against access from the hypervisor.  Shared memory is expected to be
-shared between guest and hypervisor and does not receive full TDX
-protections.
-
-A TD guest is in control of whether its memory accesses are treated as
-private or shared.  It selects the behavior with a bit in its page table
-entries.  This helps ensure that a guest does not place sensitive
-information in shared memory, exposing it to the untrusted hypervisor.
-
-#VE on Shared Memory
---------------------
-
-Access to shared mappings can cause a #VE.  The hypervisor ultimately
-controls whether a shared memory access causes a #VE, so the guest must be
-careful to only reference shared pages it can safely handle a #VE.  For
-instance, the guest should be careful not to access shared memory in the
-#VE handler before it reads the #VE info structure (TDG.VP.VEINFO.GET).
-
-Shared mapping content is entirely controlled by the hypervisor. The guest
-should only use shared mappings for communicating with the hypervisor.
-Shared mappings must never be used for sensitive memory content like kernel
-stacks.  A good rule of thumb is that hypervisor-shared memory should be
-treated the same as memory mapped to userspace.  Both the hypervisor and
-userspace are completely untrusted.
-
-MMIO for virtual devices is implemented as shared memory.  The guest must
-be careful not to access device MMIO regions unless it is also prepared to
-handle a #VE.
-
-#VE on Private Pages
---------------------
-
-An access to private mappings can also cause a #VE.  Since all kernel
-memory is also private memory, the kernel might theoretically need to
-handle a #VE on arbitrary kernel memory accesses.  This is not feasible, so
-TDX guests ensure that all guest memory has been "accepted" before memory
-is used by the kernel.
-
-A modest amount of memory (typically 512M) is pre-accepted by the firmware
-before the kernel runs to ensure that the kernel can start up without
-being subjected to a #VE.
-
-The hypervisor is permitted to unilaterally move accepted pages to a
-"blocked" state. However, if it does this, page access will not generate a
-#VE.  It will, instead, cause a "TD Exit" where the hypervisor is required
-to handle the exception.
-
-Linux #VE handler
-=================
-
-Just like page faults or #GP's, #VE exceptions can be either handled or be
-fatal.  Typically, an unhandled userspace #VE results in a SIGSEGV.
-An unhandled kernel #VE results in an oops.
-
-Handling nested exceptions on x86 is typically nasty business.  A #VE
-could be interrupted by an NMI which triggers another #VE and hilarity
-ensues.  The TDX #VE architecture anticipated this scenario and includes a
-feature to make it slightly less nasty.
-
-During #VE handling, the TDX module ensures that all interrupts (including
-NMIs) are blocked.  The block remains in place until the guest makes a
-TDG.VP.VEINFO.GET TDCALL.  This allows the guest to control when interrupts
-or a new #VE can be delivered.
-
-However, the guest kernel must still be careful to avoid potential
-#VE-triggering actions (discussed above) while this block is in place.
-While the block is in place, any #VE is elevated to a double fault (#DF)
-which is not recoverable.
-
-MMIO handling
-=============
-
-In non-TDX VMs, MMIO is usually implemented by giving a guest access to a
-mapping which will cause a VMEXIT on access, and then the hypervisor
-emulates the access.  That is not possible in TDX guests because VMEXIT
-will expose the register state to the host. TDX guests don't trust the host
-and can't have their state exposed to the host.
-
-In TDX, MMIO regions typically trigger a #VE exception in the guest.  The
-guest #VE handler then emulates the MMIO instruction inside the guest and
-converts it into a controlled TDCALL to the host, rather than exposing
-guest state to the host.
-
-MMIO addresses on x86 are just special physical addresses. They can
-theoretically be accessed with any instruction that accesses memory.
-However, the kernel instruction decoding method is limited. It is only
-designed to decode instructions like those generated by io.h macros.
-
-MMIO access via other means (like structure overlays) may result in an
-oops.
-
-Shared Memory Conversions
-=========================
-
-All TDX guest memory starts out as private at boot.  This memory can not
-be accessed by the hypervisor.  However, some kernel users like device
-drivers might have a need to share data with the hypervisor.  To do this,
-memory must be converted between shared and private.  This can be
-accomplished using some existing memory encryption helpers:
-
- * set_memory_decrypted() converts a range of pages to shared.
- * set_memory_encrypted() converts memory back to private.
-
-Device drivers are the primary user of shared memory, but there's no need
-to touch every driver. DMA buffers and ioremap() do the conversions
-automatically.
-
-TDX uses SWIOTLB for most DMA allocations. The SWIOTLB buffer is
-converted to shared on boot.
-
-For coherent DMA allocation, the DMA buffer gets converted on the
-allocation. Check force_dma_unencrypted() for details.
-
-Attestation
-===========
-
-Attestation is used to verify the TDX guest trustworthiness to other
-entities before provisioning secrets to the guest. For example, a key
-server may want to use attestation to verify that the guest is the
-desired one before releasing the encryption keys to mount the encrypted
-rootfs or a secondary drive.
-
-The TDX module records the state of the TDX guest in various stages of
-the guest boot process using the build time measurement register (MRTD)
-and runtime measurement registers (RTMR). Measurements related to the
-guest initial configuration and firmware image are recorded in the MRTD
-register. Measurements related to initial state, kernel image, firmware
-image, command line options, initrd, ACPI tables, etc are recorded in
-RTMR registers. For more details, as an example, please refer to TDX
-Virtual Firmware design specification, section titled "TD Measurement".
-At TDX guest runtime, the attestation process is used to attest to these
-measurements.
-
-The attestation process consists of two steps: TDREPORT generation and
-Quote generation.
-
-TDX guest uses TDCALL[TDG.MR.REPORT] to get the TDREPORT (TDREPORT_STRUCT)
-from the TDX module. TDREPORT is a fixed-size data structure generated by
-the TDX module which contains guest-specific information (such as build
-and boot measurements), platform security version, and the MAC to protect
-the integrity of the TDREPORT. A user-provided 64-Byte REPORTDATA is used
-as input and included in the TDREPORT. Typically it can be some nonce
-provided by attestation service so the TDREPORT can be verified uniquely.
-More details about the TDREPORT can be found in Intel TDX Module
-specification, section titled "TDG.MR.REPORT Leaf".
-
-After getting the TDREPORT, the second step of the attestation process
-is to send it to the Quoting Enclave (QE) to generate the Quote. TDREPORT
-by design can only be verified on the local platform as the MAC key is
-bound to the platform. To support remote verification of the TDREPORT,
-TDX leverages Intel SGX Quoting Enclave to verify the TDREPORT locally
-and convert it to a remotely verifiable Quote. Method of sending TDREPORT
-to QE is implementation specific. Attestation software can choose
-whatever communication channel available (i.e. vsock or TCP/IP) to
-send the TDREPORT to QE and receive the Quote.
-
-References
-==========
-
-TDX reference material is collected here:
-
-https://www.intel.com/content/www/us/en/developer/articles/technical/intel-trust-domain-extensions.html
diff --git a/Documentation/x86/tlb.rst b/Documentation/x86/tlb.rst
deleted file mode 100644 (file)
index 82ec58a..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=======
-The TLB
-=======
-
-When the kernel unmaps or modified the attributes of a range of
-memory, it has two choices:
-
- 1. Flush the entire TLB with a two-instruction sequence.  This is
-    a quick operation, but it causes collateral damage: TLB entries
-    from areas other than the one we are trying to flush will be
-    destroyed and must be refilled later, at some cost.
- 2. Use the invlpg instruction to invalidate a single page at a
-    time.  This could potentially cost many more instructions, but
-    it is a much more precise operation, causing no collateral
-    damage to other TLB entries.
-
-Which method to do depends on a few things:
-
- 1. The size of the flush being performed.  A flush of the entire
-    address space is obviously better performed by flushing the
-    entire TLB than doing 2^48/PAGE_SIZE individual flushes.
- 2. The contents of the TLB.  If the TLB is empty, then there will
-    be no collateral damage caused by doing the global flush, and
-    all of the individual flush will have ended up being wasted
-    work.
- 3. The size of the TLB.  The larger the TLB, the more collateral
-    damage we do with a full flush.  So, the larger the TLB, the
-    more attractive an individual flush looks.  Data and
-    instructions have separate TLBs, as do different page sizes.
- 4. The microarchitecture.  The TLB has become a multi-level
-    cache on modern CPUs, and the global flushes have become more
-    expensive relative to single-page flushes.
-
-There is obviously no way the kernel can know all these things,
-especially the contents of the TLB during a given flush.  The
-sizes of the flush will vary greatly depending on the workload as
-well.  There is essentially no "right" point to choose.
-
-You may be doing too many individual invalidations if you see the
-invlpg instruction (or instructions _near_ it) show up high in
-profiles.  If you believe that individual invalidations being
-called too often, you can lower the tunable::
-
-       /sys/kernel/debug/x86/tlb_single_page_flush_ceiling
-
-This will cause us to do the global flush for more cases.
-Lowering it to 0 will disable the use of the individual flushes.
-Setting it to 1 is a very conservative setting and it should
-never need to be 0 under normal circumstances.
-
-Despite the fact that a single individual flush on x86 is
-guaranteed to flush a full 2MB [1]_, hugetlbfs always uses the full
-flushes.  THP is treated exactly the same as normal memory.
-
-You might see invlpg inside of flush_tlb_mm_range() show up in
-profiles, or you can use the trace_tlb_flush() tracepoints. to
-determine how long the flush operations are taking.
-
-Essentially, you are balancing the cycles you spend doing invlpg
-with the cycles that you spend refilling the TLB later.
-
-You can measure how expensive TLB refills are by using
-performance counters and 'perf stat', like this::
-
-  perf stat -e
-    cpu/event=0x8,umask=0x84,name=dtlb_load_misses_walk_duration/,
-    cpu/event=0x8,umask=0x82,name=dtlb_load_misses_walk_completed/,
-    cpu/event=0x49,umask=0x4,name=dtlb_store_misses_walk_duration/,
-    cpu/event=0x49,umask=0x2,name=dtlb_store_misses_walk_completed/,
-    cpu/event=0x85,umask=0x4,name=itlb_misses_walk_duration/,
-    cpu/event=0x85,umask=0x2,name=itlb_misses_walk_completed/
-
-That works on an IvyBridge-era CPU (i5-3320M).  Different CPUs
-may have differently-named counters, but they should at least
-be there in some form.  You can use pmu-tools 'ocperf list'
-(https://github.com/andikleen/pmu-tools) to find the right
-counters for a given CPU.
-
-.. [1] A footnote in Intel's SDM "4.10.4.2 Recommended Invalidation"
-   says: "One execution of INVLPG is sufficient even for a page
-   with size greater than 4 KBytes."
diff --git a/Documentation/x86/topology.rst b/Documentation/x86/topology.rst
deleted file mode 100644 (file)
index 7f58010..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-============
-x86 Topology
-============
-
-This documents and clarifies the main aspects of x86 topology modelling and
-representation in the kernel. Update/change when doing changes to the
-respective code.
-
-The architecture-agnostic topology definitions are in
-Documentation/admin-guide/cputopology.rst. This file holds x86-specific
-differences/specialities which must not necessarily apply to the generic
-definitions. Thus, the way to read up on Linux topology on x86 is to start
-with the generic one and look at this one in parallel for the x86 specifics.
-
-Needless to say, code should use the generic functions - this file is *only*
-here to *document* the inner workings of x86 topology.
-
-Started by Thomas Gleixner <tglx@linutronix.de> and Borislav Petkov <bp@alien8.de>.
-
-The main aim of the topology facilities is to present adequate interfaces to
-code which needs to know/query/use the structure of the running system wrt
-threads, cores, packages, etc.
-
-The kernel does not care about the concept of physical sockets because a
-socket has no relevance to software. It's an electromechanical component. In
-the past a socket always contained a single package (see below), but with the
-advent of Multi Chip Modules (MCM) a socket can hold more than one package. So
-there might be still references to sockets in the code, but they are of
-historical nature and should be cleaned up.
-
-The topology of a system is described in the units of:
-
-    - packages
-    - cores
-    - threads
-
-Package
-=======
-Packages contain a number of cores plus shared resources, e.g. DRAM
-controller, shared caches etc.
-
-Modern systems may also use the term 'Die' for package.
-
-AMD nomenclature for package is 'Node'.
-
-Package-related topology information in the kernel:
-
-  - cpuinfo_x86.x86_max_cores:
-
-    The number of cores in a package. This information is retrieved via CPUID.
-
-  - cpuinfo_x86.x86_max_dies:
-
-    The number of dies in a package. This information is retrieved via CPUID.
-
-  - cpuinfo_x86.cpu_die_id:
-
-    The physical ID of the die. This information is retrieved via CPUID.
-
-  - cpuinfo_x86.phys_proc_id:
-
-    The physical ID of the package. This information is retrieved via CPUID
-    and deduced from the APIC IDs of the cores in the package.
-
-    Modern systems use this value for the socket. There may be multiple
-    packages within a socket. This value may differ from cpu_die_id.
-
-  - cpuinfo_x86.logical_proc_id:
-
-    The logical ID of the package. As we do not trust BIOSes to enumerate the
-    packages in a consistent way, we introduced the concept of logical package
-    ID so we can sanely calculate the number of maximum possible packages in
-    the system and have the packages enumerated linearly.
-
-  - topology_max_packages():
-
-    The maximum possible number of packages in the system. Helpful for per
-    package facilities to preallocate per package information.
-
-  - cpu_llc_id:
-
-    A per-CPU variable containing:
-
-      - On Intel, the first APIC ID of the list of CPUs sharing the Last Level
-        Cache
-
-      - On AMD, the Node ID or Core Complex ID containing the Last Level
-        Cache. In general, it is a number identifying an LLC uniquely on the
-        system.
-
-Cores
-=====
-A core consists of 1 or more threads. It does not matter whether the threads
-are SMT- or CMT-type threads.
-
-AMDs nomenclature for a CMT core is "Compute Unit". The kernel always uses
-"core".
-
-Core-related topology information in the kernel:
-
-  - smp_num_siblings:
-
-    The number of threads in a core. The number of threads in a package can be
-    calculated by::
-
-       threads_per_package = cpuinfo_x86.x86_max_cores * smp_num_siblings
-
-
-Threads
-=======
-A thread is a single scheduling unit. It's the equivalent to a logical Linux
-CPU.
-
-AMDs nomenclature for CMT threads is "Compute Unit Core". The kernel always
-uses "thread".
-
-Thread-related topology information in the kernel:
-
-  - topology_core_cpumask():
-
-    The cpumask contains all online threads in the package to which a thread
-    belongs.
-
-    The number of online threads is also printed in /proc/cpuinfo "siblings."
-
-  - topology_sibling_cpumask():
-
-    The cpumask contains all online threads in the core to which a thread
-    belongs.
-
-  - topology_logical_package_id():
-
-    The logical package ID to which a thread belongs.
-
-  - topology_physical_package_id():
-
-    The physical package ID to which a thread belongs.
-
-  - topology_core_id();
-
-    The ID of the core to which a thread belongs. It is also printed in /proc/cpuinfo
-    "core_id."
-
-
-
-System topology examples
-========================
-
-.. note::
-  The alternative Linux CPU enumeration depends on how the BIOS enumerates the
-  threads. Many BIOSes enumerate all threads 0 first and then all threads 1.
-  That has the "advantage" that the logical Linux CPU numbers of threads 0 stay
-  the same whether threads are enabled or not. That's merely an implementation
-  detail and has no practical impact.
-
-1) Single Package, Single Core::
-
-   [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
-
-2) Single Package, Dual Core
-
-   a) One thread per core::
-
-       [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
-                   -> [core 1] -> [thread 0] -> Linux CPU 1
-
-   b) Two threads per core::
-
-       [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
-                               -> [thread 1] -> Linux CPU 1
-                   -> [core 1] -> [thread 0] -> Linux CPU 2
-                               -> [thread 1] -> Linux CPU 3
-
-      Alternative enumeration::
-
-       [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
-                               -> [thread 1] -> Linux CPU 2
-                   -> [core 1] -> [thread 0] -> Linux CPU 1
-                               -> [thread 1] -> Linux CPU 3
-
-      AMD nomenclature for CMT systems::
-
-       [node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0
-                                    -> [Compute Unit Core 1] -> Linux CPU 1
-                -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2
-                                    -> [Compute Unit Core 1] -> Linux CPU 3
-
-4) Dual Package, Dual Core
-
-   a) One thread per core::
-
-       [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
-                   -> [core 1] -> [thread 0] -> Linux CPU 1
-
-       [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2
-                   -> [core 1] -> [thread 0] -> Linux CPU 3
-
-   b) Two threads per core::
-
-       [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
-                               -> [thread 1] -> Linux CPU 1
-                   -> [core 1] -> [thread 0] -> Linux CPU 2
-                               -> [thread 1] -> Linux CPU 3
-
-       [package 1] -> [core 0] -> [thread 0] -> Linux CPU 4
-                               -> [thread 1] -> Linux CPU 5
-                   -> [core 1] -> [thread 0] -> Linux CPU 6
-                               -> [thread 1] -> Linux CPU 7
-
-      Alternative enumeration::
-
-       [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
-                               -> [thread 1] -> Linux CPU 4
-                   -> [core 1] -> [thread 0] -> Linux CPU 1
-                               -> [thread 1] -> Linux CPU 5
-
-       [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2
-                               -> [thread 1] -> Linux CPU 6
-                   -> [core 1] -> [thread 0] -> Linux CPU 3
-                               -> [thread 1] -> Linux CPU 7
-
-      AMD nomenclature for CMT systems::
-
-       [node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0
-                                    -> [Compute Unit Core 1] -> Linux CPU 1
-                -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2
-                                    -> [Compute Unit Core 1] -> Linux CPU 3
-
-       [node 1] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 4
-                                    -> [Compute Unit Core 1] -> Linux CPU 5
-                -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 6
-                                    -> [Compute Unit Core 1] -> Linux CPU 7
diff --git a/Documentation/x86/tsx_async_abort.rst b/Documentation/x86/tsx_async_abort.rst
deleted file mode 100644 (file)
index 583ddc1..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-TSX Async Abort (TAA) mitigation
-================================
-
-.. _tsx_async_abort:
-
-Overview
---------
-
-TSX Async Abort (TAA) is a side channel attack on internal buffers in some
-Intel processors similar to Microachitectural Data Sampling (MDS).  In this
-case certain loads may speculatively pass invalid data to dependent operations
-when an asynchronous abort condition is pending in a Transactional
-Synchronization Extensions (TSX) transaction.  This includes loads with no
-fault or assist condition. Such loads may speculatively expose stale data from
-the same uarch data structures as in MDS, with same scope of exposure i.e.
-same-thread and cross-thread. This issue affects all current processors that
-support TSX.
-
-Mitigation strategy
--------------------
-
-a) TSX disable - one of the mitigations is to disable TSX. A new MSR
-IA32_TSX_CTRL will be available in future and current processors after
-microcode update which can be used to disable TSX. In addition, it
-controls the enumeration of the TSX feature bits (RTM and HLE) in CPUID.
-
-b) Clear CPU buffers - similar to MDS, clearing the CPU buffers mitigates this
-vulnerability. More details on this approach can be found in
-:ref:`Documentation/admin-guide/hw-vuln/mds.rst <mds>`.
-
-Kernel internal mitigation modes
---------------------------------
-
- =============    ============================================================
- off              Mitigation is disabled. Either the CPU is not affected or
-                  tsx_async_abort=off is supplied on the kernel command line.
-
- tsx disabled     Mitigation is enabled. TSX feature is disabled by default at
-                  bootup on processors that support TSX control.
-
- verw             Mitigation is enabled. CPU is affected and MD_CLEAR is
-                  advertised in CPUID.
-
- ucode needed     Mitigation is enabled. CPU is affected and MD_CLEAR is not
-                  advertised in CPUID. That is mainly for virtualization
-                  scenarios where the host has the updated microcode but the
-                  hypervisor does not expose MD_CLEAR in CPUID. It's a best
-                  effort approach without guarantee.
- =============    ============================================================
-
-If the CPU is affected and the "tsx_async_abort" kernel command line parameter is
-not provided then the kernel selects an appropriate mitigation depending on the
-status of RTM and MD_CLEAR CPUID bits.
-
-Below tables indicate the impact of tsx=on|off|auto cmdline options on state of
-TAA mitigation, VERW behavior and TSX feature for various combinations of
-MSR_IA32_ARCH_CAPABILITIES bits.
-
-1. "tsx=off"
-
-=========  =========  ============  ============  ==============  ===================  ======================
-MSR_IA32_ARCH_CAPABILITIES bits     Result with cmdline tsx=off
-----------------------------------  -------------------------------------------------------------------------
-TAA_NO     MDS_NO     TSX_CTRL_MSR  TSX state     VERW can clear  TAA mitigation       TAA mitigation
-                                    after bootup  CPU buffers     tsx_async_abort=off  tsx_async_abort=full
-=========  =========  ============  ============  ==============  ===================  ======================
-    0          0           0         HW default         Yes           Same as MDS           Same as MDS
-    0          0           1        Invalid case   Invalid case       Invalid case          Invalid case
-    0          1           0         HW default         No         Need ucode update     Need ucode update
-    0          1           1          Disabled          Yes           TSX disabled          TSX disabled
-    1          X           1          Disabled           X             None needed           None needed
-=========  =========  ============  ============  ==============  ===================  ======================
-
-2. "tsx=on"
-
-=========  =========  ============  ============  ==============  ===================  ======================
-MSR_IA32_ARCH_CAPABILITIES bits     Result with cmdline tsx=on
-----------------------------------  -------------------------------------------------------------------------
-TAA_NO     MDS_NO     TSX_CTRL_MSR  TSX state     VERW can clear  TAA mitigation       TAA mitigation
-                                    after bootup  CPU buffers     tsx_async_abort=off  tsx_async_abort=full
-=========  =========  ============  ============  ==============  ===================  ======================
-    0          0           0         HW default        Yes            Same as MDS          Same as MDS
-    0          0           1        Invalid case   Invalid case       Invalid case         Invalid case
-    0          1           0         HW default        No          Need ucode update     Need ucode update
-    0          1           1          Enabled          Yes               None              Same as MDS
-    1          X           1          Enabled          X              None needed          None needed
-=========  =========  ============  ============  ==============  ===================  ======================
-
-3. "tsx=auto"
-
-=========  =========  ============  ============  ==============  ===================  ======================
-MSR_IA32_ARCH_CAPABILITIES bits     Result with cmdline tsx=auto
-----------------------------------  -------------------------------------------------------------------------
-TAA_NO     MDS_NO     TSX_CTRL_MSR  TSX state     VERW can clear  TAA mitigation       TAA mitigation
-                                    after bootup  CPU buffers     tsx_async_abort=off  tsx_async_abort=full
-=========  =========  ============  ============  ==============  ===================  ======================
-    0          0           0         HW default    Yes                Same as MDS           Same as MDS
-    0          0           1        Invalid case  Invalid case        Invalid case          Invalid case
-    0          1           0         HW default    No              Need ucode update     Need ucode update
-    0          1           1          Disabled      Yes               TSX disabled          TSX disabled
-    1          X           1          Enabled       X                 None needed           None needed
-=========  =========  ============  ============  ==============  ===================  ======================
-
-In the tables, TSX_CTRL_MSR is a new bit in MSR_IA32_ARCH_CAPABILITIES that
-indicates whether MSR_IA32_TSX_CTRL is supported.
-
-There are two control bits in IA32_TSX_CTRL MSR:
-
-      Bit 0: When set it disables the Restricted Transactional Memory (RTM)
-             sub-feature of TSX (will force all transactions to abort on the
-             XBEGIN instruction).
-
-      Bit 1: When set it disables the enumeration of the RTM and HLE feature
-             (i.e. it will make CPUID(EAX=7).EBX{bit4} and
-             CPUID(EAX=7).EBX{bit11} read as 0).
diff --git a/Documentation/x86/usb-legacy-support.rst b/Documentation/x86/usb-legacy-support.rst
deleted file mode 100644 (file)
index e01c08b..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-
-.. SPDX-License-Identifier: GPL-2.0
-
-==================
-USB Legacy support
-==================
-
-:Author: Vojtech Pavlik <vojtech@suse.cz>, January 2004
-
-
-Also known as "USB Keyboard" or "USB Mouse support" in the BIOS Setup is a
-feature that allows one to use the USB mouse and keyboard as if they were
-their classic PS/2 counterparts.  This means one can use an USB keyboard to
-type in LILO for example.
-
-It has several drawbacks, though:
-
-1) On some machines, the emulated PS/2 mouse takes over even when no USB
-   mouse is present and a real PS/2 mouse is present.  In that case the extra
-   features (wheel, extra buttons, touchpad mode) of the real PS/2 mouse may
-   not be available.
-
-2) If CONFIG_HIGHMEM64G is enabled, the PS/2 mouse emulation can cause
-   system crashes, because the SMM BIOS is not expecting to be in PAE mode.
-   The Intel E7505 is a typical machine where this happens.
-
-3) If AMD64 64-bit mode is enabled, again system crashes often happen,
-   because the SMM BIOS isn't expecting the CPU to be in 64-bit mode.  The
-   BIOS manufacturers only test with Windows, and Windows doesn't do 64-bit
-   yet.
-
-Solutions:
-
-Problem 1)
-  can be solved by loading the USB drivers prior to loading the
-  PS/2 mouse driver. Since the PS/2 mouse driver is in 2.6 compiled into
-  the kernel unconditionally, this means the USB drivers need to be
-  compiled-in, too.
-
-Problem 2)
-  can currently only be solved by either disabling HIGHMEM64G
-  in the kernel config or USB Legacy support in the BIOS. A BIOS update
-  could help, but so far no such update exists.
-
-Problem 3)
-  is usually fixed by a BIOS update. Check the board
-  manufacturers web site. If an update is not available, disable USB
-  Legacy support in the BIOS. If this alone doesn't help, try also adding
-  idle=poll on the kernel command line. The BIOS may be entering the SMM
-  on the HLT instruction as well.
diff --git a/Documentation/x86/x86_64/5level-paging.rst b/Documentation/x86/x86_64/5level-paging.rst
deleted file mode 100644 (file)
index b792bbd..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-==============
-5-level paging
-==============
-
-Overview
-========
-Original x86-64 was limited by 4-level paging to 256 TiB of virtual address
-space and 64 TiB of physical address space. We are already bumping into
-this limit: some vendors offer servers with 64 TiB of memory today.
-
-To overcome the limitation upcoming hardware will introduce support for
-5-level paging. It is a straight-forward extension of the current page
-table structure adding one more layer of translation.
-
-It bumps the limits to 128 PiB of virtual address space and 4 PiB of
-physical address space. This "ought to be enough for anybody" ©.
-
-QEMU 2.9 and later support 5-level paging.
-
-Virtual memory layout for 5-level paging is described in
-Documentation/x86/x86_64/mm.rst
-
-
-Enabling 5-level paging
-=======================
-CONFIG_X86_5LEVEL=y enables the feature.
-
-Kernel with CONFIG_X86_5LEVEL=y still able to boot on 4-level hardware.
-In this case additional page table level -- p4d -- will be folded at
-runtime.
-
-User-space and large virtual address space
-==========================================
-On x86, 5-level paging enables 56-bit userspace virtual address space.
-Not all user space is ready to handle wide addresses. It's known that
-at least some JIT compilers use higher bits in pointers to encode their
-information. It collides with valid pointers with 5-level paging and
-leads to crashes.
-
-To mitigate this, we are not going to allocate virtual address space
-above 47-bit by default.
-
-But userspace can ask for allocation from full address space by
-specifying hint address (with or without MAP_FIXED) above 47-bits.
-
-If hint address set above 47-bit, but MAP_FIXED is not specified, we try
-to look for unmapped area by specified address. If it's already
-occupied, we look for unmapped area in *full* address space, rather than
-from 47-bit window.
-
-A high hint address would only affect the allocation in question, but not
-any future mmap()s.
-
-Specifying high hint address on older kernel or on machine without 5-level
-paging support is safe. The hint will be ignored and kernel will fall back
-to allocation from 47-bit address space.
-
-This approach helps to easily make application's memory allocator aware
-about large address space without manually tracking allocated virtual
-address space.
-
-One important case we need to handle here is interaction with MPX.
-MPX (without MAWA extension) cannot handle addresses above 47-bit, so we
-need to make sure that MPX cannot be enabled we already have VMA above
-the boundary and forbid creating such VMAs once MPX is enabled.
diff --git a/Documentation/x86/x86_64/boot-options.rst b/Documentation/x86/x86_64/boot-options.rst
deleted file mode 100644 (file)
index cbd1412..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-===========================
-AMD64 Specific Boot Options
-===========================
-
-There are many others (usually documented in driver documentation), but
-only the AMD64 specific ones are listed here.
-
-Machine check
-=============
-Please see Documentation/x86/x86_64/machinecheck.rst for sysfs runtime tunables.
-
-   mce=off
-               Disable machine check
-   mce=no_cmci
-               Disable CMCI(Corrected Machine Check Interrupt) that
-               Intel processor supports.  Usually this disablement is
-               not recommended, but it might be handy if your hardware
-               is misbehaving.
-               Note that you'll get more problems without CMCI than with
-               due to the shared banks, i.e. you might get duplicated
-               error logs.
-   mce=dont_log_ce
-               Don't make logs for corrected errors.  All events reported
-               as corrected are silently cleared by OS.
-               This option will be useful if you have no interest in any
-               of corrected errors.
-   mce=ignore_ce
-               Disable features for corrected errors, e.g. polling timer
-               and CMCI.  All events reported as corrected are not cleared
-               by OS and remained in its error banks.
-               Usually this disablement is not recommended, however if
-               there is an agent checking/clearing corrected errors
-               (e.g. BIOS or hardware monitoring applications), conflicting
-               with OS's error handling, and you cannot deactivate the agent,
-               then this option will be a help.
-   mce=no_lmce
-               Do not opt-in to Local MCE delivery. Use legacy method
-               to broadcast MCEs.
-   mce=bootlog
-               Enable logging of machine checks left over from booting.
-               Disabled by default on AMD Fam10h and older because some BIOS
-               leave bogus ones.
-               If your BIOS doesn't do that it's a good idea to enable though
-               to make sure you log even machine check events that result
-               in a reboot. On Intel systems it is enabled by default.
-   mce=nobootlog
-               Disable boot machine check logging.
-   mce=monarchtimeout (number)
-               monarchtimeout:
-               Sets the time in us to wait for other CPUs on machine checks. 0
-               to disable.
-   mce=bios_cmci_threshold
-               Don't overwrite the bios-set CMCI threshold. This boot option
-               prevents Linux from overwriting the CMCI threshold set by the
-               bios. Without this option, Linux always sets the CMCI
-               threshold to 1. Enabling this may make memory predictive failure
-               analysis less effective if the bios sets thresholds for memory
-               errors since we will not see details for all errors.
-   mce=recovery
-               Force-enable recoverable machine check code paths
-
-   nomce (for compatibility with i386)
-               same as mce=off
-
-   Everything else is in sysfs now.
-
-APICs
-=====
-
-   apic
-       Use IO-APIC. Default
-
-   noapic
-       Don't use the IO-APIC.
-
-   disableapic
-       Don't use the local APIC
-
-   nolapic
-     Don't use the local APIC (alias for i386 compatibility)
-
-   pirq=...
-       See Documentation/x86/i386/IO-APIC.rst
-
-   noapictimer
-       Don't set up the APIC timer
-
-   no_timer_check
-       Don't check the IO-APIC timer. This can work around
-       problems with incorrect timer initialization on some boards.
-
-   apicpmtimer
-       Do APIC timer calibration using the pmtimer. Implies
-       apicmaintimer. Useful when your PIT timer is totally broken.
-
-Timing
-======
-
-  notsc
-    Deprecated, use tsc=unstable instead.
-
-  nohpet
-    Don't use the HPET timer.
-
-Idle loop
-=========
-
-  idle=poll
-    Don't do power saving in the idle loop using HLT, but poll for rescheduling
-    event. This will make the CPUs eat a lot more power, but may be useful
-    to get slightly better performance in multiprocessor benchmarks. It also
-    makes some profiling using performance counters more accurate.
-    Please note that on systems with MONITOR/MWAIT support (like Intel EM64T
-    CPUs) this option has no performance advantage over the normal idle loop.
-    It may also interact badly with hyperthreading.
-
-Rebooting
-=========
-
-   reboot=b[ios] | t[riple] | k[bd] | a[cpi] | e[fi] | p[ci] [, [w]arm | [c]old]
-      bios
-        Use the CPU reboot vector for warm reset
-      warm
-        Don't set the cold reboot flag
-      cold
-        Set the cold reboot flag
-      triple
-        Force a triple fault (init)
-      kbd
-        Use the keyboard controller. cold reset (default)
-      acpi
-        Use the ACPI RESET_REG in the FADT. If ACPI is not configured or
-        the ACPI reset does not work, the reboot path attempts the reset
-        using the keyboard controller.
-      efi
-        Use efi reset_system runtime service. If EFI is not configured or
-        the EFI reset does not work, the reboot path attempts the reset using
-        the keyboard controller.
-      pci
-        Use a write to the PCI config space register 0xcf9 to trigger reboot.
-
-   Using warm reset will be much faster especially on big memory
-   systems because the BIOS will not go through the memory check.
-   Disadvantage is that not all hardware will be completely reinitialized
-   on reboot so there may be boot problems on some systems.
-
-   reboot=force
-     Don't stop other CPUs on reboot. This can make reboot more reliable
-     in some cases.
-
-   reboot=default
-     There are some built-in platform specific "quirks" - you may see:
-     "reboot: <name> series board detected. Selecting <type> for reboots."
-     In the case where you think the quirk is in error (e.g. you have
-     newer BIOS, or newer board) using this option will ignore the built-in
-     quirk table, and use the generic default reboot actions.
-
-NUMA
-====
-
-  numa=off
-    Only set up a single NUMA node spanning all memory.
-
-  numa=noacpi
-    Don't parse the SRAT table for NUMA setup
-
-  numa=nohmat
-    Don't parse the HMAT table for NUMA setup, or soft-reserved memory
-    partitioning.
-
-  numa=fake=<size>[MG]
-    If given as a memory unit, fills all system RAM with nodes of
-    size interleaved over physical nodes.
-
-  numa=fake=<N>
-    If given as an integer, fills all system RAM with N fake nodes
-    interleaved over physical nodes.
-
-  numa=fake=<N>U
-    If given as an integer followed by 'U', it will divide each
-    physical node into N emulated nodes.
-
-ACPI
-====
-
-  acpi=off
-    Don't enable ACPI
-  acpi=ht
-    Use ACPI boot table parsing, but don't enable ACPI interpreter
-  acpi=force
-    Force ACPI on (currently not needed)
-  acpi=strict
-    Disable out of spec ACPI workarounds.
-  acpi_sci={edge,level,high,low}
-    Set up ACPI SCI interrupt.
-  acpi=noirq
-    Don't route interrupts
-  acpi=nocmcff
-    Disable firmware first mode for corrected errors. This
-    disables parsing the HEST CMC error source to check if
-    firmware has set the FF flag. This may result in
-    duplicate corrected error reports.
-
-PCI
-===
-
-  pci=off
-    Don't use PCI
-  pci=conf1
-    Use conf1 access.
-  pci=conf2
-    Use conf2 access.
-  pci=rom
-    Assign ROMs.
-  pci=assign-busses
-    Assign busses
-  pci=irqmask=MASK
-    Set PCI interrupt mask to MASK
-  pci=lastbus=NUMBER
-    Scan up to NUMBER busses, no matter what the mptable says.
-  pci=noacpi
-    Don't use ACPI to set up PCI interrupt routing.
-
-IOMMU (input/output memory management unit)
-===========================================
-Multiple x86-64 PCI-DMA mapping implementations exist, for example:
-
-   1. <kernel/dma/direct.c>: use no hardware/software IOMMU at all
-      (e.g. because you have < 3 GB memory).
-      Kernel boot message: "PCI-DMA: Disabling IOMMU"
-
-   2. <arch/x86/kernel/amd_gart_64.c>: AMD GART based hardware IOMMU.
-      Kernel boot message: "PCI-DMA: using GART IOMMU"
-
-   3. <arch/x86_64/kernel/pci-swiotlb.c> : Software IOMMU implementation. Used
-      e.g. if there is no hardware IOMMU in the system and it is need because
-      you have >3GB memory or told the kernel to us it (iommu=soft))
-      Kernel boot message: "PCI-DMA: Using software bounce buffering
-      for IO (SWIOTLB)"
-
-::
-
-  iommu=[<size>][,noagp][,off][,force][,noforce]
-  [,memaper[=<order>]][,merge][,fullflush][,nomerge]
-  [,noaperture]
-
-General iommu options:
-
-    off
-      Don't initialize and use any kind of IOMMU.
-    noforce
-      Don't force hardware IOMMU usage when it is not needed. (default).
-    force
-      Force the use of the hardware IOMMU even when it is
-      not actually needed (e.g. because < 3 GB memory).
-    soft
-      Use software bounce buffering (SWIOTLB) (default for
-      Intel machines). This can be used to prevent the usage
-      of an available hardware IOMMU.
-
-iommu options only relevant to the AMD GART hardware IOMMU:
-
-    <size>
-      Set the size of the remapping area in bytes.
-    allowed
-      Overwrite iommu off workarounds for specific chipsets.
-    fullflush
-      Flush IOMMU on each allocation (default).
-    nofullflush
-      Don't use IOMMU fullflush.
-    memaper[=<order>]
-      Allocate an own aperture over RAM with size 32MB<<order.
-      (default: order=1, i.e. 64MB)
-    merge
-      Do scatter-gather (SG) merging. Implies "force" (experimental).
-    nomerge
-      Don't do scatter-gather (SG) merging.
-    noaperture
-      Ask the IOMMU not to touch the aperture for AGP.
-    noagp
-      Don't initialize the AGP driver and use full aperture.
-    panic
-      Always panic when IOMMU overflows.
-
-iommu options only relevant to the software bounce buffering (SWIOTLB) IOMMU
-implementation:
-
-    swiotlb=<slots>[,force,noforce]
-      <slots>
-        Prereserve that many 2K slots for the software IO bounce buffering.
-      force
-        Force all IO through the software TLB.
-      noforce
-        Do not initialize the software TLB.
-
-
-Miscellaneous
-=============
-
-  nogbpages
-    Do not use GB pages for kernel direct mappings.
-  gbpages
-    Use GB pages for kernel direct mappings.
-
-
-AMD SEV (Secure Encrypted Virtualization)
-=========================================
-Options relating to AMD SEV, specified via the following format:
-
-::
-
-   sev=option1[,option2]
-
-The available options are:
-
-   debug
-     Enable debug messages.
diff --git a/Documentation/x86/x86_64/cpu-hotplug-spec.rst b/Documentation/x86/x86_64/cpu-hotplug-spec.rst
deleted file mode 100644 (file)
index 8d1c91f..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-===================================================
-Firmware support for CPU hotplug under Linux/x86-64
-===================================================
-
-Linux/x86-64 supports CPU hotplug now. For various reasons Linux wants to
-know in advance of boot time the maximum number of CPUs that could be plugged
-into the system. ACPI 3.0 currently has no official way to supply
-this information from the firmware to the operating system.
-
-In ACPI each CPU needs an LAPIC object in the MADT table (5.2.11.5 in the
-ACPI 3.0 specification).  ACPI already has the concept of disabled LAPIC
-objects by setting the Enabled bit in the LAPIC object to zero.
-
-For CPU hotplug Linux/x86-64 expects now that any possible future hotpluggable
-CPU is already available in the MADT. If the CPU is not available yet
-it should have its LAPIC Enabled bit set to 0. Linux will use the number
-of disabled LAPICs to compute the maximum number of future CPUs.
-
-In the worst case the user can overwrite this choice using a command line
-option (additional_cpus=...), but it is recommended to supply the correct
-number (or a reasonable approximation of it, with erring towards more not less)
-in the MADT to avoid manual configuration.
diff --git a/Documentation/x86/x86_64/fake-numa-for-cpusets.rst b/Documentation/x86/x86_64/fake-numa-for-cpusets.rst
deleted file mode 100644 (file)
index ff9bcfd..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=====================
-Fake NUMA For CPUSets
-=====================
-
-:Author: David Rientjes <rientjes@cs.washington.edu>
-
-Using numa=fake and CPUSets for Resource Management
-
-This document describes how the numa=fake x86_64 command-line option can be used
-in conjunction with cpusets for coarse memory management.  Using this feature,
-you can create fake NUMA nodes that represent contiguous chunks of memory and
-assign them to cpusets and their attached tasks.  This is a way of limiting the
-amount of system memory that are available to a certain class of tasks.
-
-For more information on the features of cpusets, see
-Documentation/admin-guide/cgroup-v1/cpusets.rst.
-There are a number of different configurations you can use for your needs.  For
-more information on the numa=fake command line option and its various ways of
-configuring fake nodes, see Documentation/x86/x86_64/boot-options.rst.
-
-For the purposes of this introduction, we'll assume a very primitive NUMA
-emulation setup of "numa=fake=4*512,".  This will split our system memory into
-four equal chunks of 512M each that we can now use to assign to cpusets.  As
-you become more familiar with using this combination for resource control,
-you'll determine a better setup to minimize the number of nodes you have to deal
-with.
-
-A machine may be split as follows with "numa=fake=4*512," as reported by dmesg::
-
-       Faking node 0 at 0000000000000000-0000000020000000 (512MB)
-       Faking node 1 at 0000000020000000-0000000040000000 (512MB)
-       Faking node 2 at 0000000040000000-0000000060000000 (512MB)
-       Faking node 3 at 0000000060000000-0000000080000000 (512MB)
-       ...
-       On node 0 totalpages: 130975
-       On node 1 totalpages: 131072
-       On node 2 totalpages: 131072
-       On node 3 totalpages: 131072
-
-Now following the instructions for mounting the cpusets filesystem from
-Documentation/admin-guide/cgroup-v1/cpusets.rst, you can assign fake nodes (i.e. contiguous memory
-address spaces) to individual cpusets::
-
-       [root@xroads /]# mkdir exampleset
-       [root@xroads /]# mount -t cpuset none exampleset
-       [root@xroads /]# mkdir exampleset/ddset
-       [root@xroads /]# cd exampleset/ddset
-       [root@xroads /exampleset/ddset]# echo 0-1 > cpus
-       [root@xroads /exampleset/ddset]# echo 0-1 > mems
-
-Now this cpuset, 'ddset', will only allowed access to fake nodes 0 and 1 for
-memory allocations (1G).
-
-You can now assign tasks to these cpusets to limit the memory resources
-available to them according to the fake nodes assigned as mems::
-
-       [root@xroads /exampleset/ddset]# echo $$ > tasks
-       [root@xroads /exampleset/ddset]# dd if=/dev/zero of=tmp bs=1024 count=1G
-       [1] 13425
-
-Notice the difference between the system memory usage as reported by
-/proc/meminfo between the restricted cpuset case above and the unrestricted
-case (i.e. running the same 'dd' command without assigning it to a fake NUMA
-cpuset):
-
-       ========        ============    ==========
-       Name            Unrestricted    Restricted
-       ========        ============    ==========
-       MemTotal        3091900 kB      3091900 kB
-       MemFree         42113 kB        1513236 kB
-       ========        ============    ==========
-
-This allows for coarse memory management for the tasks you assign to particular
-cpusets.  Since cpusets can form a hierarchy, you can create some pretty
-interesting combinations of use-cases for various classes of tasks for your
-memory management needs.
diff --git a/Documentation/x86/x86_64/fsgs.rst b/Documentation/x86/x86_64/fsgs.rst
deleted file mode 100644 (file)
index 50960e0..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Using FS and GS segments in user space applications
-===================================================
-
-The x86 architecture supports segmentation. Instructions which access
-memory can use segment register based addressing mode. The following
-notation is used to address a byte within a segment:
-
-  Segment-register:Byte-address
-
-The segment base address is added to the Byte-address to compute the
-resulting virtual address which is accessed. This allows to access multiple
-instances of data with the identical Byte-address, i.e. the same code. The
-selection of a particular instance is purely based on the base-address in
-the segment register.
-
-In 32-bit mode the CPU provides 6 segments, which also support segment
-limits. The limits can be used to enforce address space protections.
-
-In 64-bit mode the CS/SS/DS/ES segments are ignored and the base address is
-always 0 to provide a full 64bit address space. The FS and GS segments are
-still functional in 64-bit mode.
-
-Common FS and GS usage
-------------------------------
-
-The FS segment is commonly used to address Thread Local Storage (TLS). FS
-is usually managed by runtime code or a threading library. Variables
-declared with the '__thread' storage class specifier are instantiated per
-thread and the compiler emits the FS: address prefix for accesses to these
-variables. Each thread has its own FS base address so common code can be
-used without complex address offset calculations to access the per thread
-instances. Applications should not use FS for other purposes when they use
-runtimes or threading libraries which manage the per thread FS.
-
-The GS segment has no common use and can be used freely by
-applications. GCC and Clang support GS based addressing via address space
-identifiers.
-
-Reading and writing the FS/GS base address
-------------------------------------------
-
-There exist two mechanisms to read and write the FS/GS base address:
-
- - the arch_prctl() system call
-
- - the FSGSBASE instruction family
-
-Accessing FS/GS base with arch_prctl()
---------------------------------------
-
- The arch_prctl(2) based mechanism is available on all 64-bit CPUs and all
- kernel versions.
-
- Reading the base:
-
-   arch_prctl(ARCH_GET_FS, &fsbase);
-   arch_prctl(ARCH_GET_GS, &gsbase);
-
- Writing the base:
-
-   arch_prctl(ARCH_SET_FS, fsbase);
-   arch_prctl(ARCH_SET_GS, gsbase);
-
- The ARCH_SET_GS prctl may be disabled depending on kernel configuration
- and security settings.
-
-Accessing FS/GS base with the FSGSBASE instructions
----------------------------------------------------
-
- With the Ivy Bridge CPU generation Intel introduced a new set of
- instructions to access the FS and GS base registers directly from user
- space. These instructions are also supported on AMD Family 17H CPUs. The
- following instructions are available:
-
-  =============== ===========================
-  RDFSBASE %reg   Read the FS base register
-  RDGSBASE %reg   Read the GS base register
-  WRFSBASE %reg   Write the FS base register
-  WRGSBASE %reg   Write the GS base register
-  =============== ===========================
-
- The instructions avoid the overhead of the arch_prctl() syscall and allow
- more flexible usage of the FS/GS addressing modes in user space
- applications. This does not prevent conflicts between threading libraries
- and runtimes which utilize FS and applications which want to use it for
- their own purpose.
-
-FSGSBASE instructions enablement
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- The instructions are enumerated in CPUID leaf 7, bit 0 of EBX. If
- available /proc/cpuinfo shows 'fsgsbase' in the flag entry of the CPUs.
-
- The availability of the instructions does not enable them
- automatically. The kernel has to enable them explicitly in CR4. The
- reason for this is that older kernels make assumptions about the values in
- the GS register and enforce them when GS base is set via
- arch_prctl(). Allowing user space to write arbitrary values to GS base
- would violate these assumptions and cause malfunction.
-
- On kernels which do not enable FSGSBASE the execution of the FSGSBASE
- instructions will fault with a #UD exception.
-
- The kernel provides reliable information about the enabled state in the
- ELF AUX vector. If the HWCAP2_FSGSBASE bit is set in the AUX vector, the
- kernel has FSGSBASE instructions enabled and applications can use them.
- The following code example shows how this detection works::
-
-   #include <sys/auxv.h>
-   #include <elf.h>
-
-   /* Will be eventually in asm/hwcap.h */
-   #ifndef HWCAP2_FSGSBASE
-   #define HWCAP2_FSGSBASE        (1 << 1)
-   #endif
-
-   ....
-
-   unsigned val = getauxval(AT_HWCAP2);
-
-   if (val & HWCAP2_FSGSBASE)
-        printf("FSGSBASE enabled\n");
-
-FSGSBASE instructions compiler support
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-GCC version 4.6.4 and newer provide instrinsics for the FSGSBASE
-instructions. Clang 5 supports them as well.
-
-  =================== ===========================
-  _readfsbase_u64()   Read the FS base register
-  _readfsbase_u64()   Read the GS base register
-  _writefsbase_u64()  Write the FS base register
-  _writegsbase_u64()  Write the GS base register
-  =================== ===========================
-
-To utilize these instrinsics <immintrin.h> must be included in the source
-code and the compiler option -mfsgsbase has to be added.
-
-Compiler support for FS/GS based addressing
--------------------------------------------
-
-GCC version 6 and newer provide support for FS/GS based addressing via
-Named Address Spaces. GCC implements the following address space
-identifiers for x86:
-
-  ========= ====================================
-  __seg_fs  Variable is addressed relative to FS
-  __seg_gs  Variable is addressed relative to GS
-  ========= ====================================
-
-The preprocessor symbols __SEG_FS and __SEG_GS are defined when these
-address spaces are supported. Code which implements fallback modes should
-check whether these symbols are defined. Usage example::
-
-  #ifdef __SEG_GS
-
-  long data0 = 0;
-  long data1 = 1;
-
-  long __seg_gs *ptr;
-
-  /* Check whether FSGSBASE is enabled by the kernel (HWCAP2_FSGSBASE) */
-  ....
-
-  /* Set GS base to point to data0 */
-  _writegsbase_u64(&data0);
-
-  /* Access offset 0 of GS */
-  ptr = 0;
-  printf("data0 = %ld\n", *ptr);
-
-  /* Set GS base to point to data1 */
-  _writegsbase_u64(&data1);
-  /* ptr still addresses offset 0! */
-  printf("data1 = %ld\n", *ptr);
-
-
-Clang does not provide the GCC address space identifiers, but it provides
-address spaces via an attribute based mechanism in Clang 2.6 and newer
-versions:
-
- ==================================== =====================================
-  __attribute__((address_space(256))  Variable is addressed relative to GS
-  __attribute__((address_space(257))  Variable is addressed relative to FS
- ==================================== =====================================
-
-FS/GS based addressing with inline assembly
--------------------------------------------
-
-In case the compiler does not support address spaces, inline assembly can
-be used for FS/GS based addressing mode::
-
-       mov %fs:offset, %reg
-       mov %gs:offset, %reg
-
-       mov %reg, %fs:offset
-       mov %reg, %gs:offset
diff --git a/Documentation/x86/x86_64/index.rst b/Documentation/x86/x86_64/index.rst
deleted file mode 100644 (file)
index a56070f..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-==============
-x86_64 Support
-==============
-
-.. toctree::
-   :maxdepth: 2
-
-   boot-options
-   uefi
-   mm
-   5level-paging
-   fake-numa-for-cpusets
-   cpu-hotplug-spec
-   machinecheck
-   fsgs
diff --git a/Documentation/x86/x86_64/machinecheck.rst b/Documentation/x86/x86_64/machinecheck.rst
deleted file mode 100644 (file)
index cea12ee..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-===============================================================
-Configurable sysfs parameters for the x86-64 machine check code
-===============================================================
-
-Machine checks report internal hardware error conditions detected
-by the CPU. Uncorrected errors typically cause a machine check
-(often with panic), corrected ones cause a machine check log entry.
-
-Machine checks are organized in banks (normally associated with
-a hardware subsystem) and subevents in a bank. The exact meaning
-of the banks and subevent is CPU specific.
-
-mcelog knows how to decode them.
-
-When you see the "Machine check errors logged" message in the system
-log then mcelog should run to collect and decode machine check entries
-from /dev/mcelog. Normally mcelog should be run regularly from a cronjob.
-
-Each CPU has a directory in /sys/devices/system/machinecheck/machinecheckN
-(N = CPU number).
-
-The directory contains some configurable entries. See
-Documentation/ABI/testing/sysfs-mce for more details.
-
-TBD document entries for AMD threshold interrupt configuration
-
-For more details about the x86 machine check architecture
-see the Intel and AMD architecture manuals from their developer websites.
-
-For more details about the architecture
-see http://one.firstfloor.org/~andi/mce.pdf
diff --git a/Documentation/x86/x86_64/mm.rst b/Documentation/x86/x86_64/mm.rst
deleted file mode 100644 (file)
index 35e5e18..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=================
-Memory Management
-=================
-
-Complete virtual memory map with 4-level page tables
-====================================================
-
-.. note::
-
- - Negative addresses such as "-23 TB" are absolute addresses in bytes, counted down
-   from the top of the 64-bit address space. It's easier to understand the layout
-   when seen both in absolute addresses and in distance-from-top notation.
-
-   For example 0xffffe90000000000 == -23 TB, it's 23 TB lower than the top of the
-   64-bit address space (ffffffffffffffff).
-
-   Note that as we get closer to the top of the address space, the notation changes
-   from TB to GB and then MB/KB.
-
- - "16M TB" might look weird at first sight, but it's an easier way to visualize size
-   notation than "16 EB", which few will recognize at first sight as 16 exabytes.
-   It also shows it nicely how incredibly large 64-bit address space is.
-
-::
-
-  ========================================================================================================================
-      Start addr    |   Offset   |     End addr     |  Size   | VM area description
-  ========================================================================================================================
-                    |            |                  |         |
-   0000000000000000 |    0       | 00007fffffffffff |  128 TB | user-space virtual memory, different per mm
-  __________________|____________|__________________|_________|___________________________________________________________
-                    |            |                  |         |
-   0000800000000000 | +128    TB | ffff7fffffffffff | ~16M TB | ... huge, almost 64 bits wide hole of non-canonical
-                    |            |                  |         |     virtual memory addresses up to the -128 TB
-                    |            |                  |         |     starting offset of kernel mappings.
-  __________________|____________|__________________|_________|___________________________________________________________
-                                                              |
-                                                              | Kernel-space virtual memory, shared between all processes:
-  ____________________________________________________________|___________________________________________________________
-                    |            |                  |         |
-   ffff800000000000 | -128    TB | ffff87ffffffffff |    8 TB | ... guard hole, also reserved for hypervisor
-   ffff880000000000 | -120    TB | ffff887fffffffff |  0.5 TB | LDT remap for PTI
-   ffff888000000000 | -119.5  TB | ffffc87fffffffff |   64 TB | direct mapping of all physical memory (page_offset_base)
-   ffffc88000000000 |  -55.5  TB | ffffc8ffffffffff |  0.5 TB | ... unused hole
-   ffffc90000000000 |  -55    TB | ffffe8ffffffffff |   32 TB | vmalloc/ioremap space (vmalloc_base)
-   ffffe90000000000 |  -23    TB | ffffe9ffffffffff |    1 TB | ... unused hole
-   ffffea0000000000 |  -22    TB | ffffeaffffffffff |    1 TB | virtual memory map (vmemmap_base)
-   ffffeb0000000000 |  -21    TB | ffffebffffffffff |    1 TB | ... unused hole
-   ffffec0000000000 |  -20    TB | fffffbffffffffff |   16 TB | KASAN shadow memory
-  __________________|____________|__________________|_________|____________________________________________________________
-                                                              |
-                                                              | Identical layout to the 56-bit one from here on:
-  ____________________________________________________________|____________________________________________________________
-                    |            |                  |         |
-   fffffc0000000000 |   -4    TB | fffffdffffffffff |    2 TB | ... unused hole
-                    |            |                  |         | vaddr_end for KASLR
-   fffffe0000000000 |   -2    TB | fffffe7fffffffff |  0.5 TB | cpu_entry_area mapping
-   fffffe8000000000 |   -1.5  TB | fffffeffffffffff |  0.5 TB | ... unused hole
-   ffffff0000000000 |   -1    TB | ffffff7fffffffff |  0.5 TB | %esp fixup stacks
-   ffffff8000000000 | -512    GB | ffffffeeffffffff |  444 GB | ... unused hole
-   ffffffef00000000 |  -68    GB | fffffffeffffffff |   64 GB | EFI region mapping space
-   ffffffff00000000 |   -4    GB | ffffffff7fffffff |    2 GB | ... unused hole
-   ffffffff80000000 |   -2    GB | ffffffff9fffffff |  512 MB | kernel text mapping, mapped to physical address 0
-   ffffffff80000000 |-2048    MB |                  |         |
-   ffffffffa0000000 |-1536    MB | fffffffffeffffff | 1520 MB | module mapping space
-   ffffffffff000000 |  -16    MB |                  |         |
-      FIXADDR_START | ~-11    MB | ffffffffff5fffff | ~0.5 MB | kernel-internal fixmap range, variable size and offset
-   ffffffffff600000 |  -10    MB | ffffffffff600fff |    4 kB | legacy vsyscall ABI
-   ffffffffffe00000 |   -2    MB | ffffffffffffffff |    2 MB | ... unused hole
-  __________________|____________|__________________|_________|___________________________________________________________
-
-
-Complete virtual memory map with 5-level page tables
-====================================================
-
-.. note::
-
- - With 56-bit addresses, user-space memory gets expanded by a factor of 512x,
-   from 0.125 PB to 64 PB. All kernel mappings shift down to the -64 PB starting
-   offset and many of the regions expand to support the much larger physical
-   memory supported.
-
-::
-
-  ========================================================================================================================
-      Start addr    |   Offset   |     End addr     |  Size   | VM area description
-  ========================================================================================================================
-                    |            |                  |         |
-   0000000000000000 |    0       | 00ffffffffffffff |   64 PB | user-space virtual memory, different per mm
-  __________________|____________|__________________|_________|___________________________________________________________
-                    |            |                  |         |
-   0100000000000000 |  +64    PB | feffffffffffffff | ~16K PB | ... huge, still almost 64 bits wide hole of non-canonical
-                    |            |                  |         |     virtual memory addresses up to the -64 PB
-                    |            |                  |         |     starting offset of kernel mappings.
-  __________________|____________|__________________|_________|___________________________________________________________
-                                                              |
-                                                              | Kernel-space virtual memory, shared between all processes:
-  ____________________________________________________________|___________________________________________________________
-                    |            |                  |         |
-   ff00000000000000 |  -64    PB | ff0fffffffffffff |    4 PB | ... guard hole, also reserved for hypervisor
-   ff10000000000000 |  -60    PB | ff10ffffffffffff | 0.25 PB | LDT remap for PTI
-   ff11000000000000 |  -59.75 PB | ff90ffffffffffff |   32 PB | direct mapping of all physical memory (page_offset_base)
-   ff91000000000000 |  -27.75 PB | ff9fffffffffffff | 3.75 PB | ... unused hole
-   ffa0000000000000 |  -24    PB | ffd1ffffffffffff | 12.5 PB | vmalloc/ioremap space (vmalloc_base)
-   ffd2000000000000 |  -11.5  PB | ffd3ffffffffffff |  0.5 PB | ... unused hole
-   ffd4000000000000 |  -11    PB | ffd5ffffffffffff |  0.5 PB | virtual memory map (vmemmap_base)
-   ffd6000000000000 |  -10.5  PB | ffdeffffffffffff | 2.25 PB | ... unused hole
-   ffdf000000000000 |   -8.25 PB | fffffbffffffffff |   ~8 PB | KASAN shadow memory
-  __________________|____________|__________________|_________|____________________________________________________________
-                                                              |
-                                                              | Identical layout to the 47-bit one from here on:
-  ____________________________________________________________|____________________________________________________________
-                    |            |                  |         |
-   fffffc0000000000 |   -4    TB | fffffdffffffffff |    2 TB | ... unused hole
-                    |            |                  |         | vaddr_end for KASLR
-   fffffe0000000000 |   -2    TB | fffffe7fffffffff |  0.5 TB | cpu_entry_area mapping
-   fffffe8000000000 |   -1.5  TB | fffffeffffffffff |  0.5 TB | ... unused hole
-   ffffff0000000000 |   -1    TB | ffffff7fffffffff |  0.5 TB | %esp fixup stacks
-   ffffff8000000000 | -512    GB | ffffffeeffffffff |  444 GB | ... unused hole
-   ffffffef00000000 |  -68    GB | fffffffeffffffff |   64 GB | EFI region mapping space
-   ffffffff00000000 |   -4    GB | ffffffff7fffffff |    2 GB | ... unused hole
-   ffffffff80000000 |   -2    GB | ffffffff9fffffff |  512 MB | kernel text mapping, mapped to physical address 0
-   ffffffff80000000 |-2048    MB |                  |         |
-   ffffffffa0000000 |-1536    MB | fffffffffeffffff | 1520 MB | module mapping space
-   ffffffffff000000 |  -16    MB |                  |         |
-      FIXADDR_START | ~-11    MB | ffffffffff5fffff | ~0.5 MB | kernel-internal fixmap range, variable size and offset
-   ffffffffff600000 |  -10    MB | ffffffffff600fff |    4 kB | legacy vsyscall ABI
-   ffffffffffe00000 |   -2    MB | ffffffffffffffff |    2 MB | ... unused hole
-  __________________|____________|__________________|_________|___________________________________________________________
-
-Architecture defines a 64-bit virtual address. Implementations can support
-less. Currently supported are 48- and 57-bit virtual addresses. Bits 63
-through to the most-significant implemented bit are sign extended.
-This causes hole between user space and kernel addresses if you interpret them
-as unsigned.
-
-The direct mapping covers all memory in the system up to the highest
-memory address (this means in some cases it can also include PCI memory
-holes).
-
-We map EFI runtime services in the 'efi_pgd' PGD in a 64GB large virtual
-memory window (this size is arbitrary, it can be raised later if needed).
-The mappings are not part of any other kernel PGD and are only available
-during EFI runtime calls.
-
-Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all
-physical memory, vmalloc/ioremap space and virtual memory map are randomized.
-Their order is preserved but their base will be offset early at boot time.
-
-Be very careful vs. KASLR when changing anything here. The KASLR address
-range must not overlap with anything except the KASAN shadow area, which is
-correct as KASAN disables KASLR.
-
-For both 4- and 5-level layouts, the STACKLEAK_POISON value in the last 2MB
-hole: ffffffffffff4111
diff --git a/Documentation/x86/x86_64/uefi.rst b/Documentation/x86/x86_64/uefi.rst
deleted file mode 100644 (file)
index fbc30c9..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=====================================
-General note on [U]EFI x86_64 support
-=====================================
-
-The nomenclature EFI and UEFI are used interchangeably in this document.
-
-Although the tools below are _not_ needed for building the kernel,
-the needed bootloader support and associated tools for x86_64 platforms
-with EFI firmware and specifications are listed below.
-
-1. UEFI specification:  http://www.uefi.org
-
-2. Booting Linux kernel on UEFI x86_64 platform requires bootloader
-   support. Elilo with x86_64 support can be used.
-
-3. x86_64 platform with EFI/UEFI firmware.
-
-Mechanics
----------
-
-- Build the kernel with the following configuration::
-
-       CONFIG_FB_EFI=y
-       CONFIG_FRAMEBUFFER_CONSOLE=y
-
-  If EFI runtime services are expected, the following configuration should
-  be selected::
-
-       CONFIG_EFI=y
-       CONFIG_EFIVAR_FS=y or m         # optional
-
-- Create a VFAT partition on the disk
-- Copy the following to the VFAT partition:
-
-       elilo bootloader with x86_64 support, elilo configuration file,
-       kernel image built in first step and corresponding
-       initrd. Instructions on building elilo and its dependencies
-       can be found in the elilo sourceforge project.
-
-- Boot to EFI shell and invoke elilo choosing the kernel image built
-  in first step.
-- If some or all EFI runtime services don't work, you can try following
-  kernel command line parameters to turn off some or all EFI runtime
-  services.
-
-       noefi
-               turn off all EFI runtime services
-       reboot_type=k
-               turn off EFI reboot runtime service
-
-- If the EFI memory map has additional entries not in the E820 map,
-  you can include those entries in the kernels memory map of available
-  physical RAM by using the following kernel command line parameter.
-
-       add_efi_memmap
-               include EFI memory map of available physical RAM
diff --git a/Documentation/x86/xstate.rst b/Documentation/x86/xstate.rst
deleted file mode 100644 (file)
index 5cec7fb..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-Using XSTATE features in user space applications
-================================================
-
-The x86 architecture supports floating-point extensions which are
-enumerated via CPUID. Applications consult CPUID and use XGETBV to
-evaluate which features have been enabled by the kernel XCR0.
-
-Up to AVX-512 and PKRU states, these features are automatically enabled by
-the kernel if available. Features like AMX TILE_DATA (XSTATE component 18)
-are enabled by XCR0 as well, but the first use of related instruction is
-trapped by the kernel because by default the required large XSTATE buffers
-are not allocated automatically.
-
-Using dynamically enabled XSTATE features in user space applications
---------------------------------------------------------------------
-
-The kernel provides an arch_prctl(2) based mechanism for applications to
-request the usage of such features. The arch_prctl(2) options related to
-this are:
-
--ARCH_GET_XCOMP_SUPP
-
- arch_prctl(ARCH_GET_XCOMP_SUPP, &features);
-
- ARCH_GET_XCOMP_SUPP stores the supported features in userspace storage of
- type uint64_t. The second argument is a pointer to that storage.
-
--ARCH_GET_XCOMP_PERM
-
- arch_prctl(ARCH_GET_XCOMP_PERM, &features);
-
- ARCH_GET_XCOMP_PERM stores the features for which the userspace process
- has permission in userspace storage of type uint64_t. The second argument
- is a pointer to that storage.
-
--ARCH_REQ_XCOMP_PERM
-
- arch_prctl(ARCH_REQ_XCOMP_PERM, feature_nr);
-
- ARCH_REQ_XCOMP_PERM allows to request permission for a dynamically enabled
- feature or a feature set. A feature set can be mapped to a facility, e.g.
- AMX, and can require one or more XSTATE components to be enabled.
-
- The feature argument is the number of the highest XSTATE component which
- is required for a facility to work.
-
-When requesting permission for a feature, the kernel checks the
-availability. The kernel ensures that sigaltstacks in the process's tasks
-are large enough to accommodate the resulting large signal frame. It
-enforces this both during ARCH_REQ_XCOMP_SUPP and during any subsequent
-sigaltstack(2) calls. If an installed sigaltstack is smaller than the
-resulting sigframe size, ARCH_REQ_XCOMP_SUPP results in -ENOSUPP. Also,
-sigaltstack(2) results in -ENOMEM if the requested altstack is too small
-for the permitted features.
-
-Permission, when granted, is valid per process. Permissions are inherited
-on fork(2) and cleared on exec(3).
-
-The first use of an instruction related to a dynamically enabled feature is
-trapped by the kernel. The trap handler checks whether the process has
-permission to use the feature. If the process has no permission then the
-kernel sends SIGILL to the application. If the process has permission then
-the handler allocates a larger xstate buffer for the task so the large
-state can be context switched. In the unlikely cases that the allocation
-fails, the kernel sends SIGSEGV.
-
-Dynamic features in signal frames
----------------------------------
-
-Dynamcally enabled features are not written to the signal frame upon signal
-entry if the feature is in its initial configuration.  This differs from
-non-dynamic features which are always written regardless of their
-configuration.  Signal handlers can examine the XSAVE buffer's XSTATE_BV
-field to determine if a features was written.
diff --git a/Documentation/x86/zero-page.rst b/Documentation/x86/zero-page.rst
deleted file mode 100644 (file)
index 45aa9cc..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=========
-Zero Page
-=========
-The additional fields in struct boot_params as a part of 32-bit boot
-protocol of kernel. These should be filled by bootloader or 16-bit
-real-mode setup code of the kernel. References/settings to it mainly
-are in::
-
-  arch/x86/include/uapi/asm/bootparam.h
-
-===========    =====   ======================= =================================================
-Offset/Size    Proto   Name                    Meaning
-
-000/040                ALL     screen_info             Text mode or frame buffer information
-                                               (struct screen_info)
-040/014                ALL     apm_bios_info           APM BIOS information (struct apm_bios_info)
-058/008                ALL     tboot_addr              Physical address of tboot shared page
-060/010                ALL     ist_info                Intel SpeedStep (IST) BIOS support information
-                                               (struct ist_info)
-070/008                ALL     acpi_rsdp_addr          Physical address of ACPI RSDP table
-080/010                ALL     hd0_info                hd0 disk parameter, OBSOLETE!!
-090/010                ALL     hd1_info                hd1 disk parameter, OBSOLETE!!
-0A0/010                ALL     sys_desc_table          System description table (struct sys_desc_table),
-                                               OBSOLETE!!
-0B0/010                ALL     olpc_ofw_header         OLPC's OpenFirmware CIF and friends
-0C0/004                ALL     ext_ramdisk_image       ramdisk_image high 32bits
-0C4/004                ALL     ext_ramdisk_size        ramdisk_size high 32bits
-0C8/004                ALL     ext_cmd_line_ptr        cmd_line_ptr high 32bits
-13C/004                ALL     cc_blob_address         Physical address of Confidential Computing blob
-140/080                ALL     edid_info               Video mode setup (struct edid_info)
-1C0/020                ALL     efi_info                EFI 32 information (struct efi_info)
-1E0/004                ALL     alt_mem_k               Alternative mem check, in KB
-1E4/004                ALL     scratch                 Scratch field for the kernel setup code
-1E8/001                ALL     e820_entries            Number of entries in e820_table (below)
-1E9/001                ALL     eddbuf_entries          Number of entries in eddbuf (below)
-1EA/001                ALL     edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer
-                                               (below)
-1EB/001                ALL     kbd_status              Numlock is enabled
-1EC/001                ALL     secure_boot             Secure boot is enabled in the firmware
-1EF/001                ALL     sentinel                Used to detect broken bootloaders
-290/040                ALL     edd_mbr_sig_buffer      EDD MBR signatures
-2D0/A00                ALL     e820_table              E820 memory map table
-                                               (array of struct e820_entry)
-D00/1EC                ALL     eddbuf                  EDD data (array of struct edd_info)
-===========    =====   ======================= =================================================
diff --git a/Documentation/xtensa/atomctl.rst b/Documentation/xtensa/atomctl.rst
deleted file mode 100644 (file)
index 1ecbd0b..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-===========================================
-Atomic Operation Control (ATOMCTL) Register
-===========================================
-
-We Have Atomic Operation Control (ATOMCTL) Register.
-This register determines the effect of using a S32C1I instruction
-with various combinations of:
-
-     1. With and without an Coherent Cache Controller which
-        can do Atomic Transactions to the memory internally.
-
-     2. With and without An Intelligent Memory Controller which
-        can do Atomic Transactions itself.
-
-The Core comes up with a default value of for the three types of cache ops::
-
-      0x28: (WB: Internal, WT: Internal, BY:Exception)
-
-On the FPGA Cards we typically simulate an Intelligent Memory controller
-which can implement  RCW transactions. For FPGA cards with an External
-Memory controller we let it to the atomic operations internally while
-doing a Cached (WB) transaction and use the Memory RCW for un-cached
-operations.
-
-For systems without an coherent cache controller, non-MX, we always
-use the memory controllers RCW, thought non-MX controlers likely
-support the Internal Operation.
-
-CUSTOMER-WARNING:
-   Virtually all customers buy their memory controllers from vendors that
-   don't support atomic RCW memory transactions and will likely want to
-   configure this register to not use RCW.
-
-Developers might find using RCW in Bypass mode convenient when testing
-with the cache being bypassed; for example studying cache alias problems.
-
-See Section 4.3.12.4 of ISA; Bits::
-
-                             WB     WT      BY
-                           5   4 | 3   2 | 1   0
-
-=========    ==================      ==================      ===============
-  2 Bit
-  Field
-  Values     WB - Write Back         WT - Write Thru         BY - Bypass
-=========    ==================      ==================      ===============
-    0        Exception               Exception               Exception
-    1        RCW Transaction         RCW Transaction         RCW Transaction
-    2        Internal Operation      Internal Operation      Reserved
-    3        Reserved                Reserved                Reserved
-=========    ==================      ==================      ===============
diff --git a/Documentation/xtensa/booting.rst b/Documentation/xtensa/booting.rst
deleted file mode 100644 (file)
index e1b8370..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-=====================================
-Passing boot parameters to the kernel
-=====================================
-
-Boot parameters are represented as a TLV list in the memory. Please see
-arch/xtensa/include/asm/bootparam.h for definition of the bp_tag structure and
-tag value constants. First entry in the list must have type BP_TAG_FIRST, last
-entry must have type BP_TAG_LAST. The address of the first list entry is
-passed to the kernel in the register a2. The address type depends on MMU type:
-
-- For configurations without MMU, with region protection or with MPU the
-  address must be the physical address.
-- For configurations with region translarion MMU or with MMUv3 and CONFIG_MMU=n
-  the address must be a valid address in the current mapping. The kernel will
-  not change the mapping on its own.
-- For configurations with MMUv2 the address must be a virtual address in the
-  default virtual mapping (0xd0000000..0xffffffff).
-- For configurations with MMUv3 and CONFIG_MMU=y the address may be either a
-  virtual or physical address. In either case it must be within the default
-  virtual mapping. It is considered physical if it is within the range of
-  physical addresses covered by the default KSEG mapping (XCHAL_KSEG_PADDR..
-  XCHAL_KSEG_PADDR + XCHAL_KSEG_SIZE), otherwise it is considered virtual.
diff --git a/Documentation/xtensa/features.rst b/Documentation/xtensa/features.rst
deleted file mode 100644 (file)
index 6b92c7b..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. kernel-feat:: $srctree/Documentation/features xtensa
diff --git a/Documentation/xtensa/index.rst b/Documentation/xtensa/index.rst
deleted file mode 100644 (file)
index 6995244..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-===================
-Xtensa Architecture
-===================
-
-.. toctree::
-   :maxdepth: 1
-
-   atomctl
-   booting
-   mmu
-
-   features
diff --git a/Documentation/xtensa/mmu.rst b/Documentation/xtensa/mmu.rst
deleted file mode 100644 (file)
index 450573a..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-=============================
-MMUv3 initialization sequence
-=============================
-
-The code in the initialize_mmu macro sets up MMUv3 memory mapping
-identically to MMUv2 fixed memory mapping. Depending on
-CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX symbol this code is
-located in addresses it was linked for (symbol undefined), or not
-(symbol defined), so it needs to be position-independent.
-
-The code has the following assumptions:
-
-  - This code fragment is run only on an MMU v3.
-  - TLBs are in their reset state.
-  - ITLBCFG and DTLBCFG are zero (reset state).
-  - RASID is 0x04030201 (reset state).
-  - PS.RING is zero (reset state).
-  - LITBASE is zero (reset state, PC-relative literals); required to be PIC.
-
-TLB setup proceeds along the following steps.
-
-  Legend:
-
-    - VA = virtual address (two upper nibbles of it);
-    - PA = physical address (two upper nibbles of it);
-    - pc = physical range that contains this code;
-
-After step 2, we jump to virtual address in the range 0x40000000..0x5fffffff
-or 0x00000000..0x1fffffff, depending on whether the kernel was loaded below
-0x40000000 or above. That address corresponds to next instruction to execute
-in this code. After step 4, we jump to intended (linked) address of this code.
-The scheme below assumes that the kernel is loaded below 0x40000000.
-
- ====== =====  =====  =====  =====   ====== =====  =====
- -      Step0  Step1  Step2  Step3          Step4  Step5
-
-   VA      PA     PA     PA     PA     VA      PA     PA
- ====== =====  =====  =====  =====   ====== =====  =====
- E0..FF -> E0  -> E0  -> E0          F0..FF -> F0  -> F0
- C0..DF -> C0  -> C0  -> C0          E0..EF -> F0  -> F0
- A0..BF -> A0  -> A0  -> A0          D8..DF -> 00  -> 00
- 80..9F -> 80  -> 80  -> 80          D0..D7 -> 00  -> 00
- 60..7F -> 60  -> 60  -> 60
- 40..5F -> 40         -> pc  -> pc   40..5F -> pc
- 20..3F -> 20  -> 20  -> 20
- 00..1F -> 00  -> 00  -> 00
- ====== =====  =====  =====  =====   ====== =====  =====
-
-The default location of IO peripherals is above 0xf0000000. This may be changed
-using a "ranges" property in a device tree simple-bus node. See the Devicetree
-Specification, section 4.5 for details on the syntax and semantics of
-simple-bus nodes. The following limitations apply:
-
-1. Only top level simple-bus nodes are considered
-
-2. Only one (first) simple-bus node is considered
-
-3. Empty "ranges" properties are not supported
-
-4. Only the first triplet in the "ranges" property is considered
-
-5. The parent-bus-address value is rounded down to the nearest 256MB boundary
-
-6. The IO area covers the entire 256MB segment of parent-bus-address; the
-   "ranges" triplet length field is ignored
-
-
-MMUv3 address space layouts.
-============================
-
-Default MMUv2-compatible layout::
-
-                        Symbol                   VADDR       Size
-  +------------------+
-  | Userspace        |                           0x00000000  TASK_SIZE
-  +------------------+                           0x40000000
-  +------------------+
-  | Page table       |  XCHAL_PAGE_TABLE_VADDR   0x80000000  XCHAL_PAGE_TABLE_SIZE
-  +------------------+
-  | KASAN shadow map |  KASAN_SHADOW_START       0x80400000  KASAN_SHADOW_SIZE
-  +------------------+                           0x8e400000
-  +------------------+
-  | VMALLOC area     |  VMALLOC_START            0xc0000000  128MB - 64KB
-  +------------------+  VMALLOC_END
-  +------------------+
-  | Cache aliasing   |  TLBTEMP_BASE_1           0xc8000000  DCACHE_WAY_SIZE
-  | remap area 1     |
-  +------------------+
-  | Cache aliasing   |  TLBTEMP_BASE_2                       DCACHE_WAY_SIZE
-  | remap area 2     |
-  +------------------+
-  +------------------+
-  | KMAP area        |  PKMAP_BASE                           PTRS_PER_PTE *
-  |                  |                                       DCACHE_N_COLORS *
-  |                  |                                       PAGE_SIZE
-  |                  |                                       (4MB * DCACHE_N_COLORS)
-  +------------------+
-  | Atomic KMAP area |  FIXADDR_START                        KM_TYPE_NR *
-  |                  |                                       NR_CPUS *
-  |                  |                                       DCACHE_N_COLORS *
-  |                  |                                       PAGE_SIZE
-  +------------------+  FIXADDR_TOP              0xcffff000
-  +------------------+
-  | Cached KSEG      |  XCHAL_KSEG_CACHED_VADDR  0xd0000000  128MB
-  +------------------+
-  | Uncached KSEG    |  XCHAL_KSEG_BYPASS_VADDR  0xd8000000  128MB
-  +------------------+
-  | Cached KIO       |  XCHAL_KIO_CACHED_VADDR   0xe0000000  256MB
-  +------------------+
-  | Uncached KIO     |  XCHAL_KIO_BYPASS_VADDR   0xf0000000  256MB
-  +------------------+
-
-
-256MB cached + 256MB uncached layout::
-
-                        Symbol                   VADDR       Size
-  +------------------+
-  | Userspace        |                           0x00000000  TASK_SIZE
-  +------------------+                           0x40000000
-  +------------------+
-  | Page table       |  XCHAL_PAGE_TABLE_VADDR   0x80000000  XCHAL_PAGE_TABLE_SIZE
-  +------------------+
-  | KASAN shadow map |  KASAN_SHADOW_START       0x80400000  KASAN_SHADOW_SIZE
-  +------------------+                           0x8e400000
-  +------------------+
-  | VMALLOC area     |  VMALLOC_START            0xa0000000  128MB - 64KB
-  +------------------+  VMALLOC_END
-  +------------------+
-  | Cache aliasing   |  TLBTEMP_BASE_1           0xa8000000  DCACHE_WAY_SIZE
-  | remap area 1     |
-  +------------------+
-  | Cache aliasing   |  TLBTEMP_BASE_2                       DCACHE_WAY_SIZE
-  | remap area 2     |
-  +------------------+
-  +------------------+
-  | KMAP area        |  PKMAP_BASE                           PTRS_PER_PTE *
-  |                  |                                       DCACHE_N_COLORS *
-  |                  |                                       PAGE_SIZE
-  |                  |                                       (4MB * DCACHE_N_COLORS)
-  +------------------+
-  | Atomic KMAP area |  FIXADDR_START                        KM_TYPE_NR *
-  |                  |                                       NR_CPUS *
-  |                  |                                       DCACHE_N_COLORS *
-  |                  |                                       PAGE_SIZE
-  +------------------+  FIXADDR_TOP              0xaffff000
-  +------------------+
-  | Cached KSEG      |  XCHAL_KSEG_CACHED_VADDR  0xb0000000  256MB
-  +------------------+
-  | Uncached KSEG    |  XCHAL_KSEG_BYPASS_VADDR  0xc0000000  256MB
-  +------------------+
-  +------------------+
-  | Cached KIO       |  XCHAL_KIO_CACHED_VADDR   0xe0000000  256MB
-  +------------------+
-  | Uncached KIO     |  XCHAL_KIO_BYPASS_VADDR   0xf0000000  256MB
-  +------------------+
-
-
-512MB cached + 512MB uncached layout::
-
-                        Symbol                   VADDR       Size
-  +------------------+
-  | Userspace        |                           0x00000000  TASK_SIZE
-  +------------------+                           0x40000000
-  +------------------+
-  | Page table       |  XCHAL_PAGE_TABLE_VADDR   0x80000000  XCHAL_PAGE_TABLE_SIZE
-  +------------------+
-  | KASAN shadow map |  KASAN_SHADOW_START       0x80400000  KASAN_SHADOW_SIZE
-  +------------------+                           0x8e400000
-  +------------------+
-  | VMALLOC area     |  VMALLOC_START            0x90000000  128MB - 64KB
-  +------------------+  VMALLOC_END
-  +------------------+
-  | Cache aliasing   |  TLBTEMP_BASE_1           0x98000000  DCACHE_WAY_SIZE
-  | remap area 1     |
-  +------------------+
-  | Cache aliasing   |  TLBTEMP_BASE_2                       DCACHE_WAY_SIZE
-  | remap area 2     |
-  +------------------+
-  +------------------+
-  | KMAP area        |  PKMAP_BASE                           PTRS_PER_PTE *
-  |                  |                                       DCACHE_N_COLORS *
-  |                  |                                       PAGE_SIZE
-  |                  |                                       (4MB * DCACHE_N_COLORS)
-  +------------------+
-  | Atomic KMAP area |  FIXADDR_START                        KM_TYPE_NR *
-  |                  |                                       NR_CPUS *
-  |                  |                                       DCACHE_N_COLORS *
-  |                  |                                       PAGE_SIZE
-  +------------------+  FIXADDR_TOP              0x9ffff000
-  +------------------+
-  | Cached KSEG      |  XCHAL_KSEG_CACHED_VADDR  0xa0000000  512MB
-  +------------------+
-  | Uncached KSEG    |  XCHAL_KSEG_BYPASS_VADDR  0xc0000000  512MB
-  +------------------+
-  | Cached KIO       |  XCHAL_KIO_CACHED_VADDR   0xe0000000  256MB
-  +------------------+
-  | Uncached KIO     |  XCHAL_KIO_BYPASS_VADDR   0xf0000000  256MB
-  +------------------+
index 8d5bc223f3053bf83c8a5aeaa6900ceafe111179..14fadebf42fdd5f53d5f4e75deb1dd28ae45e340 100644 (file)
@@ -73,7 +73,7 @@ Tips for patch submitters
        and ideally, should come with a patch proposal. Please do not send
        automated reports to this list either. Such bugs will be handled
        better and faster in the usual public places. See
-       Documentation/admin-guide/security-bugs.rst for details.
+       Documentation/process/security-bugs.rst for details.
 
 8.     Happy hacking.
 
@@ -224,13 +224,13 @@ S:        Orphan / Obsolete
 F:     drivers/net/ethernet/8390/
 
 9P FILE SYSTEM
-M:     Eric Van Hensbergen <ericvh@gmail.com>
+M:     Eric Van Hensbergen <ericvh@kernel.org>
 M:     Latchesar Ionkov <lucho@ionkov.net>
 M:     Dominique Martinet <asmadeus@codewreck.org>
 R:     Christian Schoenebeck <linux_oss@crudebyte.com>
-L:     v9fs-developer@lists.sourceforge.net
+L:     v9fs@lists.linux.dev
 S:     Maintained
-W:     http://swik.net/v9fs
+W:     http://github.com/v9fs
 Q:     http://patchwork.kernel.org/project/v9fs-devel/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs.git
 T:     git git://github.com/martinetd/linux.git
@@ -1071,7 +1071,7 @@ M:        Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
 R:     Carlos Bilbao <carlos.bilbao@amd.com>
 L:     platform-driver-x86@vger.kernel.org
 S:     Maintained
-F:     Documentation/x86/amd_hsmp.rst
+F:     Documentation/arch/x86/amd_hsmp.rst
 F:     arch/x86/include/asm/amd_hsmp.h
 F:     arch/x86/include/uapi/asm/amd_hsmp.h
 F:     drivers/platform/x86/amd/hsmp.c
@@ -4461,14 +4461,14 @@ F:      Documentation/devicetree/bindings/net/ieee802154/ca8210.txt
 F:     drivers/net/ieee802154/ca8210.c
 
 CANAAN/KENDRYTE K210 SOC FPIOA DRIVER
-M:     Damien Le Moal <damien.lemoal@wdc.com>
+M:     Damien Le Moal <dlemoal@kernel.org>
 L:     linux-riscv@lists.infradead.org
 L:     linux-gpio@vger.kernel.org (pinctrl driver)
 F:     Documentation/devicetree/bindings/pinctrl/canaan,k210-fpioa.yaml
 F:     drivers/pinctrl/pinctrl-k210.c
 
 CANAAN/KENDRYTE K210 SOC RESET CONTROLLER DRIVER
-M:     Damien Le Moal <damien.lemoal@wdc.com>
+M:     Damien Le Moal <dlemoal@kernel.org>
 L:     linux-kernel@vger.kernel.org
 L:     linux-riscv@lists.infradead.org
 S:     Maintained
@@ -4476,7 +4476,7 @@ F:        Documentation/devicetree/bindings/reset/canaan,k210-rst.yaml
 F:     drivers/reset/reset-k210.c
 
 CANAAN/KENDRYTE K210 SOC SYSTEM CONTROLLER DRIVER
-M:     Damien Le Moal <damien.lemoal@wdc.com>
+M:     Damien Le Moal <dlemoal@kernel.org>
 L:     linux-riscv@lists.infradead.org
 S:     Maintained
 F:      Documentation/devicetree/bindings/mfd/canaan,k210-sysctl.yaml
@@ -5940,11 +5940,6 @@ F:       drivers/devfreq/event/
 F:     include/dt-bindings/pmu/exynos_ppmu.h
 F:     include/linux/devfreq-event.h
 
-DEVICE NUMBER REGISTRY
-M:     Torben Mathiasen <device@lanana.org>
-S:     Maintained
-W:     http://lanana.org/docs/device-list/index.html
-
 DEVICE RESOURCE MANAGEMENT HELPERS
 M:     Hans de Goede <hdegoede@redhat.com>
 R:     Matti Vaittinen <mazziesaccount@gmail.com>
@@ -5971,7 +5966,7 @@ F:        include/linux/dm-*.h
 F:     include/uapi/linux/dm-*.h
 
 DEVLINK
-M:     Jiri Pirko <jiri@nvidia.com>
+M:     Jiri Pirko <jiri@resnulli.us>
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     Documentation/networking/devlink
@@ -6207,6 +6202,7 @@ DOCUMENTATION REPORTING ISSUES
 M:     Thorsten Leemhuis <linux@leemhuis.info>
 L:     linux-doc@vger.kernel.org
 S:     Maintained
+F:     Documentation/admin-guide/quickly-build-trimmed-linux.rst
 F:     Documentation/admin-guide/reporting-issues.rst
 
 DOCUMENTATION SCRIPTS
@@ -8216,6 +8212,7 @@ F:        drivers/net/ethernet/freescale/dpaa
 
 FREESCALE QORIQ DPAA FMAN DRIVER
 M:     Madalin Bucur <madalin.bucur@nxp.com>
+R:     Sean Anderson <sean.anderson@seco.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     Documentation/devicetree/bindings/net/fsl-fman.txt
@@ -9728,7 +9725,7 @@ F:        include/linux/i3c/
 IA64 (Itanium) PLATFORM
 L:     linux-ia64@vger.kernel.org
 S:     Orphan
-F:     Documentation/ia64/
+F:     Documentation/arch/ia64/
 F:     arch/ia64/
 
 IBM Operation Panel Input Driver
@@ -9871,10 +9868,10 @@ M:      Christian Brauner <brauner@kernel.org>
 M:     Seth Forshee <sforshee@kernel.org>
 L:     linux-fsdevel@vger.kernel.org
 S:     Maintained
-T:     git://git.kernel.org/pub/scm/linux/kernel/git/vfs/idmapping.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/vfs/idmapping.git
 F:     Documentation/filesystems/idmappings.rst
-F:     tools/testing/selftests/mount_setattr/
 F:     include/linux/mnt_idmapping.*
+F:     tools/testing/selftests/mount_setattr/
 
 IDT VersaClock 5 CLOCK DRIVER
 M:     Luca Ceresoli <luca@lucaceresoli.net>
@@ -10647,7 +10644,7 @@ L:      tboot-devel@lists.sourceforge.net
 S:     Supported
 W:     http://tboot.sourceforge.net
 T:     hg http://tboot.hg.sourceforge.net:8000/hgroot/tboot/tboot
-F:     Documentation/x86/intel_txt.rst
+F:     Documentation/arch/x86/intel_txt.rst
 F:     arch/x86/kernel/tboot.c
 F:     include/linux/tboot.h
 
@@ -10658,7 +10655,7 @@ L:      linux-sgx@vger.kernel.org
 S:     Supported
 Q:     https://patchwork.kernel.org/project/intel-sgx/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/sgx
-F:     Documentation/x86/sgx.rst
+F:     Documentation/arch/x86/sgx.rst
 F:     arch/x86/entry/vdso/vsgx.S
 F:     arch/x86/include/asm/sgx.h
 F:     arch/x86/include/uapi/asm/sgx.h
@@ -11757,7 +11754,7 @@ T:      git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
 F:     drivers/ata/sata_promise.*
 
 LIBATA SUBSYSTEM (Serial and Parallel ATA drivers)
-M:     Damien Le Moal <damien.lemoal@opensource.wdc.com>
+M:     Damien Le Moal <dlemoal@kernel.org>
 L:     linux-ide@vger.kernel.org
 S:     Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata.git
@@ -14593,6 +14590,7 @@ F:      net/netlabel/
 
 NETWORKING [MPTCP]
 M:     Matthieu Baerts <matthieu.baerts@tessares.net>
+M:     Mat Martineau <martineau@kernel.org>
 L:     netdev@vger.kernel.org
 L:     mptcp@lists.linux.dev
 S:     Maintained
@@ -14656,10 +14654,8 @@ F:     net/ipv4/nexthop.c
 
 NFC SUBSYSTEM
 M:     Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-L:     linux-nfc@lists.01.org (subscribers-only)
 L:     netdev@vger.kernel.org
 S:     Maintained
-B:     mailto:linux-nfc@lists.01.org
 F:     Documentation/devicetree/bindings/net/nfc/
 F:     drivers/nfc/
 F:     include/linux/platform_data/nfcmrvl.h
@@ -14670,7 +14666,6 @@ F:      net/nfc/
 NFC VIRTUAL NCI DEVICE DRIVER
 M:     Bongsu Jeon <bongsu.jeon@samsung.com>
 L:     netdev@vger.kernel.org
-L:     linux-nfc@lists.01.org (subscribers-only)
 S:     Supported
 F:     drivers/nfc/virtual_ncidev.c
 F:     tools/testing/selftests/nci/
@@ -14872,12 +14867,12 @@ M:    Sagi Grimberg <sagi@grimberg.me>
 L:     linux-nvme@lists.infradead.org
 S:     Supported
 W:     http://git.infradead.org/nvme.git
-T:     git://git.infradead.org/nvme.git
+T:     git git://git.infradead.org/nvme.git
 F:     Documentation/nvme/
-F:     drivers/nvme/host/
 F:     drivers/nvme/common/
-F:     include/linux/nvme.h
+F:     drivers/nvme/host/
 F:     include/linux/nvme-*.h
+F:     include/linux/nvme.h
 F:     include/uapi/linux/nvme_ioctl.h
 
 NVM EXPRESS FABRICS AUTHENTICATION
@@ -14912,7 +14907,7 @@ M:      Chaitanya Kulkarni <kch@nvidia.com>
 L:     linux-nvme@lists.infradead.org
 S:     Supported
 W:     http://git.infradead.org/nvme.git
-T:     git://git.infradead.org/nvme.git
+T:     git git://git.infradead.org/nvme.git
 F:     drivers/nvme/target/
 
 NVMEM FRAMEWORK
@@ -15042,7 +15037,6 @@ F:      Documentation/devicetree/bindings/sound/nxp,tfa989x.yaml
 F:     sound/soc/codecs/tfa989x.c
 
 NXP-NCI NFC DRIVER
-L:     linux-nfc@lists.01.org (subscribers-only)
 S:     Orphan
 F:     Documentation/devicetree/bindings/net/nfc/nxp,nci.yaml
 F:     drivers/nfc/nxp-nci
@@ -15079,7 +15073,7 @@ F:      Documentation/hwmon/nzxt-smart2.rst
 F:     drivers/hwmon/nzxt-smart2.c
 
 OBJAGG
-M:     Jiri Pirko <jiri@nvidia.com>
+M:     Jiri Pirko <jiri@resnulli.us>
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     include/linux/objagg.h
@@ -15642,7 +15636,7 @@ S:      Maintained
 W:     http://openrisc.io
 T:     git https://github.com/openrisc/linux.git
 F:     Documentation/devicetree/bindings/openrisc/
-F:     Documentation/openrisc/
+F:     Documentation/arch/openrisc/
 F:     arch/openrisc/
 F:     drivers/irqchip/irq-ompic.c
 F:     drivers/irqchip/irq-or1k-*
@@ -15838,7 +15832,7 @@ W:      https://parisc.wiki.kernel.org
 Q:     http://patchwork.kernel.org/project/linux-parisc/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/parisc-2.6.git
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git
-F:     Documentation/parisc/
+F:     Documentation/arch/parisc/
 F:     arch/parisc/
 F:     drivers/char/agp/parisc-agp.c
 F:     drivers/input/misc/hp_sdc_rtc.c
@@ -15853,7 +15847,7 @@ F:      drivers/video/logo/logo_parisc*
 F:     include/linux/hp_sdc.h
 
 PARMAN
-M:     Jiri Pirko <jiri@nvidia.com>
+M:     Jiri Pirko <jiri@resnulli.us>
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     include/linux/parman.h
@@ -16391,6 +16385,7 @@ R:      Alexander Shishkin <alexander.shishkin@linux.intel.com>
 R:     Jiri Olsa <jolsa@kernel.org>
 R:     Namhyung Kim <namhyung@kernel.org>
 R:     Ian Rogers <irogers@google.com>
+R:     Adrian Hunter <adrian.hunter@intel.com>
 L:     linux-perf-users@vger.kernel.org
 L:     linux-kernel@vger.kernel.org
 S:     Supported
@@ -17168,6 +17163,12 @@ F:     fs/qnx4/
 F:     include/uapi/linux/qnx4_fs.h
 F:     include/uapi/linux/qnxtypes.h
 
+QNX6 FILESYSTEM
+S:     Orphan
+F:     Documentation/filesystems/qnx6.rst
+F:     fs/qnx6/
+F:     include/linux/qnx6_fs.h
+
 QORIQ DPAA2 FSL-MC BUS DRIVER
 M:     Stuart Yoder <stuyoder@gmail.com>
 M:     Laurentiu Tudor <laurentiu.tudor@nxp.com>
@@ -17628,7 +17629,7 @@ M:      Fenghua Yu <fenghua.yu@intel.com>
 M:     Reinette Chatre <reinette.chatre@intel.com>
 L:     linux-kernel@vger.kernel.org
 S:     Supported
-F:     Documentation/x86/resctrl*
+F:     Documentation/arch/x86/resctrl*
 F:     arch/x86/include/asm/resctrl.h
 F:     arch/x86/kernel/cpu/resctrl/
 F:     tools/testing/selftests/resctrl/
@@ -17637,11 +17638,13 @@ READ-COPY UPDATE (RCU)
 M:     "Paul E. McKenney" <paulmck@kernel.org>
 M:     Frederic Weisbecker <frederic@kernel.org> (kernel/rcu/tree_nocb.h)
 M:     Neeraj Upadhyay <quic_neeraju@quicinc.com> (kernel/rcu/tasks.h)
+M:     Joel Fernandes <joel@joelfernandes.org>
 M:     Josh Triplett <josh@joshtriplett.org>
+M:     Boqun Feng <boqun.feng@gmail.com>
 R:     Steven Rostedt <rostedt@goodmis.org>
 R:     Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
 R:     Lai Jiangshan <jiangshanlai@gmail.com>
-R:     Joel Fernandes <joel@joelfernandes.org>
+R:     Zqiang <qiang1.zhang@intel.com>
 L:     rcu@vger.kernel.org
 S:     Supported
 W:     http://www.rdrop.com/users/paulmck/RCU/
@@ -17989,7 +17992,7 @@ F:      Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml
 F:     Documentation/devicetree/bindings/usb/microchip,mpfs-musb.yaml
 F:     arch/riscv/boot/dts/microchip/
 F:     drivers/char/hw_random/mpfs-rng.c
-F:     drivers/clk/microchip/clk-mpfs.c
+F:     drivers/clk/microchip/clk-mpfs*.c
 F:     drivers/i2c/busses/i2c-microchip-corei2c.c
 F:     drivers/mailbox/mailbox-mpfs.c
 F:     drivers/pci/controller/pcie-microchip-host.c
@@ -18290,8 +18293,9 @@ F:      drivers/s390/block/dasd*
 F:     include/linux/dasd_mod.h
 
 S390 IOMMU (PCI)
+M:     Niklas Schnelle <schnelle@linux.ibm.com>
 M:     Matthew Rosato <mjrosato@linux.ibm.com>
-M:     Gerald Schaefer <gerald.schaefer@linux.ibm.com>
+R:     Gerald Schaefer <gerald.schaefer@linux.ibm.com>
 L:     linux-s390@vger.kernel.org
 S:     Supported
 F:     drivers/iommu/s390-iommu.c
@@ -18486,7 +18490,6 @@ F:      include/media/drv-intf/s3c_camif.h
 
 SAMSUNG S3FWRN5 NFC DRIVER
 M:     Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-L:     linux-nfc@lists.01.org (subscribers-only)
 S:     Maintained
 F:     Documentation/devicetree/bindings/net/nfc/samsung,s3fwrn5.yaml
 F:     drivers/nfc/s3fwrn5
@@ -18801,7 +18804,7 @@ F:      include/uapi/linux/sed*
 SECURITY CONTACT
 M:     Security Officers <security@kernel.org>
 S:     Supported
-F:     Documentation/admin-guide/security-bugs.rst
+F:     Documentation/process/security-bugs.rst
 
 SECURITY SUBSYSTEM
 M:     Paul Moore <paul@paul-moore.com>
@@ -18823,8 +18826,8 @@ S:      Supported
 W:     https://selinuxproject.org
 W:     https://github.com/SELinuxProject
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git
-F:     Documentation/ABI/obsolete/sysfs-selinux-checkreqprot
-F:     Documentation/ABI/obsolete/sysfs-selinux-disable
+F:     Documentation/ABI/removed/sysfs-selinux-checkreqprot
+F:     Documentation/ABI/removed/sysfs-selinux-disable
 F:     Documentation/admin-guide/LSM/SELinux.rst
 F:     include/trace/events/avc.h
 F:     include/uapi/linux/selinux_netlink.h
@@ -19149,9 +19152,7 @@ W:      http://www.brownhat.org/sis900.html
 F:     drivers/net/ethernet/sis/sis900.*
 
 SIS FRAMEBUFFER DRIVER
-M:     Thomas Winischhofer <thomas@winischhofer.net>
-S:     Maintained
-W:     http://www.winischhofer.net/linuxsisvga.shtml
+S:     Orphan
 F:     Documentation/fb/sisfb.rst
 F:     drivers/video/fbdev/sis/
 F:     include/video/sisfb.h
@@ -19863,13 +19864,6 @@ S:     Maintained
 W:     http://wiki.laptop.org/go/DCON
 F:     drivers/staging/olpc_dcon/
 
-STAGING - REALTEK RTL8188EU DRIVERS
-M:     Larry Finger <Larry.Finger@lwfinger.net>
-M:     Phillip Potter <phil@philpotter.co.uk>
-R:     Pavel Skripkin <paskripkin@gmail.com>
-S:     Supported
-F:     drivers/staging/r8188eu/
-
 STAGING - REALTEK RTL8712U DRIVERS
 M:     Larry Finger <Larry.Finger@lwfinger.net>
 M:     Florian Schilhabel <florian.c.schilhabel@googlemail.com>.
@@ -20123,7 +20117,7 @@ M:      John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
 L:     linux-sh@vger.kernel.org
 S:     Maintained
 Q:     http://patchwork.kernel.org/project/linux-sh/list/
-F:     Documentation/sh/
+F:     Documentation/arch/sh/
 F:     arch/sh/
 F:     drivers/sh/
 
@@ -20183,7 +20177,7 @@ M:      Vineet Gupta <vgupta@kernel.org>
 L:     linux-snps-arc@lists.infradead.org
 S:     Supported
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git
-F:     Documentation/arc/
+F:     Documentation/arch/arc
 F:     Documentation/devicetree/bindings/arc/*
 F:     Documentation/devicetree/bindings/interrupt-controller/snps,arc*
 F:     arch/arc/
@@ -20653,7 +20647,6 @@ F:      sound/soc/codecs/tscs*.h
 TENSILICA XTENSA PORT (xtensa)
 M:     Chris Zankel <chris@zankel.net>
 M:     Max Filippov <jcmvbkbc@gmail.com>
-L:     linux-xtensa@linux-xtensa.org
 S:     Maintained
 T:     git https://github.com/jcmvbkbc/linux-xtensa.git
 F:     arch/xtensa/
@@ -20989,7 +20982,6 @@ F:      drivers/iio/magnetometer/tmag5273.c
 TI TRF7970A NFC DRIVER
 M:     Mark Greer <mgreer@animalcreek.com>
 L:     linux-wireless@vger.kernel.org
-L:     linux-nfc@lists.01.org (subscribers-only)
 S:     Supported
 F:     Documentation/devicetree/bindings/net/nfc/ti,trf7970a.yaml
 F:     drivers/nfc/trf7970a.c
@@ -21244,6 +21236,14 @@ S:     Maintained
 F:     Documentation/tools/rtla/
 F:     tools/tracing/rtla/
 
+TECHNICAL ADVISORY BOARD PROCESS DOCS
+M:     "Theodore Ts'o" <tytso@mit.edu>
+M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+L:     tech-board-discuss@lists.linux-foundation.org
+S:     Maintained
+F:     Documentation/process/researcher-guidelines.rst
+F:     Documentation/process/contribution-maturity-model.rst
+
 TRADITIONAL CHINESE DOCUMENTATION
 M:     Hu Haowen <src.res@email.cn>
 L:     linux-doc-tw-discuss@lists.sourceforge.net (moderated for non-subscribers)
@@ -21651,6 +21651,7 @@ USB OVER IP DRIVER
 M:     Valentina Manea <valentina.manea.m@gmail.com>
 M:     Shuah Khan <shuah@kernel.org>
 M:     Shuah Khan <skhan@linuxfoundation.org>
+R:     Hongren Zheng <i@zenithal.me>
 L:     linux-usb@vger.kernel.org
 S:     Maintained
 F:     Documentation/usb/usbip_protocol.rst
@@ -22176,7 +22177,9 @@ L:      virtualization@lists.linux-foundation.org
 L:     netdev@vger.kernel.org
 S:     Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git
+F:     kernel/vhost_task.c
 F:     drivers/vhost/
+F:     include/linux/sched/vhost_task.h
 F:     include/linux/vhost_iotlb.h
 F:     include/uapi/linux/vhost.h
 
@@ -22650,7 +22653,7 @@ L:      linux-kernel@vger.kernel.org
 S:     Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core
 F:     Documentation/devicetree/bindings/x86/
-F:     Documentation/x86/
+F:     Documentation/arch/x86/
 F:     arch/x86/
 
 X86 ENTRY CODE
@@ -22666,7 +22669,7 @@ M:      Borislav Petkov <bp@alien8.de>
 L:     linux-edac@vger.kernel.org
 S:     Maintained
 F:     Documentation/ABI/testing/sysfs-mce
-F:     Documentation/x86/x86_64/machinecheck.rst
+F:     Documentation/arch/x86/x86_64/machinecheck.rst
 F:     arch/x86/kernel/cpu/mce/*
 
 X86 MICROCODE UPDATE SUPPORT
@@ -23045,7 +23048,6 @@ F:      drivers/gpio/gpio-xra1403.c
 
 XTENSA XTFPGA PLATFORM SUPPORT
 M:     Max Filippov <jcmvbkbc@gmail.com>
-L:     linux-xtensa@linux-xtensa.org
 S:     Maintained
 F:     drivers/spi/spi-xtensa-xtfpga.c
 F:     sound/soc/xtensa/xtfpga-i2s.c
@@ -23128,7 +23130,7 @@ S:      Maintained
 F:     arch/x86/kernel/cpu/zhaoxin.c
 
 ZONEFS FILESYSTEM
-M:     Damien Le Moal <damien.lemoal@opensource.wdc.com>
+M:     Damien Le Moal <dlemoal@kernel.org>
 M:     Naohiro Aota <naohiro.aota@wdc.com>
 R:     Johannes Thumshirn <jth@kernel.org>
 L:     linux-fsdevel@vger.kernel.org
index d7bd0eb9b34633f22d70649e245575f49dfd1e41..f5543eef4f8227a40d6a0b5a2646ff8f38658d89 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 6
 PATCHLEVEL = 3
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION =
 NAME = Hurr durr I'ma ninja sloth
 
 # *DOCUMENTATION*
@@ -274,8 +274,7 @@ no-dot-config-targets := $(clean-targets) \
                         cscope gtags TAGS tags help% %docs check% coccicheck \
                         $(version_h) headers headers_% archheaders archscripts \
                         %asm-generic kernelversion %src-pkg dt_binding_check \
-                        outputmakefile rustavailable rustfmt rustfmtcheck \
-                        scripts_package
+                        outputmakefile rustavailable rustfmt rustfmtcheck
 # Installation targets should not require compiler. Unfortunately, vdso_install
 # is an exception where build artifacts may be updated. This must be fixed.
 no-compiler-targets := $(no-dot-config-targets) install dtbs_install \
@@ -1605,7 +1604,7 @@ MRPROPER_FILES += include/config include/generated          \
                  certs/signing_key.pem \
                  certs/x509.genkey \
                  vmlinux-gdb.py \
-                 *.spec \
+                 *.spec rpmbuild \
                  rust/libmacros.so
 
 # clean - Delete most, but leave enough to build external modules
@@ -1656,10 +1655,6 @@ distclean: mrproper
 %pkg: include/config/kernel.release FORCE
        $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.package $@
 
-PHONY += scripts_package
-scripts_package: scripts_basic
-       $(Q)$(MAKE) $(build)=scripts scripts/list-gitignored
-
 # Brief documentation of the typical targets used
 # ---------------------------------------------------------------------------
 
@@ -1886,6 +1881,8 @@ endif
 
 else # KBUILD_EXTMOD
 
+filechk_kernel.release = echo $(KERNELRELEASE)
+
 ###
 # External module support.
 # When building external modules the kernel used as basis is considered
index 612c5eca71bc0fea03dcf1c888076c065fc65f57..7c08b225261c4add9b50b62a907239d30ecd4cf1 100644 (file)
@@ -23,7 +23,7 @@ alpha_read_fp_reg (unsigned long reg)
 
        if (unlikely(reg >= 32))
                return 0;
-       preempt_enable();
+       preempt_disable();
        if (current_thread_info()->status & TS_SAVED_FP)
                val = current_thread_info()->fp[reg];
        else switch (reg) {
@@ -133,7 +133,7 @@ alpha_read_fp_reg_s (unsigned long reg)
        if (unlikely(reg >= 32))
                return 0;
 
-       preempt_enable();
+       preempt_disable();
        if (current_thread_info()->status & TS_SAVED_FP) {
                LDT(0, current_thread_info()->fp[reg]);
                STS(0, val);
index e24a9820e12fa0bea7e8e9db4e1b773264681a98..d64ad0fe6c0c2c519494c802f94e08242d76305d 100644 (file)
@@ -986,7 +986,7 @@ config SMP
          uniprocessor machines. On a uniprocessor machine, the kernel
          will run faster if you say N here.
 
-         See also <file:Documentation/x86/i386/IO-APIC.rst>,
+         See also <file:Documentation/arch/x86/i386/IO-APIC.rst>,
          <file:Documentation/admin-guide/lockup-watchdogs.rst> and the SMP-HOWTO available at
          <http://tldp.org/HOWTO/SMP-HOWTO.html>.
 
index 2ef651a78fa2a979cdf3712c01f8481b69789093..726ecabcef0932dcc04f76d79ee806bb8f1d8ff1 100644 (file)
@@ -107,7 +107,7 @@ ccflags-remove-$(CONFIG_FUNCTION_TRACER) += -pg
 asflags-y := -DZIMAGE
 
 # Supply kernel BSS size to the decompressor via a linker symbol.
-KBSS_SZ = $(shell echo $$(($$($(NM) $(obj)/../../../../vmlinux | \
+KBSS_SZ = $(shell echo $$(($$($(NM) vmlinux | \
                sed -n -e 's/^\([^ ]*\) [ABD] __bss_start$$/-0x\1/p' \
                       -e 's/^\([^ ]*\) [ABD] __bss_stop$$/+0x\1/p') )) )
 LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
index 94944cc219317fd43ab32971e0936f9dbb501de7..dd03e3860f97f901524570a89552adee135accce 100644 (file)
 
 &usbotg1 {
        pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg1>;
        disable-over-current;
        srp-disable;
        hnp-disable;
index ace3eb8a97b87c4002be0db5e21cb294d9aeccb1..4e1bf080eaca012ae0d1f9e6e74696eaea41da28 100644 (file)
 
 &usbotg1 {
        pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg1>;
        disable-over-current;
        srp-disable;
        hnp-disable;
index da1399057634a040321139407b0e3afecbddd149..815119c12bd48286df5bf2f0d936508d994c08a1 100644 (file)
 
 &usbotg1 {
        pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg1>;
        disable-over-current;
        srp-disable;
        hnp-disable;
index bf64ba84b358b59239d491fe2fd49fae0ffe7c03..fde8a19aac0f7c7411414ccc56091f3e1978e3ca 100644 (file)
                self-powered;
                type = "micro";
 
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       port@0 {
-                               reg = <0>;
-                               usb_dr_connector: endpoint {
-                                       remote-endpoint = <&usb1_drd_sw>;
-                               };
+               port {
+                       usb_dr_connector: endpoint {
+                               remote-endpoint = <&usb1_drd_sw>;
                        };
                };
        };
index 8b2f11e85e05c673ec442193faf4f6301e0fe45c..427f8d04ec89adfe0166e528e21b4808bc024e3a 100644 (file)
                reg = <0x62>;
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_epdpmic>;
-               #address-cells = <1>;
-               #size-cells = <0>;
                #thermal-sensor-cells = <0>;
                epd-pwr-good-gpios = <&gpio6 21 GPIO_ACTIVE_HIGH>;
 
index de2fb1c01b6e348ea188f1d34b51baf045cd8774..b82381229adf6ebdb1533af643e781a6717e6791 100644 (file)
        };
 
        reserved-memory {
+               sbl_region: sbl@2f00000 {
+                       reg = <0x02f00000 0x100000>;
+                       no-map;
+               };
+
+               external_image_region: external-image@3100000 {
+                       reg = <0x03100000 0x200000>;
+                       no-map;
+               };
+
                adsp_region: adsp@3300000 {
                        reg = <0x03300000 0x1400000>;
                        no-map;
index 2ca76b69add78d5858064ac9707cbe34f922ea93..511ca864c1b2d717f2e61638b4e52a480130837e 100644 (file)
                status = "disabled";
        };
 
-       spdif: sound@ff88b0000 {
+       spdif: sound@ff8b0000 {
                compatible = "rockchip,rk3288-spdif", "rockchip,rk3066-spdif";
                reg = <0x0 0xff8b0000 0x0 0x10000>;
                #sound-dai-cells = <0>;
index 6dc6fed12af83065464c851554c58bd763da3428..8d002c6e6cb3b53cafcd37af57ffc92973f9376a 100644 (file)
@@ -76,7 +76,7 @@ CONFIG_RFKILL=y
 CONFIG_RFKILL_INPUT=y
 CONFIG_PCI=y
 CONFIG_PCI_MSI=y
-CONFIG_PCI_IMX6=y
+CONFIG_PCI_IMX6_HOST=y
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_STANDALONE is not set
index 06b48ce23e1ca245fb87d68d6a26213d6bff6dd5..505a306e0271a9c44b7f78db3f653372e4133523 100644 (file)
@@ -244,19 +244,6 @@ THUMB(     fpreg   .req    r7      )
        .endm
 #endif
 
-       .macro  local_bh_disable, ti, tmp
-       ldr     \tmp, [\ti, #TI_PREEMPT]
-       add     \tmp, \tmp, #SOFTIRQ_DISABLE_OFFSET
-       str     \tmp, [\ti, #TI_PREEMPT]
-       .endm
-
-       .macro  local_bh_enable_ti, ti, tmp
-       get_thread_info \ti
-       ldr     \tmp, [\ti, #TI_PREEMPT]
-       sub     \tmp, \tmp, #SOFTIRQ_DISABLE_OFFSET
-       str     \tmp, [\ti, #TI_PREEMPT]
-       .endm
-
 #define USERL(l, x...)                         \
 9999:  x;                                      \
        .pushsection __ex_table,"a";            \
index 14eecaaf295fabacb68ac687912eb8f8c1da7a46..e4c2677cc1e9e45cac842f71d88267cb3cce32ac 100644 (file)
@@ -116,7 +116,7 @@ __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n)
                        tocopy = n;
 
                ua_flags = uaccess_save_and_enable();
-               memcpy((void *)to, from, tocopy);
+               __memcpy((void *)to, from, tocopy);
                uaccess_restore(ua_flags);
                to += tocopy;
                from += tocopy;
@@ -178,7 +178,7 @@ __clear_user_memset(void __user *addr, unsigned long n)
                        tocopy = n;
 
                ua_flags = uaccess_save_and_enable();
-               memset((void *)addr, 0, tocopy);
+               __memset((void *)addr, 0, tocopy);
                uaccess_restore(ua_flags);
                addr += tocopy;
                n -= tocopy;
index 9a89264cdcc0b46ec8fc9895219f09dc52830378..7483ef8bccda394c0d21847e98b37597d8ec574a 100644 (file)
 @  IRQs enabled.
 @
 ENTRY(do_vfp)
-       local_bh_disable r10, r4
-       ldr     r4, .LCvfp
-       ldr     r11, [r10, #TI_CPU]     @ CPU number
-       add     r10, r10, #TI_VFPSTATE  @ r10 = workspace
-       ldr     pc, [r4]                @ call VFP entry point
+       mov     r1, r10
+       mov     r3, r9
+       b       vfp_entry
 ENDPROC(do_vfp)
-
-ENTRY(vfp_null_entry)
-       local_bh_enable_ti r10, r4
-       ret     lr
-ENDPROC(vfp_null_entry)
-
-       .align  2
-.LCvfp:
-       .word   vfp_vector
index 26c4f61ecfa39638ac9c1442b68409601ef515ad..4d8478264d82b3d2790b69b323118f8009c53787 100644 (file)
@@ -6,9 +6,9 @@
  *  Written by Deep Blue Solutions Limited.
  *
  * This code is called from the kernel's undefined instruction trap.
- * r9 holds the return address for successful handling.
+ * r1 holds the thread_info pointer
+ * r3 holds the return address for successful handling.
  * lr holds the return address for unrecognised instructions.
- * r10 points at the start of the private FP workspace in the thread structure
  * sp points to a struct pt_regs (as defined in include/asm/proc/ptrace.h)
  */
 #include <linux/init.h>
 @ VFP hardware support entry point.
 @
 @  r0  = instruction opcode (32-bit ARM or two 16-bit Thumb)
+@  r1  = thread_info pointer
 @  r2  = PC value to resume execution after successful emulation
-@  r9  = normal "successful" return address
-@  r10 = vfp_state union
-@  r11 = CPU number
+@  r3  = normal "successful" return address
 @  lr  = unrecognised instruction return address
 @  IRQs enabled.
 ENTRY(vfp_support_entry)
+       ldr     r11, [r1, #TI_CPU]      @ CPU number
+       add     r10, r1, #TI_VFPSTATE   @ r10 = workspace
+
        DBGSTR3 "instr %08x pc %08x state %p", r0, r2, r10
 
        .fpu    vfpv2
@@ -85,9 +87,9 @@ ENTRY(vfp_support_entry)
        bne     look_for_VFP_exceptions @ VFP is already enabled
 
        DBGSTR1 "enable %x", r10
-       ldr     r3, vfp_current_hw_state_address
+       ldr     r9, vfp_current_hw_state_address
        orr     r1, r1, #FPEXC_EN       @ user FPEXC has the enable bit set
-       ldr     r4, [r3, r11, lsl #2]   @ vfp_current_hw_state pointer
+       ldr     r4, [r9, r11, lsl #2]   @ vfp_current_hw_state pointer
        bic     r5, r1, #FPEXC_EX       @ make sure exceptions are disabled
        cmp     r4, r10                 @ this thread owns the hw context?
 #ifndef CONFIG_SMP
@@ -146,7 +148,7 @@ vfp_reload_hw:
 #endif
 
        DBGSTR1 "load state %p", r10
-       str     r10, [r3, r11, lsl #2]  @ update the vfp_current_hw_state pointer
+       str     r10, [r9, r11, lsl #2]  @ update the vfp_current_hw_state pointer
                                        @ Load the saved state back into the VFP
        VFPFLDMIA r10, r5               @ reload the working registers while
                                        @ FPEXC is in a safe state
@@ -175,9 +177,12 @@ vfp_hw_state_valid:
                                        @ else it's one 32-bit instruction, so
                                        @ always subtract 4 from the following
                                        @ instruction address.
-       local_bh_enable_ti r10, r4
-       ret     r9                      @ we think we have handled things
 
+       mov     lr, r3                  @ we think we have handled things
+local_bh_enable_and_ret:
+       adr     r0, .
+       mov     r1, #SOFTIRQ_DISABLE_OFFSET
+       b       __local_bh_enable_ip    @ tail call
 
 look_for_VFP_exceptions:
        @ Check for synchronous or asynchronous exception
@@ -200,13 +205,12 @@ skip:
        @ not recognised by VFP
 
        DBGSTR  "not VFP"
-       local_bh_enable_ti r10, r4
-       ret     lr
+       b       local_bh_enable_and_ret
 
 process_exception:
        DBGSTR  "bounce"
        mov     r2, sp                  @ nothing stacked - regdump is at TOS
-       mov     lr, r9                  @ setup for a return to the user code.
+       mov     lr, r3                  @ setup for a return to the user code.
 
        @ Now call the C code to package up the bounce to the support code
        @   r0 holds the trigger instruction
index 01bc48d7384781427cc7172e5140152bdcabe4ba..349dcb944a937a72907d60eb0020c963b040afdd 100644 (file)
 /*
  * Our undef handlers (in entry.S)
  */
-asmlinkage void vfp_support_entry(void);
-asmlinkage void vfp_null_entry(void);
+asmlinkage void vfp_support_entry(u32, void *, u32, u32);
 
-asmlinkage void (*vfp_vector)(void) = vfp_null_entry;
+static bool have_vfp __ro_after_init;
 
 /*
  * Dual-use variable.
@@ -645,6 +644,25 @@ static int vfp_starting_cpu(unsigned int unused)
        return 0;
 }
 
+/*
+ * Entered with:
+ *
+ *  r0  = instruction opcode (32-bit ARM or two 16-bit Thumb)
+ *  r1  = thread_info pointer
+ *  r2  = PC value to resume execution after successful emulation
+ *  r3  = normal "successful" return address
+ *  lr  = unrecognised instruction return address
+ */
+asmlinkage void vfp_entry(u32 trigger, struct thread_info *ti, u32 resume_pc,
+                         u32 resume_return_address)
+{
+       if (unlikely(!have_vfp))
+               return;
+
+       local_bh_disable();
+       vfp_support_entry(trigger, ti, resume_pc, resume_return_address);
+}
+
 #ifdef CONFIG_KERNEL_MODE_NEON
 
 static int vfp_kmode_exception(struct pt_regs *regs, unsigned int instr)
@@ -798,7 +816,6 @@ static int __init vfp_init(void)
        vfpsid = fmrx(FPSID);
        barrier();
        unregister_undef_hook(&vfp_detect_hook);
-       vfp_vector = vfp_null_entry;
 
        pr_info("VFP support v0.3: ");
        if (VFP_arch) {
@@ -883,7 +900,7 @@ static int __init vfp_init(void)
                                  "arm/vfp:starting", vfp_starting_cpu,
                                  vfp_dying_cpu);
 
-       vfp_vector = vfp_support_entry;
+       have_vfp = true;
 
        thread_register_notifier(&vfp_notifier_block);
        vfp_pm_init();
index 123a56f7f81836d13fbbd027dc5a6a3788f822be..feb27a0ccfb4d80cffe7eb64ac99e4929fdf739b 100644 (file)
 
                        dmc: bus@38000 {
                                compatible = "simple-bus";
-                               reg = <0x0 0x38000 0x0 0x400>;
                                #address-cells = <2>;
                                #size-cells = <2>;
-                               ranges = <0x0 0x0 0x0 0x38000 0x0 0x400>;
+                               ranges = <0x0 0x0 0x0 0x38000 0x0 0x2000>;
 
                                canvas: video-lut@48 {
                                        compatible = "amlogic,canvas";
                                        reg = <0x0 0x48 0x0 0x14>;
                                };
+
+                               pmu: pmu@80 {
+                                       reg = <0x0 0x80 0x0 0x40>,
+                                             <0x0 0xc00 0x0 0x40>;
+                                       interrupts = <GIC_SPI 52 IRQ_TYPE_EDGE_RISING>;
+                               };
                        };
 
                        usb2_phy1: phy@3a000 {
                        };
                };
 
-               pmu: pmu@ff638000 {
-                       reg = <0x0 0xff638000 0x0 0x100>,
-                             <0x0 0xff638c00 0x0 0x100>;
-                       interrupts = <GIC_SPI 52 IRQ_TYPE_EDGE_RISING>;
-               };
-
                aobus: bus@ff800000 {
                        compatible = "simple-bus";
                        reg = <0x0 0xff800000 0x0 0x100000>;
index af9194eca5564df46b71cd51549a5e2898d75bf8..73eb6061c73eeaa475ef80812c2371476da36210 100644 (file)
 };
 
 &enetc_port2 {
-       nvmem-cells = <&base_mac_address 2>;
-       nvmem-cell-names = "mac-address";
        status = "okay";
 };
 
 &enetc_port3 {
-       nvmem-cells = <&base_mac_address 3>;
-       nvmem-cell-names = "mac-address";
        status = "okay";
 };
 
@@ -84,8 +80,6 @@
        managed = "in-band-status";
        phy-handle = <&qsgmii_phy0>;
        phy-mode = "qsgmii";
-       nvmem-cells = <&base_mac_address 4>;
-       nvmem-cell-names = "mac-address";
        status = "okay";
 };
 
@@ -94,8 +88,6 @@
        managed = "in-band-status";
        phy-handle = <&qsgmii_phy1>;
        phy-mode = "qsgmii";
-       nvmem-cells = <&base_mac_address 5>;
-       nvmem-cell-names = "mac-address";
        status = "okay";
 };
 
        managed = "in-band-status";
        phy-handle = <&qsgmii_phy2>;
        phy-mode = "qsgmii";
-       nvmem-cells = <&base_mac_address 6>;
-       nvmem-cell-names = "mac-address";
        status = "okay";
 };
 
        managed = "in-band-status";
        phy-handle = <&qsgmii_phy3>;
        phy-mode = "qsgmii";
-       nvmem-cells = <&base_mac_address 7>;
-       nvmem-cell-names = "mac-address";
        status = "okay";
 };
 
index 1f34c75534594ce25b440ee6d5dae1be0b3168ec..7cd29ab970d9237ee4675c87ee6f39b279aae2ba 100644 (file)
@@ -55,7 +55,5 @@
 &enetc_port1 {
        phy-handle = <&phy0>;
        phy-mode = "rgmii-id";
-       nvmem-cells = <&base_mac_address 0>;
-       nvmem-cell-names = "mac-address";
        status = "okay";
 };
index aac41192caa12801d853f96d71adee7a2599e808..113b1df74bf87cdebf0607ef3020c3e2b35ed6b2 100644 (file)
 };
 
 &enetc_port2 {
-       nvmem-cells = <&base_mac_address 2>;
-       nvmem-cell-names = "mac-address";
        status = "okay";
 };
 
 &enetc_port3 {
-       nvmem-cells = <&base_mac_address 3>;
-       nvmem-cell-names = "mac-address";
        status = "okay";
 };
 
@@ -56,8 +52,6 @@
        managed = "in-band-status";
        phy-handle = <&phy0>;
        phy-mode = "sgmii";
-       nvmem-cells = <&base_mac_address 0>;
-       nvmem-cell-names = "mac-address";
        status = "okay";
 };
 
@@ -66,8 +60,6 @@
        managed = "in-band-status";
        phy-handle = <&phy1>;
        phy-mode = "sgmii";
-       nvmem-cells = <&base_mac_address 1>;
-       nvmem-cell-names = "mac-address";
        status = "okay";
 };
 
index a4421db3784e325602ac89c9c72d28b34418d6ce..9b5e92fb753e22effdb5b14f04cf3371291df162 100644 (file)
@@ -43,7 +43,5 @@
 &enetc_port1 {
        phy-handle = <&phy1>;
        phy-mode = "rgmii-id";
-       nvmem-cells = <&base_mac_address 1>;
-       nvmem-cell-names = "mac-address";
        status = "okay";
 };
index 8b65af4a7147b6520907e282171bde5611acdffb..4ab17b984b03bc77e2243cbbfffb4d19ef3f8a4f 100644 (file)
@@ -92,8 +92,6 @@
        phy-handle = <&phy0>;
        phy-mode = "sgmii";
        managed = "in-band-status";
-       nvmem-cells = <&base_mac_address 0>;
-       nvmem-cell-names = "mac-address";
        status = "okay";
 };
 
                                label = "bootloader environment";
                        };
                };
-
-               otp-1 {
-                       compatible = "user-otp";
-
-                       nvmem-layout {
-                               compatible = "kontron,sl28-vpd";
-
-                               serial_number: serial-number {
-                               };
-
-                               base_mac_address: base-mac-address {
-                                       #nvmem-cell-cells = <1>;
-                               };
-                       };
-               };
        };
 };
 
index 1f3d225e64ece966390d4bdc967f538034a4d977..06b94bbc2b97d316188aec7fdf75d013d8d485ac 100644 (file)
@@ -117,7 +117,7 @@ lsio_subsys: bus@5d000000 {
                interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&clk IMX_SC_R_FSPI_0 IMX_SC_PM_CLK_PER>,
                         <&clk IMX_SC_R_FSPI_0 IMX_SC_PM_CLK_PER>;
-               clock-names = "fspi", "fspi_en";
+               clock-names = "fspi_en", "fspi";
                power-domains = <&pd IMX_SC_R_FSPI_0>;
                status = "disabled";
        };
index 1bcf228a22b8b3d21585fe338cb2eafa5127830f..852420349c01332544247d5de35acdfd0ee71d82 100644 (file)
        phy-handle = <&ethphy0>;
        nvmem-cells = <&fec_mac1>;
        nvmem-cell-names = "mac-address";
-       snps,reset-gpios = <&pca6416_1 2 GPIO_ACTIVE_LOW>;
-       snps,reset-delays-us = <10 20 200000>;
        status = "okay";
 
        mdio {
                        eee-broken-1000t;
                        qca,disable-smarteee;
                        qca,disable-hibernation-mode;
+                       reset-gpios = <&pca6416_1 2 GPIO_ACTIVE_LOW>;
+                       reset-assert-us = <20>;
+                       reset-deassert-us = <200000>;
                        vddio-supply = <&vddio0>;
 
                        vddio0: vddio-regulator {
index d1a6390976a9caeaadc97d15a828608dc53ab39d..3f9dfd4d38848fc314cb7081b97c6968f3429dcf 100644 (file)
                rohm,reset-snvs-powered;
 
                #clock-cells = <0>;
-               clocks = <&osc_32k 0>;
+               clocks = <&osc_32k>;
                clock-output-names = "clk-32k-out";
 
                regulators {
index 6357078185eddb44d64d4ce0cbb4b89231a55111..0e8f0d7161ad0f4989c91149bbb29f20d000a45e 100644 (file)
                compatible = "wlf,wm8960";
                reg = <0x1a>;
                clocks = <&clk IMX8MM_CLK_SAI1_ROOT>;
-               clock-names = "mclk1";
+               clock-names = "mclk";
                wlf,shared-lrclk;
                #sound-dai-cells = <0>;
        };
index 88321b5b0693e52003c5ee48698861c970c88725..6f0811587142d2725db959d100e7229c6ca82f02 100644 (file)
@@ -99,7 +99,7 @@
                compatible = "regulator-fixed";
                enable-active-high;
                gpio = <&gpio2 20 GPIO_ACTIVE_HIGH>; /* PMIC_EN_ETH */
-               off-on-delay = <500000>;
+               off-on-delay-us = <500000>;
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_reg_eth>;
                regulator-always-on;
                enable-active-high;
                /* Verdin SD_1_PWR_EN (SODIMM 76) */
                gpio = <&gpio3 5 GPIO_ACTIVE_HIGH>;
-               off-on-delay = <100000>;
+               off-on-delay-us = <100000>;
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_usdhc2_pwr_en>;
                regulator-max-microvolt = <3300000>;
index ed9ac6c5047c087565adbb8ed406c6677ec2fe22..9e0ddd6b7a322d269658c8a886fe1df9a59e9214 100644 (file)
                                sai2: sai@30020000 {
                                        compatible = "fsl,imx8mn-sai", "fsl,imx8mq-sai";
                                        reg = <0x30020000 0x10000>;
+                                       #sound-dai-cells = <0>;
                                        interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clk IMX8MN_CLK_SAI2_IPG>,
                                                <&clk IMX8MN_CLK_DUMMY>,
                                sai3: sai@30030000 {
                                        compatible = "fsl,imx8mn-sai", "fsl,imx8mq-sai";
                                        reg = <0x30030000 0x10000>;
+                                       #sound-dai-cells = <0>;
                                        interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clk IMX8MN_CLK_SAI3_IPG>,
                                                 <&clk IMX8MN_CLK_DUMMY>,
                                sai5: sai@30050000 {
                                        compatible = "fsl,imx8mn-sai", "fsl,imx8mq-sai";
                                        reg = <0x30050000 0x10000>;
+                                       #sound-dai-cells = <0>;
                                        interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clk IMX8MN_CLK_SAI5_IPG>,
                                                 <&clk IMX8MN_CLK_DUMMY>,
                                sai6: sai@30060000 {
                                        compatible = "fsl,imx8mn-sai", "fsl,imx8mq-sai";
                                        reg = <0x30060000  0x10000>;
+                                       #sound-dai-cells = <0>;
                                        interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clk IMX8MN_CLK_SAI6_IPG>,
                                                 <&clk IMX8MN_CLK_DUMMY>,
                                sai7: sai@300b0000 {
                                        compatible = "fsl,imx8mn-sai", "fsl,imx8mq-sai";
                                        reg = <0x300b0000 0x10000>;
+                                       #sound-dai-cells = <0>;
                                        interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clk IMX8MN_CLK_SAI7_IPG>,
                                                 <&clk IMX8MN_CLK_DUMMY>,
index 361426c0da0a27d2bf1e34f12c04cf3c35ef6dbc..c29622529200756040d9720a4d32afb09f9124fe 100644 (file)
@@ -10,7 +10,7 @@
                compatible = "regulator-fixed";
                enable-active-high;
                gpio = <&gpio_expander_21 4 GPIO_ACTIVE_HIGH>; /* ETH_PWR_EN */
-               off-on-delay = <500000>;
+               off-on-delay-us = <500000>;
                regulator-max-microvolt = <3300000>;
                regulator-min-microvolt = <3300000>;
                regulator-name = "+V3.3_ETH";
index 0dd6180a8e395b47976e9c8b1ca656218756c955..1608775da0adaa4cca400eadb59de4ee6820b7fb 100644 (file)
@@ -87,7 +87,7 @@
                compatible = "regulator-fixed";
                enable-active-high;
                gpio = <&gpio2 20 GPIO_ACTIVE_HIGH>; /* PMIC_EN_ETH */
-               off-on-delay = <500000>;
+               off-on-delay-us = <500000>;
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_reg_eth>;
                regulator-always-on;
                enable-active-high;
                /* Verdin SD_1_PWR_EN (SODIMM 76) */
                gpio = <&gpio4 22 GPIO_ACTIVE_HIGH>;
-               off-on-delay = <100000>;
+               off-on-delay-us = <100000>;
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_usdhc2_pwr_en>;
                regulator-max-microvolt = <3300000>;
index a19224fe1a6adf15fdbabb87baffcd4c7fb359db..a237275ee017963d26bce4bbad9fb88ef4dcb6de 100644 (file)
 
                        lcdif2: display-controller@32e90000 {
                                compatible = "fsl,imx8mp-lcdif";
-                               reg = <0x32e90000 0x238>;
+                               reg = <0x32e90000 0x10000>;
                                interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX8MP_CLK_MEDIA_DISP2_PIX_ROOT>,
-                                        <&clk IMX8MP_CLK_MEDIA_AXI_ROOT>,
-                                        <&clk IMX8MP_CLK_MEDIA_APB_ROOT>;
+                                        <&clk IMX8MP_CLK_MEDIA_APB_ROOT>,
+                                        <&clk IMX8MP_CLK_MEDIA_AXI_ROOT>;
                                clock-names = "pix", "axi", "disp_axi";
                                assigned-clocks = <&clk IMX8MP_CLK_MEDIA_DISP2_PIX>,
                                                  <&clk IMX8MP_VIDEO_PLL1>;
index 2076f9c9983ad0317c5881cc498cbe7a6c532ff3..41efd97dd6d6dcee0318607608b63faf0f3c6ff6 100644 (file)
                        lpi2c1: i2c@44340000 {
                                compatible = "fsl,imx93-lpi2c", "fsl,imx7ulp-lpi2c";
                                reg = <0x44340000 0x10000>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
                                interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX93_CLK_LPI2C1_GATE>,
                                         <&clk IMX93_CLK_BUS_AON>;
                        lpi2c2: i2c@44350000 {
                                compatible = "fsl,imx93-lpi2c", "fsl,imx7ulp-lpi2c";
                                reg = <0x44350000 0x10000>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
                                interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX93_CLK_LPI2C2_GATE>,
                                         <&clk IMX93_CLK_BUS_AON>;
                        lpi2c3: i2c@42530000 {
                                compatible = "fsl,imx93-lpi2c", "fsl,imx7ulp-lpi2c";
                                reg = <0x42530000 0x10000>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
                                interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX93_CLK_LPI2C3_GATE>,
                                         <&clk IMX93_CLK_BUS_WAKEUP>;
                        lpi2c4: i2c@42540000 {
                                compatible = "fsl,imx93-lpi2c", "fsl,imx7ulp-lpi2c";
                                reg = <0x42540000 0x10000>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
                                interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX93_CLK_LPI2C4_GATE>,
                                         <&clk IMX93_CLK_BUS_WAKEUP>;
                        lpi2c5: i2c@426b0000 {
                                compatible = "fsl,imx93-lpi2c", "fsl,imx7ulp-lpi2c";
                                reg = <0x426b0000 0x10000>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
                                interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX93_CLK_LPI2C5_GATE>,
                                         <&clk IMX93_CLK_BUS_WAKEUP>;
                        lpi2c6: i2c@426c0000 {
                                compatible = "fsl,imx93-lpi2c", "fsl,imx7ulp-lpi2c";
                                reg = <0x426c0000 0x10000>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
                                interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX93_CLK_LPI2C6_GATE>,
                                         <&clk IMX93_CLK_BUS_WAKEUP>;
                        lpi2c7: i2c@426d0000 {
                                compatible = "fsl,imx93-lpi2c", "fsl,imx7ulp-lpi2c";
                                reg = <0x426d0000 0x10000>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
                                interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX93_CLK_LPI2C7_GATE>,
                                         <&clk IMX93_CLK_BUS_WAKEUP>;
                        lpi2c8: i2c@426e0000 {
                                compatible = "fsl,imx93-lpi2c", "fsl,imx7ulp-lpi2c";
                                reg = <0x426e0000 0x10000>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
                                interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX93_CLK_LPI2C8_GATE>,
                                         <&clk IMX93_CLK_BUS_WAKEUP>;
                        eqos: ethernet@428a0000 {
                                compatible = "nxp,imx93-dwmac-eqos", "snps,dwmac-5.10a";
                                reg = <0x428a0000 0x10000>;
-                               interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>,
-                                            <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
-                               interrupt-names = "eth_wake_irq", "macirq";
+                               interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "macirq", "eth_wake_irq";
                                clocks = <&clk IMX93_CLK_ENET_QOS_GATE>,
                                         <&clk IMX93_CLK_ENET_QOS_GATE>,
                                         <&clk IMX93_CLK_ENET_TIMER2>,
                                                         <&clk IMX93_CLK_SYS_PLL_PFD0_DIV2>;
                                assigned-clock-rates = <100000000>, <250000000>;
                                intf_mode = <&wakeupmix_gpr 0x28>;
-                               clk_csr = <0>;
+                               snps,clk-csr = <0>;
                                status = "disabled";
                        };
 
index 133dbe5b429d8db13a26cc703bde55f17b9c588c..7096b999b33f8a9ca9ac2b7b4de9cefede4f98c8 100644 (file)
@@ -22,7 +22,7 @@
 
                #address-cells = <2>;
                #size-cells = <2>;
-               ranges = <0x0 0x0 0x0 0x0 0x0 0x40000000>;
+               ranges = <0x0 0x0 0x0 0x0 0x100 0x0>;
 
                apbmisc: misc@100000 {
                        compatible = "nvidia,tegra194-misc";
index 8fe8eda7654d878387d5a2a25f75009045e056d5..f1748cff8a33ba6c1261ef6532b8fb8324f19958 100644 (file)
@@ -20,7 +20,7 @@
 
                #address-cells = <2>;
                #size-cells = <2>;
-               ranges = <0x0 0x0 0x0 0x0 0x0 0x40000000>;
+               ranges = <0x0 0x0 0x0 0x0 0x100 0x0>;
 
                misc@100000 {
                        compatible = "nvidia,tegra234-misc";
index ca3f96646b90d1aefd3cebf66ae25fb7162b88ce..5cf07caf4103370c4f052d8e9af27849cad4dbb0 100644 (file)
        perst-gpios = <&tlmm 58 GPIO_ACTIVE_LOW>;
 };
 
-&pcie_phy0 {
+&pcie_qmp0 {
        status = "okay";
 };
 
-&pcie_phy1 {
+&pcie_qmp1 {
        status = "okay";
 };
 
index 651a231554e0b6e17fb3dc77687ceebfe7fa360d..1b8379ba87f9c778cae214fda62a1cfe5aa01004 100644 (file)
        perst-gpios = <&tlmm 61 GPIO_ACTIVE_LOW>;
 };
 
-&pcie_phy0 {
+&pcie_qmp0 {
        status = "okay";
 };
 
-&pcie_phy1 {
+&pcie_qmp1 {
        status = "okay";
 };
 
index c492db8561904e0deef7751dd2d5e48d076d56a1..82e260375174d1b86608db45876ff363ff1acd52 100644 (file)
@@ -33,7 +33,3 @@
 &gpio_leds_default {
        pins = "gpio81", "gpio82", "gpio83";
 };
-
-&sim_ctrl_default {
-       pins = "gpio1", "gpio2";
-};
index 700cf81cbf8c0cb512d0bdabc8e70d5f90ce3eab..8433c9710b1cfc11a77e319e0f70533beb0c213c 100644 (file)
        gpios = <&msmgpio 20 GPIO_ACTIVE_HIGH>;
 };
 
+&mpss {
+       pinctrl-0 = <&sim_ctrl_default>;
+       pinctrl-names = "default";
+};
+
 &button_default {
        pins = "gpio37";
        bias-pull-down;
        pins = "gpio20", "gpio21", "gpio22";
 };
 
-&sim_ctrl_default {
-       pins = "gpio1", "gpio2";
+/* This selects the external SIM card slot by default */
+&msmgpio {
+       sim_ctrl_default: sim-ctrl-default-state {
+               esim-sel-pins {
+                       pins = "gpio0", "gpio3";
+                       bias-disable;
+                       output-low;
+               };
+
+               sim-en-pins {
+                       pins = "gpio1";
+                       bias-disable;
+                       output-low;
+               };
+
+               sim-sel-pins {
+                       pins = "gpio2";
+                       bias-disable;
+                       output-high;
+               };
+       };
 };
index 790a9696da9de7457ba1fa7b1caff90ff0adb505..cdf34b74fa8faa132c0bad1cfd7b6efac40bd380 100644 (file)
@@ -92,9 +92,6 @@
 };
 
 &mpss {
-       pinctrl-0 = <&sim_ctrl_default>;
-       pinctrl-names = "default";
-
        status = "okay";
 };
 
                drive-strength = <2>;
                bias-disable;
        };
-
-       sim_ctrl_default: sim-ctrl-default-state {
-               function = "gpio";
-               drive-strength = <2>;
-               bias-disable;
-               output-low;
-       };
 };
index aa0a7bd7307ce18cc296c05c78506cd537e71639..dd924331b0eea6b1557fcfb02f0accc60756a328 100644 (file)
        left_spkr: speaker@0,3 {
                compatible = "sdw10217211000";
                reg = <0 3>;
-               powerdown-gpios = <&tlmm 130 GPIO_ACTIVE_HIGH>;
+               powerdown-gpios = <&tlmm 130 GPIO_ACTIVE_LOW>;
                #thermal-sensor-cells = <0>;
                sound-name-prefix = "SpkrLeft";
                #sound-dai-cells = <0>;
        right_spkr: speaker@0,4 {
                compatible = "sdw10217211000";
                reg = <0 4>;
-               powerdown-gpios = <&tlmm 130 GPIO_ACTIVE_HIGH>;
+               powerdown-gpios = <&tlmm 130 GPIO_ACTIVE_LOW>;
                #thermal-sensor-cells = <0>;
                sound-name-prefix = "SpkrRight";
                #sound-dai-cells = <0>;
index 3ccb5ffdb3ca3f29bbc636026f7944f1c2494ec2..24fa449d48a6640a0753366c95b947f02c51b431 100644 (file)
 };
 
 &remoteproc_nsp0 {
-       firmware-name = "qcom/sa8540p/cdsp.mbn";
+       firmware-name = "qcom/sa8540p/cdsp0.mbn";
        status = "okay";
 };
 
index b6137816f2f3d2e3ca832010e4e98f9de896f985..313083ec1f3966ed6f62332cab6ba04bee07bf72 100644 (file)
@@ -464,7 +464,7 @@ ap_i2c_tpm: &i2c14 {
 
 &mdss_dp_out {
        data-lanes = <0 1>;
-       link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
+       link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000>;
 };
 
 &mdss_mdp {
index bdcb74925313042d218163cb2b4fa01cf6488da3..8f4ab6bd28864fc680d9fcc8da96d2a770f80c8d 100644 (file)
                        pinctrl-names = "default";
                        pinctrl-0 = <&pcie1_clkreq_n>;
 
+                       dma-coherent;
+
                        iommus = <&apps_smmu 0x1c80 0x1>;
 
                        iommu-map = <0x0 &apps_smmu 0x1c80 0x1>,
index 98e71b933437c91693d91654c9598869e24773ec..99c6d6574559fbfb0b73ffb3cdca89450f29db62 100644 (file)
                        regulator-min-microvolt = <1800000>;
                        regulator-max-microvolt = <1800000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+                       regulator-always-on;
                };
 
                vreg_s11b: smps11 {
                        regulator-min-microvolt = <1272000>;
                        regulator-max-microvolt = <1272000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+                       regulator-always-on;
                };
 
                vreg_s12b: smps12 {
                        regulator-min-microvolt = <984000>;
                        regulator-max-microvolt = <984000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+                       regulator-always-on;
                };
 
                vreg_l3b: ldo3 {
                        regulator-min-microvolt = <3008000>;
                        regulator-max-microvolt = <3960000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
+                       regulator-always-on;
                };
        };
 
        pmic-die-temp@3 {
                reg = <PMK8350_ADC7_DIE_TEMP>;
                qcom,pre-scaling = <1 1>;
+               label = "pmk8350_die_temp";
        };
 
        xo-therm@44 {
                reg = <PMK8350_ADC7_AMUX_THM1_100K_PU>;
                qcom,hw-settle-time = <200>;
                qcom,ratiometric;
+               label = "pmk8350_xo_therm";
        };
 
        pmic-die-temp@103 {
                reg = <PM8350_ADC7_DIE_TEMP(1)>;
                qcom,pre-scaling = <1 1>;
+               label = "pmc8280_1_die_temp";
        };
 
        sys-therm@144 {
                reg = <PM8350_ADC7_AMUX_THM1_100K_PU(1)>;
                qcom,hw-settle-time = <200>;
                qcom,ratiometric;
+               label = "sys_therm1";
        };
 
        sys-therm@145 {
                reg = <PM8350_ADC7_AMUX_THM2_100K_PU(1)>;
                qcom,hw-settle-time = <200>;
                qcom,ratiometric;
+               label = "sys_therm2";
        };
 
        sys-therm@146 {
                reg = <PM8350_ADC7_AMUX_THM3_100K_PU(1)>;
                qcom,hw-settle-time = <200>;
                qcom,ratiometric;
+               label = "sys_therm3";
        };
 
        sys-therm@147 {
                reg = <PM8350_ADC7_AMUX_THM4_100K_PU(1)>;
                qcom,hw-settle-time = <200>;
                qcom,ratiometric;
+               label = "sys_therm4";
        };
 
        pmic-die-temp@303 {
                reg = <PM8350_ADC7_DIE_TEMP(3)>;
                qcom,pre-scaling = <1 1>;
+               label = "pmc8280_2_die_temp";
        };
 
        sys-therm@344 {
                reg = <PM8350_ADC7_AMUX_THM1_100K_PU(3)>;
                qcom,hw-settle-time = <200>;
                qcom,ratiometric;
+               label = "sys_therm5";
        };
 
        sys-therm@345 {
                reg = <PM8350_ADC7_AMUX_THM2_100K_PU(3)>;
                qcom,hw-settle-time = <200>;
                qcom,ratiometric;
+               label = "sys_therm6";
        };
 
        sys-therm@346 {
                reg = <PM8350_ADC7_AMUX_THM3_100K_PU(3)>;
                qcom,hw-settle-time = <200>;
                qcom,ratiometric;
+               label = "sys_therm7";
        };
 
        sys-therm@347 {
                reg = <PM8350_ADC7_AMUX_THM4_100K_PU(3)>;
                qcom,hw-settle-time = <200>;
                qcom,ratiometric;
+               label = "sys_therm8";
        };
 
        pmic-die-temp@403 {
                reg = <PMR735A_ADC7_DIE_TEMP>;
                qcom,pre-scaling = <1 1>;
+               label = "pmr735a_die_temp";
        };
 };
 
                "VA DMIC0", "MIC BIAS1",
                "VA DMIC1", "MIC BIAS1",
                "VA DMIC2", "MIC BIAS3",
-               "TX DMIC0", "MIC BIAS1",
-               "TX DMIC1", "MIC BIAS2",
-               "TX DMIC2", "MIC BIAS3",
+               "VA DMIC0", "VA MIC BIAS1",
+               "VA DMIC1", "VA MIC BIAS1",
+               "VA DMIC2", "VA MIC BIAS3",
                "TX SWR_ADC1", "ADC2_OUTPUT";
 
        wcd-playback-dai-link {
        va-dai-link {
                link-name = "VA Capture";
                cpu {
-                       sound-dai = <&q6apmbedai TX_CODEC_DMA_TX_3>;
+                       sound-dai = <&q6apmbedai VA_CODEC_DMA_TX_0>;
                };
 
                platform {
 
        vdd-micb-supply = <&vreg_s10b>;
 
-       qcom,dmic-sample-rate = <600000>;
+       qcom,dmic-sample-rate = <4800000>;
 
        status = "okay";
 };
index df7d28f7ae60e2aeb4ceeaf720c92869808d66bc..be446eba4fa76d7ff36037477bbee85c87162b88 100644 (file)
@@ -59,8 +59,9 @@
                #size-cells = <0>;
 
                pmk8280_pon: pon@1300 {
-                       compatible = "qcom,pm8998-pon";
-                       reg = <0x1300>;
+                       compatible = "qcom,pmk8350-pon";
+                       reg = <0x1300>, <0x800>;
+                       reg-names = "hlos", "pbs";
 
                        pmk8280_pon_pwrkey: pwrkey {
                                compatible = "qcom,pmk8350-pwrkey";
index 0d02599d8867227eb22c7594dbfeb4da34fc12b3..42bfa9fa5b9675b799eef46540de42388eafb0c7 100644 (file)
                        qcom,ports-sinterval-low =      /bits/ 8 <0x03 0x1f 0x1f 0x07 0x00>;
                        qcom,ports-offset1 =            /bits/ 8 <0x00 0x00 0x0B 0x01 0x00>;
                        qcom,ports-offset2 =            /bits/ 8 <0x00 0x00 0x0B 0x00 0x00>;
-                       qcom,ports-hstart =             /bits/ 8 <0xff 0x03 0xff 0xff 0xff>;
-                       qcom,ports-hstop =              /bits/ 8 <0xff 0x06 0xff 0xff 0xff>;
+                       qcom,ports-hstart =             /bits/ 8 <0xff 0x03 0x00 0xff 0xff>;
+                       qcom,ports-hstop =              /bits/ 8 <0xff 0x06 0x0f 0xff 0xff>;
                        qcom,ports-word-length =        /bits/ 8 <0x01 0x07 0x04 0xff 0xff>;
-                       qcom,ports-block-pack-mode =    /bits/ 8 <0xff 0x00 0x01 0xff 0xff>;
+                       qcom,ports-block-pack-mode =    /bits/ 8 <0xff 0xff 0x01 0xff 0xff>;
                        qcom,ports-lane-control =       /bits/ 8 <0x01 0x00 0x00 0x00 0x00>;
-                       qcom,ports-block-group-count =  /bits/ 8 <0xff 0xff 0xff 0xff 0x00>;
+                       qcom,ports-block-group-count =  /bits/ 8 <0xff 0xff 0xff 0xff 0xff>;
 
                        #sound-dai-cells = <1>;
                        #address-cells = <2>;
                                              <&intc GIC_SPI 520 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "core", "wake";
 
-                       clocks = <&vamacro>;
+                       clocks = <&txmacro>;
                        clock-names = "iface";
                        label = "TX";
                        #sound-dai-cells = <1>;
 
                        qcom,din-ports = <4>;
                        qcom,dout-ports = <0>;
-                       qcom,ports-sinterval-low =      /bits/ 8 <0x01 0x03 0x03 0x03>;
-                       qcom,ports-offset1 =            /bits/ 8 <0x01 0x00 0x02 0x01>;
+                       qcom,ports-sinterval-low =      /bits/ 8 <0x01 0x01 0x03 0x03>;
+                       qcom,ports-offset1 =            /bits/ 8 <0x01 0x00 0x02 0x00>;
                        qcom,ports-offset2 =            /bits/ 8 <0x00 0x00 0x00 0x00>;
                        qcom,ports-block-pack-mode =    /bits/ 8 <0xff 0xff 0xff 0xff>;
                        qcom,ports-hstart =             /bits/ 8 <0xff 0xff 0xff 0xff>;
                        qcom,ports-hstop =              /bits/ 8 <0xff 0xff 0xff 0xff>;
-                       qcom,ports-word-length =        /bits/ 8 <0xff 0x00 0xff 0xff>;
+                       qcom,ports-word-length =        /bits/ 8 <0xff 0xff 0xff 0xff>;
                        qcom,ports-block-group-count =  /bits/ 8 <0xff 0xff 0xff 0xff>;
-                       qcom,ports-lane-control =       /bits/ 8 <0x00 0x01 0x00 0x00>;
+                       qcom,ports-lane-control =       /bits/ 8 <0x00 0x01 0x00 0x01>;
 
                        status = "disabled";
                };
index 67d2a663ce758024b5defb1cee2b9d5194359b98..5c688cb6a7ce0baed1cf6acf0877b0a2a7be1577 100644 (file)
                left_spkr: speaker@0,3 {
                        compatible = "sdw10217211000";
                        reg = <0 3>;
-                       powerdown-gpios = <&wcdgpio 1 GPIO_ACTIVE_HIGH>;
+                       powerdown-gpios = <&wcdgpio 1 GPIO_ACTIVE_LOW>;
                        #thermal-sensor-cells = <0>;
                        sound-name-prefix = "SpkrLeft";
                        #sound-dai-cells = <0>;
 
                right_spkr: speaker@0,4 {
                        compatible = "sdw10217211000";
-                       powerdown-gpios = <&wcdgpio 2 GPIO_ACTIVE_HIGH>;
+                       powerdown-gpios = <&wcdgpio 2 GPIO_ACTIVE_LOW>;
                        reg = <0 4>;
                        #thermal-sensor-cells = <0>;
                        sound-name-prefix = "SpkrRight";
index 9850140514ba2c8cc5eb8600dae5420162c06bd8..41f59e32af644c10c137a74e9766d4a883ad5fb6 100644 (file)
                left_spkr: speaker@0,3 {
                        compatible = "sdw10217211000";
                        reg = <0 3>;
-                       powerdown-gpios = <&wcdgpio 1 GPIO_ACTIVE_HIGH>;
+                       powerdown-gpios = <&wcdgpio 1 GPIO_ACTIVE_LOW>;
                        #thermal-sensor-cells = <0>;
                        sound-name-prefix = "SpkrLeft";
                        #sound-dai-cells = <0>;
 
                right_spkr: speaker@0,4 {
                        compatible = "sdw10217211000";
-                       powerdown-gpios = <&wcdgpio 2 GPIO_ACTIVE_HIGH>;
+                       powerdown-gpios = <&wcdgpio 2 GPIO_ACTIVE_LOW>;
                        reg = <0 4>;
                        #thermal-sensor-cells = <0>;
                        sound-name-prefix = "SpkrRight";
index 4d6ec815b78b11b89c0087e0d6a1f94bfa6031d4..fbd67d2c8d78133dc5a44e22f91a328e1868cb71 100644 (file)
                                dma-names = "tx", "rx";
                                #address-cells = <1>;
                                #size-cells = <0>;
+                               status = "disabled";
                        };
                };
 
index 31b88c738510278eeab6aee842aabda505449fb3..068ee4f724855a256d8efb92f4f30e1d3dc4cd0f 100644 (file)
                        clock-names = "xo";
 
                        power-domains = <&rpmpd SM6375_VDDCX>;
+                       power-domain-names = "cx";
 
                        memory-region = <&pil_cdsp_mem>;
 
index fd20096cfc6e30f9deb5be005346deb38c012494..13e0ce8286061c7f5818c2cc08a022f4102ec28f 100644 (file)
                                      "slave_q2a",
                                      "tbu";
 
-                       iommus = <&apps_smmu 0x1d80 0x7f>;
+                       iommus = <&apps_smmu 0x1d80 0x3f>;
                        iommu-map = <0x0   &apps_smmu 0x1d80 0x1>,
                                    <0x100 &apps_smmu 0x1d81 0x1>;
 
                        assigned-clocks = <&gcc GCC_PCIE_1_AUX_CLK>;
                        assigned-clock-rates = <19200000>;
 
-                       iommus = <&apps_smmu 0x1e00 0x7f>;
+                       iommus = <&apps_smmu 0x1e00 0x3f>;
                        iommu-map = <0x0   &apps_smmu 0x1e00 0x1>,
                                    <0x100 &apps_smmu 0x1e01 0x1>;
 
index e54cdc8bc31f0bc7a9c9c53fb32dc0c11f341dd4..4c9de236676dccf63b62b353bf7ef41de453eeae 100644 (file)
        left_spkr: speaker@0,3 {
                compatible = "sdw10217211000";
                reg = <0 3>;
-               powerdown-gpios = <&tlmm 26 GPIO_ACTIVE_HIGH>;
+               powerdown-gpios = <&tlmm 26 GPIO_ACTIVE_LOW>;
                #thermal-sensor-cells = <0>;
                sound-name-prefix = "SpkrLeft";
                #sound-dai-cells = <0>;
        right_spkr: speaker@0,4 {
                compatible = "sdw10217211000";
                reg = <0 4>;
-               powerdown-gpios = <&tlmm 127 GPIO_ACTIVE_HIGH>;
+               powerdown-gpios = <&tlmm 127 GPIO_ACTIVE_LOW>;
                #thermal-sensor-cells = <0>;
                sound-name-prefix = "SpkrRight";
                #sound-dai-cells = <0>;
index acaa99c5ff8b11842e42d44258b0f053486854df..a85d47f7a9e82833dbed82f965417b938c0cd2f0 100644 (file)
 };
 
 &venus {
-       firmware-name = "qcom/sm8250/elish/venus.mbn";
+       firmware-name = "qcom/sm8250/xiaomi/elish/venus.mbn";
        status = "okay";
 };
index 1c97e28da6ad85467e99eab74e520e05be1daa15..1a5a612d4234b8a6662cab0ad3850b85cfe116ba 100644 (file)
                        power-domains = <&gcc UFS_PHY_GDSC>;
 
                        iommus = <&apps_smmu 0xe0 0x0>;
+                       dma-coherent;
 
                        clock-names =
                                "core_clk",
index 1a744a33bcf4bbdd1fc0595669777c09a41cf67f..b285b1530c109a4e52d6e0298ed0b158312cc9f6 100644 (file)
                                 <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
                                 <&vamacro>;
                        clock-names = "mclk", "npl", "macro", "dcodec", "fsgen";
-                       assigned-clocks = <&q6prmcc LPASS_CLK_ID_WSA_CORE_TX_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
-                                         <&q6prmcc LPASS_CLK_ID_WSA_CORE_TX_2X_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
+                       assigned-clocks = <&q6prmcc LPASS_CLK_ID_WSA2_CORE_TX_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+                                         <&q6prmcc LPASS_CLK_ID_WSA2_CORE_TX_2X_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
                        assigned-clock-rates = <19200000>, <19200000>;
 
                        #clock-cells = <0>;
                        power-domains = <&gcc UFS_PHY_GDSC>;
 
                        iommus = <&apps_smmu 0xe0 0x0>;
+                       dma-coherent;
 
                        interconnects = <&aggre1_noc MASTER_UFS_MEM 0 &mc_virt SLAVE_EBI1 0>,
                                        <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_UFS_MEM_CFG 0>;
index ff4d342c072571079dbfeb8694531a73ba5dde92..5d0888398b3c377f7504f6c4f10394e34fb2e666 100644 (file)
@@ -66,7 +66,7 @@
 
                CPU0: cpu@0 {
                        device_type = "cpu";
-                       compatible = "qcom,kryo";
+                       compatible = "arm,cortex-a510";
                        reg = <0 0>;
                        enable-method = "psci";
                        next-level-cache = <&L2_0>;
@@ -89,7 +89,7 @@
 
                CPU1: cpu@100 {
                        device_type = "cpu";
-                       compatible = "qcom,kryo";
+                       compatible = "arm,cortex-a510";
                        reg = <0 0x100>;
                        enable-method = "psci";
                        next-level-cache = <&L2_100>;
 
                CPU2: cpu@200 {
                        device_type = "cpu";
-                       compatible = "qcom,kryo";
+                       compatible = "arm,cortex-a510";
                        reg = <0 0x200>;
                        enable-method = "psci";
                        next-level-cache = <&L2_200>;
 
                CPU3: cpu@300 {
                        device_type = "cpu";
-                       compatible = "qcom,kryo";
+                       compatible = "arm,cortex-a715";
                        reg = <0 0x300>;
                        enable-method = "psci";
                        next-level-cache = <&L2_300>;
 
                CPU4: cpu@400 {
                        device_type = "cpu";
-                       compatible = "qcom,kryo";
+                       compatible = "arm,cortex-a715";
                        reg = <0 0x400>;
                        enable-method = "psci";
                        next-level-cache = <&L2_400>;
 
                CPU5: cpu@500 {
                        device_type = "cpu";
-                       compatible = "qcom,kryo";
+                       compatible = "arm,cortex-a710";
                        reg = <0 0x500>;
                        enable-method = "psci";
                        next-level-cache = <&L2_500>;
 
                CPU6: cpu@600 {
                        device_type = "cpu";
-                       compatible = "qcom,kryo";
+                       compatible = "arm,cortex-a710";
                        reg = <0 0x600>;
                        enable-method = "psci";
                        next-level-cache = <&L2_600>;
 
                CPU7: cpu@700 {
                        device_type = "cpu";
-                       compatible = "qcom,kryo";
+                       compatible = "arm,cortex-x3";
                        reg = <0 0x700>;
                        enable-method = "psci";
                        next-level-cache = <&L2_700>;
                        required-opps = <&rpmhpd_opp_nom>;
 
                        iommus = <&apps_smmu 0x60 0x0>;
+                       dma-coherent;
 
                        interconnects = <&aggre1_noc MASTER_UFS_MEM 0 &mc_virt SLAVE_EBI1 0>,
                                        <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_UFS_MEM_CFG 0>;
                lpass_tlmm: pinctrl@6e80000 {
                        compatible = "qcom,sm8550-lpass-lpi-pinctrl";
                        reg = <0 0x06e80000 0 0x20000>,
-                             <0 0x0725a000 0 0x10000>;
+                             <0 0x07250000 0 0x10000>;
                        gpio-controller;
                        #gpio-cells = <2>;
                        gpio-ranges = <&lpass_tlmm 0 0 23>;
                                pins = "gpio28", "gpio29";
                                function = "qup1_se0";
                                drive-strength = <2>;
-                               bias-pull-up;
+                               bias-pull-up = <2200>;
                        };
 
                        qup_i2c1_data_clk: qup-i2c1-data-clk-state {
                                pins = "gpio32", "gpio33";
                                function = "qup1_se1";
                                drive-strength = <2>;
-                               bias-pull-up;
+                               bias-pull-up = <2200>;
                        };
 
                        qup_i2c2_data_clk: qup-i2c2-data-clk-state {
                                pins = "gpio36", "gpio37";
                                function = "qup1_se2";
                                drive-strength = <2>;
-                               bias-pull-up;
+                               bias-pull-up = <2200>;
                        };
 
                        qup_i2c3_data_clk: qup-i2c3-data-clk-state {
                                pins = "gpio40", "gpio41";
                                function = "qup1_se3";
                                drive-strength = <2>;
-                               bias-pull-up;
+                               bias-pull-up = <2200>;
                        };
 
                        qup_i2c4_data_clk: qup-i2c4-data-clk-state {
                                pins = "gpio44", "gpio45";
                                function = "qup1_se4";
                                drive-strength = <2>;
-                               bias-pull-up;
+                               bias-pull-up = <2200>;
                        };
 
                        qup_i2c5_data_clk: qup-i2c5-data-clk-state {
                                pins = "gpio52", "gpio53";
                                function = "qup1_se5";
                                drive-strength = <2>;
-                               bias-pull-up;
+                               bias-pull-up = <2200>;
                        };
 
                        qup_i2c6_data_clk: qup-i2c6-data-clk-state {
                                pins = "gpio48", "gpio49";
                                function = "qup1_se6";
                                drive-strength = <2>;
-                               bias-pull-up;
+                               bias-pull-up = <2200>;
                        };
 
                        qup_i2c8_data_clk: qup-i2c8-data-clk-state {
                                        pins = "gpio57";
                                        function = "qup2_se0_l1_mira";
                                        drive-strength = <2>;
-                                       bias-pull-up;
+                                       bias-pull-up = <2200>;
                                };
 
                                sda-pins {
                                        pins = "gpio56";
                                        function = "qup2_se0_l0_mira";
                                        drive-strength = <2>;
-                                       bias-pull-up;
+                                       bias-pull-up = <2200>;
                                };
                        };
 
                                pins = "gpio60", "gpio61";
                                function = "qup2_se1";
                                drive-strength = <2>;
-                               bias-pull-up;
+                               bias-pull-up = <2200>;
                        };
 
                        qup_i2c10_data_clk: qup-i2c10-data-clk-state {
                                pins = "gpio64", "gpio65";
                                function = "qup2_se2";
                                drive-strength = <2>;
-                               bias-pull-up;
+                               bias-pull-up = <2200>;
                        };
 
                        qup_i2c11_data_clk: qup-i2c11-data-clk-state {
                                pins = "gpio68", "gpio69";
                                function = "qup2_se3";
                                drive-strength = <2>;
-                               bias-pull-up;
+                               bias-pull-up = <2200>;
                        };
 
                        qup_i2c12_data_clk: qup-i2c12-data-clk-state {
                                pins = "gpio2", "gpio3";
                                function = "qup2_se4";
                                drive-strength = <2>;
-                               bias-pull-up;
+                               bias-pull-up = <2200>;
                        };
 
                        qup_i2c13_data_clk: qup-i2c13-data-clk-state {
                                pins = "gpio80", "gpio81";
                                function = "qup2_se5";
                                drive-strength = <2>;
-                               bias-pull-up;
+                               bias-pull-up = <2200>;
                        };
 
                        qup_i2c15_data_clk: qup-i2c15-data-clk-state {
                                pins = "gpio72", "gpio106";
                                function = "qup2_se7";
                                drive-strength = <2>;
-                               bias-pull-up;
+                               bias-pull-up = <2200>;
                        };
 
                        qup_spi0_cs: qup-spi0-cs-state {
index 61b31688b469b26958e0ade3d2f7c87ffcf2c039..ce318e05f0a60a306e897bd478f9d22a6c0db000 100644 (file)
@@ -24,6 +24,8 @@
 
 &internal_display {
        compatible = "elida,kd35t133";
+       iovcc-supply = <&vcc_lcd>;
+       vdd-supply = <&vcc_lcd>;
 };
 
 &pwm0 {
index 04eba432fb0eb2d8217788004f1aadf3979140e0..80fc53c807a42c09faeca9b436e5ffe39865764a 100644 (file)
        internal_display: panel@0 {
                reg = <0>;
                backlight = <&backlight>;
-               iovcc-supply = <&vcc_lcd>;
                reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>;
                rotation = <270>;
-               vdd-supply = <&vcc_lcd>;
 
                port {
                        mipi_in_panel: endpoint {
index 139c898e590e2f3136db561ad4ee798110c42255..d94ac81eb4e67801d373564669eaf26e0ae11aad 100644 (file)
@@ -83,6 +83,8 @@
 
 &internal_display {
        compatible = "elida,kd35t133";
+       iovcc-supply = <&vcc_lcd>;
+       vdd-supply = <&vcc_lcd>;
 };
 
 &rk817 {
index 4702183b673c145c4bcb2a7b00a727f378deafb8..aa6f5b12206bad5198228625ab9395c3f695e98b 100644 (file)
@@ -59,6 +59,8 @@
 
 &internal_display {
        compatible = "elida,kd35t133";
+       iovcc-supply = <&vcc_lcd>;
+       vdd-supply = <&vcc_lcd>;
 };
 
 &rk817_charger {
index 083452c6771197f1f9114ea49a7a14d0e5aeb59b..e47d1398aecac7bbb151cd9d542b57ff7c163b7f 100644 (file)
@@ -61,7 +61,6 @@
                pinctrl-names = "default";
                pinctrl-0 = <&bl_en>;
                pwms = <&pwm0 0 1000000 PWM_POLARITY_INVERTED>;
-               pwm-delay-us = <10000>;
        };
 
        emmc_pwrseq: emmc-pwrseq {
index ee6095baba4d3a0679f1ce01106ae81c05920760..5c1929d41cc0b700998f7aa048cc815306b0f97c 100644 (file)
                power-supply = <&pp3300_disp>;
                pinctrl-names = "default";
                pinctrl-0 = <&bl_en>;
-               pwm-delay-us = <10000>;
        };
 
        gpio_keys: gpio-keys {
index a47d9f758611e2dfc11894b0edc7ff0fc39445ce..c5e7de60c12140c0dae9789cc338ef5f1b9fac3c 100644 (file)
                pinctrl-names = "default";
                pinctrl-0 = <&bl_en>;
                pwms = <&pwm1 0 1000000 0>;
-               pwm-delay-us = <10000>;
        };
 
        dmic: dmic {
index 194e48c755f6bc19d33f0736a0423d6205859450..ddd45de97950caadf131adc08f82f665453fd400 100644 (file)
                pinctrl-0 = <&panel_en_pin>;
                power-supply = <&vcc3v3_panel>;
 
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       port@0 {
-                               reg = <0>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               panel_in_edp: endpoint@0 {
-                                       reg = <0>;
-                                       remote-endpoint = <&edp_out_panel>;
-                               };
+               port {
+                       panel_in_edp: endpoint {
+                               remote-endpoint = <&edp_out_panel>;
                        };
                };
        };
        disable-wp;
        pinctrl-names = "default";
        pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>;
-       sd-uhs-sdr104;
+       sd-uhs-sdr50;
        vmmc-supply = <&vcc3v0_sd>;
        vqmmc-supply = <&vcc_sdio>;
        status = "okay";
index 78157521e94493c32b74c27b7694a734027ec37e..bca2b50e0a93473d6fe63fbcb682d5cb2ad8d126 100644 (file)
                avdd-supply = <&avdd>;
                backlight = <&backlight>;
                dvdd-supply = <&vcc3v3_s0>;
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
 
-                       port@0 {
-                               reg = <0>;
-
-                               mipi_in_panel: endpoint {
-                                       remote-endpoint = <&mipi_out_panel>;
-                               };
+               port {
+                       mipi_in_panel: endpoint {
+                               remote-endpoint = <&mipi_out_panel>;
                        };
                };
        };
index 1881b4b71f91d756b2ac62a17cd3668ab88fc856..40e7c4a700555afd6a7055a3ffd1b266b3606d9a 100644 (file)
                      <0x0 0xfff10000 0 0x10000>, /* GICH */
                      <0x0 0xfff20000 0 0x10000>; /* GICV */
                interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
-               its: interrupt-controller@fee20000 {
+               its: msi-controller@fee20000 {
                        compatible = "arm,gic-v3-its";
                        msi-controller;
                        #msi-cells = <1>;
index 65a80d1f6d911a5d400d57502c61da5f56581d00..9a0e217f069ff1a8ecdb75c5903f6407a1dfc708 100644 (file)
 };
 
 &cru {
-       assigned-clocks = <&cru PLL_GPLL>, <&pmucru PLL_PPLL>, <&cru PLL_VPLL>;
-       assigned-clock-rates = <1200000000>, <200000000>, <241500000>;
+       assigned-clocks = <&pmucru CLK_RTC_32K>, <&cru PLL_GPLL>,
+                         <&pmucru PLL_PPLL>, <&cru PLL_VPLL>;
+       assigned-clock-rates = <32768>, <1200000000>,
+                              <200000000>, <241500000>;
 };
 
 &gpio_keys_control {
index b4b2df821cba90412ad7a60e5752b2590ddb23b4..c763c7f3b1b38b71fc1702c1e6a157d58e6af2e8 100644 (file)
 };
 
 &cru {
-       assigned-clocks = <&cru PLL_GPLL>, <&pmucru PLL_PPLL>, <&cru PLL_VPLL>;
-       assigned-clock-rates = <1200000000>, <200000000>, <500000000>;
+       assigned-clocks = <&pmucru CLK_RTC_32K>, <&cru PLL_GPLL>,
+                         <&pmucru PLL_PPLL>, <&cru PLL_VPLL>;
+       assigned-clock-rates = <32768>, <1200000000>,
+                              <200000000>, <500000000>;
 };
 
 &dsi_dphy0 {
index ce7165d7f1a14da78273fdfff2b68a4eea5948cc..102e448bc026a78a3783dd9530c4f12a0aad0e09 100644 (file)
        non-removable;
        pinctrl-names = "default";
        pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>;
-       sd-uhs-sdr104;
+       sd-uhs-sdr50;
        vmmc-supply = <&vcc3v3_sys>;
        vqmmc-supply = <&vcc_1v8>;
        status = "okay";
index 005cde61b4b29b8bf24da8a833fdd9c68a366ad3..a506948b5572b2f093a19d952d7d947ddb298e20 100644 (file)
                        cache-size = <131072>;
                        cache-line-size = <64>;
                        cache-sets = <512>;
+                       cache-level = <2>;
                        next-level-cache = <&l3_cache>;
                };
 
                        cache-size = <131072>;
                        cache-line-size = <64>;
                        cache-sets = <512>;
+                       cache-level = <2>;
                        next-level-cache = <&l3_cache>;
                };
 
                        cache-size = <131072>;
                        cache-line-size = <64>;
                        cache-sets = <512>;
+                       cache-level = <2>;
                        next-level-cache = <&l3_cache>;
                };
 
                        cache-size = <131072>;
                        cache-line-size = <64>;
                        cache-sets = <512>;
+                       cache-level = <2>;
                        next-level-cache = <&l3_cache>;
                };
 
                        cache-size = <524288>;
                        cache-line-size = <64>;
                        cache-sets = <1024>;
+                       cache-level = <2>;
                        next-level-cache = <&l3_cache>;
                };
 
                        cache-size = <524288>;
                        cache-line-size = <64>;
                        cache-sets = <1024>;
+                       cache-level = <2>;
                        next-level-cache = <&l3_cache>;
                };
 
                        cache-size = <524288>;
                        cache-line-size = <64>;
                        cache-sets = <1024>;
+                       cache-level = <2>;
                        next-level-cache = <&l3_cache>;
                };
 
                        cache-size = <524288>;
                        cache-line-size = <64>;
                        cache-sets = <1024>;
+                       cache-level = <2>;
                        next-level-cache = <&l3_cache>;
                };
 
                        cache-size = <3145728>;
                        cache-line-size = <64>;
                        cache-sets = <4096>;
+                       cache-level = <3>;
                };
        };
 
index a1892a8f603236984721b7c2f74e810f1d5bbe21..3dd691c85ca0d81d0c4e6897dcdc91a81cd82581 100644 (file)
@@ -193,6 +193,9 @@ struct kvm_arch {
        /* Interrupt controller */
        struct vgic_dist        vgic;
 
+       /* Timers */
+       struct arch_timer_vm_data timer_data;
+
        /* Mandated version of PSCI */
        u32 psci_version;
 
@@ -573,9 +576,22 @@ struct kvm_vcpu_arch {
        ({                                                      \
                __build_check_flag(v, flagset, f, m);           \
                                                                \
-               v->arch.flagset & (m);                          \
+               READ_ONCE(v->arch.flagset) & (m);               \
        })
 
+/*
+ * Note that the set/clear accessors must be preempt-safe in order to
+ * avoid nesting them with load/put which also manipulate flags...
+ */
+#ifdef __KVM_NVHE_HYPERVISOR__
+/* the nVHE hypervisor is always non-preemptible */
+#define __vcpu_flags_preempt_disable()
+#define __vcpu_flags_preempt_enable()
+#else
+#define __vcpu_flags_preempt_disable() preempt_disable()
+#define __vcpu_flags_preempt_enable()  preempt_enable()
+#endif
+
 #define __vcpu_set_flag(v, flagset, f, m)                      \
        do {                                                    \
                typeof(v->arch.flagset) *fset;                  \
@@ -583,9 +599,11 @@ struct kvm_vcpu_arch {
                __build_check_flag(v, flagset, f, m);           \
                                                                \
                fset = &v->arch.flagset;                        \
+               __vcpu_flags_preempt_disable();                 \
                if (HWEIGHT(m) > 1)                             \
                        *fset &= ~(m);                          \
                *fset |= (f);                                   \
+               __vcpu_flags_preempt_enable();                  \
        } while (0)
 
 #define __vcpu_clear_flag(v, flagset, f, m)                    \
@@ -595,7 +613,9 @@ struct kvm_vcpu_arch {
                __build_check_flag(v, flagset, f, m);           \
                                                                \
                fset = &v->arch.flagset;                        \
+               __vcpu_flags_preempt_disable();                 \
                *fset &= ~(m);                                  \
+               __vcpu_flags_preempt_enable();                  \
        } while (0)
 
 #define vcpu_get_flag(v, ...)  __vcpu_get_flag((v), __VA_ARGS__)
index 5edec2f49ec98c9b040d7698db52a62be0315b48..deff21bfa6800cfc2ceefd36c6e06f01880a1f4f 100644 (file)
@@ -314,36 +314,32 @@ int do_compat_alignment_fixup(unsigned long addr, struct pt_regs *regs)
        int (*handler)(unsigned long addr, u32 instr, struct pt_regs *regs);
        unsigned int type;
        u32 instr = 0;
-       u16 tinstr = 0;
        int isize = 4;
        int thumb2_32b = 0;
-       int fault;
 
        instrptr = instruction_pointer(regs);
 
        if (compat_thumb_mode(regs)) {
                __le16 __user *ptr = (__le16 __user *)(instrptr & ~1);
+               u16 tinstr, tinst2;
 
-               fault = alignment_get_thumb(regs, ptr, &tinstr);
-               if (!fault) {
-                       if (IS_T32(tinstr)) {
-                               /* Thumb-2 32-bit */
-                               u16 tinst2;
-                               fault = alignment_get_thumb(regs, ptr + 1, &tinst2);
-                               instr = ((u32)tinstr << 16) | tinst2;
-                               thumb2_32b = 1;
-                       } else {
-                               isize = 2;
-                               instr = thumb2arm(tinstr);
-                       }
+               if (alignment_get_thumb(regs, ptr, &tinstr))
+                       return 1;
+
+               if (IS_T32(tinstr)) { /* Thumb-2 32-bit */
+                       if (alignment_get_thumb(regs, ptr + 1, &tinst2))
+                               return 1;
+                       instr = ((u32)tinstr << 16) | tinst2;
+                       thumb2_32b = 1;
+               } else {
+                       isize = 2;
+                       instr = thumb2arm(tinstr);
                }
        } else {
-               fault = alignment_get_arm(regs, (__le32 __user *)instrptr, &instr);
+               if (alignment_get_arm(regs, (__le32 __user *)instrptr, &instr))
+                       return 1;
        }
 
-       if (fault)
-               return 1;
-
        switch (CODING_BITS(instr)) {
        case 0x00000000:        /* 3.13.4 load/store instruction extensions */
                if (LDSTHD_I_BIT(instr))
index 28d8a5dca5f129784b158589a3c4c1d231ffd6e9..d731b4655df8eb271c185f732c4ec5a725fb4905 100644 (file)
@@ -66,7 +66,7 @@
        .long   .Lefi_header_end - .L_head              // SizeOfHeaders
        .long   0                                       // CheckSum
        .short  IMAGE_SUBSYSTEM_EFI_APPLICATION         // Subsystem
-       .short  0                                       // DllCharacteristics
+       .short  IMAGE_DLL_CHARACTERISTICS_NX_COMPAT     // DllCharacteristics
        .quad   0                                       // SizeOfStackReserve
        .quad   0                                       // SizeOfStackCommit
        .quad   0                                       // SizeOfHeapReserve
index ca6eadeb7d1a1142c4212dd51495099fae8db2cf..f531da6b362e902a06e9aa76968d9f0ad52e1a23 100644 (file)
@@ -29,7 +29,6 @@ menuconfig KVM
        select KVM_MMIO
        select KVM_GENERIC_DIRTYLOG_READ_PROTECT
        select KVM_XFER_TO_GUEST_WORK
-       select SRCU
        select KVM_VFIO
        select HAVE_KVM_EVENTFD
        select HAVE_KVM_IRQFD
index 00610477ec7bd8da4a7ccbd5a764851145989490..e1af4301b913d87024cc55f1d2aa4cbeb4d3f20c 100644 (file)
@@ -84,14 +84,10 @@ u64 timer_get_cval(struct arch_timer_context *ctxt)
 
 static u64 timer_get_offset(struct arch_timer_context *ctxt)
 {
-       struct kvm_vcpu *vcpu = ctxt->vcpu;
+       if (ctxt->offset.vm_offset)
+               return *ctxt->offset.vm_offset;
 
-       switch(arch_timer_ctx_index(ctxt)) {
-       case TIMER_VTIMER:
-               return __vcpu_sys_reg(vcpu, CNTVOFF_EL2);
-       default:
-               return 0;
-       }
+       return 0;
 }
 
 static void timer_set_ctl(struct arch_timer_context *ctxt, u32 ctl)
@@ -128,15 +124,12 @@ static void timer_set_cval(struct arch_timer_context *ctxt, u64 cval)
 
 static void timer_set_offset(struct arch_timer_context *ctxt, u64 offset)
 {
-       struct kvm_vcpu *vcpu = ctxt->vcpu;
-
-       switch(arch_timer_ctx_index(ctxt)) {
-       case TIMER_VTIMER:
-               __vcpu_sys_reg(vcpu, CNTVOFF_EL2) = offset;
-               break;
-       default:
+       if (!ctxt->offset.vm_offset) {
                WARN(offset, "timer %ld\n", arch_timer_ctx_index(ctxt));
+               return;
        }
+
+       WRITE_ONCE(*ctxt->offset.vm_offset, offset);
 }
 
 u64 kvm_phys_timer_read(void)
@@ -765,25 +758,6 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)
        return 0;
 }
 
-/* Make the updates of cntvoff for all vtimer contexts atomic */
-static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
-{
-       unsigned long i;
-       struct kvm *kvm = vcpu->kvm;
-       struct kvm_vcpu *tmp;
-
-       mutex_lock(&kvm->lock);
-       kvm_for_each_vcpu(i, tmp, kvm)
-               timer_set_offset(vcpu_vtimer(tmp), cntvoff);
-
-       /*
-        * When called from the vcpu create path, the CPU being created is not
-        * included in the loop above, so we just set it here as well.
-        */
-       timer_set_offset(vcpu_vtimer(vcpu), cntvoff);
-       mutex_unlock(&kvm->lock);
-}
-
 void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
 {
        struct arch_timer_cpu *timer = vcpu_timer(vcpu);
@@ -791,10 +765,11 @@ void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
        struct arch_timer_context *ptimer = vcpu_ptimer(vcpu);
 
        vtimer->vcpu = vcpu;
+       vtimer->offset.vm_offset = &vcpu->kvm->arch.timer_data.voffset;
        ptimer->vcpu = vcpu;
 
        /* Synchronize cntvoff across all vtimers of a VM. */
-       update_vtimer_cntvoff(vcpu, kvm_phys_timer_read());
+       timer_set_offset(vtimer, kvm_phys_timer_read());
        timer_set_offset(ptimer, 0);
 
        hrtimer_init(&timer->bg_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_HARD);
@@ -840,7 +815,7 @@ int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value)
                break;
        case KVM_REG_ARM_TIMER_CNT:
                timer = vcpu_vtimer(vcpu);
-               update_vtimer_cntvoff(vcpu, kvm_phys_timer_read() - value);
+               timer_set_offset(timer, kvm_phys_timer_read() - value);
                break;
        case KVM_REG_ARM_TIMER_CVAL:
                timer = vcpu_vtimer(vcpu);
index 3bd732eaf08725509f7f0991cb359d1c1c7672cc..4b2e16e696a807cb6328892082ff71bcad90d1ca 100644 (file)
@@ -220,6 +220,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
        case KVM_CAP_VCPU_ATTRIBUTES:
        case KVM_CAP_PTP_KVM:
        case KVM_CAP_ARM_SYSTEM_SUSPEND:
+       case KVM_CAP_IRQFD_RESAMPLE:
                r = 1;
                break;
        case KVM_CAP_SET_GUEST_DEBUG2:
@@ -1889,9 +1890,33 @@ static int __init do_pkvm_init(u32 hyp_va_bits)
        return ret;
 }
 
+static u64 get_hyp_id_aa64pfr0_el1(void)
+{
+       /*
+        * Track whether the system isn't affected by spectre/meltdown in the
+        * hypervisor's view of id_aa64pfr0_el1, used for protected VMs.
+        * Although this is per-CPU, we make it global for simplicity, e.g., not
+        * to have to worry about vcpu migration.
+        *
+        * Unlike for non-protected VMs, userspace cannot override this for
+        * protected VMs.
+        */
+       u64 val = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
+
+       val &= ~(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2) |
+                ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3));
+
+       val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2),
+                         arm64_get_spectre_v2_state() == SPECTRE_UNAFFECTED);
+       val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3),
+                         arm64_get_meltdown_state() == SPECTRE_UNAFFECTED);
+
+       return val;
+}
+
 static void kvm_hyp_init_symbols(void)
 {
-       kvm_nvhe_sym(id_aa64pfr0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
+       kvm_nvhe_sym(id_aa64pfr0_el1_sys_val) = get_hyp_id_aa64pfr0_el1();
        kvm_nvhe_sym(id_aa64pfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1);
        kvm_nvhe_sym(id_aa64isar0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64ISAR0_EL1);
        kvm_nvhe_sym(id_aa64isar1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64ISAR1_EL1);
index 07edfc7524c942eb2e199578b306bf92b869acbe..37440e1dda9306f7abde4cd24cc32c0d229b81ce 100644 (file)
  * Allow for protected VMs:
  * - Floating-point and Advanced SIMD
  * - Data Independent Timing
+ * - Spectre/Meltdown Mitigation
  */
 #define PVM_ID_AA64PFR0_ALLOW (\
        ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_FP) | \
        ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD) | \
-       ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_DIT) \
+       ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_DIT) | \
+       ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2) | \
+       ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3) \
        )
 
 /*
index 08d2b004f4b73cd61bd80f5b10b6749fd1052459..edd969a1f36b54bfe14b8e9a02a4bc35939f0118 100644 (file)
@@ -85,19 +85,12 @@ static u64 get_restricted_features_unsigned(u64 sys_reg_val,
 
 static u64 get_pvm_id_aa64pfr0(const struct kvm_vcpu *vcpu)
 {
-       const struct kvm *kvm = (const struct kvm *)kern_hyp_va(vcpu->kvm);
        u64 set_mask = 0;
        u64 allow_mask = PVM_ID_AA64PFR0_ALLOW;
 
        set_mask |= get_restricted_features_unsigned(id_aa64pfr0_el1_sys_val,
                PVM_ID_AA64PFR0_RESTRICT_UNSIGNED);
 
-       /* Spectre and Meltdown mitigation in KVM */
-       set_mask |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2),
-                              (u64)kvm->arch.pfr0_csv2);
-       set_mask |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3),
-                              (u64)kvm->arch.pfr0_csv3);
-
        return (id_aa64pfr0_el1_sys_val & allow_mask) | set_mask;
 }
 
index 64c086c02c603167ddffa612f59b43daa2d9830f..c4b4678bc4a4580c6d9fd924cb66656d3c87cd98 100644 (file)
@@ -44,7 +44,7 @@ static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val)
        feature = smccc_get_arg1(vcpu);
        switch (feature) {
        case KVM_PTP_VIRT_COUNTER:
-               cycles = systime_snapshot.cycles - vcpu_read_sys_reg(vcpu, CNTVOFF_EL2);
+               cycles = systime_snapshot.cycles - vcpu->kvm->arch.timer_data.voffset;
                break;
        case KVM_PTP_PHYS_COUNTER:
                cycles = systime_snapshot.cycles;
@@ -397,6 +397,8 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
        u64 val;
        int wa_level;
 
+       if (KVM_REG_SIZE(reg->id) != sizeof(val))
+               return -ENOENT;
        if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id)))
                return -EFAULT;
 
index 7113587222ffe8e1befff0c4d4d7c29e4fde29c5..3b9d4d24c361ae4f903e12c19df146dcb90c9db8 100644 (file)
@@ -666,14 +666,33 @@ static int get_user_mapping_size(struct kvm *kvm, u64 addr)
                                   CONFIG_PGTABLE_LEVELS),
                .mm_ops         = &kvm_user_mm_ops,
        };
+       unsigned long flags;
        kvm_pte_t pte = 0;      /* Keep GCC quiet... */
        u32 level = ~0;
        int ret;
 
+       /*
+        * Disable IRQs so that we hazard against a concurrent
+        * teardown of the userspace page tables (which relies on
+        * IPI-ing threads).
+        */
+       local_irq_save(flags);
        ret = kvm_pgtable_get_leaf(&pgt, addr, &pte, &level);
-       VM_BUG_ON(ret);
-       VM_BUG_ON(level >= KVM_PGTABLE_MAX_LEVELS);
-       VM_BUG_ON(!(pte & PTE_VALID));
+       local_irq_restore(flags);
+
+       if (ret)
+               return ret;
+
+       /*
+        * Not seeing an error, but not updating level? Something went
+        * deeply wrong...
+        */
+       if (WARN_ON(level >= KVM_PGTABLE_MAX_LEVELS))
+               return -EFAULT;
+
+       /* Oops, the userspace PTs are gone... Replay the fault */
+       if (!kvm_pte_valid(pte))
+               return -EAGAIN;
 
        return BIT(ARM64_HW_PGTABLE_LEVEL_SHIFT(level));
 }
@@ -1079,7 +1098,7 @@ static bool fault_supports_stage2_huge_mapping(struct kvm_memory_slot *memslot,
  *
  * Returns the size of the mapping.
  */
-static unsigned long
+static long
 transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot,
                            unsigned long hva, kvm_pfn_t *pfnp,
                            phys_addr_t *ipap)
@@ -1091,8 +1110,15 @@ transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot,
         * sure that the HVA and IPA are sufficiently aligned and that the
         * block map is contained within the memslot.
         */
-       if (fault_supports_stage2_huge_mapping(memslot, hva, PMD_SIZE) &&
-           get_user_mapping_size(kvm, hva) >= PMD_SIZE) {
+       if (fault_supports_stage2_huge_mapping(memslot, hva, PMD_SIZE)) {
+               int sz = get_user_mapping_size(kvm, hva);
+
+               if (sz < 0)
+                       return sz;
+
+               if (sz < PMD_SIZE)
+                       return PAGE_SIZE;
+
                /*
                 * The address we faulted on is backed by a transparent huge
                 * page.  However, because we map the compound huge page and
@@ -1192,7 +1218,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 {
        int ret = 0;
        bool write_fault, writable, force_pte = false;
-       bool exec_fault;
+       bool exec_fault, mte_allowed;
        bool device = false;
        unsigned long mmu_seq;
        struct kvm *kvm = vcpu->kvm;
@@ -1203,7 +1229,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
        kvm_pfn_t pfn;
        bool logging_active = memslot_is_logging(memslot);
        unsigned long fault_level = kvm_vcpu_trap_get_fault_level(vcpu);
-       unsigned long vma_pagesize, fault_granule;
+       long vma_pagesize, fault_granule;
        enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R;
        struct kvm_pgtable *pgt;
 
@@ -1217,6 +1243,20 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
                return -EFAULT;
        }
 
+       /*
+        * Permission faults just need to update the existing leaf entry,
+        * and so normally don't require allocations from the memcache. The
+        * only exception to this is when dirty logging is enabled at runtime
+        * and a write fault needs to collapse a block entry into a table.
+        */
+       if (fault_status != ESR_ELx_FSC_PERM ||
+           (logging_active && write_fault)) {
+               ret = kvm_mmu_topup_memory_cache(memcache,
+                                                kvm_mmu_cache_min_pages(kvm));
+               if (ret)
+                       return ret;
+       }
+
        /*
         * Let's check if we will get back a huge page backed by hugetlbfs, or
         * get block mapping for device MMIO region.
@@ -1269,37 +1309,21 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
                fault_ipa &= ~(vma_pagesize - 1);
 
        gfn = fault_ipa >> PAGE_SHIFT;
-       mmap_read_unlock(current->mm);
+       mte_allowed = kvm_vma_mte_allowed(vma);
 
-       /*
-        * Permission faults just need to update the existing leaf entry,
-        * and so normally don't require allocations from the memcache. The
-        * only exception to this is when dirty logging is enabled at runtime
-        * and a write fault needs to collapse a block entry into a table.
-        */
-       if (fault_status != ESR_ELx_FSC_PERM ||
-           (logging_active && write_fault)) {
-               ret = kvm_mmu_topup_memory_cache(memcache,
-                                                kvm_mmu_cache_min_pages(kvm));
-               if (ret)
-                       return ret;
-       }
+       /* Don't use the VMA after the unlock -- it may have vanished */
+       vma = NULL;
 
-       mmu_seq = vcpu->kvm->mmu_invalidate_seq;
        /*
-        * Ensure the read of mmu_invalidate_seq happens before we call
-        * gfn_to_pfn_prot (which calls get_user_pages), so that we don't risk
-        * the page we just got a reference to gets unmapped before we have a
-        * chance to grab the mmu_lock, which ensure that if the page gets
-        * unmapped afterwards, the call to kvm_unmap_gfn will take it away
-        * from us again properly. This smp_rmb() interacts with the smp_wmb()
-        * in kvm_mmu_notifier_invalidate_<page|range_end>.
+        * Read mmu_invalidate_seq so that KVM can detect if the results of
+        * vma_lookup() or __gfn_to_pfn_memslot() become stale prior to
+        * acquiring kvm->mmu_lock.
         *
-        * Besides, __gfn_to_pfn_memslot() instead of gfn_to_pfn_prot() is
-        * used to avoid unnecessary overhead introduced to locate the memory
-        * slot because it's always fixed even @gfn is adjusted for huge pages.
+        * Rely on mmap_read_unlock() for an implicit smp_rmb(), which pairs
+        * with the smp_wmb() in kvm_mmu_invalidate_end().
         */
-       smp_rmb();
+       mmu_seq = vcpu->kvm->mmu_invalidate_seq;
+       mmap_read_unlock(current->mm);
 
        pfn = __gfn_to_pfn_memslot(memslot, gfn, false, false, NULL,
                                   write_fault, &writable, NULL);
@@ -1350,11 +1374,16 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
                        vma_pagesize = transparent_hugepage_adjust(kvm, memslot,
                                                                   hva, &pfn,
                                                                   &fault_ipa);
+
+               if (vma_pagesize < 0) {
+                       ret = vma_pagesize;
+                       goto out_unlock;
+               }
        }
 
        if (fault_status != ESR_ELx_FSC_PERM && !device && kvm_has_mte(kvm)) {
                /* Check the VMM hasn't introduced a new disallowed VMA */
-               if (kvm_vma_mte_allowed(vma)) {
+               if (mte_allowed) {
                        sanitise_mte_tags(kvm, pfn, vma_pagesize);
                } else {
                        ret = -EFAULT;
index 24908400e190616f317b9e6725b4605c12d1c8a4..5eca0cdd961df8410161e35a154b17a1583b7f9e 100644 (file)
@@ -538,7 +538,8 @@ void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val)
        if (!kvm_pmu_is_3p5(vcpu))
                val &= ~ARMV8_PMU_PMCR_LP;
 
-       __vcpu_sys_reg(vcpu, PMCR_EL0) = val;
+       /* The reset bits don't indicate any state, and shouldn't be saved. */
+       __vcpu_sys_reg(vcpu, PMCR_EL0) = val & ~(ARMV8_PMU_PMCR_C | ARMV8_PMU_PMCR_P);
 
        if (val & ARMV8_PMU_PMCR_E) {
                kvm_pmu_enable_counter_mask(vcpu,
@@ -557,6 +558,7 @@ void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val)
                for_each_set_bit(i, &mask, 32)
                        kvm_pmu_set_pmc_value(kvm_vcpu_idx_to_pmc(vcpu, i), 0, true);
        }
+       kvm_vcpu_pmu_restore_guest(vcpu);
 }
 
 static bool kvm_pmu_counter_is_enabled(struct kvm_pmc *pmc)
index 53749d3a0996d73646290c4ceeb96cc21511446d..34688918c81134b8df65f5612f46321d674b670f 100644 (file)
@@ -794,7 +794,6 @@ static bool access_pmcr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
                if (!kvm_supports_32bit_el0())
                        val |= ARMV8_PMU_PMCR_LC;
                kvm_pmu_handle_pmcr(vcpu, val);
-               kvm_vcpu_pmu_restore_guest(vcpu);
        } else {
                /* PMCR.P & PMCR.C are RAZ */
                val = __vcpu_sys_reg(vcpu, PMCR_EL0)
@@ -856,6 +855,22 @@ static bool pmu_counter_idx_valid(struct kvm_vcpu *vcpu, u64 idx)
        return true;
 }
 
+static int get_pmu_evcntr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
+                         u64 *val)
+{
+       u64 idx;
+
+       if (r->CRn == 9 && r->CRm == 13 && r->Op2 == 0)
+               /* PMCCNTR_EL0 */
+               idx = ARMV8_PMU_CYCLE_IDX;
+       else
+               /* PMEVCNTRn_EL0 */
+               idx = ((r->CRm & 3) << 3) | (r->Op2 & 7);
+
+       *val = kvm_pmu_get_counter_value(vcpu, idx);
+       return 0;
+}
+
 static bool access_pmu_evcntr(struct kvm_vcpu *vcpu,
                              struct sys_reg_params *p,
                              const struct sys_reg_desc *r)
@@ -1072,7 +1087,7 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 /* Macro to expand the PMEVCNTRn_EL0 register */
 #define PMU_PMEVCNTR_EL0(n)                                            \
        { PMU_SYS_REG(SYS_PMEVCNTRn_EL0(n)),                            \
-         .reset = reset_pmevcntr,                                      \
+         .reset = reset_pmevcntr, .get_user = get_pmu_evcntr,          \
          .access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), }
 
 /* Macro to expand the PMEVTYPERn_EL0 register */
@@ -1982,7 +1997,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
        { PMU_SYS_REG(SYS_PMCEID1_EL0),
          .access = access_pmceid, .reset = NULL },
        { PMU_SYS_REG(SYS_PMCCNTR_EL0),
-         .access = access_pmu_evcntr, .reset = reset_unknown, .reg = PMCCNTR_EL0 },
+         .access = access_pmu_evcntr, .reset = reset_unknown,
+         .reg = PMCCNTR_EL0, .get_user = get_pmu_evcntr},
        { PMU_SYS_REG(SYS_PMXEVTYPER_EL0),
          .access = access_pmu_evtyper, .reset = NULL },
        { PMU_SYS_REG(SYS_PMXEVCNTR_EL0),
index a6acb94ea3d63370bec139fa5ff757206e1b1d6e..c2edadb8ec6a30de7788a6b67fdce762711b9475 100644 (file)
 /* DMB */
 #define A64_DMB_ISH aarch64_insn_gen_dmb(AARCH64_INSN_MB_ISH)
 
+/* ADR */
+#define A64_ADR(Rd, offset) \
+       aarch64_insn_gen_adr(0, offset, Rd, AARCH64_INSN_ADR_TYPE_ADR)
+
 #endif /* _BPF_JIT_H */
index 62f805f427b79fd1ce10abdee53f8b1283dc0c1e..b26da8efa616ec133b23b0d4cacd54192ea7c6af 100644 (file)
@@ -1900,7 +1900,8 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
                restore_args(ctx, args_off, nargs);
                /* call original func */
                emit(A64_LDR64I(A64_R(10), A64_SP, retaddr_off), ctx);
-               emit(A64_BLR(A64_R(10)), ctx);
+               emit(A64_ADR(A64_LR, AARCH64_INSN_SIZE * 2), ctx);
+               emit(A64_RET(A64_R(10)), ctx);
                /* store return value */
                emit(A64_STR64I(A64_R(0), A64_SP, retval_off), ctx);
                /* reserve a nop for bpf_tramp_image_put */
index ea75d72dea86966232dd4b04ec4fa4ea419ef784..e487a46d1c37b47f1c9e46b4b341bff60a0f0152 100644 (file)
@@ -72,8 +72,6 @@ struct task_struct;
 /* Prepare to copy thread state - unlazy all lazy status */
 #define prepare_to_copy(tsk)    do { } while (0)
 
-extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
 unsigned long __get_wchan(struct task_struct *p);
 
 #define KSTK_EIP(tsk)          (task_pt_regs(tsk)->pc)
index 21dfa4aa35bb1e8559c9d6b3051f9d520b87c6ec..033f5aead88a4d5e9aab8578290dc1c9dd5cc518 100644 (file)
@@ -853,7 +853,7 @@ valid_phys_addr_range (phys_addr_t phys_addr, unsigned long size)
         * /dev/mem reads and writes use copy_to_user(), which implicitly
         * uses a granule-sized kernel identity mapping.  It's really
         * only safe to do this for regions in kern_memmap.  For more
-        * details, see Documentation/ia64/aliasing.rst.
+        * details, see Documentation/arch/ia64/aliasing.rst.
         */
        attr = kern_mem_attribute(phys_addr, size);
        if (attr & EFI_MEMORY_WB || attr & EFI_MEMORY_UC)
index 2094f324901982e2a225f9a248f75db5fe4230aa..cc4733e9990a74b2a89e47d2bec7a02e67256f7c 100644 (file)
@@ -28,7 +28,7 @@
 #include <asm/native/inst.h>
 
 /*
- * See Documentation/ia64/fsys.rst for details on fsyscalls.
+ * See Documentation/arch/ia64/fsys.rst for details on fsyscalls.
  *
  * On entry to an fsyscall handler:
  *   r10       = 0 (i.e., defaults to "successful syscall return")
index 55fd3eb753ff94fe8491e095a42ca6a1c3a2b5ba..92b81bc91397f79776971c44ab70c06afb2b15c5 100644 (file)
@@ -43,7 +43,7 @@ ioremap (unsigned long phys_addr, unsigned long size)
        /*
         * For things in kern_memmap, we must use the same attribute
         * as the rest of the kernel.  For more details, see
-        * Documentation/ia64/aliasing.rst.
+        * Documentation/arch/ia64/aliasing.rst.
         */
        attr = kern_mem_attribute(phys_addr, size);
        if (attr & EFI_MEMORY_WB)
index 211757e34198a35267160298d6e0b923f5e8d5a0..0a0328e61bef3f10a0787bb3ab0584879ebc4a8c 100644 (file)
@@ -448,7 +448,7 @@ pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma,
                return -ENOSYS;
 
        /*
-        * Avoid attribute aliasing.  See Documentation/ia64/aliasing.rst
+        * Avoid attribute aliasing.  See Documentation/arch/ia64/aliasing.rst
         * for more details.
         */
        if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
index 7fd51257e0ed41b0460e584683805c2ed0f3714f..3ddde336e6a56f8c014fa0d0413379116e0f96f2 100644 (file)
@@ -447,6 +447,22 @@ config ARCH_IOREMAP
          protection support. However, you can enable LoongArch DMW-based
          ioremap() for better performance.
 
+config ARCH_WRITECOMBINE
+       bool "Enable WriteCombine (WUC) for ioremap()"
+       help
+         LoongArch maintains cache coherency in hardware, but when paired
+         with LS7A chipsets the WUC attribute (Weak-ordered UnCached, which
+         is similar to WriteCombine) is out of the scope of cache coherency
+         machanism for PCIe devices (this is a PCIe protocol violation, which
+         may be fixed in newer chipsets).
+
+         This means WUC can only used for write-only memory regions now, so
+         this option is disabled by default, making WUC silently fallback to
+         SUC for ioremap(). You can enable this option if the kernel is ensured
+         to run on hardware without this bug.
+
+         You can override this setting via writecombine=on/off boot parameter.
+
 config ARCH_STRICT_ALIGN
        bool "Enable -mstrict-align to prevent unaligned accesses" if EXPERT
        default y
index 4198753aa1d0f1782a1cb17f2a4280881aa3d0c2..976a810352c601ddb7bd286a2bf732a1b46b5ae0 100644 (file)
@@ -41,8 +41,11 @@ extern void loongarch_suspend_enter(void);
 
 static inline unsigned long acpi_get_wakeup_address(void)
 {
+#ifdef CONFIG_SUSPEND
        extern void loongarch_wakeup_start(void);
        return (unsigned long)loongarch_wakeup_start;
+#endif
+       return 0UL;
 }
 
 #endif /* _ASM_LOONGARCH_ACPI_H */
index 8fb699b4d40afb0ac7ccdeaf30a41e9783e30d26..5c9c03bdf91569154b9a449019e29b46049d5bef 100644 (file)
@@ -71,9 +71,9 @@ extern unsigned long vm_map_base;
 #define _ATYPE32_      int
 #define _ATYPE64_      __s64
 #ifdef CONFIG_64BIT
-#define _CONST64_(x)   x ## L
+#define _CONST64_(x)   x ## UL
 #else
-#define _CONST64_(x)   x ## LL
+#define _CONST64_(x)   x ## ULL
 #endif
 #endif
 
index 0051b526ac6d31307643dc317b6310a72ba53217..c60796869b2b80377d9d6afca9c8705f8d2433e1 100644 (file)
@@ -13,7 +13,6 @@ const char *get_system_type(void);
 extern void init_environ(void);
 extern void memblock_init(void);
 extern void platform_init(void);
-extern void plat_swiotlb_setup(void);
 extern int __init init_numa_memory(void);
 
 struct loongson_board_info {
index b07974218393d1dd6f47fa45f429363134f4d605..f6177f133477670edc2b5f955d379101e8147032 100644 (file)
@@ -42,6 +42,7 @@
 #define cpu_has_fpu            cpu_opt(LOONGARCH_CPU_FPU)
 #define cpu_has_lsx            cpu_opt(LOONGARCH_CPU_LSX)
 #define cpu_has_lasx           cpu_opt(LOONGARCH_CPU_LASX)
+#define cpu_has_crc32          cpu_opt(LOONGARCH_CPU_CRC32)
 #define cpu_has_complex                cpu_opt(LOONGARCH_CPU_COMPLEX)
 #define cpu_has_crypto         cpu_opt(LOONGARCH_CPU_CRYPTO)
 #define cpu_has_lvz            cpu_opt(LOONGARCH_CPU_LVZ)
index c3da91759472841c0f15e71b5f03603077ae6d0d..88773d849e332f08047460efecf97fb429976505 100644 (file)
@@ -78,25 +78,26 @@ enum cpu_type_enum {
 #define CPU_FEATURE_FPU                        3       /* CPU has FPU */
 #define CPU_FEATURE_LSX                        4       /* CPU has LSX (128-bit SIMD) */
 #define CPU_FEATURE_LASX               5       /* CPU has LASX (256-bit SIMD) */
-#define CPU_FEATURE_COMPLEX            6       /* CPU has Complex instructions */
-#define CPU_FEATURE_CRYPTO             7       /* CPU has Crypto instructions */
-#define CPU_FEATURE_LVZ                        8       /* CPU has Virtualization extension */
-#define CPU_FEATURE_LBT_X86            9       /* CPU has X86 Binary Translation */
-#define CPU_FEATURE_LBT_ARM            10      /* CPU has ARM Binary Translation */
-#define CPU_FEATURE_LBT_MIPS           11      /* CPU has MIPS Binary Translation */
-#define CPU_FEATURE_TLB                        12      /* CPU has TLB */
-#define CPU_FEATURE_CSR                        13      /* CPU has CSR */
-#define CPU_FEATURE_WATCH              14      /* CPU has watchpoint registers */
-#define CPU_FEATURE_VINT               15      /* CPU has vectored interrupts */
-#define CPU_FEATURE_CSRIPI             16      /* CPU has CSR-IPI */
-#define CPU_FEATURE_EXTIOI             17      /* CPU has EXT-IOI */
-#define CPU_FEATURE_PREFETCH           18      /* CPU has prefetch instructions */
-#define CPU_FEATURE_PMP                        19      /* CPU has perfermance counter */
-#define CPU_FEATURE_SCALEFREQ          20      /* CPU supports cpufreq scaling */
-#define CPU_FEATURE_FLATMODE           21      /* CPU has flat mode */
-#define CPU_FEATURE_EIODECODE          22      /* CPU has EXTIOI interrupt pin decode mode */
-#define CPU_FEATURE_GUESTID            23      /* CPU has GuestID feature */
-#define CPU_FEATURE_HYPERVISOR         24      /* CPU has hypervisor (running in VM) */
+#define CPU_FEATURE_CRC32              6       /* CPU has CRC32 instructions */
+#define CPU_FEATURE_COMPLEX            7       /* CPU has Complex instructions */
+#define CPU_FEATURE_CRYPTO             8       /* CPU has Crypto instructions */
+#define CPU_FEATURE_LVZ                        9       /* CPU has Virtualization extension */
+#define CPU_FEATURE_LBT_X86            10      /* CPU has X86 Binary Translation */
+#define CPU_FEATURE_LBT_ARM            11      /* CPU has ARM Binary Translation */
+#define CPU_FEATURE_LBT_MIPS           12      /* CPU has MIPS Binary Translation */
+#define CPU_FEATURE_TLB                        13      /* CPU has TLB */
+#define CPU_FEATURE_CSR                        14      /* CPU has CSR */
+#define CPU_FEATURE_WATCH              15      /* CPU has watchpoint registers */
+#define CPU_FEATURE_VINT               16      /* CPU has vectored interrupts */
+#define CPU_FEATURE_CSRIPI             17      /* CPU has CSR-IPI */
+#define CPU_FEATURE_EXTIOI             18      /* CPU has EXT-IOI */
+#define CPU_FEATURE_PREFETCH           19      /* CPU has prefetch instructions */
+#define CPU_FEATURE_PMP                        20      /* CPU has perfermance counter */
+#define CPU_FEATURE_SCALEFREQ          21      /* CPU supports cpufreq scaling */
+#define CPU_FEATURE_FLATMODE           22      /* CPU has flat mode */
+#define CPU_FEATURE_EIODECODE          23      /* CPU has EXTIOI interrupt pin decode mode */
+#define CPU_FEATURE_GUESTID            24      /* CPU has GuestID feature */
+#define CPU_FEATURE_HYPERVISOR         25      /* CPU has hypervisor (running in VM) */
 
 #define LOONGARCH_CPU_CPUCFG           BIT_ULL(CPU_FEATURE_CPUCFG)
 #define LOONGARCH_CPU_LAM              BIT_ULL(CPU_FEATURE_LAM)
@@ -104,6 +105,7 @@ enum cpu_type_enum {
 #define LOONGARCH_CPU_FPU              BIT_ULL(CPU_FEATURE_FPU)
 #define LOONGARCH_CPU_LSX              BIT_ULL(CPU_FEATURE_LSX)
 #define LOONGARCH_CPU_LASX             BIT_ULL(CPU_FEATURE_LASX)
+#define LOONGARCH_CPU_CRC32            BIT_ULL(CPU_FEATURE_CRC32)
 #define LOONGARCH_CPU_COMPLEX          BIT_ULL(CPU_FEATURE_COMPLEX)
 #define LOONGARCH_CPU_CRYPTO           BIT_ULL(CPU_FEATURE_CRYPTO)
 #define LOONGARCH_CPU_LVZ              BIT_ULL(CPU_FEATURE_LVZ)
index 402a7d9e3a53eafed41c4170de5627f673d142f4..545e2708fbf7042f6a61f29c1423be1f11de7a7e 100644 (file)
@@ -54,8 +54,10 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
  * @offset:    bus address of the memory
  * @size:      size of the resource to map
  */
+extern pgprot_t pgprot_wc;
+
 #define ioremap_wc(offset, size)       \
-       ioremap_prot((offset), (size), pgprot_val(PAGE_KERNEL_WUC))
+       ioremap_prot((offset), (size), pgprot_val(pgprot_wc))
 
 #define ioremap_cache(offset, size)    \
        ioremap_prot((offset), (size), pgprot_val(PAGE_KERNEL))
index 65b7dcdea16d0f4f59bfed5cbee2444767327a6c..83da5d29e2d17b5c4e90d70d3a18575f6707eb60 100644 (file)
@@ -117,7 +117,7 @@ static inline u32 read_cpucfg(u32 reg)
 #define  CPUCFG1_EP                    BIT(22)
 #define  CPUCFG1_RPLV                  BIT(23)
 #define  CPUCFG1_HUGEPG                        BIT(24)
-#define  CPUCFG1_IOCSRBRD              BIT(25)
+#define  CPUCFG1_CRC32                 BIT(25)
 #define  CPUCFG1_MSGINT                        BIT(26)
 
 #define LOONGARCH_CPUCFG2              0x2
@@ -423,9 +423,9 @@ static __always_inline void iocsr_write64(u64 val, u32 reg)
 #define  CSR_ASID_ASID_WIDTH           10
 #define  CSR_ASID_ASID                 (_ULCAST_(0x3ff) << CSR_ASID_ASID_SHIFT)
 
-#define LOONGARCH_CSR_PGDL             0x19    /* Page table base address when VA[47] = 0 */
+#define LOONGARCH_CSR_PGDL             0x19    /* Page table base address when VA[VALEN-1] = 0 */
 
-#define LOONGARCH_CSR_PGDH             0x1a    /* Page table base address when VA[47] = 1 */
+#define LOONGARCH_CSR_PGDH             0x1a    /* Page table base address when VA[VALEN-1] = 1 */
 
 #define LOONGARCH_CSR_PGD              0x1b    /* Page table base */
 
index 438f09d4ccf41d6032f07b7ebcb3799ff7bf4c22..88554f92e0103de153ece66aa2e8b7d1857db1c8 100644 (file)
@@ -2,8 +2,8 @@
 /* Copyright (C) 2020-2022 Loongson Technology Corporation Limited */
 SECTIONS {
        . = ALIGN(4);
-       .got : { BYTE(0) }
-       .plt : { BYTE(0) }
-       .plt.idx : { BYTE(0) }
-       .ftrace_trampoline : { BYTE(0) }
+       .got : { BYTE(0) }
+       .plt : { BYTE(0) }
+       .plt.idx : { BYTE(0) }
+       .ftrace_trampoline : { BYTE(0) }
 }
index cc48ed262021244bcbcc7e0f98b63d8dc7e4b9de..82d811b5c6e972fe06771948b4f8b5d0a2c2791b 100644 (file)
@@ -47,11 +47,12 @@ struct user_fp_state {
 };
 
 struct user_watch_state {
-       uint16_t dbg_info;
+       uint64_t dbg_info;
        struct {
                uint64_t    addr;
                uint64_t    mask;
                uint32_t    ctrl;
+               uint32_t    pad;
        } dbg_regs[8];
 };
 
index 3a3fce2d784611e1118e6a6d5dab1b509501dd9c..5adf0f736c6d74b132b9c24d6a154b12db77d309 100644 (file)
@@ -60,7 +60,7 @@ static inline void set_elf_platform(int cpu, const char *plat)
 
 /* MAP BASE */
 unsigned long vm_map_base;
-EXPORT_SYMBOL_GPL(vm_map_base);
+EXPORT_SYMBOL(vm_map_base);
 
 static void cpu_probe_addrbits(struct cpuinfo_loongarch *c)
 {
@@ -94,13 +94,18 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
        c->options = LOONGARCH_CPU_CPUCFG | LOONGARCH_CPU_CSR |
                     LOONGARCH_CPU_TLB | LOONGARCH_CPU_VINT | LOONGARCH_CPU_WATCH;
 
-       elf_hwcap = HWCAP_LOONGARCH_CPUCFG | HWCAP_LOONGARCH_CRC32;
+       elf_hwcap = HWCAP_LOONGARCH_CPUCFG;
 
        config = read_cpucfg(LOONGARCH_CPUCFG1);
        if (config & CPUCFG1_UAL) {
                c->options |= LOONGARCH_CPU_UAL;
                elf_hwcap |= HWCAP_LOONGARCH_UAL;
        }
+       if (config & CPUCFG1_CRC32) {
+               c->options |= LOONGARCH_CPU_CRC32;
+               elf_hwcap |= HWCAP_LOONGARCH_CRC32;
+       }
+
 
        config = read_cpucfg(LOONGARCH_CPUCFG2);
        if (config & CPUCFG2_LAM) {
index 5c67cc4fd56d5f68301d3738ea312632bf2a3746..0d82907b5404c31d0965df34a4220157e99d5e8e 100644 (file)
@@ -76,6 +76,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
        if (cpu_has_fpu)        seq_printf(m, " fpu");
        if (cpu_has_lsx)        seq_printf(m, " lsx");
        if (cpu_has_lasx)       seq_printf(m, " lasx");
+       if (cpu_has_crc32)      seq_printf(m, " crc32");
        if (cpu_has_complex)    seq_printf(m, " complex");
        if (cpu_has_crypto)     seq_printf(m, " crypto");
        if (cpu_has_lvz)        seq_printf(m, " lvz");
index 06bceae7d1040c6cfb38fe07acea7f1f765eb1a0..5fcffb45236764ee75fce64c2508003b5773bffc 100644 (file)
@@ -391,10 +391,10 @@ static int ptrace_hbp_fill_attr_ctrl(unsigned int note_type,
        return 0;
 }
 
-static int ptrace_hbp_get_resource_info(unsigned int note_type, u16 *info)
+static int ptrace_hbp_get_resource_info(unsigned int note_type, u64 *info)
 {
        u8 num;
-       u16 reg = 0;
+       u64 reg = 0;
 
        switch (note_type) {
        case NT_LOONGARCH_HW_BREAK:
@@ -524,15 +524,16 @@ static int ptrace_hbp_set_addr(unsigned int note_type,
        return modify_user_hw_breakpoint(bp, &attr);
 }
 
-#define PTRACE_HBP_CTRL_SZ     sizeof(u32)
 #define PTRACE_HBP_ADDR_SZ     sizeof(u64)
 #define PTRACE_HBP_MASK_SZ     sizeof(u64)
+#define PTRACE_HBP_CTRL_SZ     sizeof(u32)
+#define PTRACE_HBP_PAD_SZ      sizeof(u32)
 
 static int hw_break_get(struct task_struct *target,
                        const struct user_regset *regset,
                        struct membuf to)
 {
-       u16 info;
+       u64 info;
        u32 ctrl;
        u64 addr, mask;
        int ret, idx = 0;
@@ -545,7 +546,7 @@ static int hw_break_get(struct task_struct *target,
 
        membuf_write(&to, &info, sizeof(info));
 
-       /* (address, ctrl) registers */
+       /* (address, mask, ctrl) registers */
        while (to.left) {
                ret = ptrace_hbp_get_addr(note_type, target, idx, &addr);
                if (ret)
@@ -562,6 +563,7 @@ static int hw_break_get(struct task_struct *target,
                membuf_store(&to, addr);
                membuf_store(&to, mask);
                membuf_store(&to, ctrl);
+               membuf_zero(&to, sizeof(u32));
                idx++;
        }
 
@@ -582,7 +584,7 @@ static int hw_break_set(struct task_struct *target,
        offset = offsetof(struct user_watch_state, dbg_regs);
        user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, offset);
 
-       /* (address, ctrl) registers */
+       /* (address, mask, ctrl) registers */
        limit = regset->n * regset->size;
        while (count && offset < limit) {
                if (count < PTRACE_HBP_ADDR_SZ)
@@ -602,7 +604,7 @@ static int hw_break_set(struct task_struct *target,
                        break;
 
                ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &mask,
-                                        offset, offset + PTRACE_HBP_ADDR_SZ);
+                                        offset, offset + PTRACE_HBP_MASK_SZ);
                if (ret)
                        return ret;
 
@@ -611,8 +613,8 @@ static int hw_break_set(struct task_struct *target,
                        return ret;
                offset += PTRACE_HBP_MASK_SZ;
 
-               ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &mask,
-                                        offset, offset + PTRACE_HBP_MASK_SZ);
+               ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl,
+                                        offset, offset + PTRACE_HBP_CTRL_SZ);
                if (ret)
                        return ret;
 
@@ -620,6 +622,11 @@ static int hw_break_set(struct task_struct *target,
                if (ret)
                        return ret;
                offset += PTRACE_HBP_CTRL_SZ;
+
+               user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+                                         offset, offset + PTRACE_HBP_PAD_SZ);
+               offset += PTRACE_HBP_PAD_SZ;
+
                idx++;
        }
 
index bae84ccf6d3671c29e1849ec1542693d1ef5a06f..4444b13418f0e0621d56d339ba4302c4d0ec2f29 100644 (file)
@@ -160,6 +160,27 @@ static void __init smbios_parse(void)
        dmi_walk(find_tokens, NULL);
 }
 
+#ifdef CONFIG_ARCH_WRITECOMBINE
+pgprot_t pgprot_wc = PAGE_KERNEL_WUC;
+#else
+pgprot_t pgprot_wc = PAGE_KERNEL_SUC;
+#endif
+
+EXPORT_SYMBOL(pgprot_wc);
+
+static int __init setup_writecombine(char *p)
+{
+       if (!strcmp(p, "on"))
+               pgprot_wc = PAGE_KERNEL_WUC;
+       else if (!strcmp(p, "off"))
+               pgprot_wc = PAGE_KERNEL_SUC;
+       else
+               pr_warn("Unknown writecombine setting \"%s\".\n", p);
+
+       return 0;
+}
+early_param("writecombine", setup_writecombine);
+
 static int usermem __initdata;
 
 static int __init early_parse_mem(char *p)
@@ -368,8 +389,8 @@ static void __init arch_mem_init(char **cmdline_p)
        /*
         * In order to reduce the possibility of kernel panic when failed to
         * get IO TLB memory under CONFIG_SWIOTLB, it is better to allocate
-        * low memory as small as possible before plat_swiotlb_setup(), so
-        * make sparse_init() using top-down allocation.
+        * low memory as small as possible before swiotlb_init(), so make
+        * sparse_init() using top-down allocation.
         */
        memblock_set_bottom_up(false);
        sparse_init();
index 3a690f96f00c1a67edccefd66c8f46f006dd4f4e..2463d2fea21f5f4bc9dd762fd5b1ed3c77c0fc40 100644 (file)
@@ -30,7 +30,7 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
 
        regs->regs[1] = 0;
        for (unwind_start(&state, task, regs);
-             !unwind_done(&state); unwind_next_frame(&state)) {
+            !unwind_done(&state) && !unwind_error(&state); unwind_next_frame(&state)) {
                addr = unwind_get_return_address(&state);
                if (!addr || !consume_entry(cookie, addr))
                        break;
index a463d6961344c0899aacd72a8951b9cc5d18ea83..ba324ba76fa15605d9ada6c26101ce78aa108df1 100644 (file)
@@ -28,5 +28,6 @@ bool default_next_frame(struct unwind_state *state)
 
        } while (!get_stack_info(state->sp, state->task, info));
 
+       state->error = true;
        return false;
 }
index 9095fde8e55d5c57177c83ab0548ab888c348f16..55afc27320e12a1c52fd98445ef32f383f1d2bf1 100644 (file)
@@ -211,7 +211,7 @@ static bool next_frame(struct unwind_state *state)
                        pc = regs->csr_era;
 
                        if (user_mode(regs) || !__kernel_text_address(pc))
-                               return false;
+                               goto out;
 
                        state->first = true;
                        state->pc = pc;
@@ -226,6 +226,8 @@ static bool next_frame(struct unwind_state *state)
 
        } while (!get_stack_info(state->sp, state->task, info));
 
+out:
+       state->error = true;
        return false;
 }
 
index e018aed345866010c0822c82bfc0c5459ef2e41e..3b7d8129570b83ac87455e8bb1c2f7c8a0ee35b1 100644 (file)
@@ -41,7 +41,7 @@
  * don't have to care about aliases on other CPUs.
  */
 unsigned long empty_zero_page, zero_page_mask;
-EXPORT_SYMBOL_GPL(empty_zero_page);
+EXPORT_SYMBOL(empty_zero_page);
 EXPORT_SYMBOL(zero_page_mask);
 
 void setup_zero_pages(void)
@@ -270,7 +270,7 @@ pud_t invalid_pud_table[PTRS_PER_PUD] __page_aligned_bss;
 #endif
 #ifndef __PAGETABLE_PMD_FOLDED
 pmd_t invalid_pmd_table[PTRS_PER_PMD] __page_aligned_bss;
-EXPORT_SYMBOL_GPL(invalid_pmd_table);
+EXPORT_SYMBOL(invalid_pmd_table);
 #endif
 pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned_bss;
 EXPORT_SYMBOL(invalid_pte_table);
index 288003a9f0cae478a058102a6413e15a07585b29..d586df48ecc6432b94d034fcdc7641c9d1580794 100644 (file)
@@ -1022,6 +1022,10 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
                emit_atomic(insn, ctx);
                break;
 
+       /* Speculation barrier */
+       case BPF_ST | BPF_NOSPEC:
+               break;
+
        default:
                pr_err("bpf_jit: unknown opcode %02x\n", code);
                return -EINVAL;
index 90da899c06a194989ee4c0044f7cc908131090e7..e2fc3b4e31f0019164f57de05c05324cc2bb391d 100644 (file)
@@ -80,6 +80,10 @@ SYM_INNER_LABEL(loongarch_wakeup_start, SYM_L_GLOBAL)
 
        JUMP_VIRT_ADDR  t0, t1
 
+       /* Enable PG */
+       li.w            t0, 0xb0                # PLV=0, IE=0, PG=1
+       csrwr           t0, LOONGARCH_CSR_CRMD
+
        la.pcrel        t0, acpi_saved_sp
        ld.d            sp, t0, 0
        SETUP_WAKEUP
index e2f961208f18bec599c6712bacd7393182a6e9f6..28eebabfd34bc33bc16d9fe26432451ac1830f8a 100644 (file)
@@ -11,7 +11,7 @@ config AMIGA
        help
          This option enables support for the Amiga series of computers. If
          you plan to use this kernel on an Amiga, say Y here and browse the
-         material available in <file:Documentation/m68k>; otherwise say N.
+         material available in <file:Documentation/arch/m68k>; otherwise say N.
 
 config ATARI
        bool "Atari support"
@@ -23,7 +23,7 @@ config ATARI
          This option enables support for the 68000-based Atari series of
          computers (including the TT, Falcon and Medusa). If you plan to use
          this kernel on an Atari, say Y here and browse the material
-         available in <file:Documentation/m68k>; otherwise say N.
+         available in <file:Documentation/arch/m68k>; otherwise say N.
 
 config ATARI_KBD_CORE
        bool
index 33788668cbdbfc3ab12862e5f3b8874b15af1ea7..3779e7855bd756be930077c659d401e74df7af05 100644 (file)
@@ -5,6 +5,8 @@
 #include <asm/bmips.h>
 #include <asm/io.h>
 
+bool bmips_rac_flush_disable;
+
 void arch_sync_dma_for_cpu_all(void)
 {
        void __iomem *cbr = BMIPS_GET_CBR();
@@ -15,6 +17,9 @@ void arch_sync_dma_for_cpu_all(void)
            boot_cpu_type() != CPU_BMIPS4380)
                return;
 
+       if (unlikely(bmips_rac_flush_disable))
+               return;
+
        /* Flush stale data out of the readahead cache */
        cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG);
        __raw_writel(cfg | 0x100, cbr + BMIPS_RAC_CONFIG);
index e95b3f78e7cd414899b1445cfb315abebc6d4d74..549a6392a3d2d3c6c6f890cb9a59b7ebb03d4922 100644 (file)
@@ -35,6 +35,8 @@
 #define REG_BCM6328_OTP                ((void __iomem *)CKSEG1ADDR(0x1000062c))
 #define BCM6328_TP1_DISABLED   BIT(9)
 
+extern bool bmips_rac_flush_disable;
+
 static const unsigned long kbase = VMLINUX_LOAD_ADDRESS & 0xfff00000;
 
 struct bmips_quirk {
@@ -104,6 +106,12 @@ static void bcm6358_quirks(void)
         * disable SMP for now
         */
        bmips_smp_enabled = 0;
+
+       /*
+        * RAC flush causes kernel panics on BCM6358 when booting from TP1
+        * because the bootloader is not initializing it properly.
+        */
+       bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31));
 }
 
 static void bcm6368_quirks(void)
index 89a1511d2ee47126ca5121b1cfccd6d749ab4afb..edf9634aa8ee1d1b904252c66895ef5dbce7ec2c 100644 (file)
@@ -284,6 +284,7 @@ CONFIG_IXGB=m
 CONFIG_SKGE=m
 CONFIG_SKY2=m
 CONFIG_MYRI10GE=m
+CONFIG_FEALNX=m
 CONFIG_NATSEMI=m
 CONFIG_NS83820=m
 CONFIG_S2IO=m
index 52cbde60edf5b1b780b0ba30666aca3df4196b96..9ff55cb80a6457bba4c5a103c66372523380aff6 100644 (file)
@@ -15,6 +15,8 @@
 #define EMITS_PT_NOTE
 #endif
 
+#define RUNTIME_DISCARD_EXIT
+
 #include <asm-generic/vmlinux.lds.h>
 
 #undef mips
index 29e51649203bb5aa8f377f4b4d4b33da6bd62bd9..a8cdba75f98dde949c9cd86ef073027cc49bfad3 100644 (file)
@@ -26,7 +26,6 @@ config KVM
        select HAVE_KVM_VCPU_ASYNC_IOCTL
        select KVM_MMIO
        select MMU_NOTIFIER
-       select SRCU
        select INTERVAL_TREE
        select KVM_GENERIC_HARDWARE_ENABLING
        help
index bcc0e9915ebdab3d30a316525f5b1956c21daa1c..5abac9893b32b54e22d5b99ef9461a8b4723146d 100644 (file)
@@ -96,9 +96,6 @@ static inline struct thread_info *current_thread_info(void)
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK         0x0000FFFE
 
-/* work to do on any return to u-space */
-# define _TIF_ALLWORK_MASK     0x0000FFFF
-
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_NIOS2_THREAD_INFO_H */
index 73f8c998c64dfefa6859cd5bcda8ddafcdc51f38..d4f5f159d6f236b02c010013e61cdc1e1e915080 100644 (file)
@@ -10,7 +10,6 @@
 
 / {
        model = "fsl,T1040RDB-REV-A";
-       compatible = "fsl,T1040RDB-REV-A";
 };
 
 &seville_port0 {
index b6733e7e65805e47fc52d345040dd190ca0ea2e7..dd3aab81e9dea4c43c6982b323daee702461f1f9 100644 (file)
 };
 
 &seville_port8 {
-       ethernet = <&enet0>;
+       status = "okay";
+};
+
+&seville_port9 {
        status = "okay";
 };
index f58eb820eb5ec748eee5bf482ec5a9c6661a72c4..ad0ab33336b88c0e49d27e5d0a76ece3d5d73f12 100644 (file)
                        seville_port8: port@8 {
                                reg = <8>;
                                phy-mode = "internal";
+                               ethernet = <&enet0>;
                                status = "disabled";
 
                                fixed-link {
                        seville_port9: port@9 {
                                reg = <9>;
                                phy-mode = "internal";
+                               ethernet = <&enet1>;
                                status = "disabled";
 
                                fixed-link {
index 1102582779599bf11e224a3d95f58f8a4ffc978a..f73c98be56c8fa4b2c2cbe202b45f60692779d1e 100644 (file)
@@ -461,6 +461,7 @@ CONFIG_MV643XX_ETH=m
 CONFIG_SKGE=m
 CONFIG_SKY2=m
 CONFIG_MYRI10GE=m
+CONFIG_FEALNX=m
 CONFIG_NATSEMI=m
 CONFIG_NS83820=m
 CONFIG_PCMCIA_AXNET=m
index 2bbc0fcce04a36004ed31c4a5ce4f7ec92d2b84f..5e26c7f2c25ab29a528b3c70ddfe7926bc5a636f 100644 (file)
@@ -148,6 +148,11 @@ static inline void flush_tlb_fix_spurious_fault(struct vm_area_struct *vma,
         */
 }
 
+static inline bool __pte_protnone(unsigned long pte)
+{
+       return (pte & (pgprot_val(PAGE_NONE) | _PAGE_RWX)) == pgprot_val(PAGE_NONE);
+}
+
 static inline bool __pte_flags_need_flush(unsigned long oldval,
                                          unsigned long newval)
 {
@@ -164,8 +169,8 @@ static inline bool __pte_flags_need_flush(unsigned long oldval,
        /*
         * We do not expect kernel mappings or non-PTEs or not-present PTEs.
         */
-       VM_WARN_ON_ONCE(oldval & _PAGE_PRIVILEGED);
-       VM_WARN_ON_ONCE(newval & _PAGE_PRIVILEGED);
+       VM_WARN_ON_ONCE(!__pte_protnone(oldval) && oldval & _PAGE_PRIVILEGED);
+       VM_WARN_ON_ONCE(!__pte_protnone(newval) && newval & _PAGE_PRIVILEGED);
        VM_WARN_ON_ONCE(!(oldval & _PAGE_PTE));
        VM_WARN_ON_ONCE(!(newval & _PAGE_PTE));
        VM_WARN_ON_ONCE(!(oldval & _PAGE_PRESENT));
index 92a968202ba7ccf9c6d8b2da54fea778186e9cf5..365d2720097cb0724ced2c978de21e3f919f5b69 100644 (file)
@@ -2,7 +2,7 @@
 #ifndef __ASM_KASAN_H
 #define __ASM_KASAN_H
 
-#ifdef CONFIG_KASAN
+#if defined(CONFIG_KASAN) && !defined(CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX)
 #define _GLOBAL_KASAN(fn)      _GLOBAL(__##fn)
 #define _GLOBAL_TOC_KASAN(fn)  _GLOBAL_TOC(__##fn)
 #define EXPORT_SYMBOL_KASAN(fn)        EXPORT_SYMBOL(__##fn)
index 2aa0e31e68844336a0fd37ac81bd2b97204b454f..60ba22770f51c867d50c3bbba32e192292c0b916 100644 (file)
@@ -30,11 +30,17 @@ extern int memcmp(const void *,const void *,__kernel_size_t);
 extern void * memchr(const void *,int,__kernel_size_t);
 void memcpy_flushcache(void *dest, const void *src, size_t size);
 
+#ifdef CONFIG_KASAN
+/* __mem variants are used by KASAN to implement instrumented meminstrinsics. */
+#ifdef CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
+#define __memset memset
+#define __memcpy memcpy
+#define __memmove memmove
+#else /* CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */
 void *__memset(void *s, int c, __kernel_size_t count);
 void *__memcpy(void *to, const void *from, __kernel_size_t n);
 void *__memmove(void *to, const void *from, __kernel_size_t n);
-
-#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
+#ifndef __SANITIZE_ADDRESS__
 /*
  * For files that are not instrumented (e.g. mm/slub.c) we
  * should use not instrumented version of mem* functions.
@@ -46,8 +52,9 @@ void *__memmove(void *to, const void *from, __kernel_size_t n);
 #ifndef __NO_FORTIFY
 #define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */
 #endif
-
-#endif
+#endif /* !__SANITIZE_ADDRESS__ */
+#endif /* CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */
+#endif /* CONFIG_KASAN */
 
 #ifdef CONFIG_PPC64
 #ifndef CONFIG_KASAN
index 5a319863f2890f4a6aca7ee9b25948fe659f3eea..69623b9045d55678ef43310c4090a1caf14fe840 100644 (file)
 # If you really need to reference something from prom_init.o add
 # it to the list below:
 
-grep "^CONFIG_KASAN=y$" ${KCONFIG_CONFIG} >/dev/null
-if [ $? -eq 0 ]
+has_renamed_memintrinsics()
+{
+       grep -q "^CONFIG_KASAN=y$" ${KCONFIG_CONFIG} && \
+               ! grep -q "^CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX=y" ${KCONFIG_CONFIG}
+}
+
+if has_renamed_memintrinsics
 then
        MEM_FUNCS="__memcpy __memset"
 else
index 2087a785f05f1f188c828e1121de5f1fb3faac4d..5fff0d04b23f7a7161de470e504378807a887568 100644 (file)
@@ -290,6 +290,9 @@ static int gpr_set(struct task_struct *target, const struct user_regset *regset,
 static int ppr_get(struct task_struct *target, const struct user_regset *regset,
                   struct membuf to)
 {
+       if (!target->thread.regs)
+               return -EINVAL;
+
        return membuf_write(&to, &target->thread.regs->ppr, sizeof(u64));
 }
 
@@ -297,6 +300,9 @@ static int ppr_set(struct task_struct *target, const struct user_regset *regset,
                   unsigned int pos, unsigned int count, const void *kbuf,
                   const void __user *ubuf)
 {
+       if (!target->thread.regs)
+               return -EINVAL;
+
        return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
                                  &target->thread.regs->ppr, 0, sizeof(u64));
 }
index a9f57dad6d916436f1eb754d9559ff59855193d6..902611954200df90c43e2b2516ce242006dba09c 100644 (file)
@@ -22,7 +22,6 @@ config KVM
        select PREEMPT_NOTIFIERS
        select HAVE_KVM_EVENTFD
        select HAVE_KVM_VCPU_ASYNC_IOCTL
-       select SRCU
        select KVM_VFIO
        select IRQ_BYPASS_MANAGER
        select HAVE_KVM_IRQ_BYPASS
index 4c5405fc55387028e33e26f83fac20c99a2e5316..d23e25e8432d351dcd33e534f0d1b1765b7317aa 100644 (file)
@@ -576,6 +576,12 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
                break;
 #endif
 
+#ifdef CONFIG_HAVE_KVM_IRQFD
+       case KVM_CAP_IRQFD_RESAMPLE:
+               r = !xive_enabled();
+               break;
+#endif
+
        case KVM_CAP_PPC_ALLOC_HTAB:
                r = hv_enabled;
                break;
index 2bef19cc1b98c659b38109ba47ea2811d0976b66..af46aa88422bf950cd1868dd4715c6adf2f6c5bb 100644 (file)
@@ -271,11 +271,16 @@ static bool access_error(bool is_write, bool is_exec, struct vm_area_struct *vma
        }
 
        /*
-        * Check for a read fault.  This could be caused by a read on an
-        * inaccessible page (i.e. PROT_NONE), or a Radix MMU execute-only page.
+        * VM_READ, VM_WRITE and VM_EXEC all imply read permissions, as
+        * defined in protection_map[].  Read faults can only be caused by
+        * a PROT_NONE mapping, or with a PROT_EXEC-only mapping on Radix.
         */
-       if (unlikely(!(vma->vm_flags & VM_READ)))
+       if (unlikely(!vma_is_accessible(vma)))
                return true;
+
+       if (unlikely(radix_enabled() && ((vma->vm_flags & VM_ACCESS_FLAGS) == VM_EXEC)))
+               return true;
+
        /*
         * We should ideally do the vma pkey access check here. But in the
         * fault path, handle_mm_fault() also does the same check. To avoid
index b44ce71917d75a9668d42e0fe6fe328e653a2790..16cfe56be05bb28723a065daf1dbf2de91d29aac 100644 (file)
@@ -366,6 +366,7 @@ void update_numa_distance(struct device_node *node)
        WARN(numa_distance_table[nid][nid] == -1,
             "NUMA distance details for node %d not provided\n", nid);
 }
+EXPORT_SYMBOL_GPL(update_numa_distance);
 
 /*
  * ibm,numa-lookup-index-table= {N, domainid1, domainid2, ..... domainidN}
index b481c5c8bae11c8e556b932ac505f8597ecb79ac..21b22bf16ce66b8e374f731d2f377104eb0071fc 100644 (file)
@@ -7,6 +7,7 @@ config PPC_PSERIES
        select OF_DYNAMIC
        select FORCE_PCI
        select PCI_MSI
+       select GENERIC_ALLOCATOR
        select PPC_XICS
        select PPC_XIVE_SPAPR
        select PPC_ICP_NATIVE
index 2f8385523a1320047925af07a7219618a48c60d5..1a53e048ceb768f175237361018d6177092b4220 100644 (file)
@@ -1428,6 +1428,13 @@ static int papr_scm_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
+       /*
+        * open firmware platform device create won't update the NUMA 
+        * distance table. For PAPR SCM devices we use numa_map_to_online_node()
+        * to find the nearest online NUMA node and that requires correct
+        * distance table information.
+        */
+       update_numa_distance(dn);
 
        p = kzalloc(sizeof(*p), GFP_KERNEL);
        if (!p)
index 5591123128107c461e8143cc42b97d33d1c58e1c..513180467562b60e78956813027b90894b05ffe6 100644 (file)
@@ -856,6 +856,13 @@ int pseries_vas_dlpar_cpu(void)
 {
        int new_nr_creds, rc;
 
+       /*
+        * NX-GZIP is not enabled. Nothing to do for DLPAR event
+        */
+       if (!copypaste_feat)
+               return 0;
+
+
        rc = h_query_vas_capabilities(H_QUERY_VAS_CAPABILITIES,
                                      vascaps[VAS_GZIP_DEF_FEAT_TYPE].feat,
                                      (u64)virt_to_phys(&hv_cop_caps));
@@ -1012,6 +1019,7 @@ static int __init pseries_vas_init(void)
         * Linux supports user space COPY/PASTE only with Radix
         */
        if (!radix_enabled()) {
+               copypaste_feat = false;
                pr_err("API is supported only with radix page tables\n");
                return -ENOTSUPP;
        }
index 73c620c2a3a166b2b5c6b4d460847b01edf27541..e753a6bd48881026339abd56fe92c3944a0eb124 100644 (file)
@@ -1275,7 +1275,7 @@ static int xmon_batch_next_cpu(void)
        while (!cpumask_empty(&xmon_batch_cpus)) {
                cpu = cpumask_next_wrap(smp_processor_id(), &xmon_batch_cpus,
                                        xmon_batch_start_cpu, true);
-               if (cpu == nr_cpumask_bits)
+               if (cpu >= nr_cpu_ids)
                        break;
                if (xmon_batch_start_cpu == -1)
                        xmon_batch_start_cpu = cpu;
index c5e42cc376048dbc9d960a6275b40c983acb7618..eb7f29a412f87f8e1b01e60a0cb6116a4ec8a641 100644 (file)
@@ -126,6 +126,7 @@ config RISCV
        select OF_IRQ
        select PCI_DOMAINS_GENERIC if PCI
        select PCI_MSI if PCI
+       select RISCV_ALTERNATIVE if !XIP_KERNEL
        select RISCV_INTC
        select RISCV_TIMER if RISCV_SBI
        select SIFIVE_PLIC
@@ -401,9 +402,8 @@ config RISCV_ISA_C
 config RISCV_ISA_SVPBMT
        bool "SVPBMT extension support"
        depends on 64BIT && MMU
-       depends on !XIP_KERNEL
+       depends on RISCV_ALTERNATIVE
        default y
-       select RISCV_ALTERNATIVE
        help
           Adds support to dynamically detect the presence of the SVPBMT
           ISA-extension (Supervisor-mode: page-based memory types) and
@@ -428,8 +428,8 @@ config TOOLCHAIN_HAS_ZBB
 config RISCV_ISA_ZBB
        bool "Zbb extension support for bit manipulation instructions"
        depends on TOOLCHAIN_HAS_ZBB
-       depends on !XIP_KERNEL && MMU
-       select RISCV_ALTERNATIVE
+       depends on MMU
+       depends on RISCV_ALTERNATIVE
        default y
        help
           Adds support to dynamically detect the presence of the ZBB
@@ -443,9 +443,9 @@ config RISCV_ISA_ZBB
 
 config RISCV_ISA_ZICBOM
        bool "Zicbom extension support for non-coherent DMA operation"
-       depends on !XIP_KERNEL && MMU
+       depends on MMU
+       depends on RISCV_ALTERNATIVE
        default y
-       select RISCV_ALTERNATIVE
        select RISCV_DMA_NONCOHERENT
        help
           Adds support to dynamically detect the presence of the ZICBOM
@@ -464,6 +464,28 @@ config TOOLCHAIN_HAS_ZIHINTPAUSE
        depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zihintpause)
        depends on LLD_VERSION >= 150000 || LD_VERSION >= 23600
 
+config TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI
+       def_bool y
+       # https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=aed44286efa8ae8717a77d94b51ac3614e2ca6dc
+       depends on AS_IS_GNU && AS_VERSION >= 23800
+       help
+         Newer binutils versions default to ISA spec version 20191213 which
+         moves some instructions from the I extension to the Zicsr and Zifencei
+         extensions.
+
+config TOOLCHAIN_NEEDS_OLD_ISA_SPEC
+       def_bool y
+       depends on TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI
+       # https://github.com/llvm/llvm-project/commit/22e199e6afb1263c943c0c0d4498694e15bf8a16
+       depends on CC_IS_CLANG && CLANG_VERSION < 170000
+       help
+         Certain versions of clang do not support zicsr and zifencei via -march
+         but newer versions of binutils require it for the reasons noted in the
+         help text of CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI. This
+         option causes an older ISA spec compatible with these older versions
+         of clang to be passed to GAS, which has the same result as passing zicsr
+         and zifencei to -march.
+
 config FPU
        bool "FPU support"
        default y
index 69621ae6d647aa369cee22c5751d3a55ec93e0b6..0c8f4652cd8289b62256f8c93756b84d327f4a88 100644 (file)
@@ -2,8 +2,7 @@ menu "CPU errata selection"
 
 config ERRATA_SIFIVE
        bool "SiFive errata"
-       depends on !XIP_KERNEL
-       select RISCV_ALTERNATIVE
+       depends on RISCV_ALTERNATIVE
        help
          All SiFive errata Kconfig depend on this Kconfig. Disabling
          this Kconfig will disable all SiFive errata. Please say "Y"
@@ -35,8 +34,7 @@ config ERRATA_SIFIVE_CIP_1200
 
 config ERRATA_THEAD
        bool "T-HEAD errata"
-       depends on !XIP_KERNEL
-       select RISCV_ALTERNATIVE
+       depends on RISCV_ALTERNATIVE
        help
          All T-HEAD errata Kconfig depend on this Kconfig. Disabling
          this Kconfig will disable all T-HEAD errata. Please say "Y"
index 6203c3378922821b580ea50a953af2dd0cb141bb..b05e833a022d17094e67dff727cb9ae9aa4c6cfb 100644 (file)
@@ -57,10 +57,12 @@ riscv-march-$(CONFIG_ARCH_RV64I)    := rv64ima
 riscv-march-$(CONFIG_FPU)              := $(riscv-march-y)fd
 riscv-march-$(CONFIG_RISCV_ISA_C)      := $(riscv-march-y)c
 
-# Newer binutils versions default to ISA spec version 20191213 which moves some
-# instructions from the I extension to the Zicsr and Zifencei extensions.
-toolchain-need-zicsr-zifencei := $(call cc-option-yn, -march=$(riscv-march-y)_zicsr_zifencei)
-riscv-march-$(toolchain-need-zicsr-zifencei) := $(riscv-march-y)_zicsr_zifencei
+ifdef CONFIG_TOOLCHAIN_NEEDS_OLD_ISA_SPEC
+KBUILD_CFLAGS += -Wa,-misa-spec=2.2
+KBUILD_AFLAGS += -Wa,-misa-spec=2.2
+else
+riscv-march-$(CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI) := $(riscv-march-y)_zicsr_zifencei
+endif
 
 # Check if the toolchain supports Zihintpause extension
 riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE) := $(riscv-march-y)_zihintpause
@@ -84,6 +86,13 @@ endif
 # Avoid generating .eh_frame sections.
 KBUILD_CFLAGS += -fno-asynchronous-unwind-tables -fno-unwind-tables
 
+# The RISC-V attributes frequently cause compatibility issues and provide no
+# information, so just turn them off.
+KBUILD_CFLAGS += $(call cc-option,-mno-riscv-attribute)
+KBUILD_AFLAGS += $(call cc-option,-mno-riscv-attribute)
+KBUILD_CFLAGS += $(call as-option,-Wa$(comma)-mno-arch-attr)
+KBUILD_AFLAGS += $(call as-option,-Wa$(comma)-mno-arch-attr)
+
 KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax)
 KBUILD_AFLAGS_MODULE += $(call as-option,-Wa$(comma)-mno-relax)
 
index 07e2e2649604640156aa61b6c7594b3c23e7a902..f87c5164d9cf658d6dbc58af85764ed2c6cd4cf3 100644 (file)
                                         <&sysclk K210_CLK_APB0>;
                                clock-names = "ssi_clk", "pclk";
                                resets = <&sysrst K210_RST_SPI2>;
-                               spi-max-frequency = <25000000>;
                        };
 
                        i2s0: i2s@50250000 {
index da55cb247e89499a875ea3b8089576e324b45494..31d2ebea4286ecef4dd539645c52f70c4883ceaa 100644 (file)
@@ -111,7 +111,7 @@ void __init_or_module sifive_errata_patch_func(struct alt_entry *begin,
                        mutex_lock(&text_mutex);
                        patch_text_nosync(ALT_OLD_PTR(alt), ALT_ALT_PTR(alt),
                                          alt->alt_len);
-                       mutex_lock(&text_mutex);
+                       mutex_unlock(&text_mutex);
                        cpu_apply_errata |= tmp;
                }
        }
index 5c3e7b97fcc6f6356b5a11bb7476609d90dd713a..0a55099bb7349d0adbc9acbabe95441b4c2991e0 100644 (file)
  */
 enum fixed_addresses {
        FIX_HOLE,
+       /*
+        * The fdt fixmap mapping must be PMD aligned and will be mapped
+        * using PMD entries in fixmap_pmd in 64-bit and a PGD entry in 32-bit.
+        */
+       FIX_FDT_END,
+       FIX_FDT = FIX_FDT_END + FIX_FDT_SIZE / PAGE_SIZE - 1,
+
+       /* Below fixmaps will be mapped using fixmap_pte */
        FIX_PTE,
        FIX_PMD,
        FIX_PUD,
index 9e73922e1e2e5bf8bd35ee8197d46a35690428e5..d47d87c2d7e3d0f1393688527f3c72d589fdb907 100644 (file)
@@ -109,6 +109,6 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
 #define ftrace_init_nop ftrace_init_nop
 #endif
 
-#endif
+#endif /* CONFIG_DYNAMIC_FTRACE */
 
 #endif /* _ASM_RISCV_FTRACE_H */
index e3021b2590de0a04e5ebd9ed936b464e09ce9b47..6263a0de1c6a19e68f3ec4008ecf2a1d90e2e786 100644 (file)
@@ -57,18 +57,31 @@ struct riscv_isa_ext_data {
        unsigned int isa_ext_id;
 };
 
+unsigned long riscv_isa_extension_base(const unsigned long *isa_bitmap);
+
+#define riscv_isa_extension_mask(ext) BIT_MASK(RISCV_ISA_EXT_##ext)
+
+bool __riscv_isa_extension_available(const unsigned long *isa_bitmap, int bit);
+#define riscv_isa_extension_available(isa_bitmap, ext) \
+       __riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_##ext)
+
 static __always_inline bool
 riscv_has_extension_likely(const unsigned long ext)
 {
        compiletime_assert(ext < RISCV_ISA_EXT_MAX,
                           "ext must be < RISCV_ISA_EXT_MAX");
 
-       asm_volatile_goto(
-       ALTERNATIVE("j  %l[l_no]", "nop", 0, %[ext], 1)
-       :
-       : [ext] "i" (ext)
-       :
-       : l_no);
+       if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) {
+               asm_volatile_goto(
+               ALTERNATIVE("j  %l[l_no]", "nop", 0, %[ext], 1)
+               :
+               : [ext] "i" (ext)
+               :
+               : l_no);
+       } else {
+               if (!__riscv_isa_extension_available(NULL, ext))
+                       goto l_no;
+       }
 
        return true;
 l_no:
@@ -81,26 +94,23 @@ riscv_has_extension_unlikely(const unsigned long ext)
        compiletime_assert(ext < RISCV_ISA_EXT_MAX,
                           "ext must be < RISCV_ISA_EXT_MAX");
 
-       asm_volatile_goto(
-       ALTERNATIVE("nop", "j   %l[l_yes]", 0, %[ext], 1)
-       :
-       : [ext] "i" (ext)
-       :
-       : l_yes);
+       if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) {
+               asm_volatile_goto(
+               ALTERNATIVE("nop", "j   %l[l_yes]", 0, %[ext], 1)
+               :
+               : [ext] "i" (ext)
+               :
+               : l_yes);
+       } else {
+               if (__riscv_isa_extension_available(NULL, ext))
+                       goto l_yes;
+       }
 
        return false;
 l_yes:
        return true;
 }
 
-unsigned long riscv_isa_extension_base(const unsigned long *isa_bitmap);
-
-#define riscv_isa_extension_mask(ext) BIT_MASK(RISCV_ISA_EXT_##ext)
-
-bool __riscv_isa_extension_available(const unsigned long *isa_bitmap, int bit);
-#define riscv_isa_extension_available(isa_bitmap, ext) \
-       __riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_##ext)
-
 #endif
 
 #endif /* _ASM_RISCV_HWCAP_H */
index 5ff1f19fd45c29b4fc7d2c8b44ac4984caf1e75c..0099dc1161683ddd1e3c45460309e331b7e6b0a7 100644 (file)
@@ -19,8 +19,6 @@ typedef struct {
 #ifdef CONFIG_SMP
        /* A local icache flush is needed before user execution can resume. */
        cpumask_t icache_stale_mask;
-       /* A local tlb flush is needed before user execution can resume. */
-       cpumask_t tlb_stale_mask;
 #endif
 } mm_context_t;
 
index f433121774c0190628b0a2f071059c92d782deb7..63c98833d5105d325db88ab3a232462fc0bdae85 100644 (file)
@@ -9,4 +9,6 @@
 int patch_text_nosync(void *addr, const void *insns, size_t len);
 int patch_text(void *addr, u32 *insns, int ninsns);
 
+extern int riscv_patch_in_stop_machine;
+
 #endif /* _ASM_RISCV_PATCH_H */
index ab05f892d317a82d808d3d8e058f441a44bc45a2..f641837ccf31d62d104d6798a63b3b1e3e8d4383 100644 (file)
 
 #define FIXADDR_TOP      PCI_IO_START
 #ifdef CONFIG_64BIT
-#define FIXADDR_SIZE     PMD_SIZE
+#define MAX_FDT_SIZE    PMD_SIZE
+#define FIX_FDT_SIZE    (MAX_FDT_SIZE + SZ_2M)
+#define FIXADDR_SIZE     (PMD_SIZE + FIX_FDT_SIZE)
 #else
-#define FIXADDR_SIZE     PGDIR_SIZE
+#define MAX_FDT_SIZE    PGDIR_SIZE
+#define FIX_FDT_SIZE    MAX_FDT_SIZE
+#define FIXADDR_SIZE     (PGDIR_SIZE + FIX_FDT_SIZE)
 #endif
 #define FIXADDR_START    (FIXADDR_TOP - FIXADDR_SIZE)
 
index 907b9efd39a87dd3853c1f8f21f4baa2fdd1125c..a09196f8de688ea90123bb74fc21e080cde19f22 100644 (file)
@@ -12,6 +12,8 @@
 #include <asm/errata_list.h>
 
 #ifdef CONFIG_MMU
+extern unsigned long asid_mask;
+
 static inline void local_flush_tlb_all(void)
 {
        __asm__ __volatile__ ("sfence.vma" : : : "memory");
@@ -22,24 +24,6 @@ static inline void local_flush_tlb_page(unsigned long addr)
 {
        ALT_FLUSH_TLB_PAGE(__asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory"));
 }
-
-static inline void local_flush_tlb_all_asid(unsigned long asid)
-{
-       __asm__ __volatile__ ("sfence.vma x0, %0"
-                       :
-                       : "r" (asid)
-                       : "memory");
-}
-
-static inline void local_flush_tlb_page_asid(unsigned long addr,
-               unsigned long asid)
-{
-       __asm__ __volatile__ ("sfence.vma %0, %1"
-                       :
-                       : "r" (addr), "r" (asid)
-                       : "memory");
-}
-
 #else /* CONFIG_MMU */
 #define local_flush_tlb_all()                  do { } while (0)
 #define local_flush_tlb_page(addr)             do { } while (0)
index 260daf3236d3a8dd08ac046410170c59f5d09b29..7f34f3c7c8827aeb32662f95dd1312d5ea047256 100644 (file)
@@ -14,6 +14,10 @@ COMPAT_LD := $(LD)
 COMPAT_CC_FLAGS := -march=rv32g -mabi=ilp32
 COMPAT_LD_FLAGS := -melf32lriscv
 
+# Disable attributes, as they're useless and break the build.
+COMPAT_CC_FLAGS += $(call cc-option,-mno-riscv-attribute)
+COMPAT_CC_FLAGS += $(call as-option,-Wa$(comma)-mno-arch-attr)
+
 # Files to link into the compat_vdso
 obj-compat_vdso = $(patsubst %, %.o, $(compat_vdso-syms)) note.o
 
index 5bff37af4770b5976332b880916a73807f786534..03a6434a8cdd0035bbc59629b1751c00df24b918 100644 (file)
 void ftrace_arch_code_modify_prepare(void) __acquires(&text_mutex)
 {
        mutex_lock(&text_mutex);
+
+       /*
+        * The code sequences we use for ftrace can't be patched while the
+        * kernel is running, so we need to use stop_machine() to modify them
+        * for now.  This doesn't play nice with text_mutex, we use this flag
+        * to elide the check.
+        */
+       riscv_patch_in_stop_machine = true;
 }
 
 void ftrace_arch_code_modify_post_process(void) __releases(&text_mutex)
 {
+       riscv_patch_in_stop_machine = false;
        mutex_unlock(&text_mutex);
 }
 
@@ -107,9 +116,9 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
 {
        int out;
 
-       ftrace_arch_code_modify_prepare();
+       mutex_lock(&text_mutex);
        out = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
-       ftrace_arch_code_modify_post_process();
+       mutex_unlock(&text_mutex);
 
        return out;
 }
index 8086d1a281cd32c52fb126beb5a514732618a6e2..575e71d6c8ae2d0b4e9b0935f117299884272a80 100644 (file)
@@ -11,6 +11,7 @@
 #include <asm/kprobes.h>
 #include <asm/cacheflush.h>
 #include <asm/fixmap.h>
+#include <asm/ftrace.h>
 #include <asm/patch.h>
 
 struct patch_insn {
@@ -20,6 +21,8 @@ struct patch_insn {
        atomic_t cpu_count;
 };
 
+int riscv_patch_in_stop_machine = false;
+
 #ifdef CONFIG_MMU
 /*
  * The fix_to_virt(, idx) needs a const value (not a dynamic variable of
@@ -60,8 +63,15 @@ static int patch_insn_write(void *addr, const void *insn, size_t len)
         * Before reaching here, it was expected to lock the text_mutex
         * already, so we don't need to give another lock here and could
         * ensure that it was safe between each cores.
+        *
+        * We're currently using stop_machine() for ftrace & kprobes, and while
+        * that ensures text_mutex is held before installing the mappings it
+        * does not ensure text_mutex is held by the calling thread.  That's
+        * safe but triggers a lockdep failure, so just elide it for that
+        * specific case.
         */
-       lockdep_assert_held(&text_mutex);
+       if (!riscv_patch_in_stop_machine)
+               lockdep_assert_held(&text_mutex);
 
        if (across_pages)
                patch_map(addr + len, FIX_TEXT_POKE1);
@@ -125,6 +135,7 @@ NOKPROBE_SYMBOL(patch_text_cb);
 
 int patch_text(void *addr, u32 *insns, int ninsns)
 {
+       int ret;
        struct patch_insn patch = {
                .addr = addr,
                .insns = insns,
@@ -132,7 +143,18 @@ int patch_text(void *addr, u32 *insns, int ninsns)
                .cpu_count = ATOMIC_INIT(0),
        };
 
-       return stop_machine_cpuslocked(patch_text_cb,
-                                      &patch, cpu_online_mask);
+       /*
+        * kprobes takes text_mutex, before calling patch_text(), but as we call
+        * calls stop_machine(), the lockdep assertion in patch_insn_write()
+        * gets confused by the context in which the lock is taken.
+        * Instead, ensure the lock is held before calling stop_machine(), and
+        * set riscv_patch_in_stop_machine to skip the check in
+        * patch_insn_write().
+        */
+       lockdep_assert_held(&text_mutex);
+       riscv_patch_in_stop_machine = true;
+       ret = stop_machine_cpuslocked(patch_text_cb, &patch, cpu_online_mask);
+       riscv_patch_in_stop_machine = false;
+       return ret;
 }
 NOKPROBE_SYMBOL(patch_text);
index 376d2827e7365af086c0c2b7d40f9ec2507d999b..a059b73f4ddb263744e47774d0549efe24e5933c 100644 (file)
@@ -278,12 +278,8 @@ void __init setup_arch(char **cmdline_p)
 #if IS_ENABLED(CONFIG_BUILTIN_DTB)
        unflatten_and_copy_device_tree();
 #else
-       if (early_init_dt_verify(__va(XIP_FIXUP(dtb_early_pa))))
-               unflatten_device_tree();
-       else
-               pr_err("No DTB found in kernel mappings\n");
+       unflatten_device_tree();
 #endif
-       early_init_fdt_scan_reserved_mem();
        misc_mem_init();
 
        init_resources();
index bfb2afa4135f89690b90da20d281252a539d8cda..dee66c9290ccee95e20f93517e47d16a133b02bb 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/signal32.h>
 #include <asm/switch_to.h>
 #include <asm/csr.h>
+#include <asm/cacheflush.h>
 
 extern u32 __user_rt_sigreturn[2];
 
@@ -181,6 +182,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 {
        struct rt_sigframe __user *frame;
        long err = 0;
+       unsigned long __maybe_unused addr;
 
        frame = get_sigframe(ksig, regs, sizeof(*frame));
        if (!access_ok(frame, sizeof(*frame)))
@@ -209,7 +211,12 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
        if (copy_to_user(&frame->sigreturn_code, __user_rt_sigreturn,
                         sizeof(frame->sigreturn_code)))
                return -EFAULT;
-       regs->ra = (unsigned long)&frame->sigreturn_code;
+
+       addr = (unsigned long)&frame->sigreturn_code;
+       /* Make sure the two instructions are pushed to icache. */
+       flush_icache_range(addr, addr + sizeof(frame->sigreturn_code));
+
+       regs->ra = addr;
 #endif /* CONFIG_MMU */
 
        /*
index f9a5a7c90ff0939b7d303de2454fcb94fc0dee85..64a9c093aef93a1b9ec4a99bab001a1f9932e776 100644 (file)
@@ -101,7 +101,7 @@ void notrace walk_stackframe(struct task_struct *task,
        while (!kstack_end(ksp)) {
                if (__kernel_text_address(pc) && unlikely(!fn(arg, pc)))
                        break;
-               pc = (*ksp++) - 0x4;
+               pc = READ_ONCE_NOCHECK(*ksp++) - 0x4;
        }
 }
 
index d5a658a047a7f738fc91df06709ee0e867ac2347..5682d8c017b3e419d982115777d17c7c1184d717 100644 (file)
@@ -28,7 +28,6 @@ config KVM
        select KVM_XFER_TO_GUEST_WORK
        select HAVE_KVM_VCPU_ASYNC_IOCTL
        select HAVE_KVM_EVENTFD
-       select SRCU
        help
          Support hosting virtualized guest machines.
 
index ad34519c8a13dff001587abd739c018ac4038b6d..3ac2ff6a65dacbeb1e5c030602bef10962ecbb21 100644 (file)
@@ -147,10 +147,8 @@ static void kvm_riscv_vcpu_timer_blocking(struct kvm_vcpu *vcpu)
                return;
 
        delta_ns = kvm_riscv_delta_cycles2ns(t->next_cycles, gt, t);
-       if (delta_ns) {
-               hrtimer_start(&t->hrt, ktime_set(0, delta_ns), HRTIMER_MODE_REL);
-               t->next_set = true;
-       }
+       hrtimer_start(&t->hrt, ktime_set(0, delta_ns), HRTIMER_MODE_REL);
+       t->next_set = true;
 }
 
 static void kvm_riscv_vcpu_timer_unblocking(struct kvm_vcpu *vcpu)
index 80ce9caba8d225979426f01f9a636d11890f9de6..12e22e7330e7bd2f0feee680b143c407473f0a81 100644 (file)
@@ -22,7 +22,7 @@ DEFINE_STATIC_KEY_FALSE(use_asid_allocator);
 
 static unsigned long asid_bits;
 static unsigned long num_asids;
-static unsigned long asid_mask;
+unsigned long asid_mask;
 
 static atomic_long_t current_version;
 
@@ -196,16 +196,6 @@ switch_mm_fast:
 
        if (need_flush_tlb)
                local_flush_tlb_all();
-#ifdef CONFIG_SMP
-       else {
-               cpumask_t *mask = &mm->context.tlb_stale_mask;
-
-               if (cpumask_test_cpu(cpu, mask)) {
-                       cpumask_clear_cpu(cpu, mask);
-                       local_flush_tlb_all_asid(cntx & asid_mask);
-               }
-       }
-#endif
 }
 
 static void set_mm_noasid(struct mm_struct *mm)
@@ -215,12 +205,24 @@ static void set_mm_noasid(struct mm_struct *mm)
        local_flush_tlb_all();
 }
 
-static inline void set_mm(struct mm_struct *mm, unsigned int cpu)
+static inline void set_mm(struct mm_struct *prev,
+                         struct mm_struct *next, unsigned int cpu)
 {
-       if (static_branch_unlikely(&use_asid_allocator))
-               set_mm_asid(mm, cpu);
-       else
-               set_mm_noasid(mm);
+       /*
+        * The mm_cpumask indicates which harts' TLBs contain the virtual
+        * address mapping of the mm. Compared to noasid, using asid
+        * can't guarantee that stale TLB entries are invalidated because
+        * the asid mechanism wouldn't flush TLB for every switch_mm for
+        * performance. So when using asid, keep all CPUs footmarks in
+        * cpumask() until mm reset.
+        */
+       cpumask_set_cpu(cpu, mm_cpumask(next));
+       if (static_branch_unlikely(&use_asid_allocator)) {
+               set_mm_asid(next, cpu);
+       } else {
+               cpumask_clear_cpu(cpu, mm_cpumask(prev));
+               set_mm_noasid(next);
+       }
 }
 
 static int __init asids_init(void)
@@ -274,7 +276,8 @@ static int __init asids_init(void)
 }
 early_initcall(asids_init);
 #else
-static inline void set_mm(struct mm_struct *mm, unsigned int cpu)
+static inline void set_mm(struct mm_struct *prev,
+                         struct mm_struct *next, unsigned int cpu)
 {
        /* Nothing to do here when there is no MMU */
 }
@@ -327,10 +330,7 @@ void switch_mm(struct mm_struct *prev, struct mm_struct *next,
         */
        cpu = smp_processor_id();
 
-       cpumask_clear_cpu(cpu, mm_cpumask(prev));
-       cpumask_set_cpu(cpu, mm_cpumask(next));
-
-       set_mm(next, cpu);
+       set_mm(prev, next, cpu);
 
        flush_icache_deferred(next, cpu);
 }
index 460f785f6e09cd8fb1441f2fff49288f5256181e..d5f3e501dffb3a6dd2596682b26a011389ac2cb1 100644 (file)
@@ -143,6 +143,8 @@ static inline void vmalloc_fault(struct pt_regs *regs, int code, unsigned long a
                no_context(regs, addr);
                return;
        }
+       if (pud_leaf(*pud_k))
+               goto flush_tlb;
 
        /*
         * Since the vmalloc area is global, it is unnecessary
@@ -153,6 +155,8 @@ static inline void vmalloc_fault(struct pt_regs *regs, int code, unsigned long a
                no_context(regs, addr);
                return;
        }
+       if (pmd_leaf(*pmd_k))
+               goto flush_tlb;
 
        /*
         * Make sure the actual PTE exists as well to
@@ -172,6 +176,7 @@ static inline void vmalloc_fault(struct pt_regs *regs, int code, unsigned long a
         * ordering constraint, not a cache flush; it is
         * necessary even after writing invalid entries.
         */
+flush_tlb:
        local_flush_tlb_page(addr);
 }
 
index 478d6763a01a1ebde626635a2f7703f4415649a7..0f14f4a8d179a64f9b75541cefe3409d0cb22a12 100644 (file)
@@ -57,7 +57,6 @@ unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]
 EXPORT_SYMBOL(empty_zero_page);
 
 extern char _start[];
-#define DTB_EARLY_BASE_VA      PGDIR_SIZE
 void *_dtb_early_va __initdata;
 uintptr_t _dtb_early_pa __initdata;
 
@@ -236,31 +235,22 @@ static void __init setup_bootmem(void)
        set_max_mapnr(max_low_pfn - ARCH_PFN_OFFSET);
 
        reserve_initrd_mem();
+
+       /*
+        * No allocation should be done before reserving the memory as defined
+        * in the device tree, otherwise the allocation could end up in a
+        * reserved region.
+        */
+       early_init_fdt_scan_reserved_mem();
+
        /*
         * If DTB is built in, no need to reserve its memblock.
         * Otherwise, do reserve it but avoid using
         * early_init_fdt_reserve_self() since __pa() does
         * not work for DTB pointers that are fixmap addresses
         */
-       if (!IS_ENABLED(CONFIG_BUILTIN_DTB)) {
-               /*
-                * In case the DTB is not located in a memory region we won't
-                * be able to locate it later on via the linear mapping and
-                * get a segfault when accessing it via __va(dtb_early_pa).
-                * To avoid this situation copy DTB to a memory region.
-                * Note that memblock_phys_alloc will also reserve DTB region.
-                */
-               if (!memblock_is_memory(dtb_early_pa)) {
-                       size_t fdt_size = fdt_totalsize(dtb_early_va);
-                       phys_addr_t new_dtb_early_pa = memblock_phys_alloc(fdt_size, PAGE_SIZE);
-                       void *new_dtb_early_va = early_memremap(new_dtb_early_pa, fdt_size);
-
-                       memcpy(new_dtb_early_va, dtb_early_va, fdt_size);
-                       early_memunmap(new_dtb_early_va, fdt_size);
-                       _dtb_early_pa = new_dtb_early_pa;
-               } else
-                       memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va));
-       }
+       if (!IS_ENABLED(CONFIG_BUILTIN_DTB))
+               memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va));
 
        dma_contiguous_reserve(dma32_phys_limit);
        if (IS_ENABLED(CONFIG_64BIT))
@@ -279,9 +269,6 @@ pgd_t trampoline_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
 static pte_t fixmap_pte[PTRS_PER_PTE] __page_aligned_bss;
 
 pgd_t early_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE);
-static p4d_t __maybe_unused early_dtb_p4d[PTRS_PER_P4D] __initdata __aligned(PAGE_SIZE);
-static pud_t __maybe_unused early_dtb_pud[PTRS_PER_PUD] __initdata __aligned(PAGE_SIZE);
-static pmd_t __maybe_unused early_dtb_pmd[PTRS_PER_PMD] __initdata __aligned(PAGE_SIZE);
 
 #ifdef CONFIG_XIP_KERNEL
 #define pt_ops                 (*(struct pt_alloc_ops *)XIP_FIXUP(&pt_ops))
@@ -626,9 +613,6 @@ static void __init create_p4d_mapping(p4d_t *p4dp,
 #define trampoline_pgd_next    (pgtable_l5_enabled ?                   \
                (uintptr_t)trampoline_p4d : (pgtable_l4_enabled ?       \
                (uintptr_t)trampoline_pud : (uintptr_t)trampoline_pmd))
-#define early_dtb_pgd_next     (pgtable_l5_enabled ?                   \
-               (uintptr_t)early_dtb_p4d : (pgtable_l4_enabled ?        \
-               (uintptr_t)early_dtb_pud : (uintptr_t)early_dtb_pmd))
 #else
 #define pgd_next_t             pte_t
 #define alloc_pgd_next(__va)   pt_ops.alloc_pte(__va)
@@ -636,7 +620,6 @@ static void __init create_p4d_mapping(p4d_t *p4dp,
 #define create_pgd_next_mapping(__nextp, __va, __pa, __sz, __prot)     \
        create_pte_mapping(__nextp, __va, __pa, __sz, __prot)
 #define fixmap_pgd_next                ((uintptr_t)fixmap_pte)
-#define early_dtb_pgd_next     ((uintptr_t)early_dtb_pmd)
 #define create_p4d_mapping(__pmdp, __va, __pa, __sz, __prot) do {} while(0)
 #define create_pud_mapping(__pmdp, __va, __pa, __sz, __prot) do {} while(0)
 #define create_pmd_mapping(__pmdp, __va, __pa, __sz, __prot) do {} while(0)
@@ -860,32 +843,28 @@ static void __init create_kernel_page_table(pgd_t *pgdir, bool early)
  * this means 2 PMD entries whereas for 32-bit kernel, this is only 1 PGDIR
  * entry.
  */
-static void __init create_fdt_early_page_table(pgd_t *pgdir, uintptr_t dtb_pa)
+static void __init create_fdt_early_page_table(pgd_t *pgdir,
+                                              uintptr_t fix_fdt_va,
+                                              uintptr_t dtb_pa)
 {
-#ifndef CONFIG_BUILTIN_DTB
        uintptr_t pa = dtb_pa & ~(PMD_SIZE - 1);
 
-       create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA,
-                          IS_ENABLED(CONFIG_64BIT) ? early_dtb_pgd_next : pa,
-                          PGDIR_SIZE,
-                          IS_ENABLED(CONFIG_64BIT) ? PAGE_TABLE : PAGE_KERNEL);
-
-       if (pgtable_l5_enabled)
-               create_p4d_mapping(early_dtb_p4d, DTB_EARLY_BASE_VA,
-                                  (uintptr_t)early_dtb_pud, P4D_SIZE, PAGE_TABLE);
-
-       if (pgtable_l4_enabled)
-               create_pud_mapping(early_dtb_pud, DTB_EARLY_BASE_VA,
-                                  (uintptr_t)early_dtb_pmd, PUD_SIZE, PAGE_TABLE);
+#ifndef CONFIG_BUILTIN_DTB
+       /* Make sure the fdt fixmap address is always aligned on PMD size */
+       BUILD_BUG_ON(FIX_FDT % (PMD_SIZE / PAGE_SIZE));
 
-       if (IS_ENABLED(CONFIG_64BIT)) {
-               create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA,
+       /* In 32-bit only, the fdt lies in its own PGD */
+       if (!IS_ENABLED(CONFIG_64BIT)) {
+               create_pgd_mapping(early_pg_dir, fix_fdt_va,
+                                  pa, MAX_FDT_SIZE, PAGE_KERNEL);
+       } else {
+               create_pmd_mapping(fixmap_pmd, fix_fdt_va,
                                   pa, PMD_SIZE, PAGE_KERNEL);
-               create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA + PMD_SIZE,
+               create_pmd_mapping(fixmap_pmd, fix_fdt_va + PMD_SIZE,
                                   pa + PMD_SIZE, PMD_SIZE, PAGE_KERNEL);
        }
 
-       dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PMD_SIZE - 1));
+       dtb_early_va = (void *)fix_fdt_va + (dtb_pa & (PMD_SIZE - 1));
 #else
        /*
         * For 64-bit kernel, __va can't be used since it would return a linear
@@ -1055,7 +1034,8 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
        create_kernel_page_table(early_pg_dir, true);
 
        /* Setup early mapping for FDT early scan */
-       create_fdt_early_page_table(early_pg_dir, dtb_pa);
+       create_fdt_early_page_table(early_pg_dir,
+                                   __fix_to_virt(FIX_FDT), dtb_pa);
 
        /*
         * Bootime fixmap only can handle PMD_SIZE mapping. Thus, boot-ioremap
@@ -1097,6 +1077,16 @@ static void __init setup_vm_final(void)
        u64 i;
 
        /* Setup swapper PGD for fixmap */
+#if !defined(CONFIG_64BIT)
+       /*
+        * In 32-bit, the device tree lies in a pgd entry, so it must be copied
+        * directly in swapper_pg_dir in addition to the pgd entry that points
+        * to fixmap_pte.
+        */
+       unsigned long idx = pgd_index(__fix_to_virt(FIX_FDT));
+
+       set_pgd(&swapper_pg_dir[idx], early_pg_dir[idx]);
+#endif
        create_pgd_mapping(swapper_pg_dir, FIXADDR_START,
                           __pa_symbol(fixmap_pgd_next),
                           PGDIR_SIZE, PAGE_TABLE);
index ce7dfc81bb3fe386748557f44310aa4b1a86f3a9..ef701fa83f3685c6d497ccda59086e7b9f0da20b 100644 (file)
@@ -5,7 +5,23 @@
 #include <linux/sched.h>
 #include <asm/sbi.h>
 #include <asm/mmu_context.h>
-#include <asm/tlbflush.h>
+
+static inline void local_flush_tlb_all_asid(unsigned long asid)
+{
+       __asm__ __volatile__ ("sfence.vma x0, %0"
+                       :
+                       : "r" (asid)
+                       : "memory");
+}
+
+static inline void local_flush_tlb_page_asid(unsigned long addr,
+               unsigned long asid)
+{
+       __asm__ __volatile__ ("sfence.vma %0, %1"
+                       :
+                       : "r" (addr), "r" (asid)
+                       : "memory");
+}
 
 void flush_tlb_all(void)
 {
@@ -15,7 +31,6 @@ void flush_tlb_all(void)
 static void __sbi_tlb_flush_range(struct mm_struct *mm, unsigned long start,
                                  unsigned long size, unsigned long stride)
 {
-       struct cpumask *pmask = &mm->context.tlb_stale_mask;
        struct cpumask *cmask = mm_cpumask(mm);
        unsigned int cpuid;
        bool broadcast;
@@ -27,16 +42,7 @@ static void __sbi_tlb_flush_range(struct mm_struct *mm, unsigned long start,
        /* check if the tlbflush needs to be sent to other CPUs */
        broadcast = cpumask_any_but(cmask, cpuid) < nr_cpu_ids;
        if (static_branch_unlikely(&use_asid_allocator)) {
-               unsigned long asid = atomic_long_read(&mm->context.id);
-
-               /*
-                * TLB will be immediately flushed on harts concurrently
-                * executing this MM context. TLB flush on other harts
-                * is deferred until this MM context migrates there.
-                */
-               cpumask_setall(pmask);
-               cpumask_clear_cpu(cpuid, pmask);
-               cpumask_andnot(pmask, pmask, cmask);
+               unsigned long asid = atomic_long_read(&mm->context.id) & asid_mask;
 
                if (broadcast) {
                        sbi_remote_sfence_vma_asid(cmask, start, size, asid);
index f5a668736c79b1113b81f57b9243f9a05975619f..acdc3f040195e011634805de7027de18da05a180 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/filter.h>
 #include <linux/memory.h>
 #include <linux/stop_machine.h>
+#include <asm/patch.h>
 #include "bpf_jit.h"
 
 #define RV_REG_TCC RV_REG_A6
index d16bf715a586bb5595e5017da7c99870b096d36e..5730797a6b402c39c96cd0360486b3548631b389 100644 (file)
@@ -84,12 +84,7 @@ CFLAGS_string.o                      += $(PURGATORY_CFLAGS)
 CFLAGS_REMOVE_ctype.o          += $(PURGATORY_CFLAGS_REMOVE)
 CFLAGS_ctype.o                 += $(PURGATORY_CFLAGS)
 
-AFLAGS_REMOVE_entry.o          += -Wa,-gdwarf-2
-AFLAGS_REMOVE_memcpy.o         += -Wa,-gdwarf-2
-AFLAGS_REMOVE_memset.o         += -Wa,-gdwarf-2
-AFLAGS_REMOVE_strcmp.o         += -Wa,-gdwarf-2
-AFLAGS_REMOVE_strlen.o         += -Wa,-gdwarf-2
-AFLAGS_REMOVE_strncmp.o                += -Wa,-gdwarf-2
+asflags-remove-y               += $(foreach x, -g -gdwarf-4 -gdwarf-5, $(x) -Wa,$(x))
 
 $(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
                $(call if_changed,ld)
index b3235ab0ace83993dc62cab43e46c9aa326bed46..ed646c583e4fe694e1678d9e54356d370c67d7f8 100644 (file)
@@ -162,7 +162,7 @@ vdso_prepare: prepare0
 
 ifdef CONFIG_EXPOLINE_EXTERN
 modules_prepare: expoline_prepare
-expoline_prepare:
+expoline_prepare: scripts
        $(Q)$(MAKE) $(build)=arch/s390/lib/expoline arch/s390/lib/expoline/expoline.o
 endif
 endif
index 9b14045065b6e1e4bfbfcfa6c714a1d5d1e08a6e..74b5cd264862247fc040cabfe24c6a289d3d08a3 100644 (file)
@@ -57,11 +57,19 @@ repeat:
        if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && initrd_data.start && initrd_data.size &&
            intersects(initrd_data.start, initrd_data.size, safe_addr, size))
                safe_addr = initrd_data.start + initrd_data.size;
+       if (intersects(safe_addr, size, (unsigned long)comps, comps->len)) {
+               safe_addr = (unsigned long)comps + comps->len;
+               goto repeat;
+       }
        for_each_rb_entry(comp, comps)
                if (intersects(safe_addr, size, comp->addr, comp->len)) {
                        safe_addr = comp->addr + comp->len;
                        goto repeat;
                }
+       if (intersects(safe_addr, size, (unsigned long)certs, certs->len)) {
+               safe_addr = (unsigned long)certs + certs->len;
+               goto repeat;
+       }
        for_each_rb_entry(cert, certs)
                if (intersects(safe_addr, size, cert->addr, cert->len)) {
                        safe_addr = cert->addr + cert->len;
index 3c68fe49042c2630bf37230b672c5edf26d5338d..4ccf66d29fc24b9cad9425fc0fcb9a01bfe4b3c0 100644 (file)
@@ -23,7 +23,6 @@ CONFIG_NUMA_BALANCING=y
 CONFIG_MEMCG=y
 CONFIG_BLK_CGROUP=y
 CONFIG_CFS_BANDWIDTH=y
-CONFIG_RT_GROUP_SCHED=y
 CONFIG_CGROUP_PIDS=y
 CONFIG_CGROUP_RDMA=y
 CONFIG_CGROUP_FREEZER=y
@@ -90,7 +89,6 @@ CONFIG_MINIX_SUBPARTITION=y
 CONFIG_SOLARIS_X86_PARTITION=y
 CONFIG_UNIXWARE_DISKLABEL=y
 CONFIG_IOSCHED_BFQ=y
-CONFIG_BFQ_GROUP_IOSCHED=y
 CONFIG_BINFMT_MISC=m
 CONFIG_ZSWAP=y
 CONFIG_ZSMALLOC_STAT=y
@@ -298,7 +296,6 @@ CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_NAT=m
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_TARGET_ECN=m
 CONFIG_IP_NF_TARGET_TTL=m
 CONFIG_IP_NF_RAW=m
@@ -340,7 +337,6 @@ CONFIG_BRIDGE_MRP=y
 CONFIG_VLAN_8021Q=m
 CONFIG_VLAN_8021Q_GVRP=y
 CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CBQ=m
 CONFIG_NET_SCH_HTB=m
 CONFIG_NET_SCH_HFSC=m
 CONFIG_NET_SCH_PRIO=m
@@ -351,7 +347,6 @@ CONFIG_NET_SCH_SFQ=m
 CONFIG_NET_SCH_TEQL=m
 CONFIG_NET_SCH_TBF=m
 CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
 CONFIG_NET_SCH_NETEM=m
 CONFIG_NET_SCH_DRR=m
 CONFIG_NET_SCH_MQPRIO=m
@@ -363,14 +358,11 @@ CONFIG_NET_SCH_INGRESS=m
 CONFIG_NET_SCH_PLUG=m
 CONFIG_NET_SCH_ETS=m
 CONFIG_NET_CLS_BASIC=m
-CONFIG_NET_CLS_TCINDEX=m
 CONFIG_NET_CLS_ROUTE4=m
 CONFIG_NET_CLS_FW=m
 CONFIG_NET_CLS_U32=m
 CONFIG_CLS_U32_PERF=y
 CONFIG_CLS_U32_MARK=y
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
 CONFIG_NET_CLS_FLOW=m
 CONFIG_NET_CLS_CGROUP=y
 CONFIG_NET_CLS_BPF=m
@@ -584,7 +576,7 @@ CONFIG_DIAG288_WATCHDOG=m
 CONFIG_FB=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
-# CONFIG_HID is not set
+# CONFIG_HID_SUPPORT is not set
 # CONFIG_USB_SUPPORT is not set
 CONFIG_INFINIBAND=m
 CONFIG_INFINIBAND_USER_ACCESS=m
@@ -828,6 +820,7 @@ CONFIG_PANIC_ON_OOPS=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_WQ_WATCHDOG=y
 CONFIG_TEST_LOCKUP=m
+CONFIG_DEBUG_PREEMPT=y
 CONFIG_PROVE_LOCKING=y
 CONFIG_LOCK_STAT=y
 CONFIG_DEBUG_ATOMIC_SLEEP=y
@@ -843,6 +836,7 @@ CONFIG_RCU_CPU_STALL_TIMEOUT=300
 # CONFIG_RCU_TRACE is not set
 CONFIG_LATENCYTOP=y
 CONFIG_BOOTTIME_TRACING=y
+CONFIG_FPROBE=y
 CONFIG_FUNCTION_PROFILER=y
 CONFIG_STACK_TRACER=y
 CONFIG_IRQSOFF_TRACER=y
@@ -857,6 +851,7 @@ CONFIG_SAMPLES=y
 CONFIG_SAMPLE_TRACE_PRINTK=m
 CONFIG_SAMPLE_FTRACE_DIRECT=m
 CONFIG_SAMPLE_FTRACE_DIRECT_MULTI=m
+CONFIG_SAMPLE_FTRACE_OPS=m
 CONFIG_DEBUG_ENTRY=y
 CONFIG_CIO_INJECT=y
 CONFIG_KUNIT=m
index 9ab91632f74cca3c35eefdcd80d4d94adf74704a..693297a2e89733d888c30e78e9d95f981c6db015 100644 (file)
@@ -21,7 +21,6 @@ CONFIG_NUMA_BALANCING=y
 CONFIG_MEMCG=y
 CONFIG_BLK_CGROUP=y
 CONFIG_CFS_BANDWIDTH=y
-CONFIG_RT_GROUP_SCHED=y
 CONFIG_CGROUP_PIDS=y
 CONFIG_CGROUP_RDMA=y
 CONFIG_CGROUP_FREEZER=y
@@ -85,7 +84,6 @@ CONFIG_MINIX_SUBPARTITION=y
 CONFIG_SOLARIS_X86_PARTITION=y
 CONFIG_UNIXWARE_DISKLABEL=y
 CONFIG_IOSCHED_BFQ=y
-CONFIG_BFQ_GROUP_IOSCHED=y
 CONFIG_BINFMT_MISC=m
 CONFIG_ZSWAP=y
 CONFIG_ZSMALLOC_STAT=y
@@ -289,7 +287,6 @@ CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_NAT=m
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_TARGET_ECN=m
 CONFIG_IP_NF_TARGET_TTL=m
 CONFIG_IP_NF_RAW=m
@@ -330,7 +327,6 @@ CONFIG_BRIDGE_MRP=y
 CONFIG_VLAN_8021Q=m
 CONFIG_VLAN_8021Q_GVRP=y
 CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CBQ=m
 CONFIG_NET_SCH_HTB=m
 CONFIG_NET_SCH_HFSC=m
 CONFIG_NET_SCH_PRIO=m
@@ -341,7 +337,6 @@ CONFIG_NET_SCH_SFQ=m
 CONFIG_NET_SCH_TEQL=m
 CONFIG_NET_SCH_TBF=m
 CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
 CONFIG_NET_SCH_NETEM=m
 CONFIG_NET_SCH_DRR=m
 CONFIG_NET_SCH_MQPRIO=m
@@ -353,14 +348,11 @@ CONFIG_NET_SCH_INGRESS=m
 CONFIG_NET_SCH_PLUG=m
 CONFIG_NET_SCH_ETS=m
 CONFIG_NET_CLS_BASIC=m
-CONFIG_NET_CLS_TCINDEX=m
 CONFIG_NET_CLS_ROUTE4=m
 CONFIG_NET_CLS_FW=m
 CONFIG_NET_CLS_U32=m
 CONFIG_CLS_U32_PERF=y
 CONFIG_CLS_U32_MARK=y
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
 CONFIG_NET_CLS_FLOW=m
 CONFIG_NET_CLS_CGROUP=y
 CONFIG_NET_CLS_BPF=m
@@ -573,7 +565,7 @@ CONFIG_DIAG288_WATCHDOG=m
 CONFIG_FB=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
-# CONFIG_HID is not set
+# CONFIG_HID_SUPPORT is not set
 # CONFIG_USB_SUPPORT is not set
 CONFIG_INFINIBAND=m
 CONFIG_INFINIBAND_USER_ACCESS=m
@@ -795,6 +787,7 @@ CONFIG_RCU_REF_SCALE_TEST=m
 CONFIG_RCU_CPU_STALL_TIMEOUT=60
 CONFIG_LATENCYTOP=y
 CONFIG_BOOTTIME_TRACING=y
+CONFIG_FPROBE=y
 CONFIG_FUNCTION_PROFILER=y
 CONFIG_STACK_TRACER=y
 CONFIG_SCHED_TRACER=y
@@ -805,6 +798,7 @@ CONFIG_SAMPLES=y
 CONFIG_SAMPLE_TRACE_PRINTK=m
 CONFIG_SAMPLE_FTRACE_DIRECT=m
 CONFIG_SAMPLE_FTRACE_DIRECT_MULTI=m
+CONFIG_SAMPLE_FTRACE_OPS=m
 CONFIG_KUNIT=m
 CONFIG_KUNIT_DEBUGFS=y
 CONFIG_LKDTM=m
index a9c0c81d1de992c8cfdadb7985e293856318681e..33a232bb68af95b460eb098136fbdd23e3045751 100644 (file)
@@ -58,7 +58,7 @@ CONFIG_ZFCP=y
 # CONFIG_VMCP is not set
 # CONFIG_MONWRITER is not set
 # CONFIG_S390_VMUR is not set
-# CONFIG_HID is not set
+# CONFIG_HID_SUPPORT is not set
 # CONFIG_VIRTIO_MENU is not set
 # CONFIG_VHOST_MENU is not set
 # CONFIG_IOMMU_SUPPORT is not set
index cf9659e13f03d9245165561e3cb45ced0aef1c7e..ea244a73efad9d6b83fd7e1fff118e65b0309471 100644 (file)
@@ -474,9 +474,7 @@ long arch_ptrace(struct task_struct *child, long request,
                }
                return 0;
        case PTRACE_GET_LAST_BREAK:
-               put_user(child->thread.last_break,
-                        (unsigned long __user *) data);
-               return 0;
+               return put_user(child->thread.last_break, (unsigned long __user *)data);
        case PTRACE_ENABLE_TE:
                if (!MACHINE_HAS_TE)
                        return -EIO;
@@ -824,9 +822,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                }
                return 0;
        case PTRACE_GET_LAST_BREAK:
-               put_user(child->thread.last_break,
-                        (unsigned int __user *) data);
-               return 0;
+               return put_user(child->thread.last_break, (unsigned int __user *)data);
        }
        return compat_ptrace_request(child, request, addr, data);
 }
index 33f4ff909476cd25dee05fc9ea78bfb7fdf6ed4e..45fdf2a9b2e326140033a78bb19f95ccddfac255 100644 (file)
@@ -31,7 +31,6 @@ config KVM
        select HAVE_KVM_IRQ_ROUTING
        select HAVE_KVM_INVALID_WAKEUPS
        select HAVE_KVM_NO_POLL
-       select SRCU
        select KVM_VFIO
        select INTERVAL_TREE
        select MMU_NOTIFIER
index 0ee02dae14b2bdc1294d4685825f25f042715fac..2cda8d9d7c6ef1f4d3762dcd2d6735ccb8e18100 100644 (file)
@@ -271,10 +271,18 @@ static int handle_prog(struct kvm_vcpu *vcpu)
  * handle_external_interrupt - used for external interruption interceptions
  * @vcpu: virtual cpu
  *
- * This interception only occurs if the CPUSTAT_EXT_INT bit was set, or if
- * the new PSW does not have external interrupts disabled. In the first case,
- * we've got to deliver the interrupt manually, and in the second case, we
- * drop to userspace to handle the situation there.
+ * This interception occurs if:
+ * - the CPUSTAT_EXT_INT bit was already set when the external interrupt
+ *   occurred. In this case, the interrupt needs to be injected manually to
+ *   preserve interrupt priority.
+ * - the external new PSW has external interrupts enabled, which will cause an
+ *   interruption loop. We drop to userspace in this case.
+ *
+ * The latter case can be detected by inspecting the external mask bit in the
+ * external new psw.
+ *
+ * Under PV, only the latter case can occur, since interrupt priorities are
+ * handled in the ultravisor.
  */
 static int handle_external_interrupt(struct kvm_vcpu *vcpu)
 {
@@ -285,10 +293,18 @@ static int handle_external_interrupt(struct kvm_vcpu *vcpu)
 
        vcpu->stat.exit_external_interrupt++;
 
-       rc = read_guest_lc(vcpu, __LC_EXT_NEW_PSW, &newpsw, sizeof(psw_t));
-       if (rc)
-               return rc;
-       /* We can not handle clock comparator or timer interrupt with bad PSW */
+       if (kvm_s390_pv_cpu_is_protected(vcpu)) {
+               newpsw = vcpu->arch.sie_block->gpsw;
+       } else {
+               rc = read_guest_lc(vcpu, __LC_EXT_NEW_PSW, &newpsw, sizeof(psw_t));
+               if (rc)
+                       return rc;
+       }
+
+       /*
+        * Clock comparator or timer interrupt with external interrupt enabled
+        * will cause interrupt loop. Drop to userspace.
+        */
        if ((eic == EXT_IRQ_CLK_COMP || eic == EXT_IRQ_CPU_TIMER) &&
            (newpsw.mask & PSW_MASK_EXT))
                return -EOPNOTSUPP;
index 39b36562c043f6ba8ad0d29248744fceaaedab63..1eeb9ae57879c8d67c465fffc438e18ed3f05c58 100644 (file)
@@ -573,6 +573,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
        case KVM_CAP_S390_VCPU_RESETS:
        case KVM_CAP_SET_GUEST_DEBUG:
        case KVM_CAP_S390_DIAG318:
+       case KVM_CAP_IRQFD_RESAMPLE:
                r = 1;
                break;
        case KVM_CAP_SET_GUEST_DEBUG2:
index 720036fb1924266cb720badf76a72df1ffbead8e..d44214072779e7abbbe0862a3af28b2c01954cbb 100644 (file)
@@ -172,7 +172,7 @@ unsigned long __clear_user(void __user *to, unsigned long size)
                "4: slgr  %0,%0\n"
                "5:\n"
                EX_TABLE(0b,2b) EX_TABLE(6b,2b) EX_TABLE(3b,5b) EX_TABLE(7b,5b)
-               : "+a" (size), "+a" (to), "+a" (tmp1), "=a" (tmp2)
+               : "+&a" (size), "+&a" (to), "+a" (tmp1), "=&a" (tmp2)
                : "a" (empty_zero_page), [spec] "d" (spec.val)
                : "cc", "memory", "0");
        return size;
index d0846ba818eeaee7e574ff925f64c5365b472be0..6b1876e4ad3f52ca39e7022a0166dda03c61351e 100644 (file)
@@ -539,7 +539,7 @@ static void bpf_jit_plt(void *plt, void *ret, void *target)
 {
        memcpy(plt, bpf_plt, BPF_PLT_SIZE);
        *(void **)((char *)plt + (bpf_plt_ret - bpf_plt)) = ret;
-       *(void **)((char *)plt + (bpf_plt_target - bpf_plt)) = target;
+       *(void **)((char *)plt + (bpf_plt_target - bpf_plt)) = target ?: ret;
 }
 
 /*
@@ -2010,7 +2010,9 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
        } __packed insn;
        char expected_plt[BPF_PLT_SIZE];
        char current_plt[BPF_PLT_SIZE];
+       char new_plt[BPF_PLT_SIZE];
        char *plt;
+       char *ret;
        int err;
 
        /* Verify the branch to be patched. */
@@ -2032,12 +2034,15 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
                err = copy_from_kernel_nofault(current_plt, plt, BPF_PLT_SIZE);
                if (err < 0)
                        return err;
-               bpf_jit_plt(expected_plt, (char *)ip + 6, old_addr);
+               ret = (char *)ip + 6;
+               bpf_jit_plt(expected_plt, ret, old_addr);
                if (memcmp(current_plt, expected_plt, BPF_PLT_SIZE))
                        return -EINVAL;
                /* Adjust the call address. */
+               bpf_jit_plt(new_plt, ret, new_addr);
                s390_kernel_write(plt + (bpf_plt_target - bpf_plt),
-                                 &new_addr, sizeof(void *));
+                                 new_plt + (bpf_plt_target - bpf_plt),
+                                 sizeof(void *));
        }
 
        /* Adjust the mask of the branch. */
index ef38b1514c77aedb56b66f004b5c2a4fcfc23e4f..e16afacc8fd1b97c6eca33d456354c481a307704 100644 (file)
@@ -544,8 +544,7 @@ static struct resource *__alloc_res(struct zpci_dev *zdev, unsigned long start,
        return r;
 }
 
-int zpci_setup_bus_resources(struct zpci_dev *zdev,
-                            struct list_head *resources)
+int zpci_setup_bus_resources(struct zpci_dev *zdev)
 {
        unsigned long addr, size, flags;
        struct resource *res;
@@ -581,7 +580,6 @@ int zpci_setup_bus_resources(struct zpci_dev *zdev,
                        return -ENOMEM;
                }
                zdev->bars[i].res = res;
-               pci_add_resource(resources, res);
        }
        zdev->has_resources = 1;
 
@@ -590,17 +588,23 @@ int zpci_setup_bus_resources(struct zpci_dev *zdev,
 
 static void zpci_cleanup_bus_resources(struct zpci_dev *zdev)
 {
+       struct resource *res;
        int i;
 
+       pci_lock_rescan_remove();
        for (i = 0; i < PCI_STD_NUM_BARS; i++) {
-               if (!zdev->bars[i].size || !zdev->bars[i].res)
+               res = zdev->bars[i].res;
+               if (!res)
                        continue;
 
+               release_resource(res);
+               pci_bus_remove_resource(zdev->zbus->bus, res);
                zpci_free_iomap(zdev, zdev->bars[i].map_idx);
-               release_resource(zdev->bars[i].res);
-               kfree(zdev->bars[i].res);
+               zdev->bars[i].res = NULL;
+               kfree(res);
        }
        zdev->has_resources = 0;
+       pci_unlock_rescan_remove();
 }
 
 int pcibios_device_add(struct pci_dev *pdev)
index 6a8da1b742ae5aa76d08d6abb34e94735bc1f08e..a99926af2b69a352cdd7480ed1f2888f1728a7f9 100644 (file)
@@ -41,9 +41,7 @@ static int zpci_nb_devices;
  */
 static int zpci_bus_prepare_device(struct zpci_dev *zdev)
 {
-       struct resource_entry *window, *n;
-       struct resource *res;
-       int rc;
+       int rc, i;
 
        if (!zdev_enabled(zdev)) {
                rc = zpci_enable_device(zdev);
@@ -57,10 +55,10 @@ static int zpci_bus_prepare_device(struct zpci_dev *zdev)
        }
 
        if (!zdev->has_resources) {
-               zpci_setup_bus_resources(zdev, &zdev->zbus->resources);
-               resource_list_for_each_entry_safe(window, n, &zdev->zbus->resources) {
-                       res = window->res;
-                       pci_bus_add_resource(zdev->zbus->bus, res, 0);
+               zpci_setup_bus_resources(zdev);
+               for (i = 0; i < PCI_STD_NUM_BARS; i++) {
+                       if (zdev->bars[i].res)
+                               pci_bus_add_resource(zdev->zbus->bus, zdev->bars[i].res, 0);
                }
        }
 
index e96c9860e0644b4d1dd144d5c0fccbdf484a60cb..af9f0ac79a1b1b8a249e7a22703f3dec45dcdad8 100644 (file)
@@ -30,8 +30,7 @@ static inline void zpci_zdev_get(struct zpci_dev *zdev)
 
 int zpci_alloc_domain(int domain);
 void zpci_free_domain(int domain);
-int zpci_setup_bus_resources(struct zpci_dev *zdev,
-                            struct list_head *resources);
+int zpci_setup_bus_resources(struct zpci_dev *zdev);
 
 static inline struct zpci_dev *zdev_from_bus(struct pci_bus *bus,
                                             unsigned int devfn)
index fff419f3d7574c16e5f965559ad98d449d5180f1..336c54369636d7290a46cfc5478f94f4a26806c0 100644 (file)
@@ -85,7 +85,7 @@ config CPU_HAS_SR_RB
          that are lacking this bit must have another method in place for
          accomplishing what is taken care of by the banked registers.
 
-         See <file:Documentation/sh/register-banks.rst> for further
+         See <file:Documentation/arch/sh/register-banks.rst> for further
          information on SR.RB and register banking in the kernel in general.
 
 config CPU_HAS_PTEAEX
index 27aebf1e75a2003003cffaf82c43d46b3e206357..3ef7adf739c836d8f742e131daae0c511d3060db 100644 (file)
@@ -50,6 +50,7 @@
 #define SR_FD          0x00008000
 #define SR_MD          0x40000000
 
+#define SR_USER_MASK   0x00000303      // M, Q, S, T bits
 /*
  * DSP structure and data
  */
index 90f495d35db29a7e7b139d4541eb20fe053f02ed..a6bfc6f374911d5ac639030c196bd72ebd19d614 100644 (file)
@@ -115,6 +115,7 @@ static int
 restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p)
 {
        unsigned int err = 0;
+       unsigned int sr = regs->sr & ~SR_USER_MASK;
 
 #define COPY(x)                err |= __get_user(regs->x, &sc->sc_##x)
                        COPY(regs[1]);
@@ -130,6 +131,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p
        COPY(sr);       COPY(pc);
 #undef COPY
 
+       regs->sr = (regs->sr & SR_USER_MASK) | sr;
+
 #ifdef CONFIG_SH_FPU
        if (boot_cpu_data.flags & CPU_HAS_FPU) {
                int owned_fp;
index a825bf031f4957396c8201ff375abeafaceceab2..57a14206ad8f52de38ed2d0bbbac1ed7a86160ac 100644 (file)
@@ -283,7 +283,6 @@ config X86
        select RTC_LIB
        select RTC_MC146818_LIB
        select SPARSE_IRQ
-       select SRCU
        select SYSCTL_EXCEPTION_TRACE
        select THREAD_INFO_IN_TASK
        select TRACE_IRQFLAGS_SUPPORT
@@ -434,7 +433,7 @@ config SMP
          Y to "Enhanced Real Time Clock Support", below. The "Advanced Power
          Management" code will be disabled if you say Y here.
 
-         See also <file:Documentation/x86/i386/IO-APIC.rst>,
+         See also <file:Documentation/arch/x86/i386/IO-APIC.rst>,
          <file:Documentation/admin-guide/lockup-watchdogs.rst> and the SMP-HOWTO available at
          <http://www.tldp.org/docs.html#howto>.
 
@@ -1324,7 +1323,7 @@ config MICROCODE
          the Linux kernel.
 
          The preferred method to load microcode from a detached initrd is described
-         in Documentation/x86/microcode.rst. For that you need to enable
+         in Documentation/arch/x86/microcode.rst. For that you need to enable
          CONFIG_BLK_DEV_INITRD in order for the loader to be able to scan the
          initrd for microcode blobs.
 
@@ -1510,7 +1509,7 @@ config X86_5LEVEL
          A kernel with the option enabled can be booted on machines that
          support 4- or 5-level paging.
 
-         See Documentation/x86/x86_64/5level-paging.rst for more
+         See Documentation/arch/x86/x86_64/5level-paging.rst for more
          information.
 
          Say N if unsure.
@@ -1774,7 +1773,7 @@ config MTRR
          You can safely say Y even if your machine doesn't have MTRRs, you'll
          just add about 9 KB to your kernel.
 
-         See <file:Documentation/x86/mtrr.rst> for more information.
+         See <file:Documentation/arch/x86/mtrr.rst> for more information.
 
 config MTRR_SANITIZER
        def_bool y
@@ -1938,7 +1937,6 @@ config X86_SGX
        depends on X86_64 && CPU_SUP_INTEL && X86_X2APIC
        depends on CRYPTO=y
        depends on CRYPTO_SHA256=y
-       select SRCU
        select MMU_NOTIFIER
        select NUMA_KEEP_MEMINFO if NUMA
        select XARRAY_MULTI
@@ -2551,7 +2549,7 @@ config PAGE_TABLE_ISOLATION
          ensuring that the majority of kernel addresses are not mapped
          into userspace.
 
-         See Documentation/x86/pti.rst for more details.
+         See Documentation/arch/x86/pti.rst for more details.
 
 config RETPOLINE
        bool "Avoid speculative indirect branches in kernel"
index bdfe08f1a9304f8c7c8df77de4665fc07a63c21c..c5d614d28a759954fb6f61965c0ff5f1526ed648 100644 (file)
@@ -97,7 +97,7 @@ config IOMMU_DEBUG
          code. When you use it make sure you have a big enough
          IOMMU/AGP aperture.  Most of the options enabled by this can
          be set more finegrained using the iommu= command line
-         options. See Documentation/x86/x86_64/boot-options.rst for more
+         options. See Documentation/arch/x86/x86_64/boot-options.rst for more
          details.
 
 config IOMMU_LEAK
index b70559b821df80a1737d913c04a434d1b6511f79..2106a2bd152bfaf1edcc7d58ebfcf5548e76d14e 100644 (file)
@@ -3,9 +3,14 @@ core-y += arch/x86/crypto/
 
 #
 # Disable SSE and other FP/SIMD instructions to match normal x86
+# This is required to work around issues in older LLVM versions, but breaks
+# GCC versions < 11. See:
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99652
 #
+ifeq ($(CONFIG_CC_IS_CLANG),y)
 KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx
 KBUILD_RUSTFLAGS += -Ctarget-feature=-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2
+endif
 
 ifeq ($(CONFIG_X86_32),y)
 START := 0x8048000
index 9338c68e7413d6e6ca4c7d2e8eb7ec214e422343..b04ca8e2b213c6e647ad855140682545442321c7 100644 (file)
@@ -321,7 +321,7 @@ start_sys_seg:      .word   SYSSEG          # obsolete and meaningless, but just
 
 type_of_loader:        .byte   0               # 0 means ancient bootloader, newer
                                        # bootloaders know to change this.
-                                       # See Documentation/x86/boot.rst for
+                                       # See Documentation/arch/x86/boot.rst for
                                        # assigned ids
 
 # flags, unused bits must be zero (RFU) bit within loadflags
index eccc3431e515a674b584f2984679aa8140bcc631..d94d361f506f5d4dc505dfa253684c69f6871779 100644 (file)
@@ -8,7 +8,7 @@
  *
  * entry.S contains the system-call and fault low-level handling routines.
  *
- * Some of this is documented in Documentation/x86/entry_64.rst
+ * Some of this is documented in Documentation/arch/x86/entry_64.rst
  *
  * A note on terminology:
  * - iret frame:       Architecture defined interrupt frame from SS to RIP
index 8c45b198b62f555d1565c0d68b38304afe767f7c..bccea57dee81ecd12caac3ecc7a2cbe654d9fe90 100644 (file)
@@ -923,6 +923,7 @@ static int amd_pmu_v2_handle_irq(struct pt_regs *regs)
 
                /* Event overflow */
                handled++;
+               status &= ~mask;
                perf_sample_data_init(&data, 0, hwc->last_period);
 
                if (!x86_perf_event_set_period(event))
@@ -933,8 +934,6 @@ static int amd_pmu_v2_handle_irq(struct pt_regs *regs)
 
                if (perf_event_overflow(event, &data, regs))
                        x86_pmu_stop(event, 0);
-
-               status &= ~mask;
        }
 
        /*
index e2975a32d443fa888a76847c3a8a27597a16a7a8..d7da28fada87a35445c2c9740dda83c589a23de0 100644 (file)
@@ -8,7 +8,7 @@
 
 #define ALT_FLAGS_SHIFT                16
 
-#define ALT_FLAG_NOT           BIT(0)
+#define ALT_FLAG_NOT           (1 << 0)
 #define ALT_NOT(feature)       ((ALT_FLAG_NOT << ALT_FLAGS_SHIFT) | (feature))
 
 #ifndef __ASSEMBLY__
index 53e9b0620d969339a6f1aa890256fc7cc93b2968..d90ae472fb76fdec71fc1f1df9acc134d0f17649 100644 (file)
@@ -38,7 +38,7 @@ static void sanitize_boot_params(struct boot_params *boot_params)
         * IMPORTANT NOTE TO BOOTLOADER AUTHORS: do not simply clear
         * this field.  The purpose of this field is to guarantee
         * compliance with the x86 boot spec located in
-        * Documentation/x86/boot.rst .  That spec says that the
+        * Documentation/arch/x86/boot.rst .  That spec says that the
         * *whole* structure should be cleared, after which only the
         * portion defined by struct setup_header (boot_params->hdr)
         * should be copied in.
index cbaf174d8efd9e73ff8b187cfe338fa6cc1b5b41..b3af2d45bbbb58424e2d34b3887d836470d80d21 100644 (file)
 
 #define INTEL_FAM6_LUNARLAKE_M         0xBD
 
+#define INTEL_FAM6_ARROWLAKE           0xC6
+
 /* "Small Core" Processors (Atom/E-Core) */
 
 #define INTEL_FAM6_ATOM_BONNELL                0x1C /* Diamondville, Pineview */
index e9e2c3ba59239ad4b240a641d07a991957f5ef37..06ef25411d622b9137a5c74e6930d5492ccec6b8 100644 (file)
@@ -49,7 +49,7 @@
 
 #define __START_KERNEL_map     _AC(0xffffffff80000000, UL)
 
-/* See Documentation/x86/x86_64/mm.rst for a description of the memory map. */
+/* See Documentation/arch/x86/x86_64/mm.rst for a description of the memory map. */
 
 #define __PHYSICAL_MASK_SHIFT  52
 
index 38bf837e3554449f21b2384d2b233483573e1565..38b54b992f32e3027c5fa066f9684900fdd348d5 100644 (file)
@@ -104,7 +104,7 @@ extern unsigned int ptrs_per_p4d;
 #define PGDIR_MASK     (~(PGDIR_SIZE - 1))
 
 /*
- * See Documentation/x86/x86_64/mm.rst for a description of the memory map.
+ * See Documentation/arch/x86/x86_64/mm.rst for a description of the memory map.
  *
  * Be very careful vs. KASLR when changing anything here. The KASLR address
  * range must not overlap with anything except the KASAN shadow area, which
index 52788f79786fad74f2c373e5ce7895e79af26942..255a78d9d90672afb053875184d89b05bab52a0b 100644 (file)
@@ -49,7 +49,7 @@ DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key);
  *   simple as possible.
  * Must be called with preemption disabled.
  */
-static void __resctrl_sched_in(void)
+static inline void __resctrl_sched_in(struct task_struct *tsk)
 {
        struct resctrl_pqr_state *state = this_cpu_ptr(&pqr_state);
        u32 closid = state->default_closid;
@@ -61,13 +61,13 @@ static void __resctrl_sched_in(void)
         * Else use the closid/rmid assigned to this cpu.
         */
        if (static_branch_likely(&rdt_alloc_enable_key)) {
-               tmp = READ_ONCE(current->closid);
+               tmp = READ_ONCE(tsk->closid);
                if (tmp)
                        closid = tmp;
        }
 
        if (static_branch_likely(&rdt_mon_enable_key)) {
-               tmp = READ_ONCE(current->rmid);
+               tmp = READ_ONCE(tsk->rmid);
                if (tmp)
                        rmid = tmp;
        }
@@ -88,17 +88,17 @@ static inline unsigned int resctrl_arch_round_mon_val(unsigned int val)
        return val * scale;
 }
 
-static inline void resctrl_sched_in(void)
+static inline void resctrl_sched_in(struct task_struct *tsk)
 {
        if (static_branch_likely(&rdt_enable_key))
-               __resctrl_sched_in();
+               __resctrl_sched_in(tsk);
 }
 
 void resctrl_cpu_detect(struct cpuinfo_x86 *c);
 
 #else
 
-static inline void resctrl_sched_in(void) {}
+static inline void resctrl_sched_in(struct task_struct *tsk) {}
 static inline void resctrl_cpu_detect(struct cpuinfo_x86 *c) {}
 
 #endif /* CONFIG_X86_CPU_RESCTRL */
index b8357d6ecd47ef6766a0fe9fe5161f6447228c16..b63be696b776a7d764359cb990533871d910197d 100644 (file)
@@ -128,8 +128,9 @@ struct snp_psc_desc {
        struct psc_entry entries[VMGEXIT_PSC_MAX_ENTRY];
 } __packed;
 
-/* Guest message request error code */
+/* Guest message request error codes */
 #define SNP_GUEST_REQ_INVALID_LEN      BIT_ULL(32)
+#define SNP_GUEST_REQ_ERR_BUSY         BIT_ULL(33)
 
 #define GHCB_MSR_TERM_REQ              0x100
 #define GHCB_MSR_TERM_REASON_SET_POS   12
index cb1ee53ad3b18900a6945b11bb4e267d5d77cd6e..770dcf75eaa97e0c3c8cc191d88bd9e8a9fc1d34 100644 (file)
@@ -261,20 +261,22 @@ enum avic_ipi_failure_cause {
        AVIC_IPI_FAILURE_INVALID_BACKING_PAGE,
 };
 
-#define AVIC_PHYSICAL_MAX_INDEX_MASK   GENMASK_ULL(9, 0)
+#define AVIC_PHYSICAL_MAX_INDEX_MASK   GENMASK_ULL(8, 0)
 
 /*
- * For AVIC, the max index allowed for physical APIC ID
- * table is 0xff (255).
+ * For AVIC, the max index allowed for physical APIC ID table is 0xfe (254), as
+ * 0xff is a broadcast to all CPUs, i.e. can't be targeted individually.
  */
 #define AVIC_MAX_PHYSICAL_ID           0XFEULL
 
 /*
- * For x2AVIC, the max index allowed for physical APIC ID
- * table is 0x1ff (511).
+ * For x2AVIC, the max index allowed for physical APIC ID table is 0x1ff (511).
  */
 #define X2AVIC_MAX_PHYSICAL_ID         0x1FFUL
 
+static_assert((AVIC_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == AVIC_MAX_PHYSICAL_ID);
+static_assert((X2AVIC_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == X2AVIC_MAX_PHYSICAL_ID);
+
 #define AVIC_HPA_MASK  ~((0xFFFULL << 52) | 0xFFF)
 #define VMCB_AVIC_APIC_BAR_MASK                0xFFFFFFFFFF000ULL
 
index d13d71af5cf61045147d84ea66703ec44ee3da82..0a49a8de9f3c458ffd41fa5c4cf1a7ae3a1b47b3 100644 (file)
 
 /* Handles exceptions in both to and from, but doesn't do access_ok */
 __must_check unsigned long
-copy_user_enhanced_fast_string(void *to, const void *from, unsigned len);
-__must_check unsigned long
-copy_user_generic_string(void *to, const void *from, unsigned len);
-__must_check unsigned long
-copy_user_generic_unrolled(void *to, const void *from, unsigned len);
+rep_movs_alternative(void *to, const void *from, unsigned len);
 
 static __always_inline __must_check unsigned long
-copy_user_generic(void *to, const void *from, unsigned len)
+copy_user_generic(void *to, const void *from, unsigned long len)
 {
-       unsigned ret;
-
+       stac();
        /*
-        * If CPU has ERMS feature, use copy_user_enhanced_fast_string.
-        * Otherwise, if CPU has rep_good feature, use copy_user_generic_string.
-        * Otherwise, use copy_user_generic_unrolled.
+        * If CPU has FSRM feature, use 'rep movs'.
+        * Otherwise, use rep_movs_alternative.
         */
-       alternative_call_2(copy_user_generic_unrolled,
-                        copy_user_generic_string,
-                        X86_FEATURE_REP_GOOD,
-                        copy_user_enhanced_fast_string,
-                        X86_FEATURE_ERMS,
-                        ASM_OUTPUT2("=a" (ret), "=D" (to), "=S" (from),
-                                    "=d" (len)),
-                        "1" (to), "2" (from), "3" (len)
-                        : "memory", "rcx", "r8", "r9", "r10", "r11");
-       return ret;
+       asm volatile(
+               "1:\n\t"
+               ALTERNATIVE("rep movsb",
+                           "call rep_movs_alternative", ALT_NOT(X86_FEATURE_FSRM))
+               "2:\n"
+               _ASM_EXTABLE_UA(1b, 2b)
+               :"+c" (len), "+D" (to), "+S" (from), ASM_CALL_CONSTRAINT
+               : : "memory", "rax", "r8", "r9", "r10", "r11");
+       clac();
+       return len;
 }
 
 static __always_inline __must_check unsigned long
@@ -58,9 +52,7 @@ raw_copy_to_user(void __user *dst, const void *src, unsigned long size)
        return copy_user_generic((__force void *)dst, src, size);
 }
 
-extern long __copy_user_nocache(void *dst, const void __user *src,
-                               unsigned size, int zerorest);
-
+extern long __copy_user_nocache(void *dst, const void __user *src, unsigned size);
 extern long __copy_user_flushcache(void *dst, const void __user *src, unsigned size);
 extern void memcpy_page_flushcache(char *to, struct page *page, size_t offset,
                           size_t len);
@@ -69,8 +61,12 @@ static inline int
 __copy_from_user_inatomic_nocache(void *dst, const void __user *src,
                                  unsigned size)
 {
+       long ret;
        kasan_check_write(dst, size);
-       return __copy_user_nocache(dst, src, size, 0);
+       stac();
+       ret = __copy_user_nocache(dst, src, size);
+       clac();
+       return ret;
 }
 
 static inline int
@@ -85,11 +81,7 @@ __copy_from_user_flushcache(void *dst, const void __user *src, unsigned size)
  */
 
 __must_check unsigned long
-clear_user_original(void __user *addr, unsigned long len);
-__must_check unsigned long
-clear_user_rep_good(void __user *addr, unsigned long len);
-__must_check unsigned long
-clear_user_erms(void __user *addr, unsigned long len);
+rep_stos_alternative(void __user *addr, unsigned long len);
 
 static __always_inline __must_check unsigned long __clear_user(void __user *addr, unsigned long size)
 {
@@ -102,16 +94,12 @@ static __always_inline __must_check unsigned long __clear_user(void __user *addr
         */
        asm volatile(
                "1:\n\t"
-               ALTERNATIVE_3("rep stosb",
-                             "call clear_user_erms",     ALT_NOT(X86_FEATURE_FSRM),
-                             "call clear_user_rep_good", ALT_NOT(X86_FEATURE_ERMS),
-                             "call clear_user_original", ALT_NOT(X86_FEATURE_REP_GOOD))
+               ALTERNATIVE("rep stosb",
+                           "call rep_stos_alternative", ALT_NOT(X86_FEATURE_FSRS))
                "2:\n"
               _ASM_EXTABLE_UA(1b, 2b)
               : "+c" (size), "+D" (addr), ASM_CALL_CONSTRAINT
-              : "a" (0)
-               /* rep_good clobbers %rdx */
-              : "rdx");
+              : "a" (0));
 
        clac();
 
index 6daa9b0c8d11474b73ebd63b703fc60ef8972ba3..a3c29b1496c8353eca2f6dd13db042018fa25e51 100644 (file)
  * Sub-leaf 2: EAX: host tsc frequency in kHz
  */
 
+#define XEN_CPUID_TSC_EMULATED               (1u << 0)
+#define XEN_CPUID_HOST_TSC_RELIABLE          (1u << 1)
+#define XEN_CPUID_RDTSCP_INSTR_AVAIL         (1u << 2)
+
+#define XEN_CPUID_TSC_MODE_DEFAULT           (0)
+#define XEN_CPUID_TSC_MODE_ALWAYS_EMULATE    (1u)
+#define XEN_CPUID_TSC_MODE_NEVER_EMULATE     (2u)
+#define XEN_CPUID_TSC_MODE_PVRDTSCP          (3u)
+
 /*
  * Leaf 5 (0x40000x04)
  * HVM-specific features
  * Sub-leaf 0: EAX: Features
  * Sub-leaf 0: EBX: vcpu id (iff EAX has XEN_HVM_CPUID_VCPU_ID_PRESENT flag)
+ * Sub-leaf 0: ECX: domain id (iff EAX has XEN_HVM_CPUID_DOMID_PRESENT flag)
  */
 #define XEN_HVM_CPUID_APIC_ACCESS_VIRT (1u << 0) /* Virtualized APIC registers */
 #define XEN_HVM_CPUID_X2APIC_VIRT      (1u << 1) /* Virtualized x2APIC accesses */
 #define XEN_HVM_CPUID_VCPU_ID_PRESENT  (1u << 3) /* vcpu id is present in EBX */
 #define XEN_HVM_CPUID_DOMID_PRESENT    (1u << 4) /* domid is present in ECX */
 /*
- * Bits 55:49 from the IO-APIC RTE and bits 11:5 from the MSI address can be
- * used to store high bits for the Destination ID. This expands the Destination
- * ID field from 8 to 15 bits, allowing to target APIC IDs up 32768.
+ * With interrupt format set to 0 (non-remappable) bits 55:49 from the
+ * IO-APIC RTE and bits 11:5 from the MSI address can be used to store
+ * high bits for the Destination ID. This expands the Destination ID
+ * field from 8 to 15 bits, allowing to target APIC IDs up 32768.
  */
 #define XEN_HVM_CPUID_EXT_DEST_ID      (1u << 5)
-/* Per-vCPU event channel upcalls */
+/*
+ * Per-vCPU event channel upcalls work correctly with physical IRQs
+ * bound to event channels.
+ */
 #define XEN_HVM_CPUID_UPCALL_VECTOR    (1u << 6)
 
 /*
index 1c38174b5f0197355a96135b03858d6bebe3e84a..0dac4ab5b55baeac5d3f29d7e9727d1a30d844f7 100644 (file)
@@ -146,7 +146,11 @@ static int __init acpi_parse_madt(struct acpi_table_header *table)
 
                pr_debug("Local APIC address 0x%08x\n", madt->address);
        }
-       if (madt->header.revision >= 5)
+
+       /* ACPI 6.3 and newer support the online capable bit. */
+       if (acpi_gbl_FADT.header.revision > 6 ||
+           (acpi_gbl_FADT.header.revision == 6 &&
+            acpi_gbl_FADT.minor_revision >= 3))
                acpi_support_online_capable = true;
 
        default_acpi_madt_oem_check(madt->header.oem_id,
@@ -193,7 +197,8 @@ static bool __init acpi_is_processor_usable(u32 lapic_flags)
        if (lapic_flags & ACPI_MADT_ENABLED)
                return true;
 
-       if (acpi_support_online_capable && (lapic_flags & ACPI_MADT_ONLINE_CAPABLE))
+       if (!acpi_support_online_capable ||
+           (lapic_flags & ACPI_MADT_ONLINE_CAPABLE))
                return true;
 
        return false;
index 380753b14cab0751310c8bd1e9f1a2970ee39478..1547781e505b46815c59249dc2300bbf5c7fae73 100644 (file)
@@ -880,6 +880,15 @@ void init_spectral_chicken(struct cpuinfo_x86 *c)
                }
        }
 #endif
+       /*
+        * Work around Erratum 1386.  The XSAVES instruction malfunctions in
+        * certain circumstances on Zen1/2 uarch, and not all parts have had
+        * updated microcode at the time of writing (March 2023).
+        *
+        * Affected parts all have no supervisor XSAVE states, meaning that
+        * the XSAVEC instruction (which works fine) is equivalent.
+        */
+       clear_cpu_cap(c, X86_FEATURE_XSAVES);
 }
 
 static void init_amd_zn(struct cpuinfo_x86 *c)
@@ -920,6 +929,10 @@ static void init_amd(struct cpuinfo_x86 *c)
        if (c->x86 >= 0x10)
                set_cpu_cap(c, X86_FEATURE_REP_GOOD);
 
+       /* AMD FSRM also implies FSRS */
+       if (cpu_has(c, X86_FEATURE_FSRM))
+               set_cpu_cap(c, X86_FEATURE_FSRS);
+
        /* get apicid instead of initial apic id from cpuid */
        c->apicid = hard_smp_processor_id();
 
index 7832a69d170e723c1088098606d9f7b9796d1a94..2eec60f50057a7204ea9e36e208d2637614de06d 100644 (file)
@@ -2355,6 +2355,7 @@ static void mce_restart(void)
 {
        mce_timer_delete_all();
        on_each_cpu(mce_cpu_restart, NULL, 1);
+       mce_schedule_work();
 }
 
 /* Toggle features for corrected errors */
index 9eb457b1034133dc03d5560f4c82053bbdc4816c..f5fdeb1e3606ec3ce989624d513a459f3fd3d04a 100644 (file)
@@ -61,7 +61,7 @@ static u8 amd_ucode_patch[MAX_NUMNODES][PATCH_MAX_SIZE];
 
 /*
  * Microcode patch container file is prepended to the initrd in cpio
- * format. See Documentation/x86/microcode.rst
+ * format. See Documentation/arch/x86/microcode.rst
  */
 static const char
 ucode_path[] __maybe_unused = "kernel/x86/microcode/AuthenticAMD.bin";
index f36dc2f796c5c0eca284a9d58c8139d2a108472f..f1197366a97dc44278d6fa829df7c15eec16bd65 100644 (file)
@@ -358,12 +358,16 @@ static void __init ms_hyperv_init_platform(void)
         * To mirror what Windows does we should extract CPU management
         * features and use the ReservedIdentityBit to detect if Linux is the
         * root partition. But that requires negotiating CPU management
-        * interface (a process to be finalized).
+        * interface (a process to be finalized). For now, use the privilege
+        * flag as the indicator for running as root.
         *
-        * For now, use the privilege flag as the indicator for running as
-        * root.
+        * Hyper-V should never specify running as root and as a Confidential
+        * VM. But to protect against a compromised/malicious Hyper-V trying
+        * to exploit root behavior to expose Confidential VM memory, ignore
+        * the root partition setting if also a Confidential VM.
         */
-       if (cpuid_ebx(HYPERV_CPUID_FEATURES) & HV_CPU_MANAGEMENT) {
+       if ((ms_hyperv.priv_high & HV_CPU_MANAGEMENT) &&
+           !(ms_hyperv.priv_high & HV_ISOLATION)) {
                hv_root_partition = true;
                pr_info("Hyper-V: running as root partition\n");
        }
index eb07d4435391bedc4db1a2d6483bda477c093bea..b44c487727d456e445a4ad53ddaff76d84e449b1 100644 (file)
@@ -368,7 +368,6 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
 {
        struct resctrl_schema *s;
        struct rdtgroup *rdtgrp;
-       struct rdt_domain *dom;
        struct rdt_resource *r;
        char *tok, *resname;
        int ret = 0;
@@ -397,10 +396,7 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
                goto out;
        }
 
-       list_for_each_entry(s, &resctrl_schema_all, list) {
-               list_for_each_entry(dom, &s->res->domains, list)
-                       memset(dom->staged_config, 0, sizeof(dom->staged_config));
-       }
+       rdt_staged_configs_clear();
 
        while ((tok = strsep(&buf, "\n")) != NULL) {
                resname = strim(strsep(&tok, ":"));
@@ -445,6 +441,7 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
        }
 
 out:
+       rdt_staged_configs_clear();
        rdtgroup_kn_unlock(of->kn);
        cpus_read_unlock();
        return ret ?: nbytes;
index 8edecc5763d8e31313294145b7e0af8a6e477611..85ceaf9a31ac20099c86647b4958e4ca0f28fa6b 100644 (file)
@@ -555,5 +555,6 @@ void __check_limbo(struct rdt_domain *d, bool force_free);
 void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
 void __init thread_throttle_mode_init(void);
 void __init mbm_config_rftype_init(const char *config);
+void rdt_staged_configs_clear(void);
 
 #endif /* _ASM_X86_RESCTRL_INTERNAL_H */
index 7fe51488e136ab7b6c320589ca09c5dd1d37ed0b..0e7b6afe2fa682097f6d463a0f5e4148e9940599 100644 (file)
@@ -76,7 +76,7 @@ unsigned int resctrl_rmid_realloc_limit;
 #define CF(cf) ((unsigned long)(1048576 * (cf) + 0.5))
 
 /*
- * The correction factor table is documented in Documentation/x86/resctrl.rst.
+ * The correction factor table is documented in Documentation/arch/x86/resctrl.rst.
  * If rmid > rmid threshold, MBM total and local values should be multiplied
  * by the correction factor.
  *
index e2c1599d1b373d8ff9fb4d0af5e1e6d4787bfded..6ad33f355861feab9a1f013ff82e026e9638044b 100644 (file)
@@ -78,6 +78,19 @@ void rdt_last_cmd_printf(const char *fmt, ...)
        va_end(ap);
 }
 
+void rdt_staged_configs_clear(void)
+{
+       struct rdt_resource *r;
+       struct rdt_domain *dom;
+
+       lockdep_assert_held(&rdtgroup_mutex);
+
+       for_each_alloc_capable_rdt_resource(r) {
+               list_for_each_entry(dom, &r->domains, list)
+                       memset(dom->staged_config, 0, sizeof(dom->staged_config));
+       }
+}
+
 /*
  * Trivial allocator for CLOSIDs. Since h/w only supports a small number,
  * we can keep a bitmap of free CLOSIDs in a single integer.
@@ -314,7 +327,7 @@ static void update_cpu_closid_rmid(void *info)
         * executing task might have its own closid selected. Just reuse
         * the context switch code.
         */
-       resctrl_sched_in();
+       resctrl_sched_in(current);
 }
 
 /*
@@ -530,7 +543,7 @@ static void _update_task_closid_rmid(void *task)
         * Otherwise, the MSR is updated when the task is scheduled in.
         */
        if (task == current)
-               resctrl_sched_in();
+               resctrl_sched_in(task);
 }
 
 static void update_task_closid_rmid(struct task_struct *t)
@@ -3107,7 +3120,9 @@ static int rdtgroup_init_alloc(struct rdtgroup *rdtgrp)
 {
        struct resctrl_schema *s;
        struct rdt_resource *r;
-       int ret;
+       int ret = 0;
+
+       rdt_staged_configs_clear();
 
        list_for_each_entry(s, &resctrl_schema_all, list) {
                r = s->res;
@@ -3119,20 +3134,22 @@ static int rdtgroup_init_alloc(struct rdtgroup *rdtgrp)
                } else {
                        ret = rdtgroup_init_cat(s, rdtgrp->closid);
                        if (ret < 0)
-                               return ret;
+                               goto out;
                }
 
                ret = resctrl_arch_update_domains(r, rdtgrp->closid);
                if (ret < 0) {
                        rdt_last_cmd_puts("Failed to initialize allocations\n");
-                       return ret;
+                       goto out;
                }
 
        }
 
        rdtgrp->mode = RDT_MODE_SHAREABLE;
 
-       return 0;
+out:
+       rdt_staged_configs_clear();
+       return ret;
 }
 
 static int mkdir_rdt_prepare(struct kernfs_node *parent_kn,
index e5a37b6e9aa585df3a91abfef9b6231f61940363..166692f2d501112a887106971212cc1b8e6c2856 100644 (file)
@@ -892,20 +892,19 @@ static struct miscdevice sgx_dev_provision = {
 int sgx_set_attribute(unsigned long *allowed_attributes,
                      unsigned int attribute_fd)
 {
-       struct file *file;
+       struct fd f = fdget(attribute_fd);
 
-       file = fget(attribute_fd);
-       if (!file)
+       if (!f.file)
                return -EINVAL;
 
-       if (file->f_op != &sgx_provision_fops) {
-               fput(file);
+       if (f.file->f_op != &sgx_provision_fops) {
+               fdput(f);
                return -EINVAL;
        }
 
        *allowed_attributes |= SGX_ATTR_PROVISIONKEY;
 
-       fput(file);
+       fdput(f);
        return 0;
 }
 EXPORT_SYMBOL_GPL(sgx_set_attribute);
index 0f2020653fba05544f1477ba5871c18a991e924e..d2dad21259a8d2d4cf06d4d908690625501fdab3 100644 (file)
@@ -15,7 +15,7 @@
 
 #define EREMOVE_ERROR_MESSAGE \
        "EREMOVE returned %d (0x%x) and an EPC page was leaked. SGX may become unusable. " \
-       "Refer to Documentation/x86/sgx.rst for more information."
+       "Refer to Documentation/arch/x86/sgx.rst for more information."
 
 #define SGX_MAX_EPC_SECTIONS           8
 #define SGX_EEXTEND_BLOCK_SIZE         256
index 714166cc25f2f6bff10cffd2dee9d40a2fca9db8..0bab497c94369428ceb247f8de26582b7716ce84 100644 (file)
@@ -1118,21 +1118,20 @@ void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate,
        zerofrom = offsetof(struct xregs_state, extended_state_area);
 
        /*
-        * The ptrace buffer is in non-compacted XSAVE format.  In
-        * non-compacted format disabled features still occupy state space,
-        * but there is no state to copy from in the compacted
-        * init_fpstate. The gap tracking will zero these states.
-        */
-       mask = fpstate->user_xfeatures;
-
-       /*
-        * Dynamic features are not present in init_fpstate. When they are
-        * in an all zeros init state, remove those from 'mask' to zero
-        * those features in the user buffer instead of retrieving them
-        * from init_fpstate.
+        * This 'mask' indicates which states to copy from fpstate.
+        * Those extended states that are not present in fpstate are
+        * either disabled or initialized:
+        *
+        * In non-compacted format, disabled features still occupy
+        * state space but there is no state to copy from in the
+        * compacted init_fpstate. The gap tracking will zero these
+        * states.
+        *
+        * The extended features have an all zeroes init state. Thus,
+        * remove them from 'mask' to zero those features in the user
+        * buffer instead of retrieving them from init_fpstate.
         */
-       if (fpu_state_size_dynamic())
-               mask &= (header.xfeatures | xinit->header.xcomp_bv);
+       mask = header.xfeatures;
 
        for_each_extended_xfeature(i, mask) {
                /*
@@ -1151,9 +1150,8 @@ void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate,
                        pkru.pkru = pkru_val;
                        membuf_write(&to, &pkru, sizeof(pkru));
                } else {
-                       copy_feature(header.xfeatures & BIT_ULL(i), &to,
+                       membuf_write(&to,
                                     __raw_xsave_addr(xsave, i),
-                                    __raw_xsave_addr(xinit, i),
                                     xstate_sizes[i]);
                }
                /*
index 1265ad519249c027cae82d8941d394b8dbc50795..fb4f1e01b64a28af7b85ff26fa8edac39ce67bd6 100644 (file)
@@ -136,10 +136,12 @@ SYM_TYPED_FUNC_START(ftrace_stub)
        RET
 SYM_FUNC_END(ftrace_stub)
 
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
 SYM_TYPED_FUNC_START(ftrace_stub_graph)
        CALL_DEPTH_ACCOUNT
        RET
 SYM_FUNC_END(ftrace_stub_graph)
+#endif
 
 #ifdef CONFIG_DYNAMIC_FTRACE
 
index 6b58610a15521da6323b856e14f7dbe8bcb3ed28..a61c12c012709799ba0b2e1f11295b0861a96122 100644 (file)
@@ -476,7 +476,7 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
        efi_map_offset = params_cmdline_sz;
        efi_setup_data_offset = efi_map_offset + ALIGN(efi_map_sz, 16);
 
-       /* Copy setup header onto bootparams. Documentation/x86/boot.rst */
+       /* Copy setup header onto bootparams. Documentation/arch/x86/boot.rst */
        setup_header_size = 0x0202 + kernel[0x0201] - setup_hdr_offset;
 
        /* Is there a limit on setup header size? */
index 30bbe4abb5d615a91c1a6939700cf06defe390df..de6be0a3965ee4cc5cdd1e42f1042eab71f30c7e 100644 (file)
@@ -124,7 +124,7 @@ void __init pci_iommu_alloc(void)
 }
 
 /*
- * See <Documentation/x86/x86_64/boot-options.rst> for the iommu kernel
+ * See <Documentation/arch/x86/x86_64/boot-options.rst> for the iommu kernel
  * parameter documentation.
  */
 static __init int iommu_setup(char *p)
index 470c128759eab3c82b05539f13e204354452cdc1..708c87b88cc150ee64145de90de938e0482afa3f 100644 (file)
@@ -212,7 +212,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
        switch_fpu_finish();
 
        /* Load the Intel cache allocation PQR MSR. */
-       resctrl_sched_in();
+       resctrl_sched_in(next_p);
 
        return prev_p;
 }
index 4e34b3b68ebdc96a76c9bf265415ecac3a5314a8..bb65a68b4b49968c6d33ea9324b37c3a242e1458 100644 (file)
@@ -656,7 +656,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
        }
 
        /* Load the Intel cache allocation PQR MSR. */
-       resctrl_sched_in();
+       resctrl_sched_in(next_p);
 
        return prev_p;
 }
index 679026a640efd8e2e87a03d3b5e57cf18de1a6dd..3f664ab277c4987ac57f41959a300f3a8f5c6439 100644 (file)
@@ -2183,9 +2183,6 @@ int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned
        struct ghcb *ghcb;
        int ret;
 
-       if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
-               return -ENODEV;
-
        if (!fw_err)
                return -EINVAL;
 
@@ -2212,15 +2209,26 @@ int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned
        if (ret)
                goto e_put;
 
-       if (ghcb->save.sw_exit_info_2) {
-               /* Number of expected pages are returned in RBX */
-               if (exit_code == SVM_VMGEXIT_EXT_GUEST_REQUEST &&
-                   ghcb->save.sw_exit_info_2 == SNP_GUEST_REQ_INVALID_LEN)
-                       input->data_npages = ghcb_get_rbx(ghcb);
+       *fw_err = ghcb->save.sw_exit_info_2;
+       switch (*fw_err) {
+       case 0:
+               break;
 
-               *fw_err = ghcb->save.sw_exit_info_2;
+       case SNP_GUEST_REQ_ERR_BUSY:
+               ret = -EAGAIN;
+               break;
 
+       case SNP_GUEST_REQ_INVALID_LEN:
+               /* Number of expected pages are returned in RBX */
+               if (exit_code == SVM_VMGEXIT_EXT_GUEST_REQUEST) {
+                       input->data_npages = ghcb_get_rbx(ghcb);
+                       ret = -ENOSPC;
+                       break;
+               }
+               fallthrough;
+       default:
                ret = -EIO;
+               break;
        }
 
 e_put:
index ef80d361b4632ec64bb8aacd0f0bf6e88acb1021..10622cf2b30f4335f8b8a8bb0e9a8056065b823d 100644 (file)
@@ -33,8 +33,8 @@ static int __init iommu_init_noop(void) { return 0; }
 static void iommu_shutdown_noop(void) { }
 bool __init bool_x86_init_noop(void) { return false; }
 void x86_op_int_noop(int cpu) { }
-static __init int set_rtc_noop(const struct timespec64 *now) { return -EINVAL; }
-static __init void get_rtc_noop(struct timespec64 *now) { }
+static int set_rtc_noop(const struct timespec64 *now) { return -EINVAL; }
+static void get_rtc_noop(struct timespec64 *now) { }
 
 static __initconst const struct of_device_id of_cmos_match[] = {
        { .compatible = "motorola,mc146818" },
index 8e578311ca9d4d1e24302d471eab0bdb4d40535f..89ca7f4c1464337bd42646caa24d37c3df2464d3 100644 (file)
@@ -46,7 +46,6 @@ config KVM
        select KVM_XFER_TO_GUEST_WORK
        select KVM_GENERIC_DIRTYLOG_READ_PROTECT
        select KVM_VFIO
-       select SRCU
        select INTERVAL_TREE
        select HAVE_KVM_PM_NOTIFIER if PM
        select KVM_GENERIC_HARDWARE_ENABLING
index 042dee5561258f166f289276be3376d6130c4a0c..995eb50543601f70f8162ef1dfc2a79f6d21d032 100644 (file)
@@ -368,9 +368,39 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
                mask_after = e->fields.mask;
                if (mask_before != mask_after)
                        kvm_fire_mask_notifiers(ioapic->kvm, KVM_IRQCHIP_IOAPIC, index, mask_after);
-               if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG
-                   && ioapic->irr & (1 << index))
-                       ioapic_service(ioapic, index, false);
+               if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG &&
+                   ioapic->irr & (1 << index) && !e->fields.mask && !e->fields.remote_irr) {
+                       /*
+                        * Pending status in irr may be outdated: the IRQ line may have
+                        * already been deasserted by a device while the IRQ was masked.
+                        * This occurs, for instance, if the interrupt is handled in a
+                        * Linux guest as a oneshot interrupt (IRQF_ONESHOT). In this
+                        * case the guest acknowledges the interrupt to the device in
+                        * its threaded irq handler, i.e. after the EOI but before
+                        * unmasking, so at the time of unmasking the IRQ line is
+                        * already down but our pending irr bit is still set. In such
+                        * cases, injecting this pending interrupt to the guest is
+                        * buggy: the guest will receive an extra unwanted interrupt.
+                        *
+                        * So we need to check here if the IRQ is actually still pending.
+                        * As we are generally not able to probe the IRQ line status
+                        * directly, we do it through irqfd resampler. Namely, we clear
+                        * the pending status and notify the resampler that this interrupt
+                        * is done, without actually injecting it into the guest. If the
+                        * IRQ line is actually already deasserted, we are done. If it is
+                        * still asserted, a new interrupt will be shortly triggered
+                        * through irqfd and injected into the guest.
+                        *
+                        * If, however, it's not possible to resample (no irqfd resampler
+                        * registered for this irq), then unconditionally inject this
+                        * pending interrupt into the guest, so the guest will not miss
+                        * an interrupt, although may get an extra unwanted interrupt.
+                        */
+                       if (kvm_notify_irqfd_resampler(ioapic->kvm, KVM_IRQCHIP_IOAPIC, index))
+                               ioapic->irr &= ~(1 << index);
+                       else
+                               ioapic_service(ioapic, index, false);
+               }
                if (e->fields.delivery_mode == APIC_DM_FIXED) {
                        struct kvm_lapic_irq irq;
 
index 287e98ef9df3d820244133f4aa73547abe613f1d..6272dabec02da8ae81aaf39fe5165d5b3c225f7b 100644 (file)
@@ -12,6 +12,11 @@ int hv_remote_flush_tlb_with_range(struct kvm *kvm,
 int hv_remote_flush_tlb(struct kvm *kvm);
 void hv_track_root_tdp(struct kvm_vcpu *vcpu, hpa_t root_tdp);
 #else /* !CONFIG_HYPERV */
+static inline int hv_remote_flush_tlb(struct kvm *kvm)
+{
+       return -EOPNOTSUPP;
+}
+
 static inline void hv_track_root_tdp(struct kvm_vcpu *vcpu, hpa_t root_tdp)
 {
 }
index ca684979e90d65e27a9fc250326e2d947e6c4a82..cfc8ab7730250598cf0f29be7bacfe5e49a82424 100644 (file)
 #include "irq.h"
 #include "svm.h"
 
-/* AVIC GATAG is encoded using VM and VCPU IDs */
-#define AVIC_VCPU_ID_BITS              8
-#define AVIC_VCPU_ID_MASK              ((1 << AVIC_VCPU_ID_BITS) - 1)
+/*
+ * Encode the arbitrary VM ID and the vCPU's default APIC ID, i.e the vCPU ID,
+ * into the GATag so that KVM can retrieve the correct vCPU from a GALog entry
+ * if an interrupt can't be delivered, e.g. because the vCPU isn't running.
+ *
+ * For the vCPU ID, use however many bits are currently allowed for the max
+ * guest physical APIC ID (limited by the size of the physical ID table), and
+ * use whatever bits remain to assign arbitrary AVIC IDs to VMs.  Note, the
+ * size of the GATag is defined by hardware (32 bits), but is an opaque value
+ * as far as hardware is concerned.
+ */
+#define AVIC_VCPU_ID_MASK              AVIC_PHYSICAL_MAX_INDEX_MASK
 
-#define AVIC_VM_ID_BITS                        24
-#define AVIC_VM_ID_NR                  (1 << AVIC_VM_ID_BITS)
-#define AVIC_VM_ID_MASK                        ((1 << AVIC_VM_ID_BITS) - 1)
+#define AVIC_VM_ID_SHIFT               HWEIGHT32(AVIC_PHYSICAL_MAX_INDEX_MASK)
+#define AVIC_VM_ID_MASK                        (GENMASK(31, AVIC_VM_ID_SHIFT) >> AVIC_VM_ID_SHIFT)
 
-#define AVIC_GATAG(x, y)               (((x & AVIC_VM_ID_MASK) << AVIC_VCPU_ID_BITS) | \
-                                               (y & AVIC_VCPU_ID_MASK))
-#define AVIC_GATAG_TO_VMID(x)          ((x >> AVIC_VCPU_ID_BITS) & AVIC_VM_ID_MASK)
+#define AVIC_GATAG_TO_VMID(x)          ((x >> AVIC_VM_ID_SHIFT) & AVIC_VM_ID_MASK)
 #define AVIC_GATAG_TO_VCPUID(x)                (x & AVIC_VCPU_ID_MASK)
 
+#define __AVIC_GATAG(vm_id, vcpu_id)   ((((vm_id) & AVIC_VM_ID_MASK) << AVIC_VM_ID_SHIFT) | \
+                                        ((vcpu_id) & AVIC_VCPU_ID_MASK))
+#define AVIC_GATAG(vm_id, vcpu_id)                                     \
+({                                                                     \
+       u32 ga_tag = __AVIC_GATAG(vm_id, vcpu_id);                      \
+                                                                       \
+       WARN_ON_ONCE(AVIC_GATAG_TO_VCPUID(ga_tag) != (vcpu_id));        \
+       WARN_ON_ONCE(AVIC_GATAG_TO_VMID(ga_tag) != (vm_id));            \
+       ga_tag;                                                         \
+})
+
+static_assert(__AVIC_GATAG(AVIC_VM_ID_MASK, AVIC_VCPU_ID_MASK) == -1u);
+
 static bool force_avic;
 module_param_unsafe(force_avic, bool, 0444);
 
index c25aeb550cd97fbbbae82e7f1b95a5d0f8bc8add..52398d49bc2f54f50f7dd0e9a461d16843b703a0 100644 (file)
@@ -1767,18 +1767,20 @@ int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd)
 {
        struct kvm_sev_info *dst_sev = &to_kvm_svm(kvm)->sev_info;
        struct kvm_sev_info *src_sev, *cg_cleanup_sev;
-       struct file *source_kvm_file;
+       struct fd f = fdget(source_fd);
        struct kvm *source_kvm;
        bool charged = false;
        int ret;
 
-       source_kvm_file = fget(source_fd);
-       if (!file_is_kvm(source_kvm_file)) {
+       if (!f.file)
+               return -EBADF;
+
+       if (!file_is_kvm(f.file)) {
                ret = -EBADF;
                goto out_fput;
        }
 
-       source_kvm = source_kvm_file->private_data;
+       source_kvm = f.file->private_data;
        ret = sev_lock_two_vms(kvm, source_kvm);
        if (ret)
                goto out_fput;
@@ -1828,8 +1830,7 @@ out_dst_cgroup:
 out_unlock:
        sev_unlock_two_vms(kvm, source_kvm);
 out_fput:
-       if (source_kvm_file)
-               fput(source_kvm_file);
+       fdput(f);
        return ret;
 }
 
@@ -2046,18 +2047,20 @@ failed:
 
 int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd)
 {
-       struct file *source_kvm_file;
+       struct fd f = fdget(source_fd);
        struct kvm *source_kvm;
        struct kvm_sev_info *source_sev, *mirror_sev;
        int ret;
 
-       source_kvm_file = fget(source_fd);
-       if (!file_is_kvm(source_kvm_file)) {
+       if (!f.file)
+               return -EBADF;
+
+       if (!file_is_kvm(f.file)) {
                ret = -EBADF;
                goto e_source_fput;
        }
 
-       source_kvm = source_kvm_file->private_data;
+       source_kvm = f.file->private_data;
        ret = sev_lock_two_vms(kvm, source_kvm);
        if (ret)
                goto e_source_fput;
@@ -2103,8 +2106,7 @@ int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd)
 e_unlock:
        sev_unlock_two_vms(kvm, source_kvm);
 e_source_fput:
-       if (source_kvm_file)
-               fput(source_kvm_file);
+       fdput(f);
        return ret;
 }
 
index 252e7f37e4e2e27f2194d008c7c18e7c26c00eb1..f25bc3cbb250007b905e9c3c4d3be0daec6f918f 100644 (file)
@@ -3729,7 +3729,7 @@ static void svm_enable_nmi_window(struct kvm_vcpu *vcpu)
        svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
 }
 
-static void svm_flush_tlb_current(struct kvm_vcpu *vcpu)
+static void svm_flush_tlb_asid(struct kvm_vcpu *vcpu)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
 
@@ -3753,6 +3753,37 @@ static void svm_flush_tlb_current(struct kvm_vcpu *vcpu)
                svm->current_vmcb->asid_generation--;
 }
 
+static void svm_flush_tlb_current(struct kvm_vcpu *vcpu)
+{
+       hpa_t root_tdp = vcpu->arch.mmu->root.hpa;
+
+       /*
+        * When running on Hyper-V with EnlightenedNptTlb enabled, explicitly
+        * flush the NPT mappings via hypercall as flushing the ASID only
+        * affects virtual to physical mappings, it does not invalidate guest
+        * physical to host physical mappings.
+        */
+       if (svm_hv_is_enlightened_tlb_enabled(vcpu) && VALID_PAGE(root_tdp))
+               hyperv_flush_guest_mapping(root_tdp);
+
+       svm_flush_tlb_asid(vcpu);
+}
+
+static void svm_flush_tlb_all(struct kvm_vcpu *vcpu)
+{
+       /*
+        * When running on Hyper-V with EnlightenedNptTlb enabled, remote TLB
+        * flushes should be routed to hv_remote_flush_tlb() without requesting
+        * a "regular" remote flush.  Reaching this point means either there's
+        * a KVM bug or a prior hv_remote_flush_tlb() call failed, both of
+        * which might be fatal to the guest.  Yell, but try to recover.
+        */
+       if (WARN_ON_ONCE(svm_hv_is_enlightened_tlb_enabled(vcpu)))
+               hv_remote_flush_tlb(vcpu->kvm);
+
+       svm_flush_tlb_asid(vcpu);
+}
+
 static void svm_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t gva)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
@@ -4745,10 +4776,10 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
        .set_rflags = svm_set_rflags,
        .get_if_flag = svm_get_if_flag,
 
-       .flush_tlb_all = svm_flush_tlb_current,
+       .flush_tlb_all = svm_flush_tlb_all,
        .flush_tlb_current = svm_flush_tlb_current,
        .flush_tlb_gva = svm_flush_tlb_gva,
-       .flush_tlb_guest = svm_flush_tlb_current,
+       .flush_tlb_guest = svm_flush_tlb_asid,
 
        .vcpu_pre_run = svm_vcpu_pre_run,
        .vcpu_run = svm_vcpu_run,
index cff838f15db5399b1fba358965e38fb8adcddea0..786d46d73a8e5e3c743b0b85e6c578674dd624e1 100644 (file)
@@ -6,6 +6,8 @@
 #ifndef __ARCH_X86_KVM_SVM_ONHYPERV_H__
 #define __ARCH_X86_KVM_SVM_ONHYPERV_H__
 
+#include <asm/mshyperv.h>
+
 #if IS_ENABLED(CONFIG_HYPERV)
 
 #include "kvm_onhyperv.h"
@@ -15,6 +17,14 @@ static struct kvm_x86_ops svm_x86_ops;
 
 int svm_hv_enable_l2_tlb_flush(struct kvm_vcpu *vcpu);
 
+static inline bool svm_hv_is_enlightened_tlb_enabled(struct kvm_vcpu *vcpu)
+{
+       struct hv_vmcb_enlightenments *hve = &to_svm(vcpu)->vmcb->control.hv_enlightenments;
+
+       return ms_hyperv.nested_features & HV_X64_NESTED_ENLIGHTENED_TLB &&
+              !!hve->hv_enlightenments_control.enlightened_npt_tlb;
+}
+
 static inline void svm_hv_init_vmcb(struct vmcb *vmcb)
 {
        struct hv_vmcb_enlightenments *hve = &vmcb->control.hv_enlightenments;
@@ -80,6 +90,11 @@ static inline void svm_hv_update_vp_id(struct vmcb *vmcb, struct kvm_vcpu *vcpu)
 }
 #else
 
+static inline bool svm_hv_is_enlightened_tlb_enabled(struct kvm_vcpu *vcpu)
+{
+       return false;
+}
+
 static inline void svm_hv_init_vmcb(struct vmcb *vmcb)
 {
 }
index 7c4f5ca405c75f881264ec10c76da9ca3886d65e..768487611db78a85dbe57f11a9584d215496b5f1 100644 (file)
@@ -2903,7 +2903,7 @@ static int nested_vmx_check_address_space_size(struct kvm_vcpu *vcpu,
 static int nested_vmx_check_host_state(struct kvm_vcpu *vcpu,
                                       struct vmcs12 *vmcs12)
 {
-       bool ia32e;
+       bool ia32e = !!(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE);
 
        if (CC(!nested_host_cr0_valid(vcpu, vmcs12->host_cr0)) ||
            CC(!nested_host_cr4_valid(vcpu, vmcs12->host_cr4)) ||
@@ -2923,12 +2923,6 @@ static int nested_vmx_check_host_state(struct kvm_vcpu *vcpu,
                                           vmcs12->host_ia32_perf_global_ctrl)))
                return -EINVAL;
 
-#ifdef CONFIG_X86_64
-       ia32e = !!(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE);
-#else
-       ia32e = false;
-#endif
-
        if (ia32e) {
                if (CC(!(vmcs12->host_cr4 & X86_CR4_PAE)))
                        return -EINVAL;
@@ -3022,7 +3016,7 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu,
                                        struct vmcs12 *vmcs12,
                                        enum vm_entry_failure_code *entry_failure_code)
 {
-       bool ia32e;
+       bool ia32e = !!(vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE);
 
        *entry_failure_code = ENTRY_FAIL_DEFAULT;
 
@@ -3048,6 +3042,13 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu,
                                           vmcs12->guest_ia32_perf_global_ctrl)))
                return -EINVAL;
 
+       if (CC((vmcs12->guest_cr0 & (X86_CR0_PG | X86_CR0_PE)) == X86_CR0_PG))
+               return -EINVAL;
+
+       if (CC(ia32e && !(vmcs12->guest_cr4 & X86_CR4_PAE)) ||
+           CC(ia32e && !(vmcs12->guest_cr0 & X86_CR0_PG)))
+               return -EINVAL;
+
        /*
         * If the load IA32_EFER VM-entry control is 1, the following checks
         * are performed on the field for the IA32_EFER MSR:
@@ -3059,7 +3060,6 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu,
         */
        if (to_vmx(vcpu)->nested.nested_run_pending &&
            (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_EFER)) {
-               ia32e = (vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) != 0;
                if (CC(!kvm_valid_efer(vcpu, vmcs12->guest_ia32_efer)) ||
                    CC(ia32e != !!(vmcs12->guest_ia32_efer & EFER_LMA)) ||
                    CC(((vmcs12->guest_cr0 & X86_CR0_PG) &&
@@ -3868,7 +3868,12 @@ static void nested_vmx_inject_exception_vmexit(struct kvm_vcpu *vcpu)
                exit_qual = 0;
        }
 
-       if (ex->has_error_code) {
+       /*
+        * Unlike AMD's Paged Real Mode, which reports an error code on #PF
+        * VM-Exits even if the CPU is in Real Mode, Intel VMX never sets the
+        * "has error code" flags on VM-Exit if the CPU is in Real Mode.
+        */
+       if (ex->has_error_code && is_protmode(vcpu)) {
                /*
                 * Intel CPUs do not generate error codes with bits 31:16 set,
                 * and more importantly VMX disallows setting bits 31:16 in the
index f550540ed54ee1820f6c02074e5f8cc7683e62ba..631fd7da2bc36fc7b86c1d04500d168f5cc9b8de 100644 (file)
@@ -262,7 +262,7 @@ SYM_INNER_LABEL(vmx_vmexit, SYM_L_GLOBAL)
         * eIBRS has its own protection against poisoned RSB, so it doesn't
         * need the RSB filling sequence.  But it does need to be enabled, and a
         * single call to retire, before the first unbalanced RET.
-         */
+        */
 
        FILL_RETURN_BUFFER %_ASM_CX, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_VMEXIT,\
                           X86_FEATURE_RSB_VMEXIT_LITE
@@ -311,7 +311,7 @@ SYM_FUNC_END(vmx_do_nmi_irqoff)
  * vmread_error_trampoline - Trampoline from inline asm to vmread_error()
  * @field:     VMCS field encoding that failed
  * @fault:     %true if the VMREAD faulted, %false if it failed
-
+ *
  * Save and restore volatile registers across a call to vmread_error().  Note,
  * all parameters are passed on the stack.
  */
index bcac3efcde412b3340664f818d16170475cc01cd..d2d6e1b6c7882779c657adc062c83ae049445bc9 100644 (file)
@@ -874,7 +874,7 @@ void vmx_update_exception_bitmap(struct kvm_vcpu *vcpu)
         */
        if (is_guest_mode(vcpu))
                eb |= get_vmcs12(vcpu)->exception_bitmap;
-        else {
+       else {
                int mask = 0, match = 0;
 
                if (enable_ept && (eb & (1u << PF_VECTOR))) {
@@ -1282,7 +1282,7 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
                }
        }
 
-       if (vmx->nested.need_vmcs12_to_shadow_sync)
+       if (vmx->nested.need_vmcs12_to_shadow_sync)
                nested_sync_vmcs12_to_shadow(vcpu);
 
        if (vmx->guest_state_loaded)
@@ -5049,10 +5049,10 @@ static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu, bool for_injection)
        if (to_vmx(vcpu)->nested.nested_run_pending)
                return -EBUSY;
 
-       /*
-        * An IRQ must not be injected into L2 if it's supposed to VM-Exit,
-        * e.g. if the IRQ arrived asynchronously after checking nested events.
-        */
+       /*
+        * An IRQ must not be injected into L2 if it's supposed to VM-Exit,
+        * e.g. if the IRQ arrived asynchronously after checking nested events.
+        */
        if (for_injection && is_guest_mode(vcpu) && nested_exit_on_intr(vcpu))
                return -EBUSY;
 
index 7713420abab093b19d6c19e41d9ca9454c006a08..3d852ce8492066705214e84456eb2fc5bda80b42 100644 (file)
@@ -4432,6 +4432,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
        case KVM_CAP_VAPIC:
        case KVM_CAP_ENABLE_CAP:
        case KVM_CAP_VM_DISABLE_NX_HUGE_PAGES:
+       case KVM_CAP_IRQFD_RESAMPLE:
                r = 1;
                break;
        case KVM_CAP_EXIT_HYPERCALL:
@@ -8903,6 +8904,8 @@ restart:
        }
 
        if (ctxt->have_exception) {
+               WARN_ON_ONCE(vcpu->mmio_needed && !vcpu->mmio_is_write);
+               vcpu->mmio_needed = false;
                r = 1;
                inject_emulated_exception(vcpu);
        } else if (vcpu->arch.pio.count) {
@@ -9906,13 +9909,20 @@ int kvm_check_nested_events(struct kvm_vcpu *vcpu)
 
 static void kvm_inject_exception(struct kvm_vcpu *vcpu)
 {
+       /*
+        * Suppress the error code if the vCPU is in Real Mode, as Real Mode
+        * exceptions don't report error codes.  The presence of an error code
+        * is carried with the exception and only stripped when the exception
+        * is injected as intercepted #PF VM-Exits for AMD's Paged Real Mode do
+        * report an error code despite the CPU being in Real Mode.
+        */
+       vcpu->arch.exception.has_error_code &= is_protmode(vcpu);
+
        trace_kvm_inj_exception(vcpu->arch.exception.vector,
                                vcpu->arch.exception.has_error_code,
                                vcpu->arch.exception.error_code,
                                vcpu->arch.exception.injected);
 
-       if (vcpu->arch.exception.error_code && !is_protmode(vcpu))
-               vcpu->arch.exception.error_code = false;
        static_call(kvm_x86_inject_exception)(vcpu);
 }
 
index 4f1a40a86534329100d0344bb9388ddede6dc54e..01932af64193c14a3da15d86b92ca2ee332929ad 100644 (file)
@@ -71,6 +71,6 @@ ifneq ($(CONFIG_GENERIC_CSUM),y)
 endif
         lib-y += clear_page_64.o copy_page_64.o
         lib-y += memmove_64.o memset_64.o
-        lib-y += copy_user_64.o
+        lib-y += copy_user_64.o copy_user_uncached_64.o
        lib-y += cmpxchg16b_emu.o
 endif
index ecbfb4dd3b019c5731d15d095dd16067fd6288bb..f74a3e704a1cf0783e10c9c01d5d2e6bc3c5876f 100644 (file)
@@ -57,134 +57,85 @@ EXPORT_SYMBOL_GPL(clear_page_erms)
  * Input:
  * rdi destination
  * rcx count
+ * rax is zero
  *
  * Output:
  * rcx: uncleared bytes or 0 if successful.
  */
-SYM_FUNC_START(clear_user_original)
-       /*
-        * Copy only the lower 32 bits of size as that is enough to handle the rest bytes,
-        * i.e., no need for a 'q' suffix and thus a REX prefix.
-        */
-       mov %ecx,%eax
-       shr $3,%rcx
-       jz .Lrest_bytes
+SYM_FUNC_START(rep_stos_alternative)
+       cmpq $64,%rcx
+       jae .Lunrolled
 
-       # do the qwords first
-       .p2align 4
-.Lqwords:
-       movq $0,(%rdi)
-       lea 8(%rdi),%rdi
-       dec %rcx
-       jnz .Lqwords
+       cmp $8,%ecx
+       jae .Lword
 
-.Lrest_bytes:
-       and $7,  %eax
-       jz .Lexit
+       testl %ecx,%ecx
+       je .Lexit
 
-       # now do the rest bytes
-.Lbytes:
-       movb $0,(%rdi)
+.Lclear_user_tail:
+0:     movb %al,(%rdi)
        inc %rdi
-       dec %eax
-       jnz .Lbytes
-
+       dec %rcx
+       jnz .Lclear_user_tail
 .Lexit:
-       /*
-        * %rax still needs to be cleared in the exception case because this function is called
-        * from inline asm and the compiler expects %rax to be zero when exiting the inline asm,
-        * in case it might reuse it somewhere.
-        */
-        xor %eax,%eax
-        RET
-
-.Lqwords_exception:
-        # convert remaining qwords back into bytes to return to caller
-        shl $3, %rcx
-        and $7, %eax
-        add %rax,%rcx
-        jmp .Lexit
-
-.Lbytes_exception:
-        mov %eax,%ecx
-        jmp .Lexit
-
-        _ASM_EXTABLE_UA(.Lqwords, .Lqwords_exception)
-        _ASM_EXTABLE_UA(.Lbytes, .Lbytes_exception)
-SYM_FUNC_END(clear_user_original)
-EXPORT_SYMBOL(clear_user_original)
-
-/*
- * Alternative clear user-space when CPU feature X86_FEATURE_REP_GOOD is
- * present.
- * Input:
- * rdi destination
- * rcx count
- *
- * Output:
- * rcx: uncleared bytes or 0 if successful.
- */
-SYM_FUNC_START(clear_user_rep_good)
-       # call the original thing for less than a cacheline
-       cmp $64, %rcx
-       jb clear_user_original
-
-.Lprep:
-       # copy lower 32-bits for rest bytes
-       mov %ecx, %edx
-       shr $3, %rcx
-       jz .Lrep_good_rest_bytes
-
-.Lrep_good_qwords:
-       rep stosq
-
-.Lrep_good_rest_bytes:
-       and $7, %edx
-       jz .Lrep_good_exit
-
-.Lrep_good_bytes:
-       mov %edx, %ecx
-       rep stosb
-
-.Lrep_good_exit:
-       # see .Lexit comment above
-       xor %eax, %eax
        RET
 
-.Lrep_good_qwords_exception:
-       # convert remaining qwords back into bytes to return to caller
-       shl $3, %rcx
-       and $7, %edx
-       add %rdx, %rcx
-       jmp .Lrep_good_exit
+       _ASM_EXTABLE_UA( 0b, .Lexit)
 
-       _ASM_EXTABLE_UA(.Lrep_good_qwords, .Lrep_good_qwords_exception)
-       _ASM_EXTABLE_UA(.Lrep_good_bytes, .Lrep_good_exit)
-SYM_FUNC_END(clear_user_rep_good)
-EXPORT_SYMBOL(clear_user_rep_good)
+.Lword:
+1:     movq %rax,(%rdi)
+       addq $8,%rdi
+       sub $8,%ecx
+       je .Lexit
+       cmp $8,%ecx
+       jae .Lword
+       jmp .Lclear_user_tail
 
-/*
- * Alternative clear user-space when CPU feature X86_FEATURE_ERMS is present.
- * Input:
- * rdi destination
- * rcx count
- *
- * Output:
- * rcx: uncleared bytes or 0 if successful.
- *
- */
-SYM_FUNC_START(clear_user_erms)
-       # call the original thing for less than a cacheline
-       cmp $64, %rcx
-       jb clear_user_original
-
-.Lerms_bytes:
-       rep stosb
-
-.Lerms_exit:
-       xorl %eax,%eax
+       .p2align 4
+.Lunrolled:
+10:    movq %rax,(%rdi)
+11:    movq %rax,8(%rdi)
+12:    movq %rax,16(%rdi)
+13:    movq %rax,24(%rdi)
+14:    movq %rax,32(%rdi)
+15:    movq %rax,40(%rdi)
+16:    movq %rax,48(%rdi)
+17:    movq %rax,56(%rdi)
+       addq $64,%rdi
+       subq $64,%rcx
+       cmpq $64,%rcx
+       jae .Lunrolled
+       cmpl $8,%ecx
+       jae .Lword
+       testl %ecx,%ecx
+       jne .Lclear_user_tail
        RET
 
-       _ASM_EXTABLE_UA(.Lerms_bytes, .Lerms_exit)
-SYM_FUNC_END(clear_user_erms)
-EXPORT_SYMBOL(clear_user_erms)
+       /*
+        * If we take an exception on any of the
+        * word stores, we know that %rcx isn't zero,
+        * so we can just go to the tail clearing to
+        * get the exact count.
+        *
+        * The unrolled case might end up clearing
+        * some bytes twice. Don't care.
+        *
+        * We could use the value in %rdi to avoid
+        * a second fault on the exact count case,
+        * but do we really care? No.
+        *
+        * Finally, we could try to align %rdi at the
+        * top of the unrolling. But unaligned stores
+        * just aren't that common or expensive.
+        */
+       _ASM_EXTABLE_UA( 1b, .Lclear_user_tail)
+       _ASM_EXTABLE_UA(10b, .Lclear_user_tail)
+       _ASM_EXTABLE_UA(11b, .Lclear_user_tail)
+       _ASM_EXTABLE_UA(12b, .Lclear_user_tail)
+       _ASM_EXTABLE_UA(13b, .Lclear_user_tail)
+       _ASM_EXTABLE_UA(14b, .Lclear_user_tail)
+       _ASM_EXTABLE_UA(15b, .Lclear_user_tail)
+       _ASM_EXTABLE_UA(16b, .Lclear_user_tail)
+       _ASM_EXTABLE_UA(17b, .Lclear_user_tail)
+SYM_FUNC_END(rep_stos_alternative)
+EXPORT_SYMBOL(rep_stos_alternative)
index 9dec1b38a98fcdd756b170fdd1b3a3243640c6c3..4fc5c2de2de467c689ddf91eb1684eeb00aeb9db 100644 (file)
  */
 
 #include <linux/linkage.h>
-#include <asm/current.h>
-#include <asm/asm-offsets.h>
-#include <asm/thread_info.h>
-#include <asm/cpufeatures.h>
-#include <asm/alternative.h>
 #include <asm/asm.h>
-#include <asm/smap.h>
 #include <asm/export.h>
-#include <asm/trapnr.h>
-
-.macro ALIGN_DESTINATION
-       /* check for bad alignment of destination */
-       movl %edi,%ecx
-       andl $7,%ecx
-       jz 102f                         /* already aligned */
-       subl $8,%ecx
-       negl %ecx
-       subl %ecx,%edx
-100:   movb (%rsi),%al
-101:   movb %al,(%rdi)
-       incq %rsi
-       incq %rdi
-       decl %ecx
-       jnz 100b
-102:
-
-       _ASM_EXTABLE_CPY(100b, .Lcopy_user_handle_align)
-       _ASM_EXTABLE_CPY(101b, .Lcopy_user_handle_align)
-.endm
 
 /*
- * copy_user_generic_unrolled - memory copy with exception handling.
- * This version is for CPUs like P4 that don't have efficient micro
- * code for rep movsq
- *
- * Input:
- * rdi destination
- * rsi source
- * rdx count
- *
- * Output:
- * eax uncopied bytes or 0 if successful.
- */
-SYM_FUNC_START(copy_user_generic_unrolled)
-       ASM_STAC
-       cmpl $8,%edx
-       jb .Lcopy_user_short_string_bytes
-       ALIGN_DESTINATION
-       movl %edx,%ecx
-       andl $63,%edx
-       shrl $6,%ecx
-       jz copy_user_short_string
-1:     movq (%rsi),%r8
-2:     movq 1*8(%rsi),%r9
-3:     movq 2*8(%rsi),%r10
-4:     movq 3*8(%rsi),%r11
-5:     movq %r8,(%rdi)
-6:     movq %r9,1*8(%rdi)
-7:     movq %r10,2*8(%rdi)
-8:     movq %r11,3*8(%rdi)
-9:     movq 4*8(%rsi),%r8
-10:    movq 5*8(%rsi),%r9
-11:    movq 6*8(%rsi),%r10
-12:    movq 7*8(%rsi),%r11
-13:    movq %r8,4*8(%rdi)
-14:    movq %r9,5*8(%rdi)
-15:    movq %r10,6*8(%rdi)
-16:    movq %r11,7*8(%rdi)
-       leaq 64(%rsi),%rsi
-       leaq 64(%rdi),%rdi
-       decl %ecx
-       jnz 1b
-       jmp copy_user_short_string
-
-30:    shll $6,%ecx
-       addl %ecx,%edx
-       jmp .Lcopy_user_handle_tail
-
-       _ASM_EXTABLE_CPY(1b, 30b)
-       _ASM_EXTABLE_CPY(2b, 30b)
-       _ASM_EXTABLE_CPY(3b, 30b)
-       _ASM_EXTABLE_CPY(4b, 30b)
-       _ASM_EXTABLE_CPY(5b, 30b)
-       _ASM_EXTABLE_CPY(6b, 30b)
-       _ASM_EXTABLE_CPY(7b, 30b)
-       _ASM_EXTABLE_CPY(8b, 30b)
-       _ASM_EXTABLE_CPY(9b, 30b)
-       _ASM_EXTABLE_CPY(10b, 30b)
-       _ASM_EXTABLE_CPY(11b, 30b)
-       _ASM_EXTABLE_CPY(12b, 30b)
-       _ASM_EXTABLE_CPY(13b, 30b)
-       _ASM_EXTABLE_CPY(14b, 30b)
-       _ASM_EXTABLE_CPY(15b, 30b)
-       _ASM_EXTABLE_CPY(16b, 30b)
-SYM_FUNC_END(copy_user_generic_unrolled)
-EXPORT_SYMBOL(copy_user_generic_unrolled)
-
-/* Some CPUs run faster using the string copy instructions.
- * This is also a lot simpler. Use them when possible.
- *
- * Only 4GB of copy is supported. This shouldn't be a problem
- * because the kernel normally only writes from/to page sized chunks
- * even if user space passed a longer buffer.
- * And more would be dangerous because both Intel and AMD have
- * errata with rep movsq > 4GB. If someone feels the need to fix
- * this please consider this.
+ * rep_movs_alternative - memory copy with exception handling.
+ * This version is for CPUs that don't have FSRM (Fast Short Rep Movs)
  *
  * Input:
  * rdi destination
  * rsi source
- * rdx count
+ * rcx count
  *
  * Output:
- * eax uncopied bytes or 0 if successful.
- */
-SYM_FUNC_START(copy_user_generic_string)
-       ASM_STAC
-       cmpl $8,%edx
-       jb 2f           /* less than 8 bytes, go to byte copy loop */
-       ALIGN_DESTINATION
-       movl %edx,%ecx
-       shrl $3,%ecx
-       andl $7,%edx
-1:     rep movsq
-2:     movl %edx,%ecx
-3:     rep movsb
-       xorl %eax,%eax
-       ASM_CLAC
-       RET
-
-11:    leal (%rdx,%rcx,8),%ecx
-12:    movl %ecx,%edx          /* ecx is zerorest also */
-       jmp .Lcopy_user_handle_tail
-
-       _ASM_EXTABLE_CPY(1b, 11b)
-       _ASM_EXTABLE_CPY(3b, 12b)
-SYM_FUNC_END(copy_user_generic_string)
-EXPORT_SYMBOL(copy_user_generic_string)
-
-/*
- * Some CPUs are adding enhanced REP MOVSB/STOSB instructions.
- * It's recommended to use enhanced REP MOVSB/STOSB if it's enabled.
- *
- * Input:
- * rdi destination
- * rsi source
- * rdx count
+ * rcx uncopied bytes or 0 if successful.
  *
- * Output:
- * eax uncopied bytes or 0 if successful.
+ * NOTE! The calling convention is very intentionally the same as
+ * for 'rep movs', so that we can rewrite the function call with
+ * just a plain 'rep movs' on machines that have FSRM.  But to make
+ * it simpler for us, we can clobber rsi/rdi and rax/r8-r11 freely.
  */
-SYM_FUNC_START(copy_user_enhanced_fast_string)
-       ASM_STAC
-       /* CPUs without FSRM should avoid rep movsb for short copies */
-       ALTERNATIVE "cmpl $64, %edx; jb copy_user_short_string", "", X86_FEATURE_FSRM
-       movl %edx,%ecx
-1:     rep movsb
-       xorl %eax,%eax
-       ASM_CLAC
+SYM_FUNC_START(rep_movs_alternative)
+       cmpq $64,%rcx
+       jae .Lunrolled
+
+       cmp $8,%ecx
+       jae .Lword
+
+       testl %ecx,%ecx
+       je .Lexit
+
+.Lcopy_user_tail:
+0:     movb (%rsi),%al
+1:     movb %al,(%rdi)
+       inc %rdi
+       inc %rsi
+       dec %rcx
+       jne .Lcopy_user_tail
+.Lexit:
        RET
 
-12:    movl %ecx,%edx          /* ecx is zerorest also */
-       jmp .Lcopy_user_handle_tail
-
-       _ASM_EXTABLE_CPY(1b, 12b)
-SYM_FUNC_END(copy_user_enhanced_fast_string)
-EXPORT_SYMBOL(copy_user_enhanced_fast_string)
-
-/*
- * Try to copy last bytes and clear the rest if needed.
- * Since protection fault in copy_from/to_user is not a normal situation,
- * it is not necessary to optimize tail handling.
- * Don't try to copy the tail if machine check happened
- *
- * Input:
- * eax trap number written by ex_handler_copy()
- * rdi destination
- * rsi source
- * rdx count
- *
- * Output:
- * eax uncopied bytes or 0 if successful.
- */
-SYM_CODE_START_LOCAL(.Lcopy_user_handle_tail)
-       cmp $X86_TRAP_MC,%eax
-       je 3f
-
-       movl %edx,%ecx
-1:     rep movsb
-2:     mov %ecx,%eax
-       ASM_CLAC
+       _ASM_EXTABLE_UA( 0b, .Lexit)
+       _ASM_EXTABLE_UA( 1b, .Lexit)
+
+       .p2align 4
+.Lword:
+2:     movq (%rsi),%rax
+3:     movq %rax,(%rdi)
+       addq $8,%rsi
+       addq $8,%rdi
+       sub $8,%ecx
+       je .Lexit
+       cmp $8,%ecx
+       jae .Lword
+       jmp .Lcopy_user_tail
+
+       _ASM_EXTABLE_UA( 2b, .Lcopy_user_tail)
+       _ASM_EXTABLE_UA( 3b, .Lcopy_user_tail)
+
+       .p2align 4
+.Lunrolled:
+10:    movq (%rsi),%r8
+11:    movq 8(%rsi),%r9
+12:    movq 16(%rsi),%r10
+13:    movq 24(%rsi),%r11
+14:    movq %r8,(%rdi)
+15:    movq %r9,8(%rdi)
+16:    movq %r10,16(%rdi)
+17:    movq %r11,24(%rdi)
+20:    movq 32(%rsi),%r8
+21:    movq 40(%rsi),%r9
+22:    movq 48(%rsi),%r10
+23:    movq 56(%rsi),%r11
+24:    movq %r8,32(%rdi)
+25:    movq %r9,40(%rdi)
+26:    movq %r10,48(%rdi)
+27:    movq %r11,56(%rdi)
+       addq $64,%rsi
+       addq $64,%rdi
+       subq $64,%rcx
+       cmpq $64,%rcx
+       jae .Lunrolled
+       cmpl $8,%ecx
+       jae .Lword
+       testl %ecx,%ecx
+       jne .Lcopy_user_tail
        RET
 
-3:
-       movl %edx,%eax
-       ASM_CLAC
-       RET
-
-       _ASM_EXTABLE_CPY(1b, 2b)
-
-.Lcopy_user_handle_align:
-       addl %ecx,%edx                  /* ecx is zerorest also */
-       jmp .Lcopy_user_handle_tail
-
-SYM_CODE_END(.Lcopy_user_handle_tail)
-
-/*
- * Finish memcpy of less than 64 bytes.  #AC should already be set.
- *
- * Input:
- * rdi destination
- * rsi source
- * rdx count (< 64)
- *
- * Output:
- * eax uncopied bytes or 0 if successful.
- */
-SYM_CODE_START_LOCAL(copy_user_short_string)
-       movl %edx,%ecx
-       andl $7,%edx
-       shrl $3,%ecx
-       jz .Lcopy_user_short_string_bytes
-18:    movq (%rsi),%r8
-19:    movq %r8,(%rdi)
-       leaq 8(%rsi),%rsi
-       leaq 8(%rdi),%rdi
-       decl %ecx
-       jnz 18b
-.Lcopy_user_short_string_bytes:
-       andl %edx,%edx
-       jz 23f
-       movl %edx,%ecx
-21:    movb (%rsi),%al
-22:    movb %al,(%rdi)
-       incq %rsi
-       incq %rdi
-       decl %ecx
-       jnz 21b
-23:    xor %eax,%eax
-       ASM_CLAC
-       RET
-
-40:    leal (%rdx,%rcx,8),%edx
-       jmp 60f
-50:    movl %ecx,%edx          /* ecx is zerorest also */
-60:    jmp .Lcopy_user_handle_tail
-
-       _ASM_EXTABLE_CPY(18b, 40b)
-       _ASM_EXTABLE_CPY(19b, 40b)
-       _ASM_EXTABLE_CPY(21b, 50b)
-       _ASM_EXTABLE_CPY(22b, 50b)
-SYM_CODE_END(copy_user_short_string)
-
-/*
- * copy_user_nocache - Uncached memory copy with exception handling
- * This will force destination out of cache for more performance.
- *
- * Note: Cached memory copy is used when destination or size is not
- * naturally aligned. That is:
- *  - Require 8-byte alignment when size is 8 bytes or larger.
- *  - Require 4-byte alignment when size is 4 bytes.
- */
-SYM_FUNC_START(__copy_user_nocache)
-       ASM_STAC
-
-       /* If size is less than 8 bytes, go to 4-byte copy */
-       cmpl $8,%edx
-       jb .L_4b_nocache_copy_entry
-
-       /* If destination is not 8-byte aligned, "cache" copy to align it */
-       ALIGN_DESTINATION
-
-       /* Set 4x8-byte copy count and remainder */
-       movl %edx,%ecx
-       andl $63,%edx
-       shrl $6,%ecx
-       jz .L_8b_nocache_copy_entry     /* jump if count is 0 */
-
-       /* Perform 4x8-byte nocache loop-copy */
-.L_4x8b_nocache_copy_loop:
-1:     movq (%rsi),%r8
-2:     movq 1*8(%rsi),%r9
-3:     movq 2*8(%rsi),%r10
-4:     movq 3*8(%rsi),%r11
-5:     movnti %r8,(%rdi)
-6:     movnti %r9,1*8(%rdi)
-7:     movnti %r10,2*8(%rdi)
-8:     movnti %r11,3*8(%rdi)
-9:     movq 4*8(%rsi),%r8
-10:    movq 5*8(%rsi),%r9
-11:    movq 6*8(%rsi),%r10
-12:    movq 7*8(%rsi),%r11
-13:    movnti %r8,4*8(%rdi)
-14:    movnti %r9,5*8(%rdi)
-15:    movnti %r10,6*8(%rdi)
-16:    movnti %r11,7*8(%rdi)
-       leaq 64(%rsi),%rsi
-       leaq 64(%rdi),%rdi
-       decl %ecx
-       jnz .L_4x8b_nocache_copy_loop
-
-       /* Set 8-byte copy count and remainder */
-.L_8b_nocache_copy_entry:
-       movl %edx,%ecx
-       andl $7,%edx
-       shrl $3,%ecx
-       jz .L_4b_nocache_copy_entry     /* jump if count is 0 */
-
-       /* Perform 8-byte nocache loop-copy */
-.L_8b_nocache_copy_loop:
-20:    movq (%rsi),%r8
-21:    movnti %r8,(%rdi)
-       leaq 8(%rsi),%rsi
-       leaq 8(%rdi),%rdi
-       decl %ecx
-       jnz .L_8b_nocache_copy_loop
-
-       /* If no byte left, we're done */
-.L_4b_nocache_copy_entry:
-       andl %edx,%edx
-       jz .L_finish_copy
-
-       /* If destination is not 4-byte aligned, go to byte copy: */
-       movl %edi,%ecx
-       andl $3,%ecx
-       jnz .L_1b_cache_copy_entry
-
-       /* Set 4-byte copy count (1 or 0) and remainder */
-       movl %edx,%ecx
-       andl $3,%edx
-       shrl $2,%ecx
-       jz .L_1b_cache_copy_entry       /* jump if count is 0 */
-
-       /* Perform 4-byte nocache copy: */
-30:    movl (%rsi),%r8d
-31:    movnti %r8d,(%rdi)
-       leaq 4(%rsi),%rsi
-       leaq 4(%rdi),%rdi
-
-       /* If no bytes left, we're done: */
-       andl %edx,%edx
-       jz .L_finish_copy
-
-       /* Perform byte "cache" loop-copy for the remainder */
-.L_1b_cache_copy_entry:
-       movl %edx,%ecx
-.L_1b_cache_copy_loop:
-40:    movb (%rsi),%al
-41:    movb %al,(%rdi)
-       incq %rsi
-       incq %rdi
-       decl %ecx
-       jnz .L_1b_cache_copy_loop
-
-       /* Finished copying; fence the prior stores */
-.L_finish_copy:
-       xorl %eax,%eax
-       ASM_CLAC
-       sfence
-       RET
-
-.L_fixup_4x8b_copy:
-       shll $6,%ecx
-       addl %ecx,%edx
-       jmp .L_fixup_handle_tail
-.L_fixup_8b_copy:
-       lea (%rdx,%rcx,8),%rdx
-       jmp .L_fixup_handle_tail
-.L_fixup_4b_copy:
-       lea (%rdx,%rcx,4),%rdx
-       jmp .L_fixup_handle_tail
-.L_fixup_1b_copy:
-       movl %ecx,%edx
-.L_fixup_handle_tail:
-       sfence
-       jmp .Lcopy_user_handle_tail
-
-       _ASM_EXTABLE_CPY(1b, .L_fixup_4x8b_copy)
-       _ASM_EXTABLE_CPY(2b, .L_fixup_4x8b_copy)
-       _ASM_EXTABLE_CPY(3b, .L_fixup_4x8b_copy)
-       _ASM_EXTABLE_CPY(4b, .L_fixup_4x8b_copy)
-       _ASM_EXTABLE_CPY(5b, .L_fixup_4x8b_copy)
-       _ASM_EXTABLE_CPY(6b, .L_fixup_4x8b_copy)
-       _ASM_EXTABLE_CPY(7b, .L_fixup_4x8b_copy)
-       _ASM_EXTABLE_CPY(8b, .L_fixup_4x8b_copy)
-       _ASM_EXTABLE_CPY(9b, .L_fixup_4x8b_copy)
-       _ASM_EXTABLE_CPY(10b, .L_fixup_4x8b_copy)
-       _ASM_EXTABLE_CPY(11b, .L_fixup_4x8b_copy)
-       _ASM_EXTABLE_CPY(12b, .L_fixup_4x8b_copy)
-       _ASM_EXTABLE_CPY(13b, .L_fixup_4x8b_copy)
-       _ASM_EXTABLE_CPY(14b, .L_fixup_4x8b_copy)
-       _ASM_EXTABLE_CPY(15b, .L_fixup_4x8b_copy)
-       _ASM_EXTABLE_CPY(16b, .L_fixup_4x8b_copy)
-       _ASM_EXTABLE_CPY(20b, .L_fixup_8b_copy)
-       _ASM_EXTABLE_CPY(21b, .L_fixup_8b_copy)
-       _ASM_EXTABLE_CPY(30b, .L_fixup_4b_copy)
-       _ASM_EXTABLE_CPY(31b, .L_fixup_4b_copy)
-       _ASM_EXTABLE_CPY(40b, .L_fixup_1b_copy)
-       _ASM_EXTABLE_CPY(41b, .L_fixup_1b_copy)
-SYM_FUNC_END(__copy_user_nocache)
-EXPORT_SYMBOL(__copy_user_nocache)
+       _ASM_EXTABLE_UA(10b, .Lcopy_user_tail)
+       _ASM_EXTABLE_UA(11b, .Lcopy_user_tail)
+       _ASM_EXTABLE_UA(12b, .Lcopy_user_tail)
+       _ASM_EXTABLE_UA(13b, .Lcopy_user_tail)
+       _ASM_EXTABLE_UA(14b, .Lcopy_user_tail)
+       _ASM_EXTABLE_UA(15b, .Lcopy_user_tail)
+       _ASM_EXTABLE_UA(16b, .Lcopy_user_tail)
+       _ASM_EXTABLE_UA(17b, .Lcopy_user_tail)
+       _ASM_EXTABLE_UA(20b, .Lcopy_user_tail)
+       _ASM_EXTABLE_UA(21b, .Lcopy_user_tail)
+       _ASM_EXTABLE_UA(22b, .Lcopy_user_tail)
+       _ASM_EXTABLE_UA(23b, .Lcopy_user_tail)
+       _ASM_EXTABLE_UA(24b, .Lcopy_user_tail)
+       _ASM_EXTABLE_UA(25b, .Lcopy_user_tail)
+       _ASM_EXTABLE_UA(26b, .Lcopy_user_tail)
+       _ASM_EXTABLE_UA(27b, .Lcopy_user_tail)
+SYM_FUNC_END(rep_movs_alternative)
+EXPORT_SYMBOL(rep_movs_alternative)
diff --git a/arch/x86/lib/copy_user_uncached_64.S b/arch/x86/lib/copy_user_uncached_64.S
new file mode 100644 (file)
index 0000000..5c5f38d
--- /dev/null
@@ -0,0 +1,242 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2023 Linus Torvalds <torvalds@linux-foundation.org>
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+#include <asm/export.h>
+
+/*
+ * copy_user_nocache - Uncached memory copy with exception handling
+ *
+ * This copies from user space into kernel space, but the kernel
+ * space accesses can take a machine check exception, so they too
+ * need exception handling.
+ *
+ * Note: only 32-bit and 64-bit stores have non-temporal versions,
+ * and we only use aligned versions. Any unaligned parts at the
+ * start or end of the copy will be done using normal cached stores.
+ *
+ * Input:
+ * rdi destination
+ * rsi source
+ * edx count
+ *
+ * Output:
+ * rax uncopied bytes or 0 if successful.
+ */
+SYM_FUNC_START(__copy_user_nocache)
+       /* If destination is not 7-byte aligned, we'll have to align it */
+       testb $7,%dil
+       jne .Lalign
+
+.Lis_aligned:
+       cmp $64,%edx
+       jb .Lquadwords
+
+       .p2align 4,0x90
+.Lunrolled:
+10:    movq (%rsi),%r8
+11:    movq 8(%rsi),%r9
+12:    movq 16(%rsi),%r10
+13:    movq 24(%rsi),%r11
+20:    movnti %r8,(%rdi)
+21:    movnti %r9,8(%rdi)
+22:    movnti %r10,16(%rdi)
+23:    movnti %r11,24(%rdi)
+30:    movq 32(%rsi),%r8
+31:    movq 40(%rsi),%r9
+32:    movq 48(%rsi),%r10
+33:    movq 56(%rsi),%r11
+40:    movnti %r8,32(%rdi)
+41:    movnti %r9,40(%rdi)
+42:    movnti %r10,48(%rdi)
+43:    movnti %r11,56(%rdi)
+
+       addq $64,%rsi
+       addq $64,%rdi
+       sub $64,%edx
+       cmp $64,%edx
+       jae .Lunrolled
+
+/*
+ * First set of user mode loads have been done
+ * without any stores, so if they fail, we can
+ * just try the non-unrolled loop.
+ */
+_ASM_EXTABLE_UA(10b, .Lquadwords)
+_ASM_EXTABLE_UA(11b, .Lquadwords)
+_ASM_EXTABLE_UA(12b, .Lquadwords)
+_ASM_EXTABLE_UA(13b, .Lquadwords)
+
+/*
+ * The second set of user mode loads have been
+ * done with 32 bytes stored to the destination,
+ * so we need to take that into account before
+ * falling back to the unrolled loop.
+ */
+_ASM_EXTABLE_UA(30b, .Lfixup32)
+_ASM_EXTABLE_UA(31b, .Lfixup32)
+_ASM_EXTABLE_UA(32b, .Lfixup32)
+_ASM_EXTABLE_UA(33b, .Lfixup32)
+
+/*
+ * An exception on a write means that we're
+ * done, but we need to update the count
+ * depending on where in the unrolled loop
+ * we were.
+ */
+_ASM_EXTABLE_UA(20b, .Ldone0)
+_ASM_EXTABLE_UA(21b, .Ldone8)
+_ASM_EXTABLE_UA(22b, .Ldone16)
+_ASM_EXTABLE_UA(23b, .Ldone24)
+_ASM_EXTABLE_UA(40b, .Ldone32)
+_ASM_EXTABLE_UA(41b, .Ldone40)
+_ASM_EXTABLE_UA(42b, .Ldone48)
+_ASM_EXTABLE_UA(43b, .Ldone56)
+
+.Lquadwords:
+       cmp $8,%edx
+       jb .Llong
+50:    movq (%rsi),%rax
+51:    movnti %rax,(%rdi)
+       addq $8,%rsi
+       addq $8,%rdi
+       sub $8,%edx
+       jmp .Lquadwords
+
+/*
+ * If we fail on the last full quadword, we will
+ * not try to do any byte-wise cached accesses.
+ * We will try to do one more 4-byte uncached
+ * one, though.
+ */
+_ASM_EXTABLE_UA(50b, .Llast4)
+_ASM_EXTABLE_UA(51b, .Ldone0)
+
+.Llong:
+       test $4,%dl
+       je .Lword
+60:    movl (%rsi),%eax
+61:    movnti %eax,(%rdi)
+       addq $4,%rsi
+       addq $4,%rdi
+       sub $4,%edx
+.Lword:
+       sfence
+       test $2,%dl
+       je .Lbyte
+70:    movw (%rsi),%ax
+71:    movw %ax,(%rdi)
+       addq $2,%rsi
+       addq $2,%rdi
+       sub $2,%edx
+.Lbyte:
+       test $1,%dl
+       je .Ldone
+80:    movb (%rsi),%al
+81:    movb %al,(%rdi)
+       dec %edx
+.Ldone:
+       mov %edx,%eax
+       RET
+
+/*
+ * If we fail on the last four bytes, we won't
+ * bother with any fixups. It's dead, Jim. Note
+ * that there's no need for 'sfence' for any
+ * of this, since the exception will have been
+ * serializing.
+ */
+_ASM_EXTABLE_UA(60b, .Ldone)
+_ASM_EXTABLE_UA(61b, .Ldone)
+_ASM_EXTABLE_UA(70b, .Ldone)
+_ASM_EXTABLE_UA(71b, .Ldone)
+_ASM_EXTABLE_UA(80b, .Ldone)
+_ASM_EXTABLE_UA(81b, .Ldone)
+
+/*
+ * This is the "head needs aliging" case when
+ * the destination isn't 8-byte aligned. The
+ * 4-byte case can be done uncached, but any
+ * smaller alignment is done with regular stores.
+ */
+.Lalign:
+       test $1,%dil
+       je .Lalign_word
+       test %edx,%edx
+       je .Ldone
+90:    movb (%rsi),%al
+91:    movb %al,(%rdi)
+       inc %rsi
+       inc %rdi
+       dec %edx
+.Lalign_word:
+       test $2,%dil
+       je .Lalign_long
+       cmp $2,%edx
+       jb .Lbyte
+92:    movw (%rsi),%ax
+93:    movw %ax,(%rdi)
+       addq $2,%rsi
+       addq $2,%rdi
+       sub $2,%edx
+.Lalign_long:
+       test $4,%dil
+       je .Lis_aligned
+       cmp $4,%edx
+       jb .Lword
+94:    movl (%rsi),%eax
+95:    movnti %eax,(%rdi)
+       addq $4,%rsi
+       addq $4,%rdi
+       sub $4,%edx
+       jmp .Lis_aligned
+
+/*
+ * If we fail on the initial alignment accesses,
+ * we're all done. Again, no point in trying to
+ * do byte-by-byte probing if the 4-byte load
+ * fails - we're not doing any uncached accesses
+ * any more.
+ */
+_ASM_EXTABLE_UA(90b, .Ldone)
+_ASM_EXTABLE_UA(91b, .Ldone)
+_ASM_EXTABLE_UA(92b, .Ldone)
+_ASM_EXTABLE_UA(93b, .Ldone)
+_ASM_EXTABLE_UA(94b, .Ldone)
+_ASM_EXTABLE_UA(95b, .Ldone)
+
+/*
+ * Exception table fixups for faults in the middle
+ */
+.Ldone56: sub $8,%edx
+.Ldone48: sub $8,%edx
+.Ldone40: sub $8,%edx
+.Ldone32: sub $8,%edx
+.Ldone24: sub $8,%edx
+.Ldone16: sub $8,%edx
+.Ldone8: sub $8,%edx
+.Ldone0:
+       mov %edx,%eax
+       RET
+
+.Lfixup32:
+       addq $32,%rsi
+       addq $32,%rdi
+       sub $32,%edx
+       jmp .Lquadwords
+
+.Llast4:
+52:    movl (%rsi),%eax
+53:    movnti %eax,(%rdi)
+       sfence
+       sub $4,%edx
+       mov %edx,%eax
+       RET
+_ASM_EXTABLE_UA(52b, .Ldone0)
+_ASM_EXTABLE_UA(53b, .Ldone0)
+
+SYM_FUNC_END(__copy_user_nocache)
+EXPORT_SYMBOL(__copy_user_nocache)
index a64017602010ea8a4b61538f25918c6e58da7887..8f95fb267caa7c91d066002838198106ef052199 100644 (file)
 
 .section .noinstr.text, "ax"
 
-/*
- * We build a jump to memcpy_orig by default which gets NOPped out on
- * the majority of x86 CPUs which set REP_GOOD. In addition, CPUs which
- * have the enhanced REP MOVSB/STOSB feature (ERMS), change those NOPs
- * to a jmp to memcpy_erms which does the REP; MOVSB mem copy.
- */
-
 /*
  * memcpy - Copy a memory block.
  *
  *
  * Output:
  * rax original destination
+ *
+ * The FSRM alternative should be done inline (avoiding the call and
+ * the disgusting return handling), but that would require some help
+ * from the compiler for better calling conventions.
+ *
+ * The 'rep movsb' itself is small enough to replace the call, but the
+ * two register moves blow up the code. And one of them is "needed"
+ * only for the return value that is the same as the source input,
+ * which the compiler could/should do much better anyway.
  */
 SYM_TYPED_FUNC_START(__memcpy)
-       ALTERNATIVE_2 "jmp memcpy_orig", "", X86_FEATURE_REP_GOOD, \
-                     "jmp memcpy_erms", X86_FEATURE_ERMS
+       ALTERNATIVE "jmp memcpy_orig", "", X86_FEATURE_FSRM
 
        movq %rdi, %rax
        movq %rdx, %rcx
-       shrq $3, %rcx
-       andl $7, %edx
-       rep movsq
-       movl %edx, %ecx
        rep movsb
        RET
 SYM_FUNC_END(__memcpy)
@@ -46,17 +43,6 @@ EXPORT_SYMBOL(__memcpy)
 SYM_FUNC_ALIAS(memcpy, __memcpy)
 EXPORT_SYMBOL(memcpy)
 
-/*
- * memcpy_erms() - enhanced fast string memcpy. This is faster and
- * simpler than memcpy. Use memcpy_erms when possible.
- */
-SYM_FUNC_START_LOCAL(memcpy_erms)
-       movq %rdi, %rax
-       movq %rdx, %rcx
-       rep movsb
-       RET
-SYM_FUNC_END(memcpy_erms)
-
 SYM_FUNC_START_LOCAL(memcpy_orig)
        movq %rdi, %rax
 
index 6143b1a6fa2caa0d5977d22c3f1c23456ff6d3bf..7c59a704c4584bf7ef3e6a50f2021c31e6f15029 100644 (file)
  * rdx   count (bytes)
  *
  * rax   original destination
+ *
+ * The FSRS alternative should be done inline (avoiding the call and
+ * the disgusting return handling), but that would require some help
+ * from the compiler for better calling conventions.
+ *
+ * The 'rep stosb' itself is small enough to replace the call, but all
+ * the register moves blow up the code. And two of them are "needed"
+ * only for the return value that is the same as the source input,
+ * which the compiler could/should do much better anyway.
  */
 SYM_FUNC_START(__memset)
-       /*
-        * Some CPUs support enhanced REP MOVSB/STOSB feature. It is recommended
-        * to use it when possible. If not available, use fast string instructions.
-        *
-        * Otherwise, use original memset function.
-        */
-       ALTERNATIVE_2 "jmp memset_orig", "", X86_FEATURE_REP_GOOD, \
-                     "jmp memset_erms", X86_FEATURE_ERMS
+       ALTERNATIVE "jmp memset_orig", "", X86_FEATURE_FSRS
 
        movq %rdi,%r9
+       movb %sil,%al
        movq %rdx,%rcx
-       andl $7,%edx
-       shrq $3,%rcx
-       /* expand byte value  */
-       movzbl %sil,%esi
-       movabs $0x0101010101010101,%rax
-       imulq %rsi,%rax
-       rep stosq
-       movl %edx,%ecx
        rep stosb
        movq %r9,%rax
        RET
@@ -48,26 +43,6 @@ EXPORT_SYMBOL(__memset)
 SYM_FUNC_ALIAS(memset, __memset)
 EXPORT_SYMBOL(memset)
 
-/*
- * ISO C memset - set a memory block to a byte value. This function uses
- * enhanced rep stosb to override the fast string function.
- * The code is simpler and shorter than the fast string function as well.
- *
- * rdi   destination
- * rsi   value (char)
- * rdx   count (bytes)
- *
- * rax   original destination
- */
-SYM_FUNC_START_LOCAL(memset_erms)
-       movq %rdi,%r9
-       movb %sil,%al
-       movq %rdx,%rcx
-       rep stosb
-       movq %r9,%rax
-       RET
-SYM_FUNC_END(memset_erms)
-
 SYM_FUNC_START_LOCAL(memset_orig)
        movq %rdi,%r10
 
index 6c1f8ac5e7214496d3ac953d6c64866574eefbba..c3a5bbc0b41ef4c82163a33cbc5171968c8e4f3b 100644 (file)
@@ -45,7 +45,11 @@ EXPORT_SYMBOL_GPL(arch_wb_cache_pmem);
 long __copy_user_flushcache(void *dst, const void __user *src, unsigned size)
 {
        unsigned long flushed, dest = (unsigned long) dst;
-       long rc = __copy_user_nocache(dst, src, size, 0);
+       long rc;
+
+       stac();
+       rc = __copy_user_nocache(dst, src, size);
+       clac();
 
        /*
         * __copy_user_nocache() uses non-temporal stores for the bulk
index 7316a822425992efec14fb5598d42f32eac43f6c..e91500a80963945c1558707404703cd69a045bb4 100644 (file)
@@ -10,6 +10,7 @@
 #include <asm/fixmap.h>
 #include <asm/desc.h>
 #include <asm/kasan.h>
+#include <asm/setup.h>
 
 static DEFINE_PER_CPU_PAGE_ALIGNED(struct entry_stack_page, entry_stack_storage);
 
@@ -29,6 +30,12 @@ static __init void init_cea_offsets(void)
        unsigned int max_cea;
        unsigned int i, j;
 
+       if (!kaslr_enabled()) {
+               for_each_possible_cpu(i)
+                       per_cpu(_cea_offset, i) = i;
+               return;
+       }
+
        max_cea = (CPU_ENTRY_AREA_MAP_SIZE - PAGE_SIZE) / CPU_ENTRY_AREA_SIZE;
 
        /* O(sodding terrible) */
index 88cccd65029dba414912656310c3e72313a4aa4b..c6efcf559d8821261cb1724bf45275101a351238 100644 (file)
@@ -600,7 +600,8 @@ void __init sme_enable(struct boot_params *bp)
        cmdline_ptr = (const char *)((u64)bp->hdr.cmd_line_ptr |
                                     ((u64)bp->ext_cmd_line_ptr << 32));
 
-       cmdline_find_option(cmdline_ptr, cmdline_arg, buffer, sizeof(buffer));
+       if (cmdline_find_option(cmdline_ptr, cmdline_arg, buffer, sizeof(buffer)) < 0)
+               return;
 
        if (!strncmp(buffer, cmdline_on, sizeof(buffer)))
                sme_me_mask = me_mask;
index 356758b7d4b4766bef29dc899d6505f85b40157d..f0099ee70e02b10ffc7bb27677afb0b66256dace 100644 (file)
@@ -234,7 +234,7 @@ within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
  * take full advantage of the the limited (s32) immediate addressing range (2G)
  * of x86_64.
  *
- * See Documentation/x86/x86_64/mm.rst for more detail.
+ * See Documentation/arch/x86/x86_64/mm.rst for more detail.
  */
 
 static inline unsigned long highmap_start_pfn(void)
index 92d73ccede70d6c6fba85fff37170aba8df963e6..16c5292d227d2fd8f87d966fec5a2e9c4b41d8f8 100644 (file)
@@ -925,7 +925,7 @@ void flush_tlb_multi(const struct cpumask *cpumask,
 }
 
 /*
- * See Documentation/x86/tlb.rst for details.  We choose 33
+ * See Documentation/arch/x86/tlb.rst for details.  We choose 33
  * because it is large enough to cover the vast majority (at
  * least 95%) of allocations, and is small enough that we are
  * confident it will not cause too much overhead.  Each single
index 615a76d70019470b286d90fa91079836d46ea0ce..bf5161dcf89e7ebf9c454456252a856c8aa9bfab 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/dmi.h>
 #include <linux/pci.h>
 #include <linux/vgaarb.h>
+#include <asm/amd_nb.h>
 #include <asm/hpet.h>
 #include <asm/pci_x86.h>
 
@@ -824,3 +825,23 @@ static void rs690_fix_64bit_dma(struct pci_dev *pdev)
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7910, rs690_fix_64bit_dma);
 
 #endif
+
+#ifdef CONFIG_AMD_NB
+
+#define AMD_15B8_RCC_DEV2_EPF0_STRAP2                                  0x10136008
+#define AMD_15B8_RCC_DEV2_EPF0_STRAP2_NO_SOFT_RESET_DEV2_F0_MASK       0x00000080L
+
+static void quirk_clear_strap_no_soft_reset_dev2_f0(struct pci_dev *dev)
+{
+       u32 data;
+
+       if (!amd_smn_read(0, AMD_15B8_RCC_DEV2_EPF0_STRAP2, &data)) {
+               data &= ~AMD_15B8_RCC_DEV2_EPF0_STRAP2_NO_SOFT_RESET_DEV2_F0_MASK;
+               if (amd_smn_write(0, AMD_15B8_RCC_DEV2_EPF0_STRAP2, data))
+                       pci_err(dev, "Failed to write data 0x%x\n", data);
+       } else {
+               pci_err(dev, "Failed to read data\n");
+       }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15b8, quirk_clear_strap_no_soft_reset_dev2_f0);
+#endif
index ed0442e354344fad84fce7fcc29c67934828a9f9..00a92cb2c81474782146b801f56a5d5880c8afb7 100644 (file)
@@ -86,7 +86,7 @@ static void __init init_pvh_bootparams(bool xen_guest)
        }
 
        /*
-        * See Documentation/x86/boot.rst.
+        * See Documentation/arch/x86/boot.rst.
         *
         * Version 2.12 supports Xen entry point but we will use default x86/PC
         * environment (i.e. hardware_subarch 0).
index 17f09dc263811ab18f949af7303189263763a0e5..82fec66d46d29ee7e41e392fd5f22c524ad4f727 100644 (file)
@@ -69,8 +69,7 @@ CFLAGS_sha256.o                       += $(PURGATORY_CFLAGS)
 CFLAGS_REMOVE_string.o         += $(PURGATORY_CFLAGS_REMOVE)
 CFLAGS_string.o                        += $(PURGATORY_CFLAGS)
 
-AFLAGS_REMOVE_setup-x86_$(BITS).o      += -Wa,-gdwarf-2
-AFLAGS_REMOVE_entry64.o                        += -Wa,-gdwarf-2
+asflags-remove-y               += $(foreach x, -g -gdwarf-4 -gdwarf-5, $(x) -Wa,$(x))
 
 $(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
                $(call if_changed,ld)
index 3c5b52fbe4a7f9f69b98487d78c066f94a4064c9..a9ec8c9f5c5dd04fd7747d943b791adf9d9b1025 100644 (file)
@@ -45,6 +45,6 @@ obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o
 
 obj-$(CONFIG_XEN_DEBUG_FS)     += debugfs.o
 
-obj-$(CONFIG_XEN_PV_DOM0)      += vga.o
+obj-$(CONFIG_XEN_DOM0)         += vga.o
 
 obj-$(CONFIG_XEN_EFI)          += efi.o
index bb59cc6ddb2d425d4a782eb443969910e4508d83..093b78c8bbec0724e59947211b55e3eaae76cc8c 100644 (file)
@@ -1390,7 +1390,8 @@ asmlinkage __visible void __init xen_start_kernel(struct start_info *si)
 
                x86_platform.set_legacy_features =
                                xen_dom0_set_legacy_features;
-               xen_init_vga(info, xen_start_info->console.dom0.info_size);
+               xen_init_vga(info, xen_start_info->console.dom0.info_size,
+                            &boot_params.screen_info);
                xen_start_info->console.domU.mfn = 0;
                xen_start_info->console.domU.evtchn = 0;
 
index bcae606bbc5cfd3145aefb4f3bf2c11b5e07afe0..ada3868c02c231d0f10863cabf71a076f003acb5 100644 (file)
@@ -43,6 +43,19 @@ void __init xen_pvh_init(struct boot_params *boot_params)
        x86_init.oem.banner = xen_banner;
 
        xen_efi_init(boot_params);
+
+       if (xen_initial_domain()) {
+               struct xen_platform_op op = {
+                       .cmd = XENPF_get_dom0_console,
+               };
+               int ret = HYPERVISOR_platform_op(&op);
+
+               if (ret > 0)
+                       xen_init_vga(&op.u.dom0_console,
+                                    min(ret * sizeof(char),
+                                        sizeof(op.u.dom0_console)),
+                                    &boot_params->screen_info);
+       }
 }
 
 void __init mem_map_via_hcall(struct boot_params *boot_params_p)
index 1d597364b49dc3f9b7e8d259f1300181d4beab8e..b74ac2562cfbafddf4be10d53983515febbc7276 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/pvclock.h>
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
+#include <asm/xen/cpuid.h>
 
 #include <xen/events.h>
 #include <xen/features.h>
@@ -503,11 +504,7 @@ static int __init xen_tsc_safe_clocksource(void)
        /* Leaf 4, sub-leaf 0 (0x40000x03) */
        cpuid_count(xen_cpuid_base() + 3, 0, &eax, &ebx, &ecx, &edx);
 
-       /* tsc_mode = no_emulate (2) */
-       if (ebx != 2)
-               return 0;
-
-       return 1;
+       return ebx == XEN_CPUID_TSC_MODE_NEVER_EMULATE;
 }
 
 static void __init xen_time_init(void)
index 14ea32e734d59315c5aa70e1ba484be3468a5550..d97adab8420f4c248011e87d7c43417ad3b2ca6e 100644 (file)
@@ -9,10 +9,9 @@
 
 #include "xen-ops.h"
 
-void __init xen_init_vga(const struct dom0_vga_console_info *info, size_t size)
+void __init xen_init_vga(const struct dom0_vga_console_info *info, size_t size,
+                        struct screen_info *screen_info)
 {
-       struct screen_info *screen_info = &boot_params.screen_info;
-
        /* This is drawn from a dump from vgacon:startup in
         * standard Linux. */
        screen_info->orig_video_mode = 3;
index 9a8bb972193d884e097adb1b58d71d7aa9d614e0..a10903785a33863c358de6d73ede4dd38a82be80 100644 (file)
@@ -108,11 +108,12 @@ static inline void xen_uninit_lock_cpu(int cpu)
 
 struct dom0_vga_console_info;
 
-#ifdef CONFIG_XEN_PV_DOM0
-void __init xen_init_vga(const struct dom0_vga_console_info *, size_t size);
+#ifdef CONFIG_XEN_DOM0
+void __init xen_init_vga(const struct dom0_vga_console_info *, size_t size,
+                        struct screen_info *);
 #else
 static inline void __init xen_init_vga(const struct dom0_vga_console_info *info,
-                                      size_t size)
+                                      size_t size, struct screen_info *si)
 {
 }
 #endif
index 9793b49fc641755099094331c2b5efde94720d8f..574795a20d6f66df74f0bd80af515c3847d8b969 100644 (file)
@@ -43,7 +43,7 @@
 #if XCHAL_HAVE_S32C1I && (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RC_2009_0)
 /*
  * We Have Atomic Operation Control (ATOMCTL) Register; Initialize it.
- * For details see Documentation/xtensa/atomctl.rst
+ * For details see Documentation/arch/xtensa/atomctl.rst
  */
 #if XCHAL_DCACHE_IS_COHERENT
        movi    a3, 0x25        /* For SMP/MX -- internal for writeback,
index cd98366a9b238841c7e4aaa021fb623d3eb52136..f0a7d1c2641e0c67f9a652f9c0626a85f7c43184 100644 (file)
@@ -539,7 +539,7 @@ static size_t kstack_depth_to_print = CONFIG_PRINT_STACK_DEPTH;
 
 void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl)
 {
-       size_t len;
+       size_t len, off = 0;
 
        if (!sp)
                sp = stack_pointer(task);
@@ -548,9 +548,17 @@ void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl)
                  kstack_depth_to_print * STACK_DUMP_ENTRY_SIZE);
 
        printk("%sStack:\n", loglvl);
-       print_hex_dump(loglvl, " ", DUMP_PREFIX_NONE,
-                      STACK_DUMP_LINE_SIZE, STACK_DUMP_ENTRY_SIZE,
-                      sp, len, false);
+       while (off < len) {
+               u8 line[STACK_DUMP_LINE_SIZE];
+               size_t line_len = len - off > STACK_DUMP_LINE_SIZE ?
+                       STACK_DUMP_LINE_SIZE : len - off;
+
+               __memcpy(line, (u8 *)sp + off, line_len);
+               print_hex_dump(loglvl, " ", DUMP_PREFIX_NONE,
+                              STACK_DUMP_LINE_SIZE, STACK_DUMP_ENTRY_SIZE,
+                              line, line_len, false);
+               off += STACK_DUMP_LINE_SIZE;
+       }
        show_trace(task, sp, loglvl);
 }
 
index 5d9d9c84d51657f1c6d9e5b25bd3cac406308d76..941b2dca70db7337122df8ad9cdd1fb30bdeed1a 100644 (file)
@@ -204,9 +204,6 @@ config BLK_INLINE_ENCRYPTION_FALLBACK
 
 source "block/partitions/Kconfig"
 
-config BLOCK_COMPAT
-       def_bool COMPAT
-
 config BLK_MQ_PCI
        def_bool PCI
 
index 8a8d4441519ce7bcbf28e3c5a21d236c994cf115..d9ed3108c17af60d0b0a8cc53629bbfba104bf4f 100644 (file)
@@ -2854,11 +2854,11 @@ bfq_setup_stable_merge(struct bfq_data *bfqd, struct bfq_queue *bfqq,
 {
        int proc_ref = min(bfqq_process_refs(bfqq),
                           bfqq_process_refs(stable_merge_bfqq));
-       struct bfq_queue *new_bfqq;
+       struct bfq_queue *new_bfqq = NULL;
 
-       if (idling_boosts_thr_without_issues(bfqd, bfqq) ||
-           proc_ref == 0)
-               return NULL;
+       bfqq_data->stable_merge_bfqq = NULL;
+       if (idling_boosts_thr_without_issues(bfqd, bfqq) || proc_ref == 0)
+               goto out;
 
        /* next function will take at least one ref */
        new_bfqq = bfq_setup_merge(bfqq, stable_merge_bfqq);
@@ -2873,6 +2873,11 @@ bfq_setup_stable_merge(struct bfq_data *bfqd, struct bfq_queue *bfqq,
                        new_bfqq_data->stably_merged = true;
                }
        }
+
+out:
+       /* deschedule stable merge, because done or aborted here */
+       bfq_put_stable_ref(stable_merge_bfqq);
+
        return new_bfqq;
 }
 
@@ -2933,11 +2938,6 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
                        struct bfq_queue *stable_merge_bfqq =
                                bfqq_data->stable_merge_bfqq;
 
-                       /* deschedule stable merge, because done or aborted here */
-                       bfq_put_stable_ref(stable_merge_bfqq);
-
-                       bfqq_data->stable_merge_bfqq = NULL;
-
                        return bfq_setup_stable_merge(bfqd, bfqq,
                                                      stable_merge_bfqq,
                                                      bfqq_data);
index 9e5e0277a4d95a5e2f09b6cafaf4d8cd97ee5983..42926e6cb83c8e328cfd1e904989430737cc9326 100644 (file)
@@ -959,16 +959,11 @@ again:
        }
 }
 
-unsigned long bdev_start_io_acct(struct block_device *bdev,
-                                unsigned int sectors, enum req_op op,
+unsigned long bdev_start_io_acct(struct block_device *bdev, enum req_op op,
                                 unsigned long start_time)
 {
-       const int sgrp = op_stat_group(op);
-
        part_stat_lock();
        update_io_ticks(bdev, start_time, false);
-       part_stat_inc(bdev, ios[sgrp]);
-       part_stat_add(bdev, sectors[sgrp], sectors);
        part_stat_local_inc(bdev, in_flight[op_is_write(op)]);
        part_stat_unlock();
 
@@ -984,13 +979,12 @@ EXPORT_SYMBOL(bdev_start_io_acct);
  */
 unsigned long bio_start_io_acct(struct bio *bio)
 {
-       return bdev_start_io_acct(bio->bi_bdev, bio_sectors(bio),
-                                 bio_op(bio), jiffies);
+       return bdev_start_io_acct(bio->bi_bdev, bio_op(bio), jiffies);
 }
 EXPORT_SYMBOL_GPL(bio_start_io_acct);
 
 void bdev_end_io_acct(struct block_device *bdev, enum req_op op,
-                     unsigned long start_time)
+                     unsigned int sectors, unsigned long start_time)
 {
        const int sgrp = op_stat_group(op);
        unsigned long now = READ_ONCE(jiffies);
@@ -998,6 +992,8 @@ void bdev_end_io_acct(struct block_device *bdev, enum req_op op,
 
        part_stat_lock();
        update_io_ticks(bdev, now, true);
+       part_stat_inc(bdev, ios[sgrp]);
+       part_stat_add(bdev, sectors[sgrp], sectors);
        part_stat_add(bdev, nsecs[sgrp], jiffies_to_nsecs(duration));
        part_stat_local_dec(bdev, in_flight[op_is_write(op)]);
        part_stat_unlock();
@@ -1007,7 +1003,7 @@ EXPORT_SYMBOL(bdev_end_io_acct);
 void bio_end_io_acct_remapped(struct bio *bio, unsigned long start_time,
                              struct block_device *orig_bdev)
 {
-       bdev_end_io_acct(orig_bdev, bio_op(bio), start_time);
+       bdev_end_io_acct(orig_bdev, bio_op(bio), bio_sectors(bio), start_time);
 }
 EXPORT_SYMBOL_GPL(bio_end_io_acct_remapped);
 
index 9137d16cecdc38bb130a9592fa690a005ed72827..04c55f1c492eb144b332139478b5cc390dbbf075 100644 (file)
@@ -29,10 +29,11 @@ static struct bio_map_data *bio_alloc_map_data(struct iov_iter *data,
        bmd = kmalloc(struct_size(bmd, iov, data->nr_segs), gfp_mask);
        if (!bmd)
                return NULL;
-       memcpy(bmd->iov, data->iov, sizeof(struct iovec) * data->nr_segs);
        bmd->iter = *data;
-       if (iter_is_iovec(data))
-               bmd->iter.iov = bmd->iov;
+       if (iter_is_iovec(data)) {
+               memcpy(bmd->iov, iter_iov(data), sizeof(struct iovec) * data->nr_segs);
+               bmd->iter.__iov = bmd->iov;
+       }
        return bmd;
 }
 
index d0cb2ef18fe21dfa07fe4eec5c76bde6d6286f05..2831f78f86a033dbd0131a5da659741728d6a2c6 100644 (file)
@@ -1359,8 +1359,6 @@ bool blk_rq_is_poll(struct request *rq)
                return false;
        if (rq->mq_hctx->type != HCTX_TYPE_POLL)
                return false;
-       if (WARN_ON_ONCE(!rq->bio))
-               return false;
        return true;
 }
 EXPORT_SYMBOL_GPL(blk_rq_is_poll);
@@ -1368,7 +1366,7 @@ EXPORT_SYMBOL_GPL(blk_rq_is_poll);
 static void blk_rq_poll_completion(struct request *rq, struct completion *wait)
 {
        do {
-               bio_poll(rq->bio, NULL, 0);
+               blk_mq_poll(rq->q, blk_rq_to_qc(rq), NULL, 0);
                cond_resched();
        } while (!completion_done(wait));
 }
@@ -2725,6 +2723,7 @@ static void blk_mq_dispatch_plug_list(struct blk_plug *plug, bool from_sched)
        struct blk_mq_hw_ctx *this_hctx = NULL;
        struct blk_mq_ctx *this_ctx = NULL;
        struct request *requeue_list = NULL;
+       struct request **requeue_lastp = &requeue_list;
        unsigned int depth = 0;
        LIST_HEAD(list);
 
@@ -2735,10 +2734,10 @@ static void blk_mq_dispatch_plug_list(struct blk_plug *plug, bool from_sched)
                        this_hctx = rq->mq_hctx;
                        this_ctx = rq->mq_ctx;
                } else if (this_hctx != rq->mq_hctx || this_ctx != rq->mq_ctx) {
-                       rq_list_add(&requeue_list, rq);
+                       rq_list_add_tail(&requeue_lastp, rq);
                        continue;
                }
-               list_add_tail(&rq->queuelist, &list);
+               list_add(&rq->queuelist, &list);
                depth++;
        } while (!rq_list_empty(plug->mq_list));
 
@@ -2879,16 +2878,15 @@ static inline struct request *blk_mq_get_cached_request(struct request_queue *q,
 
        if (!plug)
                return NULL;
+       rq = rq_list_peek(&plug->cached_rq);
+       if (!rq || rq->q != q)
+               return NULL;
 
        if (blk_mq_attempt_bio_merge(q, *bio, nsegs)) {
                *bio = NULL;
                return NULL;
        }
 
-       rq = rq_list_peek(&plug->cached_rq);
-       if (!rq || rq->q != q)
-               return NULL;
-
        type = blk_mq_get_hctx_type((*bio)->bi_opf);
        hctx_type = rq->mq_hctx->type;
        if (type != hctx_type &&
index ef59fee62780d301d4756000e660464078a6eaa2..a7482d2cc82e721a4c1acf8a0884b22ae9e195ac 100644 (file)
@@ -378,12 +378,13 @@ static inline bool hctx_may_queue(struct blk_mq_hw_ctx *hctx,
 #define __blk_mq_run_dispatch_ops(q, check_sleep, dispatch_ops)        \
 do {                                                           \
        if ((q)->tag_set->flags & BLK_MQ_F_BLOCKING) {          \
+               struct blk_mq_tag_set *__tag_set = (q)->tag_set; \
                int srcu_idx;                                   \
                                                                \
                might_sleep_if(check_sleep);                    \
-               srcu_idx = srcu_read_lock((q)->tag_set->srcu);  \
+               srcu_idx = srcu_read_lock(__tag_set->srcu);     \
                (dispatch_ops);                                 \
-               srcu_read_unlock((q)->tag_set->srcu, srcu_idx); \
+               srcu_read_unlock(__tag_set->srcu, srcu_idx);    \
        } else {                                                \
                rcu_read_lock();                                \
                (dispatch_ops);                                 \
index 3ee5577e15860ceb1221c609160cc6b5f56158f1..7f874737af6824fff5d58946993e20c9d51d136c 100644 (file)
@@ -368,7 +368,6 @@ int disk_scan_partitions(struct gendisk *disk, fmode_t mode)
        if (disk->open_partitions)
                return -EBUSY;
 
-       set_bit(GD_NEED_PART_SCAN, &disk->state);
        /*
         * If the device is opened exclusively by current thread already, it's
         * safe to scan partitons, otherwise, use bd_prepare_to_claim() to
@@ -381,12 +380,19 @@ int disk_scan_partitions(struct gendisk *disk, fmode_t mode)
                        return ret;
        }
 
+       set_bit(GD_NEED_PART_SCAN, &disk->state);
        bdev = blkdev_get_by_dev(disk_devt(disk), mode & ~FMODE_EXCL, NULL);
        if (IS_ERR(bdev))
                ret =  PTR_ERR(bdev);
        else
-               blkdev_put(bdev, mode);
+               blkdev_put(bdev, mode & ~FMODE_EXCL);
 
+       /*
+        * If blkdev_get_by_dev() failed early, GD_NEED_PART_SCAN is still set,
+        * and this will cause that re-assemble partitioned raid device will
+        * creat partition for underlying disk.
+        */
+       clear_bit(GD_NEED_PART_SCAN, &disk->state);
        if (!(mode & FMODE_EXCL))
                bd_abort_claiming(disk->part0, disk_scan_partitions);
        return ret;
index 5042cc54fa5ec68d71d54185f438df3959479865..a7a49b17ceb1fe837b786597170826e87dac33e4 100644 (file)
@@ -33,7 +33,11 @@ extern __initconst const unsigned long system_certificate_list_size;
 extern __initconst const unsigned long module_cert_size;
 
 /**
- * restrict_link_to_builtin_trusted - Restrict keyring addition by built in CA
+ * restrict_link_by_builtin_trusted - Restrict keyring addition by built-in CA
+ * @dest_keyring: Keyring being linked to.
+ * @type: The type of key being added.
+ * @payload: The payload of the new key.
+ * @restriction_key: A ring of keys that can be used to vouch for the new cert.
  *
  * Restrict the addition of keys into a keyring based on the key-to-be-added
  * being vouched for by a key in the built in system keyring.
@@ -50,7 +54,11 @@ int restrict_link_by_builtin_trusted(struct key *dest_keyring,
 #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
 /**
  * restrict_link_by_builtin_and_secondary_trusted - Restrict keyring
- *   addition by both builtin and secondary keyrings
+ *   addition by both built-in and secondary keyrings.
+ * @dest_keyring: Keyring being linked to.
+ * @type: The type of key being added.
+ * @payload: The payload of the new key.
+ * @restrict_key: A ring of keys that can be used to vouch for the new cert.
  *
  * Restrict the addition of keys into a keyring based on the key-to-be-added
  * being vouched for by a key in either the built-in or the secondary system
@@ -75,7 +83,7 @@ int restrict_link_by_builtin_and_secondary_trusted(
                                          secondary_trusted_keys);
 }
 
-/**
+/*
  * Allocate a struct key_restriction for the "builtin and secondary trust"
  * keyring. Only for use in system_trusted_keyring_init().
  */
index 4fa769c4bcdb78c46c9fb1e124736ae39a32fbec..f0d4ff3c20a83275d5161e8e5c8d87793aa46ae7 100644 (file)
@@ -79,16 +79,16 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
                }
 
                if (sinfo->msgdigest_len != sig->digest_size) {
-                       pr_debug("Sig %u: Invalid digest size (%u)\n",
-                                sinfo->index, sinfo->msgdigest_len);
+                       pr_warn("Sig %u: Invalid digest size (%u)\n",
+                               sinfo->index, sinfo->msgdigest_len);
                        ret = -EBADMSG;
                        goto error;
                }
 
                if (memcmp(sig->digest, sinfo->msgdigest,
                           sinfo->msgdigest_len) != 0) {
-                       pr_debug("Sig %u: Message digest doesn't match\n",
-                                sinfo->index);
+                       pr_warn("Sig %u: Message digest doesn't match\n",
+                               sinfo->index);
                        ret = -EKEYREJECTED;
                        goto error;
                }
@@ -478,7 +478,7 @@ int pkcs7_supply_detached_data(struct pkcs7_message *pkcs7,
                               const void *data, size_t datalen)
 {
        if (pkcs7->data) {
-               pr_debug("Data already supplied\n");
+               pr_warn("Data already supplied\n");
                return -EINVAL;
        }
        pkcs7->data = data;
index 6b1ac5f5896a7f830d61f97cd645d15c9d105331..276bdb62749882a838d3305461e3eb3a58e8ab89 100644 (file)
@@ -108,6 +108,46 @@ int restrict_link_by_signature(struct key *dest_keyring,
        return ret;
 }
 
+/**
+ * restrict_link_by_ca - Restrict additions to a ring of CA keys
+ * @dest_keyring: Keyring being linked to.
+ * @type: The type of key being added.
+ * @payload: The payload of the new key.
+ * @trust_keyring: Unused.
+ *
+ * Check if the new certificate is a CA. If it is a CA, then mark the new
+ * certificate as being ok to link.
+ *
+ * Returns 0 if the new certificate was accepted, -ENOKEY if the
+ * certificate is not a CA. -ENOPKG if the signature uses unsupported
+ * crypto, or some other error if there is a matching certificate but
+ * the signature check cannot be performed.
+ */
+int restrict_link_by_ca(struct key *dest_keyring,
+                       const struct key_type *type,
+                       const union key_payload *payload,
+                       struct key *trust_keyring)
+{
+       const struct public_key *pkey;
+
+       if (type != &key_type_asymmetric)
+               return -EOPNOTSUPP;
+
+       pkey = payload->data[asym_crypto];
+       if (!pkey)
+               return -ENOPKG;
+       if (!test_bit(KEY_EFLAG_CA, &pkey->key_eflags))
+               return -ENOKEY;
+       if (!test_bit(KEY_EFLAG_KEYCERTSIGN, &pkey->key_eflags))
+               return -ENOKEY;
+       if (!IS_ENABLED(CONFIG_INTEGRITY_CA_MACHINE_KEYRING_MAX))
+               return 0;
+       if (test_bit(KEY_EFLAG_DIGITALSIG, &pkey->key_eflags))
+               return -ENOKEY;
+
+       return 0;
+}
+
 static bool match_either_id(const struct asymmetric_key_id **pair,
                            const struct asymmetric_key_id *single)
 {
index 7553ab18db898ffd887b7a7c487506780eb409e6..22beaf2213a224da9ca8f8fdf3519b071ac64a95 100644 (file)
@@ -74,7 +74,7 @@ static int pefile_parse_binary(const void *pebuf, unsigned int pelen,
                break;
 
        default:
-               pr_debug("Unknown PEOPT magic = %04hx\n", pe32->magic);
+               pr_warn("Unknown PEOPT magic = %04hx\n", pe32->magic);
                return -ELIBBAD;
        }
 
@@ -95,7 +95,7 @@ static int pefile_parse_binary(const void *pebuf, unsigned int pelen,
        ctx->certs_size = ddir->certs.size;
 
        if (!ddir->certs.virtual_address || !ddir->certs.size) {
-               pr_debug("Unsigned PE binary\n");
+               pr_warn("Unsigned PE binary\n");
                return -ENODATA;
        }
 
@@ -127,7 +127,7 @@ static int pefile_strip_sig_wrapper(const void *pebuf,
        unsigned len;
 
        if (ctx->sig_len < sizeof(wrapper)) {
-               pr_debug("Signature wrapper too short\n");
+               pr_warn("Signature wrapper too short\n");
                return -ELIBBAD;
        }
 
@@ -135,19 +135,23 @@ static int pefile_strip_sig_wrapper(const void *pebuf,
        pr_debug("sig wrapper = { %x, %x, %x }\n",
                 wrapper.length, wrapper.revision, wrapper.cert_type);
 
-       /* Both pesign and sbsign round up the length of certificate table
-        * (in optional header data directories) to 8 byte alignment.
+       /* sbsign rounds up the length of certificate table (in optional
+        * header data directories) to 8 byte alignment.  However, the PE
+        * specification states that while entries are 8-byte aligned, this is
+        * not included in their length, and as a result, pesign has not
+        * rounded up since 0.110.
         */
-       if (round_up(wrapper.length, 8) != ctx->sig_len) {
-               pr_debug("Signature wrapper len wrong\n");
+       if (wrapper.length > ctx->sig_len) {
+               pr_warn("Signature wrapper bigger than sig len (%x > %x)\n",
+                       ctx->sig_len, wrapper.length);
                return -ELIBBAD;
        }
        if (wrapper.revision != WIN_CERT_REVISION_2_0) {
-               pr_debug("Signature is not revision 2.0\n");
+               pr_warn("Signature is not revision 2.0\n");
                return -ENOTSUPP;
        }
        if (wrapper.cert_type != WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
-               pr_debug("Signature certificate type is not PKCS\n");
+               pr_warn("Signature certificate type is not PKCS\n");
                return -ENOTSUPP;
        }
 
@@ -160,7 +164,7 @@ static int pefile_strip_sig_wrapper(const void *pebuf,
        ctx->sig_offset += sizeof(wrapper);
        ctx->sig_len -= sizeof(wrapper);
        if (ctx->sig_len < 4) {
-               pr_debug("Signature data missing\n");
+               pr_warn("Signature data missing\n");
                return -EKEYREJECTED;
        }
 
@@ -194,7 +198,7 @@ check_len:
                return 0;
        }
 not_pkcs7:
-       pr_debug("Signature data not PKCS#7\n");
+       pr_warn("Signature data not PKCS#7\n");
        return -ELIBBAD;
 }
 
@@ -337,8 +341,8 @@ static int pefile_digest_pe(const void *pebuf, unsigned int pelen,
        digest_size = crypto_shash_digestsize(tfm);
 
        if (digest_size != ctx->digest_len) {
-               pr_debug("Digest size mismatch (%zx != %x)\n",
-                        digest_size, ctx->digest_len);
+               pr_warn("Digest size mismatch (%zx != %x)\n",
+                       digest_size, ctx->digest_len);
                ret = -EBADMSG;
                goto error_no_desc;
        }
@@ -369,7 +373,7 @@ static int pefile_digest_pe(const void *pebuf, unsigned int pelen,
         * PKCS#7 certificate.
         */
        if (memcmp(digest, ctx->digest, ctx->digest_len) != 0) {
-               pr_debug("Digest mismatch\n");
+               pr_warn("Digest mismatch\n");
                ret = -EKEYREJECTED;
        } else {
                pr_debug("The digests match!\n");
index 7a9b084e2043d72fa8859f6220316ab44ac79f92..0a7049b470c1812a710b9815a052e02b253e8f44 100644 (file)
@@ -579,6 +579,34 @@ int x509_process_extension(void *context, size_t hdrlen,
                return 0;
        }
 
+       if (ctx->last_oid == OID_keyUsage) {
+               /*
+                * Get hold of the keyUsage bit string
+                * v[1] is the encoding size
+                *       (Expect either 0x02 or 0x03, making it 1 or 2 bytes)
+                * v[2] is the number of unused bits in the bit string
+                *       (If >= 3 keyCertSign is missing when v[1] = 0x02)
+                * v[3] and possibly v[4] contain the bit string
+                *
+                * From RFC 5280 4.2.1.3:
+                *   0x04 is where keyCertSign lands in this bit string
+                *   0x80 is where digitalSignature lands in this bit string
+                */
+               if (v[0] != ASN1_BTS)
+                       return -EBADMSG;
+               if (vlen < 4)
+                       return -EBADMSG;
+               if (v[2] >= 8)
+                       return -EBADMSG;
+               if (v[3] & 0x80)
+                       ctx->cert->pub->key_eflags |= 1 << KEY_EFLAG_DIGITALSIG;
+               if (v[1] == 0x02 && v[2] <= 2 && (v[3] & 0x04))
+                       ctx->cert->pub->key_eflags |= 1 << KEY_EFLAG_KEYCERTSIGN;
+               else if (vlen > 4 && v[1] == 0x03 && (v[3] & 0x04))
+                       ctx->cert->pub->key_eflags |= 1 << KEY_EFLAG_KEYCERTSIGN;
+               return 0;
+       }
+
        if (ctx->last_oid == OID_authorityKeyIdentifier) {
                /* Get hold of the CA key fingerprint */
                ctx->raw_akid = v;
@@ -586,6 +614,28 @@ int x509_process_extension(void *context, size_t hdrlen,
                return 0;
        }
 
+       if (ctx->last_oid == OID_basicConstraints) {
+               /*
+                * Get hold of the basicConstraints
+                * v[1] is the encoding size
+                *      (Expect 0x2 or greater, making it 1 or more bytes)
+                * v[2] is the encoding type
+                *      (Expect an ASN1_BOOL for the CA)
+                * v[3] is the contents of the ASN1_BOOL
+                *      (Expect 1 if the CA is TRUE)
+                * vlen should match the entire extension size
+                */
+               if (v[0] != (ASN1_CONS_BIT | ASN1_SEQ))
+                       return -EBADMSG;
+               if (vlen < 2)
+                       return -EBADMSG;
+               if (v[1] != vlen - 2)
+                       return -EBADMSG;
+               if (vlen >= 4 && v[1] != 0 && v[2] == ASN1_BOOL && v[3] == 1)
+                       ctx->cert->pub->key_eflags |= 1 << KEY_EFLAG_CA;
+               return 0;
+       }
+
        return 0;
 }
 
index 07aa77aed1c8dd27dd63b0ed658cb923c5cde5f4..f22fd44d586b2eab2ed203819588fc494c22014b 100644 (file)
@@ -1,4 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-obj-y  += habanalabs/
-obj-y  += ivpu/
+obj-$(CONFIG_DRM_ACCEL_HABANALABS)     += habanalabs/
+obj-$(CONFIG_DRM_ACCEL_IVPU)           += ivpu/
index 231f29bb50257e9595f856e29cc312f937c33cb4..6a320a73e3ccf17b09209284883774c991e2ef9f 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/pci.h>
 
 #include <drm/drm_accel.h>
-#include <drm/drm_drv.h>
 #include <drm/drm_file.h>
 #include <drm/drm_gem.h>
 #include <drm/drm_ioctl.h>
@@ -118,6 +117,10 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
        struct pci_dev *pdev = to_pci_dev(vdev->drm.dev);
        struct drm_ivpu_param *args = data;
        int ret = 0;
+       int idx;
+
+       if (!drm_dev_enter(dev, &idx))
+               return -ENODEV;
 
        switch (args->param) {
        case DRM_IVPU_PARAM_DEVICE_ID:
@@ -171,6 +174,7 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
                break;
        }
 
+       drm_dev_exit(idx);
        return ret;
 }
 
@@ -470,8 +474,8 @@ static int ivpu_dev_init(struct ivpu_device *vdev)
 
        vdev->hw->ops = &ivpu_hw_mtl_ops;
        vdev->platform = IVPU_PLATFORM_INVALID;
-       vdev->context_xa_limit.min = IVPU_GLOBAL_CONTEXT_MMU_SSID + 1;
-       vdev->context_xa_limit.max = IVPU_CONTEXT_LIMIT;
+       vdev->context_xa_limit.min = IVPU_USER_CONTEXT_MIN_SSID;
+       vdev->context_xa_limit.max = IVPU_USER_CONTEXT_MAX_SSID;
        atomic64_set(&vdev->unique_id_counter, 0);
        xa_init_flags(&vdev->context_xa, XA_FLAGS_ALLOC);
        xa_init_flags(&vdev->submitted_jobs_xa, XA_FLAGS_ALLOC1);
@@ -565,6 +569,8 @@ err_mmu_gctx_fini:
        ivpu_mmu_global_context_fini(vdev);
 err_power_down:
        ivpu_hw_power_down(vdev);
+       if (IVPU_WA(d3hot_after_power_off))
+               pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot);
 err_xa_destroy:
        xa_destroy(&vdev->submitted_jobs_xa);
        xa_destroy(&vdev->context_xa);
@@ -575,7 +581,11 @@ static void ivpu_dev_fini(struct ivpu_device *vdev)
 {
        ivpu_pm_disable(vdev);
        ivpu_shutdown(vdev);
+       if (IVPU_WA(d3hot_after_power_off))
+               pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot);
        ivpu_job_done_thread_fini(vdev);
+       ivpu_pm_cancel_recovery(vdev);
+
        ivpu_ipc_fini(vdev);
        ivpu_fw_fini(vdev);
        ivpu_mmu_global_context_fini(vdev);
@@ -622,7 +632,7 @@ static void ivpu_remove(struct pci_dev *pdev)
 {
        struct ivpu_device *vdev = pci_get_drvdata(pdev);
 
-       drm_dev_unregister(&vdev->drm);
+       drm_dev_unplug(&vdev->drm);
        ivpu_dev_fini(vdev);
 }
 
index f47b4965db2e33ced85211672116e7c7a0cc3aad..d3013fbd13b32fbaaffd2886b27eaaca6f9bf011 100644 (file)
@@ -7,6 +7,7 @@
 #define __IVPU_DRV_H__
 
 #include <drm/drm_device.h>
+#include <drm/drm_drv.h>
 #include <drm/drm_managed.h>
 #include <drm/drm_mm.h>
 #include <drm/drm_print.h>
 #define PCI_DEVICE_ID_MTL   0x7d1d
 
 #define IVPU_GLOBAL_CONTEXT_MMU_SSID 0
-#define IVPU_CONTEXT_LIMIT          64
+/* SSID 1 is used by the VPU to represent invalid context */
+#define IVPU_USER_CONTEXT_MIN_SSID   2
+#define IVPU_USER_CONTEXT_MAX_SSID   (IVPU_USER_CONTEXT_MIN_SSID + 63)
+
 #define IVPU_NUM_ENGINES            2
 
 #define IVPU_PLATFORM_SILICON 0
@@ -70,6 +74,7 @@
 struct ivpu_wa_table {
        bool punit_disabled;
        bool clear_runtime_mem;
+       bool d3hot_after_power_off;
 };
 
 struct ivpu_hw_info;
index 62bfaa9081c4f8b6df89e038e26bceeec6a5eea9..382ec127be8ea1081f3a4446a82553c536b40f0e 100644 (file)
 #include "ivpu_mmu.h"
 #include "ivpu_pm.h"
 
-#define TILE_FUSE_ENABLE_BOTH       0x0
-#define TILE_FUSE_ENABLE_UPPER      0x1
-#define TILE_FUSE_ENABLE_LOWER      0x2
-
-#define TILE_SKU_BOTH_MTL           0x3630
-#define TILE_SKU_LOWER_MTL          0x3631
-#define TILE_SKU_UPPER_MTL          0x3632
+#define TILE_FUSE_ENABLE_BOTH        0x0
+#define TILE_SKU_BOTH_MTL            0x3630
 
 /* Work point configuration values */
-#define WP_CONFIG_1_TILE_5_3_RATIO   0x0101
-#define WP_CONFIG_1_TILE_4_3_RATIO   0x0102
-#define WP_CONFIG_2_TILE_5_3_RATIO   0x0201
-#define WP_CONFIG_2_TILE_4_3_RATIO   0x0202
-#define WP_CONFIG_0_TILE_PLL_OFF     0x0000
+#define CONFIG_1_TILE                0x01
+#define CONFIG_2_TILE                0x02
+#define PLL_RATIO_5_3                0x01
+#define PLL_RATIO_4_3                0x02
+#define WP_CONFIG(tile, ratio)       (((tile) << 8) | (ratio))
+#define WP_CONFIG_1_TILE_5_3_RATIO   WP_CONFIG(CONFIG_1_TILE, PLL_RATIO_5_3)
+#define WP_CONFIG_1_TILE_4_3_RATIO   WP_CONFIG(CONFIG_1_TILE, PLL_RATIO_4_3)
+#define WP_CONFIG_2_TILE_5_3_RATIO   WP_CONFIG(CONFIG_2_TILE, PLL_RATIO_5_3)
+#define WP_CONFIG_2_TILE_4_3_RATIO   WP_CONFIG(CONFIG_2_TILE, PLL_RATIO_4_3)
+#define WP_CONFIG_0_TILE_PLL_OFF     WP_CONFIG(0, 0)
 
 #define PLL_REF_CLK_FREQ            (50 * 1000000)
 #define PLL_SIMULATION_FREQ         (10 * 1000000)
-#define PLL_RATIO_TO_FREQ(x)        ((x) * PLL_REF_CLK_FREQ)
 #define PLL_DEFAULT_EPP_VALUE       0x80
 
 #define TIM_SAFE_ENABLE                     0xf1d0dead
@@ -101,6 +100,7 @@ static void ivpu_hw_wa_init(struct ivpu_device *vdev)
 {
        vdev->wa.punit_disabled = ivpu_is_fpga(vdev);
        vdev->wa.clear_runtime_mem = false;
+       vdev->wa.d3hot_after_power_off = true;
 }
 
 static void ivpu_hw_timeouts_init(struct ivpu_device *vdev)
@@ -218,7 +218,8 @@ static int ivpu_pll_drive(struct ivpu_device *vdev, bool enable)
                config = 0;
        }
 
-       ivpu_dbg(vdev, PM, "PLL workpoint request: %d Hz\n", PLL_RATIO_TO_FREQ(target_ratio));
+       ivpu_dbg(vdev, PM, "PLL workpoint request: config 0x%04x pll ratio 0x%x\n",
+                config, target_ratio);
 
        ret = ivpu_pll_cmd_send(vdev, hw->pll.min_ratio, hw->pll.max_ratio, target_ratio, config);
        if (ret) {
@@ -403,11 +404,6 @@ static int ivpu_boot_host_ss_axi_enable(struct ivpu_device *vdev)
        return ivpu_boot_host_ss_axi_drive(vdev, true);
 }
 
-static int ivpu_boot_host_ss_axi_disable(struct ivpu_device *vdev)
-{
-       return ivpu_boot_host_ss_axi_drive(vdev, false);
-}
-
 static int ivpu_boot_host_ss_top_noc_drive(struct ivpu_device *vdev, bool enable)
 {
        int ret;
@@ -441,11 +437,6 @@ static int ivpu_boot_host_ss_top_noc_enable(struct ivpu_device *vdev)
        return ivpu_boot_host_ss_top_noc_drive(vdev, true);
 }
 
-static int ivpu_boot_host_ss_top_noc_disable(struct ivpu_device *vdev)
-{
-       return ivpu_boot_host_ss_top_noc_drive(vdev, false);
-}
-
 static void ivpu_boot_pwr_island_trickle_drive(struct ivpu_device *vdev, bool enable)
 {
        u32 val = REGV_RD32(MTL_VPU_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0);
@@ -504,16 +495,6 @@ static void ivpu_boot_dpu_active_drive(struct ivpu_device *vdev, bool enable)
        REGV_WR32(MTL_VPU_HOST_SS_AON_DPU_ACTIVE, val);
 }
 
-static int ivpu_boot_pwr_domain_disable(struct ivpu_device *vdev)
-{
-       ivpu_boot_dpu_active_drive(vdev, false);
-       ivpu_boot_pwr_island_isolation_drive(vdev, true);
-       ivpu_boot_pwr_island_trickle_drive(vdev, false);
-       ivpu_boot_pwr_island_drive(vdev, false);
-
-       return ivpu_boot_wait_for_pwr_island_status(vdev, 0x0);
-}
-
 static int ivpu_boot_pwr_domain_enable(struct ivpu_device *vdev)
 {
        int ret;
@@ -629,34 +610,10 @@ static int ivpu_boot_d0i3_drive(struct ivpu_device *vdev, bool enable)
 static int ivpu_hw_mtl_info_init(struct ivpu_device *vdev)
 {
        struct ivpu_hw_info *hw = vdev->hw;
-       u32 tile_fuse;
-
-       tile_fuse = REGB_RD32(MTL_BUTTRESS_TILE_FUSE);
-       if (!REG_TEST_FLD(MTL_BUTTRESS_TILE_FUSE, VALID, tile_fuse))
-               ivpu_warn(vdev, "Tile Fuse: Invalid (0x%x)\n", tile_fuse);
-
-       hw->tile_fuse = REG_GET_FLD(MTL_BUTTRESS_TILE_FUSE, SKU, tile_fuse);
-       switch (hw->tile_fuse) {
-       case TILE_FUSE_ENABLE_LOWER:
-               hw->sku = TILE_SKU_LOWER_MTL;
-               hw->config = WP_CONFIG_1_TILE_5_3_RATIO;
-               ivpu_dbg(vdev, MISC, "Tile Fuse: Enable Lower\n");
-               break;
-       case TILE_FUSE_ENABLE_UPPER:
-               hw->sku = TILE_SKU_UPPER_MTL;
-               hw->config = WP_CONFIG_1_TILE_4_3_RATIO;
-               ivpu_dbg(vdev, MISC, "Tile Fuse: Enable Upper\n");
-               break;
-       case TILE_FUSE_ENABLE_BOTH:
-               hw->sku = TILE_SKU_BOTH_MTL;
-               hw->config = WP_CONFIG_2_TILE_5_3_RATIO;
-               ivpu_dbg(vdev, MISC, "Tile Fuse: Enable Both\n");
-               break;
-       default:
-               hw->config = WP_CONFIG_0_TILE_PLL_OFF;
-               ivpu_dbg(vdev, MISC, "Tile Fuse: Disable\n");
-               break;
-       }
+
+       hw->tile_fuse = TILE_FUSE_ENABLE_BOTH;
+       hw->sku = TILE_SKU_BOTH_MTL;
+       hw->config = WP_CONFIG_2_TILE_4_3_RATIO;
 
        ivpu_pll_init_frequency_ratios(vdev);
 
@@ -797,21 +754,8 @@ static int ivpu_hw_mtl_power_down(struct ivpu_device *vdev)
 {
        int ret = 0;
 
-       /* FPGA requires manual clearing of IP_Reset bit by enabling quiescent state */
-       if (ivpu_is_fpga(vdev)) {
-               if (ivpu_boot_host_ss_top_noc_disable(vdev)) {
-                       ivpu_err(vdev, "Failed to disable TOP NOC\n");
-                       ret = -EIO;
-               }
-
-               if (ivpu_boot_host_ss_axi_disable(vdev)) {
-                       ivpu_err(vdev, "Failed to disable AXI\n");
-                       ret = -EIO;
-               }
-       }
-
-       if (ivpu_boot_pwr_domain_disable(vdev)) {
-               ivpu_err(vdev, "Failed to disable power domain\n");
+       if (ivpu_hw_mtl_reset(vdev)) {
+               ivpu_err(vdev, "Failed to reset the VPU\n");
                ret = -EIO;
        }
 
@@ -844,6 +788,19 @@ static void ivpu_hw_mtl_wdt_disable(struct ivpu_device *vdev)
        REGV_WR32(MTL_VPU_CPU_SS_TIM_GEN_CONFIG, val);
 }
 
+static u32 ivpu_hw_mtl_pll_to_freq(u32 ratio, u32 config)
+{
+       u32 pll_clock = PLL_REF_CLK_FREQ * ratio;
+       u32 cpu_clock;
+
+       if ((config & 0xff) == PLL_RATIO_4_3)
+               cpu_clock = pll_clock * 2 / 4;
+       else
+               cpu_clock = pll_clock * 2 / 5;
+
+       return cpu_clock;
+}
+
 /* Register indirect accesses */
 static u32 ivpu_hw_mtl_reg_pll_freq_get(struct ivpu_device *vdev)
 {
@@ -855,7 +812,7 @@ static u32 ivpu_hw_mtl_reg_pll_freq_get(struct ivpu_device *vdev)
        if (!ivpu_is_silicon(vdev))
                return PLL_SIMULATION_FREQ;
 
-       return PLL_RATIO_TO_FREQ(pll_curr_ratio);
+       return ivpu_hw_mtl_pll_to_freq(pll_curr_ratio, vdev->hw->config);
 }
 
 static u32 ivpu_hw_mtl_reg_telemetry_offset_get(struct ivpu_device *vdev)
index 9838202ecfadf27fc0fe3a74495e145a08dea500..68f5b6668e00b9812864db1c9e432adc4f9d6c3c 100644 (file)
@@ -21,7 +21,7 @@ struct ivpu_bo;
 #define IVPU_IPC_ALIGNMENT        64
 
 #define IVPU_IPC_HDR_FREE         0
-#define IVPU_IPC_HDR_ALLOCATED    0
+#define IVPU_IPC_HDR_ALLOCATED    1
 
 /**
  * struct ivpu_ipc_hdr - The IPC message header structure, exchanged
index 94068aedf97cfee791469f5aa908c118ce2c355d..3c6f1e16cf2ff7a1090cd471cb84f93d26feba21 100644 (file)
@@ -461,26 +461,22 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32
 
        job->cmd_buf_vpu_addr = bo->vpu_addr + commands_offset;
 
-       ret = drm_gem_lock_reservations((struct drm_gem_object **)job->bos, buf_count,
-                                       &acquire_ctx);
+       ret = drm_gem_lock_reservations((struct drm_gem_object **)job->bos, 1, &acquire_ctx);
        if (ret) {
                ivpu_warn(vdev, "Failed to lock reservations: %d\n", ret);
                return ret;
        }
 
-       for (i = 0; i < buf_count; i++) {
-               ret = dma_resv_reserve_fences(job->bos[i]->base.resv, 1);
-               if (ret) {
-                       ivpu_warn(vdev, "Failed to reserve fences: %d\n", ret);
-                       goto unlock_reservations;
-               }
+       ret = dma_resv_reserve_fences(bo->base.resv, 1);
+       if (ret) {
+               ivpu_warn(vdev, "Failed to reserve fences: %d\n", ret);
+               goto unlock_reservations;
        }
 
-       for (i = 0; i < buf_count; i++)
-               dma_resv_add_fence(job->bos[i]->base.resv, job->done_fence, DMA_RESV_USAGE_WRITE);
+       dma_resv_add_fence(bo->base.resv, job->done_fence, DMA_RESV_USAGE_WRITE);
 
 unlock_reservations:
-       drm_gem_unlock_reservations((struct drm_gem_object **)job->bos, buf_count, &acquire_ctx);
+       drm_gem_unlock_reservations((struct drm_gem_object **)job->bos, 1, &acquire_ctx);
 
        wmb(); /* Flush write combining buffers */
 
@@ -489,12 +485,12 @@ unlock_reservations:
 
 int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 {
-       int ret = 0;
        struct ivpu_file_priv *file_priv = file->driver_priv;
        struct ivpu_device *vdev = file_priv->vdev;
        struct drm_ivpu_submit *params = data;
        struct ivpu_job *job;
        u32 *buf_handles;
+       int idx, ret;
 
        if (params->engine > DRM_IVPU_ENGINE_COPY)
                return -EINVAL;
@@ -523,6 +519,11 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
                goto free_handles;
        }
 
+       if (!drm_dev_enter(&vdev->drm, &idx)) {
+               ret = -ENODEV;
+               goto free_handles;
+       }
+
        ivpu_dbg(vdev, JOB, "Submit ioctl: ctx %u buf_count %u\n",
                 file_priv->ctx.id, params->buffer_count);
 
@@ -530,7 +531,7 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
        if (!job) {
                ivpu_err(vdev, "Failed to create job\n");
                ret = -ENOMEM;
-               goto free_handles;
+               goto dev_exit;
        }
 
        ret = ivpu_job_prepare_bos_for_submit(file, job, buf_handles, params->buffer_count,
@@ -548,6 +549,8 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 
 job_put:
        job_put(job);
+dev_exit:
+       drm_dev_exit(idx);
 free_handles:
        kfree(buf_handles);
 
index 553bcbd787b3c868fdc3c9ca6ccb85ade4b644cf..bde42d6383da66beed974d42754f0bb445275f7f 100644 (file)
@@ -98,12 +98,18 @@ retry:
 static void ivpu_pm_recovery_work(struct work_struct *work)
 {
        struct ivpu_pm_info *pm = container_of(work, struct ivpu_pm_info, recovery_work);
-       struct ivpu_device *vdev =  pm->vdev;
+       struct ivpu_device *vdev = pm->vdev;
        char *evt[2] = {"IVPU_PM_EVENT=IVPU_RECOVER", NULL};
        int ret;
 
-       ret = pci_reset_function(to_pci_dev(vdev->drm.dev));
-       if (ret)
+retry:
+       ret = pci_try_reset_function(to_pci_dev(vdev->drm.dev));
+       if (ret == -EAGAIN && !drm_dev_is_unplugged(&vdev->drm)) {
+               cond_resched();
+               goto retry;
+       }
+
+       if (ret && ret != -EAGAIN)
                ivpu_err(vdev, "Failed to reset VPU: %d\n", ret);
 
        kobject_uevent_env(&vdev->drm.dev->kobj, KOBJ_CHANGE, evt);
@@ -134,32 +140,28 @@ int ivpu_pm_suspend_cb(struct device *dev)
 {
        struct drm_device *drm = dev_get_drvdata(dev);
        struct ivpu_device *vdev = to_ivpu_device(drm);
-       int ret;
+       unsigned long timeout;
 
        ivpu_dbg(vdev, PM, "Suspend..\n");
 
-       ret = ivpu_suspend(vdev);
-       if (ret && vdev->pm->suspend_reschedule_counter) {
-               ivpu_dbg(vdev, PM, "Failed to enter idle, rescheduling suspend, retries left %d\n",
-                        vdev->pm->suspend_reschedule_counter);
-               pm_schedule_suspend(dev, vdev->timeout.reschedule_suspend);
-               vdev->pm->suspend_reschedule_counter--;
-               return -EBUSY;
-       } else if (!vdev->pm->suspend_reschedule_counter) {
-               ivpu_warn(vdev, "Failed to enter idle, force suspend\n");
-               ivpu_pm_prepare_cold_boot(vdev);
-       } else {
-               ivpu_pm_prepare_warm_boot(vdev);
+       timeout = jiffies + msecs_to_jiffies(vdev->timeout.tdr);
+       while (!ivpu_hw_is_idle(vdev)) {
+               cond_resched();
+               if (time_after_eq(jiffies, timeout)) {
+                       ivpu_err(vdev, "Failed to enter idle on system suspend\n");
+                       return -EBUSY;
+               }
        }
 
-       vdev->pm->suspend_reschedule_counter = PM_RESCHEDULE_LIMIT;
+       ivpu_suspend(vdev);
+       ivpu_pm_prepare_warm_boot(vdev);
 
        pci_save_state(to_pci_dev(dev));
        pci_set_power_state(to_pci_dev(dev), PCI_D3hot);
 
        ivpu_dbg(vdev, PM, "Suspend done.\n");
 
-       return ret;
+       return 0;
 }
 
 int ivpu_pm_resume_cb(struct device *dev)
@@ -306,6 +308,11 @@ int ivpu_pm_init(struct ivpu_device *vdev)
        return 0;
 }
 
+void ivpu_pm_cancel_recovery(struct ivpu_device *vdev)
+{
+       cancel_work_sync(&vdev->pm->recovery_work);
+}
+
 void ivpu_pm_enable(struct ivpu_device *vdev)
 {
        struct device *dev = vdev->drm.dev;
index dc1b3758e13f4ab47218e3813bcb6d0f62745bbc..baca981872551cc6e9a1380075c4fc749a735515 100644 (file)
@@ -21,6 +21,7 @@ struct ivpu_pm_info {
 int ivpu_pm_init(struct ivpu_device *vdev);
 void ivpu_pm_enable(struct ivpu_device *vdev);
 void ivpu_pm_disable(struct ivpu_device *vdev);
+void ivpu_pm_cancel_recovery(struct ivpu_device *vdev);
 
 int ivpu_pm_suspend_cb(struct device *dev);
 int ivpu_pm_resume_cb(struct device *dev);
index 97b711e57bff457bbfec645aeee7ca2efd668229..c7a6d0b69dabd4426cd6811176929abbaaaa2439 100644 (file)
@@ -1984,6 +1984,7 @@ static int instance;
 static int acpi_video_bus_add(struct acpi_device *device)
 {
        struct acpi_video_bus *video;
+       bool auto_detect;
        int error;
        acpi_status status;
 
@@ -2045,10 +2046,20 @@ static int acpi_video_bus_add(struct acpi_device *device)
        mutex_unlock(&video_list_lock);
 
        /*
-        * The userspace visible backlight_device gets registered separately
-        * from acpi_video_register_backlight().
+        * If backlight-type auto-detection is used then a native backlight may
+        * show up later and this may change the result from video to native.
+        * Therefor normally the userspace visible /sys/class/backlight device
+        * gets registered separately by the GPU driver calling
+        * acpi_video_register_backlight() when an internal panel is detected.
+        * Register the backlight now when not using auto-detection, so that
+        * when the kernel cmdline or DMI-quirks are used the backlight will
+        * get registered even if acpi_video_register_backlight() is not called.
         */
        acpi_video_run_bcl_for_osi(video);
+       if (__acpi_video_get_backlight_type(false, &auto_detect) == acpi_backlight_video &&
+           !auto_detect)
+               acpi_video_bus_register_backlight(video);
+
        acpi_video_bus_add_notify_handler(video);
 
        return 0;
index 82d1728b9bc6a65ca8512da50153959f039e1a7b..df596d46dd974eba813e0431fdf5cda2e21f9445 100644 (file)
@@ -142,9 +142,6 @@ static acpi_status acpi_ev_fixed_event_initialize(void)
                        status =
                            acpi_write_bit_register(acpi_gbl_fixed_event_info
                                                    [i].enable_register_id,
-                                                   (i ==
-                                                    ACPI_EVENT_PCIE_WAKE) ?
-                                                   ACPI_ENABLE_EVENT :
                                                    ACPI_DISABLE_EVENT);
                        if (ACPI_FAILURE(status)) {
                                return (status);
@@ -188,11 +185,6 @@ u32 acpi_ev_fixed_event_detect(void)
                return (int_status);
        }
 
-       if (fixed_enable & ACPI_BITMASK_PCIEXP_WAKE_DISABLE)
-               fixed_enable &= ~ACPI_BITMASK_PCIEXP_WAKE_DISABLE;
-       else
-               fixed_enable |= ACPI_BITMASK_PCIEXP_WAKE_DISABLE;
-
        ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
                          "Fixed Event Block: Enable %08X Status %08X\n",
                          fixed_enable, fixed_status));
@@ -258,9 +250,6 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event)
        if (!acpi_gbl_fixed_event_handlers[event].handler) {
                (void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
                                              enable_register_id,
-                                             (event ==
-                                              ACPI_EVENT_PCIE_WAKE) ?
-                                             ACPI_ENABLE_EVENT :
                                              ACPI_DISABLE_EVENT);
 
                ACPI_ERROR((AE_INFO,
index 37b3f641feaab238f50895cb8202af42d13588f1..bd936476dda9667c1b28714c867dce9703761479 100644 (file)
@@ -311,20 +311,6 @@ acpi_status acpi_hw_legacy_wake(u8 sleep_state)
                                    [ACPI_EVENT_SLEEP_BUTTON].
                                    status_register_id, ACPI_CLEAR_STATUS);
 
-       /* Enable pcie wake event if support */
-       if ((acpi_gbl_FADT.flags & ACPI_FADT_PCI_EXPRESS_WAKE)) {
-               (void)
-                   acpi_write_bit_register(acpi_gbl_fixed_event_info
-                                           [ACPI_EVENT_PCIE_WAKE].
-                                           enable_register_id,
-                                           ACPI_DISABLE_EVENT);
-               (void)
-                   acpi_write_bit_register(acpi_gbl_fixed_event_info
-                                           [ACPI_EVENT_PCIE_WAKE].
-                                           status_register_id,
-                                           ACPI_CLEAR_STATUS);
-       }
-
        acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING);
        return_ACPI_STATUS(status);
 }
index 53afa5edb6ecb79131626ac96dc0d9ccc4ba3ab1..cda6e16dddf78c8cc9c0dd1b04fb2563ecfe8e54 100644 (file)
@@ -186,10 +186,6 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] =
                                        ACPI_BITREG_RT_CLOCK_ENABLE,
                                        ACPI_BITMASK_RT_CLOCK_STATUS,
                                        ACPI_BITMASK_RT_CLOCK_ENABLE},
-       /* ACPI_EVENT_PCIE_WAKE     */ {ACPI_BITREG_PCIEXP_WAKE_STATUS,
-                                       ACPI_BITREG_PCIEXP_WAKE_DISABLE,
-                                       ACPI_BITMASK_PCIEXP_WAKE_STATUS,
-                                       ACPI_BITMASK_PCIEXP_WAKE_DISABLE},
 };
 #endif                         /* !ACPI_REDUCED_HARDWARE */
 
index 9531dd0fef5099715a594be4fa4e30f826ad1f8c..a96da65057b19bfb46f390966831a23509291dcb 100644 (file)
@@ -459,85 +459,67 @@ out_free:
                              Notification Handling
    -------------------------------------------------------------------------- */
 
-/*
- * acpi_bus_notify
- * ---------------
- * Callback for all 'system-level' device notifications (values 0x00-0x7F).
+/**
+ * acpi_bus_notify - Global system-level (0x00-0x7F) notifications handler
+ * @handle: Target ACPI object.
+ * @type: Notification type.
+ * @data: Ignored.
+ *
+ * This only handles notifications related to device hotplug.
  */
 static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
 {
        struct acpi_device *adev;
-       u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
-       bool hotplug_event = false;
 
        switch (type) {
        case ACPI_NOTIFY_BUS_CHECK:
                acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n");
-               hotplug_event = true;
                break;
 
        case ACPI_NOTIFY_DEVICE_CHECK:
                acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK event\n");
-               hotplug_event = true;
                break;
 
        case ACPI_NOTIFY_DEVICE_WAKE:
                acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_WAKE event\n");
-               break;
+               return;
 
        case ACPI_NOTIFY_EJECT_REQUEST:
                acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n");
-               hotplug_event = true;
                break;
 
        case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
                acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK_LIGHT event\n");
                /* TBD: Exactly what does 'light' mean? */
-               break;
+               return;
 
        case ACPI_NOTIFY_FREQUENCY_MISMATCH:
                acpi_handle_err(handle, "Device cannot be configured due "
                                "to a frequency mismatch\n");
-               break;
+               return;
 
        case ACPI_NOTIFY_BUS_MODE_MISMATCH:
                acpi_handle_err(handle, "Device cannot be configured due "
                                "to a bus mode mismatch\n");
-               break;
+               return;
 
        case ACPI_NOTIFY_POWER_FAULT:
                acpi_handle_err(handle, "Device has suffered a power fault\n");
-               break;
+               return;
 
        default:
                acpi_handle_debug(handle, "Unknown event type 0x%x\n", type);
-               break;
+               return;
        }
 
        adev = acpi_get_acpi_dev(handle);
-       if (!adev)
-               goto err;
-
-       if (adev->dev.driver) {
-               struct acpi_driver *driver = to_acpi_driver(adev->dev.driver);
-
-               if (driver && driver->ops.notify &&
-                   (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS))
-                       driver->ops.notify(adev, type);
-       }
-
-       if (!hotplug_event) {
-               acpi_put_acpi_dev(adev);
-               return;
-       }
 
-       if (ACPI_SUCCESS(acpi_hotplug_schedule(adev, type)))
+       if (adev && ACPI_SUCCESS(acpi_hotplug_schedule(adev, type)))
                return;
 
        acpi_put_acpi_dev(adev);
 
- err:
-       acpi_evaluate_ost(handle, type, ost_code, NULL);
+       acpi_evaluate_ost(handle, type, ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL);
 }
 
 static void acpi_notify_device(acpi_handle handle, u32 event, void *data)
@@ -562,42 +544,51 @@ static u32 acpi_device_fixed_event(void *data)
        return ACPI_INTERRUPT_HANDLED;
 }
 
-static int acpi_device_install_notify_handler(struct acpi_device *device)
+static int acpi_device_install_notify_handler(struct acpi_device *device,
+                                             struct acpi_driver *acpi_drv)
 {
        acpi_status status;
 
-       if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON)
+       if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) {
                status =
                    acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
                                                     acpi_device_fixed_event,
                                                     device);
-       else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON)
+       } else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) {
                status =
                    acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
                                                     acpi_device_fixed_event,
                                                     device);
-       else
-               status = acpi_install_notify_handler(device->handle,
-                                                    ACPI_DEVICE_NOTIFY,
+       } else {
+               u32 type = acpi_drv->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS ?
+                               ACPI_ALL_NOTIFY : ACPI_DEVICE_NOTIFY;
+
+               status = acpi_install_notify_handler(device->handle, type,
                                                     acpi_notify_device,
                                                     device);
+       }
 
        if (ACPI_FAILURE(status))
                return -EINVAL;
        return 0;
 }
 
-static void acpi_device_remove_notify_handler(struct acpi_device *device)
+static void acpi_device_remove_notify_handler(struct acpi_device *device,
+                                             struct acpi_driver *acpi_drv)
 {
-       if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON)
+       if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) {
                acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
                                                acpi_device_fixed_event);
-       else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON)
+       } else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) {
                acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
                                                acpi_device_fixed_event);
-       else
-               acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
+       } else {
+               u32 type = acpi_drv->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS ?
+                               ACPI_ALL_NOTIFY : ACPI_DEVICE_NOTIFY;
+
+               acpi_remove_notify_handler(device->handle, type,
                                           acpi_notify_device);
+       }
 }
 
 /* Handle events targeting \_SB device (at present only graceful shutdown) */
@@ -1039,7 +1030,7 @@ static int acpi_device_probe(struct device *dev)
                 acpi_drv->name, acpi_dev->pnp.bus_id);
 
        if (acpi_drv->ops.notify) {
-               ret = acpi_device_install_notify_handler(acpi_dev);
+               ret = acpi_device_install_notify_handler(acpi_dev, acpi_drv);
                if (ret) {
                        if (acpi_drv->ops.remove)
                                acpi_drv->ops.remove(acpi_dev);
@@ -1062,7 +1053,7 @@ static void acpi_device_remove(struct device *dev)
        struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver);
 
        if (acpi_drv->ops.notify)
-               acpi_device_remove_notify_handler(acpi_dev);
+               acpi_device_remove_notify_handler(acpi_dev, acpi_drv);
 
        if (acpi_drv->ops.remove)
                acpi_drv->ops.remove(acpi_dev);
index 10975bb603fb15c099165ad4fa15b88ab3c794ef..a35dd0e41c27043bc0cb6f8783c1bc0280cb1155 100644 (file)
@@ -536,16 +536,19 @@ static int topology_get_acpi_cpu_tag(struct acpi_table_header *table,
 static struct acpi_table_header *acpi_get_pptt(void)
 {
        static struct acpi_table_header *pptt;
+       static bool is_pptt_checked;
        acpi_status status;
 
        /*
         * PPTT will be used at runtime on every CPU hotplug in path, so we
         * don't need to call acpi_put_table() to release the table mapping.
         */
-       if (!pptt) {
+       if (!pptt && !is_pptt_checked) {
                status = acpi_get_table(ACPI_SIG_PPTT, 0, &pptt);
                if (ACPI_FAILURE(status))
                        acpi_pptt_warn_missing();
+
+               is_pptt_checked = true;
        }
 
        return pptt;
index 1278969eec1f9928ed75dbbd00aefa1620f08575..4bd16b3f0781481f6cfd54d760f47f3ad54b405a 100644 (file)
@@ -263,6 +263,12 @@ static int __init acpi_processor_driver_init(void)
        if (acpi_disabled)
                return 0;
 
+       if (!cpufreq_register_notifier(&acpi_processor_notifier_block,
+                                      CPUFREQ_POLICY_NOTIFIER)) {
+               acpi_processor_cpufreq_init = true;
+               acpi_processor_ignore_ppc_init();
+       }
+
        result = driver_register(&acpi_processor_driver);
        if (result < 0)
                return result;
@@ -276,12 +282,6 @@ static int __init acpi_processor_driver_init(void)
        cpuhp_setup_state_nocalls(CPUHP_ACPI_CPUDRV_DEAD, "acpi/cpu-drv:dead",
                                  NULL, acpi_soft_cpu_dead);
 
-       if (!cpufreq_register_notifier(&acpi_processor_notifier_block,
-                                      CPUFREQ_POLICY_NOTIFIER)) {
-               acpi_processor_cpufreq_init = true;
-               acpi_processor_ignore_ppc_init();
-       }
-
        acpi_processor_throttling_init();
        return 0;
 err:
index e534fd49a67e50877cc9ecd2672720fceed467f5..b7c6287eccca28c17908646a52af083d9e31a5dd 100644 (file)
@@ -140,9 +140,13 @@ void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy)
                ret = freq_qos_add_request(&policy->constraints,
                                           &pr->thermal_req,
                                           FREQ_QOS_MAX, INT_MAX);
-               if (ret < 0)
+               if (ret < 0) {
                        pr_err("Failed to add freq constraint for CPU%d (%d)\n",
                               cpu, ret);
+                       continue;
+               }
+
+               thermal_cooling_device_update(pr->cdev);
        }
 }
 
@@ -153,8 +157,12 @@ void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy)
        for_each_cpu(cpu, policy->related_cpus) {
                struct acpi_processor *pr = per_cpu(processors, cpu);
 
-               if (pr)
-                       freq_qos_remove_request(&pr->thermal_req);
+               if (!pr)
+                       continue;
+
+               freq_qos_remove_request(&pr->thermal_req);
+
+               thermal_cooling_device_update(pr->cdev);
        }
 }
 #else                          /* ! CONFIG_CPU_FREQ */
index 7c9125df5a651cfaca6da86adc9d6932cd97fdf4..e8492b3a393ab6932c1f6c791bee1c442688fb64 100644 (file)
@@ -400,6 +400,13 @@ static const struct dmi_system_id medion_laptop[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "M17T"),
                },
        },
+       {
+               .ident = "MEDION S17413",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
+                       DMI_MATCH(DMI_BOARD_NAME, "M1xA"),
+               },
+       },
        { }
 };
 
@@ -432,6 +439,13 @@ static const struct dmi_system_id asus_laptop[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "S5602ZA"),
                },
        },
+       {
+               .ident = "Asus ExpertBook B1502CBA",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_BOARD_NAME, "B1502CBA"),
+               },
+       },
        {
                .ident = "Asus ExpertBook B2402CBA",
                .matches = {
index 710ac640267dd301da56d7e504b1f3435fe91b42..e85729fc481fde1864222e5821d7ccaaf07da509 100644 (file)
@@ -276,6 +276,43 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
                },
        },
 
+       /*
+        * Models which need acpi_video backlight control where the GPU drivers
+        * do not call acpi_video_register_backlight() because no internal panel
+        * is detected. Typically these are all-in-ones (monitors with builtin
+        * PC) where the panel connection shows up as regular DP instead of eDP.
+        */
+       {
+        .callback = video_detect_force_video,
+        /* Apple iMac14,1 */
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "iMac14,1"),
+               },
+       },
+       {
+        .callback = video_detect_force_video,
+        /* Apple iMac14,2 */
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "iMac14,2"),
+               },
+       },
+
+       /*
+        * Older models with nvidia GPU which need acpi_video backlight
+        * control and where the old nvidia binary driver series does not
+        * call acpi_video_register_backlight().
+        */
+       {
+        .callback = video_detect_force_video,
+        /* ThinkPad W530 */
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+               DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W530"),
+               },
+       },
+
        /*
         * These models have a working acpi_video backlight control, and using
         * native backlight causes a regression where backlight does not work
@@ -495,6 +532,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
                DMI_MATCH(DMI_PRODUCT_NAME, "Precision 7510"),
                },
        },
+       {
+        .callback = video_detect_force_native,
+        /* Acer Aspire 3830TG */
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3830TG"),
+               },
+       },
        {
         .callback = video_detect_force_native,
         /* Acer Aspire 4810T */
@@ -716,6 +761,13 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
                DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"),
                },
        },
+       {
+        .callback = video_detect_force_native,
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 15 3535"),
+               },
+       },
 
        /*
         * Desktops which falsely report a backlight and which our heuristics
@@ -767,7 +819,7 @@ static bool prefer_native_over_acpi_video(void)
  * Determine which type of backlight interface to use on this system,
  * First check cmdline, then dmi quirks, then do autodetect.
  */
-static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
+enum acpi_backlight_type __acpi_video_get_backlight_type(bool native, bool *auto_detect)
 {
        static DEFINE_MUTEX(init_mutex);
        static bool nvidia_wmi_ec_present;
@@ -792,6 +844,9 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
                native_available = true;
        mutex_unlock(&init_mutex);
 
+       if (auto_detect)
+               *auto_detect = false;
+
        /*
         * The below heuristics / detection steps are in order of descending
         * presedence. The commandline takes presedence over anything else.
@@ -803,6 +858,9 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
        if (acpi_backlight_dmi != acpi_backlight_undef)
                return acpi_backlight_dmi;
 
+       if (auto_detect)
+               *auto_detect = true;
+
        /* Special cases such as nvidia_wmi_ec and apple gmux. */
        if (nvidia_wmi_ec_present)
                return acpi_backlight_nvidia_wmi_ec;
@@ -822,15 +880,4 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
        /* No ACPI video/native (old hw), use vendor specific fw methods. */
        return acpi_backlight_vendor;
 }
-
-enum acpi_backlight_type acpi_video_get_backlight_type(void)
-{
-       return __acpi_video_get_backlight_type(false);
-}
-EXPORT_SYMBOL(acpi_video_get_backlight_type);
-
-bool acpi_video_backlight_use_native(void)
-{
-       return __acpi_video_get_backlight_type(true) == acpi_backlight_native;
-}
-EXPORT_SYMBOL(acpi_video_backlight_use_native);
+EXPORT_SYMBOL(__acpi_video_get_backlight_type);
index e45285d4e62a423532414f2c052a6af963c39230..ba420a28a4aadce7c087183d2cb4deb178e3bd08 100644 (file)
@@ -213,6 +213,7 @@ bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *s
       disk in the system.
  */
 static const struct x86_cpu_id storage_d3_cpu_ids[] = {
+       X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 24, NULL),  /* Picasso */
        X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 96, NULL),  /* Renoir */
        X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 104, NULL), /* Lucienne */
        X86_MATCH_VENDOR_FAM_MODEL(AMD, 25, 80, NULL),  /* Cezanne */
@@ -251,6 +252,7 @@ bool force_storage_d3(void)
 #define ACPI_QUIRK_UART1_TTY_UART2_SKIP                                BIT(1)
 #define ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY                    BIT(2)
 #define ACPI_QUIRK_USE_ACPI_AC_AND_BATTERY                     BIT(3)
+#define ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS                    BIT(4)
 
 static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
        /*
@@ -279,6 +281,16 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
         *    need the x86-android-tablets module to properly work.
         */
 #if IS_ENABLED(CONFIG_X86_ANDROID_TABLETS)
+       {
+               /* Acer Iconia One 7 B1-750 */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "VESPA2"),
+               },
+               .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
+                                       ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY |
+                                       ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS),
+       },
        {
                .matches = {
                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
@@ -286,7 +298,19 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
                },
                .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
                                        ACPI_QUIRK_UART1_TTY_UART2_SKIP |
-                                       ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
+                                       ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY |
+                                       ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS),
+       },
+       {
+               /* Lenovo Yoga Book X90F/L */
+               .matches = {
+                       DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"),
+               },
+               .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
+                                       ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY |
+                                       ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS),
        },
        {
                .matches = {
@@ -294,7 +318,8 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"),
                },
                .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
-                                       ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
+                                       ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY |
+                                       ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS),
        },
        {
                /* Lenovo Yoga Tablet 2 1050F/L */
@@ -336,7 +361,8 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "M890BAP"),
                },
                .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
-                                       ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
+                                       ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY |
+                                       ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS),
        },
        {
                /* Whitelabel (sold as various brands) TM800A550L */
@@ -413,6 +439,20 @@ int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *s
        return 0;
 }
 EXPORT_SYMBOL_GPL(acpi_quirk_skip_serdev_enumeration);
+
+bool acpi_quirk_skip_gpio_event_handlers(void)
+{
+       const struct dmi_system_id *dmi_id;
+       long quirks;
+
+       dmi_id = dmi_first_match(acpi_quirk_skip_dmi_ids);
+       if (!dmi_id)
+               return false;
+
+       quirks = (unsigned long)dmi_id->driver_data;
+       return (quirks & ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS);
+}
+EXPORT_SYMBOL_GPL(acpi_quirk_skip_gpio_event_handlers);
 #endif
 
 /* Lists of PMIC ACPI HIDs with an (often better) native charger driver */
index 294a266a0dda579c58475678ade746f2e2c723ff..c1576d943b4364b861c85ec609fd51c21dbe46d4 100644 (file)
@@ -381,6 +381,7 @@ static void pata_parport_dev_release(struct device *dev)
 {
        struct pi_adapter *pi = container_of(dev, struct pi_adapter, dev);
 
+       ida_free(&pata_parport_bus_dev_ids, dev->id);
        kfree(pi);
 }
 
@@ -433,23 +434,27 @@ static struct pi_adapter *pi_init_one(struct parport *parport,
        if (bus_for_each_dev(&pata_parport_bus_type, NULL, &match, pi_find_dev))
                return NULL;
 
+       id = ida_alloc(&pata_parport_bus_dev_ids, GFP_KERNEL);
+       if (id < 0)
+               return NULL;
+
        pi = kzalloc(sizeof(struct pi_adapter), GFP_KERNEL);
-       if (!pi)
+       if (!pi) {
+               ida_free(&pata_parport_bus_dev_ids, id);
                return NULL;
+       }
 
        /* set up pi->dev before pi_probe_unit() so it can use dev_printk() */
        pi->dev.parent = &pata_parport_bus;
        pi->dev.bus = &pata_parport_bus_type;
        pi->dev.driver = &pr->driver;
        pi->dev.release = pata_parport_dev_release;
-       id = ida_alloc(&pata_parport_bus_dev_ids, GFP_KERNEL);
-       if (id < 0)
-               return NULL; /* pata_parport_dev_release will do kfree(pi) */
        pi->dev.id = id;
        dev_set_name(&pi->dev, "pata_parport.%u", pi->dev.id);
        if (device_register(&pi->dev)) {
                put_device(&pi->dev);
-               goto out_ida_free;
+               /* pata_parport_dev_release will do ida_free(dev->id) and kfree(pi) */
+               return NULL;
        }
 
        pi->proto = pr;
@@ -464,8 +469,7 @@ static struct pi_adapter *pi_init_one(struct parport *parport,
        pi->port = parport->base;
 
        par_cb.private = pi;
-       pi->pardev = parport_register_dev_model(parport, DRV_NAME, &par_cb,
-                                               pi->dev.id);
+       pi->pardev = parport_register_dev_model(parport, DRV_NAME, &par_cb, id);
        if (!pi->pardev)
                goto out_module_put;
 
@@ -487,12 +491,13 @@ static struct pi_adapter *pi_init_one(struct parport *parport,
 
        pi_connect(pi);
        if (ata_host_activate(host, 0, NULL, 0, &pata_parport_sht))
-               goto out_unreg_parport;
+               goto out_disconnect;
 
        return pi;
 
-out_unreg_parport:
+out_disconnect:
        pi_disconnect(pi);
+out_unreg_parport:
        parport_unregister_device(pi->pardev);
        if (pi->proto->release_proto)
                pi->proto->release_proto(pi);
@@ -500,8 +505,7 @@ out_module_put:
        module_put(pi->proto->owner);
 out_unreg_dev:
        device_unregister(&pi->dev);
-out_ida_free:
-       ida_free(&pata_parport_bus_dev_ids, pi->dev.id);
+       /* pata_parport_dev_release will do ida_free(dev->id) and kfree(pi) */
        return NULL;
 }
 
@@ -626,8 +630,7 @@ static void pi_remove_one(struct device *dev)
        pi_disconnect(pi);
        pi_release(pi);
        device_unregister(dev);
-       ida_free(&pata_parport_bus_dev_ids, dev->id);
-       /* pata_parport_dev_release will do kfree(pi) */
+       /* pata_parport_dev_release will do ida_free(dev->id) and kfree(pi) */
 }
 
 static ssize_t delete_device_store(struct bus_type *bus, const char *buf,
@@ -643,6 +646,7 @@ static ssize_t delete_device_store(struct bus_type *bus, const char *buf,
        }
 
        pi_remove_one(dev);
+       put_device(dev);
        mutex_unlock(&pi_mutex);
 
        return count;
index eec0cc2144e0227155df540cc2e0e75208e5d37b..e327a0229dc173442b2789a402a8ea0adb931cdd 100644 (file)
@@ -2909,6 +2909,7 @@ close_card_oam(struct idt77252_dev *card)
 
                                recycle_rx_pool_skb(card, &vc->rcv.rx_pool);
                        }
+                       kfree(vc);
                }
        }
 }
@@ -2952,6 +2953,15 @@ open_card_ubr0(struct idt77252_dev *card)
        return 0;
 }
 
+static void
+close_card_ubr0(struct idt77252_dev *card)
+{
+       struct vc_map *vc = card->vcs[0];
+
+       free_scq(card, vc->scq);
+       kfree(vc);
+}
+
 static int
 idt77252_dev_open(struct idt77252_dev *card)
 {
@@ -3001,6 +3011,7 @@ static void idt77252_dev_close(struct atm_dev *dev)
        struct idt77252_dev *card = dev->dev_data;
        u32 conf;
 
+       close_card_ubr0(card);
        close_card_oam(card);
 
        conf = SAR_CFG_RXPTH |  /* enable receive path           */
index f6573c335f4c4c17b6d5277d3af75e9e31226409..f3903d002819e8ef9f7702a4670613319e342267 100644 (file)
@@ -474,12 +474,18 @@ int detect_cache_attributes(unsigned int cpu)
 
 populate_leaves:
        /*
-        * populate_cache_leaves() may completely setup the cache leaves and
-        * shared_cpu_map or it may leave it partially setup.
+        * If LLC is valid the cache leaves were already populated so just go to
+        * update the cpu map.
         */
-       ret = populate_cache_leaves(cpu);
-       if (ret)
-               goto free_ci;
+       if (!last_level_cache_is_valid(cpu)) {
+               /*
+                * populate_cache_leaves() may completely setup the cache leaves and
+                * shared_cpu_map or it may leave it partially setup.
+                */
+               ret = populate_cache_leaves(cpu);
+               if (ret)
+                       goto free_ci;
+       }
 
        /*
         * For systems using DT for cache hierarchy, fw_token
index 182c6122f8152b7b3822562c38e69b0cabc7fb0c..c1815b9dae68efc6810fce4560668f612d5a0db6 100644 (file)
@@ -487,7 +487,8 @@ static const struct attribute_group *cpu_root_attr_groups[] = {
 bool cpu_is_hotpluggable(unsigned int cpu)
 {
        struct device *dev = get_cpu_device(cpu);
-       return dev && container_of(dev, struct cpu, dev)->hotpluggable;
+       return dev && container_of(dev, struct cpu, dev)->hotpluggable
+               && tick_nohz_cpu_hotpluggable(cpu);
 }
 EXPORT_SYMBOL_GPL(cpu_is_hotpluggable);
 
index 60757ac31701d220ceb892e4b99f028ab9afdeab..f49f2a5282e1512d99eef768529b71d293b53d4c 100644 (file)
@@ -1615,7 +1615,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
                        drbd_send_sync_param(peer_device);
        }
 
-       kvfree_rcu(old_disk_conf);
+       kvfree_rcu_mightsleep(old_disk_conf);
        kfree(old_plan);
        mod_timer(&device->request_timer, jiffies + HZ);
        goto success;
@@ -2446,7 +2446,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
 
        mutex_unlock(&connection->resource->conf_update);
        mutex_unlock(&connection->data.mutex);
-       kvfree_rcu(old_net_conf);
+       kvfree_rcu_mightsleep(old_net_conf);
 
        if (connection->cstate >= C_WF_REPORT_PARAMS) {
                struct drbd_peer_device *peer_device;
@@ -2860,7 +2860,7 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info)
                new_disk_conf->disk_size = (sector_t)rs.resize_size;
                rcu_assign_pointer(device->ldev->disk_conf, new_disk_conf);
                mutex_unlock(&device->resource->conf_update);
-               kvfree_rcu(old_disk_conf);
+               kvfree_rcu_mightsleep(old_disk_conf);
                new_disk_conf = NULL;
        }
 
index 757f4692b5bd8034909b32334b27f5e952bb935e..e197b2a465d22986a1e9ecb7e273ba12640fde59 100644 (file)
@@ -3759,7 +3759,7 @@ static int receive_protocol(struct drbd_connection *connection, struct packet_in
                drbd_info(connection, "peer data-integrity-alg: %s\n",
                          integrity_alg[0] ? integrity_alg : "(none)");
 
-       kvfree_rcu(old_net_conf);
+       kvfree_rcu_mightsleep(old_net_conf);
        return 0;
 
 disconnect_rcu_unlock:
@@ -4127,7 +4127,7 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info
 
                        rcu_assign_pointer(device->ldev->disk_conf, new_disk_conf);
                        mutex_unlock(&connection->resource->conf_update);
-                       kvfree_rcu(old_disk_conf);
+                       kvfree_rcu_mightsleep(old_disk_conf);
 
                        drbd_info(device, "Peer sets u_size to %lu sectors (old: %lu)\n",
                                 (unsigned long)p_usize, (unsigned long)my_usize);
index 75d13ea0024f554a2d425c8f3c87ac72aae2c260..2aeea295fa28ec61f4bf62a4d9bd2c76c540970c 100644 (file)
@@ -2071,7 +2071,7 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)
                conn_free_crypto(connection);
                mutex_unlock(&connection->resource->conf_update);
 
-               kvfree_rcu(old_conf);
+               kvfree_rcu_mightsleep(old_conf);
        }
 
        if (ns_max.susp_fen) {
index 839373451c2b7dc8d2db845decfeca198fce0452..bc31bb7072a2cb7294d32066f5d0aa14130349b4 100644 (file)
@@ -1010,9 +1010,6 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
        /* This is safe, since we have a reference from open(). */
        __module_get(THIS_MODULE);
 
-       /* suppress uevents while reconfiguring the device */
-       dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 1);
-
        /*
         * If we don't hold exclusive handle for the device, upgrade to it
         * here to avoid changing device under exclusive owner.
@@ -1067,6 +1064,9 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
                }
        }
 
+       /* suppress uevents while reconfiguring the device */
+       dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 1);
+
        disk_force_media_change(lo->lo_disk, DISK_EVENT_MEDIA_CHANGE);
        set_disk_ro(lo->lo_disk, (lo->lo_flags & LO_FLAGS_READ_ONLY) != 0);
 
@@ -1109,17 +1109,17 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
        if (partscan)
                clear_bit(GD_SUPPRESS_PART_SCAN, &lo->lo_disk->state);
 
+       /* enable and uncork uevent now that we are done */
+       dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 0);
+
        loop_global_unlock(lo, is_loop);
        if (partscan)
                loop_reread_partitions(lo);
+
        if (!(mode & FMODE_EXCL))
                bd_abort_claiming(bdev, loop_configure);
 
-       error = 0;
-done:
-       /* enable and uncork uevent now that we are done */
-       dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 0);
-       return error;
+       return 0;
 
 out_unlock:
        loop_global_unlock(lo, is_loop);
@@ -1130,7 +1130,7 @@ out_putf:
        fput(file);
        /* This is safe: open() is still holding a reference. */
        module_put(THIS_MODULE);
-       goto done;
+       return error;
 }
 
 static void __loop_clr_fd(struct loop_device *lo, bool release)
@@ -1859,35 +1859,44 @@ static blk_status_t loop_queue_rq(struct blk_mq_hw_ctx *hctx,
 
 static void loop_handle_cmd(struct loop_cmd *cmd)
 {
+       struct cgroup_subsys_state *cmd_blkcg_css = cmd->blkcg_css;
+       struct cgroup_subsys_state *cmd_memcg_css = cmd->memcg_css;
        struct request *rq = blk_mq_rq_from_pdu(cmd);
        const bool write = op_is_write(req_op(rq));
        struct loop_device *lo = rq->q->queuedata;
        int ret = 0;
        struct mem_cgroup *old_memcg = NULL;
+       const bool use_aio = cmd->use_aio;
 
        if (write && (lo->lo_flags & LO_FLAGS_READ_ONLY)) {
                ret = -EIO;
                goto failed;
        }
 
-       if (cmd->blkcg_css)
-               kthread_associate_blkcg(cmd->blkcg_css);
-       if (cmd->memcg_css)
+       if (cmd_blkcg_css)
+               kthread_associate_blkcg(cmd_blkcg_css);
+       if (cmd_memcg_css)
                old_memcg = set_active_memcg(
-                       mem_cgroup_from_css(cmd->memcg_css));
+                       mem_cgroup_from_css(cmd_memcg_css));
 
+       /*
+        * do_req_filebacked() may call blk_mq_complete_request() synchronously
+        * or asynchronously if using aio. Hence, do not touch 'cmd' after
+        * do_req_filebacked() has returned unless we are sure that 'cmd' has
+        * not yet been completed.
+        */
        ret = do_req_filebacked(lo, rq);
 
-       if (cmd->blkcg_css)
+       if (cmd_blkcg_css)
                kthread_associate_blkcg(NULL);
 
-       if (cmd->memcg_css) {
+       if (cmd_memcg_css) {
                set_active_memcg(old_memcg);
-               css_put(cmd->memcg_css);
+               css_put(cmd_memcg_css);
        }
  failed:
        /* complete non-aio request */
-       if (!cmd->use_aio || ret) {
+       if (!use_aio || ret) {
                if (ret == -EOPNOTSUPP)
                        cmd->ret = ret;
                else
index 4c601ca9552a07dd4ae9828c6703d1dc3d694b4c..9e6b032c8ecc2c93a2dffb32dcdcb0e6100f575b 100644 (file)
@@ -1413,8 +1413,7 @@ static inline void nullb_complete_cmd(struct nullb_cmd *cmd)
        case NULL_IRQ_SOFTIRQ:
                switch (cmd->nq->dev->queue_mode) {
                case NULL_Q_MQ:
-                       if (likely(!blk_should_fake_timeout(cmd->rq->q)))
-                               blk_mq_complete_request(cmd->rq);
+                       blk_mq_complete_request(cmd->rq);
                        break;
                case NULL_Q_BIO:
                        /*
@@ -1658,12 +1657,13 @@ static enum blk_eh_timer_return null_timeout_rq(struct request *rq)
 }
 
 static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx,
-                        const struct blk_mq_queue_data *bd)
+                                 const struct blk_mq_queue_data *bd)
 {
-       struct nullb_cmd *cmd = blk_mq_rq_to_pdu(bd->rq);
+       struct request *rq = bd->rq;
+       struct nullb_cmd *cmd = blk_mq_rq_to_pdu(rq);
        struct nullb_queue *nq = hctx->driver_data;
-       sector_t nr_sectors = blk_rq_sectors(bd->rq);
-       sector_t sector = blk_rq_pos(bd->rq);
+       sector_t nr_sectors = blk_rq_sectors(rq);
+       sector_t sector = blk_rq_pos(rq);
        const bool is_poll = hctx->type == HCTX_TYPE_POLL;
 
        might_sleep_if(hctx->flags & BLK_MQ_F_BLOCKING);
@@ -1672,14 +1672,15 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx,
                hrtimer_init(&cmd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
                cmd->timer.function = null_cmd_timer_expired;
        }
-       cmd->rq = bd->rq;
+       cmd->rq = rq;
        cmd->error = BLK_STS_OK;
        cmd->nq = nq;
-       cmd->fake_timeout = should_timeout_request(bd->rq);
+       cmd->fake_timeout = should_timeout_request(rq) ||
+               blk_should_fake_timeout(rq->q);
 
-       blk_mq_start_request(bd->rq);
+       blk_mq_start_request(rq);
 
-       if (should_requeue_request(bd->rq)) {
+       if (should_requeue_request(rq)) {
                /*
                 * Alternate between hitting the core BUSY path, and the
                 * driver driven requeue path
@@ -1687,22 +1688,20 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx,
                nq->requeue_selection++;
                if (nq->requeue_selection & 1)
                        return BLK_STS_RESOURCE;
-               else {
-                       blk_mq_requeue_request(bd->rq, true);
-                       return BLK_STS_OK;
-               }
+               blk_mq_requeue_request(rq, true);
+               return BLK_STS_OK;
        }
 
        if (is_poll) {
                spin_lock(&nq->poll_lock);
-               list_add_tail(&bd->rq->queuelist, &nq->poll_list);
+               list_add_tail(&rq->queuelist, &nq->poll_list);
                spin_unlock(&nq->poll_lock);
                return BLK_STS_OK;
        }
        if (cmd->fake_timeout)
                return BLK_STS_OK;
 
-       return null_handle_cmd(cmd, sector, nr_sectors, req_op(bd->rq));
+       return null_handle_cmd(cmd, sector, nr_sectors, req_op(rq));
 }
 
 static void cleanup_queue(struct nullb_queue *nq)
index fb855da971ee7b388efd1f385fe6c929bda97d4f..9fa821fa76b07b47d673f7d57c591fc8e5ddd4a9 100644 (file)
@@ -972,6 +972,8 @@ static int vdc_port_probe(struct vio_dev *vdev, const struct vio_device_id *id)
        print_version();
 
        hp = mdesc_grab();
+       if (!hp)
+               return -ENODEV;
 
        err = -ENODEV;
        if ((vdev->dev_no << PARTITION_SHIFT) & ~(u64)MINORMASK) {
index d1d1c8d606c8d8e9c79f094ffc626e2909df7b14..604c1a13c76efce3a2a3641ac5bf57d68775629d 100644 (file)
@@ -246,7 +246,7 @@ static int ublk_validate_params(const struct ublk_device *ub)
        if (ub->params.types & UBLK_PARAM_TYPE_BASIC) {
                const struct ublk_param_basic *p = &ub->params.basic;
 
-               if (p->logical_bs_shift > PAGE_SHIFT)
+               if (p->logical_bs_shift > PAGE_SHIFT || p->logical_bs_shift < 9)
                        return -EINVAL;
 
                if (p->logical_bs_shift > p->physical_bs_shift)
@@ -715,7 +715,8 @@ static void __ublk_fail_req(struct ublk_queue *ubq, struct ublk_io *io,
        }
 }
 
-static void ubq_complete_io_cmd(struct ublk_io *io, int res)
+static void ubq_complete_io_cmd(struct ublk_io *io, int res,
+                               unsigned issue_flags)
 {
        /* mark this cmd owned by ublksrv */
        io->flags |= UBLK_IO_FLAG_OWNED_BY_SRV;
@@ -727,7 +728,7 @@ static void ubq_complete_io_cmd(struct ublk_io *io, int res)
        io->flags &= ~UBLK_IO_FLAG_ACTIVE;
 
        /* tell ublksrv one io request is coming */
-       io_uring_cmd_done(io->cmd, res, 0);
+       io_uring_cmd_done(io->cmd, res, 0, issue_flags);
 }
 
 #define UBLK_REQUEUE_DELAY_MS  3
@@ -744,7 +745,8 @@ static inline void __ublk_abort_rq(struct ublk_queue *ubq,
        mod_delayed_work(system_wq, &ubq->dev->monitor_work, 0);
 }
 
-static inline void __ublk_rq_task_work(struct request *req)
+static inline void __ublk_rq_task_work(struct request *req,
+                                      unsigned issue_flags)
 {
        struct ublk_queue *ubq = req->mq_hctx->driver_data;
        int tag = req->tag;
@@ -782,7 +784,7 @@ static inline void __ublk_rq_task_work(struct request *req)
                        pr_devel("%s: need get data. op %d, qid %d tag %d io_flags %x\n",
                                        __func__, io->cmd->cmd_op, ubq->q_id,
                                        req->tag, io->flags);
-                       ubq_complete_io_cmd(io, UBLK_IO_RES_NEED_GET_DATA);
+                       ubq_complete_io_cmd(io, UBLK_IO_RES_NEED_GET_DATA, issue_flags);
                        return;
                }
                /*
@@ -820,17 +822,18 @@ static inline void __ublk_rq_task_work(struct request *req)
                        mapped_bytes >> 9;
        }
 
-       ubq_complete_io_cmd(io, UBLK_IO_RES_OK);
+       ubq_complete_io_cmd(io, UBLK_IO_RES_OK, issue_flags);
 }
 
-static inline void ublk_forward_io_cmds(struct ublk_queue *ubq)
+static inline void ublk_forward_io_cmds(struct ublk_queue *ubq,
+                                       unsigned issue_flags)
 {
        struct llist_node *io_cmds = llist_del_all(&ubq->io_cmds);
        struct ublk_rq_data *data, *tmp;
 
        io_cmds = llist_reverse_order(io_cmds);
        llist_for_each_entry_safe(data, tmp, io_cmds, node)
-               __ublk_rq_task_work(blk_mq_rq_from_pdu(data));
+               __ublk_rq_task_work(blk_mq_rq_from_pdu(data), issue_flags);
 }
 
 static inline void ublk_abort_io_cmds(struct ublk_queue *ubq)
@@ -842,12 +845,12 @@ static inline void ublk_abort_io_cmds(struct ublk_queue *ubq)
                __ublk_abort_rq(ubq, blk_mq_rq_from_pdu(data));
 }
 
-static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd)
+static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd, unsigned issue_flags)
 {
        struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd);
        struct ublk_queue *ubq = pdu->ubq;
 
-       ublk_forward_io_cmds(ubq);
+       ublk_forward_io_cmds(ubq, issue_flags);
 }
 
 static void ublk_rq_task_work_fn(struct callback_head *work)
@@ -856,8 +859,9 @@ static void ublk_rq_task_work_fn(struct callback_head *work)
                        struct ublk_rq_data, work);
        struct request *req = blk_mq_rq_from_pdu(data);
        struct ublk_queue *ubq = req->mq_hctx->driver_data;
+       unsigned issue_flags = IO_URING_F_UNLOCKED;
 
-       ublk_forward_io_cmds(ubq);
+       ublk_forward_io_cmds(ubq, issue_flags);
 }
 
 static void ublk_queue_cmd(struct ublk_queue *ubq, struct request *rq)
@@ -1111,7 +1115,8 @@ static void ublk_cancel_queue(struct ublk_queue *ubq)
                struct ublk_io *io = &ubq->ios[i];
 
                if (io->flags & UBLK_IO_FLAG_ACTIVE)
-                       io_uring_cmd_done(io->cmd, UBLK_IO_RES_ABORT, 0);
+                       io_uring_cmd_done(io->cmd, UBLK_IO_RES_ABORT, 0,
+                                               IO_URING_F_UNLOCKED);
        }
 
        /* all io commands are canceled */
@@ -1256,9 +1261,10 @@ static void ublk_handle_need_get_data(struct ublk_device *ub, int q_id,
        ublk_queue_cmd(ubq, req);
 }
 
-static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
+static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd,
+                              unsigned int issue_flags,
+                              struct ublksrv_io_cmd *ub_cmd)
 {
-       struct ublksrv_io_cmd *ub_cmd = (struct ublksrv_io_cmd *)cmd->cmd;
        struct ublk_device *ub = cmd->file->private_data;
        struct ublk_queue *ubq;
        struct ublk_io *io;
@@ -1351,12 +1357,29 @@ static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
        return -EIOCBQUEUED;
 
  out:
-       io_uring_cmd_done(cmd, ret, 0);
+       io_uring_cmd_done(cmd, ret, 0, issue_flags);
        pr_devel("%s: complete: cmd op %d, tag %d ret %x io_flags %x\n",
                        __func__, cmd_op, tag, ret, io->flags);
        return -EIOCBQUEUED;
 }
 
+static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
+{
+       struct ublksrv_io_cmd *ub_src = (struct ublksrv_io_cmd *) cmd->cmd;
+       struct ublksrv_io_cmd ub_cmd;
+
+       /*
+        * Not necessary for async retry, but let's keep it simple and always
+        * copy the values to avoid any potential reuse.
+        */
+       ub_cmd.q_id = READ_ONCE(ub_src->q_id);
+       ub_cmd.tag = READ_ONCE(ub_src->tag);
+       ub_cmd.result = READ_ONCE(ub_src->result);
+       ub_cmd.addr = READ_ONCE(ub_src->addr);
+
+       return __ublk_ch_uring_cmd(cmd, issue_flags, &ub_cmd);
+}
+
 static const struct file_operations ublk_ch_fops = {
        .owner = THIS_MODULE,
        .open = ublk_ch_open,
@@ -1602,17 +1625,18 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub, struct io_uring_cmd *cmd)
                set_bit(GD_SUPPRESS_PART_SCAN, &disk->state);
 
        get_device(&ub->cdev_dev);
+       ub->dev_info.state = UBLK_S_DEV_LIVE;
        ret = add_disk(disk);
        if (ret) {
                /*
                 * Has to drop the reference since ->free_disk won't be
                 * called in case of add_disk failure.
                 */
+               ub->dev_info.state = UBLK_S_DEV_DEAD;
                ublk_put_device(ub);
                goto out_put_disk;
        }
        set_bit(UB_STATE_USED, &ub->state);
-       ub->dev_info.state = UBLK_S_DEV_LIVE;
 out_put_disk:
        if (ret)
                put_disk(disk);
@@ -1946,6 +1970,8 @@ static int ublk_ctrl_set_params(struct ublk_device *ub,
                /* clear all we don't support yet */
                ub->params.types &= UBLK_PARAM_TYPE_ALL;
                ret = ublk_validate_params(ub);
+               if (ret)
+                       ub->params.types = 0;
        }
        mutex_unlock(&ub->mutex);
 
@@ -2233,7 +2259,7 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd,
        if (ub)
                ublk_put_device(ub);
  out:
-       io_uring_cmd_done(cmd, ret, 0);
+       io_uring_cmd_done(cmd, ret, 0, issue_flags);
        pr_devel("%s: cmd done ret %d cmd_op %x, dev id %d qid %d\n",
                        __func__, ret, cmd->cmd_op, header->dev_id, header->queue_id);
        return -EIOCBQUEUED;
index 2723eede6f217ea1f8fdf8e46a7965d12fe22ba9..2b918e28acaacd973221e56344977053072f7f7d 100644 (file)
@@ -96,16 +96,14 @@ struct virtblk_req {
 
                /*
                 * The zone append command has an extended in header.
-                * The status field in zone_append_in_hdr must have
-                * the same offset in virtblk_req as the non-zoned
-                * status field above.
+                * The status field in zone_append_in_hdr must always
+                * be the last byte.
                 */
                struct {
+                       __virtio64 sector;
                        u8 status;
-                       u8 reserved[7];
-                       __le64 append_sector;
-               } zone_append_in_hdr;
-       };
+               } zone_append;
+       } in_hdr;
 
        size_t in_hdr_len;
 
@@ -154,7 +152,7 @@ static int virtblk_add_req(struct virtqueue *vq, struct virtblk_req *vbr)
                        sgs[num_out + num_in++] = vbr->sg_table.sgl;
        }
 
-       sg_init_one(&in_hdr, &vbr->status, vbr->in_hdr_len);
+       sg_init_one(&in_hdr, &vbr->in_hdr.status, vbr->in_hdr_len);
        sgs[num_out + num_in++] = &in_hdr;
 
        return virtqueue_add_sgs(vq, sgs, num_out, num_in, vbr, GFP_ATOMIC);
@@ -242,11 +240,14 @@ static blk_status_t virtblk_setup_cmd(struct virtio_device *vdev,
                                      struct request *req,
                                      struct virtblk_req *vbr)
 {
-       size_t in_hdr_len = sizeof(vbr->status);
+       size_t in_hdr_len = sizeof(vbr->in_hdr.status);
        bool unmap = false;
        u32 type;
        u64 sector = 0;
 
+       if (!IS_ENABLED(CONFIG_BLK_DEV_ZONED) && op_is_zone_mgmt(req_op(req)))
+               return BLK_STS_NOTSUPP;
+
        /* Set fields for all request types */
        vbr->out_hdr.ioprio = cpu_to_virtio32(vdev, req_get_ioprio(req));
 
@@ -287,7 +288,7 @@ static blk_status_t virtblk_setup_cmd(struct virtio_device *vdev,
        case REQ_OP_ZONE_APPEND:
                type = VIRTIO_BLK_T_ZONE_APPEND;
                sector = blk_rq_pos(req);
-               in_hdr_len = sizeof(vbr->zone_append_in_hdr);
+               in_hdr_len = sizeof(vbr->in_hdr.zone_append);
                break;
        case REQ_OP_ZONE_RESET:
                type = VIRTIO_BLK_T_ZONE_RESET;
@@ -297,7 +298,10 @@ static blk_status_t virtblk_setup_cmd(struct virtio_device *vdev,
                type = VIRTIO_BLK_T_ZONE_RESET_ALL;
                break;
        case REQ_OP_DRV_IN:
-               /* Out header already filled in, nothing to do */
+               /*
+                * Out header has already been prepared by the caller (virtblk_get_id()
+                * or virtblk_submit_zone_report()), nothing to do here.
+                */
                return 0;
        default:
                WARN_ON_ONCE(1);
@@ -318,16 +322,28 @@ static blk_status_t virtblk_setup_cmd(struct virtio_device *vdev,
        return 0;
 }
 
+/*
+ * The status byte is always the last byte of the virtblk request
+ * in-header. This helper fetches its value for all in-header formats
+ * that are currently defined.
+ */
+static inline u8 virtblk_vbr_status(struct virtblk_req *vbr)
+{
+       return *((u8 *)&vbr->in_hdr + vbr->in_hdr_len - 1);
+}
+
 static inline void virtblk_request_done(struct request *req)
 {
        struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
-       blk_status_t status = virtblk_result(vbr->status);
+       blk_status_t status = virtblk_result(virtblk_vbr_status(vbr));
+       struct virtio_blk *vblk = req->mq_hctx->queue->queuedata;
 
        virtblk_unmap_data(req, vbr);
        virtblk_cleanup_cmd(req);
 
        if (req_op(req) == REQ_OP_ZONE_APPEND)
-               req->__sector = le64_to_cpu(vbr->zone_append_in_hdr.append_sector);
+               req->__sector = virtio64_to_cpu(vblk->vdev,
+                                               vbr->in_hdr.zone_append.sector);
 
        blk_mq_end_request(req, status);
 }
@@ -355,7 +371,7 @@ static int virtblk_handle_req(struct virtio_blk_vq *vq,
 
                if (likely(!blk_should_fake_timeout(req->q)) &&
                    !blk_mq_complete_request_remote(req) &&
-                   !blk_mq_add_to_batch(req, iob, vbr->status,
+                   !blk_mq_add_to_batch(req, iob, virtblk_vbr_status(vbr),
                                         virtblk_complete_batch))
                        virtblk_request_done(req);
                req_done++;
@@ -550,7 +566,6 @@ static void virtio_queue_rqs(struct request **rqlist)
 #ifdef CONFIG_BLK_DEV_ZONED
 static void *virtblk_alloc_report_buffer(struct virtio_blk *vblk,
                                          unsigned int nr_zones,
-                                         unsigned int zone_sectors,
                                          size_t *buflen)
 {
        struct request_queue *q = vblk->disk->queue;
@@ -558,7 +573,7 @@ static void *virtblk_alloc_report_buffer(struct virtio_blk *vblk,
        void *buf;
 
        nr_zones = min_t(unsigned int, nr_zones,
-                        get_capacity(vblk->disk) >> ilog2(zone_sectors));
+                        get_capacity(vblk->disk) >> ilog2(vblk->zone_sectors));
 
        bufsize = sizeof(struct virtio_blk_zone_report) +
                nr_zones * sizeof(struct virtio_blk_zone_descriptor);
@@ -592,7 +607,7 @@ static int virtblk_submit_zone_report(struct virtio_blk *vblk,
                return PTR_ERR(req);
 
        vbr = blk_mq_rq_to_pdu(req);
-       vbr->in_hdr_len = sizeof(vbr->status);
+       vbr->in_hdr_len = sizeof(vbr->in_hdr.status);
        vbr->out_hdr.type = cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_ZONE_REPORT);
        vbr->out_hdr.sector = cpu_to_virtio64(vblk->vdev, sector);
 
@@ -601,7 +616,7 @@ static int virtblk_submit_zone_report(struct virtio_blk *vblk,
                goto out;
 
        blk_execute_rq(req, false);
-       err = blk_status_to_errno(virtblk_result(vbr->status));
+       err = blk_status_to_errno(virtblk_result(vbr->in_hdr.status));
 out:
        blk_mq_free_request(req);
        return err;
@@ -609,29 +624,72 @@ out:
 
 static int virtblk_parse_zone(struct virtio_blk *vblk,
                               struct virtio_blk_zone_descriptor *entry,
-                              unsigned int idx, unsigned int zone_sectors,
-                              report_zones_cb cb, void *data)
+                              unsigned int idx, report_zones_cb cb, void *data)
 {
        struct blk_zone zone = { };
 
-       if (entry->z_type != VIRTIO_BLK_ZT_SWR &&
-           entry->z_type != VIRTIO_BLK_ZT_SWP &&
-           entry->z_type != VIRTIO_BLK_ZT_CONV) {
-               dev_err(&vblk->vdev->dev, "invalid zone type %#x\n",
-                       entry->z_type);
-               return -EINVAL;
+       zone.start = virtio64_to_cpu(vblk->vdev, entry->z_start);
+       if (zone.start + vblk->zone_sectors <= get_capacity(vblk->disk))
+               zone.len = vblk->zone_sectors;
+       else
+               zone.len = get_capacity(vblk->disk) - zone.start;
+       zone.capacity = virtio64_to_cpu(vblk->vdev, entry->z_cap);
+       zone.wp = virtio64_to_cpu(vblk->vdev, entry->z_wp);
+
+       switch (entry->z_type) {
+       case VIRTIO_BLK_ZT_SWR:
+               zone.type = BLK_ZONE_TYPE_SEQWRITE_REQ;
+               break;
+       case VIRTIO_BLK_ZT_SWP:
+               zone.type = BLK_ZONE_TYPE_SEQWRITE_PREF;
+               break;
+       case VIRTIO_BLK_ZT_CONV:
+               zone.type = BLK_ZONE_TYPE_CONVENTIONAL;
+               break;
+       default:
+               dev_err(&vblk->vdev->dev, "zone %llu: invalid type %#x\n",
+                       zone.start, entry->z_type);
+               return -EIO;
        }
 
-       zone.type = entry->z_type;
-       zone.cond = entry->z_state;
-       zone.len = zone_sectors;
-       zone.capacity = le64_to_cpu(entry->z_cap);
-       zone.start = le64_to_cpu(entry->z_start);
-       if (zone.cond == BLK_ZONE_COND_FULL)
+       switch (entry->z_state) {
+       case VIRTIO_BLK_ZS_EMPTY:
+               zone.cond = BLK_ZONE_COND_EMPTY;
+               break;
+       case VIRTIO_BLK_ZS_CLOSED:
+               zone.cond = BLK_ZONE_COND_CLOSED;
+               break;
+       case VIRTIO_BLK_ZS_FULL:
+               zone.cond = BLK_ZONE_COND_FULL;
                zone.wp = zone.start + zone.len;
-       else
-               zone.wp = le64_to_cpu(entry->z_wp);
+               break;
+       case VIRTIO_BLK_ZS_EOPEN:
+               zone.cond = BLK_ZONE_COND_EXP_OPEN;
+               break;
+       case VIRTIO_BLK_ZS_IOPEN:
+               zone.cond = BLK_ZONE_COND_IMP_OPEN;
+               break;
+       case VIRTIO_BLK_ZS_NOT_WP:
+               zone.cond = BLK_ZONE_COND_NOT_WP;
+               break;
+       case VIRTIO_BLK_ZS_RDONLY:
+               zone.cond = BLK_ZONE_COND_READONLY;
+               zone.wp = ULONG_MAX;
+               break;
+       case VIRTIO_BLK_ZS_OFFLINE:
+               zone.cond = BLK_ZONE_COND_OFFLINE;
+               zone.wp = ULONG_MAX;
+               break;
+       default:
+               dev_err(&vblk->vdev->dev, "zone %llu: invalid condition %#x\n",
+                       zone.start, entry->z_state);
+               return -EIO;
+       }
 
+       /*
+        * The callback below checks the validity of the reported
+        * entry data, no need to further validate it here.
+        */
        return cb(&zone, idx, data);
 }
 
@@ -641,39 +699,47 @@ static int virtblk_report_zones(struct gendisk *disk, sector_t sector,
 {
        struct virtio_blk *vblk = disk->private_data;
        struct virtio_blk_zone_report *report;
-       unsigned int zone_sectors = vblk->zone_sectors;
-       unsigned int nz, i;
-       int ret, zone_idx = 0;
+       unsigned long long nz, i;
        size_t buflen;
+       unsigned int zone_idx = 0;
+       int ret;
 
        if (WARN_ON_ONCE(!vblk->zone_sectors))
                return -EOPNOTSUPP;
 
-       report = virtblk_alloc_report_buffer(vblk, nr_zones,
-                                            zone_sectors, &buflen);
+       report = virtblk_alloc_report_buffer(vblk, nr_zones, &buflen);
        if (!report)
                return -ENOMEM;
 
+       mutex_lock(&vblk->vdev_mutex);
+
+       if (!vblk->vdev) {
+               ret = -ENXIO;
+               goto fail_report;
+       }
+
        while (zone_idx < nr_zones && sector < get_capacity(vblk->disk)) {
                memset(report, 0, buflen);
 
                ret = virtblk_submit_zone_report(vblk, (char *)report,
                                                 buflen, sector);
-               if (ret) {
-                       if (ret > 0)
-                               ret = -EIO;
-                       goto out_free;
-               }
-               nz = min((unsigned int)le64_to_cpu(report->nr_zones), nr_zones);
+               if (ret)
+                       goto fail_report;
+
+               nz = min_t(u64, virtio64_to_cpu(vblk->vdev, report->nr_zones),
+                          nr_zones);
                if (!nz)
                        break;
 
                for (i = 0; i < nz && zone_idx < nr_zones; i++) {
                        ret = virtblk_parse_zone(vblk, &report->zones[i],
-                                                zone_idx, zone_sectors, cb, data);
+                                                zone_idx, cb, data);
                        if (ret)
-                               goto out_free;
-                       sector = le64_to_cpu(report->zones[i].z_start) + zone_sectors;
+                               goto fail_report;
+
+                       sector = virtio64_to_cpu(vblk->vdev,
+                                                report->zones[i].z_start) +
+                                vblk->zone_sectors;
                        zone_idx++;
                }
        }
@@ -682,7 +748,8 @@ static int virtblk_report_zones(struct gendisk *disk, sector_t sector,
                ret = zone_idx;
        else
                ret = -EINVAL;
-out_free:
+fail_report:
+       mutex_unlock(&vblk->vdev_mutex);
        kvfree(report);
        return ret;
 }
@@ -691,20 +758,28 @@ static void virtblk_revalidate_zones(struct virtio_blk *vblk)
 {
        u8 model;
 
-       if (!vblk->zone_sectors)
-               return;
-
        virtio_cread(vblk->vdev, struct virtio_blk_config,
                     zoned.model, &model);
-       if (!blk_revalidate_disk_zones(vblk->disk, NULL))
-               set_capacity_and_notify(vblk->disk, 0);
+       switch (model) {
+       default:
+               dev_err(&vblk->vdev->dev, "unknown zone model %d\n", model);
+               fallthrough;
+       case VIRTIO_BLK_Z_NONE:
+       case VIRTIO_BLK_Z_HA:
+               disk_set_zoned(vblk->disk, BLK_ZONED_NONE);
+               return;
+       case VIRTIO_BLK_Z_HM:
+               WARN_ON_ONCE(!vblk->zone_sectors);
+               if (!blk_revalidate_disk_zones(vblk->disk, NULL))
+                       set_capacity_and_notify(vblk->disk, 0);
+       }
 }
 
 static int virtblk_probe_zoned_device(struct virtio_device *vdev,
                                       struct virtio_blk *vblk,
                                       struct request_queue *q)
 {
-       u32 v;
+       u32 v, wg;
        u8 model;
        int ret;
 
@@ -713,16 +788,11 @@ static int virtblk_probe_zoned_device(struct virtio_device *vdev,
 
        switch (model) {
        case VIRTIO_BLK_Z_NONE:
+       case VIRTIO_BLK_Z_HA:
+               /* Present the host-aware device as non-zoned */
                return 0;
        case VIRTIO_BLK_Z_HM:
                break;
-       case VIRTIO_BLK_Z_HA:
-               /*
-                * Present the host-aware device as a regular drive.
-                * TODO It is possible to add an option to make it appear
-                * in the system as a zoned drive.
-                */
-               return 0;
        default:
                dev_err(&vdev->dev, "unsupported zone model %d\n", model);
                return -EINVAL;
@@ -735,32 +805,31 @@ static int virtblk_probe_zoned_device(struct virtio_device *vdev,
 
        virtio_cread(vdev, struct virtio_blk_config,
                     zoned.max_open_zones, &v);
-       disk_set_max_open_zones(vblk->disk, le32_to_cpu(v));
-
-       dev_dbg(&vdev->dev, "max open zones = %u\n", le32_to_cpu(v));
+       disk_set_max_open_zones(vblk->disk, v);
+       dev_dbg(&vdev->dev, "max open zones = %u\n", v);
 
        virtio_cread(vdev, struct virtio_blk_config,
                     zoned.max_active_zones, &v);
-       disk_set_max_active_zones(vblk->disk, le32_to_cpu(v));
-       dev_dbg(&vdev->dev, "max active zones = %u\n", le32_to_cpu(v));
+       disk_set_max_active_zones(vblk->disk, v);
+       dev_dbg(&vdev->dev, "max active zones = %u\n", v);
 
        virtio_cread(vdev, struct virtio_blk_config,
-                    zoned.write_granularity, &v);
-       if (!v) {
+                    zoned.write_granularity, &wg);
+       if (!wg) {
                dev_warn(&vdev->dev, "zero write granularity reported\n");
                return -ENODEV;
        }
-       blk_queue_physical_block_size(q, le32_to_cpu(v));
-       blk_queue_io_min(q, le32_to_cpu(v));
+       blk_queue_physical_block_size(q, wg);
+       blk_queue_io_min(q, wg);
 
-       dev_dbg(&vdev->dev, "write granularity = %u\n", le32_to_cpu(v));
+       dev_dbg(&vdev->dev, "write granularity = %u\n", wg);
 
        /*
         * virtio ZBD specification doesn't require zones to be a power of
         * two sectors in size, but the code in this driver expects that.
         */
-       virtio_cread(vdev, struct virtio_blk_config, zoned.zone_sectors, &v);
-       vblk->zone_sectors = le32_to_cpu(v);
+       virtio_cread(vdev, struct virtio_blk_config, zoned.zone_sectors,
+                    &vblk->zone_sectors);
        if (vblk->zone_sectors == 0 || !is_power_of_2(vblk->zone_sectors)) {
                dev_err(&vdev->dev,
                        "zoned device with non power of two zone size %u\n",
@@ -783,36 +852,46 @@ static int virtblk_probe_zoned_device(struct virtio_device *vdev,
                        dev_warn(&vdev->dev, "zero max_append_sectors reported\n");
                        return -ENODEV;
                }
-               blk_queue_max_zone_append_sectors(q, le32_to_cpu(v));
-               dev_dbg(&vdev->dev, "max append sectors = %u\n", le32_to_cpu(v));
+               if ((v << SECTOR_SHIFT) < wg) {
+                       dev_err(&vdev->dev,
+                               "write granularity %u exceeds max_append_sectors %u limit\n",
+                               wg, v);
+                       return -ENODEV;
+               }
+
+               blk_queue_max_zone_append_sectors(q, v);
+               dev_dbg(&vdev->dev, "max append sectors = %u\n", v);
        }
 
        return ret;
 }
 
-static inline bool virtblk_has_zoned_feature(struct virtio_device *vdev)
-{
-       return virtio_has_feature(vdev, VIRTIO_BLK_F_ZONED);
-}
 #else
 
 /*
  * Zoned block device support is not configured in this kernel.
- * We only need to define a few symbols to avoid compilation errors.
+ * Host-managed zoned devices can't be supported, but others are
+ * good to go as regular block devices.
  */
 #define virtblk_report_zones       NULL
+
 static inline void virtblk_revalidate_zones(struct virtio_blk *vblk)
 {
 }
+
 static inline int virtblk_probe_zoned_device(struct virtio_device *vdev,
                        struct virtio_blk *vblk, struct request_queue *q)
 {
-       return -EOPNOTSUPP;
-}
+       u8 model;
 
-static inline bool virtblk_has_zoned_feature(struct virtio_device *vdev)
-{
-       return false;
+       virtio_cread(vdev, struct virtio_blk_config, zoned.model, &model);
+       if (model == VIRTIO_BLK_Z_HM) {
+               dev_err(&vdev->dev,
+                       "virtio_blk: zoned devices are not supported");
+               return -EOPNOTSUPP;
+       }
+
+       return 0;
 }
 #endif /* CONFIG_BLK_DEV_ZONED */
 
@@ -831,7 +910,7 @@ static int virtblk_get_id(struct gendisk *disk, char *id_str)
                return PTR_ERR(req);
 
        vbr = blk_mq_rq_to_pdu(req);
-       vbr->in_hdr_len = sizeof(vbr->status);
+       vbr->in_hdr_len = sizeof(vbr->in_hdr.status);
        vbr->out_hdr.type = cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_GET_ID);
        vbr->out_hdr.sector = 0;
 
@@ -840,7 +919,7 @@ static int virtblk_get_id(struct gendisk *disk, char *id_str)
                goto out;
 
        blk_execute_rq(req, false);
-       err = blk_status_to_errno(virtblk_result(vbr->status));
+       err = blk_status_to_errno(virtblk_result(vbr->in_hdr.status));
 out:
        blk_mq_free_request(req);
        return err;
@@ -1498,15 +1577,16 @@ static int virtblk_probe(struct virtio_device *vdev)
        virtblk_update_capacity(vblk, false);
        virtio_device_ready(vdev);
 
-       if (virtblk_has_zoned_feature(vdev)) {
+       /*
+        * All steps that follow use the VQs therefore they need to be
+        * placed after the virtio_device_ready() call above.
+        */
+       if (virtio_has_feature(vdev, VIRTIO_BLK_F_ZONED)) {
                err = virtblk_probe_zoned_device(vdev, vblk, q);
                if (err)
                        goto out_cleanup_disk;
        }
 
-       dev_info(&vdev->dev, "blk config size: %zu\n",
-               sizeof(struct virtio_blk_config));
-
        err = device_add_disk(&vdev->dev, vblk->disk, virtblk_attr_groups);
        if (err)
                goto out_cleanup_disk;
@@ -1607,10 +1687,7 @@ static unsigned int features[] = {
        VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
        VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE,
        VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_WRITE_ZEROES,
-       VIRTIO_BLK_F_SECURE_ERASE,
-#ifdef CONFIG_BLK_DEV_ZONED
-       VIRTIO_BLK_F_ZONED,
-#endif /* CONFIG_BLK_DEV_ZONED */
+       VIRTIO_BLK_F_SECURE_ERASE, VIRTIO_BLK_F_ZONED,
 };
 
 static struct virtio_driver virtio_blk = {
index 3006e2a0f37e1fa960f454ea0376f7e4e758c539..43e98a598bd9a51994bbbed072ad98b0f1a696b2 100644 (file)
@@ -511,7 +511,7 @@ static const char *btbcm_get_board_name(struct device *dev)
        len = strlen(tmp) + 1;
        board_type = devm_kzalloc(dev, len, GFP_KERNEL);
        strscpy(board_type, tmp, len);
-       for (i = 0; i < board_type[i]; i++) {
+       for (i = 0; i < len; i++) {
                if (board_type[i] == '/')
                        board_type[i] = '-';
        }
index bede8b0055940b69ad75c5f02aa6722d26627836..af774688f1c0dacf18e6cce1749c558bfcd6bd3f 100644 (file)
 #define ECDSA_HEADER_LEN       320
 
 #define BTINTEL_PPAG_NAME   "PPAG"
-#define BTINTEL_PPAG_PREFIX "\\_SB_.PCI0.XHCI.RHUB"
+
+/* structure to store the PPAG data read from ACPI table */
+struct btintel_ppag {
+       u32     domain;
+       u32     mode;
+       acpi_status status;
+       struct hci_dev *hdev;
+};
 
 #define CMD_WRITE_BOOT_PARAMS  0xfc0e
 struct cmd_write_boot_params {
@@ -1295,17 +1302,16 @@ static acpi_status btintel_ppag_callback(acpi_handle handle, u32 lvl, void *data
 
        status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
        if (ACPI_FAILURE(status)) {
-               bt_dev_warn(hdev, "ACPI Failure: %s", acpi_format_exception(status));
+               bt_dev_warn(hdev, "PPAG-BT: ACPI Failure: %s", acpi_format_exception(status));
                return status;
        }
 
-       if (strncmp(BTINTEL_PPAG_PREFIX, string.pointer,
-                   strlen(BTINTEL_PPAG_PREFIX))) {
+       len = strlen(string.pointer);
+       if (len < strlen(BTINTEL_PPAG_NAME)) {
                kfree(string.pointer);
                return AE_OK;
        }
 
-       len = strlen(string.pointer);
        if (strncmp((char *)string.pointer + len - 4, BTINTEL_PPAG_NAME, 4)) {
                kfree(string.pointer);
                return AE_OK;
@@ -1314,7 +1320,8 @@ static acpi_status btintel_ppag_callback(acpi_handle handle, u32 lvl, void *data
 
        status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
        if (ACPI_FAILURE(status)) {
-               bt_dev_warn(hdev, "ACPI Failure: %s", acpi_format_exception(status));
+               ppag->status = status;
+               bt_dev_warn(hdev, "PPAG-BT: ACPI Failure: %s", acpi_format_exception(status));
                return status;
        }
 
@@ -1323,8 +1330,9 @@ static acpi_status btintel_ppag_callback(acpi_handle handle, u32 lvl, void *data
 
        if (p->type != ACPI_TYPE_PACKAGE || p->package.count != 2) {
                kfree(buffer.pointer);
-               bt_dev_warn(hdev, "Invalid object type: %d or package count: %d",
+               bt_dev_warn(hdev, "PPAG-BT: Invalid object type: %d or package count: %d",
                            p->type, p->package.count);
+               ppag->status = AE_ERROR;
                return AE_ERROR;
        }
 
@@ -1335,6 +1343,7 @@ static acpi_status btintel_ppag_callback(acpi_handle handle, u32 lvl, void *data
 
        ppag->domain = (u32)p->package.elements[0].integer.value;
        ppag->mode = (u32)p->package.elements[1].integer.value;
+       ppag->status = AE_OK;
        kfree(buffer.pointer);
        return AE_CTRL_TERMINATE;
 }
@@ -2314,12 +2323,12 @@ error:
 
 static void btintel_set_ppag(struct hci_dev *hdev, struct intel_version_tlv *ver)
 {
-       acpi_status status;
        struct btintel_ppag ppag;
        struct sk_buff *skb;
        struct btintel_loc_aware_reg ppag_cmd;
+       acpi_handle handle;
 
-    /* PPAG is not supported if CRF is HrP2, Jfp2, JfP1 */
+       /* PPAG is not supported if CRF is HrP2, Jfp2, JfP1 */
        switch (ver->cnvr_top & 0xFFF) {
        case 0x504:     /* Hrp2 */
        case 0x202:     /* Jfp2 */
@@ -2327,29 +2336,35 @@ static void btintel_set_ppag(struct hci_dev *hdev, struct intel_version_tlv *ver
                return;
        }
 
+       handle = ACPI_HANDLE(GET_HCIDEV_DEV(hdev));
+       if (!handle) {
+               bt_dev_info(hdev, "No support for BT device in ACPI firmware");
+               return;
+       }
+
        memset(&ppag, 0, sizeof(ppag));
 
        ppag.hdev = hdev;
-       status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
-                                    ACPI_UINT32_MAX, NULL,
-                                    btintel_ppag_callback, &ppag, NULL);
+       ppag.status = AE_NOT_FOUND;
+       acpi_walk_namespace(ACPI_TYPE_PACKAGE, handle, 1, NULL,
+                           btintel_ppag_callback, &ppag, NULL);
 
-       if (ACPI_FAILURE(status)) {
-               /* Do not log warning message if ACPI entry is not found */
-               if (status == AE_NOT_FOUND)
+       if (ACPI_FAILURE(ppag.status)) {
+               if (ppag.status == AE_NOT_FOUND) {
+                       bt_dev_dbg(hdev, "PPAG-BT: ACPI entry not found");
                        return;
-               bt_dev_warn(hdev, "PPAG: ACPI Failure: %s", acpi_format_exception(status));
+               }
                return;
        }
 
        if (ppag.domain != 0x12) {
-               bt_dev_warn(hdev, "PPAG-BT Domain disabled");
+               bt_dev_warn(hdev, "PPAG-BT: domain is not bluetooth");
                return;
        }
 
        /* PPAG mode, BIT0 = 0 Disabled, BIT0 = 1 Enabled */
        if (!(ppag.mode & BIT(0))) {
-               bt_dev_dbg(hdev, "PPAG disabled");
+               bt_dev_dbg(hdev, "PPAG-BT: disabled");
                return;
        }
 
index 8e7da877efae6a8f114c0b1e95c654a96889a129..8fdb65b66315a7c93d5794a14dfd6e3a894de4fc 100644 (file)
@@ -137,13 +137,6 @@ struct intel_offload_use_cases {
        __u8    preset[8];
 } __packed;
 
-/* structure to store the PPAG data read from ACPI table */
-struct btintel_ppag {
-       u32     domain;
-       u32     mode;
-       struct hci_dev *hdev;
-};
-
 struct btintel_loc_aware_reg {
        __le32 mcc;
        __le32 sel;
index 2acb719e596f59e930c520b5030f0c6d0e5a55cb..11c7e04bf3947e37039e32cbe234b9cabec2e6e6 100644 (file)
@@ -122,6 +122,21 @@ static int btqcomsmd_setup(struct hci_dev *hdev)
        return 0;
 }
 
+static int btqcomsmd_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+       int ret;
+
+       ret = qca_set_bdaddr_rome(hdev, bdaddr);
+       if (ret)
+               return ret;
+
+       /* The firmware stops responding for a while after setting the bdaddr,
+        * causing timeouts for subsequent commands. Sleep a bit to avoid this.
+        */
+       usleep_range(1000, 10000);
+       return 0;
+}
+
 static int btqcomsmd_probe(struct platform_device *pdev)
 {
        struct btqcomsmd *btq;
@@ -162,7 +177,7 @@ static int btqcomsmd_probe(struct platform_device *pdev)
        hdev->close = btqcomsmd_close;
        hdev->send = btqcomsmd_send;
        hdev->setup = btqcomsmd_setup;
-       hdev->set_bdaddr = qca_set_bdaddr_rome;
+       hdev->set_bdaddr = btqcomsmd_set_bdaddr;
 
        ret = hci_register_dev(hdev);
        if (ret < 0)
index 795be33f2892d5ea41afbcb461c4e0c8e939ef2a..51000320e1ea89442af6a46d03974749e9f80fed 100644 (file)
@@ -354,9 +354,11 @@ static void btsdio_remove(struct sdio_func *func)
 
        BT_DBG("func %p", func);
 
+       cancel_work_sync(&data->work);
        if (!data)
                return;
 
+       cancel_work_sync(&data->work);
        hdev = data->hdev;
 
        sdio_set_drvdata(func, NULL);
index 18bc94718711592e2d559077afe010cc50802c4b..5c536151ef8367362517bd8a50a5b47a2b7ce1f9 100644 (file)
@@ -1050,21 +1050,11 @@ static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
                hci_skb_expect(skb) -= len;
 
                if (skb->len == HCI_ACL_HDR_SIZE) {
-                       __u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle);
                        __le16 dlen = hci_acl_hdr(skb)->dlen;
-                       __u8 type;
 
                        /* Complete ACL header */
                        hci_skb_expect(skb) = __le16_to_cpu(dlen);
 
-                       /* Detect if ISO packet has been sent over bulk */
-                       if (hci_conn_num(data->hdev, ISO_LINK)) {
-                               type = hci_conn_lookup_type(data->hdev,
-                                                           hci_handle(handle));
-                               if (type == ISO_LINK)
-                                       hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
-                       }
-
                        if (skb_tailroom(skb) < hci_skb_expect(skb)) {
                                kfree_skb(skb);
                                skb = NULL;
index 2a6b4f676458612e00b0551fad9aa51ea57ff6b7..cf463c1d2102c6fb9bb13bbaea33f1844c9daa17 100644 (file)
@@ -204,8 +204,8 @@ static int weim_parse_dt(struct platform_device *pdev)
        const struct of_device_id *of_id = of_match_device(weim_id_table,
                                                           &pdev->dev);
        const struct imx_weim_devtype *devtype = of_id->data;
+       int ret = 0, have_child = 0;
        struct device_node *child;
-       int ret, have_child = 0;
        struct weim_priv *priv;
        void __iomem *base;
        u32 reg;
@@ -329,6 +329,12 @@ static int of_weim_notify(struct notifier_block *nb, unsigned long action,
                                 "Failed to setup timing for '%pOF'\n", rd->dn);
 
                if (!of_node_check_flag(rd->dn, OF_POPULATED)) {
+                       /*
+                        * Clear the flag before adding the device so that
+                        * fw_devlink doesn't skip adding consumers to this
+                        * device.
+                        */
+                       rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
                        if (!of_platform_device_create(rd->dn, NULL, &pdev->dev)) {
                                dev_err(&pdev->dev,
                                        "Failed to create child device '%pOF'\n",
index ce3ccd172cc868d9f89ea2c5489a600ea08e2a0d..253f2ddb891308591db05ada2de72aa8703043da 100644 (file)
@@ -1311,7 +1311,7 @@ static void __cold try_to_generate_entropy(void)
                        /* Basic CPU round-robin, which avoids the current CPU. */
                        do {
                                cpu = cpumask_next(cpu, &timer_cpus);
-                               if (cpu == nr_cpumask_bits)
+                               if (cpu >= nr_cpu_ids)
                                        cpu = cpumask_first(&timer_cpus);
                        } while (cpu == smp_processor_id() && num_cpus > 1);
 
index 40360e599bc36083fd3fa10e11d48473915e8e80..bd757d836c5cf9ba53b6355da877d5907e32a8e7 100644 (file)
@@ -144,8 +144,12 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
 
        ret = -EIO;
        virt = acpi_os_map_iomem(start, len);
-       if (!virt)
+       if (!virt) {
+               dev_warn(&chip->dev, "%s: Failed to map ACPI memory\n", __func__);
+               /* try EFI log next */
+               ret = -ENODEV;
                goto err;
+       }
 
        memcpy_fromio(log->bios_event_log, virt, len);
 
index 8512ec76d5260d6788686b33bd3dc79db34fa937..639c3f395a5afc461e495d5a175f332496ff1f43 100644 (file)
@@ -36,7 +36,7 @@ static int tpm_bios_measurements_open(struct inode *inode,
                inode_unlock(inode);
                return -ENODEV;
        }
-       chip_seqops = (struct tpm_chip_seqops *)inode->i_private;
+       chip_seqops = inode->i_private;
        seqops = chip_seqops->seqops;
        chip = chip_seqops->chip;
        get_device(&chip->dev);
@@ -55,8 +55,8 @@ static int tpm_bios_measurements_open(struct inode *inode,
 static int tpm_bios_measurements_release(struct inode *inode,
                                         struct file *file)
 {
-       struct seq_file *seq = (struct seq_file *)file->private_data;
-       struct tpm_chip *chip = (struct tpm_chip *)seq->private;
+       struct seq_file *seq = file->private_data;
+       struct tpm_chip *chip = seq->private;
 
        put_device(&chip->dev);
 
index c4d0b744e3cc7379b6af00af991df869a88c00a4..2d28f55ef490b3787c0f5c384023f0a99acea951 100644 (file)
@@ -138,13 +138,13 @@ static const struct i2c_device_id st33zp24_i2c_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, st33zp24_i2c_id);
 
-static const struct of_device_id of_st33zp24_i2c_match[] = {
+static const struct of_device_id of_st33zp24_i2c_match[] __maybe_unused = {
        { .compatible = "st,st33zp24-i2c", },
        {}
 };
 MODULE_DEVICE_TABLE(of, of_st33zp24_i2c_match);
 
-static const struct acpi_device_id st33zp24_i2c_acpi_match[] = {
+static const struct acpi_device_id st33zp24_i2c_acpi_match[] __maybe_unused = {
        {"SMO3324"},
        {}
 };
index 2154059f02351fc2a6b2a4ef702ea7252b6f32c9..f5811b301d3b224ab67621f1cb204c07ecdf954f 100644 (file)
@@ -255,13 +255,13 @@ static const struct spi_device_id st33zp24_spi_id[] = {
 };
 MODULE_DEVICE_TABLE(spi, st33zp24_spi_id);
 
-static const struct of_device_id of_st33zp24_spi_match[] = {
+static const struct of_device_id of_st33zp24_spi_match[] __maybe_unused = {
        { .compatible = "st,st33zp24-spi", },
        {}
 };
 MODULE_DEVICE_TABLE(of, of_st33zp24_spi_match);
 
-static const struct acpi_device_id st33zp24_spi_acpi_match[] = {
+static const struct acpi_device_id st33zp24_spi_acpi_match[] __maybe_unused = {
        {"SMO3324"},
        {}
 };
index b99f55f2d4fd25dd1669489d81f07ac8c7513100..6fdfa65a00c3797a18c8aa2f5942eaac78623a36 100644 (file)
@@ -511,6 +511,63 @@ static int tpm_add_legacy_sysfs(struct tpm_chip *chip)
        return 0;
 }
 
+/*
+ * Some AMD fTPM versions may cause stutter
+ * https://www.amd.com/en/support/kb/faq/pa-410
+ *
+ * Fixes are available in two series of fTPM firmware:
+ * 6.x.y.z series: 6.0.18.6 +
+ * 3.x.y.z series: 3.57.y.5 +
+ */
+static bool tpm_amd_is_rng_defective(struct tpm_chip *chip)
+{
+       u32 val1, val2;
+       u64 version;
+       int ret;
+
+       if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
+               return false;
+
+       ret = tpm_request_locality(chip);
+       if (ret)
+               return false;
+
+       ret = tpm2_get_tpm_pt(chip, TPM2_PT_MANUFACTURER, &val1, NULL);
+       if (ret)
+               goto release;
+       if (val1 != 0x414D4400U /* AMD */) {
+               ret = -ENODEV;
+               goto release;
+       }
+       ret = tpm2_get_tpm_pt(chip, TPM2_PT_FIRMWARE_VERSION_1, &val1, NULL);
+       if (ret)
+               goto release;
+       ret = tpm2_get_tpm_pt(chip, TPM2_PT_FIRMWARE_VERSION_2, &val2, NULL);
+
+release:
+       tpm_relinquish_locality(chip);
+
+       if (ret)
+               return false;
+
+       version = ((u64)val1 << 32) | val2;
+       if ((version >> 48) == 6) {
+               if (version >= 0x0006000000180006ULL)
+                       return false;
+       } else if ((version >> 48) == 3) {
+               if (version >= 0x0003005700000005ULL)
+                       return false;
+       } else {
+               return false;
+       }
+
+       dev_warn(&chip->dev,
+                "AMD fTPM version 0x%llx causes system stutter; hwrng disabled\n",
+                version);
+
+       return true;
+}
+
 static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
 {
        struct tpm_chip *chip = container_of(rng, struct tpm_chip, hwrng);
@@ -520,7 +577,8 @@ static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
 
 static int tpm_add_hwrng(struct tpm_chip *chip)
 {
-       if (!IS_ENABLED(CONFIG_HW_RANDOM_TPM) || tpm_is_firmware_upgrade(chip))
+       if (!IS_ENABLED(CONFIG_HW_RANDOM_TPM) || tpm_is_firmware_upgrade(chip) ||
+           tpm_amd_is_rng_defective(chip))
                return 0;
 
        snprintf(chip->hwrng_name, sizeof(chip->hwrng_name),
@@ -547,6 +605,30 @@ static int tpm_get_pcr_allocation(struct tpm_chip *chip)
        return rc;
 }
 
+/*
+ * tpm_chip_startup() - performs auto startup and allocates the PCRs
+ * @chip: TPM chip to use.
+ */
+int tpm_chip_startup(struct tpm_chip *chip)
+{
+       int rc;
+
+       rc = tpm_chip_start(chip);
+       if (rc)
+               return rc;
+
+       rc = tpm_auto_startup(chip);
+       if (rc)
+               goto stop;
+
+       rc = tpm_get_pcr_allocation(chip);
+stop:
+       tpm_chip_stop(chip);
+
+       return rc;
+}
+EXPORT_SYMBOL_GPL(tpm_chip_startup);
+
 /*
  * tpm_chip_register() - create a character device for the TPM chip
  * @chip: TPM chip to use.
@@ -562,20 +644,6 @@ int tpm_chip_register(struct tpm_chip *chip)
 {
        int rc;
 
-       rc = tpm_chip_start(chip);
-       if (rc)
-               return rc;
-       rc = tpm_auto_startup(chip);
-       if (rc) {
-               tpm_chip_stop(chip);
-               return rc;
-       }
-
-       rc = tpm_get_pcr_allocation(chip);
-       tpm_chip_stop(chip);
-       if (rc)
-               return rc;
-
        tpm_sysfs_add_device(chip);
 
        tpm_bios_log_setup(chip);
@@ -624,7 +692,8 @@ EXPORT_SYMBOL_GPL(tpm_chip_register);
 void tpm_chip_unregister(struct tpm_chip *chip)
 {
        tpm_del_legacy_sysfs(chip);
-       if (IS_ENABLED(CONFIG_HW_RANDOM_TPM) && !tpm_is_firmware_upgrade(chip))
+       if (IS_ENABLED(CONFIG_HW_RANDOM_TPM) && !tpm_is_firmware_upgrade(chip) &&
+           !tpm_amd_is_rng_defective(chip))
                hwrng_unregister(&chip->hwrng);
        tpm_bios_log_teardown(chip);
        if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip))
index 24ee4e1cc452a006945ffbe9c257275332a46d6d..88d3bd76e0760dbaabe4f038d06f5ea103835b9c 100644 (file)
@@ -150,6 +150,79 @@ enum tpm_sub_capabilities {
        TPM_CAP_PROP_TIS_DURATION = 0x120,
 };
 
+enum tpm2_pt_props {
+       TPM2_PT_NONE = 0x00000000,
+       TPM2_PT_GROUP = 0x00000100,
+       TPM2_PT_FIXED = TPM2_PT_GROUP * 1,
+       TPM2_PT_FAMILY_INDICATOR = TPM2_PT_FIXED + 0,
+       TPM2_PT_LEVEL = TPM2_PT_FIXED + 1,
+       TPM2_PT_REVISION = TPM2_PT_FIXED + 2,
+       TPM2_PT_DAY_OF_YEAR = TPM2_PT_FIXED + 3,
+       TPM2_PT_YEAR = TPM2_PT_FIXED + 4,
+       TPM2_PT_MANUFACTURER = TPM2_PT_FIXED + 5,
+       TPM2_PT_VENDOR_STRING_1 = TPM2_PT_FIXED + 6,
+       TPM2_PT_VENDOR_STRING_2 = TPM2_PT_FIXED + 7,
+       TPM2_PT_VENDOR_STRING_3 = TPM2_PT_FIXED + 8,
+       TPM2_PT_VENDOR_STRING_4 = TPM2_PT_FIXED + 9,
+       TPM2_PT_VENDOR_TPM_TYPE = TPM2_PT_FIXED + 10,
+       TPM2_PT_FIRMWARE_VERSION_1 = TPM2_PT_FIXED + 11,
+       TPM2_PT_FIRMWARE_VERSION_2 = TPM2_PT_FIXED + 12,
+       TPM2_PT_INPUT_BUFFER = TPM2_PT_FIXED + 13,
+       TPM2_PT_HR_TRANSIENT_MIN = TPM2_PT_FIXED + 14,
+       TPM2_PT_HR_PERSISTENT_MIN = TPM2_PT_FIXED + 15,
+       TPM2_PT_HR_LOADED_MIN = TPM2_PT_FIXED + 16,
+       TPM2_PT_ACTIVE_SESSIONS_MAX = TPM2_PT_FIXED + 17,
+       TPM2_PT_PCR_COUNT = TPM2_PT_FIXED + 18,
+       TPM2_PT_PCR_SELECT_MIN = TPM2_PT_FIXED + 19,
+       TPM2_PT_CONTEXT_GAP_MAX = TPM2_PT_FIXED + 20,
+       TPM2_PT_NV_COUNTERS_MAX = TPM2_PT_FIXED + 22,
+       TPM2_PT_NV_INDEX_MAX = TPM2_PT_FIXED + 23,
+       TPM2_PT_MEMORY = TPM2_PT_FIXED + 24,
+       TPM2_PT_CLOCK_UPDATE = TPM2_PT_FIXED + 25,
+       TPM2_PT_CONTEXT_HASH = TPM2_PT_FIXED + 26,
+       TPM2_PT_CONTEXT_SYM = TPM2_PT_FIXED + 27,
+       TPM2_PT_CONTEXT_SYM_SIZE = TPM2_PT_FIXED + 28,
+       TPM2_PT_ORDERLY_COUNT = TPM2_PT_FIXED + 29,
+       TPM2_PT_MAX_COMMAND_SIZE = TPM2_PT_FIXED + 30,
+       TPM2_PT_MAX_RESPONSE_SIZE = TPM2_PT_FIXED + 31,
+       TPM2_PT_MAX_DIGEST = TPM2_PT_FIXED + 32,
+       TPM2_PT_MAX_OBJECT_CONTEXT = TPM2_PT_FIXED + 33,
+       TPM2_PT_MAX_SESSION_CONTEXT = TPM2_PT_FIXED + 34,
+       TPM2_PT_PS_FAMILY_INDICATOR = TPM2_PT_FIXED + 35,
+       TPM2_PT_PS_LEVEL = TPM2_PT_FIXED + 36,
+       TPM2_PT_PS_REVISION = TPM2_PT_FIXED + 37,
+       TPM2_PT_PS_DAY_OF_YEAR = TPM2_PT_FIXED + 38,
+       TPM2_PT_PS_YEAR = TPM2_PT_FIXED + 39,
+       TPM2_PT_SPLIT_MAX = TPM2_PT_FIXED + 40,
+       TPM2_PT_TOTAL_COMMANDS = TPM2_PT_FIXED + 41,
+       TPM2_PT_LIBRARY_COMMANDS = TPM2_PT_FIXED + 42,
+       TPM2_PT_VENDOR_COMMANDS = TPM2_PT_FIXED + 43,
+       TPM2_PT_NV_BUFFER_MAX = TPM2_PT_FIXED + 44,
+       TPM2_PT_MODES = TPM2_PT_FIXED + 45,
+       TPM2_PT_MAX_CAP_BUFFER = TPM2_PT_FIXED + 46,
+       TPM2_PT_VAR = TPM2_PT_GROUP * 2,
+       TPM2_PT_PERMANENT = TPM2_PT_VAR + 0,
+       TPM2_PT_STARTUP_CLEAR = TPM2_PT_VAR + 1,
+       TPM2_PT_HR_NV_INDEX = TPM2_PT_VAR + 2,
+       TPM2_PT_HR_LOADED = TPM2_PT_VAR + 3,
+       TPM2_PT_HR_LOADED_AVAIL = TPM2_PT_VAR + 4,
+       TPM2_PT_HR_ACTIVE = TPM2_PT_VAR + 5,
+       TPM2_PT_HR_ACTIVE_AVAIL = TPM2_PT_VAR + 6,
+       TPM2_PT_HR_TRANSIENT_AVAIL = TPM2_PT_VAR + 7,
+       TPM2_PT_HR_PERSISTENT = TPM2_PT_VAR + 8,
+       TPM2_PT_HR_PERSISTENT_AVAIL = TPM2_PT_VAR + 9,
+       TPM2_PT_NV_COUNTERS = TPM2_PT_VAR + 10,
+       TPM2_PT_NV_COUNTERS_AVAIL = TPM2_PT_VAR + 11,
+       TPM2_PT_ALGORITHM_SET = TPM2_PT_VAR + 12,
+       TPM2_PT_LOADED_CURVES = TPM2_PT_VAR + 13,
+       TPM2_PT_LOCKOUT_COUNTER = TPM2_PT_VAR + 14,
+       TPM2_PT_MAX_AUTH_FAIL = TPM2_PT_VAR + 15,
+       TPM2_PT_LOCKOUT_INTERVAL = TPM2_PT_VAR + 16,
+       TPM2_PT_LOCKOUT_RECOVERY = TPM2_PT_VAR + 17,
+       TPM2_PT_NV_WRITE_RECOVERY = TPM2_PT_VAR + 18,
+       TPM2_PT_AUDIT_COUNTER_0 = TPM2_PT_VAR + 19,
+       TPM2_PT_AUDIT_COUNTER_1 = TPM2_PT_VAR + 20,
+};
 
 /* 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18
  * bytes, but 128 is still a relatively large number of random bytes and
@@ -190,6 +263,7 @@ static inline void tpm_msleep(unsigned int delay_msec)
                     delay_msec * 1000);
 };
 
+int tpm_chip_startup(struct tpm_chip *chip);
 int tpm_chip_start(struct tpm_chip *chip);
 void tpm_chip_stop(struct tpm_chip *chip);
 struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip);
index deff23bb54bf1769ef402076b7a17300ea8c55a4..528f35b14fb636f34697b1167b113dba3e3a9a08 100644 (file)
@@ -334,11 +334,11 @@ static int ftpm_tee_remove(struct device *dev)
        return 0;
 }
 
-static int ftpm_plat_tee_remove(struct platform_device *pdev)
+static void ftpm_plat_tee_remove(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
 
-       return ftpm_tee_remove(dev);
+       ftpm_tee_remove(dev);
 }
 
 /**
@@ -367,7 +367,7 @@ static struct platform_driver ftpm_tee_plat_driver = {
        },
        .shutdown = ftpm_plat_tee_shutdown,
        .probe = ftpm_plat_tee_probe,
-       .remove = ftpm_plat_tee_remove,
+       .remove_new = ftpm_plat_tee_remove,
 };
 
 /* UUID of the fTPM TA */
index ed5dabd3c72d62708a56d813c7713d7bc2c98c0f..7af389806643379fa76507755550fdae92871de9 100644 (file)
@@ -50,6 +50,45 @@ static inline struct tpm_tis_tcg_phy *to_tpm_tis_tcg_phy(struct tpm_tis_data *da
        return container_of(data, struct tpm_tis_tcg_phy, priv);
 }
 
+#ifdef CONFIG_PREEMPT_RT
+/*
+ * Flush previous write operations with a dummy read operation to the
+ * TPM MMIO base address.
+ */
+static inline void tpm_tis_flush(void __iomem *iobase)
+{
+       ioread8(iobase + TPM_ACCESS(0));
+}
+#else
+#define tpm_tis_flush(iobase) do { } while (0)
+#endif
+
+/*
+ * Write a byte word to the TPM MMIO address, and flush the write queue.
+ * The flush ensures that the data is sent immediately over the bus and not
+ * aggregated with further requests and transferred later in a batch. The large
+ * write requests can lead to unwanted latency spikes by blocking the CPU until
+ * the complete batch has been transferred.
+ */
+static inline void tpm_tis_iowrite8(u8 b, void __iomem *iobase, u32 addr)
+{
+       iowrite8(b, iobase + addr);
+       tpm_tis_flush(iobase);
+}
+
+/*
+ * Write a 32-bit word to the TPM MMIO address, and flush the write queue.
+ * The flush ensures that the data is sent immediately over the bus and not
+ * aggregated with further requests and transferred later in a batch. The large
+ * write requests can lead to unwanted latency spikes by blocking the CPU until
+ * the complete batch has been transferred.
+ */
+static inline void tpm_tis_iowrite32(u32 b, void __iomem *iobase, u32 addr)
+{
+       iowrite32(b, iobase + addr);
+       tpm_tis_flush(iobase);
+}
+
 static int interrupts = -1;
 module_param(interrupts, int, 0444);
 MODULE_PARM_DESC(interrupts, "Enable interrupts");
@@ -186,12 +225,12 @@ static int tpm_tcg_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
        switch (io_mode) {
        case TPM_TIS_PHYS_8:
                while (len--)
-                       iowrite8(*value++, phy->iobase + addr);
+                       tpm_tis_iowrite8(*value++, phy->iobase, addr);
                break;
        case TPM_TIS_PHYS_16:
                return -EINVAL;
        case TPM_TIS_PHYS_32:
-               iowrite32(le32_to_cpu(*((__le32 *)value)), phy->iobase + addr);
+               tpm_tis_iowrite32(le32_to_cpu(*((__le32 *)value)), phy->iobase, addr);
                break;
        }
 
@@ -227,7 +266,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info)
                irq = tpm_info->irq;
 
        if (itpm || is_itpm(ACPI_COMPANION(dev)))
-               phy->priv.flags |= TPM_TIS_ITPM_WORKAROUND;
+               set_bit(TPM_TIS_ITPM_WORKAROUND, &phy->priv.flags);
 
        return tpm_tis_core_init(dev, &phy->priv, irq, &tpm_tcg,
                                 ACPI_HANDLE(dev));
@@ -324,14 +363,12 @@ static int tpm_tis_plat_probe(struct platform_device *pdev)
        return tpm_tis_init(&pdev->dev, &tpm_info);
 }
 
-static int tpm_tis_plat_remove(struct platform_device *pdev)
+static void tpm_tis_plat_remove(struct platform_device *pdev)
 {
        struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
 
        tpm_chip_unregister(chip);
        tpm_tis_remove(chip);
-
-       return 0;
 }
 
 #ifdef CONFIG_OF
@@ -344,7 +381,7 @@ MODULE_DEVICE_TABLE(of, tis_of_platform_match);
 
 static struct platform_driver tis_drv = {
        .probe = tpm_tis_plat_probe,
-       .remove = tpm_tis_plat_remove,
+       .remove_new = tpm_tis_plat_remove,
        .driver = {
                .name           = "tpm_tis",
                .pm             = &tpm_tis_pm,
index 3f98e587b3e849aa35346cc8110c17c7c1987cbe..c2421162cf345794b81288bba2b91217666b4dd1 100644 (file)
@@ -44,6 +44,20 @@ static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
        return false;
 }
 
+static u8 tpm_tis_filter_sts_mask(u8 int_mask, u8 sts_mask)
+{
+       if (!(int_mask & TPM_INTF_STS_VALID_INT))
+               sts_mask &= ~TPM_STS_VALID;
+
+       if (!(int_mask & TPM_INTF_DATA_AVAIL_INT))
+               sts_mask &= ~TPM_STS_DATA_AVAIL;
+
+       if (!(int_mask & TPM_INTF_CMD_READY_INT))
+               sts_mask &= ~TPM_STS_COMMAND_READY;
+
+       return sts_mask;
+}
+
 static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
                unsigned long timeout, wait_queue_head_t *queue,
                bool check_cancel)
@@ -53,41 +67,56 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
        long rc;
        u8 status;
        bool canceled = false;
+       u8 sts_mask;
+       int ret = 0;
 
        /* check current status */
        status = chip->ops->status(chip);
        if ((status & mask) == mask)
                return 0;
 
-       stop = jiffies + timeout;
+       sts_mask = mask & (TPM_STS_VALID | TPM_STS_DATA_AVAIL |
+                          TPM_STS_COMMAND_READY);
+       /* check what status changes can be handled by irqs */
+       sts_mask = tpm_tis_filter_sts_mask(priv->int_mask, sts_mask);
 
-       if (chip->flags & TPM_CHIP_FLAG_IRQ) {
+       stop = jiffies + timeout;
+       /* process status changes with irq support */
+       if (sts_mask) {
+               ret = -ETIME;
 again:
                timeout = stop - jiffies;
                if ((long)timeout <= 0)
                        return -ETIME;
                rc = wait_event_interruptible_timeout(*queue,
-                       wait_for_tpm_stat_cond(chip, mask, check_cancel,
+                       wait_for_tpm_stat_cond(chip, sts_mask, check_cancel,
                                               &canceled),
                        timeout);
                if (rc > 0) {
                        if (canceled)
                                return -ECANCELED;
-                       return 0;
+                       ret = 0;
                }
                if (rc == -ERESTARTSYS && freezing(current)) {
                        clear_thread_flag(TIF_SIGPENDING);
                        goto again;
                }
-       } else {
-               do {
-                       usleep_range(priv->timeout_min,
-                                    priv->timeout_max);
-                       status = chip->ops->status(chip);
-                       if ((status & mask) == mask)
-                               return 0;
-               } while (time_before(jiffies, stop));
        }
+
+       if (ret)
+               return ret;
+
+       mask &= ~sts_mask;
+       if (!mask) /* all done */
+               return 0;
+       /* process status changes without irq support */
+       do {
+               status = chip->ops->status(chip);
+               if ((status & mask) == mask)
+                       return 0;
+               usleep_range(priv->timeout_min,
+                            priv->timeout_max);
+       } while (time_before(jiffies, stop));
        return -ETIME;
 }
 
@@ -136,16 +165,27 @@ static bool check_locality(struct tpm_chip *chip, int l)
        return false;
 }
 
-static int release_locality(struct tpm_chip *chip, int l)
+static int __tpm_tis_relinquish_locality(struct tpm_tis_data *priv, int l)
+{
+       tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
+
+       return 0;
+}
+
+static int tpm_tis_relinquish_locality(struct tpm_chip *chip, int l)
 {
        struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
 
-       tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
+       mutex_lock(&priv->locality_count_mutex);
+       priv->locality_count--;
+       if (priv->locality_count == 0)
+               __tpm_tis_relinquish_locality(priv, l);
+       mutex_unlock(&priv->locality_count_mutex);
 
        return 0;
 }
 
-static int request_locality(struct tpm_chip *chip, int l)
+static int __tpm_tis_request_locality(struct tpm_chip *chip, int l)
 {
        struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
        unsigned long stop, timeout;
@@ -186,6 +226,20 @@ again:
        return -1;
 }
 
+static int tpm_tis_request_locality(struct tpm_chip *chip, int l)
+{
+       struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+       int ret = 0;
+
+       mutex_lock(&priv->locality_count_mutex);
+       if (priv->locality_count == 0)
+               ret = __tpm_tis_request_locality(chip, l);
+       if (!ret)
+               priv->locality_count++;
+       mutex_unlock(&priv->locality_count_mutex);
+       return ret;
+}
+
 static u8 tpm_tis_status(struct tpm_chip *chip)
 {
        struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
@@ -351,7 +405,7 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
        struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
        int rc, status, burstcnt;
        size_t count = 0;
-       bool itpm = priv->flags & TPM_TIS_ITPM_WORKAROUND;
+       bool itpm = test_bit(TPM_TIS_ITPM_WORKAROUND, &priv->flags);
 
        status = tpm_tis_status(chip);
        if ((status & TPM_STS_COMMAND_READY) == 0) {
@@ -484,7 +538,8 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
        int rc, irq;
        struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
 
-       if (!(chip->flags & TPM_CHIP_FLAG_IRQ) || priv->irq_tested)
+       if (!(chip->flags & TPM_CHIP_FLAG_IRQ) ||
+            test_bit(TPM_TIS_IRQ_TESTED, &priv->flags))
                return tpm_tis_send_main(chip, buf, len);
 
        /* Verify receipt of the expected IRQ */
@@ -494,11 +549,11 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
        rc = tpm_tis_send_main(chip, buf, len);
        priv->irq = irq;
        chip->flags |= TPM_CHIP_FLAG_IRQ;
-       if (!priv->irq_tested)
+       if (!test_bit(TPM_TIS_IRQ_TESTED, &priv->flags))
                tpm_msleep(1);
-       if (!priv->irq_tested)
+       if (!test_bit(TPM_TIS_IRQ_TESTED, &priv->flags))
                disable_interrupts(chip);
-       priv->irq_tested = true;
+       set_bit(TPM_TIS_IRQ_TESTED, &priv->flags);
        return rc;
 }
 
@@ -641,7 +696,7 @@ static int probe_itpm(struct tpm_chip *chip)
        size_t len = sizeof(cmd_getticks);
        u16 vendor;
 
-       if (priv->flags & TPM_TIS_ITPM_WORKAROUND)
+       if (test_bit(TPM_TIS_ITPM_WORKAROUND, &priv->flags))
                return 0;
 
        rc = tpm_tis_read16(priv, TPM_DID_VID(0), &vendor);
@@ -652,7 +707,7 @@ static int probe_itpm(struct tpm_chip *chip)
        if (vendor != TPM_VID_INTEL)
                return 0;
 
-       if (request_locality(chip, 0) != 0)
+       if (tpm_tis_request_locality(chip, 0) != 0)
                return -EBUSY;
 
        rc = tpm_tis_send_data(chip, cmd_getticks, len);
@@ -661,19 +716,19 @@ static int probe_itpm(struct tpm_chip *chip)
 
        tpm_tis_ready(chip);
 
-       priv->flags |= TPM_TIS_ITPM_WORKAROUND;
+       set_bit(TPM_TIS_ITPM_WORKAROUND, &priv->flags);
 
        rc = tpm_tis_send_data(chip, cmd_getticks, len);
        if (rc == 0)
                dev_info(&chip->dev, "Detected an iTPM.\n");
        else {
-               priv->flags &= ~TPM_TIS_ITPM_WORKAROUND;
+               clear_bit(TPM_TIS_ITPM_WORKAROUND, &priv->flags);
                rc = -EFAULT;
        }
 
 out:
        tpm_tis_ready(chip);
-       release_locality(chip, priv->locality);
+       tpm_tis_relinquish_locality(chip, priv->locality);
 
        return rc;
 }
@@ -702,7 +757,7 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id)
        struct tpm_chip *chip = dev_id;
        struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
        u32 interrupt;
-       int i, rc;
+       int rc;
 
        rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &interrupt);
        if (rc < 0)
@@ -711,20 +766,19 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id)
        if (interrupt == 0)
                return IRQ_NONE;
 
-       priv->irq_tested = true;
+       set_bit(TPM_TIS_IRQ_TESTED, &priv->flags);
        if (interrupt & TPM_INTF_DATA_AVAIL_INT)
                wake_up_interruptible(&priv->read_queue);
-       if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
-               for (i = 0; i < 5; i++)
-                       if (check_locality(chip, i))
-                               break;
+
        if (interrupt &
            (TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT |
             TPM_INTF_CMD_READY_INT))
                wake_up_interruptible(&priv->int_queue);
 
        /* Clear interrupts handled with TPM_EOI */
+       tpm_tis_request_locality(chip, 0);
        rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), interrupt);
+       tpm_tis_relinquish_locality(chip, 0);
        if (rc < 0)
                return IRQ_NONE;
 
@@ -732,25 +786,22 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static int tpm_tis_gen_interrupt(struct tpm_chip *chip)
+static void tpm_tis_gen_interrupt(struct tpm_chip *chip)
 {
        const char *desc = "attempting to generate an interrupt";
        u32 cap2;
        cap_t cap;
        int ret;
 
-       ret = request_locality(chip, 0);
-       if (ret < 0)
-               return ret;
+       chip->flags |= TPM_CHIP_FLAG_IRQ;
 
        if (chip->flags & TPM_CHIP_FLAG_TPM2)
                ret = tpm2_get_tpm_pt(chip, 0x100, &cap2, desc);
        else
                ret = tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc, 0);
 
-       release_locality(chip, 0);
-
-       return ret;
+       if (ret)
+               chip->flags &= ~TPM_CHIP_FLAG_IRQ;
 }
 
 /* Register the IRQ and issue a command that will cause an interrupt. If an
@@ -765,60 +816,66 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
        int rc;
        u32 int_status;
 
-       if (devm_request_irq(chip->dev.parent, irq, tis_int_handler, flags,
-                            dev_name(&chip->dev), chip) != 0) {
+
+       rc = devm_request_threaded_irq(chip->dev.parent, irq, NULL,
+                                      tis_int_handler, IRQF_ONESHOT | flags,
+                                      dev_name(&chip->dev), chip);
+       if (rc) {
                dev_info(&chip->dev, "Unable to request irq: %d for probe\n",
                         irq);
                return -1;
        }
        priv->irq = irq;
 
+       rc = tpm_tis_request_locality(chip, 0);
+       if (rc < 0)
+               return rc;
+
        rc = tpm_tis_read8(priv, TPM_INT_VECTOR(priv->locality),
                           &original_int_vec);
-       if (rc < 0)
+       if (rc < 0) {
+               tpm_tis_relinquish_locality(chip, priv->locality);
                return rc;
+       }
 
        rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), irq);
        if (rc < 0)
-               return rc;
+               goto restore_irqs;
 
        rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &int_status);
        if (rc < 0)
-               return rc;
+               goto restore_irqs;
 
        /* Clear all existing */
        rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), int_status);
        if (rc < 0)
-               return rc;
-
+               goto restore_irqs;
        /* Turn on */
        rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality),
                             intmask | TPM_GLOBAL_INT_ENABLE);
        if (rc < 0)
-               return rc;
+               goto restore_irqs;
 
-       priv->irq_tested = false;
+       clear_bit(TPM_TIS_IRQ_TESTED, &priv->flags);
 
        /* Generate an interrupt by having the core call through to
         * tpm_tis_send
         */
-       rc = tpm_tis_gen_interrupt(chip);
-       if (rc < 0)
-               return rc;
+       tpm_tis_gen_interrupt(chip);
 
+restore_irqs:
        /* tpm_tis_send will either confirm the interrupt is working or it
         * will call disable_irq which undoes all of the above.
         */
        if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
-               rc = tpm_tis_write8(priv, original_int_vec,
-                               TPM_INT_VECTOR(priv->locality));
-               if (rc < 0)
-                       return rc;
-
-               return 1;
+               tpm_tis_write8(priv, original_int_vec,
+                              TPM_INT_VECTOR(priv->locality));
+               rc = -1;
        }
 
-       return 0;
+       tpm_tis_relinquish_locality(chip, priv->locality);
+
+       return rc;
 }
 
 /* Try to find the IRQ the TPM is using. This is for legacy x86 systems that
@@ -932,8 +989,8 @@ static const struct tpm_class_ops tpm_tis = {
        .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
        .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
        .req_canceled = tpm_tis_req_canceled,
-       .request_locality = request_locality,
-       .relinquish_locality = release_locality,
+       .request_locality = tpm_tis_request_locality,
+       .relinquish_locality = tpm_tis_relinquish_locality,
        .clk_enable = tpm_tis_clkrun_enable,
 };
 
@@ -967,6 +1024,8 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
        priv->timeout_min = TPM_TIMEOUT_USECS_MIN;
        priv->timeout_max = TPM_TIMEOUT_USECS_MAX;
        priv->phy_ops = phy_ops;
+       priv->locality_count = 0;
+       mutex_init(&priv->locality_count_mutex);
 
        dev_set_drvdata(&chip->dev, priv);
 
@@ -1009,18 +1068,50 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
        if (rc < 0)
                goto out_err;
 
-       intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT |
-                  TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT;
+       /* Figure out the capabilities */
+       rc = tpm_tis_read32(priv, TPM_INTF_CAPS(priv->locality), &intfcaps);
+       if (rc < 0)
+               goto out_err;
+
+       dev_dbg(dev, "TPM interface capabilities (0x%x):\n",
+               intfcaps);
+       if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
+               dev_dbg(dev, "\tBurst Count Static\n");
+       if (intfcaps & TPM_INTF_CMD_READY_INT) {
+               intmask |= TPM_INTF_CMD_READY_INT;
+               dev_dbg(dev, "\tCommand Ready Int Support\n");
+       }
+       if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
+               dev_dbg(dev, "\tInterrupt Edge Falling\n");
+       if (intfcaps & TPM_INTF_INT_EDGE_RISING)
+               dev_dbg(dev, "\tInterrupt Edge Rising\n");
+       if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
+               dev_dbg(dev, "\tInterrupt Level Low\n");
+       if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
+               dev_dbg(dev, "\tInterrupt Level High\n");
+       if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT) {
+               intmask |= TPM_INTF_LOCALITY_CHANGE_INT;
+               dev_dbg(dev, "\tLocality Change Int Support\n");
+       }
+       if (intfcaps & TPM_INTF_STS_VALID_INT) {
+               intmask |= TPM_INTF_STS_VALID_INT;
+               dev_dbg(dev, "\tSts Valid Int Support\n");
+       }
+       if (intfcaps & TPM_INTF_DATA_AVAIL_INT) {
+               intmask |= TPM_INTF_DATA_AVAIL_INT;
+               dev_dbg(dev, "\tData Avail Int Support\n");
+       }
+
        intmask &= ~TPM_GLOBAL_INT_ENABLE;
 
-       rc = request_locality(chip, 0);
+       rc = tpm_tis_request_locality(chip, 0);
        if (rc < 0) {
                rc = -ENODEV;
                goto out_err;
        }
 
        tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
-       release_locality(chip, 0);
+       tpm_tis_relinquish_locality(chip, 0);
 
        rc = tpm_chip_start(chip);
        if (rc)
@@ -1044,35 +1135,14 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
                goto out_err;
        }
 
-       /* Figure out the capabilities */
-       rc = tpm_tis_read32(priv, TPM_INTF_CAPS(priv->locality), &intfcaps);
-       if (rc < 0)
-               goto out_err;
-
-       dev_dbg(dev, "TPM interface capabilities (0x%x):\n",
-               intfcaps);
-       if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
-               dev_dbg(dev, "\tBurst Count Static\n");
-       if (intfcaps & TPM_INTF_CMD_READY_INT)
-               dev_dbg(dev, "\tCommand Ready Int Support\n");
-       if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
-               dev_dbg(dev, "\tInterrupt Edge Falling\n");
-       if (intfcaps & TPM_INTF_INT_EDGE_RISING)
-               dev_dbg(dev, "\tInterrupt Edge Rising\n");
-       if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
-               dev_dbg(dev, "\tInterrupt Level Low\n");
-       if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
-               dev_dbg(dev, "\tInterrupt Level High\n");
-       if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
-               dev_dbg(dev, "\tLocality Change Int Support\n");
-       if (intfcaps & TPM_INTF_STS_VALID_INT)
-               dev_dbg(dev, "\tSts Valid Int Support\n");
-       if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
-               dev_dbg(dev, "\tData Avail Int Support\n");
-
        /* INTERRUPT Setup */
        init_waitqueue_head(&priv->read_queue);
        init_waitqueue_head(&priv->int_queue);
+
+       rc = tpm_chip_startup(chip);
+       if (rc)
+               goto out_err;
+
        if (irq != -1) {
                /*
                 * Before doing irq testing issue a command to the TPM in polling mode
@@ -1080,13 +1150,13 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
                 * proper timeouts for the driver.
                 */
 
-               rc = request_locality(chip, 0);
+               rc = tpm_tis_request_locality(chip, 0);
                if (rc < 0)
                        goto out_err;
 
                rc = tpm_get_timeouts(chip);
 
-               release_locality(chip, 0);
+               tpm_tis_relinquish_locality(chip, 0);
 
                if (rc) {
                        dev_err(dev, "Could not get TPM timeouts and durations\n");
@@ -1094,17 +1164,23 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
                        goto out_err;
                }
 
-               if (irq) {
+               if (irq)
                        tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
                                                 irq);
-                       if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
-                               dev_err(&chip->dev, FW_BUG
-                                       "TPM interrupt not working, polling instead\n");
+               else
+                       tpm_tis_probe_irq(chip, intmask);
 
-                               disable_interrupts(chip);
-                       }
+               if (chip->flags & TPM_CHIP_FLAG_IRQ) {
+                       priv->int_mask = intmask;
                } else {
-                       tpm_tis_probe_irq(chip, intmask);
+                       dev_err(&chip->dev, FW_BUG
+                                       "TPM interrupt not working, polling instead\n");
+
+                       rc = tpm_tis_request_locality(chip, 0);
+                       if (rc < 0)
+                               goto out_err;
+                       disable_interrupts(chip);
+                       tpm_tis_relinquish_locality(chip, 0);
                }
        }
 
@@ -1143,13 +1219,7 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
        if (rc < 0)
                goto out;
 
-       rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
-       if (rc < 0)
-               goto out;
-
-       intmask |= TPM_INTF_CMD_READY_INT
-           | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
-           | TPM_INTF_STS_VALID_INT | TPM_GLOBAL_INT_ENABLE;
+       intmask = priv->int_mask | TPM_GLOBAL_INT_ENABLE;
 
        tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
 
@@ -1165,28 +1235,27 @@ int tpm_tis_resume(struct device *dev)
        struct tpm_chip *chip = dev_get_drvdata(dev);
        int ret;
 
+       ret = tpm_tis_request_locality(chip, 0);
+       if (ret < 0)
+               return ret;
+
        if (chip->flags & TPM_CHIP_FLAG_IRQ)
                tpm_tis_reenable_interrupts(chip);
 
        ret = tpm_pm_resume(dev);
        if (ret)
-               return ret;
+               goto out;
 
        /*
         * TPM 1.2 requires self-test on resume. This function actually returns
         * an error code but for unknown reason it isn't handled.
         */
-       if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
-               ret = request_locality(chip, 0);
-               if (ret < 0)
-                       return ret;
-
+       if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
                tpm1_do_selftest(chip);
+out:
+       tpm_tis_relinquish_locality(chip, 0);
 
-               release_locality(chip, 0);
-       }
-
-       return 0;
+       return ret;
 }
 EXPORT_SYMBOL_GPL(tpm_tis_resume);
 #endif
index b68479e0de10f396ea294a0c68988c9a479763d9..e978f457fd4d4ce083a7a9f9689df5f2d7a8ed9d 100644 (file)
@@ -87,13 +87,16 @@ enum tpm_tis_flags {
        TPM_TIS_ITPM_WORKAROUND         = BIT(0),
        TPM_TIS_INVALID_STATUS          = BIT(1),
        TPM_TIS_DEFAULT_CANCELLATION    = BIT(2),
+       TPM_TIS_IRQ_TESTED              = BIT(3),
 };
 
 struct tpm_tis_data {
        u16 manufacturer_id;
+       struct mutex locality_count_mutex;
+       unsigned int locality_count;
        int locality;
        int irq;
-       bool irq_tested;
+       unsigned int int_mask;
        unsigned long flags;
        void __iomem *ilb_base_addr;
        u16 clkrun_enabled;
index 77cea5b31c6e4b67eaabc9ec9839170095018935..376ae18a04ebb7c7a3f5d6116f2a2b7e626634f3 100644 (file)
@@ -100,8 +100,7 @@ static int tpm_cr50_i2c_wait_tpm_ready(struct tpm_chip *chip)
        }
 
        /* Wait for interrupt to indicate TPM is ready to respond */
-       if (!wait_for_completion_timeout(&priv->tpm_ready,
-                                        msecs_to_jiffies(chip->timeout_a))) {
+       if (!wait_for_completion_timeout(&priv->tpm_ready, chip->timeout_a)) {
                dev_warn(&chip->dev, "Timeout waiting for TPM ready\n");
                return -ETIMEDOUT;
        }
index a0963a3e92bdd86da6627412eeff1e0b8a00aa6a..1f5207974a17b6ba0a7835c306b0f17ad6bb991f 100644 (file)
@@ -231,7 +231,7 @@ static const struct spi_device_id tpm_tis_spi_id[] = {
 };
 MODULE_DEVICE_TABLE(spi, tpm_tis_spi_id);
 
-static const struct of_device_id of_tis_spi_match[] = {
+static const struct of_device_id of_tis_spi_match[] __maybe_unused = {
        { .compatible = "st,st33htpm-spi", .data = tpm_tis_spi_probe },
        { .compatible = "infineon,slb9670", .data = tpm_tis_spi_probe },
        { .compatible = "tcg,tpm_tis-spi", .data = tpm_tis_spi_probe },
@@ -240,7 +240,7 @@ static const struct of_device_id of_tis_spi_match[] = {
 };
 MODULE_DEVICE_TABLE(of, of_tis_spi_match);
 
-static const struct acpi_device_id acpi_tis_spi_match[] = {
+static const struct acpi_device_id acpi_tis_spi_match[] __maybe_unused = {
        {"SMO0768", 0},
        {}
 };
index 679196c614017aac6994c7402e1612b85a44aa8f..49278746b0e2f97a9b8af1331dc0530ab2a95db5 100644 (file)
@@ -127,14 +127,12 @@ static int tpm_tis_synquacer_probe(struct platform_device *pdev)
        return tpm_tis_synquacer_init(&pdev->dev, &tpm_info);
 }
 
-static int tpm_tis_synquacer_remove(struct platform_device *pdev)
+static void tpm_tis_synquacer_remove(struct platform_device *pdev)
 {
        struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
 
        tpm_chip_unregister(chip);
        tpm_tis_remove(chip);
-
-       return 0;
 }
 
 #ifdef CONFIG_OF
@@ -155,7 +153,7 @@ MODULE_DEVICE_TABLE(acpi, tpm_synquacer_acpi_tbl);
 
 static struct platform_driver tis_synquacer_drv = {
        .probe = tpm_tis_synquacer_probe,
-       .remove = tpm_tis_synquacer_remove,
+       .remove_new = tpm_tis_synquacer_remove,
        .driver = {
                .name           = "tpm_tis_synquacer",
                .pm             = &tpm_tis_synquacer_pm,
index b6c5bf69a2b2c65aa24c2dfcfb6050c1412708d8..1eef05bb1f995eea850c3a18697a6d2f11106215 100644 (file)
@@ -91,7 +91,7 @@ config COMMON_CLK_RK808
 config COMMON_CLK_HI655X
        tristate "Clock driver for Hi655x" if EXPERT
        depends on (MFD_HI655X_PMIC || COMPILE_TEST)
-       depends on REGMAP
+       select REGMAP
        default MFD_HI655X_PMIC
        help
          This driver supports the hi655x PMIC clock. This
index 290a2846a86b654034293308f33602114c85dae1..0fafa5cba4427d219d6337d20b15e26ff09fd32c 100644 (file)
@@ -69,4 +69,3 @@ builtin_platform_driver(bcm2835_aux_clk_driver);
 
 MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
 MODULE_DESCRIPTION("BCM2835 auxiliary peripheral clock driver");
-MODULE_LICENSE("GPL");
index e74fe6219d14e2e0c39b65a5e9b2a9cef7c42d9a..8dc476ef5bf975e8251c693304d7f91a1fe57a57 100644 (file)
@@ -2350,4 +2350,3 @@ builtin_platform_driver(bcm2835_clk_driver);
 
 MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
 MODULE_DESCRIPTION("BCM2835 clock driver");
-MODULE_LICENSE("GPL");
index 5225d17d6b3f39210dc19de7ffb861f4544e124a..8609fca29cc4e08ddd49066392acf563bc95891e 100644 (file)
@@ -99,4 +99,3 @@ module_platform_driver(of_fixed_mmio_clk_driver);
 
 MODULE_AUTHOR("Jan Kotas <jank@cadence.com>");
 MODULE_DESCRIPTION("Memory Mapped IO Fixed clock driver");
-MODULE_LICENSE("GPL v2");
index 6238fcea04673052e60e6a2293f021bd44d34d40..ee5baf993ff21d3b9c6bda31db1a5b6c83a38f49 100644 (file)
@@ -88,5 +88,4 @@ module_platform_driver(fsl_sai_clk_driver);
 
 MODULE_DESCRIPTION("Freescale SAI bitclock-as-a-clock driver");
 MODULE_AUTHOR("Michael Walle <michael@walle.cc>");
-MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:fsl-sai-clk");
index 67a7cb3503c3697b169e436f5aeb361de4e2febe..4eed667eddaf25b4e3bd974ade93a0243109bf6a 100644 (file)
@@ -495,7 +495,7 @@ static unsigned long k210_pll_get_rate(struct clk_hw *hw,
        f = FIELD_GET(K210_PLL_CLKF, reg) + 1;
        od = FIELD_GET(K210_PLL_CLKOD, reg) + 1;
 
-       return (u64)parent_rate * f / (r * od);
+       return div_u64((u64)parent_rate * f, r * od);
 }
 
 static const struct clk_ops k210_pll_ops = {
index f91f30560820d529e035c2e62efee3b659acbe6c..ff3a52d48479092257a98ddaaf3b2af701a6bd99 100644 (file)
@@ -143,8 +143,9 @@ static int rs9_regmap_i2c_read(void *context,
 static const struct regmap_config rs9_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
-       .cache_type = REGCACHE_NONE,
+       .cache_type = REGCACHE_FLAT,
        .max_register = RS9_REG_BCP,
+       .num_reg_defaults_raw = 0x8,
        .rd_table = &rs9_readable_table,
        .wr_table = &rs9_writeable_table,
        .reg_write = rs9_regmap_i2c_write,
index 9ea1a80acbe8b5be6475d2f729e5609c0a61d3a9..8036bd8cbb0ac21fbe5688c71809effd85b68224 100644 (file)
@@ -841,5 +841,4 @@ static void __exit hi3559av100_crg_exit(void)
 module_exit(hi3559av100_crg_exit);
 
 
-MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("HiSilicon Hi3559AV100 CRG Driver");
index 2836adb817b70e85c01009926003355506e07ce5..e3696a88b5a36af229370e8b7a996d60a987dcb4 100644 (file)
@@ -95,14 +95,16 @@ static const struct clk_div_table video_div_table[] = {
        { }
 };
 
-static const char * enet1_ref_sels[] = { "enet1_ref_125m", "enet1_ref_pad", };
+static const char * enet1_ref_sels[] = { "enet1_ref_125m", "enet1_ref_pad", "dummy", "dummy"};
 static const u32 enet1_ref_sels_table[] = { IMX6UL_GPR1_ENET1_TX_CLK_DIR,
-                                           IMX6UL_GPR1_ENET1_CLK_SEL };
+                                           IMX6UL_GPR1_ENET1_CLK_SEL, 0,
+                                           IMX6UL_GPR1_ENET1_TX_CLK_DIR | IMX6UL_GPR1_ENET1_CLK_SEL };
 static const u32 enet1_ref_sels_table_mask = IMX6UL_GPR1_ENET1_TX_CLK_DIR |
                                             IMX6UL_GPR1_ENET1_CLK_SEL;
-static const char * enet2_ref_sels[] = { "enet2_ref_125m", "enet2_ref_pad", };
+static const char * enet2_ref_sels[] = { "enet2_ref_125m", "enet2_ref_pad", "dummy", "dummy"};
 static const u32 enet2_ref_sels_table[] = { IMX6UL_GPR1_ENET2_TX_CLK_DIR,
-                                           IMX6UL_GPR1_ENET2_CLK_SEL };
+                                           IMX6UL_GPR1_ENET2_CLK_SEL, 0,
+                                           IMX6UL_GPR1_ENET2_TX_CLK_DIR | IMX6UL_GPR1_ENET2_CLK_SEL };
 static const u32 enet2_ref_sels_table_mask = IMX6UL_GPR1_ENET2_TX_CLK_DIR |
                                             IMX6UL_GPR1_ENET2_CLK_SEL;
 
index 0ddc73e07be429734d32aae75f08534782b3c564..bce61c45e96748d5a7f3e67ec82a5fecdd6f74a3 100644 (file)
@@ -291,4 +291,3 @@ module_exit(clk_ccc_exit);
 
 MODULE_DESCRIPTION("Microchip PolarFire SoC Clock Conditioning Circuitry Driver");
 MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
-MODULE_LICENSE("GPL");
index ce81e4087a8fce2e8d2239e6d706de7f33b24c7d..2bfbab8db94bf54dcb164012d79d45b0b0df3d2f 100644 (file)
@@ -17,7 +17,6 @@ static const struct regmap_config sprdclk_regmap_config = {
        .reg_bits       = 32,
        .reg_stride     = 4,
        .val_bits       = 32,
-       .max_register   = 0xffff,
        .fast_io        = true,
 };
 
@@ -43,6 +42,8 @@ int sprd_clk_regmap_init(struct platform_device *pdev,
        struct device *dev = &pdev->dev;
        struct device_node *node = dev->of_node, *np;
        struct regmap *regmap;
+       struct resource *res;
+       struct regmap_config reg_config = sprdclk_regmap_config;
 
        if (of_find_property(node, "sprd,syscon", NULL)) {
                regmap = syscon_regmap_lookup_by_phandle(node, "sprd,syscon");
@@ -59,12 +60,14 @@ int sprd_clk_regmap_init(struct platform_device *pdev,
                        return PTR_ERR(regmap);
                }
        } else {
-               base = devm_platform_ioremap_resource(pdev, 0);
+               base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
                if (IS_ERR(base))
                        return PTR_ERR(base);
 
+               reg_config.max_register = resource_size(res) - reg_config.reg_stride;
+
                regmap = devm_regmap_init_mmio(&pdev->dev, base,
-                                              &sprdclk_regmap_config);
+                                              &reg_config);
                if (IS_ERR(regmap)) {
                        pr_err("failed to init regmap\n");
                        return PTR_ERR(regmap);
index deed4afadb298e1173a55a729a1708c1e298994c..d9cb937665cfcf657a80bbb150b2b04858599c8c 100644 (file)
@@ -97,10 +97,6 @@ struct quad8 {
        struct quad8_reg __iomem *reg;
 };
 
-/* Borrow Toggle flip-flop */
-#define QUAD8_FLAG_BT BIT(0)
-/* Carry Toggle flip-flop */
-#define QUAD8_FLAG_CT BIT(1)
 /* Error flag */
 #define QUAD8_FLAG_E BIT(4)
 /* Up/Down flag */
@@ -133,6 +129,9 @@ struct quad8 {
 #define QUAD8_CMR_QUADRATURE_X2 0x10
 #define QUAD8_CMR_QUADRATURE_X4 0x18
 
+/* Each Counter is 24 bits wide */
+#define LS7267_CNTR_MAX GENMASK(23, 0)
+
 static int quad8_signal_read(struct counter_device *counter,
                             struct counter_signal *signal,
                             enum counter_signal_level *level)
@@ -156,18 +155,10 @@ static int quad8_count_read(struct counter_device *counter,
 {
        struct quad8 *const priv = counter_priv(counter);
        struct channel_reg __iomem *const chan = priv->reg->channel + count->id;
-       unsigned int flags;
-       unsigned int borrow;
-       unsigned int carry;
        unsigned long irqflags;
        int i;
 
-       flags = ioread8(&chan->control);
-       borrow = flags & QUAD8_FLAG_BT;
-       carry = !!(flags & QUAD8_FLAG_CT);
-
-       /* Borrow XOR Carry effectively doubles count range */
-       *val = (unsigned long)(borrow ^ carry) << 24;
+       *val = 0;
 
        spin_lock_irqsave(&priv->lock, irqflags);
 
@@ -191,8 +182,7 @@ static int quad8_count_write(struct counter_device *counter,
        unsigned long irqflags;
        int i;
 
-       /* Only 24-bit values are supported */
-       if (val > 0xFFFFFF)
+       if (val > LS7267_CNTR_MAX)
                return -ERANGE;
 
        spin_lock_irqsave(&priv->lock, irqflags);
@@ -378,7 +368,7 @@ static int quad8_action_read(struct counter_device *counter,
 
        /* Handle Index signals */
        if (synapse->signal->id >= 16) {
-               if (priv->preset_enable[count->id])
+               if (!priv->preset_enable[count->id])
                        *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
                else
                        *action = COUNTER_SYNAPSE_ACTION_NONE;
@@ -806,8 +796,7 @@ static int quad8_count_preset_write(struct counter_device *counter,
        struct quad8 *const priv = counter_priv(counter);
        unsigned long irqflags;
 
-       /* Only 24-bit values are supported */
-       if (preset > 0xFFFFFF)
+       if (preset > LS7267_CNTR_MAX)
                return -ERANGE;
 
        spin_lock_irqsave(&priv->lock, irqflags);
@@ -834,8 +823,7 @@ static int quad8_count_ceiling_read(struct counter_device *counter,
                *ceiling = priv->preset[count->id];
                break;
        default:
-               /* By default 0x1FFFFFF (25 bits unsigned) is maximum count */
-               *ceiling = 0x1FFFFFF;
+               *ceiling = LS7267_CNTR_MAX;
                break;
        }
 
@@ -850,8 +838,7 @@ static int quad8_count_ceiling_write(struct counter_device *counter,
        struct quad8 *const priv = counter_priv(counter);
        unsigned long irqflags;
 
-       /* Only 24-bit values are supported */
-       if (ceiling > 0xFFFFFF)
+       if (ceiling > LS7267_CNTR_MAX)
                return -ERANGE;
 
        spin_lock_irqsave(&priv->lock, irqflags);
index 73c7643b26972b4f79fa6dc65ee745e48a9aee88..8dd46fad151eb01a823815aa1eb3507f88172312 100644 (file)
@@ -840,22 +840,20 @@ static int amd_pstate_update_status(const char *buf, size_t size)
 
        switch(mode_idx) {
        case AMD_PSTATE_DISABLE:
-               if (!current_pstate_driver)
-                       return -EINVAL;
-               if (cppc_state == AMD_PSTATE_ACTIVE)
-                       return -EBUSY;
-               cpufreq_unregister_driver(current_pstate_driver);
-               amd_pstate_driver_cleanup();
+               if (current_pstate_driver) {
+                       cpufreq_unregister_driver(current_pstate_driver);
+                       amd_pstate_driver_cleanup();
+               }
                break;
        case AMD_PSTATE_PASSIVE:
                if (current_pstate_driver) {
                        if (current_pstate_driver == &amd_pstate_driver)
                                return 0;
                        cpufreq_unregister_driver(current_pstate_driver);
-                       cppc_state = AMD_PSTATE_PASSIVE;
-                       current_pstate_driver = &amd_pstate_driver;
                }
 
+               current_pstate_driver = &amd_pstate_driver;
+               cppc_state = AMD_PSTATE_PASSIVE;
                ret = cpufreq_register_driver(current_pstate_driver);
                break;
        case AMD_PSTATE_ACTIVE:
@@ -863,10 +861,10 @@ static int amd_pstate_update_status(const char *buf, size_t size)
                        if (current_pstate_driver == &amd_pstate_epp_driver)
                                return 0;
                        cpufreq_unregister_driver(current_pstate_driver);
-                       current_pstate_driver = &amd_pstate_epp_driver;
-                       cppc_state = AMD_PSTATE_ACTIVE;
                }
 
+               current_pstate_driver = &amd_pstate_epp_driver;
+               cppc_state = AMD_PSTATE_ACTIVE;
                ret = cpufreq_register_driver(current_pstate_driver);
                break;
        default:
index 6ad2954948a5abb2f9612d4e52832d73ef25020d..11316c3b14ca49806839059a2b754658a4710826 100644 (file)
@@ -106,7 +106,8 @@ static void psci_pd_remove(void)
        struct psci_pd_provider *pd_provider, *it;
        struct generic_pm_domain *genpd;
 
-       list_for_each_entry_safe(pd_provider, it, &psci_pd_providers, link) {
+       list_for_each_entry_safe_reverse(pd_provider, it,
+                                        &psci_pd_providers, link) {
                of_genpd_del_provider(pd_provider->node);
 
                genpd = of_genpd_remove_last(pd_provider->node);
index 45deda18ed322ef60af2ddb5bdebf8ec6a8b2448..02cc2c38b44baf8ef37c3dd9c4b4d7806181e3bb 100644 (file)
@@ -101,25 +101,40 @@ static int map_hdm_decoder_regs(struct cxl_port *port, void __iomem *crb,
                                      BIT(CXL_CM_CAP_CAP_ID_HDM));
 }
 
-static struct cxl_hdm *devm_cxl_setup_emulated_hdm(struct cxl_port *port,
-                                                  struct cxl_endpoint_dvsec_info *info)
+static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info)
 {
-       struct device *dev = &port->dev;
        struct cxl_hdm *cxlhdm;
+       void __iomem *hdm;
+       u32 ctrl;
+       int i;
 
-       if (!info->mem_enabled)
-               return ERR_PTR(-ENODEV);
+       if (!info)
+               return false;
 
-       cxlhdm = devm_kzalloc(dev, sizeof(*cxlhdm), GFP_KERNEL);
-       if (!cxlhdm)
-               return ERR_PTR(-ENOMEM);
+       cxlhdm = dev_get_drvdata(&info->port->dev);
+       hdm = cxlhdm->regs.hdm_decoder;
 
-       cxlhdm->port = port;
-       cxlhdm->decoder_count = info->ranges;
-       cxlhdm->target_count = info->ranges;
-       dev_set_drvdata(&port->dev, cxlhdm);
+       if (!hdm)
+               return true;
 
-       return cxlhdm;
+       /*
+        * If HDM decoders are present and the driver is in control of
+        * Mem_Enable skip DVSEC based emulation
+        */
+       if (!info->mem_enabled)
+               return false;
+
+       /*
+        * If any decoders are committed already, there should not be any
+        * emulated DVSEC decoders.
+        */
+       for (i = 0; i < cxlhdm->decoder_count; i++) {
+               ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(i));
+               if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl))
+                       return false;
+       }
+
+       return true;
 }
 
 /**
@@ -138,13 +153,14 @@ struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port,
        cxlhdm = devm_kzalloc(dev, sizeof(*cxlhdm), GFP_KERNEL);
        if (!cxlhdm)
                return ERR_PTR(-ENOMEM);
-
        cxlhdm->port = port;
-       crb = ioremap(port->component_reg_phys, CXL_COMPONENT_REG_BLOCK_SIZE);
-       if (!crb) {
-               if (info && info->mem_enabled)
-                       return devm_cxl_setup_emulated_hdm(port, info);
+       dev_set_drvdata(dev, cxlhdm);
 
+       crb = ioremap(port->component_reg_phys, CXL_COMPONENT_REG_BLOCK_SIZE);
+       if (!crb && info && info->mem_enabled) {
+               cxlhdm->decoder_count = info->ranges;
+               return cxlhdm;
+       } else if (!crb) {
                dev_err(dev, "No component registers mapped\n");
                return ERR_PTR(-ENXIO);
        }
@@ -160,7 +176,15 @@ struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port,
                return ERR_PTR(-ENXIO);
        }
 
-       dev_set_drvdata(dev, cxlhdm);
+       /*
+        * Now that the hdm capability is parsed, decide if range
+        * register emulation is needed and fixup cxlhdm accordingly.
+        */
+       if (should_emulate_decoders(info)) {
+               dev_dbg(dev, "Fallback map %d range register%s\n", info->ranges,
+                       info->ranges > 1 ? "s" : "");
+               cxlhdm->decoder_count = info->ranges;
+       }
 
        return cxlhdm;
 }
@@ -714,14 +738,20 @@ static int cxl_decoder_reset(struct cxl_decoder *cxld)
        return 0;
 }
 
-static int cxl_setup_hdm_decoder_from_dvsec(struct cxl_port *port,
-                                           struct cxl_decoder *cxld, int which,
-                                           struct cxl_endpoint_dvsec_info *info)
+static int cxl_setup_hdm_decoder_from_dvsec(
+       struct cxl_port *port, struct cxl_decoder *cxld, u64 *dpa_base,
+       int which, struct cxl_endpoint_dvsec_info *info)
 {
+       struct cxl_endpoint_decoder *cxled;
+       u64 len;
+       int rc;
+
        if (!is_cxl_endpoint(port))
                return -EOPNOTSUPP;
 
-       if (!range_len(&info->dvsec_range[which]))
+       cxled = to_cxl_endpoint_decoder(&cxld->dev);
+       len = range_len(&info->dvsec_range[which]);
+       if (!len)
                return -ENOENT;
 
        cxld->target_type = CXL_DECODER_EXPANDER;
@@ -736,40 +766,24 @@ static int cxl_setup_hdm_decoder_from_dvsec(struct cxl_port *port,
        cxld->flags |= CXL_DECODER_F_ENABLE | CXL_DECODER_F_LOCK;
        port->commit_end = cxld->id;
 
-       return 0;
-}
-
-static bool should_emulate_decoders(struct cxl_port *port)
-{
-       struct cxl_hdm *cxlhdm = dev_get_drvdata(&port->dev);
-       void __iomem *hdm = cxlhdm->regs.hdm_decoder;
-       u32 ctrl;
-       int i;
-
-       if (!is_cxl_endpoint(cxlhdm->port))
-               return false;
-
-       if (!hdm)
-               return true;
-
-       /*
-        * If any decoders are committed already, there should not be any
-        * emulated DVSEC decoders.
-        */
-       for (i = 0; i < cxlhdm->decoder_count; i++) {
-               ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(i));
-               if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl))
-                       return false;
+       rc = devm_cxl_dpa_reserve(cxled, *dpa_base, len, 0);
+       if (rc) {
+               dev_err(&port->dev,
+                       "decoder%d.%d: Failed to reserve DPA range %#llx - %#llx\n (%d)",
+                       port->id, cxld->id, *dpa_base, *dpa_base + len - 1, rc);
+               return rc;
        }
+       *dpa_base += len;
+       cxled->state = CXL_DECODER_STATE_AUTO;
 
-       return true;
+       return 0;
 }
 
 static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
                            int *target_map, void __iomem *hdm, int which,
                            u64 *dpa_base, struct cxl_endpoint_dvsec_info *info)
 {
-       struct cxl_endpoint_decoder *cxled = NULL;
+       struct cxl_endpoint_decoder *cxled;
        u64 size, base, skip, dpa_size;
        bool committed;
        u32 remainder;
@@ -780,11 +794,9 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
                unsigned char target_id[8];
        } target_list;
 
-       if (should_emulate_decoders(port))
-               return cxl_setup_hdm_decoder_from_dvsec(port, cxld, which, info);
-
-       if (is_endpoint_decoder(&cxld->dev))
-               cxled = to_cxl_endpoint_decoder(&cxld->dev);
+       if (should_emulate_decoders(info))
+               return cxl_setup_hdm_decoder_from_dvsec(port, cxld, dpa_base,
+                                                       which, info);
 
        ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(which));
        base = ioread64_hi_lo(hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(which));
@@ -806,9 +818,6 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
                .end = base + size - 1,
        };
 
-       if (cxled && !committed && range_len(&info->dvsec_range[which]))
-               return cxl_setup_hdm_decoder_from_dvsec(port, cxld, which, info);
-
        /* decoders are enabled if committed */
        if (committed) {
                cxld->flags |= CXL_DECODER_F_ENABLE;
@@ -846,7 +855,7 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
        if (rc)
                return rc;
 
-       if (!cxled) {
+       if (!info) {
                target_list.value =
                        ioread64_hi_lo(hdm + CXL_HDM_DECODER0_TL_LOW(which));
                for (i = 0; i < cxld->interleave_ways; i++)
@@ -866,6 +875,7 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
                return -ENXIO;
        }
        skip = ioread64_hi_lo(hdm + CXL_HDM_DECODER0_SKIP_LOW(which));
+       cxled = to_cxl_endpoint_decoder(&cxld->dev);
        rc = devm_cxl_dpa_reserve(cxled, *dpa_base + skip, dpa_size, skip);
        if (rc) {
                dev_err(&port->dev,
index 7328a255241138d8d2f0f963b7139a8281a82c0a..523d5b9fd7fcf2a1fb0b62c85dabac13c63b3c00 100644 (file)
@@ -462,7 +462,7 @@ static struct pci_doe_mb *find_cdat_doe(struct device *uport)
        return NULL;
 }
 
-#define CDAT_DOE_REQ(entry_handle)                                     \
+#define CDAT_DOE_REQ(entry_handle) cpu_to_le32                         \
        (FIELD_PREP(CXL_DOE_TABLE_ACCESS_REQ_CODE,                      \
                    CXL_DOE_TABLE_ACCESS_REQ_CODE_READ) |               \
         FIELD_PREP(CXL_DOE_TABLE_ACCESS_TABLE_TYPE,                    \
@@ -475,8 +475,8 @@ static void cxl_doe_task_complete(struct pci_doe_task *task)
 }
 
 struct cdat_doe_task {
-       u32 request_pl;
-       u32 response_pl[32];
+       __le32 request_pl;
+       __le32 response_pl[32];
        struct completion c;
        struct pci_doe_task task;
 };
@@ -510,10 +510,10 @@ static int cxl_cdat_get_length(struct device *dev,
                return rc;
        }
        wait_for_completion(&t.c);
-       if (t.task.rv < sizeof(u32))
+       if (t.task.rv < 2 * sizeof(__le32))
                return -EIO;
 
-       *length = t.response_pl[1];
+       *length = le32_to_cpu(t.response_pl[1]);
        dev_dbg(dev, "CDAT length %zu\n", *length);
 
        return 0;
@@ -524,13 +524,13 @@ static int cxl_cdat_read_table(struct device *dev,
                               struct cxl_cdat *cdat)
 {
        size_t length = cdat->length;
-       u32 *data = cdat->table;
+       __le32 *data = cdat->table;
        int entry_handle = 0;
 
        do {
                DECLARE_CDAT_DOE_TASK(CDAT_DOE_REQ(entry_handle), t);
+               struct cdat_entry_header *entry;
                size_t entry_dw;
-               u32 *entry;
                int rc;
 
                rc = pci_doe_submit_task(cdat_doe, &t.task);
@@ -539,26 +539,34 @@ static int cxl_cdat_read_table(struct device *dev,
                        return rc;
                }
                wait_for_completion(&t.c);
-               /* 1 DW header + 1 DW data min */
-               if (t.task.rv < (2 * sizeof(u32)))
+
+               /* 1 DW Table Access Response Header + CDAT entry */
+               entry = (struct cdat_entry_header *)(t.response_pl + 1);
+               if ((entry_handle == 0 &&
+                    t.task.rv != sizeof(__le32) + sizeof(struct cdat_header)) ||
+                   (entry_handle > 0 &&
+                    (t.task.rv < sizeof(__le32) + sizeof(*entry) ||
+                     t.task.rv != sizeof(__le32) + le16_to_cpu(entry->length))))
                        return -EIO;
 
                /* Get the CXL table access header entry handle */
                entry_handle = FIELD_GET(CXL_DOE_TABLE_ACCESS_ENTRY_HANDLE,
-                                        t.response_pl[0]);
-               entry = t.response_pl + 1;
-               entry_dw = t.task.rv / sizeof(u32);
+                                        le32_to_cpu(t.response_pl[0]));
+               entry_dw = t.task.rv / sizeof(__le32);
                /* Skip Header */
                entry_dw -= 1;
-               entry_dw = min(length / sizeof(u32), entry_dw);
+               entry_dw = min(length / sizeof(__le32), entry_dw);
                /* Prevent length < 1 DW from causing a buffer overflow */
                if (entry_dw) {
-                       memcpy(data, entry, entry_dw * sizeof(u32));
-                       length -= entry_dw * sizeof(u32);
+                       memcpy(data, entry, entry_dw * sizeof(__le32));
+                       length -= entry_dw * sizeof(__le32);
                        data += entry_dw;
                }
        } while (entry_handle != CXL_DOE_TABLE_ACCESS_LAST_ENTRY);
 
+       /* Length in CDAT header may exceed concatenation of CDAT entries */
+       cdat->length -= length;
+
        return 0;
 }
 
index c2e4b10937884a7ec3cc1266f395ce2dedcbe209..f8c38d9972522a605e9bf94f436343f62df0e64f 100644 (file)
@@ -62,9 +62,9 @@ static int match_nvdimm_bridge(struct device *dev, void *data)
        return is_cxl_nvdimm_bridge(dev);
 }
 
-struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct device *start)
+struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_memdev *cxlmd)
 {
-       struct cxl_port *port = find_cxl_root(start);
+       struct cxl_port *port = find_cxl_root(dev_get_drvdata(&cxlmd->dev));
        struct device *dev;
 
        if (!port)
@@ -253,7 +253,7 @@ int devm_cxl_add_nvdimm(struct cxl_memdev *cxlmd)
        struct device *dev;
        int rc;
 
-       cxl_nvb = cxl_find_nvdimm_bridge(&cxlmd->dev);
+       cxl_nvb = cxl_find_nvdimm_bridge(cxlmd);
        if (!cxl_nvb)
                return -ENODEV;
 
index 8ee6b6e2e2a4edd698e6812e75fa68902ff833fe..4d1f9c5b5029a594835b0ed251fe229648cc4853 100644 (file)
@@ -823,41 +823,17 @@ static bool dev_is_cxl_root_child(struct device *dev)
        return false;
 }
 
-/* Find a 2nd level CXL port that has a dport that is an ancestor of @match */
-static int match_root_child(struct device *dev, const void *match)
+struct cxl_port *find_cxl_root(struct cxl_port *port)
 {
-       const struct device *iter = NULL;
-       struct cxl_dport *dport;
-       struct cxl_port *port;
-
-       if (!dev_is_cxl_root_child(dev))
-               return 0;
-
-       port = to_cxl_port(dev);
-       iter = match;
-       while (iter) {
-               dport = cxl_find_dport_by_dev(port, iter);
-               if (dport)
-                       break;
-               iter = iter->parent;
-       }
-
-       return !!iter;
-}
+       struct cxl_port *iter = port;
 
-struct cxl_port *find_cxl_root(struct device *dev)
-{
-       struct device *port_dev;
-       struct cxl_port *root;
+       while (iter && !is_cxl_root(iter))
+               iter = to_cxl_port(iter->dev.parent);
 
-       port_dev = bus_find_device(&cxl_bus_type, NULL, dev, match_root_child);
-       if (!port_dev)
+       if (!iter)
                return NULL;
-
-       root = to_cxl_port(port_dev->parent);
-       get_device(&root->dev);
-       put_device(port_dev);
-       return root;
+       get_device(&iter->dev);
+       return iter;
 }
 EXPORT_SYMBOL_NS_GPL(find_cxl_root, CXL);
 
index f29028148806baa2982eaf5b3a9e92840f8bff92..b2fd67fcebfb5742ce2095d062b7201075e4b10f 100644 (file)
@@ -134,9 +134,13 @@ static int cxl_region_decode_reset(struct cxl_region *cxlr, int count)
                struct cxl_endpoint_decoder *cxled = p->targets[i];
                struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
                struct cxl_port *iter = cxled_to_port(cxled);
+               struct cxl_dev_state *cxlds = cxlmd->cxlds;
                struct cxl_ep *ep;
                int rc = 0;
 
+               if (cxlds->rcd)
+                       goto endpoint_reset;
+
                while (!is_cxl_root(to_cxl_port(iter->dev.parent)))
                        iter = to_cxl_port(iter->dev.parent);
 
@@ -153,6 +157,7 @@ static int cxl_region_decode_reset(struct cxl_region *cxlr, int count)
                                return rc;
                }
 
+endpoint_reset:
                rc = cxled->cxld.reset(&cxled->cxld);
                if (rc)
                        return rc;
@@ -1199,6 +1204,7 @@ static void cxl_region_teardown_targets(struct cxl_region *cxlr)
 {
        struct cxl_region_params *p = &cxlr->params;
        struct cxl_endpoint_decoder *cxled;
+       struct cxl_dev_state *cxlds;
        struct cxl_memdev *cxlmd;
        struct cxl_port *iter;
        struct cxl_ep *ep;
@@ -1214,6 +1220,10 @@ static void cxl_region_teardown_targets(struct cxl_region *cxlr)
        for (i = 0; i < p->nr_targets; i++) {
                cxled = p->targets[i];
                cxlmd = cxled_to_memdev(cxled);
+               cxlds = cxlmd->cxlds;
+
+               if (cxlds->rcd)
+                       continue;
 
                iter = cxled_to_port(cxled);
                while (!is_cxl_root(to_cxl_port(iter->dev.parent)))
@@ -1229,14 +1239,24 @@ static int cxl_region_setup_targets(struct cxl_region *cxlr)
 {
        struct cxl_region_params *p = &cxlr->params;
        struct cxl_endpoint_decoder *cxled;
+       struct cxl_dev_state *cxlds;
+       int i, rc, rch = 0, vh = 0;
        struct cxl_memdev *cxlmd;
        struct cxl_port *iter;
        struct cxl_ep *ep;
-       int i, rc;
 
        for (i = 0; i < p->nr_targets; i++) {
                cxled = p->targets[i];
                cxlmd = cxled_to_memdev(cxled);
+               cxlds = cxlmd->cxlds;
+
+               /* validate that all targets agree on topology */
+               if (!cxlds->rcd) {
+                       vh++;
+               } else {
+                       rch++;
+                       continue;
+               }
 
                iter = cxled_to_port(cxled);
                while (!is_cxl_root(to_cxl_port(iter->dev.parent)))
@@ -1256,6 +1276,12 @@ static int cxl_region_setup_targets(struct cxl_region *cxlr)
                }
        }
 
+       if (rch && vh) {
+               dev_err(&cxlr->dev, "mismatched CXL topologies detected\n");
+               cxl_region_teardown_targets(cxlr);
+               return -ENXIO;
+       }
+
        return 0;
 }
 
@@ -1648,6 +1674,7 @@ static int cxl_region_attach(struct cxl_region *cxlr,
                if (rc)
                        goto err_decrement;
                p->state = CXL_CONFIG_ACTIVE;
+               set_bit(CXL_REGION_F_INCOHERENT, &cxlr->flags);
        }
 
        cxled->cxld.interleave_ways = p->interleave_ways;
@@ -1749,8 +1776,6 @@ static int attach_target(struct cxl_region *cxlr,
 
        down_read(&cxl_dpa_rwsem);
        rc = cxl_region_attach(cxlr, cxled, pos);
-       if (rc == 0)
-               set_bit(CXL_REGION_F_INCOHERENT, &cxlr->flags);
        up_read(&cxl_dpa_rwsem);
        up_write(&cxl_region_rwsem);
        return rc;
@@ -2251,7 +2276,7 @@ static struct cxl_pmem_region *cxl_pmem_region_alloc(struct cxl_region *cxlr)
                 * bridge for one device is the same for all.
                 */
                if (i == 0) {
-                       cxl_nvb = cxl_find_nvdimm_bridge(&cxlmd->dev);
+                       cxl_nvb = cxl_find_nvdimm_bridge(cxlmd);
                        if (!cxl_nvb) {
                                cxlr_pmem = ERR_PTR(-ENODEV);
                                goto out;
index f2b0962a552d582cd190f028cc54f76cfbc9cffb..044a92d9813e239d1b97e7a4935f36850c30e154 100644 (file)
@@ -658,7 +658,7 @@ struct pci_bus *cxl_port_to_pci_bus(struct cxl_port *port);
 struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport,
                                   resource_size_t component_reg_phys,
                                   struct cxl_dport *parent_dport);
-struct cxl_port *find_cxl_root(struct device *dev);
+struct cxl_port *find_cxl_root(struct cxl_port *port);
 int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd);
 void cxl_bus_rescan(void);
 void cxl_bus_drain(void);
@@ -695,13 +695,15 @@ int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint)
 
 /**
  * struct cxl_endpoint_dvsec_info - Cached DVSEC info
- * @mem_enabled: cached value of mem_enabled in the DVSEC, PCIE_DEVICE
+ * @mem_enabled: cached value of mem_enabled in the DVSEC at init time
  * @ranges: Number of active HDM ranges this device uses.
+ * @port: endpoint port associated with this info instance
  * @dvsec_range: cached attributes of the ranges in the DVSEC, PCIE_DEVICE
  */
 struct cxl_endpoint_dvsec_info {
        bool mem_enabled;
        int ranges;
+       struct cxl_port *port;
        struct range dvsec_range[2];
 };
 
@@ -758,7 +760,7 @@ struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev);
 bool is_cxl_nvdimm(struct device *dev);
 bool is_cxl_nvdimm_bridge(struct device *dev);
 int devm_cxl_add_nvdimm(struct cxl_memdev *cxlmd);
-struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct device *dev);
+struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_memdev *cxlmd);
 
 #ifdef CONFIG_CXL_REGION
 bool is_cxl_pmem_region(struct device *dev);
index be6a2ef3cce3738a45cc19d8c9cb54aff93af693..0465ef963cd6a0b23dae3cfb7177d9a033dcde18 100644 (file)
@@ -68,6 +68,20 @@ enum cxl_regloc_type {
        CXL_REGLOC_RBI_TYPES
 };
 
+struct cdat_header {
+       __le32 length;
+       u8 revision;
+       u8 checksum;
+       u8 reserved[6];
+       __le32 sequence;
+} __packed;
+
+struct cdat_entry_header {
+       u8 type;
+       u8 reserved;
+       __le16 length;
+} __packed;
+
 int devm_cxl_port_enumerate_dports(struct cxl_port *port);
 struct cxl_dev_state;
 int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm,
index 1049bb5ea496129177e3db06fae3b64198548483..22a7ab2bae7c7e53878faf3b372718f50ea1457f 100644 (file)
@@ -78,8 +78,8 @@ static int cxl_switch_port_probe(struct cxl_port *port)
 
 static int cxl_endpoint_port_probe(struct cxl_port *port)
 {
+       struct cxl_endpoint_dvsec_info info = { .port = port };
        struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport);
-       struct cxl_endpoint_dvsec_info info = { 0 };
        struct cxl_dev_state *cxlds = cxlmd->cxlds;
        struct cxl_hdm *cxlhdm;
        struct cxl_port *root;
@@ -119,7 +119,7 @@ static int cxl_endpoint_port_probe(struct cxl_port *port)
         * This can't fail in practice as CXL root exit unregisters all
         * descendant ports and that in turn synchronizes with cxl_port_probe()
         */
-       root = find_cxl_root(&cxlmd->dev);
+       root = find_cxl_root(port);
 
        /*
         * Now that all endpoint decoders are successfully enumerated, try to
index 90f28bda29c8bd41e19b340e779c351634d29283..4cf8da77bdd91329012579de26bb7aa01f7979f4 100644 (file)
@@ -75,6 +75,7 @@
 
 #define REG_TX_INTSTATE(idx)           (0x0030 + (idx) * 4)
 #define REG_RX_INTSTATE(idx)           (0x0040 + (idx) * 4)
+#define REG_GLOBAL_INTSTATE(idx)       (0x0050 + (idx) * 4)
 #define REG_CHAN_INTSTATUS(ch, idx)    (0x8010 + (ch) * 0x200 + (idx) * 4)
 #define REG_CHAN_INTMASK(ch, idx)      (0x8020 + (ch) * 0x200 + (idx) * 4)
 
@@ -511,7 +512,10 @@ static int admac_terminate_all(struct dma_chan *chan)
        admac_stop_chan(adchan);
        admac_reset_rings(adchan);
 
-       adchan->current_tx = NULL;
+       if (adchan->current_tx) {
+               list_add_tail(&adchan->current_tx->node, &adchan->to_free);
+               adchan->current_tx = NULL;
+       }
        /*
         * Descriptors can only be freed after the tasklet
         * has been killed (in admac_synchronize).
@@ -672,13 +676,14 @@ static void admac_handle_chan_int(struct admac_data *ad, int no)
 static irqreturn_t admac_interrupt(int irq, void *devid)
 {
        struct admac_data *ad = devid;
-       u32 rx_intstate, tx_intstate;
+       u32 rx_intstate, tx_intstate, global_intstate;
        int i;
 
        rx_intstate = readl_relaxed(ad->base + REG_RX_INTSTATE(ad->irq_index));
        tx_intstate = readl_relaxed(ad->base + REG_TX_INTSTATE(ad->irq_index));
+       global_intstate = readl_relaxed(ad->base + REG_GLOBAL_INTSTATE(ad->irq_index));
 
-       if (!tx_intstate && !rx_intstate)
+       if (!tx_intstate && !rx_intstate && !global_intstate)
                return IRQ_NONE;
 
        for (i = 0; i < ad->nchannels; i += 2) {
@@ -693,6 +698,12 @@ static irqreturn_t admac_interrupt(int irq, void *devid)
                rx_intstate >>= 1;
        }
 
+       if (global_intstate) {
+               dev_warn(ad->dev, "clearing unknown global interrupt flag: %x\n",
+                        global_intstate);
+               writel_relaxed(~(u32) 0, ad->base + REG_GLOBAL_INTSTATE(ad->irq_index));
+       }
+
        return IRQ_HANDLED;
 }
 
@@ -850,6 +861,9 @@ static int admac_probe(struct platform_device *pdev)
 
        dma->directions = BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM);
        dma->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
+       dma->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
+                       BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
+                       BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
        dma->dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
                        BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
                        BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
index c24bca210104c1e92a46da5ef8340489e27d5da7..826b98284fa1f845698cc996035d5f6bb56fdcc5 100644 (file)
@@ -1342,7 +1342,7 @@ int dmaenginem_async_device_register(struct dma_device *device)
        if (ret)
                return ret;
 
-       return devm_add_action(device->dev, dmaenginem_async_device_unregister, device);
+       return devm_add_action_or_reset(device->dev, dmaenginem_async_device_unregister, device);
 }
 EXPORT_SYMBOL(dmaenginem_async_device_register);
 
index 462109c61653752b698558421a0192124ae0e20c..93ee298d52b894f1a7200844168c2baaf0406763 100644 (file)
@@ -277,7 +277,7 @@ failed:
 
 /**
  * xdma_xfer_start - Start DMA transfer
- * @xdma_chan: DMA channel pointer
+ * @xchan: DMA channel pointer
  */
 static int xdma_xfer_start(struct xdma_chan *xchan)
 {
index 73140b854b313f53736c690162a05595a036e6b8..c15928b8c5cc9976b9f12ca5a7e4154dcbb0e888 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/device.h>
-#include <linux/of.h>
 
 #include "common.h"
 
@@ -436,7 +435,7 @@ struct scmi_device *scmi_device_create(struct device_node *np,
        /* Nothing to do. */
        if (!phead) {
                mutex_unlock(&scmi_requested_devices_mtx);
-               return scmi_dev;
+               return NULL;
        }
 
        /* Walk the list of requested devices for protocol and create them */
index d21c7eafd641c228ce7e156ee516f5b645376c9b..dbc474ff62b71362a510cd02ecba2c50d72f7b53 100644 (file)
@@ -2221,8 +2221,8 @@ static int __scmi_xfer_info_init(struct scmi_info *sinfo,
        hash_init(info->pending_xfers);
 
        /* Allocate a bitmask sized to hold MSG_TOKEN_MAX tokens */
-       info->xfer_alloc_table = devm_kcalloc(dev, BITS_TO_LONGS(MSG_TOKEN_MAX),
-                                             sizeof(long), GFP_KERNEL);
+       info->xfer_alloc_table = devm_bitmap_zalloc(dev, MSG_TOKEN_MAX,
+                                                   GFP_KERNEL);
        if (!info->xfer_alloc_table)
                return -ENOMEM;
 
@@ -2657,6 +2657,7 @@ static int scmi_probe(struct platform_device *pdev)
        struct scmi_handle *handle;
        const struct scmi_desc *desc;
        struct scmi_info *info;
+       bool coex = IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX);
        struct device *dev = &pdev->dev;
        struct device_node *child, *np = dev->of_node;
 
@@ -2731,16 +2732,13 @@ static int scmi_probe(struct platform_device *pdev)
                        dev_warn(dev, "Failed to setup SCMI debugfs.\n");
 
                if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) {
-                       bool coex =
-                             IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX);
-
                        ret = scmi_debugfs_raw_mode_setup(info);
                        if (!coex) {
                                if (ret)
                                        goto clear_dev_req_notifier;
 
-                               /* Bail out anyway when coex enabled */
-                               return ret;
+                               /* Bail out anyway when coex disabled. */
+                               return 0;
                        }
 
                        /* Coex enabled, carry on in any case. */
@@ -2764,6 +2762,8 @@ static int scmi_probe(struct platform_device *pdev)
        ret = scmi_protocol_acquire(handle, SCMI_PROTOCOL_BASE);
        if (ret) {
                dev_err(dev, "unable to communicate with SCMI\n");
+               if (coex)
+                       return 0;
                goto notification_exit;
        }
 
index 0d9c9538b7f4175e0139563649ff2c687721f72e..112c285deb97b768fa3c23f6d738d8c0d043025b 100644 (file)
@@ -52,6 +52,39 @@ static bool mailbox_chan_available(struct device_node *of_node, int idx)
                                           "#mbox-cells", idx, NULL);
 }
 
+static int mailbox_chan_validate(struct device *cdev)
+{
+       int num_mb, num_sh, ret = 0;
+       struct device_node *np = cdev->of_node;
+
+       num_mb = of_count_phandle_with_args(np, "mboxes", "#mbox-cells");
+       num_sh = of_count_phandle_with_args(np, "shmem", NULL);
+       /* Bail out if mboxes and shmem descriptors are inconsistent */
+       if (num_mb <= 0 || num_sh > 2 || num_mb != num_sh) {
+               dev_warn(cdev, "Invalid channel descriptor for '%s'\n",
+                        of_node_full_name(np));
+               return -EINVAL;
+       }
+
+       if (num_sh > 1) {
+               struct device_node *np_tx, *np_rx;
+
+               np_tx = of_parse_phandle(np, "shmem", 0);
+               np_rx = of_parse_phandle(np, "shmem", 1);
+               /* SCMI Tx and Rx shared mem areas have to be distinct */
+               if (!np_tx || !np_rx || np_tx == np_rx) {
+                       dev_warn(cdev, "Invalid shmem descriptor for '%s'\n",
+                                of_node_full_name(np));
+                       ret = -EINVAL;
+               }
+
+               of_node_put(np_tx);
+               of_node_put(np_rx);
+       }
+
+       return ret;
+}
+
 static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
                              bool tx)
 {
@@ -64,6 +97,10 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
        resource_size_t size;
        struct resource res;
 
+       ret = mailbox_chan_validate(cdev);
+       if (ret)
+               return ret;
+
        smbox = devm_kzalloc(dev, sizeof(*smbox), GFP_KERNEL);
        if (!smbox)
                return -ENOMEM;
index f54e6fdf08e2bf4c62c4b93f7550b6f47074d361..f80a9af3d16e94de51e4f124ec4ff40a43eaa31a 100644 (file)
@@ -215,6 +215,14 @@ efi_earlycon_write(struct console *con, const char *str, unsigned int num)
        }
 }
 
+static bool __initdata fb_probed;
+
+void __init efi_earlycon_reprobe(void)
+{
+       if (fb_probed)
+               setup_earlycon("efifb");
+}
+
 static int __init efi_earlycon_setup(struct earlycon_device *device,
                                     const char *opt)
 {
@@ -222,15 +230,17 @@ static int __init efi_earlycon_setup(struct earlycon_device *device,
        u16 xres, yres;
        u32 i;
 
-       if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
+       fb_wb = opt && !strcmp(opt, "ram");
+
+       if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) {
+               fb_probed = true;
                return -ENODEV;
+       }
 
        fb_base = screen_info.lfb_base;
        if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
                fb_base |= (u64)screen_info.ext_lfb_base << 32;
 
-       fb_wb = opt && !strcmp(opt, "ram");
-
        si = &screen_info;
        xres = si->lfb_width;
        yres = si->lfb_height;
index 2c16080e1f71907c6f7b03434c4cd2ac47a6ea62..ef0820f1a9246ede74aa4a7aec41938628d2c755 100644 (file)
@@ -72,6 +72,9 @@ static void __init init_screen_info(void)
                if (memblock_is_map_memory(screen_info.lfb_base))
                        memblock_mark_nomap(screen_info.lfb_base,
                                            screen_info.lfb_size);
+
+               if (IS_ENABLED(CONFIG_EFI_EARLYCON))
+                       efi_earlycon_reprobe();
        }
 }
 
index 43e9a4cab9f5dcf169d158929bb3d9711817621b..ccdd6a130d98618ec52098bcc1cfc7f4f588c400 100644 (file)
@@ -44,4 +44,4 @@ OBJCOPYFLAGS_vmlinuz.efi := -O binary
 $(obj)/vmlinuz.efi: $(obj)/vmlinuz.efi.elf FORCE
        $(call if_changed,objcopy)
 
-targets += zboot-header.o vmlinuz.o vmlinuz.efi.elf vmlinuz.efi
+targets += zboot-header.o vmlinuz vmlinuz.o vmlinuz.efi.elf vmlinuz.efi
index d4a6b12a87413024a9c1df0b7a1744e8d0cd8f1a..770b8ecb73984c6115a5c37e2105637d4ec9bfd6 100644 (file)
@@ -85,8 +85,10 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
                }
        }
 
-       if (image->image_base != _text)
+       if (image->image_base != _text) {
                efi_err("FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value\n");
+               image->image_base = _text;
+       }
 
        if (!IS_ALIGNED((u64)_text, SEGMENT_ALIGN))
                efi_err("FIRMWARE BUG: kernel image not aligned on %dk boundary\n",
@@ -139,6 +141,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
        *image_addr = *reserve_addr;
        memcpy((void *)*image_addr, _text, kernel_size);
        caches_clean_inval_pou(*image_addr, *image_addr + kernel_codesize);
+       efi_remap_image(*image_addr, *reserve_size, kernel_codesize);
 
        return EFI_SUCCESS;
 }
index 3997702663727e30948d9083bad6e70e1498af02..8aad8c49d43f18e0903e055ecfbf38740c957fa0 100644 (file)
 
 static bool system_needs_vamap(void)
 {
-       const u8 *type1_family = efi_get_smbios_string(1, family);
+       const struct efi_smbios_type4_record *record;
+       const u32 __aligned(1) *socid;
+       const u8 *version;
 
        /*
         * Ampere eMAG, Altra, and Altra Max machines crash in SetTime() if
-        * SetVirtualAddressMap() has not been called prior.
+        * SetVirtualAddressMap() has not been called prior. Most Altra systems
+        * can be identified by the SMCCC soc ID, which is conveniently exposed
+        * via the type 4 SMBIOS records. Otherwise, test the processor version
+        * field. eMAG systems all appear to have the processor version field
+        * set to "eMAG".
         */
-       if (!type1_family || (
-           strcmp(type1_family, "eMAG") &&
-           strcmp(type1_family, "Altra") &&
-           strcmp(type1_family, "Altra Max")))
+       record = (struct efi_smbios_type4_record *)efi_get_smbios_record(4);
+       if (!record)
                return false;
 
-       efi_warn("Working around broken SetVirtualAddressMap()\n");
-       return true;
+       socid = (u32 *)record->processor_id;
+       switch (*socid & 0xffff000f) {
+               static char const altra[] = "Ampere(TM) Altra(TM) Processor";
+               static char const emag[] = "eMAG";
+
+       default:
+               version = efi_get_smbios_string(&record->header, 4,
+                                               processor_version);
+               if (!version || (strncmp(version, altra, sizeof(altra) - 1) &&
+                                strncmp(version, emag, sizeof(emag) - 1)))
+                       break;
+
+               fallthrough;
+
+       case 0x0a160001:        // Altra
+       case 0x0a160002:        // Altra Max
+               efi_warn("Working around broken SetVirtualAddressMap()\n");
+               return true;
+       }
+
+       return false;
 }
 
 efi_status_t check_platform_features(void)
index 5245c4f031c0a70a5a8aa1146a7da3b5abb7d933..cc4dcaea67fa67f4ae5ba312a6c3cdb575663a45 100644 (file)
@@ -5,6 +5,15 @@
 
 #include "efistub.h"
 
+static unsigned long screen_info_offset;
+
+struct screen_info *alloc_screen_info(void)
+{
+       if (IS_ENABLED(CONFIG_ARM))
+               return __alloc_screen_info();
+       return (void *)&screen_info + screen_info_offset;
+}
+
 /*
  * EFI entry point for the generic EFI stub used by ARM, arm64, RISC-V and
  * LoongArch. This is the entrypoint that is described in the PE/COFF header
@@ -56,6 +65,8 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
                return status;
        }
 
+       screen_info_offset = image_addr - (unsigned long)image->image_base;
+
        status = efi_stub_common(handle, image, image_addr, cmdline_ptr);
 
        efi_free(image_size, image_addr);
index 2955c1ac6a36ee00cff656f63eb79c57a98fb10d..f9c1e8a2bd1d3e49b5e98bfa6d419fe9b74b075d 100644 (file)
 static u64 virtmap_base = EFI_RT_VIRTUAL_BASE;
 static bool flat_va_mapping = (EFI_RT_VIRTUAL_OFFSET != 0);
 
-struct screen_info * __weak alloc_screen_info(void)
-{
-       return &screen_info;
-}
-
 void __weak free_screen_info(struct screen_info *si)
 {
 }
index 6bd3bb86d9679a1c26f6fa7416536f91e8762ba0..148013bcb5f89fdd90de221f4d88da83f6e75337 100644 (file)
@@ -1062,6 +1062,7 @@ efi_enable_reset_attack_mitigation(void) { }
 void efi_retrieve_tpm2_eventlog(void);
 
 struct screen_info *alloc_screen_info(void);
+struct screen_info *__alloc_screen_info(void);
 void free_screen_info(struct screen_info *si);
 
 void efi_cache_sync_image(unsigned long image_base,
@@ -1074,6 +1075,8 @@ struct efi_smbios_record {
        u16     handle;
 };
 
+const struct efi_smbios_record *efi_get_smbios_record(u8 type);
+
 struct efi_smbios_type1_record {
        struct efi_smbios_record        header;
 
@@ -1087,14 +1090,46 @@ struct efi_smbios_type1_record {
        u8                              family;
 };
 
-#define efi_get_smbios_string(__type, __name) ({                       \
-       int size = sizeof(struct efi_smbios_type ## __type ## _record); \
+struct efi_smbios_type4_record {
+       struct efi_smbios_record        header;
+
+       u8                              socket;
+       u8                              processor_type;
+       u8                              processor_family;
+       u8                              processor_manufacturer;
+       u8                              processor_id[8];
+       u8                              processor_version;
+       u8                              voltage;
+       u16                             external_clock;
+       u16                             max_speed;
+       u16                             current_speed;
+       u8                              status;
+       u8                              processor_upgrade;
+       u16                             l1_cache_handle;
+       u16                             l2_cache_handle;
+       u16                             l3_cache_handle;
+       u8                              serial_number;
+       u8                              asset_tag;
+       u8                              part_number;
+       u8                              core_count;
+       u8                              enabled_core_count;
+       u8                              thread_count;
+       u16                             processor_characteristics;
+       u16                             processor_family2;
+       u16                             core_count2;
+       u16                             enabled_core_count2;
+       u16                             thread_count2;
+       u16                             thread_enabled;
+};
+
+#define efi_get_smbios_string(__record, __type, __name) ({             \
        int off = offsetof(struct efi_smbios_type ## __type ## _record, \
                           __name);                                     \
-       __efi_get_smbios_string(__type, off, size);                     \
+       __efi_get_smbios_string((__record), __type, off);               \
 })
 
-const u8 *__efi_get_smbios_string(u8 type, int offset, int recsize);
+const u8 *__efi_get_smbios_string(const struct efi_smbios_record *record,
+                                 u8 type, int offset);
 
 void efi_remap_image(unsigned long image_base, unsigned alloc_size,
                     unsigned long code_size);
index 1692d19ae80f0065627650344aa6dbae92180928..32c7a54923b4c1273feee1db101accd48083256c 100644 (file)
@@ -101,6 +101,7 @@ efi_status_t efi_random_alloc(unsigned long size,
         * to calculate the randomly chosen address, and allocate it directly
         * using EFI_ALLOCATE_ADDRESS.
         */
+       status = EFI_OUT_OF_RESOURCES;
        for (map_offset = 0; map_offset < map->map_size; map_offset += map->desc_size) {
                efi_memory_desc_t *md = (void *)map->map + map_offset;
                efi_physical_addr_t target;
index 8e76a8b384ba142d6967b59e9dc310b4828f60f7..4be1c4d1f922becd08ddd13d542f4d2fbd6e1883 100644 (file)
  * early, but it only works if the EFI stub is part of the core kernel image
  * itself. The zboot decompressor can only use the configuration table
  * approach.
- *
- * In order to support both methods from the same build of the EFI stub
- * library, provide this dummy global definition of struct screen_info. If it
- * is required to satisfy a link dependency, it means we need to override the
- * __weak alloc and free methods with the ones below, and those will be pulled
- * in as well.
  */
-struct screen_info screen_info;
 
 static efi_guid_t screen_info_guid = LINUX_EFI_SCREEN_INFO_TABLE_GUID;
 
-struct screen_info *alloc_screen_info(void)
+struct screen_info *__alloc_screen_info(void)
 {
        struct screen_info *si;
        efi_status_t status;
index 460418b7f5f5e9ab1d721ec096eaa77bb2462c58..c217de2cc8d56dc2796679f207772ff1288ba3d4 100644 (file)
@@ -22,21 +22,30 @@ struct efi_smbios_protocol {
        u8 minor_version;
 };
 
-const u8 *__efi_get_smbios_string(u8 type, int offset, int recsize)
+const struct efi_smbios_record *efi_get_smbios_record(u8 type)
 {
        struct efi_smbios_record *record;
        efi_smbios_protocol_t *smbios;
        efi_status_t status;
        u16 handle = 0xfffe;
-       const u8 *strtable;
 
        status = efi_bs_call(locate_protocol, &EFI_SMBIOS_PROTOCOL_GUID, NULL,
                             (void **)&smbios) ?:
                 efi_call_proto(smbios, get_next, &handle, &type, &record, NULL);
        if (status != EFI_SUCCESS)
                return NULL;
+       return record;
+}
+
+const u8 *__efi_get_smbios_string(const struct efi_smbios_record *record,
+                                 u8 type, int offset)
+{
+       const u8 *strtable;
+
+       if (!record)
+               return NULL;
 
-       strtable = (u8 *)record + recsize;
+       strtable = (u8 *)record + record->length;
        for (int i = 1; i < ((u8 *)record)[offset]; i++) {
                int len = strlen(strtable);
 
index ec4525d40e0cf6d635161da889f14862d7a5610d..445cb646eaaaf1c657f572e0f2d42c63962bfe27 100644 (file)
@@ -63,7 +63,7 @@ __efistub_efi_zboot_header:
        .long           .Lefi_header_end - .Ldoshdr
        .long           0
        .short          IMAGE_SUBSYSTEM_EFI_APPLICATION
-       .short          0
+       .short          IMAGE_DLL_CHARACTERISTICS_NX_COMPAT
 #ifdef CONFIG_64BIT
        .quad           0, 0, 0, 0
 #else
index ba234e062a1a29dae5618fa9c85bb65ff96fbee5..6105e5e2eda4612b3aa59e9c3e10e25f81075d7d 100644 (file)
@@ -57,6 +57,11 @@ void __weak efi_cache_sync_image(unsigned long image_base,
        // executable code loaded into memory to be safe for execution.
 }
 
+struct screen_info *alloc_screen_info(void)
+{
+       return __alloc_screen_info();
+}
+
 asmlinkage efi_status_t __efiapi
 efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
 {
index f06fdacc9bc830c8f89916a342f795fc33d988cb..456d0e5eaf78b595a66c622103b719e0fd2d3a69 100644 (file)
@@ -272,6 +272,14 @@ static const struct dmi_system_id efifb_dmi_swap_width_height[] __initconst = {
                                        "IdeaPad Duet 3 10IGL5"),
                },
        },
+       {
+               /* Lenovo Yoga Book X91F / X91L */
+               .matches = {
+                       DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       /* Non exact match to match F + L versions */
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"),
+               },
+       },
        {},
 };
 
@@ -341,7 +349,7 @@ static const struct fwnode_operations efifb_fwnode_ops = {
 #ifdef CONFIG_EFI
 static struct fwnode_handle efifb_fwnode;
 
-__init void sysfb_apply_efi_quirks(struct platform_device *pd)
+__init void sysfb_apply_efi_quirks(void)
 {
        if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI ||
            !(screen_info.capabilities & VIDEO_CAPABILITY_SKIP_QUIRKS))
@@ -355,7 +363,10 @@ __init void sysfb_apply_efi_quirks(struct platform_device *pd)
                screen_info.lfb_height = temp;
                screen_info.lfb_linelength = 4 * screen_info.lfb_width;
        }
+}
 
+__init void sysfb_set_efifb_fwnode(struct platform_device *pd)
+{
        if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI && IS_ENABLED(CONFIG_PCI)) {
                fwnode_init(&efifb_fwnode, &efifb_fwnode_ops);
                pd->dev.fwnode = &efifb_fwnode;
index 29619f49873a18abd897c7f84751fb266a8e9cac..d9629ff8786199c33500b154616584013c8d1d1e 100644 (file)
@@ -167,7 +167,8 @@ int psci_set_osi_mode(bool enable)
 
        err = invoke_psci_fn(PSCI_1_0_FN_SET_SUSPEND_MODE, suspend_mode, 0, 0);
        if (err < 0)
-               pr_warn("failed to set %s mode: %d\n", enable ? "OSI" : "PC", err);
+               pr_info(FW_BUG "failed to set %s mode: %d\n",
+                               enable ? "OSI" : "PC", err);
        return psci_to_linux_errno(err);
 }
 
index 468d4d5ab550c91cfa415418cc5333746dc596c8..b1e11f85b805462fb96def68632ae11fe3a7fd88 100644 (file)
@@ -1479,7 +1479,7 @@ static int qcom_scm_probe(struct platform_device *pdev)
 
        init_completion(&__scm->waitq_comp);
 
-       irq = platform_get_irq(pdev, 0);
+       irq = platform_get_irq_optional(pdev, 0);
        if (irq < 0) {
                if (irq != -ENXIO)
                        return irq;
index 3fd3563d962b87d73ff2fc2bb3079461cd9f22e0..3c197db42c9d936866f9ff68cf7561e4735cfe1e 100644 (file)
@@ -81,6 +81,8 @@ static __init int sysfb_init(void)
        if (disabled)
                goto unlock_mutex;
 
+       sysfb_apply_efi_quirks();
+
        /* try to create a simple-framebuffer device */
        compatible = sysfb_parse_mode(si, &mode);
        if (compatible) {
@@ -107,7 +109,7 @@ static __init int sysfb_init(void)
                goto unlock_mutex;
        }
 
-       sysfb_apply_efi_quirks(pd);
+       sysfb_set_efifb_fwnode(pd);
 
        ret = platform_device_add_data(pd, si, sizeof(*si));
        if (ret)
index ce9c007ed66ff76d64bf3fd4c023198152a32459..82c64cb9f5316c230fcb25b34936f96f92e215d1 100644 (file)
@@ -141,7 +141,7 @@ __init struct platform_device *sysfb_create_simplefb(const struct screen_info *s
        if (!pd)
                return ERR_PTR(-ENOMEM);
 
-       sysfb_apply_efi_quirks(pd);
+       sysfb_set_efifb_fwnode(pd);
 
        ret = platform_device_add_resources(pd, &res, 1);
        if (ret)
index acd83d29c8667d86b7d854e8f240a16123afa21f..ce86a18503054110062a315c2449c6ce57bad26a 100644 (file)
@@ -206,7 +206,7 @@ static int do_feature_check_call(const u32 api_id)
        }
 
        /* Add new entry if not present */
-       feature_data = kmalloc(sizeof(*feature_data), GFP_KERNEL);
+       feature_data = kmalloc(sizeof(*feature_data), GFP_ATOMIC);
        if (!feature_data)
                return -ENOMEM;
 
index 0914e7328b1a53664d233b5f2bd52576b09d397b..1bc04378118c7b2d6c672a31b8550c448edfa58b 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/module.h>
 #include <linux/stddef.h>
 #include <linux/errno.h>
-#include <linux/aer.h>
 
 #include "dfl.h"
 
@@ -376,10 +375,6 @@ int cci_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *pcidevid)
                return ret;
        }
 
-       ret = pci_enable_pcie_error_reporting(pcidev);
-       if (ret && ret != -EINVAL)
-               dev_info(&pcidev->dev, "PCIE AER unavailable %d.\n", ret);
-
        pci_set_master(pcidev);
 
        ret = dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(64));
@@ -387,24 +382,22 @@ int cci_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *pcidevid)
                ret = dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(32));
        if (ret) {
                dev_err(&pcidev->dev, "No suitable DMA support available.\n");
-               goto disable_error_report_exit;
+               return ret;
        }
 
        ret = cci_init_drvdata(pcidev);
        if (ret) {
                dev_err(&pcidev->dev, "Fail to init drvdata %d.\n", ret);
-               goto disable_error_report_exit;
+               return ret;
        }
 
        ret = cci_enumerate_feature_devs(pcidev);
-       if (!ret)
+       if (ret) {
+               dev_err(&pcidev->dev, "enumeration failure %d.\n", ret);
                return ret;
+       }
 
-       dev_err(&pcidev->dev, "enumeration failure %d.\n", ret);
-
-disable_error_report_exit:
-       pci_disable_pcie_error_reporting(pcidev);
-       return ret;
+       return 0;
 }
 
 static int cci_pci_sriov_configure(struct pci_dev *pcidev, int num_vfs)
@@ -448,7 +441,6 @@ static void cci_pci_remove(struct pci_dev *pcidev)
                cci_pci_sriov_configure(pcidev, 0);
 
        cci_remove_feature_devs(pcidev);
-       pci_disable_pcie_error_reporting(pcidev);
 }
 
 static struct pci_driver cci_pci_driver = {
index 5cd40acab5bfb85f52302ea244c2906af1213f1f..0953e6e4db041d635a349b4a45fe9714e7343755 100644 (file)
@@ -363,7 +363,6 @@ fpga_bridge_register(struct device *parent, const char *name,
        bridge->dev.parent = parent;
        bridge->dev.of_node = parent->of_node;
        bridge->dev.id = id;
-       of_platform_populate(bridge->dev.of_node, NULL, NULL, &bridge->dev);
 
        ret = dev_set_name(&bridge->dev, "br%d", id);
        if (ret)
@@ -375,6 +374,8 @@ fpga_bridge_register(struct device *parent, const char *name,
                return ERR_PTR(ret);
        }
 
+       of_platform_populate(bridge->dev.of_node, NULL, NULL, &bridge->dev);
+
        return bridge;
 
 error_device:
index f0acedc801827a3c268eedee45264781b14c6cf1..d7e2f9f461bcab3bd196699076ba47e660f82719 100644 (file)
@@ -474,7 +474,7 @@ static enum fw_upload_err rsu_send_data(struct m10bmc_sec *sec)
 
        ret = sec->ops->rsu_status(sec);
        if (ret < 0)
-               return ret;
+               return FW_UPLOAD_ERR_HW_ERROR;
        status = ret;
 
        if (!rsu_status_ok(status)) {
index 2d9c491f7be9477be2bf187c1d28941395bb968f..b76d85449b8fb2a15e9cea2cd563663ccbd8f61e 100644 (file)
@@ -69,7 +69,7 @@ static int xlnx_pr_decoupler_enable_show(struct fpga_bridge *bridge)
        if (err)
                return err;
 
-       status = readl(priv->io_base);
+       status = xlnx_pr_decouple_read(priv, CTRL_OFFSET);
 
        clk_disable(priv->clk);
 
index 13be729710f28250fad8772c6a9b80a1be984a47..badbe05823180507916c95eca9013b0841374a83 100644 (file)
@@ -100,7 +100,7 @@ config GPIO_GENERIC
        tristate
 
 config GPIO_REGMAP
-       depends on REGMAP
+       select REGMAP
        tristate
 
 # put drivers in the right section, in alphabetical order
index a3846faf3780dcbe7337fe5db085c657eed89fe0..11c48130bb8f16a88e1bee7bc4659475f92e1dbe 100644 (file)
@@ -86,6 +86,7 @@ static const struct regmap_config dio48e_regmap_config = {
        .volatile_table = &dio48e_volatile_table,
        .precious_table = &dio48e_precious_table,
        .cache_type = REGCACHE_FLAT,
+       .use_raw_spinlock = true,
 };
 
 /* only bit 3 on each respective Port C supports interrupts */
index ca2175b84e2417593bbc3292c524b9f68823c997..ba73ee9c0c291508516bf18839dba413e5933294 100644 (file)
@@ -81,6 +81,7 @@ static const struct regmap_config idi48_regmap_config = {
        .wr_table = &idi_48_wr_table,
        .rd_table = &idi_48_rd_table,
        .precious_table = &idi_48_precious_table,
+       .use_raw_spinlock = true,
 };
 
 #define IDI48_NGPIO 48
index 26b1f7465e09176fe56cd9456a55665a1a0cc033..43b2dc8821e6b59eb849d5301cd3456f21d64af0 100644 (file)
@@ -324,7 +324,7 @@ static struct irq_chip gpio_irqchip = {
        .irq_enable     = gpio_irq_enable,
        .irq_disable    = gpio_irq_disable,
        .irq_set_type   = gpio_irq_type,
-       .flags          = IRQCHIP_SET_TYPE_MASKED,
+       .flags          = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_SKIP_SET_WAKE,
 };
 
 static void gpio_irq_handler(struct irq_desc *desc)
@@ -641,9 +641,6 @@ static void davinci_gpio_save_context(struct davinci_gpio_controller *chips,
                context->set_falling = readl_relaxed(&g->set_falling);
        }
 
-       /* Clear Bank interrupt enable bit */
-       writel_relaxed(0, base + BINTEN);
-
        /* Clear all interrupt status registers */
        writel_relaxed(GENMASK(31, 0), &g->intstat);
 }
index d8a421ce26a83e1b9f98dfbc37bd4135cbf34497..31ae0adbb295ab190bd69ef37ffbb02062536d1a 100644 (file)
@@ -536,6 +536,9 @@ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
        if (ACPI_FAILURE(status))
                return;
 
+       if (acpi_quirk_skip_gpio_event_handlers())
+               return;
+
        acpi_walk_resources(handle, METHOD_NAME__AEI,
                            acpi_gpiochip_alloc_event, acpi_gpio);
 
index 164141bc8b4ad1e145ead120d3094ea02efa40bb..39018f784f9c01d430472a7541c03ec645d35ce5 100644 (file)
@@ -1272,6 +1272,7 @@ void amdgpu_device_pci_config_reset(struct amdgpu_device *adev);
 int amdgpu_device_pci_reset(struct amdgpu_device *adev);
 bool amdgpu_device_need_post(struct amdgpu_device *adev);
 bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev);
+bool amdgpu_device_aspm_support_quirk(void);
 
 void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes,
                                  u64 num_vis_bytes);
@@ -1391,10 +1392,12 @@ int amdgpu_acpi_smart_shift_update(struct drm_device *dev, enum amdgpu_ss ss_sta
 int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev);
 
 void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps);
+bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev);
 void amdgpu_acpi_detect(void);
 #else
 static inline int amdgpu_acpi_init(struct amdgpu_device *adev) { return 0; }
 static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { }
+static inline bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev) { return false; }
 static inline void amdgpu_acpi_detect(void) { }
 static inline bool amdgpu_acpi_is_power_shift_control_supported(void) { return false; }
 static inline int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev,
@@ -1405,11 +1408,9 @@ static inline int amdgpu_acpi_smart_shift_update(struct drm_device *dev,
 
 #if defined(CONFIG_ACPI) && defined(CONFIG_SUSPEND)
 bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev);
-bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev);
 bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev);
 #else
 static inline bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) { return false; }
-static inline bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev) { return false; }
 static inline bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev) { return false; }
 #endif
 
index d4196fcb85a08a364a4a7b235c30a62dde7fa8f8..aeeec211861c434bae58aae748586e4a608360d5 100644 (file)
@@ -971,6 +971,34 @@ static bool amdgpu_atcs_pci_probe_handle(struct pci_dev *pdev)
        return true;
 }
 
+
+/**
+ * amdgpu_acpi_should_gpu_reset
+ *
+ * @adev: amdgpu_device_pointer
+ *
+ * returns true if should reset GPU, false if not
+ */
+bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev)
+{
+       if ((adev->flags & AMD_IS_APU) &&
+           adev->gfx.imu.funcs) /* Not need to do mode2 reset for IMU enabled APUs */
+               return false;
+
+       if ((adev->flags & AMD_IS_APU) &&
+           amdgpu_acpi_is_s3_active(adev))
+               return false;
+
+       if (amdgpu_sriov_vf(adev))
+               return false;
+
+#if IS_ENABLED(CONFIG_SUSPEND)
+       return pm_suspend_target_state != PM_SUSPEND_TO_IDLE;
+#else
+       return true;
+#endif
+}
+
 /*
  * amdgpu_acpi_detect - detect ACPI ATIF/ATCS methods
  *
@@ -1042,24 +1070,6 @@ bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev)
                (pm_suspend_target_state == PM_SUSPEND_MEM);
 }
 
-/**
- * amdgpu_acpi_should_gpu_reset
- *
- * @adev: amdgpu_device_pointer
- *
- * returns true if should reset GPU, false if not
- */
-bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev)
-{
-       if (adev->flags & AMD_IS_APU)
-               return false;
-
-       if (amdgpu_sriov_vf(adev))
-               return false;
-
-       return pm_suspend_target_state != PM_SUSPEND_TO_IDLE;
-}
-
 /**
  * amdgpu_acpi_is_s0ix_active
  *
index c4a4e2fe66814ccf07a2edd13a00bd5bbf8bedd2..3d98fc2ad36b04eb0d44fbc0e897608e5122a8c7 100644 (file)
 
 #include <drm/drm_drv.h>
 
+#if IS_ENABLED(CONFIG_X86)
+#include <asm/intel-family.h>
+#endif
+
 MODULE_FIRMWARE("amdgpu/vega10_gpu_info.bin");
 MODULE_FIRMWARE("amdgpu/vega12_gpu_info.bin");
 MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin");
@@ -1356,6 +1360,17 @@ bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev)
        return pcie_aspm_enabled(adev->pdev);
 }
 
+bool amdgpu_device_aspm_support_quirk(void)
+{
+#if IS_ENABLED(CONFIG_X86)
+       struct cpuinfo_x86 *c = &cpu_data(0);
+
+       return !(c->x86 == 6 && c->x86_model == INTEL_FAM6_ALDERLAKE);
+#else
+       return true;
+#endif
+}
+
 /* if we get transitioned to only one device, take VGA back */
 /**
  * amdgpu_device_vga_set_decode - enable/disable vga decode
@@ -4145,8 +4160,6 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
        if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DEV_D3))
                DRM_WARN("smart shift update failed\n");
 
-       drm_kms_helper_poll_disable(dev);
-
        if (fbcon)
                drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, true);
 
@@ -4243,8 +4256,6 @@ exit:
        if (fbcon)
                drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, false);
 
-       drm_kms_helper_poll_enable(dev);
-
        amdgpu_ras_resume(adev);
 
        if (adev->mode_info.num_crtc) {
index b719852daa071a00c543485a75f43af2fb45e28b..1a3cb53d2e0d0cc977c756635cf5146a51d50007 100644 (file)
@@ -543,6 +543,7 @@ static void amdgpu_discovery_read_from_harvest_table(struct amdgpu_device *adev,
        struct harvest_table *harvest_info;
        u16 offset;
        int i;
+       uint32_t umc_harvest_config = 0;
 
        bhdr = (struct binary_header *)adev->mman.discovery_bin;
        offset = le16_to_cpu(bhdr->table_list[HARVEST_INFO].offset);
@@ -570,12 +571,17 @@ static void amdgpu_discovery_read_from_harvest_table(struct amdgpu_device *adev,
                        adev->harvest_ip_mask |= AMD_HARVEST_IP_DMU_MASK;
                        break;
                case UMC_HWID:
+                       umc_harvest_config |=
+                               1 << (le16_to_cpu(harvest_info->list[i].number_instance));
                        (*umc_harvest_count)++;
                        break;
                default:
                        break;
                }
        }
+
+       adev->umc.active_mask = ((1 << adev->umc.node_inst_num) - 1) &
+                               ~umc_harvest_config;
 }
 
 /* ================================================== */
@@ -1156,8 +1162,10 @@ static int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
                                                AMDGPU_MAX_SDMA_INSTANCES);
                        }
 
-                       if (le16_to_cpu(ip->hw_id) == UMC_HWID)
+                       if (le16_to_cpu(ip->hw_id) == UMC_HWID) {
                                adev->gmc.num_umc++;
+                               adev->umc.node_inst_num++;
+                       }
 
                        for (k = 0; k < num_base_address; k++) {
                                /*
index 503f89a766c3774e4626b70f7ea49cacd7e31b2f..d60fe7eb5579aeae48961105b832e1a47fe1300c 100644 (file)
@@ -1618,6 +1618,8 @@ int amdgpu_display_suspend_helper(struct amdgpu_device *adev)
        struct drm_connector_list_iter iter;
        int r;
 
+       drm_kms_helper_poll_disable(dev);
+
        /* turn off display hw */
        drm_modeset_lock_all(dev);
        drm_connector_list_iter_begin(dev, &iter);
@@ -1694,6 +1696,8 @@ int amdgpu_display_resume_helper(struct amdgpu_device *adev)
 
        drm_modeset_unlock_all(dev);
 
+       drm_kms_helper_poll_enable(dev);
+
        return 0;
 }
 
index f5ffca24def4000f42043d4c09e5f05fe86f8876..ba5def374368e578ba842f20bbeab6d38777f52e 100644 (file)
@@ -2467,7 +2467,10 @@ static int amdgpu_pmops_freeze(struct device *dev)
        adev->in_s4 = false;
        if (r)
                return r;
-       return amdgpu_asic_reset(adev);
+
+       if (amdgpu_acpi_should_gpu_reset(adev))
+               return amdgpu_asic_reset(adev);
+       return 0;
 }
 
 static int amdgpu_pmops_thaw(struct device *dev)
index faff4a3f96e6e8911e573daf46b4b894103a76e3..f52d0ba91a770a4b437a1137aa88cf6a7113cf53 100644 (file)
@@ -678,6 +678,15 @@ void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring)
                ptr = &ring->fence_drv.fences[i];
                old = rcu_dereference_protected(*ptr, 1);
                if (old && old->ops == &amdgpu_job_fence_ops) {
+                       struct amdgpu_job *job;
+
+                       /* For non-scheduler bad job, i.e. failed ib test, we need to signal
+                        * it right here or we won't be able to track them in fence_drv
+                        * and they will remain unsignaled during sa_bo free.
+                        */
+                       job = container_of(old, struct amdgpu_job, hw_fence);
+                       if (!job->base.s_fence && !dma_fence_is_signaled(old))
+                               dma_fence_signal(old);
                        RCU_INIT_POINTER(*ptr, NULL);
                        dma_fence_put(old);
                }
index d0a1cc88832cc4bd3c53ddf6f5f1127d491bcb2a..fafebec5b7b66da8911ffb2f112817a1f1f626ae 100644 (file)
@@ -596,6 +596,9 @@ int amdgpu_irq_put(struct amdgpu_device *adev, struct amdgpu_irq_src *src,
        if (!src->enabled_types || !src->funcs->set)
                return -EINVAL;
 
+       if (WARN_ON(!amdgpu_irq_enabled(adev, src, type)))
+               return -EINVAL;
+
        if (atomic_dec_and_test(&src->enabled_types[type]))
                return amdgpu_irq_update(adev, src, type);
 
index e3e1ed4314dd65a84a918e4fc343a023abc713f5..6c7d672412b21454278ecd151f61c1ef5c59987e 100644 (file)
@@ -1315,7 +1315,7 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
 
        if (!bo->resource || bo->resource->mem_type != TTM_PL_VRAM ||
            !(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE) ||
-           adev->in_suspend || adev->shutdown)
+           adev->in_suspend || drm_dev_is_unplugged(adev_to_drm(adev)))
                return;
 
        if (WARN_ON_ONCE(!dma_resv_trylock(bo->base.resv)))
index 28fe6d94105409b9783985183ddae9606b1e7c84..3f5d13035aff0ce55b4740a01bbdaa4306a137ff 100644 (file)
@@ -602,27 +602,14 @@ psp_cmd_submit_buf(struct psp_context *psp,
                   struct psp_gfx_cmd_resp *cmd, uint64_t fence_mc_addr)
 {
        int ret;
-       int index, idx;
+       int index;
        int timeout = 20000;
        bool ras_intr = false;
        bool skip_unsupport = false;
-       bool dev_entered;
 
        if (psp->adev->no_hw_access)
                return 0;
 
-       dev_entered = drm_dev_enter(adev_to_drm(psp->adev), &idx);
-       /*
-        * We allow sending PSP messages LOAD_ASD and UNLOAD_TA without acquiring
-        * a lock in drm_dev_enter during driver unload because we must call
-        * drm_dev_unplug as the beginning  of unload driver sequence . It is very
-        * crucial that userspace can't access device instances anymore.
-        */
-       if (!dev_entered)
-               WARN_ON(psp->cmd_buf_mem->cmd_id != GFX_CMD_ID_LOAD_ASD &&
-                       psp->cmd_buf_mem->cmd_id != GFX_CMD_ID_UNLOAD_TA &&
-                       psp->cmd_buf_mem->cmd_id != GFX_CMD_ID_INVOKE_CMD);
-
        memset(psp->cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE);
 
        memcpy(psp->cmd_buf_mem, cmd, sizeof(struct psp_gfx_cmd_resp));
@@ -686,8 +673,6 @@ psp_cmd_submit_buf(struct psp_context *psp,
        }
 
 exit:
-       if (dev_entered)
-               drm_dev_exit(idx);
        return ret;
 }
 
index f2bf979af5883596169c12aba6db42ceaaa66f30..36e19336f3b34ee8d71883658a7352b61b96de3e 100644 (file)
@@ -42,7 +42,7 @@
 #define LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) LOOP_UMC_INST((umc_inst)) LOOP_UMC_CH_INST((ch_inst))
 
 #define LOOP_UMC_NODE_INST(node_inst) \
-               for ((node_inst) = 0; (node_inst) < adev->umc.node_inst_num; (node_inst)++)
+               for_each_set_bit((node_inst), &(adev->umc.active_mask), adev->umc.node_inst_num)
 
 #define LOOP_UMC_EACH_NODE_INST_AND_CH(node_inst, umc_inst, ch_inst) \
                LOOP_UMC_NODE_INST((node_inst)) LOOP_UMC_INST_AND_CH((umc_inst), (ch_inst))
@@ -69,7 +69,7 @@ struct amdgpu_umc {
        /* number of umc instance with memory map register access */
        uint32_t umc_inst_num;
 
-       /*number of umc node instance with memory map register access*/
+       /* Total number of umc node instance including harvest one */
        uint32_t node_inst_num;
 
        /* UMC regiser per channel offset */
@@ -82,6 +82,9 @@ struct amdgpu_umc {
 
        const struct amdgpu_umc_funcs *funcs;
        struct amdgpu_umc_ras *ras;
+
+       /* active mask for umc node instance */
+       unsigned long active_mask;
 };
 
 int amdgpu_umc_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block);
index 25217b05c0ea8dabd5c4ef4fd22885e875d2af2c..e7974de8b035d6f356db79549408e6fef9755364 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/firmware.h>
 #include <linux/module.h>
+#include <linux/dmi.h>
 #include <linux/pci.h>
 #include <linux/debugfs.h>
 #include <drm/drm_drv.h>
@@ -114,6 +115,24 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
            (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
                adev->vcn.indirect_sram = true;
 
+       /*
+        * Some Steam Deck's BIOS versions are incompatible with the
+        * indirect SRAM mode, leading to amdgpu being unable to get
+        * properly probed (and even potentially crashing the kernel).
+        * Hence, check for these versions here - notice this is
+        * restricted to Vangogh (Deck's APU).
+        */
+       if (adev->ip_versions[UVD_HWIP][0] == IP_VERSION(3, 0, 2)) {
+               const char *bios_ver = dmi_get_system_info(DMI_BIOS_VERSION);
+
+               if (bios_ver && (!strncmp("F7A0113", bios_ver, 7) ||
+                    !strncmp("F7A0114", bios_ver, 7))) {
+                       adev->vcn.indirect_sram = false;
+                       dev_info(adev->dev,
+                               "Steam Deck quirk: indirect SRAM disabled on BIOS %s\n", bios_ver);
+               }
+       }
+
        hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
        adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version);
 
index b9e9480448afe9e56324daf866deb77eb2d34063..4f7bab52282ac1b6463fb2420315bbdf4b92b0ba 100644 (file)
@@ -124,6 +124,8 @@ enum AMDGIM_FEATURE_FLAG {
        AMDGIM_FEATURE_PP_ONE_VF = (1 << 4),
        /* Indirect Reg Access enabled */
        AMDGIM_FEATURE_INDIRECT_REG_ACCESS = (1 << 5),
+       /* AV1 Support MODE*/
+       AMDGIM_FEATURE_AV1_SUPPORT = (1 << 6),
 };
 
 enum AMDGIM_REG_ACCESS_FLAG {
@@ -322,6 +324,8 @@ static inline bool is_virtual_machine(void)
        ((!amdgpu_in_reset(adev)) && adev->virt.tdr_debug)
 #define amdgpu_sriov_is_normal(adev) \
        ((!amdgpu_in_reset(adev)) && (!adev->virt.tdr_debug))
+#define amdgpu_sriov_is_av1_support(adev) \
+       ((adev)->virt.gim_feature & AMDGIM_FEATURE_AV1_SUPPORT)
 bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev);
 void amdgpu_virt_init_setting(struct amdgpu_device *adev);
 void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
index 6c97148ca0ed35dc9c66c828bd45a870281a5c44..24d42d24e6a01e033a84edbbfe561e0878dd6049 100644 (file)
@@ -93,7 +93,8 @@ union amd_sriov_msg_feature_flags {
                uint32_t mm_bw_management  : 1;
                uint32_t pp_one_vf_mode    : 1;
                uint32_t reg_indirect_acc  : 1;
-               uint32_t reserved          : 26;
+               uint32_t av1_support       : 1;
+               uint32_t reserved          : 25;
        } flags;
        uint32_t all;
 };
index 3bf697a80cf2fc30a4dcc49e154ee87b5ffe4370..ecf8ceb53311ac2d1dbb09b80244fef86dc3bca3 100644 (file)
@@ -1287,6 +1287,11 @@ static int gfx_v11_0_sw_init(void *handle)
                break;
        }
 
+       /* Enable CG flag in one VF mode for enabling RLC safe mode enter/exit */
+       if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(11, 0, 3) &&
+               amdgpu_sriov_is_pp_one_vf(adev))
+               adev->cg_flags = AMD_CG_SUPPORT_GFX_CGCG;
+
        /* EOP Event */
        r = amdgpu_irq_add_id(adev, SOC21_IH_CLIENTID_GRBM_CP,
                              GFX_11_0_0__SRCID__CP_EOP_INTERRUPT,
@@ -4655,6 +4660,14 @@ static bool gfx_v11_0_check_soft_reset(void *handle)
        return false;
 }
 
+static int gfx_v11_0_post_soft_reset(void *handle)
+{
+       /**
+        * GFX soft reset will impact MES, need resume MES when do GFX soft reset
+        */
+       return amdgpu_mes_resume((struct amdgpu_device *)handle);
+}
+
 static uint64_t gfx_v11_0_get_gpu_clock_counter(struct amdgpu_device *adev)
 {
        uint64_t clock;
@@ -6166,6 +6179,7 @@ static const struct amd_ip_funcs gfx_v11_0_ip_funcs = {
        .wait_for_idle = gfx_v11_0_wait_for_idle,
        .soft_reset = gfx_v11_0_soft_reset,
        .check_soft_reset = gfx_v11_0_check_soft_reset,
+       .post_soft_reset = gfx_v11_0_post_soft_reset,
        .set_clockgating_state = gfx_v11_0_set_clockgating_state,
        .set_powergating_state = gfx_v11_0_set_powergating_state,
        .get_clockgating_state = gfx_v11_0_get_clockgating_state,
index 85e0afc3d4f7f336715629779c44170eb4ab7c8f..af7b3ba1ca0002caae1c0dc47080f6b49c24a8ec 100644 (file)
@@ -567,7 +567,6 @@ static void gmc_v11_0_set_umc_funcs(struct amdgpu_device *adev)
        case IP_VERSION(8, 10, 0):
                adev->umc.channel_inst_num = UMC_V8_10_CHANNEL_INSTANCE_NUM;
                adev->umc.umc_inst_num = UMC_V8_10_UMC_INSTANCE_NUM;
-               adev->umc.node_inst_num = adev->gmc.num_umc;
                adev->umc.max_ras_err_cnt_per_query = UMC_V8_10_TOTAL_CHANNEL_NUM(adev);
                adev->umc.channel_offs = UMC_V8_10_PER_CHANNEL_OFFSET;
                adev->umc.retire_unit = UMC_V8_10_NA_COL_2BITS_POWER_OF_2_NUM;
index 4b0d563c6522c7b050591c49f0cd89595b96d7d0..4ef1fa4603c8ec994698847d91627608627e9d27 100644 (file)
@@ -382,11 +382,6 @@ static void nbio_v7_2_init_registers(struct amdgpu_device *adev)
                if (def != data)
                        WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regBIF1_PCIE_MST_CTRL_3), data);
                break;
-       case IP_VERSION(7, 5, 1):
-               data = RREG32_SOC15(NBIO, 0, regRCC_DEV2_EPF0_STRAP2);
-               data &= ~RCC_DEV2_EPF0_STRAP2__STRAP_NO_SOFT_RESET_DEV2_F0_MASK;
-               WREG32_SOC15(NBIO, 0, regRCC_DEV2_EPF0_STRAP2, data);
-               fallthrough;
        default:
                def = data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CONFIG_CNTL));
                data = REG_SET_FIELD(data, PCIE_CONFIG_CNTL,
@@ -399,6 +394,15 @@ static void nbio_v7_2_init_registers(struct amdgpu_device *adev)
                break;
        }
 
+       switch (adev->ip_versions[NBIO_HWIP][0]) {
+       case IP_VERSION(7, 3, 0):
+       case IP_VERSION(7, 5, 1):
+               data = RREG32_SOC15(NBIO, 0, regRCC_DEV2_EPF0_STRAP2);
+               data &= ~RCC_DEV2_EPF0_STRAP2__STRAP_NO_SOFT_RESET_DEV2_F0_MASK;
+               WREG32_SOC15(NBIO, 0, regRCC_DEV2_EPF0_STRAP2, data);
+               break;
+       }
+
        if (amdgpu_sriov_vf(adev))
                adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0,
                        regBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2;
index d972025f0d20f59a9d06808ad2c2f103c0c09bea..ebe0e2d7dbd1b59d772ae52d641f43a9914921b3 100644 (file)
@@ -444,9 +444,10 @@ static int nv_read_register(struct amdgpu_device *adev, u32 se_num,
        *value = 0;
        for (i = 0; i < ARRAY_SIZE(nv_allowed_read_registers); i++) {
                en = &nv_allowed_read_registers[i];
-               if (adev->reg_offset[en->hwip][en->inst] &&
-                   reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg]
-                                  + en->reg_offset))
+               if (!adev->reg_offset[en->hwip][en->inst])
+                       continue;
+               else if (reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg]
+                                       + en->reg_offset))
                        continue;
 
                *value = nv_get_register_value(adev,
@@ -577,7 +578,7 @@ static void nv_pcie_gen3_enable(struct amdgpu_device *adev)
 
 static void nv_program_aspm(struct amdgpu_device *adev)
 {
-       if (!amdgpu_device_should_use_aspm(adev))
+       if (!amdgpu_device_should_use_aspm(adev) || !amdgpu_device_aspm_support_quirk())
                return;
 
        if (!(adev->flags & AMD_IS_APU) &&
@@ -1054,8 +1055,8 @@ static int nv_common_late_init(void *handle)
                        amdgpu_virt_update_sriov_video_codec(adev,
                                                             sriov_sc_video_codecs_encode_array,
                                                             ARRAY_SIZE(sriov_sc_video_codecs_encode_array),
-                                                            sriov_sc_video_codecs_decode_array_vcn1,
-                                                            ARRAY_SIZE(sriov_sc_video_codecs_decode_array_vcn1));
+                                                            sriov_sc_video_codecs_decode_array_vcn0,
+                                                            ARRAY_SIZE(sriov_sc_video_codecs_decode_array_vcn0));
                }
        }
 
index 7cd17dda32ceb3026425c8db3e293f19b7613ec5..2eddd7f6cd41e02564ea079a0a9d08b67d697cd8 100644 (file)
@@ -439,8 +439,9 @@ static int soc15_read_register(struct amdgpu_device *adev, u32 se_num,
        *value = 0;
        for (i = 0; i < ARRAY_SIZE(soc15_allowed_read_registers); i++) {
                en = &soc15_allowed_read_registers[i];
-               if (adev->reg_offset[en->hwip][en->inst] &&
-                       reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg]
+               if (!adev->reg_offset[en->hwip][en->inst])
+                       continue;
+               else if (reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg]
                                        + en->reg_offset))
                        continue;
 
index 620f7409825dfe24d69f85d427f8c579c7bd1aad..c82b3a7ea5f0840c2f894ac6fc77b2c92f488840 100644 (file)
@@ -102,6 +102,59 @@ static const struct amdgpu_video_codecs vcn_4_0_0_video_codecs_decode_vcn1 =
        .codec_array = vcn_4_0_0_video_codecs_decode_array_vcn1,
 };
 
+/* SRIOV SOC21, not const since data is controlled by host */
+static struct amdgpu_video_codec_info sriov_vcn_4_0_0_video_codecs_encode_array_vcn0[] = {
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
+};
+
+static struct amdgpu_video_codec_info sriov_vcn_4_0_0_video_codecs_encode_array_vcn1[] = {
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
+};
+
+static struct amdgpu_video_codecs sriov_vcn_4_0_0_video_codecs_encode_vcn0 = {
+       .codec_count = ARRAY_SIZE(sriov_vcn_4_0_0_video_codecs_encode_array_vcn0),
+       .codec_array = sriov_vcn_4_0_0_video_codecs_encode_array_vcn0,
+};
+
+static struct amdgpu_video_codecs sriov_vcn_4_0_0_video_codecs_encode_vcn1 = {
+       .codec_count = ARRAY_SIZE(sriov_vcn_4_0_0_video_codecs_encode_array_vcn1),
+       .codec_array = sriov_vcn_4_0_0_video_codecs_encode_array_vcn1,
+};
+
+static struct amdgpu_video_codec_info sriov_vcn_4_0_0_video_codecs_decode_array_vcn0[] = {
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
+};
+
+static struct amdgpu_video_codec_info sriov_vcn_4_0_0_video_codecs_decode_array_vcn1[] = {
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+       {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
+};
+
+static struct amdgpu_video_codecs sriov_vcn_4_0_0_video_codecs_decode_vcn0 = {
+       .codec_count = ARRAY_SIZE(sriov_vcn_4_0_0_video_codecs_decode_array_vcn0),
+       .codec_array = sriov_vcn_4_0_0_video_codecs_decode_array_vcn0,
+};
+
+static struct amdgpu_video_codecs sriov_vcn_4_0_0_video_codecs_decode_vcn1 = {
+       .codec_count = ARRAY_SIZE(sriov_vcn_4_0_0_video_codecs_decode_array_vcn1),
+       .codec_array = sriov_vcn_4_0_0_video_codecs_decode_array_vcn1,
+};
+
 static int soc21_query_video_codecs(struct amdgpu_device *adev, bool encode,
                                 const struct amdgpu_video_codecs **codecs)
 {
@@ -111,16 +164,32 @@ static int soc21_query_video_codecs(struct amdgpu_device *adev, bool encode,
        switch (adev->ip_versions[UVD_HWIP][0]) {
        case IP_VERSION(4, 0, 0):
        case IP_VERSION(4, 0, 2):
-               if (adev->vcn.harvest_config & AMDGPU_VCN_HARVEST_VCN0) {
-                       if (encode)
-                               *codecs = &vcn_4_0_0_video_codecs_encode_vcn1;
-                       else
-                               *codecs = &vcn_4_0_0_video_codecs_decode_vcn1;
+       case IP_VERSION(4, 0, 4):
+               if (amdgpu_sriov_vf(adev)) {
+                       if ((adev->vcn.harvest_config & AMDGPU_VCN_HARVEST_VCN0) ||
+                       !amdgpu_sriov_is_av1_support(adev)) {
+                               if (encode)
+                                       *codecs = &sriov_vcn_4_0_0_video_codecs_encode_vcn1;
+                               else
+                                       *codecs = &sriov_vcn_4_0_0_video_codecs_decode_vcn1;
+                       } else {
+                               if (encode)
+                                       *codecs = &sriov_vcn_4_0_0_video_codecs_encode_vcn0;
+                               else
+                                       *codecs = &sriov_vcn_4_0_0_video_codecs_decode_vcn0;
+                       }
                } else {
-                       if (encode)
-                               *codecs = &vcn_4_0_0_video_codecs_encode_vcn0;
-                       else
-                               *codecs = &vcn_4_0_0_video_codecs_decode_vcn0;
+                       if ((adev->vcn.harvest_config & AMDGPU_VCN_HARVEST_VCN0)) {
+                               if (encode)
+                                       *codecs = &vcn_4_0_0_video_codecs_encode_vcn1;
+                               else
+                                       *codecs = &vcn_4_0_0_video_codecs_decode_vcn1;
+                       } else {
+                               if (encode)
+                                       *codecs = &vcn_4_0_0_video_codecs_encode_vcn0;
+                               else
+                                       *codecs = &vcn_4_0_0_video_codecs_decode_vcn0;
+                       }
                }
                return 0;
        default:
@@ -291,9 +360,10 @@ static int soc21_read_register(struct amdgpu_device *adev, u32 se_num,
        *value = 0;
        for (i = 0; i < ARRAY_SIZE(soc21_allowed_read_registers); i++) {
                en = &soc21_allowed_read_registers[i];
-               if (adev->reg_offset[en->hwip][en->inst] &&
-                   reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg]
-                                  + en->reg_offset))
+               if (!adev->reg_offset[en->hwip][en->inst])
+                       continue;
+               else if (reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg]
+                                       + en->reg_offset))
                        continue;
 
                *value = soc21_get_register_value(adev,
@@ -728,8 +798,23 @@ static int soc21_common_late_init(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       if (amdgpu_sriov_vf(adev))
+       if (amdgpu_sriov_vf(adev)) {
                xgpu_nv_mailbox_get_irq(adev);
+               if ((adev->vcn.harvest_config & AMDGPU_VCN_HARVEST_VCN0) ||
+               !amdgpu_sriov_is_av1_support(adev)) {
+                       amdgpu_virt_update_sriov_video_codec(adev,
+                                                            sriov_vcn_4_0_0_video_codecs_encode_array_vcn1,
+                                                            ARRAY_SIZE(sriov_vcn_4_0_0_video_codecs_encode_array_vcn1),
+                                                            sriov_vcn_4_0_0_video_codecs_decode_array_vcn1,
+                                                            ARRAY_SIZE(sriov_vcn_4_0_0_video_codecs_decode_array_vcn1));
+               } else {
+                       amdgpu_virt_update_sriov_video_codec(adev,
+                                                            sriov_vcn_4_0_0_video_codecs_encode_array_vcn0,
+                                                            ARRAY_SIZE(sriov_vcn_4_0_0_video_codecs_encode_array_vcn0),
+                                                            sriov_vcn_4_0_0_video_codecs_decode_array_vcn0,
+                                                            ARRAY_SIZE(sriov_vcn_4_0_0_video_codecs_decode_array_vcn0));
+               }
+       }
 
        return 0;
 }
index 25eaf4af5fcf4b510f253d8ef7dcb725baa3b67f..c6dfd433fec7bc4f85338f8bffbb19f6b5fd4e82 100644 (file)
@@ -31,9 +31,9 @@
 /* number of umc instance with memory map register access */
 #define UMC_V8_10_UMC_INSTANCE_NUM             2
 
-/* Total channel instances for all umc nodes */
+/* Total channel instances for all available umc nodes */
 #define UMC_V8_10_TOTAL_CHANNEL_NUM(adev) \
-       (UMC_V8_10_CHANNEL_INSTANCE_NUM * UMC_V8_10_UMC_INSTANCE_NUM * (adev)->umc.node_inst_num)
+       (UMC_V8_10_CHANNEL_INSTANCE_NUM * UMC_V8_10_UMC_INSTANCE_NUM * (adev)->gmc.num_umc)
 
 /* UMC regiser per channel offset */
 #define UMC_V8_10_PER_CHANNEL_OFFSET   0x400
index 12ef782eb4785d38d830de14e2d70b58d749a80b..ceab8783575ca701d0df16d6413f8a9b770d5f9a 100644 (file)
 #include "mxgpu_vi.h"
 #include "amdgpu_dm.h"
 
-#if IS_ENABLED(CONFIG_X86)
-#include <asm/intel-family.h>
-#endif
-
 #define ixPCIE_LC_L1_PM_SUBSTATE       0x100100C6
 #define PCIE_LC_L1_PM_SUBSTATE__LC_L1_SUBSTATES_OVERRIDE_EN_MASK       0x00000001L
 #define PCIE_LC_L1_PM_SUBSTATE__LC_PCI_PM_L1_2_OVERRIDE_MASK   0x00000002L
@@ -1138,24 +1134,13 @@ static void vi_enable_aspm(struct amdgpu_device *adev)
                WREG32_PCIE(ixPCIE_LC_CNTL, data);
 }
 
-static bool aspm_support_quirk_check(void)
-{
-#if IS_ENABLED(CONFIG_X86)
-       struct cpuinfo_x86 *c = &cpu_data(0);
-
-       return !(c->x86 == 6 && c->x86_model == INTEL_FAM6_ALDERLAKE);
-#else
-       return true;
-#endif
-}
-
 static void vi_program_aspm(struct amdgpu_device *adev)
 {
        u32 data, data1, orig;
        bool bL1SS = false;
        bool bClkReqSupport = true;
 
-       if (!amdgpu_device_should_use_aspm(adev) || !aspm_support_quirk_check())
+       if (!amdgpu_device_should_use_aspm(adev) || !amdgpu_device_aspm_support_quirk())
                return;
 
        if (adev->flags & AMD_IS_APU ||
index a0e30f21e12e70a763b0a773895b20daee59b13a..de310ed367ca1dda7c41a437476cf1b70a345677 100644 (file)
@@ -1312,14 +1312,14 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
                args->n_success = i+1;
        }
 
-       mutex_unlock(&p->mutex);
-
        err = amdgpu_amdkfd_gpuvm_sync_memory(dev->adev, (struct kgd_mem *) mem, true);
        if (err) {
                pr_debug("Sync memory failed, wait interrupted by user signal\n");
                goto sync_memory_failed;
        }
 
+       mutex_unlock(&p->mutex);
+
        /* Flush TLBs after waiting for the page table updates to complete */
        for (i = 0; i < args->n_devices; i++) {
                peer_pdd = kfd_process_device_data_by_id(p, devices_arr[i]);
@@ -1335,9 +1335,9 @@ get_process_device_data_failed:
 bind_process_to_device_failed:
 get_mem_obj_from_handle_failed:
 map_memory_to_gpu_failed:
+sync_memory_failed:
        mutex_unlock(&p->mutex);
 copy_from_user_failed:
-sync_memory_failed:
        kfree(devices_arr);
 
        return err;
@@ -1351,6 +1351,7 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
        void *mem;
        long err = 0;
        uint32_t *devices_arr = NULL, i;
+       bool flush_tlb;
 
        if (!args->n_devices) {
                pr_debug("Device IDs array empty\n");
@@ -1403,16 +1404,19 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
                }
                args->n_success = i+1;
        }
-       mutex_unlock(&p->mutex);
 
-       if (kfd_flush_tlb_after_unmap(pdd->dev)) {
+       flush_tlb = kfd_flush_tlb_after_unmap(pdd->dev);
+       if (flush_tlb) {
                err = amdgpu_amdkfd_gpuvm_sync_memory(pdd->dev->adev,
                                (struct kgd_mem *) mem, true);
                if (err) {
                        pr_debug("Sync memory failed, wait interrupted by user signal\n");
                        goto sync_memory_failed;
                }
+       }
+       mutex_unlock(&p->mutex);
 
+       if (flush_tlb) {
                /* Flush TLBs after waiting for the page table updates to complete */
                for (i = 0; i < args->n_devices; i++) {
                        peer_pdd = kfd_process_device_data_by_id(p, devices_arr[i]);
@@ -1428,9 +1432,9 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
 bind_process_to_device_failed:
 get_mem_obj_from_handle_failed:
 unmap_memory_from_gpu_failed:
+sync_memory_failed:
        mutex_unlock(&p->mutex);
 copy_from_user_failed:
-sync_memory_failed:
        kfree(devices_arr);
        return err;
 }
index 3de7f616a001cf6a8be622f87db2bb286c7e1c3d..ec70a1658dc3871c1dd960af26586a76dbb847a8 100644 (file)
@@ -59,6 +59,7 @@ static int kfd_gtt_sa_init(struct kfd_dev *kfd, unsigned int buf_size,
                                unsigned int chunk_size);
 static void kfd_gtt_sa_fini(struct kfd_dev *kfd);
 
+static int kfd_resume_iommu(struct kfd_dev *kfd);
 static int kfd_resume(struct kfd_dev *kfd);
 
 static void kfd_device_info_set_sdma_info(struct kfd_dev *kfd)
@@ -624,7 +625,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
 
        svm_migrate_init(kfd->adev);
 
-       if (kgd2kfd_resume_iommu(kfd))
+       if (kfd_resume_iommu(kfd))
                goto device_iommu_error;
 
        if (kfd_resume(kfd))
@@ -772,6 +773,14 @@ int kgd2kfd_resume(struct kfd_dev *kfd, bool run_pm)
 }
 
 int kgd2kfd_resume_iommu(struct kfd_dev *kfd)
+{
+       if (!kfd->init_complete)
+               return 0;
+
+       return kfd_resume_iommu(kfd);
+}
+
+static int kfd_resume_iommu(struct kfd_dev *kfd)
 {
        int err = 0;
 
index cbef2e147da5898df3b85de6b567f88fc96c892a..38c9e1ca66913006ed8b62b3e215f9828dd212c5 100644 (file)
@@ -280,7 +280,7 @@ phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd)
        if (!pdd->doorbell_index) {
                int r = kfd_alloc_process_doorbells(pdd->dev,
                                                    &pdd->doorbell_index);
-               if (r)
+               if (r < 0)
                        return 0;
        }
 
index de8ce72344fc57f14d3198256f458cfe8891797e..54933903bcb8a3a2547dc31d8354c7b1a31b3850 100644 (file)
@@ -289,7 +289,7 @@ static unsigned long svm_migrate_unsuccessful_pages(struct migrate_vma *migrate)
 static int
 svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
                         struct migrate_vma *migrate, struct dma_fence **mfence,
-                        dma_addr_t *scratch)
+                        dma_addr_t *scratch, uint64_t ttm_res_offset)
 {
        uint64_t npages = migrate->npages;
        struct device *dev = adev->dev;
@@ -299,19 +299,13 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
        uint64_t i, j;
        int r;
 
-       pr_debug("svms 0x%p [0x%lx 0x%lx]\n", prange->svms, prange->start,
-                prange->last);
+       pr_debug("svms 0x%p [0x%lx 0x%lx 0x%llx]\n", prange->svms, prange->start,
+                prange->last, ttm_res_offset);
 
        src = scratch;
        dst = (uint64_t *)(scratch + npages);
 
-       r = svm_range_vram_node_new(adev, prange, true);
-       if (r) {
-               dev_dbg(adev->dev, "fail %d to alloc vram\n", r);
-               goto out;
-       }
-
-       amdgpu_res_first(prange->ttm_res, prange->offset << PAGE_SHIFT,
+       amdgpu_res_first(prange->ttm_res, ttm_res_offset,
                         npages << PAGE_SHIFT, &cursor);
        for (i = j = 0; i < npages; i++) {
                struct page *spage;
@@ -391,14 +385,14 @@ out_free_vram_pages:
                migrate->dst[i + 3] = 0;
        }
 #endif
-out:
+
        return r;
 }
 
 static long
 svm_migrate_vma_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
                        struct vm_area_struct *vma, uint64_t start,
-                       uint64_t end, uint32_t trigger)
+                       uint64_t end, uint32_t trigger, uint64_t ttm_res_offset)
 {
        struct kfd_process *p = container_of(prange->svms, struct kfd_process, svms);
        uint64_t npages = (end - start) >> PAGE_SHIFT;
@@ -451,7 +445,7 @@ svm_migrate_vma_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
        else
                pr_debug("0x%lx pages migrated\n", cpages);
 
-       r = svm_migrate_copy_to_vram(adev, prange, &migrate, &mfence, scratch);
+       r = svm_migrate_copy_to_vram(adev, prange, &migrate, &mfence, scratch, ttm_res_offset);
        migrate_vma_pages(&migrate);
 
        pr_debug("successful/cpages/npages 0x%lx/0x%lx/0x%lx\n",
@@ -499,6 +493,7 @@ svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc,
        unsigned long addr, start, end;
        struct vm_area_struct *vma;
        struct amdgpu_device *adev;
+       uint64_t ttm_res_offset;
        unsigned long cpages = 0;
        long r = 0;
 
@@ -520,6 +515,13 @@ svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc,
        start = prange->start << PAGE_SHIFT;
        end = (prange->last + 1) << PAGE_SHIFT;
 
+       r = svm_range_vram_node_new(adev, prange, true);
+       if (r) {
+               dev_dbg(adev->dev, "fail %ld to alloc vram\n", r);
+               return r;
+       }
+       ttm_res_offset = prange->offset << PAGE_SHIFT;
+
        for (addr = start; addr < end;) {
                unsigned long next;
 
@@ -528,18 +530,21 @@ svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc,
                        break;
 
                next = min(vma->vm_end, end);
-               r = svm_migrate_vma_to_vram(adev, prange, vma, addr, next, trigger);
+               r = svm_migrate_vma_to_vram(adev, prange, vma, addr, next, trigger, ttm_res_offset);
                if (r < 0) {
                        pr_debug("failed %ld to migrate\n", r);
                        break;
                } else {
                        cpages += r;
                }
+               ttm_res_offset += next - addr;
                addr = next;
        }
 
        if (cpages)
                prange->actual_loc = best_loc;
+       else
+               svm_range_vram_node_free(prange);
 
        return r < 0 ? r : 0;
 }
index 09b966dc376818c08e53020dbea1b0f695f68043..aee2212e52f69aea69b6cd06e476c391713a8a1c 100644 (file)
@@ -77,6 +77,7 @@ err_ioctl:
 
 static void kfd_exit(void)
 {
+       kfd_cleanup_processes();
        kfd_debugfs_fini();
        kfd_process_destroy_wq();
        kfd_procfs_shutdown();
index bfa30d12406b35c7c174a6baa550678e4a31c943..7e4d992e48b3c99495763fbf36508b46fb1e7f78 100644 (file)
@@ -928,6 +928,7 @@ bool kfd_dev_is_large_bar(struct kfd_dev *dev);
 
 int kfd_process_create_wq(void);
 void kfd_process_destroy_wq(void);
+void kfd_cleanup_processes(void);
 struct kfd_process *kfd_create_process(struct file *filep);
 struct kfd_process *kfd_get_process(const struct task_struct *task);
 struct kfd_process *kfd_lookup_process_by_pasid(u32 pasid);
index 7acd55a814b2f32999ba4aa9b68db91da30ccfc7..4208e0f01064dd492e7aa85e28c99622bbee90b4 100644 (file)
@@ -1167,6 +1167,17 @@ static void kfd_process_free_notifier(struct mmu_notifier *mn)
        kfd_unref_process(container_of(mn, struct kfd_process, mmu_notifier));
 }
 
+static void kfd_process_notifier_release_internal(struct kfd_process *p)
+{
+       cancel_delayed_work_sync(&p->eviction_work);
+       cancel_delayed_work_sync(&p->restore_work);
+
+       /* Indicate to other users that MM is no longer valid */
+       p->mm = NULL;
+
+       mmu_notifier_put(&p->mmu_notifier);
+}
+
 static void kfd_process_notifier_release(struct mmu_notifier *mn,
                                        struct mm_struct *mm)
 {
@@ -1181,17 +1192,22 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn,
                return;
 
        mutex_lock(&kfd_processes_mutex);
+       /*
+        * Do early return if table is empty.
+        *
+        * This could potentially happen if this function is called concurrently
+        * by mmu_notifier and by kfd_cleanup_pocesses.
+        *
+        */
+       if (hash_empty(kfd_processes_table)) {
+               mutex_unlock(&kfd_processes_mutex);
+               return;
+       }
        hash_del_rcu(&p->kfd_processes);
        mutex_unlock(&kfd_processes_mutex);
        synchronize_srcu(&kfd_processes_srcu);
 
-       cancel_delayed_work_sync(&p->eviction_work);
-       cancel_delayed_work_sync(&p->restore_work);
-
-       /* Indicate to other users that MM is no longer valid */
-       p->mm = NULL;
-
-       mmu_notifier_put(&p->mmu_notifier);
+       kfd_process_notifier_release_internal(p);
 }
 
 static const struct mmu_notifier_ops kfd_process_mmu_notifier_ops = {
@@ -1200,6 +1216,43 @@ static const struct mmu_notifier_ops kfd_process_mmu_notifier_ops = {
        .free_notifier = kfd_process_free_notifier,
 };
 
+/*
+ * This code handles the case when driver is being unloaded before all
+ * mm_struct are released.  We need to safely free the kfd_process and
+ * avoid race conditions with mmu_notifier that might try to free them.
+ *
+ */
+void kfd_cleanup_processes(void)
+{
+       struct kfd_process *p;
+       struct hlist_node *p_temp;
+       unsigned int temp;
+       HLIST_HEAD(cleanup_list);
+
+       /*
+        * Move all remaining kfd_process from the process table to a
+        * temp list for processing.   Once done, callback from mmu_notifier
+        * release will not see the kfd_process in the table and do early return,
+        * avoiding double free issues.
+        */
+       mutex_lock(&kfd_processes_mutex);
+       hash_for_each_safe(kfd_processes_table, temp, p_temp, p, kfd_processes) {
+               hash_del_rcu(&p->kfd_processes);
+               synchronize_srcu(&kfd_processes_srcu);
+               hlist_add_head(&p->kfd_processes, &cleanup_list);
+       }
+       mutex_unlock(&kfd_processes_mutex);
+
+       hlist_for_each_entry_safe(p, p_temp, &cleanup_list, kfd_processes)
+               kfd_process_notifier_release_internal(p);
+
+       /*
+        * Ensures that all outstanding free_notifier get called, triggering
+        * the release of the kfd_process struct.
+        */
+       mmu_notifier_synchronize();
+}
+
 static int kfd_process_init_cwsr_apu(struct kfd_process *p, struct file *filep)
 {
        unsigned long  offset;
index 5137476ec18e67d521d0ef590eb6cd8f4de94fd1..4236539d9f932e34c62357767972c53c9498f92a 100644 (file)
@@ -218,8 +218,8 @@ static int init_user_queue(struct process_queue_manager *pqm,
        return 0;
 
 cleanup:
-       if (dev->shared_resources.enable_mes)
-               uninit_queue(*q);
+       uninit_queue(*q);
+       *q = NULL;
        return retval;
 }
 
index 009ef917dad47b3eb1df6c10d82663f7ccac35a6..a01fd41643fc2abd4cc2a058c82498503790e0fe 100644 (file)
@@ -5105,9 +5105,9 @@ static void fill_dc_dirty_rects(struct drm_plane *plane,
 
                for (; flip_addrs->dirty_rect_count < num_clips; clips++)
                        fill_dc_dirty_rect(new_plane_state->plane,
-                                          &dirty_rects[i], clips->x1,
-                                          clips->y1, clips->x2 - clips->x1,
-                                          clips->y2 - clips->y1,
+                                          &dirty_rects[flip_addrs->dirty_rect_count],
+                                          clips->x1, clips->y1,
+                                          clips->x2 - clips->x1, clips->y2 - clips->y1,
                                           &flip_addrs->dirty_rect_count,
                                           false);
                return;
@@ -7244,7 +7244,6 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
        if (!aconnector->mst_root)
                drm_connector_attach_max_bpc_property(&aconnector->base, 8, 16);
 
-       /* This defaults to the max in the range, but we want 8bpc for non-edp. */
        aconnector->base.state->max_bpc = 16;
        aconnector->base.state->max_requested_bpc = aconnector->base.state->max_bpc;
 
index dc4f37240beb4c3a61bfd77386ac548c14be0ebe..8af70feca7205107f03aa1215de09152830210e5 100644 (file)
@@ -169,10 +169,21 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable)
        if (rc)
                return rc;
 
-       irq_source = IRQ_TYPE_VBLANK + acrtc->otg_inst;
+       if (amdgpu_in_reset(adev)) {
+               irq_source = IRQ_TYPE_VBLANK + acrtc->otg_inst;
+               /* During gpu-reset we disable and then enable vblank irq, so
+                * don't use amdgpu_irq_get/put() to avoid refcount change.
+                */
+               if (!dc_interrupt_set(adev->dm.dc, irq_source, enable))
+                       rc = -EBUSY;
+       } else {
+               rc = (enable)
+                       ? amdgpu_irq_get(adev, &adev->crtc_irq, acrtc->crtc_id)
+                       : amdgpu_irq_put(adev, &adev->crtc_irq, acrtc->crtc_id);
+       }
 
-       if (!dc_interrupt_set(adev->dm.dc, irq_source, enable))
-               return -EBUSY;
+       if (rc)
+               return rc;
 
 skip:
        if (amdgpu_in_reset(adev))
index 8e572f07ec476030258036f6538aba733cd1f1d4..4abfd2c9679f456c15c1cb2cb2e9158eb811ba34 100644 (file)
@@ -561,7 +561,7 @@ static void update_config(void *handle, struct cp_psp_stream_config *config)
        link->dp.mst_enabled = config->mst_enabled;
        link->dp.usb4_enabled = config->usb4_enabled;
        display->adjust.disable = MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION;
-       link->adjust.auth_delay = 0;
+       link->adjust.auth_delay = 2;
        link->adjust.hdcp1.disable = 0;
        conn_state = aconnector->base.state;
 
index 1583157da355b2c7c500ee4b9fb51e7298cd4e71..efd025d8961e682812de5b748e61795e45b7f1cb 100644 (file)
@@ -177,6 +177,40 @@ void dm_helpers_dp_update_branch_info(
        const struct dc_link *link)
 {}
 
+static void dm_helpers_construct_old_payload(
+                       struct dc_link *link,
+                       int pbn_per_slot,
+                       struct drm_dp_mst_atomic_payload *new_payload,
+                       struct drm_dp_mst_atomic_payload *old_payload)
+{
+       struct link_mst_stream_allocation_table current_link_table =
+                                                                       link->mst_stream_alloc_table;
+       struct link_mst_stream_allocation *dc_alloc;
+       int i;
+
+       *old_payload = *new_payload;
+
+       /* Set correct time_slots/PBN of old payload.
+        * other fields (delete & dsc_enabled) in
+        * struct drm_dp_mst_atomic_payload are don't care fields
+        * while calling drm_dp_remove_payload()
+        */
+       for (i = 0; i < current_link_table.stream_count; i++) {
+               dc_alloc =
+                       &current_link_table.stream_allocations[i];
+
+               if (dc_alloc->vcp_id == new_payload->vcpi) {
+                       old_payload->time_slots = dc_alloc->slot_count;
+                       old_payload->pbn = dc_alloc->slot_count * pbn_per_slot;
+                       break;
+               }
+       }
+
+       /* make sure there is an old payload*/
+       ASSERT(i != current_link_table.stream_count);
+
+}
+
 /*
  * Writes payload allocation table in immediate downstream device.
  */
@@ -188,7 +222,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 {
        struct amdgpu_dm_connector *aconnector;
        struct drm_dp_mst_topology_state *mst_state;
-       struct drm_dp_mst_atomic_payload *payload;
+       struct drm_dp_mst_atomic_payload *target_payload, *new_payload, old_payload;
        struct drm_dp_mst_topology_mgr *mst_mgr;
 
        aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
@@ -204,17 +238,26 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
        mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
 
        /* It's OK for this to fail */
-       payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
-       if (enable)
-               drm_dp_add_payload_part1(mst_mgr, mst_state, payload);
-       else
-               drm_dp_remove_payload(mst_mgr, mst_state, payload, payload);
+       new_payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
+
+       if (enable) {
+               target_payload = new_payload;
+
+               drm_dp_add_payload_part1(mst_mgr, mst_state, new_payload);
+       } else {
+               /* construct old payload by VCPI*/
+               dm_helpers_construct_old_payload(stream->link, mst_state->pbn_div,
+                                               new_payload, &old_payload);
+               target_payload = &old_payload;
+
+               drm_dp_remove_payload(mst_mgr, mst_state, &old_payload, new_payload);
+       }
 
        /* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
         * AUX message. The sequence is slot 1-63 allocated sequence for each
         * stream. AMD ASIC stream slot allocation should follow the same
         * sequence. copy DRM MST allocation to dc */
-       fill_dc_mst_payload_table_from_drm(stream->link, enable, payload, proposed_table);
+       fill_dc_mst_payload_table_from_drm(stream->link, enable, target_payload, proposed_table);
 
        return true;
 }
index e25e1b2bf19493b747a623269bb6b967936592d7..8dc442f90eafa14241eb97e29455306200ea298f 100644 (file)
@@ -212,6 +212,21 @@ bool needs_dsc_aux_workaround(struct dc_link *link)
        return false;
 }
 
+bool is_synaptics_cascaded_panamera(struct dc_link *link, struct drm_dp_mst_port *port)
+{
+       u8 branch_vendor_data[4] = { 0 }; // Vendor data 0x50C ~ 0x50F
+
+       if (drm_dp_dpcd_read(port->mgr->aux, DP_BRANCH_VENDOR_SPECIFIC_START, &branch_vendor_data, 4) == 4) {
+               if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
+                               IS_SYNAPTICS_CASCADED_PANAMERA(link->dpcd_caps.branch_dev_name, branch_vendor_data)) {
+                       DRM_INFO("Synaptics Cascaded MST hub\n");
+                       return true;
+               }
+       }
+
+       return false;
+}
+
 static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnector)
 {
        struct dc_sink *dc_sink = aconnector->dc_sink;
@@ -235,6 +250,10 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto
            needs_dsc_aux_workaround(aconnector->dc_link))
                aconnector->dsc_aux = &aconnector->mst_root->dm_dp_aux.aux;
 
+       /* synaptics cascaded MST hub case */
+       if (!aconnector->dsc_aux && is_synaptics_cascaded_panamera(aconnector->dc_link, port))
+               aconnector->dsc_aux = port->mgr->aux;
+
        if (!aconnector->dsc_aux)
                return false;
 
@@ -662,12 +681,25 @@ struct dsc_mst_fairness_params {
        struct amdgpu_dm_connector *aconnector;
 };
 
-static int kbps_to_peak_pbn(int kbps)
+static uint16_t get_fec_overhead_multiplier(struct dc_link *dc_link)
+{
+       u8 link_coding_cap;
+       uint16_t fec_overhead_multiplier_x1000 = PBN_FEC_OVERHEAD_MULTIPLIER_8B_10B;
+
+       link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(dc_link);
+       if (link_coding_cap == DP_128b_132b_ENCODING)
+               fec_overhead_multiplier_x1000 = PBN_FEC_OVERHEAD_MULTIPLIER_128B_132B;
+
+       return fec_overhead_multiplier_x1000;
+}
+
+static int kbps_to_peak_pbn(int kbps, uint16_t fec_overhead_multiplier_x1000)
 {
        u64 peak_kbps = kbps;
 
        peak_kbps *= 1006;
-       peak_kbps = div_u64(peak_kbps, 1000);
+       peak_kbps *= fec_overhead_multiplier_x1000;
+       peak_kbps = div_u64(peak_kbps, 1000 * 1000);
        return (int) DIV64_U64_ROUND_UP(peak_kbps * 64, (54 * 8 * 1000));
 }
 
@@ -761,11 +793,12 @@ static int increase_dsc_bpp(struct drm_atomic_state *state,
        int link_timeslots_used;
        int fair_pbn_alloc;
        int ret = 0;
+       uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link);
 
        for (i = 0; i < count; i++) {
                if (vars[i + k].dsc_enabled) {
                        initial_slack[i] =
-                       kbps_to_peak_pbn(params[i].bw_range.max_kbps) - vars[i + k].pbn;
+                       kbps_to_peak_pbn(params[i].bw_range.max_kbps, fec_overhead_multiplier_x1000) - vars[i + k].pbn;
                        bpp_increased[i] = false;
                        remaining_to_increase += 1;
                } else {
@@ -861,6 +894,7 @@ static int try_disable_dsc(struct drm_atomic_state *state,
        int next_index;
        int remaining_to_try = 0;
        int ret;
+       uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link);
 
        for (i = 0; i < count; i++) {
                if (vars[i + k].dsc_enabled
@@ -890,7 +924,7 @@ static int try_disable_dsc(struct drm_atomic_state *state,
                if (next_index == -1)
                        break;
 
-               vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps);
+               vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
                ret = drm_dp_atomic_find_time_slots(state,
                                                    params[next_index].port->mgr,
                                                    params[next_index].port,
@@ -903,7 +937,7 @@ static int try_disable_dsc(struct drm_atomic_state *state,
                        vars[next_index].dsc_enabled = false;
                        vars[next_index].bpp_x16 = 0;
                } else {
-                       vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps);
+                       vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps, fec_overhead_multiplier_x1000);
                        ret = drm_dp_atomic_find_time_slots(state,
                                                            params[next_index].port->mgr,
                                                            params[next_index].port,
@@ -932,6 +966,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
        int count = 0;
        int i, k, ret;
        bool debugfs_overwrite = false;
+       uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link);
 
        memset(params, 0, sizeof(params));
 
@@ -993,7 +1028,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
        /* Try no compression */
        for (i = 0; i < count; i++) {
                vars[i + k].aconnector = params[i].aconnector;
-               vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps);
+               vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
                vars[i + k].dsc_enabled = false;
                vars[i + k].bpp_x16 = 0;
                ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr, params[i].port,
@@ -1012,7 +1047,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
        /* Try max compression */
        for (i = 0; i < count; i++) {
                if (params[i].compression_possible && params[i].clock_force_enable != DSC_CLK_FORCE_DISABLE) {
-                       vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps);
+                       vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps, fec_overhead_multiplier_x1000);
                        vars[i + k].dsc_enabled = true;
                        vars[i + k].bpp_x16 = params[i].bw_range.min_target_bpp_x16;
                        ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr,
@@ -1020,7 +1055,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
                        if (ret < 0)
                                return ret;
                } else {
-                       vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps);
+                       vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
                        vars[i + k].dsc_enabled = false;
                        vars[i + k].bpp_x16 = 0;
                        ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr,
index 97fd70df531bf1c4804b23d35301805ae472c8a1..1e4ede1e57abd3f83399f5cb16e2fa42818e9779 100644 (file)
 #define SYNAPTICS_RC_OFFSET        0x4BC
 #define SYNAPTICS_RC_DATA          0x4C0
 
+#define DP_BRANCH_VENDOR_SPECIFIC_START 0x50C
+
+/**
+ * Panamera MST Hub detection
+ * Offset DPCD 050Eh == 0x5A indicates cascaded MST hub case
+ * Check from beginning of branch device vendor specific field (050Ch)
+ */
+#define IS_SYNAPTICS_PANAMERA(branchDevName) (((int)branchDevName[4] & 0xF0) == 0x50 ? 1 : 0)
+#define BRANCH_HW_REVISION_PANAMERA_A2 0x10
+#define SYNAPTICS_CASCADED_HUB_ID  0x5A
+#define IS_SYNAPTICS_CASCADED_PANAMERA(devName, data) ((IS_SYNAPTICS_PANAMERA(devName) && ((int)data[2] == SYNAPTICS_CASCADED_HUB_ID)) ? 1 : 0)
+
+#define PBN_FEC_OVERHEAD_MULTIPLIER_8B_10B     1031
+#define PBN_FEC_OVERHEAD_MULTIPLIER_128B_132B  1000
+
 struct amdgpu_display_manager;
 struct amdgpu_dm_connector;
 
index 24715ca2fa9441a26050399e2ff3941fda47ec59..01383aac6b4190f84e12765e6782c209b8309ed3 100644 (file)
@@ -529,6 +529,19 @@ static struct clk_bw_params vg_bw_params = {
 
 };
 
+static uint32_t find_max_clk_value(const uint32_t clocks[], uint32_t num_clocks)
+{
+       uint32_t max = 0;
+       int i;
+
+       for (i = 0; i < num_clocks; ++i) {
+               if (clocks[i] > max)
+                       max = clocks[i];
+       }
+
+       return max;
+}
+
 static unsigned int find_dcfclk_for_voltage(const struct vg_dpm_clocks *clock_table,
                unsigned int voltage)
 {
@@ -572,12 +585,16 @@ static void vg_clk_mgr_helper_populate_bw_params(
 
        bw_params->clk_table.num_entries = j + 1;
 
-       for (i = 0; i < bw_params->clk_table.num_entries; i++, j--) {
+       for (i = 0; i < bw_params->clk_table.num_entries - 1; i++, j--) {
                bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[j].fclk;
                bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].memclk;
                bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].voltage;
                bw_params->clk_table.entries[i].dcfclk_mhz = find_dcfclk_for_voltage(clock_table, clock_table->DfPstateTable[j].voltage);
        }
+       bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[j].fclk;
+       bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].memclk;
+       bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].voltage;
+       bw_params->clk_table.entries[i].dcfclk_mhz = find_max_clk_value(clock_table->DcfClocks, VG_NUM_DCFCLK_DPM_LEVELS);
 
        bw_params->vram_type = bios_info->memory_type;
        bw_params->num_channels = bios_info->ma_channel_number;
index 3b4d4d68359bb8f8165ea6b126a3fa6969a6246e..df787fcf8e86e06e17646d09f26cdb938d51a318 100644 (file)
@@ -998,8 +998,5 @@ void dcn30_prepare_bandwidth(struct dc *dc,
                        dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz);
 
        dcn20_prepare_bandwidth(dc, context);
-
-       dc_dmub_srv_p_state_delegate(dc,
-               context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching, context);
 }
 
index 54ed3de869d3b001d98d8f8c0ab972fe7d819065..9ffba4c6fe550f3676e587896a8dc2df4f9c971a 100644 (file)
@@ -1697,6 +1697,23 @@ static void dcn314_get_panel_config_defaults(struct dc_panel_config *panel_confi
        *panel_config = panel_config_defaults;
 }
 
+static bool filter_modes_for_single_channel_workaround(struct dc *dc,
+               struct dc_state *context)
+{
+       // Filter 2K@240Hz+8K@24fps above combination timing if memory only has single dimm LPDDR
+       if (dc->clk_mgr->bw_params->vram_type == 34 && dc->clk_mgr->bw_params->num_channels < 2) {
+               int total_phy_pix_clk = 0;
+
+               for (int i = 0; i < context->stream_count; i++)
+                       if (context->res_ctx.pipe_ctx[i].stream)
+                               total_phy_pix_clk += context->res_ctx.pipe_ctx[i].stream->phy_pix_clk;
+
+               if (total_phy_pix_clk >= (1148928+826260)) //2K@240Hz+8K@24fps
+                       return true;
+       }
+       return false;
+}
+
 bool dcn314_validate_bandwidth(struct dc *dc,
                struct dc_state *context,
                bool fast_validate)
@@ -1712,6 +1729,9 @@ bool dcn314_validate_bandwidth(struct dc *dc,
 
        BW_VAL_TRACE_COUNT();
 
+       if (filter_modes_for_single_channel_workaround(dc, context))
+               goto validate_fail;
+
        DC_FP_START();
        // do not support self refresh only
        out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate, false);
index e4472c6be6c3231a29aa161fcf948f627eb1201f..3fb4bcc343531b6271c4dae8a48802c3426726bf 100644 (file)
@@ -271,8 +271,7 @@ static void dccg32_set_dpstreamclk(
        dccg32_set_dtbclk_p_src(dccg, src, otg_inst);
 
        /* enabled to select one of the DTBCLKs for pipe */
-       switch (otg_inst)
-       {
+       switch (dp_hpo_inst) {
        case 0:
                REG_UPDATE_2(DPSTREAMCLK_CNTL,
                             DPSTREAMCLK0_EN,
index 16f892125b6fac12680d681efa99810bd6847f67..9d14045cccd63e1e2e56307b3e273420d494442a 100644 (file)
@@ -1104,7 +1104,7 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign
                        *k2_div = PIXEL_RATE_DIV_BY_2;
                else
                        *k2_div = PIXEL_RATE_DIV_BY_4;
-       } else if (dc_is_dp_signal(stream->signal) || dc_is_virtual_signal(stream->signal)) {
+       } else if (dc_is_dp_signal(stream->signal)) {
                if (two_pix_per_container) {
                        *k1_div = PIXEL_RATE_DIV_BY_1;
                        *k2_div = PIXEL_RATE_DIV_BY_2;
index 74e50c09bb62f9156a8436d4b86025e5b9b5b8a9..4b7abb4af623599072ec0ede6e300ec82b9c30d8 100644 (file)
@@ -1915,6 +1915,7 @@ int dcn32_populate_dml_pipes_from_context(
        bool subvp_in_use = false;
        uint8_t is_pipe_split_expected[MAX_PIPES] = {0};
        struct dc_crtc_timing *timing;
+       bool vsr_odm_support = false;
 
        dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
 
@@ -1932,12 +1933,15 @@ int dcn32_populate_dml_pipes_from_context(
                timing = &pipe->stream->timing;
 
                pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal;
+               vsr_odm_support = (res_ctx->pipe_ctx[i].stream->src.width >= 5120 &&
+                               res_ctx->pipe_ctx[i].stream->src.width > res_ctx->pipe_ctx[i].stream->dst.width);
                if (context->stream_count == 1 &&
                                context->stream_status[0].plane_count == 1 &&
                                !dc_is_hdmi_signal(res_ctx->pipe_ctx[i].stream->signal) &&
                                is_h_timing_divisible_by_2(res_ctx->pipe_ctx[i].stream) &&
                                pipe->stream->timing.pix_clk_100hz * 100 > DCN3_2_VMIN_DISPCLK_HZ &&
-                               dc->debug.enable_single_display_2to1_odm_policy) {
+                               dc->debug.enable_single_display_2to1_odm_policy &&
+                               !vsr_odm_support) { //excluding 2to1 ODM combine on >= 5k vsr
                        pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_2to1;
                }
                pipe_cnt++;
@@ -2182,6 +2186,7 @@ static bool dcn32_resource_construct(
        dc->caps.edp_dsc_support = true;
        dc->caps.extended_aux_timeout_support = true;
        dc->caps.dmcub_support = true;
+       dc->caps.seamless_odm = true;
 
        /* Color pipeline capabilities */
        dc->caps.color.dpp.dcn_arch = 1;
index b37d14369a622ca27151ac5976e78346f87a1030..59836570603ac6e3aef195b9d62aa8eea92f3b50 100644 (file)
@@ -222,7 +222,7 @@ struct _vcs_dpi_ip_params_st dcn3_15_ip = {
        .maximum_dsc_bits_per_component = 10,
        .dsc422_native_support = false,
        .is_line_buffer_bpp_fixed = true,
-       .line_buffer_fixed_bpp = 49,
+       .line_buffer_fixed_bpp = 48,
        .line_buffer_size_bits = 789504,
        .max_line_buffer_lines = 12,
        .writeback_interface_buffer_size_kbytes = 90,
index 38216c789d7771459162272aa25148497e8a6ea8..f70025ef7b69edfcef5a28e45f384a686cb009a5 100644 (file)
@@ -855,6 +855,7 @@ static bool detect_link_and_local_sink(struct dc_link *link,
        struct dc_sink *prev_sink = NULL;
        struct dpcd_caps prev_dpcd_caps;
        enum dc_connection_type new_connection_type = dc_connection_none;
+       enum dc_connection_type pre_connection_type = link->type;
        const uint32_t post_oui_delay = 30; // 30ms
 
        DC_LOGGER_INIT(link->ctx->logger);
@@ -957,6 +958,8 @@ static bool detect_link_and_local_sink(struct dc_link *link,
                        }
 
                        if (!detect_dp(link, &sink_caps, reason)) {
+                               link->type = pre_connection_type;
+
                                if (prev_sink)
                                        dc_sink_release(prev_sink);
                                return false;
@@ -1244,11 +1247,16 @@ bool link_detect(struct dc_link *link, enum dc_detect_reason reason)
        bool is_delegated_to_mst_top_mgr = false;
        enum dc_connection_type pre_link_type = link->type;
 
+       DC_LOGGER_INIT(link->ctx->logger);
+
        is_local_sink_detect_success = detect_link_and_local_sink(link, reason);
 
        if (is_local_sink_detect_success && link->local_sink)
                verify_link_capability(link, link->local_sink, reason);
 
+       DC_LOG_DC("%s: link_index=%d is_local_sink_detect_success=%d pre_link_type=%d link_type=%d\n", __func__,
+                               link->link_index, is_local_sink_detect_success, pre_link_type, link->type);
+
        if (is_local_sink_detect_success && link->local_sink &&
                        dc_is_dp_signal(link->local_sink->sink_signal) &&
                        link->dpcd_caps.is_mst_capable)
index e39b133d05af4e47f17c8993080160726c8ab3f6..b56f07f99d092bc83819ad7014cbb5492f415483 100644 (file)
@@ -934,6 +934,10 @@ bool psr_su_set_dsc_slice_height(struct dc *dc, struct dc_link *link,
 
        pic_height = stream->timing.v_addressable +
                stream->timing.v_border_top + stream->timing.v_border_bottom;
+
+       if (stream->timing.dsc_cfg.num_slices_v == 0)
+               return false;
+
        slice_height = pic_height / stream->timing.dsc_cfg.num_slices_v;
        config->dsc_slice_height = slice_height;
 
index f77401709d83cccad7e34d4fab6e5a70e81c3af8..2162ecd1057d1c40286644ac4774c0bfb30dcbf9 100644 (file)
@@ -27,7 +27,7 @@
 // *** IMPORTANT ***
 // SMU TEAM: Always increment the interface version if
 // any structure is changed in this file
-#define PMFW_DRIVER_IF_VERSION 7
+#define PMFW_DRIVER_IF_VERSION 8
 
 typedef struct {
   int32_t value;
@@ -198,7 +198,7 @@ typedef struct {
   uint16_t SkinTemp;
   uint16_t DeviceState;
   uint16_t CurTemp;                     //[centi-Celsius]
-  uint16_t spare2;
+  uint16_t FilterAlphaValue;
 
   uint16_t AverageGfxclkFrequency;
   uint16_t AverageFclkFrequency;
index 1c0ae2cb757b8d30fc4974119300e558a521c1b1..85a090b9e3d9745da9e520988f289550c4f2b659 100644 (file)
@@ -29,7 +29,7 @@
 #define SMU13_DRIVER_IF_VERSION_YELLOW_CARP 0x04
 #define SMU13_DRIVER_IF_VERSION_ALDE 0x08
 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_0 0x37
-#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x07
+#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x08
 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_5 0x04
 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10 0x32
 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x37
 #define CTF_OFFSET_HOTSPOT             5
 #define CTF_OFFSET_MEM                 5
 
+static const int pmfw_decoded_link_speed[5] = {1, 2, 3, 4, 5};
+static const int pmfw_decoded_link_width[7] = {0, 1, 2, 4, 8, 12, 16};
+
+#define DECODE_GEN_SPEED(gen_speed_idx)                (pmfw_decoded_link_speed[gen_speed_idx])
+#define DECODE_LANE_WIDTH(lane_width_idx)      (pmfw_decoded_link_width[lane_width_idx])
+
 struct smu_13_0_max_sustainable_clocks {
        uint32_t display_clock;
        uint32_t phy_clock;
index 697e98a0a20ab9c5afc74305e2eb5b66e6e34a1e..75f18681e984c33a5c7cf83d7a22aa92b794f3c9 100644 (file)
@@ -2143,16 +2143,9 @@ static int sienna_cichlid_set_default_od_settings(struct smu_context *smu)
                (OverDriveTable_t *)smu->smu_table.boot_overdrive_table;
        OverDriveTable_t *user_od_table =
                (OverDriveTable_t *)smu->smu_table.user_overdrive_table;
+       OverDriveTable_t user_od_table_bak;
        int ret = 0;
 
-       /*
-        * For S3/S4/Runpm resume, no need to setup those overdrive tables again as
-        *   - either they already have the default OD settings got during cold bootup
-        *   - or they have some user customized OD settings which cannot be overwritten
-        */
-       if (smu->adev->in_suspend)
-               return 0;
-
        ret = smu_cmn_update_table(smu, SMU_TABLE_OVERDRIVE,
                                   0, (void *)boot_od_table, false);
        if (ret) {
@@ -2163,7 +2156,23 @@ static int sienna_cichlid_set_default_od_settings(struct smu_context *smu)
        sienna_cichlid_dump_od_table(smu, boot_od_table);
 
        memcpy(od_table, boot_od_table, sizeof(OverDriveTable_t));
-       memcpy(user_od_table, boot_od_table, sizeof(OverDriveTable_t));
+
+       /*
+        * For S3/S4/Runpm resume, we need to setup those overdrive tables again,
+        * but we have to preserve user defined values in "user_od_table".
+        */
+       if (!smu->adev->in_suspend) {
+               memcpy(user_od_table, boot_od_table, sizeof(OverDriveTable_t));
+               smu->user_dpm_profile.user_od = false;
+       } else if (smu->user_dpm_profile.user_od) {
+               memcpy(&user_od_table_bak, user_od_table, sizeof(OverDriveTable_t));
+               memcpy(user_od_table, boot_od_table, sizeof(OverDriveTable_t));
+               user_od_table->GfxclkFmin = user_od_table_bak.GfxclkFmin;
+               user_od_table->GfxclkFmax = user_od_table_bak.GfxclkFmax;
+               user_od_table->UclkFmin = user_od_table_bak.UclkFmin;
+               user_od_table->UclkFmax = user_od_table_bak.UclkFmax;
+               user_od_table->VddGfxOffset = user_od_table_bak.VddGfxOffset;
+       }
 
        return 0;
 }
@@ -2373,6 +2382,20 @@ static int sienna_cichlid_od_edit_dpm_table(struct smu_context *smu,
        return ret;
 }
 
+static int sienna_cichlid_restore_user_od_settings(struct smu_context *smu)
+{
+       struct smu_table_context *table_context = &smu->smu_table;
+       OverDriveTable_t *od_table = table_context->overdrive_table;
+       OverDriveTable_t *user_od_table = table_context->user_overdrive_table;
+       int res;
+
+       res = smu_v11_0_restore_user_od_settings(smu);
+       if (res == 0)
+               memcpy(od_table, user_od_table, sizeof(OverDriveTable_t));
+
+       return res;
+}
+
 static int sienna_cichlid_run_btc(struct smu_context *smu)
 {
        int res;
@@ -4400,7 +4423,7 @@ static const struct pptable_funcs sienna_cichlid_ppt_funcs = {
        .set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range,
        .set_default_od_settings = sienna_cichlid_set_default_od_settings,
        .od_edit_dpm_table = sienna_cichlid_od_edit_dpm_table,
-       .restore_user_od_settings = smu_v11_0_restore_user_od_settings,
+       .restore_user_od_settings = sienna_cichlid_restore_user_od_settings,
        .run_btc = sienna_cichlid_run_btc,
        .set_power_source = smu_v11_0_set_power_source,
        .get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
index 923a9fb3c8873cd4eb175710ec11887d08b27848..a5c97d61e92a67115208c83e0c59a07c15fdf183 100644 (file)
@@ -46,6 +46,7 @@
 #include "asic_reg/mp/mp_13_0_0_sh_mask.h"
 #include "smu_cmn.h"
 #include "amdgpu_ras.h"
+#include "umc_v8_10.h"
 
 /*
  * DO NOT use these for err/warn/info/debug messages.
 
 #define DEBUGSMC_MSG_Mode1Reset        2
 
+/*
+ * SMU_v13_0_10 supports ECCTABLE since version 80.34.0,
+ * use this to check ECCTABLE feature whether support
+ */
+#define SUPPORT_ECCTABLE_SMU_13_0_10_VERSION 0x00502200
+
 static struct cmn2asic_msg_mapping smu_v13_0_0_message_map[SMU_MSG_MAX_COUNT] = {
        MSG_MAP(TestMessage,                    PPSMC_MSG_TestMessage,                 1),
        MSG_MAP(GetSmuVersion,                  PPSMC_MSG_GetSmuVersion,               1),
@@ -229,6 +236,7 @@ static struct cmn2asic_mapping smu_v13_0_0_table_map[SMU_TABLE_COUNT] = {
        TAB_MAP(ACTIVITY_MONITOR_COEFF),
        [SMU_TABLE_COMBO_PPTABLE] = {1, TABLE_COMBO_PPTABLE},
        TAB_MAP(I2C_COMMANDS),
+       TAB_MAP(ECCINFO),
 };
 
 static struct cmn2asic_mapping smu_v13_0_0_pwr_src_map[SMU_POWER_SOURCE_COUNT] = {
@@ -462,6 +470,8 @@ static int smu_v13_0_0_tables_init(struct smu_context *smu)
                       AMDGPU_GEM_DOMAIN_VRAM);
        SMU_TABLE_INIT(tables, SMU_TABLE_COMBO_PPTABLE, MP0_MP1_DATA_REGION_SIZE_COMBOPPTABLE,
                        PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
+       SMU_TABLE_INIT(tables, SMU_TABLE_ECCINFO, sizeof(EccInfoTable_t),
+                       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
 
        smu_table->metrics_table = kzalloc(sizeof(SmuMetricsExternal_t), GFP_KERNEL);
        if (!smu_table->metrics_table)
@@ -477,8 +487,14 @@ static int smu_v13_0_0_tables_init(struct smu_context *smu)
        if (!smu_table->watermarks_table)
                goto err2_out;
 
+       smu_table->ecc_table = kzalloc(tables[SMU_TABLE_ECCINFO].size, GFP_KERNEL);
+       if (!smu_table->ecc_table)
+               goto err3_out;
+
        return 0;
 
+err3_out:
+       kfree(smu_table->watermarks_table);
 err2_out:
        kfree(smu_table->gpu_metrics_table);
 err1_out:
@@ -1128,8 +1144,8 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
                                        (pcie_table->pcie_lane[i] == 5) ? "x12" :
                                        (pcie_table->pcie_lane[i] == 6) ? "x16" : "",
                                        pcie_table->clk_freq[i],
-                                       ((gen_speed - 1) == pcie_table->pcie_gen[i]) &&
-                                       (lane_width == link_width[pcie_table->pcie_lane[i]]) ?
+                                       (gen_speed == DECODE_GEN_SPEED(pcie_table->pcie_gen[i])) &&
+                                       (lane_width == DECODE_LANE_WIDTH(link_width[pcie_table->pcie_lane[i]])) ?
                                        "*" : "");
                break;
 
@@ -2036,6 +2052,64 @@ static int smu_v13_0_0_send_bad_mem_channel_flag(struct smu_context *smu,
        return ret;
 }
 
+static int smu_v13_0_0_check_ecc_table_support(struct smu_context *smu)
+{
+       struct amdgpu_device *adev = smu->adev;
+       uint32_t if_version = 0xff, smu_version = 0xff;
+       int ret = 0;
+
+       ret = smu_cmn_get_smc_version(smu, &if_version, &smu_version);
+       if (ret)
+               return -EOPNOTSUPP;
+
+       if ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 10)) &&
+               (smu_version >= SUPPORT_ECCTABLE_SMU_13_0_10_VERSION))
+               return ret;
+       else
+               return -EOPNOTSUPP;
+}
+
+static ssize_t smu_v13_0_0_get_ecc_info(struct smu_context *smu,
+                                                                       void *table)
+{
+       struct smu_table_context *smu_table = &smu->smu_table;
+       struct amdgpu_device *adev = smu->adev;
+       EccInfoTable_t *ecc_table = NULL;
+       struct ecc_info_per_ch *ecc_info_per_channel = NULL;
+       int i, ret = 0;
+       struct umc_ecc_info *eccinfo = (struct umc_ecc_info *)table;
+
+       ret = smu_v13_0_0_check_ecc_table_support(smu);
+       if (ret)
+               return ret;
+
+       ret = smu_cmn_update_table(smu,
+                                       SMU_TABLE_ECCINFO,
+                                       0,
+                                       smu_table->ecc_table,
+                                       false);
+       if (ret) {
+               dev_info(adev->dev, "Failed to export SMU ecc table!\n");
+               return ret;
+       }
+
+       ecc_table = (EccInfoTable_t *)smu_table->ecc_table;
+
+       for (i = 0; i < UMC_V8_10_TOTAL_CHANNEL_NUM(adev); i++) {
+               ecc_info_per_channel = &(eccinfo->ecc[i]);
+               ecc_info_per_channel->ce_count_lo_chip =
+                               ecc_table->EccInfo[i].ce_count_lo_chip;
+               ecc_info_per_channel->ce_count_hi_chip =
+                               ecc_table->EccInfo[i].ce_count_hi_chip;
+               ecc_info_per_channel->mca_umc_status =
+                               ecc_table->EccInfo[i].mca_umc_status;
+               ecc_info_per_channel->mca_umc_addr =
+                               ecc_table->EccInfo[i].mca_umc_addr;
+       }
+
+       return ret;
+}
+
 static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
        .get_allowed_feature_mask = smu_v13_0_0_get_allowed_feature_mask,
        .set_default_dpm_table = smu_v13_0_0_set_default_dpm_table,
@@ -2111,6 +2185,7 @@ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
        .send_hbm_bad_pages_num = smu_v13_0_0_smu_send_bad_mem_page_num,
        .send_hbm_bad_channel_flag = smu_v13_0_0_send_bad_mem_channel_flag,
        .gpo_control = smu_v13_0_gpo_control,
+       .get_ecc_info = smu_v13_0_0_get_ecc_info,
 };
 
 void smu_v13_0_0_set_ppt_funcs(struct smu_context *smu)
index 9e1967d8049e3a02db79a68563810f713b3292f4..4399416dd9b8f47cadd52b6641edae45a1c6588b 100644 (file)
@@ -575,6 +575,14 @@ static int smu_v13_0_7_set_default_dpm_table(struct smu_context *smu)
                                                     dpm_table);
                if (ret)
                        return ret;
+
+               if (skutable->DriverReportedClocks.GameClockAc &&
+                       (dpm_table->dpm_levels[dpm_table->count - 1].value >
+                       skutable->DriverReportedClocks.GameClockAc)) {
+                       dpm_table->dpm_levels[dpm_table->count - 1].value =
+                               skutable->DriverReportedClocks.GameClockAc;
+                       dpm_table->max = skutable->DriverReportedClocks.GameClockAc;
+               }
        } else {
                dpm_table->count = 1;
                dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100;
@@ -828,6 +836,57 @@ static int smu_v13_0_7_get_smu_metrics_data(struct smu_context *smu,
        return ret;
 }
 
+static int smu_v13_0_7_get_dpm_ultimate_freq(struct smu_context *smu,
+                                            enum smu_clk_type clk_type,
+                                            uint32_t *min,
+                                            uint32_t *max)
+{
+       struct smu_13_0_dpm_context *dpm_context =
+               smu->smu_dpm.dpm_context;
+       struct smu_13_0_dpm_table *dpm_table;
+
+       switch (clk_type) {
+       case SMU_MCLK:
+       case SMU_UCLK:
+               /* uclk dpm table */
+               dpm_table = &dpm_context->dpm_tables.uclk_table;
+               break;
+       case SMU_GFXCLK:
+       case SMU_SCLK:
+               /* gfxclk dpm table */
+               dpm_table = &dpm_context->dpm_tables.gfx_table;
+               break;
+       case SMU_SOCCLK:
+               /* socclk dpm table */
+               dpm_table = &dpm_context->dpm_tables.soc_table;
+               break;
+       case SMU_FCLK:
+               /* fclk dpm table */
+               dpm_table = &dpm_context->dpm_tables.fclk_table;
+               break;
+       case SMU_VCLK:
+       case SMU_VCLK1:
+               /* vclk dpm table */
+               dpm_table = &dpm_context->dpm_tables.vclk_table;
+               break;
+       case SMU_DCLK:
+       case SMU_DCLK1:
+               /* dclk dpm table */
+               dpm_table = &dpm_context->dpm_tables.dclk_table;
+               break;
+       default:
+               dev_err(smu->adev->dev, "Unsupported clock type!\n");
+               return -EINVAL;
+       }
+
+       if (min)
+               *min = dpm_table->min;
+       if (max)
+               *max = dpm_table->max;
+
+       return 0;
+}
+
 static int smu_v13_0_7_read_sensor(struct smu_context *smu,
                                   enum amd_pp_sensors sensor,
                                   void *data,
@@ -1074,8 +1133,8 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu,
                                        (pcie_table->pcie_lane[i] == 5) ? "x12" :
                                        (pcie_table->pcie_lane[i] == 6) ? "x16" : "",
                                        pcie_table->clk_freq[i],
-                                       (gen_speed == pcie_table->pcie_gen[i]) &&
-                                       (lane_width == pcie_table->pcie_lane[i]) ?
+                                       (gen_speed == DECODE_GEN_SPEED(pcie_table->pcie_gen[i])) &&
+                                       (lane_width == DECODE_LANE_WIDTH(pcie_table->pcie_lane[i])) ?
                                        "*" : "");
                break;
 
@@ -1329,9 +1388,17 @@ static int smu_v13_0_7_populate_umd_state_clk(struct smu_context *smu)
                                &dpm_context->dpm_tables.fclk_table;
        struct smu_umd_pstate_table *pstate_table =
                                &smu->pstate_table;
+       struct smu_table_context *table_context = &smu->smu_table;
+       PPTable_t *pptable = table_context->driver_pptable;
+       DriverReportedClocks_t driver_clocks =
+               pptable->SkuTable.DriverReportedClocks;
 
        pstate_table->gfxclk_pstate.min = gfx_table->min;
-       pstate_table->gfxclk_pstate.peak = gfx_table->max;
+       if (driver_clocks.GameClockAc &&
+               (driver_clocks.GameClockAc < gfx_table->max))
+               pstate_table->gfxclk_pstate.peak = driver_clocks.GameClockAc;
+       else
+               pstate_table->gfxclk_pstate.peak = gfx_table->max;
 
        pstate_table->uclk_pstate.min = mem_table->min;
        pstate_table->uclk_pstate.peak = mem_table->max;
@@ -1348,12 +1415,12 @@ static int smu_v13_0_7_populate_umd_state_clk(struct smu_context *smu)
        pstate_table->fclk_pstate.min = fclk_table->min;
        pstate_table->fclk_pstate.peak = fclk_table->max;
 
-       /*
-        * For now, just use the mininum clock frequency.
-        * TODO: update them when the real pstate settings available
-        */
-       pstate_table->gfxclk_pstate.standard = gfx_table->min;
-       pstate_table->uclk_pstate.standard = mem_table->min;
+       if (driver_clocks.BaseClockAc &&
+               driver_clocks.BaseClockAc < gfx_table->max)
+               pstate_table->gfxclk_pstate.standard = driver_clocks.BaseClockAc;
+       else
+               pstate_table->gfxclk_pstate.standard = gfx_table->max;
+       pstate_table->uclk_pstate.standard = mem_table->max;
        pstate_table->socclk_pstate.standard = soc_table->min;
        pstate_table->vclk_pstate.standard = vclk_table->min;
        pstate_table->dclk_pstate.standard = dclk_table->min;
@@ -1676,7 +1743,7 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = {
        .dpm_set_jpeg_enable = smu_v13_0_set_jpeg_enable,
        .init_pptable_microcode = smu_v13_0_init_pptable_microcode,
        .populate_umd_state_clk = smu_v13_0_7_populate_umd_state_clk,
-       .get_dpm_ultimate_freq = smu_v13_0_get_dpm_ultimate_freq,
+       .get_dpm_ultimate_freq = smu_v13_0_7_get_dpm_ultimate_freq,
        .get_vbios_bootup_values = smu_v13_0_get_vbios_bootup_values,
        .read_sensor = smu_v13_0_7_read_sensor,
        .feature_is_enabled = smu_cmn_feature_is_enabled,
index 0643887800b4d33cea277876b604e44a18f76c5c..142668cd6d7cdd079d893a81aa97a459f5838dcc 100644 (file)
@@ -99,7 +99,6 @@ static int armada_drm_bind(struct device *dev)
        if (ret) {
                dev_err(dev, "[" DRM_NAME ":%s] can't kick out simple-fb: %d\n",
                        __func__, ret);
-               kfree(priv);
                return ret;
        }
 
index 2019a8167d693d516b118ae2d1d37ace24276067..b40baced1331666372e98115091e2d08b9ba5a2e 100644 (file)
@@ -676,8 +676,8 @@ static int lt8912_parse_dt(struct lt8912 *lt)
 
        lt->hdmi_port = of_drm_find_bridge(port_node);
        if (!lt->hdmi_port) {
-               dev_err(lt->dev, "%s: Failed to get hdmi port\n", __func__);
-               ret = -ENODEV;
+               ret = -EPROBE_DEFER;
+               dev_err_probe(lt->dev, ret, "%s: Failed to get hdmi port\n", __func__);
                goto err_free_host_node;
        }
 
index 0264abe552788fc934d6c16a7fae878947a5cc15..faf5e9efa7d3380b0c76603ab86544a360fe83d5 100644 (file)
@@ -44,10 +44,8 @@ int drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame,
 
        /* Sink EOTF is Bit map while infoframe is absolute values */
        if (!is_eotf_supported(hdr_metadata->hdmi_metadata_type1.eotf,
-           connector->hdr_sink_metadata.hdmi_type1.eotf)) {
-               DRM_DEBUG_KMS("EOTF Not Supported\n");
-               return -EINVAL;
-       }
+           connector->hdr_sink_metadata.hdmi_type1.eotf))
+               DRM_DEBUG_KMS("Unknown EOTF %d\n", hdr_metadata->hdmi_metadata_type1.eotf);
 
        err = hdmi_drm_infoframe_init(frame);
        if (err < 0)
index 5457c02ca1abcad673f2bafa0e7b8ee3a7b57cce..fed41800fea737c2f1c231892be471c9a5ead22a 100644 (file)
@@ -1070,6 +1070,7 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
        drm_printf(p, "connector[%u]: %s\n", connector->base.id, connector->name);
        drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
        drm_printf(p, "\tself_refresh_aware=%d\n", state->self_refresh_aware);
+       drm_printf(p, "\tmax_requested_bpc=%d\n", state->max_requested_bpc);
 
        if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
                if (state->writeback_job && state->writeback_job->fb)
index 3d1f50f481cfda6d85845c47a95d2218028f6c51..7098f125b54a9a3004ea98345f7ec486cc8ae24a 100644 (file)
@@ -146,8 +146,8 @@ int drm_buddy_init(struct drm_buddy *mm, u64 size, u64 chunk_size)
                unsigned int order;
                u64 root_size;
 
-               root_size = rounddown_pow_of_two(size);
-               order = ilog2(root_size) - ilog2(chunk_size);
+               order = ilog2(size) - ilog2(chunk_size);
+               root_size = chunk_size << order;
 
                root = drm_block_alloc(mm, NULL, order, offset);
                if (!root)
index 3d0a4da661bc985c5c2b144fecd2d2de80677f26..261a62e1593416e5228b4a859788e798b1e4cf59 100644 (file)
@@ -2796,7 +2796,7 @@ u32 drm_edid_get_panel_id(struct i2c_adapter *adapter)
         * the EDID then we'll just return 0.
         */
 
-       base_block = kmalloc(EDID_LENGTH, GFP_KERNEL);
+       base_block = kzalloc(EDID_LENGTH, GFP_KERNEL);
        if (!base_block)
                return 0;
 
index 7a3cb08dc942e1703b0ab7e2767328d501e44821..a5d392f7e11f6a1bb7ef0578de0f6a6f39e406fd 100644 (file)
@@ -1388,10 +1388,13 @@ EXPORT_SYMBOL(drm_gem_lru_move_tail);
  *
  * @lru: The LRU to scan
  * @nr_to_scan: The number of pages to try to reclaim
+ * @remaining: The number of pages left to reclaim, should be initialized by caller
  * @shrink: Callback to try to shrink/reclaim the object.
  */
 unsigned long
-drm_gem_lru_scan(struct drm_gem_lru *lru, unsigned nr_to_scan,
+drm_gem_lru_scan(struct drm_gem_lru *lru,
+                unsigned int nr_to_scan,
+                unsigned long *remaining,
                 bool (*shrink)(struct drm_gem_object *obj))
 {
        struct drm_gem_lru still_in_lru;
@@ -1430,8 +1433,10 @@ drm_gem_lru_scan(struct drm_gem_lru *lru, unsigned nr_to_scan,
                 * hit shrinker in response to trying to get backing pages
                 * for this obj (ie. while it's lock is already held)
                 */
-               if (!dma_resv_trylock(obj->resv))
+               if (!dma_resv_trylock(obj->resv)) {
+                       *remaining += obj->size >> PAGE_SHIFT;
                        goto tail;
+               }
 
                if (shrink(obj)) {
                        freed += obj->size >> PAGE_SHIFT;
index 75185a960fc408f1042999e4c9b6c04baef6831b..2b2163c8138ef488563c996ff0334cf80add92bb 100644 (file)
@@ -619,11 +619,14 @@ int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct
        int ret;
 
        if (obj->import_attach) {
-               /* Drop the reference drm_gem_mmap_obj() acquired.*/
-               drm_gem_object_put(obj);
                vma->vm_private_data = NULL;
+               ret = dma_buf_mmap(obj->dma_buf, vma, 0);
+
+               /* Drop the reference drm_gem_mmap_obj() acquired.*/
+               if (!ret)
+                       drm_gem_object_put(obj);
 
-               return dma_buf_mmap(obj->dma_buf, vma, 0);
+               return ret;
        }
 
        ret = drm_gem_shmem_get_pages(shmem);
index 5522d610c5cfdea29aeb587f93017a55d4224580..b1a38e6ce2f8fad28bbef491a02c29b7257beaa1 100644 (file)
@@ -328,10 +328,17 @@ static const struct dmi_system_id orientation_data[] = {
                  DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Duet 3 10IGL5"),
                },
                .driver_data = (void *)&lcd1200x1920_rightside_up,
-       }, {    /* Lenovo Yoga Book X90F / X91F / X91L */
+       }, {    /* Lenovo Yoga Book X90F / X90L */
                .matches = {
-                 /* Non exact match to match all versions */
-                 DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"),
+                 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
+                 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
+                 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"),
+               },
+               .driver_data = (void *)&lcd1200x1920_rightside_up,
+       }, {    /* Lenovo Yoga Book X91F / X91L */
+               .matches = {
+                 /* Non exact match to match F + L versions */
+                 DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"),
                },
                .driver_data = (void *)&lcd1200x1920_rightside_up,
        }, {    /* Lenovo Yoga Tablet 2 830F / 830L */
index 44ca803237a5f9c8b43cc92129245beeffc121b9..31a7f59ccb49ee7c552e58991c444dd8754e8582 100644 (file)
@@ -22,7 +22,6 @@
 #include "etnaviv_gem.h"
 #include "etnaviv_mmu.h"
 #include "etnaviv_perfmon.h"
-#include "common.xml.h"
 
 /*
  * DRM operations:
@@ -476,47 +475,7 @@ static const struct drm_ioctl_desc etnaviv_ioctls[] = {
        ETNA_IOCTL(PM_QUERY_SIG, pm_query_sig, DRM_RENDER_ALLOW),
 };
 
-static void etnaviv_fop_show_fdinfo(struct seq_file *m, struct file *f)
-{
-       struct drm_file *file = f->private_data;
-       struct drm_device *dev = file->minor->dev;
-       struct etnaviv_drm_private *priv = dev->dev_private;
-       struct etnaviv_file_private *ctx = file->driver_priv;
-
-       /*
-        * For a description of the text output format used here, see
-        * Documentation/gpu/drm-usage-stats.rst.
-        */
-       seq_printf(m, "drm-driver:\t%s\n", dev->driver->name);
-       seq_printf(m, "drm-client-id:\t%u\n", ctx->id);
-
-       for (int i = 0; i < ETNA_MAX_PIPES; i++) {
-               struct etnaviv_gpu *gpu = priv->gpu[i];
-               char engine[10] = "UNK";
-               int cur = 0;
-
-               if (!gpu)
-                       continue;
-
-               if (gpu->identity.features & chipFeatures_PIPE_2D)
-                       cur = snprintf(engine, sizeof(engine), "2D");
-               if (gpu->identity.features & chipFeatures_PIPE_3D)
-                       cur = snprintf(engine + cur, sizeof(engine) - cur,
-                                      "%s3D", cur ? "/" : "");
-               if (gpu->identity.nn_core_count > 0)
-                       cur = snprintf(engine + cur, sizeof(engine) - cur,
-                                      "%sNN", cur ? "/" : "");
-
-               seq_printf(m, "drm-engine-%s:\t%llu ns\n", engine,
-                          ctx->sched_entity[i].elapsed_ns);
-       }
-}
-
-static const struct file_operations fops = {
-       .owner = THIS_MODULE,
-       DRM_GEM_FOPS,
-       .show_fdinfo = etnaviv_fop_show_fdinfo,
-};
+DEFINE_DRM_GEM_FOPS(fops);
 
 static const struct drm_driver etnaviv_drm_driver = {
        .driver_features    = DRIVER_GEM | DRIVER_RENDER,
index 7031db145a77a1c33c9175914dc57489abd03342..3524b5811682af447d6809a8dd10c4d736c7b372 100644 (file)
@@ -91,7 +91,15 @@ static void *etnaviv_gem_prime_vmap_impl(struct etnaviv_gem_object *etnaviv_obj)
 static int etnaviv_gem_prime_mmap_obj(struct etnaviv_gem_object *etnaviv_obj,
                struct vm_area_struct *vma)
 {
-       return dma_buf_mmap(etnaviv_obj->base.dma_buf, vma, 0);
+       int ret;
+
+       ret = dma_buf_mmap(etnaviv_obj->base.dma_buf, vma, 0);
+       if (!ret) {
+               /* Drop the reference acquired by drm_gem_mmap_obj(). */
+               drm_gem_object_put(&etnaviv_obj->base);
+       }
+
+       return ret;
 }
 
 static const struct etnaviv_gem_ops etnaviv_gem_prime_ops = {
index 468a792e6a405a7f3b18bec607704d1e0c7740ef..fc0eaf40dc941745d43181d60f27db0b6a0f9d64 100644 (file)
@@ -300,9 +300,21 @@ static void configure_dual_link_mode(struct intel_encoder *encoder,
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
        u32 dss_ctl1;
 
-       dss_ctl1 = intel_de_read(dev_priv, DSS_CTL1);
+       /* FIXME: Move all DSS handling to intel_vdsc.c */
+       if (DISPLAY_VER(dev_priv) >= 12) {
+               struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
+
+               dss_ctl1_reg = ICL_PIPE_DSS_CTL1(crtc->pipe);
+               dss_ctl2_reg = ICL_PIPE_DSS_CTL2(crtc->pipe);
+       } else {
+               dss_ctl1_reg = DSS_CTL1;
+               dss_ctl2_reg = DSS_CTL2;
+       }
+
+       dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg);
        dss_ctl1 |= SPLITTER_ENABLE;
        dss_ctl1 &= ~OVERLAP_PIXELS_MASK;
        dss_ctl1 |= OVERLAP_PIXELS(intel_dsi->pixel_overlap);
@@ -323,16 +335,16 @@ static void configure_dual_link_mode(struct intel_encoder *encoder,
 
                dss_ctl1 &= ~LEFT_DL_BUF_TARGET_DEPTH_MASK;
                dss_ctl1 |= LEFT_DL_BUF_TARGET_DEPTH(dl_buffer_depth);
-               dss_ctl2 = intel_de_read(dev_priv, DSS_CTL2);
+               dss_ctl2 = intel_de_read(dev_priv, dss_ctl2_reg);
                dss_ctl2 &= ~RIGHT_DL_BUF_TARGET_DEPTH_MASK;
                dss_ctl2 |= RIGHT_DL_BUF_TARGET_DEPTH(dl_buffer_depth);
-               intel_de_write(dev_priv, DSS_CTL2, dss_ctl2);
+               intel_de_write(dev_priv, dss_ctl2_reg, dss_ctl2);
        } else {
                /* Interleave */
                dss_ctl1 |= DUAL_LINK_MODE_INTERLEAVE;
        }
 
-       intel_de_write(dev_priv, DSS_CTL1, dss_ctl1);
+       intel_de_write(dev_priv, dss_ctl1_reg, dss_ctl1);
 }
 
 /* aka DSI 8X clock */
index 8d97c299e6577b786dc39aa881e184b386b1ccd9..bd598a7f5047de31d7ded149926ba4c59f4532e1 100644 (file)
@@ -46,6 +46,11 @@ struct intel_color_funcs {
         * registers involved with the same commit.
         */
        void (*color_commit_arm)(const struct intel_crtc_state *crtc_state);
+       /*
+        * Perform any extra tasks needed after all the
+        * double buffered registers have been latched.
+        */
+       void (*color_post_update)(const struct intel_crtc_state *crtc_state);
        /*
         * Load LUTs (and other single buffered color management
         * registers). Will (hopefully) be called during the vblank
@@ -614,9 +619,33 @@ static void ilk_lut_12p4_pack(struct drm_color_lut *entry, u32 ldw, u32 udw)
 
 static void icl_color_commit_noarm(const struct intel_crtc_state *crtc_state)
 {
+       /*
+        * Despite Wa_1406463849, ICL no longer suffers from the SKL
+        * DC5/PSR CSC black screen issue (see skl_color_commit_noarm()).
+        * Possibly due to the extra sticky CSC arming
+        * (see icl_color_post_update()).
+        *
+        * On TGL+ all CSC arming issues have been properly fixed.
+        */
        icl_load_csc_matrix(crtc_state);
 }
 
+static void skl_color_commit_noarm(const struct intel_crtc_state *crtc_state)
+{
+       /*
+        * Possibly related to display WA #1184, SKL CSC loses the latched
+        * CSC coeff/offset register values if the CSC registers are disarmed
+        * between DC5 exit and PSR exit. This will cause the plane(s) to
+        * output all black (until CSC_MODE is rearmed and properly latched).
+        * Once PSR exit (and proper register latching) has occurred the
+        * danger is over. Thus when PSR is enabled the CSC coeff/offset
+        * register programming will be peformed from skl_color_commit_arm()
+        * which is called after PSR exit.
+        */
+       if (!crtc_state->has_psr)
+               ilk_load_csc_matrix(crtc_state);
+}
+
 static void ilk_color_commit_noarm(const struct intel_crtc_state *crtc_state)
 {
        ilk_load_csc_matrix(crtc_state);
@@ -659,6 +688,9 @@ static void skl_color_commit_arm(const struct intel_crtc_state *crtc_state)
        enum pipe pipe = crtc->pipe;
        u32 val = 0;
 
+       if (crtc_state->has_psr)
+               ilk_load_csc_matrix(crtc_state);
+
        /*
         * We don't (yet) allow userspace to control the pipe background color,
         * so force it to black, but apply pipe gamma and CSC appropriately
@@ -677,6 +709,47 @@ static void skl_color_commit_arm(const struct intel_crtc_state *crtc_state)
                          crtc_state->csc_mode);
 }
 
+static void icl_color_commit_arm(const struct intel_crtc_state *crtc_state)
+{
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+       struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+       enum pipe pipe = crtc->pipe;
+
+       /*
+        * We don't (yet) allow userspace to control the pipe background color,
+        * so force it to black.
+        */
+       intel_de_write(i915, SKL_BOTTOM_COLOR(pipe), 0);
+
+       intel_de_write(i915, GAMMA_MODE(crtc->pipe),
+                      crtc_state->gamma_mode);
+
+       intel_de_write_fw(i915, PIPE_CSC_MODE(crtc->pipe),
+                         crtc_state->csc_mode);
+}
+
+static void icl_color_post_update(const struct intel_crtc_state *crtc_state)
+{
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+       struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+
+       /*
+        * Despite Wa_1406463849, ICL CSC is no longer disarmed by
+        * coeff/offset register *writes*. Instead, once CSC_MODE
+        * is armed it stays armed, even after it has been latched.
+        * Afterwards the coeff/offset registers become effectively
+        * self-arming. That self-arming must be disabled before the
+        * next icl_color_commit_noarm() tries to write the next set
+        * of coeff/offset registers. Fortunately register *reads*
+        * do still disarm the CSC. Naturally this must not be done
+        * until the previously written CSC registers have actually
+        * been latched.
+        *
+        * TGL+ no longer need this workaround.
+        */
+       intel_de_read_fw(i915, PIPE_CSC_PREOFF_HI(crtc->pipe));
+}
+
 static struct drm_property_blob *
 create_linear_lut(struct drm_i915_private *i915, int lut_size)
 {
@@ -1373,6 +1446,14 @@ void intel_color_commit_arm(const struct intel_crtc_state *crtc_state)
        i915->display.funcs.color->color_commit_arm(crtc_state);
 }
 
+void intel_color_post_update(const struct intel_crtc_state *crtc_state)
+{
+       struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+
+       if (i915->display.funcs.color->color_post_update)
+               i915->display.funcs.color->color_post_update(crtc_state);
+}
+
 void intel_color_prepare_commit(struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -3064,10 +3145,20 @@ static const struct intel_color_funcs i9xx_color_funcs = {
        .lut_equal = i9xx_lut_equal,
 };
 
+static const struct intel_color_funcs tgl_color_funcs = {
+       .color_check = icl_color_check,
+       .color_commit_noarm = icl_color_commit_noarm,
+       .color_commit_arm = icl_color_commit_arm,
+       .load_luts = icl_load_luts,
+       .read_luts = icl_read_luts,
+       .lut_equal = icl_lut_equal,
+};
+
 static const struct intel_color_funcs icl_color_funcs = {
        .color_check = icl_color_check,
        .color_commit_noarm = icl_color_commit_noarm,
-       .color_commit_arm = skl_color_commit_arm,
+       .color_commit_arm = icl_color_commit_arm,
+       .color_post_update = icl_color_post_update,
        .load_luts = icl_load_luts,
        .read_luts = icl_read_luts,
        .lut_equal = icl_lut_equal,
@@ -3075,7 +3166,7 @@ static const struct intel_color_funcs icl_color_funcs = {
 
 static const struct intel_color_funcs glk_color_funcs = {
        .color_check = glk_color_check,
-       .color_commit_noarm = ilk_color_commit_noarm,
+       .color_commit_noarm = skl_color_commit_noarm,
        .color_commit_arm = skl_color_commit_arm,
        .load_luts = glk_load_luts,
        .read_luts = glk_read_luts,
@@ -3084,7 +3175,7 @@ static const struct intel_color_funcs glk_color_funcs = {
 
 static const struct intel_color_funcs skl_color_funcs = {
        .color_check = ivb_color_check,
-       .color_commit_noarm = ilk_color_commit_noarm,
+       .color_commit_noarm = skl_color_commit_noarm,
        .color_commit_arm = skl_color_commit_arm,
        .load_luts = bdw_load_luts,
        .read_luts = bdw_read_luts,
@@ -3180,7 +3271,9 @@ void intel_color_init_hooks(struct drm_i915_private *i915)
                else
                        i915->display.funcs.color = &i9xx_color_funcs;
        } else {
-               if (DISPLAY_VER(i915) >= 11)
+               if (DISPLAY_VER(i915) >= 12)
+                       i915->display.funcs.color = &tgl_color_funcs;
+               else if (DISPLAY_VER(i915) == 11)
                        i915->display.funcs.color = &icl_color_funcs;
                else if (DISPLAY_VER(i915) == 10)
                        i915->display.funcs.color = &glk_color_funcs;
index d620b5b1e2a6ebdc68e98d16c65b3ccaa7e84c09..8002492be709096aec9169c4e89483d8ccac112f 100644 (file)
@@ -21,6 +21,7 @@ void intel_color_prepare_commit(struct intel_crtc_state *crtc_state);
 void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state);
 void intel_color_commit_noarm(const struct intel_crtc_state *crtc_state);
 void intel_color_commit_arm(const struct intel_crtc_state *crtc_state);
+void intel_color_post_update(const struct intel_crtc_state *crtc_state);
 void intel_color_load_luts(const struct intel_crtc_state *crtc_state);
 void intel_color_get_config(struct intel_crtc_state *crtc_state);
 bool intel_color_lut_equal(const struct intel_crtc_state *crtc_state,
index 82be0fbe99342bf901b9473f5f95afe4fedd8b2c..d5b5d40ed817f264fcd0c0219d22bd931caca2f5 100644 (file)
@@ -683,6 +683,14 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
         */
        intel_vrr_send_push(new_crtc_state);
 
+       /*
+        * Seamless M/N update may need to update frame timings.
+        *
+        * FIXME Should be synchronized with the start of vblank somehow...
+        */
+       if (new_crtc_state->seamless_m_n && intel_crtc_needs_fastset(new_crtc_state))
+               intel_crtc_update_active_timings(new_crtc_state);
+
        local_irq_enable();
 
        if (intel_vgpu_active(dev_priv))
index d3994e2a7d6362e77dd50a67f6f2ad070a328f2f..63b4b73f47c6aaf9b235d62f1032806aa59110c2 100644 (file)
@@ -1209,6 +1209,9 @@ static void intel_post_plane_update(struct intel_atomic_state *state,
        if (needs_cursorclk_wa(old_crtc_state) &&
            !needs_cursorclk_wa(new_crtc_state))
                icl_wa_cursorclkgating(dev_priv, pipe, false);
+
+       if (intel_crtc_needs_color_update(new_crtc_state))
+               intel_color_post_update(new_crtc_state);
 }
 
 static void intel_crtc_enable_flip_done(struct intel_atomic_state *state,
@@ -5145,6 +5148,7 @@ intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
         * only fields that are know to not cause problems are preserved. */
 
        saved_state->uapi = crtc_state->uapi;
+       saved_state->inherited = crtc_state->inherited;
        saved_state->scaler_state = crtc_state->scaler_state;
        saved_state->shared_dpll = crtc_state->shared_dpll;
        saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
@@ -7090,6 +7094,8 @@ static void intel_update_crtc(struct intel_atomic_state *state,
 
        intel_fbc_update(state, crtc);
 
+       drm_WARN_ON(&i915->drm, !intel_display_power_is_enabled(i915, POWER_DOMAIN_DC_OFF));
+
        if (!modeset &&
            intel_crtc_needs_color_update(new_crtc_state))
                intel_color_commit_noarm(new_crtc_state);
@@ -7457,8 +7463,28 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
        drm_atomic_helper_wait_for_dependencies(&state->base);
        drm_dp_mst_atomic_wait_for_dependencies(&state->base);
 
-       if (state->modeset)
-               wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET);
+       /*
+        * During full modesets we write a lot of registers, wait
+        * for PLLs, etc. Doing that while DC states are enabled
+        * is not a good idea.
+        *
+        * During fastsets and other updates we also need to
+        * disable DC states due to the following scenario:
+        * 1. DC5 exit and PSR exit happen
+        * 2. Some or all _noarm() registers are written
+        * 3. Due to some long delay PSR is re-entered
+        * 4. DC5 entry -> DMC saves the already written new
+        *    _noarm() registers and the old not yet written
+        *    _arm() registers
+        * 5. DC5 exit -> DMC restores a mixture of old and
+        *    new register values and arms the update
+        * 6. PSR exit -> hardware latches a mixture of old and
+        *    new register values -> corrupted frame, or worse
+        * 7. New _arm() registers are finally written
+        * 8. Hardware finally latches a complete set of new
+        *    register values, and subsequent frames will be OK again
+        */
+       wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DC_OFF);
 
        intel_atomic_prepare_plane_clear_colors(state);
 
@@ -7607,8 +7633,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
                 * the culprit.
                 */
                intel_uncore_arm_unclaimed_mmio_detection(&dev_priv->uncore);
-               intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET, wakeref);
        }
+       intel_display_power_put(dev_priv, POWER_DOMAIN_DC_OFF, wakeref);
        intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref);
 
        /*
index 54c517ca9632fb1be3150c40a3935cbbbf63956c..582234f0c49ace7bb3af97a86565c130a28a52eb 100644 (file)
@@ -1631,6 +1631,8 @@ struct intel_psr {
        bool psr2_sel_fetch_cff_enabled;
        bool req_psr2_sdp_prior_scanline;
        u8 sink_sync_latency;
+       u8 io_wake_lines;
+       u8 fast_wake_lines;
        ktime_t last_entry_attempt;
        ktime_t last_exit;
        bool sink_not_reliable;
index 257aa2b7cf2045d116a98088f8fa6db5a36935dd..3485d5e6dd3c75d21d4dfe9abcf4d7d369f67260 100644 (file)
@@ -384,15 +384,12 @@ static void disable_all_event_handlers(struct drm_i915_private *i915)
        }
 }
 
-static void pipedmc_clock_gating_wa(struct drm_i915_private *i915, bool enable)
+static void adlp_pipedmc_clock_gating_wa(struct drm_i915_private *i915, bool enable)
 {
        enum pipe pipe;
 
-       if (DISPLAY_VER(i915) < 13)
-               return;
-
        /*
-        * Wa_16015201720:adl-p,dg2, mtl
+        * Wa_16015201720:adl-p,dg2
         * The WA requires clock gating to be disabled all the time
         * for pipe A and B.
         * For pipe C and D clock gating needs to be disabled only
@@ -408,6 +405,25 @@ static void pipedmc_clock_gating_wa(struct drm_i915_private *i915, bool enable)
                                     PIPEDMC_GATING_DIS, 0);
 }
 
+static void mtl_pipedmc_clock_gating_wa(struct drm_i915_private *i915)
+{
+       /*
+        * Wa_16015201720
+        * The WA requires clock gating to be disabled all the time
+        * for pipe A and B.
+        */
+       intel_de_rmw(i915, GEN9_CLKGATE_DIS_0, 0,
+                    MTL_PIPEDMC_GATING_DIS_A | MTL_PIPEDMC_GATING_DIS_B);
+}
+
+static void pipedmc_clock_gating_wa(struct drm_i915_private *i915, bool enable)
+{
+       if (DISPLAY_VER(i915) >= 14 && enable)
+               mtl_pipedmc_clock_gating_wa(i915);
+       else if (DISPLAY_VER(i915) == 13)
+               adlp_pipedmc_clock_gating_wa(i915, enable);
+}
+
 void intel_dmc_enable_pipe(struct drm_i915_private *i915, enum pipe pipe)
 {
        if (!has_dmc_id_fw(i915, PIPE_TO_DMC_ID(pipe)))
index 5a176bfb10a2b009f9438500548d7a5f1204e57c..30c98810e28bba338603e789152b8d52906b6119 100644 (file)
@@ -163,7 +163,7 @@ static u32 skl_get_aux_send_ctl(struct intel_dp *intel_dp,
              DP_AUX_CH_CTL_TIME_OUT_MAX |
              DP_AUX_CH_CTL_RECEIVE_ERROR |
              (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
-             DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(32) |
+             DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(24) |
              DP_AUX_CH_CTL_SYNC_PULSE_SKL(32);
 
        if (intel_tc_port_in_tbt_alt_mode(dig_port))
index 054a009e800d77e39fdbdd7d94e48f6266779348..7c9b328bc2d733e22f2a4d9012de3a90d636acd4 100644 (file)
@@ -232,7 +232,7 @@ static int intel_dp_dsc_mst_compute_link_config(struct intel_encoder *encoder,
                        return slots;
        }
 
-       intel_link_compute_m_n(crtc_state->pipe_bpp,
+       intel_link_compute_m_n(crtc_state->dsc.compressed_bpp,
                               crtc_state->lane_count,
                               adjusted_mode->crtc_clock,
                               crtc_state->port_clock,
@@ -265,6 +265,19 @@ static int intel_dp_mst_update_slots(struct intel_encoder *encoder,
        return 0;
 }
 
+static bool intel_dp_mst_has_audio(const struct drm_connector_state *conn_state)
+{
+       const struct intel_digital_connector_state *intel_conn_state =
+               to_intel_digital_connector_state(conn_state);
+       struct intel_connector *connector =
+               to_intel_connector(conn_state->connector);
+
+       if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)
+               return connector->port->has_audio;
+       else
+               return intel_conn_state->force_audio == HDMI_AUDIO_ON;
+}
+
 static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
                                       struct intel_crtc_state *pipe_config,
                                       struct drm_connector_state *conn_state)
@@ -272,10 +285,6 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
        struct intel_dp *intel_dp = &intel_mst->primary->dp;
-       struct intel_connector *connector =
-               to_intel_connector(conn_state->connector);
-       struct intel_digital_connector_state *intel_conn_state =
-               to_intel_digital_connector_state(conn_state);
        const struct drm_display_mode *adjusted_mode =
                &pipe_config->hw.adjusted_mode;
        struct link_config_limits limits;
@@ -287,11 +296,9 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
        pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
        pipe_config->has_pch_encoder = false;
 
-       if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)
-               pipe_config->has_audio = connector->port->has_audio;
-       else
-               pipe_config->has_audio =
-                       intel_conn_state->force_audio == HDMI_AUDIO_ON;
+       pipe_config->has_audio =
+               intel_dp_mst_has_audio(conn_state) &&
+               intel_audio_compute_config(encoder, pipe_config, conn_state);
 
        /*
         * for MST we always configure max link bw - the spec doesn't
index ad1a37b515fb1c8991d1832bd99a2d301bc15c20..2a9f40a2b3ed0b75e9d95e087f7532f2f05f99c0 100644 (file)
@@ -301,6 +301,7 @@ intel_dpt_create(struct intel_framebuffer *fb)
        vm->pte_encode = gen8_ggtt_pte_encode;
 
        dpt->obj = dpt_obj;
+       dpt->obj->is_dpt = true;
 
        return &dpt->vm;
 }
@@ -309,5 +310,6 @@ void intel_dpt_destroy(struct i915_address_space *vm)
 {
        struct i915_dpt *dpt = i915_vm_to_dpt(vm);
 
+       dpt->obj->is_dpt = false;
        i915_vm_put(&dpt->vm);
 }
index f76b06293eb94293f222fa64cd3c67f664302862..38825b30db16cc3a87ce84756ec4e089b3c662f1 100644 (file)
@@ -210,6 +210,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
        bool prealloc = false;
        void __iomem *vaddr;
        struct drm_i915_gem_object *obj;
+       struct i915_gem_ww_ctx ww;
        int ret;
 
        mutex_lock(&ifbdev->hpd_lock);
@@ -283,13 +284,24 @@ static int intelfb_create(struct drm_fb_helper *helper,
                info->fix.smem_len = vma->size;
        }
 
-       vaddr = i915_vma_pin_iomap(vma);
-       if (IS_ERR(vaddr)) {
-               drm_err(&dev_priv->drm,
-                       "Failed to remap framebuffer into virtual memory (%pe)\n", vaddr);
-               ret = PTR_ERR(vaddr);
-               goto out_unpin;
+       for_i915_gem_ww(&ww, ret, false) {
+               ret = i915_gem_object_lock(vma->obj, &ww);
+
+               if (ret)
+                       continue;
+
+               vaddr = i915_vma_pin_iomap(vma);
+               if (IS_ERR(vaddr)) {
+                       drm_err(&dev_priv->drm,
+                               "Failed to remap framebuffer into virtual memory (%pe)\n", vaddr);
+                       ret = PTR_ERR(vaddr);
+                       continue;
+               }
        }
+
+       if (ret)
+               goto out_unpin;
+
        info->screen_base = vaddr;
        info->screen_size = vma->size;
 
index 7a72e15e68369f2e2bdbf58afabd48ab06c5de68..9f1a0bebae24086964adc83bbacee3668a174105 100644 (file)
@@ -542,6 +542,14 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
        val |= EDP_PSR2_FRAME_BEFORE_SU(max_t(u8, intel_dp->psr.sink_sync_latency + 1, 2));
        val |= intel_psr2_get_tp_time(intel_dp);
 
+       if (DISPLAY_VER(dev_priv) >= 12) {
+               if (intel_dp->psr.io_wake_lines < 9 &&
+                   intel_dp->psr.fast_wake_lines < 9)
+                       val |= TGL_EDP_PSR2_BLOCK_COUNT_NUM_2;
+               else
+                       val |= TGL_EDP_PSR2_BLOCK_COUNT_NUM_3;
+       }
+
        /* Wa_22012278275:adl-p */
        if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_E0)) {
                static const u8 map[] = {
@@ -558,31 +566,21 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
                 * Still using the default IO_BUFFER_WAKE and FAST_WAKE, see
                 * comments bellow for more information
                 */
-               u32 tmp, lines = 7;
-
-               val |= TGL_EDP_PSR2_BLOCK_COUNT_NUM_2;
+               u32 tmp;
 
-               tmp = map[lines - TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES];
+               tmp = map[intel_dp->psr.io_wake_lines - TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES];
                tmp = tmp << TGL_EDP_PSR2_IO_BUFFER_WAKE_SHIFT;
                val |= tmp;
 
-               tmp = map[lines - TGL_EDP_PSR2_FAST_WAKE_MIN_LINES];
+               tmp = map[intel_dp->psr.fast_wake_lines - TGL_EDP_PSR2_FAST_WAKE_MIN_LINES];
                tmp = tmp << TGL_EDP_PSR2_FAST_WAKE_MIN_SHIFT;
                val |= tmp;
        } else if (DISPLAY_VER(dev_priv) >= 12) {
-               /*
-                * TODO: 7 lines of IO_BUFFER_WAKE and FAST_WAKE are default
-                * values from BSpec. In order to setting an optimal power
-                * consumption, lower than 4k resolution mode needs to decrease
-                * IO_BUFFER_WAKE and FAST_WAKE. And higher than 4K resolution
-                * mode needs to increase IO_BUFFER_WAKE and FAST_WAKE.
-                */
-               val |= TGL_EDP_PSR2_BLOCK_COUNT_NUM_2;
-               val |= TGL_EDP_PSR2_IO_BUFFER_WAKE(7);
-               val |= TGL_EDP_PSR2_FAST_WAKE(7);
+               val |= TGL_EDP_PSR2_IO_BUFFER_WAKE(intel_dp->psr.io_wake_lines);
+               val |= TGL_EDP_PSR2_FAST_WAKE(intel_dp->psr.fast_wake_lines);
        } else if (DISPLAY_VER(dev_priv) >= 9) {
-               val |= EDP_PSR2_IO_BUFFER_WAKE(7);
-               val |= EDP_PSR2_FAST_WAKE(7);
+               val |= EDP_PSR2_IO_BUFFER_WAKE(intel_dp->psr.io_wake_lines);
+               val |= EDP_PSR2_FAST_WAKE(intel_dp->psr.fast_wake_lines);
        }
 
        if (intel_dp->psr.req_psr2_sdp_prior_scanline)
@@ -842,6 +840,46 @@ static bool _compute_psr2_sdp_prior_scanline_indication(struct intel_dp *intel_d
        return true;
 }
 
+static bool _compute_psr2_wake_times(struct intel_dp *intel_dp,
+                                    struct intel_crtc_state *crtc_state)
+{
+       struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+       int io_wake_lines, io_wake_time, fast_wake_lines, fast_wake_time;
+       u8 max_wake_lines;
+
+       if (DISPLAY_VER(i915) >= 12) {
+               io_wake_time = 42;
+               /*
+                * According to Bspec it's 42us, but based on testing
+                * it is not enough -> use 45 us.
+                */
+               fast_wake_time = 45;
+               max_wake_lines = 12;
+       } else {
+               io_wake_time = 50;
+               fast_wake_time = 32;
+               max_wake_lines = 8;
+       }
+
+       io_wake_lines = intel_usecs_to_scanlines(
+               &crtc_state->uapi.adjusted_mode, io_wake_time);
+       fast_wake_lines = intel_usecs_to_scanlines(
+               &crtc_state->uapi.adjusted_mode, fast_wake_time);
+
+       if (io_wake_lines > max_wake_lines ||
+           fast_wake_lines > max_wake_lines)
+               return false;
+
+       if (i915->params.psr_safest_params)
+               io_wake_lines = fast_wake_lines = max_wake_lines;
+
+       /* According to Bspec lower limit should be set as 7 lines. */
+       intel_dp->psr.io_wake_lines = max(io_wake_lines, 7);
+       intel_dp->psr.fast_wake_lines = max(fast_wake_lines, 7);
+
+       return true;
+}
+
 static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
                                    struct intel_crtc_state *crtc_state)
 {
@@ -936,6 +974,12 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
                return false;
        }
 
+       if (!_compute_psr2_wake_times(intel_dp, crtc_state)) {
+               drm_dbg_kms(&dev_priv->drm,
+                           "PSR2 not enabled, Unable to use long enough wake times\n");
+               return false;
+       }
+
        if (HAS_PSR2_SEL_FETCH(dev_priv)) {
                if (!intel_psr2_sel_fetch_config_valid(intel_dp, crtc_state) &&
                    !HAS_PSR_HW_TRACKING(dev_priv)) {
index c65c771f5c461f018bcc4620809782571109eea0..1cfb94b5cedbdfa757f0a16e3f25f73e5d28e37c 100644 (file)
@@ -1419,6 +1419,36 @@ static const struct intel_mpllb_state dg2_hdmi_262750 = {
                REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
 };
 
+static const struct intel_mpllb_state dg2_hdmi_267300 = {
+       .clock = 267300,
+       .ref_control =
+               REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
+       .mpllb_cp =
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 7) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
+       .mpllb_div =
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
+       .mpllb_div2 =
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 74) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
+       .mpllb_fracn1 =
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
+       .mpllb_fracn2 =
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 30146) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 36699),
+       .mpllb_sscen =
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
+};
+
 static const struct intel_mpllb_state dg2_hdmi_268500 = {
        .clock = 268500,
        .ref_control =
@@ -1509,6 +1539,36 @@ static const struct intel_mpllb_state dg2_hdmi_241500 = {
                REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
 };
 
+static const struct intel_mpllb_state dg2_hdmi_319890 = {
+       .clock = 319890,
+       .ref_control =
+               REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
+       .mpllb_cp =
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
+       .mpllb_div =
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 2),
+       .mpllb_div2 =
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 94) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
+       .mpllb_fracn1 =
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
+       .mpllb_fracn2 =
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 64094) |
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 13631),
+       .mpllb_sscen =
+               REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
+};
+
 static const struct intel_mpllb_state dg2_hdmi_497750 = {
        .clock = 497750,
        .ref_control =
@@ -1696,8 +1756,10 @@ static const struct intel_mpllb_state * const dg2_hdmi_tables[] = {
        &dg2_hdmi_209800,
        &dg2_hdmi_241500,
        &dg2_hdmi_262750,
+       &dg2_hdmi_267300,
        &dg2_hdmi_268500,
        &dg2_hdmi_296703,
+       &dg2_hdmi_319890,
        &dg2_hdmi_497750,
        &dg2_hdmi_592000,
        &dg2_hdmi_593407,
index f45328712bff1bd582dc8bf4ad2c825923c4cee9..be510b9c0d07e21772ece0ad8e5c6ae257fc78e2 100644 (file)
@@ -418,9 +418,9 @@ static bool icl_tc_phy_is_owned(struct intel_digital_port *dig_port)
        val = intel_de_read(i915, PORT_TX_DFLEXDPCSSS(dig_port->tc_phy_fia));
        if (val == 0xffffffff) {
                drm_dbg_kms(&i915->drm,
-                           "Port %s: PHY in TCCOLD, assume safe mode\n",
+                           "Port %s: PHY in TCCOLD, assume not owned\n",
                            dig_port->tc_port_name);
-               return true;
+               return false;
        }
 
        return val & DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx);
index 8949fb0a944f6b5a5ea7dd7abd7d2d3cff2f77d5..3198b64ad7dbc3da80b3c33b52492f12dbea9579 100644 (file)
@@ -127,7 +127,8 @@ i915_gem_object_create_lmem_from_data(struct drm_i915_private *i915,
 
        memcpy(map, data, size);
 
-       i915_gem_object_unpin_map(obj);
+       i915_gem_object_flush_map(obj);
+       __i915_gem_object_release_map(obj);
 
        return obj;
 }
index f9a8acbba715e191fee09cc384a425d34f57bacb..885ccde9dc3c0fde4bf313beb82ecf13055bd3f2 100644 (file)
@@ -303,7 +303,7 @@ i915_gem_object_never_mmap(const struct drm_i915_gem_object *obj)
 static inline bool
 i915_gem_object_is_framebuffer(const struct drm_i915_gem_object *obj)
 {
-       return READ_ONCE(obj->frontbuffer);
+       return READ_ONCE(obj->frontbuffer) || obj->is_dpt;
 }
 
 static inline unsigned int
index 19c9bdd8f905f0cbec9ba3d40fa32334c0efd2b5..5dcbbef31d44556b2eb8a1a86df8acd0c733638c 100644 (file)
@@ -491,6 +491,9 @@ struct drm_i915_gem_object {
         */
        unsigned int cache_dirty:1;
 
+       /* @is_dpt: Object houses a display page table (DPT) */
+       unsigned int is_dpt:1;
+
        /**
         * @read_domains: Read memory domains.
         *
index 7420276827a5b7eb61414b6af0b3fa0ed1236c82..4758f21c91e15ea25931527aa8e556217ff59edb 100644 (file)
@@ -1067,11 +1067,12 @@ static vm_fault_t vm_fault_ttm(struct vm_fault *vmf)
                        .interruptible = true,
                        .no_wait_gpu = true, /* should be idle already */
                };
+               int err;
 
                GEM_BUG_ON(!bo->ttm || !(bo->ttm->page_flags & TTM_TT_FLAG_SWAPPED));
 
-               ret = ttm_bo_validate(bo, i915_ttm_sys_placement(), &ctx);
-               if (ret) {
+               err = ttm_bo_validate(bo, i915_ttm_sys_placement(), &ctx);
+               if (err) {
                        dma_resv_unlock(bo->base.resv);
                        return VM_FAULT_SIGBUS;
                }
index 1bbe6708d0a7f4001747d8bc6b5eb3a12c26162e..750326434677f1703f1c21b8e015a1436fa05f40 100644 (file)
@@ -2018,6 +2018,8 @@ process_csb(struct intel_engine_cs *engine, struct i915_request **inactive)
         * inspecting the queue to see if we need to resumbit.
         */
        if (*prev != *execlists->active) { /* elide lite-restores */
+               struct intel_context *prev_ce = NULL, *active_ce = NULL;
+
                /*
                 * Note the inherent discrepancy between the HW runtime,
                 * recorded as part of the context switch, and the CPU
@@ -2029,9 +2031,15 @@ process_csb(struct intel_engine_cs *engine, struct i915_request **inactive)
                 * and correct overselves later when updating from HW.
                 */
                if (*prev)
-                       lrc_runtime_stop((*prev)->context);
+                       prev_ce = (*prev)->context;
                if (*execlists->active)
-                       lrc_runtime_start((*execlists->active)->context);
+                       active_ce = (*execlists->active)->context;
+               if (prev_ce != active_ce) {
+                       if (prev_ce)
+                               lrc_runtime_stop(prev_ce);
+                       if (active_ce)
+                               lrc_runtime_start(active_ce);
+               }
                new_timeslice(execlists);
        }
 
index f0dbfc434e077357729e3e3f3f9c9ac50d9e5125..40d357cf8b042f835f9c96943d3b7b0cc5b068d9 100644 (file)
@@ -737,12 +737,12 @@ int intel_gt_init(struct intel_gt *gt)
        if (err)
                goto err_gt;
 
-       intel_uc_init_late(&gt->uc);
-
        err = i915_inject_probe_error(gt->i915, -EIO);
        if (err)
                goto err_gt;
 
+       intel_uc_init_late(&gt->uc);
+
        intel_migrate_init(&gt->migrate, gt);
 
        goto out_fw;
index cef3d6f5c34e0130b4943d48a456c75da31b275e..56b993f6e7dc9337aa98d24b08748606d9e8a922 100644 (file)
 #include "intel_rc6.h"
 #include "intel_rps.h"
 #include "intel_wakeref.h"
-#include "intel_pcode.h"
 #include "pxp/intel_pxp_pm.h"
 
 #define I915_GT_SUSPEND_IDLE_TIMEOUT (HZ / 2)
 
-static void mtl_media_busy(struct intel_gt *gt)
-{
-       /* Wa_14017073508: mtl */
-       if (IS_MTL_GRAPHICS_STEP(gt->i915, P, STEP_A0, STEP_B0) &&
-           gt->type == GT_MEDIA)
-               snb_pcode_write_p(gt->uncore, PCODE_MBOX_GT_STATE,
-                                 PCODE_MBOX_GT_STATE_MEDIA_BUSY,
-                                 PCODE_MBOX_GT_STATE_DOMAIN_MEDIA, 0);
-}
-
-static void mtl_media_idle(struct intel_gt *gt)
-{
-       /* Wa_14017073508: mtl */
-       if (IS_MTL_GRAPHICS_STEP(gt->i915, P, STEP_A0, STEP_B0) &&
-           gt->type == GT_MEDIA)
-               snb_pcode_write_p(gt->uncore, PCODE_MBOX_GT_STATE,
-                                 PCODE_MBOX_GT_STATE_MEDIA_NOT_BUSY,
-                                 PCODE_MBOX_GT_STATE_DOMAIN_MEDIA, 0);
-}
-
 static void user_forcewake(struct intel_gt *gt, bool suspend)
 {
        int count = atomic_read(&gt->user_wakeref);
@@ -93,9 +72,6 @@ static int __gt_unpark(struct intel_wakeref *wf)
 
        GT_TRACE(gt, "\n");
 
-       /* Wa_14017073508: mtl */
-       mtl_media_busy(gt);
-
        /*
         * It seems that the DMC likes to transition between the DC states a lot
         * when there are no connected displays (no active power domains) during
@@ -145,9 +121,6 @@ static int __gt_park(struct intel_wakeref *wf)
        GEM_BUG_ON(!wakeref);
        intel_display_power_put_async(i915, POWER_DOMAIN_GT_IRQ, wakeref);
 
-       /* Wa_14017073508: mtl */
-       mtl_media_idle(gt);
-
        return 0;
 }
 
index 83df4cd5e06cb929f09d79a6a3f14bfb373e38c7..80dbbef86b1dbf2313311bbe82df2a651179120a 100644 (file)
@@ -580,7 +580,7 @@ static bool perf_limit_reasons_eval(void *data)
 }
 
 DEFINE_SIMPLE_ATTRIBUTE(perf_limit_reasons_fops, perf_limit_reasons_get,
-                       perf_limit_reasons_clear, "%llu\n");
+                       perf_limit_reasons_clear, "0x%llx\n");
 
 void intel_gt_pm_debugfs_register(struct intel_gt *gt, struct dentry *root)
 {
index 5c91622dfca420bc37c7c200b9e20927a14ca720..f4150f61f39c0be7cae48e67fc3430a7640ce0c1 100644 (file)
@@ -486,6 +486,7 @@ static bool bxt_check_bios_rc6_setup(struct intel_rc6 *rc6)
 static bool rc6_supported(struct intel_rc6 *rc6)
 {
        struct drm_i915_private *i915 = rc6_to_i915(rc6);
+       struct intel_gt *gt = rc6_to_gt(rc6);
 
        if (!HAS_RC6(i915))
                return false;
@@ -502,6 +503,13 @@ static bool rc6_supported(struct intel_rc6 *rc6)
                return false;
        }
 
+       if (IS_MTL_MEDIA_STEP(gt->i915, STEP_A0, STEP_B0) &&
+           gt->type == GT_MEDIA) {
+               drm_notice(&i915->drm,
+                          "Media RC6 disabled on A step\n");
+               return false;
+       }
+
        return true;
 }
 
index f5d7b51264331386623fcf8c1efedc9fec6a3792..2c92fa9d194271a7b2a6e5afb57c28b057febba2 100644 (file)
@@ -2075,16 +2075,6 @@ void intel_rps_sanitize(struct intel_rps *rps)
                rps_disable_interrupts(rps);
 }
 
-u32 intel_rps_read_rpstat_fw(struct intel_rps *rps)
-{
-       struct drm_i915_private *i915 = rps_to_i915(rps);
-       i915_reg_t rpstat;
-
-       rpstat = (GRAPHICS_VER(i915) >= 12) ? GEN12_RPSTAT1 : GEN6_RPSTAT1;
-
-       return intel_uncore_read_fw(rps_to_gt(rps)->uncore, rpstat);
-}
-
 u32 intel_rps_read_rpstat(struct intel_rps *rps)
 {
        struct drm_i915_private *i915 = rps_to_i915(rps);
@@ -2095,7 +2085,7 @@ u32 intel_rps_read_rpstat(struct intel_rps *rps)
        return intel_uncore_read(rps_to_gt(rps)->uncore, rpstat);
 }
 
-u32 intel_rps_get_cagf(struct intel_rps *rps, u32 rpstat)
+static u32 intel_rps_get_cagf(struct intel_rps *rps, u32 rpstat)
 {
        struct drm_i915_private *i915 = rps_to_i915(rps);
        u32 cagf;
@@ -2118,10 +2108,11 @@ u32 intel_rps_get_cagf(struct intel_rps *rps, u32 rpstat)
        return cagf;
 }
 
-static u32 read_cagf(struct intel_rps *rps)
+static u32 __read_cagf(struct intel_rps *rps, bool take_fw)
 {
        struct drm_i915_private *i915 = rps_to_i915(rps);
        struct intel_uncore *uncore = rps_to_uncore(rps);
+       i915_reg_t r = INVALID_MMIO_REG;
        u32 freq;
 
        /*
@@ -2129,22 +2120,30 @@ static u32 read_cagf(struct intel_rps *rps)
         * registers will return 0 freq when GT is in RC6
         */
        if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 70)) {
-               freq = intel_uncore_read(uncore, MTL_MIRROR_TARGET_WP1);
+               r = MTL_MIRROR_TARGET_WP1;
        } else if (GRAPHICS_VER(i915) >= 12) {
-               freq = intel_uncore_read(uncore, GEN12_RPSTAT1);
+               r = GEN12_RPSTAT1;
        } else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
                vlv_punit_get(i915);
                freq = vlv_punit_read(i915, PUNIT_REG_GPU_FREQ_STS);
                vlv_punit_put(i915);
        } else if (GRAPHICS_VER(i915) >= 6) {
-               freq = intel_uncore_read(uncore, GEN6_RPSTAT1);
+               r = GEN6_RPSTAT1;
        } else {
-               freq = intel_uncore_read(uncore, MEMSTAT_ILK);
+               r = MEMSTAT_ILK;
        }
 
+       if (i915_mmio_reg_valid(r))
+               freq = take_fw ? intel_uncore_read(uncore, r) : intel_uncore_read_fw(uncore, r);
+
        return intel_rps_get_cagf(rps, freq);
 }
 
+static u32 read_cagf(struct intel_rps *rps)
+{
+       return __read_cagf(rps, true);
+}
+
 u32 intel_rps_read_actual_frequency(struct intel_rps *rps)
 {
        struct intel_runtime_pm *rpm = rps_to_uncore(rps)->rpm;
@@ -2157,7 +2156,12 @@ u32 intel_rps_read_actual_frequency(struct intel_rps *rps)
        return freq;
 }
 
-u32 intel_rps_read_punit_req(struct intel_rps *rps)
+u32 intel_rps_read_actual_frequency_fw(struct intel_rps *rps)
+{
+       return intel_gpu_freq(rps, __read_cagf(rps, false));
+}
+
+static u32 intel_rps_read_punit_req(struct intel_rps *rps)
 {
        struct intel_uncore *uncore = rps_to_uncore(rps);
        struct intel_runtime_pm *rpm = rps_to_uncore(rps)->rpm;
index c622962c6befb369bb81b5bd02163bca0d0e92fa..a3fa987aa91f132e9aa6013683e09a6dfcf5710b 100644 (file)
@@ -37,8 +37,8 @@ void intel_rps_mark_interactive(struct intel_rps *rps, bool interactive);
 
 int intel_gpu_freq(struct intel_rps *rps, int val);
 int intel_freq_opcode(struct intel_rps *rps, int val);
-u32 intel_rps_get_cagf(struct intel_rps *rps, u32 rpstat1);
 u32 intel_rps_read_actual_frequency(struct intel_rps *rps);
+u32 intel_rps_read_actual_frequency_fw(struct intel_rps *rps);
 u32 intel_rps_get_requested_frequency(struct intel_rps *rps);
 u32 intel_rps_get_min_frequency(struct intel_rps *rps);
 u32 intel_rps_get_min_raw_freq(struct intel_rps *rps);
@@ -49,10 +49,8 @@ int intel_rps_set_max_frequency(struct intel_rps *rps, u32 val);
 u32 intel_rps_get_rp0_frequency(struct intel_rps *rps);
 u32 intel_rps_get_rp1_frequency(struct intel_rps *rps);
 u32 intel_rps_get_rpn_frequency(struct intel_rps *rps);
-u32 intel_rps_read_punit_req(struct intel_rps *rps);
 u32 intel_rps_read_punit_req_frequency(struct intel_rps *rps);
 u32 intel_rps_read_rpstat(struct intel_rps *rps);
-u32 intel_rps_read_rpstat_fw(struct intel_rps *rps);
 void gen6_rps_get_freq_caps(struct intel_rps *rps, struct intel_rps_freq_caps *caps);
 void intel_rps_raise_unslice(struct intel_rps *rps);
 void intel_rps_lower_unslice(struct intel_rps *rps);
index aa87d3832d60d92539413d6cc5f840873c65696a..d7e8c374f153e01ed26d46e3bdb3bd90a72d0651 100644 (file)
@@ -27,7 +27,7 @@ struct drm_printer;
  * is only relevant to pre-Xe_HP platforms (Xe_HP and beyond use the
  * I915_MAX_SS_FUSE_BITS value below).
  */
-#define GEN_MAX_SS_PER_HSW_SLICE       6
+#define GEN_MAX_SS_PER_HSW_SLICE       8
 
 /*
  * Maximum number of 32-bit registers used by hardware to express the
index fc3b994626a4fdc9f3d61fee47c23d304d3a5189..710999d7189ee3537f7436495e3ef70b7182fed4 100644 (file)
@@ -1571,6 +1571,27 @@ int intel_guc_capture_print_engine_node(struct drm_i915_error_state_buf *ebuf,
 
 #endif //CONFIG_DRM_I915_CAPTURE_ERROR
 
+static void guc_capture_find_ecode(struct intel_engine_coredump *ee)
+{
+       struct gcap_reg_list_info *reginfo;
+       struct guc_mmio_reg *regs;
+       i915_reg_t reg_ipehr = RING_IPEHR(0);
+       i915_reg_t reg_instdone = RING_INSTDONE(0);
+       int i;
+
+       if (!ee->guc_capture_node)
+               return;
+
+       reginfo = ee->guc_capture_node->reginfo + GUC_CAPTURE_LIST_TYPE_ENGINE_INSTANCE;
+       regs = reginfo->regs;
+       for (i = 0; i < reginfo->num_regs; i++) {
+               if (regs[i].offset == reg_ipehr.reg)
+                       ee->ipehr = regs[i].value;
+               else if (regs[i].offset == reg_instdone.reg)
+                       ee->instdone.instdone = regs[i].value;
+       }
+}
+
 void intel_guc_capture_free_node(struct intel_engine_coredump *ee)
 {
        if (!ee || !ee->guc_capture_node)
@@ -1612,6 +1633,7 @@ void intel_guc_capture_get_matching_node(struct intel_gt *gt,
                        list_del(&n->link);
                        ee->guc_capture_node = n;
                        ee->guc_capture = guc->capture;
+                       guc_capture_find_ecode(ee);
                        return;
                }
        }
index b5855091cf6a92af7f6a14f0896d59f25a6fe8a4..8f8dd05835c5aaf766e0f70ccbba6a3c85904dda 100644 (file)
 
 static bool __guc_rc_supported(struct intel_guc *guc)
 {
-       struct intel_gt *gt = guc_to_gt(guc);
-
-       /*
-        * Wa_14017073508: mtl
-        * Do not enable gucrc to avoid additional interrupts which
-        * may disrupt pcode wa.
-        */
-       if (IS_MTL_GRAPHICS_STEP(gt->i915, P, STEP_A0, STEP_B0) &&
-           gt->type == GT_MEDIA)
-               return false;
-
        /* GuC RC is unavailable for pre-Gen12 */
        return guc->submission_supported &&
-               GRAPHICS_VER(gt->i915) >= 12;
+               GRAPHICS_VER(guc_to_gt(guc)->i915) >= 12;
 }
 
 static bool __guc_rc_selected(struct intel_guc *guc)
index 410905da8e974465cd4b42fb2cef87ff0a4c1ed6..0c103ca160d10de2811b9c78146b5ccd0d3ec071 100644 (file)
@@ -235,6 +235,13 @@ static void delayed_huc_load_fini(struct intel_huc *huc)
        i915_sw_fence_fini(&huc->delayed_load.fence);
 }
 
+int intel_huc_sanitize(struct intel_huc *huc)
+{
+       delayed_huc_load_complete(huc);
+       intel_uc_fw_sanitize(&huc->fw);
+       return 0;
+}
+
 static bool vcs_supported(struct intel_gt *gt)
 {
        intel_engine_mask_t mask = gt->info.engine_mask;
index 52db03620c609ab69302e50f2ba64fc3e42709b6..db555b3c1f56272c424728906f3c3aa3b4d1dfe1 100644 (file)
@@ -41,6 +41,7 @@ struct intel_huc {
        } delayed_load;
 };
 
+int intel_huc_sanitize(struct intel_huc *huc);
 void intel_huc_init_early(struct intel_huc *huc);
 int intel_huc_init(struct intel_huc *huc);
 void intel_huc_fini(struct intel_huc *huc);
@@ -54,12 +55,6 @@ bool intel_huc_is_authenticated(struct intel_huc *huc);
 void intel_huc_register_gsc_notifier(struct intel_huc *huc, struct bus_type *bus);
 void intel_huc_unregister_gsc_notifier(struct intel_huc *huc, struct bus_type *bus);
 
-static inline int intel_huc_sanitize(struct intel_huc *huc)
-{
-       intel_uc_fw_sanitize(&huc->fw);
-       return 0;
-}
-
 static inline bool intel_huc_is_supported(struct intel_huc *huc)
 {
        return intel_uc_fw_is_supported(&huc->fw);
index 7412abf166a8c366e2711a120ca9b65acc5294e7..8ef93889061a6367e3558137a816efa0e32599da 100644 (file)
@@ -92,8 +92,7 @@ static void debug_active_init(struct i915_active *ref)
 static void debug_active_activate(struct i915_active *ref)
 {
        lockdep_assert_held(&ref->tree_lock);
-       if (!atomic_read(&ref->count)) /* before the first inc */
-               debug_object_activate(ref, &active_debug_desc);
+       debug_object_activate(ref, &active_debug_desc);
 }
 
 static void debug_active_deactivate(struct i915_active *ref)
@@ -422,12 +421,12 @@ replace_barrier(struct i915_active *ref, struct i915_active_fence *active)
         * we can use it to substitute for the pending idle-barrer
         * request that we want to emit on the kernel_context.
         */
-       __active_del_barrier(ref, node_from_active(active));
-       return true;
+       return __active_del_barrier(ref, node_from_active(active));
 }
 
 int i915_active_add_request(struct i915_active *ref, struct i915_request *rq)
 {
+       u64 idx = i915_request_timeline(rq)->fence_context;
        struct dma_fence *fence = &rq->fence;
        struct i915_active_fence *active;
        int err;
@@ -437,16 +436,19 @@ int i915_active_add_request(struct i915_active *ref, struct i915_request *rq)
        if (err)
                return err;
 
-       active = active_instance(ref, i915_request_timeline(rq)->fence_context);
-       if (!active) {
-               err = -ENOMEM;
-               goto out;
-       }
+       do {
+               active = active_instance(ref, idx);
+               if (!active) {
+                       err = -ENOMEM;
+                       goto out;
+               }
+
+               if (replace_barrier(ref, active)) {
+                       RCU_INIT_POINTER(active->fence, NULL);
+                       atomic_dec(&ref->count);
+               }
+       } while (unlikely(is_barrier(active)));
 
-       if (replace_barrier(ref, active)) {
-               RCU_INIT_POINTER(active->fence, NULL);
-               atomic_dec(&ref->count);
-       }
        if (!__i915_active_fence_set(active, fence))
                __i915_active_acquire(ref);
 
index 824a34ec0b83889e6075c4f6371023848f5534ed..0040749363001c0e6ce6edd5dafd004f03d74b84 100644 (file)
@@ -1592,9 +1592,7 @@ static void i915_oa_stream_destroy(struct i915_perf_stream *stream)
        /*
         * Wa_16011777198:dg2: Unset the override of GUCRC mode to enable rc6.
         */
-       if (intel_uc_uses_guc_rc(&gt->uc) &&
-           (IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_C0) ||
-            IS_DG2_GRAPHICS_STEP(gt->i915, G11, STEP_A0, STEP_B0)))
+       if (stream->override_gucrc)
                drm_WARN_ON(&gt->i915->drm,
                            intel_guc_slpc_unset_gucrc_mode(&gt->uc.guc.slpc));
 
@@ -3305,8 +3303,10 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
                if (ret) {
                        drm_dbg(&stream->perf->i915->drm,
                                "Unable to override gucrc mode\n");
-                       goto err_config;
+                       goto err_gucrc;
                }
+
+               stream->override_gucrc = true;
        }
 
        ret = alloc_oa_buffer(stream);
@@ -3345,11 +3345,15 @@ err_enable:
        free_oa_buffer(stream);
 
 err_oa_buf_alloc:
-       free_oa_configs(stream);
+       if (stream->override_gucrc)
+               intel_guc_slpc_unset_gucrc_mode(&gt->uc.guc.slpc);
 
+err_gucrc:
        intel_uncore_forcewake_put(stream->uncore, FORCEWAKE_ALL);
        intel_engine_pm_put(stream->engine);
 
+       free_oa_configs(stream);
+
 err_config:
        free_noa_wait(stream);
 
@@ -4634,13 +4638,13 @@ int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
                err = oa_config->id;
                goto sysfs_err;
        }
-
-       mutex_unlock(&perf->metrics_lock);
+       id = oa_config->id;
 
        drm_dbg(&perf->i915->drm,
                "Added config %s id=%i\n", oa_config->uuid, oa_config->id);
+       mutex_unlock(&perf->metrics_lock);
 
-       return oa_config->id;
+       return id;
 
 sysfs_err:
        mutex_unlock(&perf->metrics_lock);
index ca150b7af3f29a5b2c72b017705c3a1f40e6f6af..4d5d8c365d9e2e4629d6b4ddc288acdda34d0f9c 100644 (file)
@@ -316,6 +316,12 @@ struct i915_perf_stream {
         * buffer should be checked for available data.
         */
        u64 poll_oa_period;
+
+       /**
+        * @override_gucrc: GuC RC has been overridden for the perf stream,
+        * and we need to restore the default configuration on release.
+        */
+       bool override_gucrc;
 };
 
 /**
index 52531ab28c5f5530538769a3a7e8febf1025363f..6d422b056f8a8e5a94b697d95a59265939d6d148 100644 (file)
@@ -393,14 +393,12 @@ frequency_sample(struct intel_gt *gt, unsigned int period_ns)
                 * case we assume the system is running at the intended
                 * frequency. Fortunately, the read should rarely fail!
                 */
-               val = intel_rps_read_rpstat_fw(rps);
-               if (val)
-                       val = intel_rps_get_cagf(rps, val);
-               else
-                       val = rps->cur_freq;
+               val = intel_rps_read_actual_frequency_fw(rps);
+               if (!val)
+                       val = intel_gpu_freq(rps, rps->cur_freq);
 
                add_sample_mult(&pmu->sample[__I915_SAMPLE_FREQ_ACT],
-                               intel_gpu_freq(rps, val), period_ns / 1000);
+                               val, period_ns / 1000);
        }
 
        if (pmu->enable & config_mask(I915_PMU_REQUESTED_FREQUENCY)) {
index 3b2642397b8288f617fcfb291516409a3ae0b9ea..747b53b567a091fa2e8a65d1899d3c167e6167f3 100644 (file)
  * GEN9 clock gating regs
  */
 #define GEN9_CLKGATE_DIS_0             _MMIO(0x46530)
-#define   DARBF_GATING_DIS             (1 << 27)
-#define   PWM2_GATING_DIS              (1 << 14)
-#define   PWM1_GATING_DIS              (1 << 13)
+#define   DARBF_GATING_DIS             REG_BIT(27)
+#define   MTL_PIPEDMC_GATING_DIS_A     REG_BIT(15)
+#define   MTL_PIPEDMC_GATING_DIS_B     REG_BIT(14)
+#define   PWM2_GATING_DIS              REG_BIT(14)
+#define   PWM1_GATING_DIS              REG_BIT(13)
 
 #define GEN9_CLKGATE_DIS_3             _MMIO(0x46538)
 #define   TGL_VRH_GATING_DIS           REG_BIT(31)
 /*   XEHP_PCODE_FREQUENCY_CONFIG param2 */
 #define     PCODE_MBOX_DOMAIN_NONE             0x0
 #define     PCODE_MBOX_DOMAIN_MEDIAFF          0x3
-
-/* Wa_14017210380: mtl */
-#define   PCODE_MBOX_GT_STATE                  0x50
-/* sub-commands (param1) */
-#define     PCODE_MBOX_GT_STATE_MEDIA_BUSY     0x1
-#define     PCODE_MBOX_GT_STATE_MEDIA_NOT_BUSY 0x2
-/* param2 */
-#define     PCODE_MBOX_GT_STATE_DOMAIN_MEDIA   0x1
-
 #define GEN6_PCODE_DATA                                _MMIO(0x138128)
 #define   GEN6_PCODE_FREQ_IA_RATIO_SHIFT       8
 #define   GEN6_PCODE_FREQ_RING_RATIO_SHIFT     16
index 79bfe3938d3c6abfd6829f6435ab98167dcdc490..7caf937c3c90d6b7d74456d7f276871ec8527547 100644 (file)
@@ -325,23 +325,23 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
 
        ret = meson_encoder_hdmi_init(priv);
        if (ret)
-               goto exit_afbcd;
+               goto unbind_all;
 
        ret = meson_plane_create(priv);
        if (ret)
-               goto exit_afbcd;
+               goto unbind_all;
 
        ret = meson_overlay_create(priv);
        if (ret)
-               goto exit_afbcd;
+               goto unbind_all;
 
        ret = meson_crtc_create(priv);
        if (ret)
-               goto exit_afbcd;
+               goto unbind_all;
 
        ret = request_irq(priv->vsync_irq, meson_irq, 0, drm->driver->name, drm);
        if (ret)
-               goto exit_afbcd;
+               goto unbind_all;
 
        drm_mode_config_reset(drm);
 
@@ -359,6 +359,9 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
 
 uninstall_irq:
        free_irq(priv->vsync_irq, drm);
+unbind_all:
+       if (has_components)
+               component_unbind_all(drm->dev, drm);
 exit_afbcd:
        if (priv->afbcd.ops)
                priv->afbcd.ops->exit(priv);
index 534621a13a34d28140541e8d881dafb24f64a78a..3d046878ce6cb74f5a3662e795e091be9d7b4b75 100644 (file)
@@ -718,7 +718,7 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
        dw_plat_data = &meson_dw_hdmi->dw_plat_data;
 
        ret = devm_regulator_get_enable_optional(dev, "hdmi");
-       if (ret < 0)
+       if (ret < 0 && ret != -ENODEV)
                return ret;
 
        meson_dw_hdmi->hdmitx_apb = devm_reset_control_get_exclusive(dev,
index 154837688ab0d17b98f61d81918b99edb3441621..5df1957c8e41f4e438545f91dd9eecb423e53b91 100644 (file)
@@ -100,6 +100,8 @@ void meson_vpp_init(struct meson_drm *priv)
                               priv->io_base + _REG(VPP_DOLBY_CTRL));
                writel_relaxed(0x1020080,
                                priv->io_base + _REG(VPP_DUMMY_DATA1));
+               writel_relaxed(0x42020,
+                               priv->io_base + _REG(VPP_DUMMY_DATA));
        } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
                writel_relaxed(0xf, priv->io_base + _REG(DOLBY_PATH_CTRL));
 
index 871870ddf7ec1892ac260fc101804ac26fe03ac9..949b18a29a5540af3f327cd9466e55a09e3fb135 100644 (file)
@@ -23,7 +23,6 @@ config DRM_MSM
        select SHMEM
        select TMPFS
        select QCOM_SCM
-       select DEVFREQ_GOV_SIMPLE_ONDEMAND
        select WANT_DEV_COREDUMP
        select SND_SOC_HDMI_CODEC if SND_SOC
        select SYNC_FILE
index d09221f97f71c38f64b38b5fe12a55ddfb95bc64..a1e006ec5dcec2eaa5c72d34d06d31e4f0ba1308 100644 (file)
@@ -151,8 +151,8 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
        OUT_RING(ring, 1);
 
        /* Enable local preemption for finegrain preemption */
-       OUT_PKT7(ring, CP_PREEMPT_ENABLE_GLOBAL, 1);
-       OUT_RING(ring, 0x02);
+       OUT_PKT7(ring, CP_PREEMPT_ENABLE_LOCAL, 1);
+       OUT_RING(ring, 0x1);
 
        /* Allow CP_CONTEXT_SWITCH_YIELD packets in the IB2 */
        OUT_PKT7(ring, CP_YIELD_ENABLE, 1);
@@ -806,7 +806,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
        gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x0000003F);
 
        /* Set the highest bank bit */
-       if (adreno_is_a540(adreno_gpu))
+       if (adreno_is_a540(adreno_gpu) || adreno_is_a530(adreno_gpu))
                regbit = 2;
        else
                regbit = 1;
index 7658e89844b460bac2336a297844a05dc7ca94cb..f58dd564d122badde91a998b8f8f476849d533d5 100644 (file)
@@ -63,7 +63,7 @@ static struct msm_ringbuffer *get_next_ring(struct msm_gpu *gpu)
                struct msm_ringbuffer *ring = gpu->rb[i];
 
                spin_lock_irqsave(&ring->preempt_lock, flags);
-               empty = (get_wptr(ring) == ring->memptrs->rptr);
+               empty = (get_wptr(ring) == gpu->funcs->get_rptr(gpu, ring));
                spin_unlock_irqrestore(&ring->preempt_lock, flags);
 
                if (!empty)
@@ -207,6 +207,7 @@ void a5xx_preempt_hw_init(struct msm_gpu *gpu)
                a5xx_gpu->preempt[i]->wptr = 0;
                a5xx_gpu->preempt[i]->rptr = 0;
                a5xx_gpu->preempt[i]->rbase = gpu->rb[i]->iova;
+               a5xx_gpu->preempt[i]->rptr_addr = shadowptr(a5xx_gpu, gpu->rb[i]);
        }
 
        /* Write a 0 to signal that we aren't switching pagetables */
@@ -257,7 +258,6 @@ static int preempt_init_ring(struct a5xx_gpu *a5xx_gpu,
        ptr->data = 0;
        ptr->cntl = MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE;
 
-       ptr->rptr_addr = shadowptr(a5xx_gpu, ring);
        ptr->counter = counters_iova;
 
        return 0;
index f3c9600221d48c0a0551e4ecf86b57b5f391f763..7f5bc73b204024944b302c6c34c0a6e48de9c6ae 100644 (file)
@@ -974,7 +974,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
        int status, ret;
 
        if (WARN(!gmu->initialized, "The GMU is not set up yet\n"))
-               return 0;
+               return -EINVAL;
 
        gmu->hung = false;
 
index aae60cbd9164d347a3693186f2eda5f29c7749df..6faea5049f765dd64c2c895a48f2822fe9e21247 100644 (file)
@@ -1746,7 +1746,9 @@ static void a6xx_destroy(struct msm_gpu *gpu)
 
        a6xx_llc_slices_destroy(a6xx_gpu);
 
+       mutex_lock(&a6xx_gpu->gmu.lock);
        a6xx_gmu_remove(a6xx_gpu);
+       mutex_unlock(&a6xx_gpu->gmu.lock);
 
        adreno_gpu_cleanup(adreno_gpu);
 
index 36f062c7582f9a8ec7b7b54c6a3e8abb1804252a..c5c4c93b3689c0e9bc9b3928a88c3e0497d07620 100644 (file)
@@ -558,7 +558,8 @@ static void adreno_unbind(struct device *dev, struct device *master,
        struct msm_drm_private *priv = dev_get_drvdata(master);
        struct msm_gpu *gpu = dev_to_gpu(dev);
 
-       WARN_ON_ONCE(adreno_system_suspend(dev));
+       if (pm_runtime_enabled(dev))
+               WARN_ON_ONCE(adreno_system_suspend(dev));
        gpu->funcs->destroy(gpu);
 
        priv->gpu_pdev = NULL;
index cf053e8f081e9ecd9aa32ce94fa862b5b7a2d870..497c9e1673abbb842492e19b4233f0da1d9e3940 100644 (file)
 #include "dpu_hw_catalog.h"
 #include "dpu_kms.h"
 
-#define VIG_MASK \
+#define VIG_BASE_MASK \
        (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\
-       BIT(DPU_SSPP_CSC_10BIT) | BIT(DPU_SSPP_CDP) |\
+       BIT(DPU_SSPP_CDP) |\
        BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_EXCL_RECT))
 
+#define VIG_MASK \
+       (VIG_BASE_MASK | \
+       BIT(DPU_SSPP_CSC_10BIT))
+
 #define VIG_MSM8998_MASK \
        (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
 
 #define VIG_SC7180_MASK \
        (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4))
 
-#define VIG_SM8250_MASK \
-       (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE))
-
-#define VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
+#define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL))
 
 #define DMA_MSM8998_MASK \
        (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\
@@ -51,7 +52,7 @@
        (DMA_MSM8998_MASK | BIT(DPU_SSPP_CURSOR))
 
 #define MIXER_MSM8998_MASK \
-       (BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER))
+       (BIT(DPU_MIXER_SOURCESPLIT))
 
 #define MIXER_SDM845_MASK \
        (BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA))
@@ -314,10 +315,9 @@ static const struct dpu_caps msm8998_dpu_caps = {
 };
 
 static const struct dpu_caps qcm2290_dpu_caps = {
-       .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+       .max_mixer_width = DEFAULT_DPU_LINE_WIDTH,
        .max_mixer_blendstages = 0x4,
        .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
-       .ubwc_version = DPU_HW_UBWC_VER_20,
        .has_dim_layer = true,
        .has_idle_pc = true,
        .max_linewidth = 2160,
@@ -353,9 +353,9 @@ static const struct dpu_caps sc7180_dpu_caps = {
 };
 
 static const struct dpu_caps sm6115_dpu_caps = {
-       .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+       .max_mixer_width = DEFAULT_DPU_LINE_WIDTH,
        .max_mixer_blendstages = 0x4,
-       .qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
+       .qseed_type = DPU_SSPP_SCALER_QSEED4,
        .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
        .ubwc_version = DPU_HW_UBWC_VER_10,
        .has_dim_layer = true,
@@ -399,7 +399,7 @@ static const struct dpu_caps sc8180x_dpu_caps = {
 static const struct dpu_caps sc8280xp_dpu_caps = {
        .max_mixer_width = 2560,
        .max_mixer_blendstages = 11,
-       .qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
+       .qseed_type = DPU_SSPP_SCALER_QSEED4,
        .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
        .ubwc_version = DPU_HW_UBWC_VER_40,
        .has_src_split = true,
@@ -413,7 +413,7 @@ static const struct dpu_caps sc8280xp_dpu_caps = {
 static const struct dpu_caps sm8250_dpu_caps = {
        .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
        .max_mixer_blendstages = 0xb,
-       .qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
+       .qseed_type = DPU_SSPP_SCALER_QSEED4,
        .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
        .ubwc_version = DPU_HW_UBWC_VER_40,
        .has_src_split = true,
@@ -427,7 +427,7 @@ static const struct dpu_caps sm8250_dpu_caps = {
 static const struct dpu_caps sm8350_dpu_caps = {
        .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
        .max_mixer_blendstages = 0xb,
-       .qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
+       .qseed_type = DPU_SSPP_SCALER_QSEED4,
        .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
        .ubwc_version = DPU_HW_UBWC_VER_40,
        .has_src_split = true,
@@ -455,7 +455,7 @@ static const struct dpu_caps sm8450_dpu_caps = {
 static const struct dpu_caps sm8550_dpu_caps = {
        .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
        .max_mixer_blendstages = 0xb,
-       .qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
+       .qseed_type = DPU_SSPP_SCALER_QSEED4,
        .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
        .ubwc_version = DPU_HW_UBWC_VER_40,
        .has_src_split = true,
@@ -525,9 +525,9 @@ static const struct dpu_mdp_cfg sdm845_mdp[] = {
                        .reg_off = 0x2AC, .bit_off = 8},
        .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
                        .reg_off = 0x2B4, .bit_off = 8},
-       .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
+       .clk_ctrls[DPU_CLK_CTRL_DMA2] = {
                        .reg_off = 0x2BC, .bit_off = 8},
-       .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
+       .clk_ctrls[DPU_CLK_CTRL_DMA3] = {
                        .reg_off = 0x2C4, .bit_off = 8},
        },
 };
@@ -542,9 +542,9 @@ static const struct dpu_mdp_cfg sc7180_mdp[] = {
                .reg_off = 0x2AC, .bit_off = 0},
        .clk_ctrls[DPU_CLK_CTRL_DMA0] = {
                .reg_off = 0x2AC, .bit_off = 8},
-       .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
+       .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
                .reg_off = 0x2B4, .bit_off = 8},
-       .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
+       .clk_ctrls[DPU_CLK_CTRL_DMA2] = {
                .reg_off = 0x2C4, .bit_off = 8},
        .clk_ctrls[DPU_CLK_CTRL_WB2] = {
                .reg_off = 0x3B8, .bit_off = 24},
@@ -569,9 +569,9 @@ static const struct dpu_mdp_cfg sc8180x_mdp[] = {
                        .reg_off = 0x2AC, .bit_off = 8},
        .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
                        .reg_off = 0x2B4, .bit_off = 8},
-       .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
+       .clk_ctrls[DPU_CLK_CTRL_DMA2] = {
                        .reg_off = 0x2BC, .bit_off = 8},
-       .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
+       .clk_ctrls[DPU_CLK_CTRL_DMA3] = {
                        .reg_off = 0x2C4, .bit_off = 8},
        },
 };
@@ -609,9 +609,9 @@ static const struct dpu_mdp_cfg sm8250_mdp[] = {
                        .reg_off = 0x2AC, .bit_off = 8},
        .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
                        .reg_off = 0x2B4, .bit_off = 8},
-       .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
+       .clk_ctrls[DPU_CLK_CTRL_DMA2] = {
                        .reg_off = 0x2BC, .bit_off = 8},
-       .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
+       .clk_ctrls[DPU_CLK_CTRL_DMA3] = {
                        .reg_off = 0x2C4, .bit_off = 8},
        .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = {
                        .reg_off = 0x2BC, .bit_off = 20},
@@ -638,9 +638,9 @@ static const struct dpu_mdp_cfg sm8350_mdp[] = {
                        .reg_off = 0x2ac, .bit_off = 8},
        .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
                        .reg_off = 0x2b4, .bit_off = 8},
-       .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
+       .clk_ctrls[DPU_CLK_CTRL_DMA2] = {
                        .reg_off = 0x2bc, .bit_off = 8},
-       .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
+       .clk_ctrls[DPU_CLK_CTRL_DMA3] = {
                        .reg_off = 0x2c4, .bit_off = 8},
        .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = {
                        .reg_off = 0x2bc, .bit_off = 20},
@@ -666,9 +666,9 @@ static const struct dpu_mdp_cfg sm8450_mdp[] = {
                        .reg_off = 0x2AC, .bit_off = 8},
        .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
                        .reg_off = 0x2B4, .bit_off = 8},
-       .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
+       .clk_ctrls[DPU_CLK_CTRL_DMA2] = {
                        .reg_off = 0x2BC, .bit_off = 8},
-       .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
+       .clk_ctrls[DPU_CLK_CTRL_DMA3] = {
                        .reg_off = 0x2C4, .bit_off = 8},
        .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = {
                        .reg_off = 0x2BC, .bit_off = 20},
@@ -685,9 +685,9 @@ static const struct dpu_mdp_cfg sc7280_mdp[] = {
                .reg_off = 0x2AC, .bit_off = 0},
        .clk_ctrls[DPU_CLK_CTRL_DMA0] = {
                .reg_off = 0x2AC, .bit_off = 8},
-       .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
+       .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
                .reg_off = 0x2B4, .bit_off = 8},
-       .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
+       .clk_ctrls[DPU_CLK_CTRL_DMA2] = {
                .reg_off = 0x2C4, .bit_off = 8},
        },
 };
@@ -696,7 +696,7 @@ static const struct dpu_mdp_cfg sc8280xp_mdp[] = {
        {
        .name = "top_0", .id = MDP_TOP,
        .base = 0x0, .len = 0x494,
-       .features = 0,
+       .features = BIT(DPU_MDP_PERIPH_0_REMOVED),
        .highest_bank_bit = 2,
        .ubwc_swizzle = 6,
        .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0},
@@ -705,8 +705,8 @@ static const struct dpu_mdp_cfg sc8280xp_mdp[] = {
        .clk_ctrls[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0},
        .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8},
        .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8},
-       .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = { .reg_off = 0x2bc, .bit_off = 8},
-       .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = { .reg_off = 0x2c4, .bit_off = 8},
+       .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8},
+       .clk_ctrls[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8},
        .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20},
        },
 };
@@ -734,9 +734,9 @@ static const struct dpu_mdp_cfg sm8550_mdp[] = {
                        .reg_off = 0x28330, .bit_off = 0},
        .clk_ctrls[DPU_CLK_CTRL_DMA3] = {
                        .reg_off = 0x2a330, .bit_off = 0},
-       .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
+       .clk_ctrls[DPU_CLK_CTRL_DMA4] = {
                        .reg_off = 0x2c330, .bit_off = 0},
-       .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
+       .clk_ctrls[DPU_CLK_CTRL_DMA5] = {
                        .reg_off = 0x2e330, .bit_off = 0},
        .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = {
                        .reg_off = 0x2bc, .bit_off = 20},
@@ -828,19 +828,19 @@ static const struct dpu_ctl_cfg sdm845_ctl[] = {
 static const struct dpu_ctl_cfg sc7180_ctl[] = {
        {
        .name = "ctl_0", .id = CTL_0,
-       .base = 0x1000, .len = 0xE4,
+       .base = 0x1000, .len = 0x1dc,
        .features = BIT(DPU_CTL_ACTIVE_CFG),
        .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
        },
        {
        .name = "ctl_1", .id = CTL_1,
-       .base = 0x1200, .len = 0xE4,
+       .base = 0x1200, .len = 0x1dc,
        .features = BIT(DPU_CTL_ACTIVE_CFG),
        .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
        },
        {
        .name = "ctl_2", .id = CTL_2,
-       .base = 0x1400, .len = 0xE4,
+       .base = 0x1400, .len = 0x1dc,
        .features = BIT(DPU_CTL_ACTIVE_CFG),
        .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
        },
@@ -1190,9 +1190,9 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = {
        SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000,  DMA_MSM8998_MASK,
                sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
        SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000,  DMA_CURSOR_MSM8998_MASK,
-               sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
+               sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
        SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000,  DMA_CURSOR_MSM8998_MASK,
-               sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
+               sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3),
 };
 
 static const struct dpu_sspp_cfg sdm845_sspp[] = {
@@ -1209,9 +1209,9 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = {
        SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000,  DMA_SDM845_MASK,
                sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
        SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000,  DMA_CURSOR_SDM845_MASK,
-               sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
+               sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
        SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000,  DMA_CURSOR_SDM845_MASK,
-               sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
+               sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3),
 };
 
 static const struct dpu_sspp_sub_blks sc7180_vig_sblk_0 =
@@ -1226,57 +1226,57 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = {
        SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_SDM845_MASK,
                sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
        SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000,  DMA_CURSOR_SDM845_MASK,
-               sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
+               sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
        SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000,  DMA_CURSOR_SDM845_MASK,
-               sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
+               sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
 };
 
 static const struct dpu_sspp_sub_blks sm6115_vig_sblk_0 =
-                               _VIG_SBLK("0", 2, DPU_SSPP_SCALER_QSEED3LITE);
+                               _VIG_SBLK("0", 2, DPU_SSPP_SCALER_QSEED4);
 
 static const struct dpu_sspp_cfg sm6115_sspp[] = {
-       SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SM8250_MASK,
+       SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK,
                sm6115_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
        SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_SDM845_MASK,
                sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
 };
 
 static const struct dpu_sspp_sub_blks sm8250_vig_sblk_0 =
-                               _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3LITE);
+                               _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED4);
 static const struct dpu_sspp_sub_blks sm8250_vig_sblk_1 =
-                               _VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED3LITE);
+                               _VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED4);
 static const struct dpu_sspp_sub_blks sm8250_vig_sblk_2 =
-                               _VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED3LITE);
+                               _VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED4);
 static const struct dpu_sspp_sub_blks sm8250_vig_sblk_3 =
-                               _VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED3LITE);
+                               _VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED4);
 
 static const struct dpu_sspp_cfg sm8250_sspp[] = {
-       SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SM8250_MASK,
+       SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK,
                sm8250_vig_sblk_0, 0,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
-       SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SM8250_MASK,
+       SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SC7180_MASK,
                sm8250_vig_sblk_1, 4,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
-       SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SM8250_MASK,
+       SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SC7180_MASK,
                sm8250_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
-       SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SM8250_MASK,
+       SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SC7180_MASK,
                sm8250_vig_sblk_3, 12,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
        SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_SDM845_MASK,
                sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
        SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000,  DMA_SDM845_MASK,
                sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
        SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000,  DMA_CURSOR_SDM845_MASK,
-               sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
+               sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
        SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000,  DMA_CURSOR_SDM845_MASK,
-               sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
+               sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3),
 };
 
 static const struct dpu_sspp_sub_blks sm8450_vig_sblk_0 =
-                               _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3LITE);
+                               _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED4);
 static const struct dpu_sspp_sub_blks sm8450_vig_sblk_1 =
-                               _VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED3LITE);
+                               _VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED4);
 static const struct dpu_sspp_sub_blks sm8450_vig_sblk_2 =
-                               _VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED3LITE);
+                               _VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED4);
 static const struct dpu_sspp_sub_blks sm8450_vig_sblk_3 =
-                               _VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED3LITE);
+                               _VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED4);
 
 static const struct dpu_sspp_cfg sm8450_sspp[] = {
        SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK,
@@ -1292,21 +1292,21 @@ static const struct dpu_sspp_cfg sm8450_sspp[] = {
        SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000,  DMA_SDM845_MASK,
                sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
        SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000,  DMA_CURSOR_SDM845_MASK,
-               sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
+               sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
        SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000,  DMA_CURSOR_SDM845_MASK,
-               sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
+               sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3),
 };
 
 static const struct dpu_sspp_sub_blks sm8550_vig_sblk_0 =
-                               _VIG_SBLK("0", 7, DPU_SSPP_SCALER_QSEED3LITE);
+                               _VIG_SBLK("0", 7, DPU_SSPP_SCALER_QSEED4);
 static const struct dpu_sspp_sub_blks sm8550_vig_sblk_1 =
-                               _VIG_SBLK("1", 8, DPU_SSPP_SCALER_QSEED3LITE);
+                               _VIG_SBLK("1", 8, DPU_SSPP_SCALER_QSEED4);
 static const struct dpu_sspp_sub_blks sm8550_vig_sblk_2 =
-                               _VIG_SBLK("2", 9, DPU_SSPP_SCALER_QSEED3LITE);
+                               _VIG_SBLK("2", 9, DPU_SSPP_SCALER_QSEED4);
 static const struct dpu_sspp_sub_blks sm8550_vig_sblk_3 =
-                               _VIG_SBLK("3", 10, DPU_SSPP_SCALER_QSEED3LITE);
+                               _VIG_SBLK("3", 10, DPU_SSPP_SCALER_QSEED4);
 static const struct dpu_sspp_sub_blks sm8550_dma_sblk_4 = _DMA_SBLK("12", 5);
-static const struct dpu_sspp_sub_blks sd8550_dma_sblk_5 = _DMA_SBLK("13", 6);
+static const struct dpu_sspp_sub_blks sm8550_dma_sblk_5 = _DMA_SBLK("13", 6);
 
 static const struct dpu_sspp_cfg sm8550_sspp[] = {
        SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK,
@@ -1326,9 +1326,9 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
        SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000,  DMA_SDM845_MASK,
                sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3),
        SSPP_BLK("sspp_12", SSPP_DMA4, 0x2c000,  DMA_CURSOR_SDM845_MASK,
-               sm8550_dma_sblk_4, 14, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
+               sm8550_dma_sblk_4, 14, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA4),
        SSPP_BLK("sspp_13", SSPP_DMA5, 0x2e000,  DMA_CURSOR_SDM845_MASK,
-               sd8550_dma_sblk_5, 15, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
+               sm8550_dma_sblk_5, 15, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA5),
 };
 
 static const struct dpu_sspp_cfg sc7280_sspp[] = {
@@ -1337,37 +1337,37 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = {
        SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_SDM845_MASK,
                sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
        SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000,  DMA_CURSOR_SDM845_MASK,
-               sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
+               sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
        SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000,  DMA_CURSOR_SDM845_MASK,
-               sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
+               sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
 };
 
 static const struct dpu_sspp_sub_blks sc8280xp_vig_sblk_0 =
-                               _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3LITE);
+                               _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED4);
 static const struct dpu_sspp_sub_blks sc8280xp_vig_sblk_1 =
-                               _VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED3LITE);
+                               _VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED4);
 static const struct dpu_sspp_sub_blks sc8280xp_vig_sblk_2 =
-                               _VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED3LITE);
+                               _VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED4);
 static const struct dpu_sspp_sub_blks sc8280xp_vig_sblk_3 =
-                               _VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED3LITE);
+                               _VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED4);
 
 static const struct dpu_sspp_cfg sc8280xp_sspp[] = {
-       SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SM8250_MASK,
+       SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK,
                 sc8280xp_vig_sblk_0, 0,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
-       SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SM8250_MASK,
+       SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SC7180_MASK,
                 sc8280xp_vig_sblk_1, 4,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
-       SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SM8250_MASK,
+       SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SC7180_MASK,
                 sc8280xp_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
-       SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SM8250_MASK,
+       SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SC7180_MASK,
                 sc8280xp_vig_sblk_3, 12,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
        SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK,
                 sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
        SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK,
                 sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
        SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK,
-                sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
+                sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
        SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_SDM845_MASK,
-                sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
+                sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3),
 };
 
 #define _VIG_SBLK_NOSCALE(num, sdma_pri) \
@@ -1517,7 +1517,7 @@ static const struct dpu_lm_cfg sc7280_lm[] = {
 /* QCM2290 */
 
 static const struct dpu_lm_sub_blks qcm2290_lm_sblk = {
-       .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+       .maxwidth = DEFAULT_DPU_LINE_WIDTH,
        .maxblendstages = 4, /* excluding base layer */
        .blendstage_base = { /* offsets relative to mixer base */
                0x20, 0x38, 0x50, 0x68
@@ -1714,7 +1714,7 @@ static const struct dpu_pingpong_cfg sm8350_pp[] = {
 };
 
 static const struct dpu_pingpong_cfg sc7280_pp[] = {
-       PP_BLK("pingpong_0", PINGPONG_0, 0x59000, 0, sc7280_pp_sblk, -1, -1),
+       PP_BLK("pingpong_0", PINGPONG_0, 0x69000, 0, sc7280_pp_sblk, -1, -1),
        PP_BLK("pingpong_1", PINGPONG_1, 0x6a000, 0, sc7280_pp_sblk, -1, -1),
        PP_BLK("pingpong_2", PINGPONG_2, 0x6b000, 0, sc7280_pp_sblk, -1, -1),
        PP_BLK("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, -1, -1),
@@ -2841,8 +2841,6 @@ static const struct dpu_mdss_cfg qcm2290_dpu_cfg = {
        .intf = qcm2290_intf,
        .vbif_count = ARRAY_SIZE(sdm845_vbif),
        .vbif = sdm845_vbif,
-       .reg_dma_count = 1,
-       .dma_cfg = &sdm845_regdma,
        .perf = &qcm2290_perf_data,
        .mdss_irqs = IRQ_SC7180_MASK,
 };
index ddab9caebb18c40d4d30e7b08ea03a53face758a..e6590302b3bfc0e29d51645c5530c04d6ee42bec 100644 (file)
@@ -515,6 +515,8 @@ enum dpu_clk_ctrl_type {
        DPU_CLK_CTRL_DMA1,
        DPU_CLK_CTRL_DMA2,
        DPU_CLK_CTRL_DMA3,
+       DPU_CLK_CTRL_DMA4,
+       DPU_CLK_CTRL_DMA5,
        DPU_CLK_CTRL_CURSOR0,
        DPU_CLK_CTRL_CURSOR1,
        DPU_CLK_CTRL_INLINE_ROT0_SSPP,
index b88a2f3724e6dd491ab29ce661e7b877cfd82798..6c53ea560ffaa734ace47fb28798dc9c6168ae0e 100644 (file)
@@ -446,7 +446,9 @@ static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
                         * CTL_LAYER has 3-bit field (and extra bits in EXT register),
                         * all EXT registers has 4-bit fields.
                         */
-                       if (cfg->idx == 0) {
+                       if (cfg->idx == -1) {
+                               continue;
+                       } else if (cfg->idx == 0) {
                                mixercfg[0] |= mix << cfg->shift;
                                mixercfg[1] |= ext << cfg->ext_shift;
                        } else {
index 396429e63756b5e82dc42f0e69587a54ea136000..66c1b70d244fcb3ca91d511cb8baa039c8b0793b 100644 (file)
@@ -577,6 +577,8 @@ void dpu_rm_release(struct dpu_global_state *global_state,
                ARRAY_SIZE(global_state->ctl_to_enc_id), enc->base.id);
        _dpu_rm_clear_mapping(global_state->dsc_to_enc_id,
                ARRAY_SIZE(global_state->dsc_to_enc_id), enc->base.id);
+       _dpu_rm_clear_mapping(global_state->dspp_to_enc_id,
+               ARRAY_SIZE(global_state->dspp_to_enc_id), enc->base.id);
 }
 
 int dpu_rm_reserve(
index 051bdbc093cf99657b44671a12a317fcd5fefd96..f38296ad87434eca9aead0f47b47d0c4bcc896cf 100644 (file)
@@ -107,6 +107,7 @@ msm_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)
                bool (*shrink)(struct drm_gem_object *obj);
                bool cond;
                unsigned long freed;
+               unsigned long remaining;
        } stages[] = {
                /* Stages of progressively more aggressive/expensive reclaim: */
                { &priv->lru.dontneed, purge,        true },
@@ -116,14 +117,18 @@ msm_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)
        };
        long nr = sc->nr_to_scan;
        unsigned long freed = 0;
+       unsigned long remaining = 0;
 
        for (unsigned i = 0; (nr > 0) && (i < ARRAY_SIZE(stages)); i++) {
                if (!stages[i].cond)
                        continue;
                stages[i].freed =
-                       drm_gem_lru_scan(stages[i].lru, nr, stages[i].shrink);
+                       drm_gem_lru_scan(stages[i].lru, nr,
+                                       &stages[i].remaining,
+                                        stages[i].shrink);
                nr -= stages[i].freed;
                freed += stages[i].freed;
+               remaining += stages[i].remaining;
        }
 
        if (freed) {
@@ -132,7 +137,7 @@ msm_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)
                                     stages[3].freed);
        }
 
-       return (freed > 0) ? freed : SHRINK_STOP;
+       return (freed > 0 && remaining > 0) ? freed : SHRINK_STOP;
 }
 
 #ifdef CONFIG_DEBUG_FS
@@ -182,10 +187,12 @@ msm_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr)
                NULL,
        };
        unsigned idx, unmapped = 0;
+       unsigned long remaining = 0;
 
        for (idx = 0; lrus[idx] && unmapped < vmap_shrink_limit; idx++) {
                unmapped += drm_gem_lru_scan(lrus[idx],
                                             vmap_shrink_limit - unmapped,
+                                            &remaining,
                                             vmap_shrink);
        }
 
index be4bf77103cd753adadcd10584250fc85b55c9df..ac8ed731f76d9007bdaf97df6cb163aa703dbe92 100644 (file)
@@ -637,8 +637,8 @@ static struct msm_submit_post_dep *msm_parse_post_deps(struct drm_device *dev,
        int ret = 0;
        uint32_t i, j;
 
-       post_deps = kmalloc_array(nr_syncobjs, sizeof(*post_deps),
-                                 GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
+       post_deps = kcalloc(nr_syncobjs, sizeof(*post_deps),
+                           GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
        if (!post_deps)
                return ERR_PTR(-ENOMEM);
 
@@ -653,7 +653,6 @@ static struct msm_submit_post_dep *msm_parse_post_deps(struct drm_device *dev,
                }
 
                post_deps[i].point = syncobj_desc.point;
-               post_deps[i].chain = NULL;
 
                if (syncobj_desc.flags) {
                        ret = -EINVAL;
index ed9d374147b8d11614c3c175f1b659b82607b56c..5bb777ff13130853e9742fefb4e58a44f97356a5 100644 (file)
@@ -363,6 +363,35 @@ nv50_outp_atomic_check_view(struct drm_encoder *encoder,
        return 0;
 }
 
+static void
+nv50_outp_atomic_fix_depth(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state)
+{
+       struct nv50_head_atom *asyh = nv50_head_atom(crtc_state);
+       struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+       struct drm_display_mode *mode = &asyh->state.adjusted_mode;
+       unsigned int max_rate, mode_rate;
+
+       switch (nv_encoder->dcb->type) {
+       case DCB_OUTPUT_DP:
+               max_rate = nv_encoder->dp.link_nr * nv_encoder->dp.link_bw;
+
+               /* we don't support more than 10 anyway */
+               asyh->or.bpc = min_t(u8, asyh->or.bpc, 10);
+
+               /* reduce the bpc until it works out */
+               while (asyh->or.bpc > 6) {
+                       mode_rate = DIV_ROUND_UP(mode->clock * asyh->or.bpc * 3, 8);
+                       if (mode_rate <= max_rate)
+                               break;
+
+                       asyh->or.bpc -= 2;
+               }
+               break;
+       default:
+               break;
+       }
+}
+
 static int
 nv50_outp_atomic_check(struct drm_encoder *encoder,
                       struct drm_crtc_state *crtc_state,
@@ -381,6 +410,9 @@ nv50_outp_atomic_check(struct drm_encoder *encoder,
        if (crtc_state->mode_changed || crtc_state->connectors_changed)
                asyh->or.bpc = connector->display_info.bpc;
 
+       /* We might have to reduce the bpc */
+       nv50_outp_atomic_fix_depth(encoder, crtc_state);
+
        return 0;
 }
 
index 591c852f326b92c97ea862c3bb6ecae6400a37e6..76a6ae5d565268c50bde978b4fc45f1eded04e58 100644 (file)
@@ -35,8 +35,9 @@ struct nv50_wndw {
 
 int nv50_wndw_new_(const struct nv50_wndw_func *, struct drm_device *,
                   enum drm_plane_type, const char *name, int index,
-                  const u32 *format, enum nv50_disp_interlock_type,
-                  u32 interlock_data, u32 heads, struct nv50_wndw **);
+                  const u32 *format, u32 heads,
+                  enum nv50_disp_interlock_type, u32 interlock_data,
+                  struct nv50_wndw **);
 void nv50_wndw_flush_set(struct nv50_wndw *, u32 *interlock,
                         struct nv50_wndw_atom *);
 void nv50_wndw_flush_clr(struct nv50_wndw *, u32 *interlock, bool flush,
index c5a4f49ee2065416137af9fc64180b1b4ce9e570..01a22a13b452047425a63914cad7f2f081c8d37b 100644 (file)
@@ -2,6 +2,7 @@
 #ifndef __NVKM_FB_H__
 #define __NVKM_FB_H__
 #include <core/subdev.h>
+#include <core/falcon.h>
 #include <core/mm.h>
 
 /* memory type/access flags, do not match hardware values */
@@ -33,7 +34,7 @@ struct nvkm_fb {
        const struct nvkm_fb_func *func;
        struct nvkm_subdev subdev;
 
-       struct nvkm_blob vpr_scrubber;
+       struct nvkm_falcon_fw vpr_scrubber;
 
        struct {
                struct page *flush_page;
index 40409a29f5b69cb8dad01d136de0f6b85fed11e7..91b5ecc57538083f7be573fbc25ec3a91ce0c9dd 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/apple-gmux.h>
 #include <linux/backlight.h>
 #include <linux/idr.h>
+#include <drm/drm_probe_helper.h>
 
 #include "nouveau_drv.h"
 #include "nouveau_reg.h"
@@ -299,8 +300,12 @@ nv50_backlight_init(struct nouveau_backlight *bl,
        struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
        struct nvif_object *device = &drm->client.device.object;
 
+       /*
+        * Note when this runs the connectors have not been probed yet,
+        * so nv_conn->base.status is not set yet.
+        */
        if (!nvif_rd32(device, NV50_PDISP_SOR_PWM_CTL(ffs(nv_encoder->dcb->or) - 1)) ||
-           nv_conn->base.status != connector_status_connected)
+           drm_helper_probe_detect(&nv_conn->base, NULL, false) != connector_status_connected)
                return -ENODEV;
 
        if (nv_conn->type == DCB_CONNECTOR_eDP) {
index e00876f92aeea582c13642664b4774cf4c5726c8..d49b4875fc3c934fe4d6cd87c0d3b1b3b997088f 100644 (file)
@@ -263,8 +263,6 @@ nouveau_dp_irq(struct work_struct *work)
 }
 
 /* TODO:
- * - Use the minimum possible BPC here, once we add support for the max bpc
- *   property.
  * - Validate against the DP caps advertised by the GPU (we don't check these
  *   yet)
  */
@@ -276,7 +274,11 @@ nv50_dp_mode_valid(struct drm_connector *connector,
 {
        const unsigned int min_clock = 25000;
        unsigned int max_rate, mode_rate, ds_max_dotclock, clock = mode->clock;
-       const u8 bpp = connector->display_info.bpc * 3;
+       /* Check with the minmum bpc always, so we can advertise better modes.
+        * In particlar not doing this causes modes to be dropped on HDR
+        * displays as we might check with a bpc of 16 even.
+        */
+       const u8 bpp = 6 * 3;
 
        if (mode->flags & DRM_MODE_FLAG_INTERLACE && !outp->caps.dp_interlace)
                return MODE_NO_INTERLACE;
index f77e44958037e02459940f3d9413a957e391b293..ab9062e5097770be99ff6fefc7f6faddc9085738 100644 (file)
@@ -645,7 +645,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
                                struct drm_nouveau_gem_pushbuf_reloc *reloc,
                                struct drm_nouveau_gem_pushbuf_bo *bo)
 {
-       long ret = 0;
+       int ret = 0;
        unsigned i;
 
        for (i = 0; i < req->nr_relocs; i++) {
@@ -653,6 +653,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
                struct drm_nouveau_gem_pushbuf_bo *b;
                struct nouveau_bo *nvbo;
                uint32_t data;
+               long lret;
 
                if (unlikely(r->bo_index >= req->nr_buffers)) {
                        NV_PRINTK(err, cli, "reloc bo index invalid\n");
@@ -703,13 +704,18 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
                                data |= r->vor;
                }
 
-               ret = dma_resv_wait_timeout(nvbo->bo.base.resv,
-                                           DMA_RESV_USAGE_BOOKKEEP,
-                                           false, 15 * HZ);
-               if (ret == 0)
+               lret = dma_resv_wait_timeout(nvbo->bo.base.resv,
+                                            DMA_RESV_USAGE_BOOKKEEP,
+                                            false, 15 * HZ);
+               if (!lret)
                        ret = -EBUSY;
+               else if (lret > 0)
+                       ret = 0;
+               else
+                       ret = lret;
+
                if (ret) {
-                       NV_PRINTK(err, cli, "reloc wait_idle failed: %ld\n",
+                       NV_PRINTK(err, cli, "reloc wait_idle failed: %d\n",
                                  ret);
                        break;
                }
index bac7dcc4c2c1308fc36c3ea2b5ef5ef3351ce4d4..0955340cc421898625fa06d33dfb3a34658d17a1 100644 (file)
@@ -143,6 +143,10 @@ nvkm_fb_mem_unlock(struct nvkm_fb *fb)
        if (!fb->func->vpr.scrub_required)
                return 0;
 
+       ret = nvkm_subdev_oneinit(subdev);
+       if (ret)
+               return ret;
+
        if (!fb->func->vpr.scrub_required(fb)) {
                nvkm_debug(subdev, "VPR not locked\n");
                return 0;
@@ -150,7 +154,7 @@ nvkm_fb_mem_unlock(struct nvkm_fb *fb)
 
        nvkm_debug(subdev, "VPR locked, running scrubber binary\n");
 
-       if (!fb->vpr_scrubber.size) {
+       if (!fb->vpr_scrubber.fw.img) {
                nvkm_warn(subdev, "VPR locked, but no scrubber binary!\n");
                return 0;
        }
@@ -229,7 +233,7 @@ nvkm_fb_dtor(struct nvkm_subdev *subdev)
 
        nvkm_ram_del(&fb->ram);
 
-       nvkm_blob_dtor(&fb->vpr_scrubber);
+       nvkm_falcon_fw_dtor(&fb->vpr_scrubber);
 
        if (fb->sysmem.flush_page) {
                dma_unmap_page(subdev->device->dev, fb->sysmem.flush_page_addr,
index 5098f219e3e6f86b6c1ad2a284f99d34e0125edb..a7456e7864636978b0fad6da210ce1e4a201a1ce 100644 (file)
@@ -37,5 +37,5 @@ ga100_fb = {
 int
 ga100_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
 {
-       return gp102_fb_new_(&ga100_fb, device, type, inst, pfb);
+       return gf100_fb_new_(&ga100_fb, device, type, inst, pfb);
 }
index 5a21b0ae459580b1318727e00e1432a94f1abbeb..dd476e079fe1cbf0c0abb876585de69d60c9f36a 100644 (file)
 #include <engine/nvdec.h>
 
 static int
-ga102_fb_vpr_scrub(struct nvkm_fb *fb)
+ga102_fb_oneinit(struct nvkm_fb *fb)
 {
-       struct nvkm_falcon_fw fw = {};
-       int ret;
+       struct nvkm_subdev *subdev = &fb->subdev;
 
-       ret = nvkm_falcon_fw_ctor_hs_v2(&ga102_flcn_fw, "mem-unlock", &fb->subdev, "nvdec/scrubber",
-                                       0, &fb->subdev.device->nvdec[0]->falcon, &fw);
-       if (ret)
-               return ret;
+       nvkm_falcon_fw_ctor_hs_v2(&ga102_flcn_fw, "mem-unlock", subdev, "nvdec/scrubber",
+                                 0, &subdev->device->nvdec[0]->falcon, &fb->vpr_scrubber);
 
-       ret = nvkm_falcon_fw_boot(&fw, &fb->subdev, true, NULL, NULL, 0, 0);
-       nvkm_falcon_fw_dtor(&fw);
-       return ret;
+       return gf100_fb_oneinit(fb);
 }
 
 static const struct nvkm_fb_func
 ga102_fb = {
        .dtor = gf100_fb_dtor,
-       .oneinit = gf100_fb_oneinit,
+       .oneinit = ga102_fb_oneinit,
        .init = gm200_fb_init,
        .init_page = gv100_fb_init_page,
        .init_unkn = gp100_fb_init_unkn,
@@ -51,13 +46,13 @@ ga102_fb = {
        .ram_new = ga102_ram_new,
        .default_bigpage = 16,
        .vpr.scrub_required = tu102_fb_vpr_scrub_required,
-       .vpr.scrub = ga102_fb_vpr_scrub,
+       .vpr.scrub = gp102_fb_vpr_scrub,
 };
 
 int
 ga102_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
 {
-       return gp102_fb_new_(&ga102_fb, device, type, inst, pfb);
+       return gf100_fb_new_(&ga102_fb, device, type, inst, pfb);
 }
 
 MODULE_FIRMWARE("nvidia/ga102/nvdec/scrubber.bin");
index 76678dd60f93f9fd7373615776d73266abbe7344..c4c6f67af7ccc817a48e6dd84d3faee7d3c45e05 100644 (file)
@@ -31,6 +31,7 @@ gf108_fb = {
        .init = gf100_fb_init,
        .init_page = gf100_fb_init_page,
        .intr = gf100_fb_intr,
+       .sysmem.flush_page_init = gf100_fb_sysmem_flush_page_init,
        .ram_new = gf108_ram_new,
        .default_bigpage = 17,
 };
index f73442ccb424b491461054cb30abe87aaf6f8520..433fa966ba2319119d1140eb7cba2d7e02cc7483 100644 (file)
@@ -77,6 +77,7 @@ gk104_fb = {
        .init = gf100_fb_init,
        .init_page = gf100_fb_init_page,
        .intr = gf100_fb_intr,
+       .sysmem.flush_page_init = gf100_fb_sysmem_flush_page_init,
        .ram_new = gk104_ram_new,
        .default_bigpage = 17,
        .clkgate_pack = gk104_fb_clkgate_pack,
index 45d6cdffafeedc5f326bc45556357d882531f7d9..4dc283dedf8b5b383446ccdfa560bd15ca558297 100644 (file)
@@ -59,6 +59,7 @@ gk110_fb = {
        .init = gf100_fb_init,
        .init_page = gf100_fb_init_page,
        .intr = gf100_fb_intr,
+       .sysmem.flush_page_init = gf100_fb_sysmem_flush_page_init,
        .ram_new = gk104_ram_new,
        .default_bigpage = 17,
        .clkgate_pack = gk110_fb_clkgate_pack,
index de52462a92bf0ecd2b85a509091800e7b9761444..90bfff616d35bb539efd77d8fc49eab163fee089 100644 (file)
@@ -31,6 +31,7 @@ gm107_fb = {
        .init = gf100_fb_init,
        .init_page = gf100_fb_init_page,
        .intr = gf100_fb_intr,
+       .sysmem.flush_page_init = gf100_fb_sysmem_flush_page_init,
        .ram_new = gm107_ram_new,
        .default_bigpage = 17,
 };
index 2658481d575b62c9db6ffbe63beb4477c5dc65e6..14d942e8b857f43566fb7359d52464a092f69480 100644 (file)
 int
 gp102_fb_vpr_scrub(struct nvkm_fb *fb)
 {
-       struct nvkm_subdev *subdev = &fb->subdev;
-       struct nvkm_falcon_fw fw = {};
-       int ret;
-
-       ret = nvkm_falcon_fw_ctor_hs(&gm200_flcn_fw, "mem-unlock", subdev, NULL,
-                                    "nvdec/scrubber", 0, &subdev->device->nvdec[0]->falcon, &fw);
-       if (ret)
-               return ret;
-
-       ret = nvkm_falcon_fw_boot(&fw, subdev, true, NULL, NULL, 0, 0x00000000);
-       nvkm_falcon_fw_dtor(&fw);
-       return ret;
+       return nvkm_falcon_fw_boot(&fb->vpr_scrubber, &fb->subdev, true, NULL, NULL, 0, 0x00000000);
 }
 
 bool
@@ -51,10 +40,21 @@ gp102_fb_vpr_scrub_required(struct nvkm_fb *fb)
        return (nvkm_rd32(device, 0x100cd0) & 0x00000010) != 0;
 }
 
+int
+gp102_fb_oneinit(struct nvkm_fb *fb)
+{
+       struct nvkm_subdev *subdev = &fb->subdev;
+
+       nvkm_falcon_fw_ctor_hs(&gm200_flcn_fw, "mem-unlock", subdev, NULL, "nvdec/scrubber",
+                              0, &subdev->device->nvdec[0]->falcon, &fb->vpr_scrubber);
+
+       return gf100_fb_oneinit(fb);
+}
+
 static const struct nvkm_fb_func
 gp102_fb = {
        .dtor = gf100_fb_dtor,
-       .oneinit = gf100_fb_oneinit,
+       .oneinit = gp102_fb_oneinit,
        .init = gm200_fb_init,
        .init_remapper = gp100_fb_init_remapper,
        .init_page = gm200_fb_init_page,
@@ -64,23 +64,10 @@ gp102_fb = {
        .ram_new = gp100_ram_new,
 };
 
-int
-gp102_fb_new_(const struct nvkm_fb_func *func, struct nvkm_device *device,
-             enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
-{
-       int ret = gf100_fb_new_(func, device, type, inst, pfb);
-       if (ret)
-               return ret;
-
-       nvkm_firmware_load_blob(&(*pfb)->subdev, "nvdec/scrubber", "", 0,
-                               &(*pfb)->vpr_scrubber);
-       return 0;
-}
-
 int
 gp102_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
 {
-       return gp102_fb_new_(&gp102_fb, device, type, inst, pfb);
+       return gf100_fb_new_(&gp102_fb, device, type, inst, pfb);
 }
 
 MODULE_FIRMWARE("nvidia/gp102/nvdec/scrubber.bin");
index 0e3c0a8f5d716e6796d0a40f790b6c312ccf479e..4d8a286a7a348ce2e918720716a12143b152da66 100644 (file)
@@ -31,7 +31,7 @@ gv100_fb_init_page(struct nvkm_fb *fb)
 static const struct nvkm_fb_func
 gv100_fb = {
        .dtor = gf100_fb_dtor,
-       .oneinit = gf100_fb_oneinit,
+       .oneinit = gp102_fb_oneinit,
        .init = gm200_fb_init,
        .init_page = gv100_fb_init_page,
        .init_unkn = gp100_fb_init_unkn,
@@ -45,7 +45,7 @@ gv100_fb = {
 int
 gv100_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
 {
-       return gp102_fb_new_(&gv100_fb, device, type, inst, pfb);
+       return gf100_fb_new_(&gv100_fb, device, type, inst, pfb);
 }
 
 MODULE_FIRMWARE("nvidia/gv100/nvdec/scrubber.bin");
index f517751f94acddc5f4c1d585085cc644f72c931c..726c30c8bf95d3fa27864d06fc26704b25242e49 100644 (file)
@@ -83,8 +83,7 @@ int gm200_fb_init_page(struct nvkm_fb *);
 void gp100_fb_init_remapper(struct nvkm_fb *);
 void gp100_fb_init_unkn(struct nvkm_fb *);
 
-int gp102_fb_new_(const struct nvkm_fb_func *, struct nvkm_device *, enum nvkm_subdev_type, int,
-                 struct nvkm_fb **);
+int gp102_fb_oneinit(struct nvkm_fb *);
 bool gp102_fb_vpr_scrub_required(struct nvkm_fb *);
 int gp102_fb_vpr_scrub(struct nvkm_fb *);
 
index be82af0364ee449081c6936b7dbe3f3757146baa..b8803c124c3b2307df5214ca3463d9c0d683fbb8 100644 (file)
@@ -31,7 +31,7 @@ tu102_fb_vpr_scrub_required(struct nvkm_fb *fb)
 static const struct nvkm_fb_func
 tu102_fb = {
        .dtor = gf100_fb_dtor,
-       .oneinit = gf100_fb_oneinit,
+       .oneinit = gp102_fb_oneinit,
        .init = gm200_fb_init,
        .init_page = gv100_fb_init_page,
        .init_unkn = gp100_fb_init_unkn,
@@ -45,7 +45,7 @@ tu102_fb = {
 int
 tu102_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb)
 {
-       return gp102_fb_new_(&tu102_fb, device, type, inst, pfb);
+       return gf100_fb_new_(&tu102_fb, device, type, inst, pfb);
 }
 
 MODULE_FIRMWARE("nvidia/tu102/nvdec/scrubber.bin");
index 4e83a1891f3edc493ac3c5b9bbe1b7eab8b5b52b..e961fa27702ce61f8675f6b63b6ef4dfd1496e05 100644 (file)
@@ -282,7 +282,7 @@ static void panfrost_mmu_flush_range(struct panfrost_device *pfdev,
        if (pm_runtime_active(pfdev->dev))
                mmu_hw_do_operation(pfdev, mmu, iova, size, AS_COMMAND_FLUSH_PT);
 
-       pm_runtime_put_sync_autosuspend(pfdev->dev);
+       pm_runtime_put_autosuspend(pfdev->dev);
 }
 
 static int mmu_map_sg(struct panfrost_device *pfdev, struct panfrost_mmu *mmu,
@@ -504,6 +504,7 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as,
                if (IS_ERR(pages[i])) {
                        mutex_unlock(&bo->base.pages_lock);
                        ret = PTR_ERR(pages[i]);
+                       pages[i] = NULL;
                        goto err_pages;
                }
        }
index ba3b817895091fc285c965c518ad3ed614d6ad53..293c228a83f90f65faf3276a6b2eee16f0a9270c 100644 (file)
@@ -839,6 +839,8 @@ static void vop2_enable(struct vop2 *vop2)
                return;
        }
 
+       regcache_sync(vop2->map);
+
        if (vop2->data->soc_id == 3566)
                vop2_writel(vop2, RK3568_OTP_WIN_EN, 1);
 
@@ -867,6 +869,8 @@ static void vop2_disable(struct vop2 *vop2)
 
        pm_runtime_put_sync(vop2->dev);
 
+       regcache_mark_dirty(vop2->map);
+
        clk_disable_unprepare(vop2->aclk);
        clk_disable_unprepare(vop2->hclk);
 }
index 15d04a0ec623469d6bd89c8460a335b9b22cfd8f..e0a8890a62e23a933c853b73ef27b5ee31acbbc2 100644 (file)
@@ -507,12 +507,19 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job)
 {
        struct drm_sched_entity *entity = sched_job->entity;
        bool first;
+       ktime_t submit_ts;
 
        trace_drm_sched_job(sched_job, entity);
        atomic_inc(entity->rq->sched->score);
        WRITE_ONCE(entity->last_user, current->group_leader);
+
+       /*
+        * After the sched_job is pushed into the entity queue, it may be
+        * completed and freed up at any time. We can no longer access it.
+        * Make sure to set the submit_ts first, to avoid a race.
+        */
+       sched_job->submit_ts = submit_ts = ktime_get();
        first = spsc_queue_push(&entity->job_queue, &sched_job->queue_node);
-       sched_job->submit_ts = ktime_get();
 
        /* first job wakes up scheduler */
        if (first) {
@@ -529,7 +536,7 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job)
                spin_unlock(&entity->rq_lock);
 
                if (drm_sched_policy == DRM_SCHED_POLICY_FIFO)
-                       drm_sched_rq_update_fifo(entity, sched_job->submit_ts);
+                       drm_sched_rq_update_fifo(entity, submit_ts);
 
                drm_sched_wakeup(entity->rq->sched);
        }
index 4e6ad6e122bc44943ab73366a653ebbf2bdda51a..1e08cc5a17029e627cea89a314797573657cc8fe 100644 (file)
@@ -308,7 +308,8 @@ static void drm_sched_start_timeout(struct drm_gpu_scheduler *sched)
  */
 void drm_sched_fault(struct drm_gpu_scheduler *sched)
 {
-       mod_delayed_work(sched->timeout_wq, &sched->work_tdr, 0);
+       if (sched->ready)
+               mod_delayed_work(sched->timeout_wq, &sched->work_tdr, 0);
 }
 EXPORT_SYMBOL(drm_sched_fault);
 
@@ -906,12 +907,6 @@ drm_sched_get_cleanup_job(struct drm_gpu_scheduler *sched)
 
        spin_unlock(&sched->job_list_lock);
 
-       if (job) {
-               job->entity->elapsed_ns += ktime_to_ns(
-                       ktime_sub(job->s_fence->finished.timestamp,
-                                 job->s_fence->scheduled.timestamp));
-       }
-
        return job;
 }
 
index cc94efbbf2d4eede4b9f4f95c15303273d056ced..d6c741716167ae8e2f3ee485b49df4886943bcf9 100644 (file)
@@ -95,12 +95,12 @@ static int sun4i_drv_bind(struct device *dev)
        /* drm_vblank_init calls kcalloc, which can fail */
        ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
        if (ret)
-               goto cleanup_mode_config;
+               goto unbind_all;
 
        /* Remove early framebuffers (ie. simplefb) */
        ret = drm_aperture_remove_framebuffers(false, &sun4i_drv_driver);
        if (ret)
-               goto cleanup_mode_config;
+               goto unbind_all;
 
        sun4i_framebuffer_init(drm);
 
@@ -119,6 +119,8 @@ static int sun4i_drv_bind(struct device *dev)
 
 finish_poll:
        drm_kms_helper_poll_fini(drm);
+unbind_all:
+       component_unbind_all(dev, NULL);
 cleanup_mode_config:
        drm_mode_config_cleanup(drm);
        of_reserved_mem_device_release(dev);
index f8ee714df3967eb2dc93b86885e8fdc3d903210b..09ee6f6af896bd9c36f24b9e08a41f037e764ed8 100644 (file)
@@ -89,7 +89,8 @@ static int check_block(struct kunit *test, struct drm_buddy *mm,
                err = -EINVAL;
        }
 
-       if (!is_power_of_2(block_size)) {
+       /* We can't use is_power_of_2() for a u64 on 32-bit systems. */
+       if (block_size & (block_size - 1)) {
                kunit_err(test, "block size not power of two\n");
                err = -EINVAL;
        }
index cf35b609050322e4946190d76d1f82d1b4010ff6..accfa52e78c51881571e61c55468419022f8ad16 100644 (file)
@@ -455,7 +455,7 @@ static void cirrus_pipe_update(struct drm_simple_display_pipe *pipe,
        if (state->fb && cirrus->cpp != cirrus_cpp(state->fb))
                cirrus_mode_set(cirrus, &crtc->mode, state->fb);
 
-       if (drm_atomic_helper_damage_merged(old_state, state, &rect))
+       if (state->fb && drm_atomic_helper_damage_merged(old_state, state, &rect))
                cirrus_fb_blit_rect(state->fb, &shadow_plane_state->data[0], &rect);
 }
 
index 326a3d13a82956846a428ac2e395bab48297a486..c286c6ffe07f691af62cd8f77cf6cdffdce43b71 100644 (file)
@@ -295,8 +295,6 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo,
        if (unlock_resv)
                dma_resv_unlock(bo->base.resv);
 
-       ttm_bo_put(bo);
-
        return 0;
 }
 
index c7a1862f322a1cfadb039d58f52d2fcd30e07dd1..ae2f19dc9f81696894f010a732d5e78fad950276 100644 (file)
@@ -158,7 +158,7 @@ int ttm_device_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx,
                        struct ttm_buffer_object *bo = res->bo;
                        uint32_t num_pages;
 
-                       if (!bo)
+                       if (!bo || bo->resource != res)
                                continue;
 
                        num_pages = PFN_UP(bo->base.size);
index a04a9b20896dcab4c9baebf509be50a9422f3ba2..1778a2081fd6f72b88a79ffdcd2df879a383a885 100644 (file)
@@ -604,7 +604,7 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
        bool use_dma_api = !virtio_has_dma_quirk(vgdev->vdev);
 
        if (virtio_gpu_is_shmem(bo) && use_dma_api)
-               dma_sync_sgtable_for_device(&vgdev->vdev->dev,
+               dma_sync_sgtable_for_device(vgdev->vdev->dev.parent,
                                            bo->base.sgt, DMA_TO_DEVICE);
 
        cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
@@ -1026,7 +1026,7 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev,
        bool use_dma_api = !virtio_has_dma_quirk(vgdev->vdev);
 
        if (virtio_gpu_is_shmem(bo) && use_dma_api)
-               dma_sync_sgtable_for_device(&vgdev->vdev->dev,
+               dma_sync_sgtable_for_device(vgdev->vdev->dev.parent,
                                            bo->base.sgt, DMA_TO_DEVICE);
 
        cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
index 4872d183d86044ed7243e858e93c72deb203048e..aae2efeef503213ccc6695735b6bebf7d4511c16 100644 (file)
@@ -487,7 +487,6 @@ static int host1x_get_resets(struct host1x *host)
 static int host1x_probe(struct platform_device *pdev)
 {
        struct host1x *host;
-       int syncpt_irq;
        int err;
 
        host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
@@ -517,8 +516,8 @@ static int host1x_probe(struct platform_device *pdev)
        }
 
        host->syncpt_irq = platform_get_irq(pdev, 0);
-       if (syncpt_irq < 0)
-               return syncpt_irq;
+       if (host->syncpt_irq < 0)
+               return host->syncpt_irq;
 
        mutex_init(&host->devices_lock);
        INIT_LIST_HEAD(&host->devices);
index 82f64fb31fdab669bf81ccb415ed230d5734b13e..4ce012f83253ec9f12e3c12b5f95c12142cb4e8c 100644 (file)
@@ -1122,7 +1122,7 @@ config HID_TOPRE
        tristate "Topre REALFORCE keyboards"
        depends on HID
        help
-         Say Y for N-key rollover support on Topre REALFORCE R2 108 key keyboards.
+         Say Y for N-key rollover support on Topre REALFORCE R2 108/87 key keyboards.
 
 config HID_THINGM
        tristate "ThingM blink(1) USB RGB LED"
index 842afc88a9496c382cb936fd24b78baef054e2bd..22623eb4f72f2979b8f282b85c7fb006faa47241 100644 (file)
@@ -256,6 +256,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
 {
        struct hid_report *report;
        struct hid_field *field;
+       unsigned int max_buffer_size = HID_MAX_BUFFER_SIZE;
        unsigned int usages;
        unsigned int offset;
        unsigned int i;
@@ -286,8 +287,11 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
        offset = report->size;
        report->size += parser->global.report_size * parser->global.report_count;
 
+       if (parser->device->ll_driver->max_buffer_size)
+               max_buffer_size = parser->device->ll_driver->max_buffer_size;
+
        /* Total size check: Allow for possible report index byte */
-       if (report->size > (HID_MAX_BUFFER_SIZE - 1) << 3) {
+       if (report->size > (max_buffer_size - 1) << 3) {
                hid_err(parser->device, "report is too long\n");
                return -1;
        }
@@ -1963,6 +1967,7 @@ int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *
        struct hid_report_enum *report_enum = hid->report_enum + type;
        struct hid_report *report;
        struct hid_driver *hdrv;
+       int max_buffer_size = HID_MAX_BUFFER_SIZE;
        u32 rsize, csize = size;
        u8 *cdata = data;
        int ret = 0;
@@ -1978,10 +1983,13 @@ int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *
 
        rsize = hid_compute_report_size(report);
 
-       if (report_enum->numbered && rsize >= HID_MAX_BUFFER_SIZE)
-               rsize = HID_MAX_BUFFER_SIZE - 1;
-       else if (rsize > HID_MAX_BUFFER_SIZE)
-               rsize = HID_MAX_BUFFER_SIZE;
+       if (hid->ll_driver->max_buffer_size)
+               max_buffer_size = hid->ll_driver->max_buffer_size;
+
+       if (report_enum->numbered && rsize >= max_buffer_size)
+               rsize = max_buffer_size - 1;
+       else if (rsize > max_buffer_size)
+               rsize = max_buffer_size;
 
        if (csize < rsize) {
                dbg_hid("report %d is too short, (%d < %d)\n", report->id,
@@ -2396,7 +2404,12 @@ int hid_hw_raw_request(struct hid_device *hdev,
                       unsigned char reportnum, __u8 *buf,
                       size_t len, enum hid_report_type rtype, enum hid_class_request reqtype)
 {
-       if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf)
+       unsigned int max_buffer_size = HID_MAX_BUFFER_SIZE;
+
+       if (hdev->ll_driver->max_buffer_size)
+               max_buffer_size = hdev->ll_driver->max_buffer_size;
+
+       if (len < 1 || len > max_buffer_size || !buf)
                return -EINVAL;
 
        return hdev->ll_driver->raw_request(hdev, reportnum, buf, len,
@@ -2415,7 +2428,12 @@ EXPORT_SYMBOL_GPL(hid_hw_raw_request);
  */
 int hid_hw_output_report(struct hid_device *hdev, __u8 *buf, size_t len)
 {
-       if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf)
+       unsigned int max_buffer_size = HID_MAX_BUFFER_SIZE;
+
+       if (hdev->ll_driver->max_buffer_size)
+               max_buffer_size = hdev->ll_driver->max_buffer_size;
+
+       if (len < 1 || len > max_buffer_size || !buf)
                return -EINVAL;
 
        if (hdev->ll_driver->output_report)
index 1e16b0fa310d16994b61845df5428fe007ac6693..27cadadda7c9d8c781f6d7d8575bc1fbf54a1e7b 100644 (file)
@@ -1354,6 +1354,7 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
        girq->parents = NULL;
        girq->default_type = IRQ_TYPE_NONE;
        girq->handler = handle_simple_irq;
+       girq->threaded = true;
 
        ret = gpiochip_add_data(&dev->gc, dev);
        if (ret < 0) {
index 63545cd307e5f8805672301dac5adbfa0025f5f2..c2e9b6d1fd7d3eda054e33cf73a47a3b1f4deea4 100644 (file)
 #define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN   0x261A
 #define I2C_DEVICE_ID_SURFACE_GO2_TOUCHSCREEN  0x2A1C
 #define I2C_DEVICE_ID_LENOVO_YOGA_C630_TOUCHSCREEN     0x279F
+#define I2C_DEVICE_ID_HP_SPECTRE_X360_13T_AW100        0x29F5
+#define I2C_DEVICE_ID_HP_SPECTRE_X360_14T_EA100_V1     0x2BED
+#define I2C_DEVICE_ID_HP_SPECTRE_X360_14T_EA100_V2     0x2BEE
 
 #define USB_VENDOR_ID_ELECOM           0x056e
 #define USB_DEVICE_ID_ELECOM_BM084     0x0061
 
 #define USB_VENDOR_ID_TOPRE                    0x0853
 #define USB_DEVICE_ID_TOPRE_REALFORCE_R2_108                   0x0148
+#define USB_DEVICE_ID_TOPRE_REALFORCE_R2_87                    0x0146
 
 #define USB_VENDOR_ID_TOPSEED          0x0766
 #define USB_DEVICE_ID_TOPSEED_CYBERLINK        0x0204
index 7fc967964dd8167de925c977e2207b8cb82b4603..5c65a584b3fa00492112309e8b3454feec66e70e 100644 (file)
@@ -398,6 +398,12 @@ static const struct hid_device_id hid_battery_quirks[] = {
          HID_BATTERY_QUIRK_IGNORE },
        { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_LENOVO_YOGA_C630_TOUCHSCREEN),
          HID_BATTERY_QUIRK_IGNORE },
+       { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_13T_AW100),
+         HID_BATTERY_QUIRK_IGNORE },
+       { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_14T_EA100_V1),
+         HID_BATTERY_QUIRK_IGNORE },
+       { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_14T_EA100_V2),
+         HID_BATTERY_QUIRK_IGNORE },
        {}
 };
 
index 25dcda76d6c7bb481c366bdb971b87827860f049..5fc88a063297856931ce625aba974af3c07bb7e5 100644 (file)
@@ -4399,6 +4399,8 @@ static const struct hid_device_id hidpp_devices[] = {
          HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb02a) },
        { /* MX Master 3 mouse over Bluetooth */
          HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb023) },
+       { /* MX Master 3S mouse over Bluetooth */
+         HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb034) },
        {}
 };
 
index 3e3f89e01d819bb30b2eb30c36adc1d0ba89df42..d85398721659ab6ac90ddb9e48fea4c89fd90e38 100644 (file)
@@ -940,7 +940,7 @@ hid_sensor_register_platform_device(struct platform_device *pdev,
                                    struct hid_sensor_hub_device *hsdev,
                                    const struct hid_sensor_custom_match *match)
 {
-       char real_usage[HID_SENSOR_USAGE_LENGTH];
+       char real_usage[HID_SENSOR_USAGE_LENGTH] = { 0 };
        struct platform_device *custom_pdev;
        const char *dev_name;
        char *c;
index 88a91cdad5f800e951121b6e252fa7780629df22..d1d5ca310eadc0fd7b4d5a44c050efffe7b96e69 100644 (file)
@@ -36,6 +36,8 @@ static __u8 *topre_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 static const struct hid_device_id topre_id_table[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_TOPRE,
                         USB_DEVICE_ID_TOPRE_REALFORCE_R2_108) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_TOPRE,
+                        USB_DEVICE_ID_TOPRE_REALFORCE_R2_87) },
        { }
 };
 MODULE_DEVICE_TABLE(hid, topre_id_table);
index 15e14239af829bd7574b6440e4a5b097eaca893f..a49c6affd7c4c48cdd09e3bdcca95139d0c066b8 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright (c) 2014-2016, Intel Corporation.
  */
 
+#include <linux/devm-helpers.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/delay.h>
@@ -621,7 +622,6 @@ static void recv_ipc(struct ishtp_device *dev, uint32_t doorbell_val)
        case MNG_RESET_NOTIFY:
                if (!ishtp_dev) {
                        ishtp_dev = dev;
-                       INIT_WORK(&fw_reset_work, fw_reset_work_fn);
                }
                schedule_work(&fw_reset_work);
                break;
@@ -940,6 +940,7 @@ struct ishtp_device *ish_dev_init(struct pci_dev *pdev)
 {
        struct ishtp_device *dev;
        int     i;
+       int     ret;
 
        dev = devm_kzalloc(&pdev->dev,
                           sizeof(struct ishtp_device) + sizeof(struct ish_hw),
@@ -975,6 +976,12 @@ struct ishtp_device *ish_dev_init(struct pci_dev *pdev)
                list_add_tail(&tx_buf->link, &dev->wr_free_list);
        }
 
+       ret = devm_work_autocancel(&pdev->dev, &fw_reset_work, fw_reset_work_fn);
+       if (ret) {
+               dev_err(dev->devc, "Failed to initialise FW reset work\n");
+               return NULL;
+       }
+
        dev->ops = &ish_hw_ops;
        dev->devc = &pdev->dev;
        dev->mtu = IPC_PAYLOAD_SIZE - sizeof(struct ishtp_msg_hdr);
index 81385ab37fa9a0dc40a703e6a4594501aa12c236..7fc738a223755601e50e51cecbf8f985e6241f01 100644 (file)
@@ -241,8 +241,8 @@ static int ishtp_cl_bus_match(struct device *dev, struct device_driver *drv)
        struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
        struct ishtp_cl_driver *driver = to_ishtp_cl_driver(drv);
 
-       return guid_equal(&driver->id[0].guid,
-                         &device->fw_client->props.protocol_name);
+       return(device->fw_client ? guid_equal(&driver->id[0].guid,
+              &device->fw_client->props.protocol_name) : 0);
 }
 
 /**
index f161c95a1ad2e9bc65316a06898eafc27ec18a5e..4588d2cd4ea4444fdbb5bb5388d9eeffc6cc55eb 100644 (file)
@@ -395,6 +395,7 @@ static const struct hid_ll_driver uhid_hid_driver = {
        .parse = uhid_hid_parse,
        .raw_request = uhid_hid_raw_request,
        .output_report = uhid_hid_output_report,
+       .max_buffer_size = UHID_DATA_MAX,
 };
 
 #ifdef CONFIG_COMPAT
index 9dc27e5d367a20c9bce2cb4f6253913724bf02e2..da51b50787dff39ef697b82d4e8f8708c39c9ce0 100644 (file)
@@ -409,6 +409,10 @@ void vmbus_disconnect(void)
  */
 struct vmbus_channel *relid2channel(u32 relid)
 {
+       if (vmbus_connection.channels == NULL) {
+               pr_warn_once("relid2channel: relid=%d: No channels mapped!\n", relid);
+               return NULL;
+       }
        if (WARN_ON(relid >= MAX_CHANNEL_RELIDS))
                return NULL;
        return READ_ONCE(vmbus_connection.channels[relid]);
index 51b3d16c32233d78a524a9afca79af57dffce362..6e4c92b500b8e383fd99fcc3aca91027e6cfb355 100644 (file)
@@ -488,10 +488,10 @@ static ssize_t temp_store(struct device *dev, struct device_attribute *attr,
                val = (temp - val) / 1000;
 
                if (sattr->index != 1) {
-                       data->temp[HYSTERSIS][sattr->index] &= 0xF0;
+                       data->temp[HYSTERSIS][sattr->index] &= 0x0F;
                        data->temp[HYSTERSIS][sattr->index] |= (val & 0xF) << 4;
                } else {
-                       data->temp[HYSTERSIS][sattr->index] &= 0x0F;
+                       data->temp[HYSTERSIS][sattr->index] &= 0xF0;
                        data->temp[HYSTERSIS][sattr->index] |= (val & 0xF);
                }
 
@@ -556,11 +556,11 @@ static ssize_t temp_st_show(struct device *dev, struct device_attribute *attr,
                val = data->enh_acoustics[0] & 0xf;
                break;
        case 1:
-               val = (data->enh_acoustics[1] >> 4) & 0xf;
+               val = data->enh_acoustics[1] & 0xf;
                break;
        case 2:
        default:
-               val = data->enh_acoustics[1] & 0xf;
+               val = (data->enh_acoustics[1] >> 4) & 0xf;
                break;
        }
 
index 33edb5c02f7d79d4e8ff7a75fe7ae03c84a83579..d193ed3cb35e5b315f104b04e272862922028e17 100644 (file)
@@ -757,6 +757,7 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata,
        struct hwmon_device *hwdev;
        const char *label;
        struct device *hdev;
+       struct device *tdev = dev;
        int i, err, id;
 
        /* Complain about invalid characters in hwmon name attribute */
@@ -826,7 +827,9 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata,
        hwdev->name = name;
        hdev->class = &hwmon_class;
        hdev->parent = dev;
-       hdev->of_node = dev ? dev->of_node : NULL;
+       while (tdev && !tdev->of_node)
+               tdev = tdev->parent;
+       hdev->of_node = tdev ? tdev->of_node : NULL;
        hwdev->chip = chip;
        dev_set_drvdata(hdev, drvdata);
        dev_set_name(hdev, HWMON_ID_FORMAT, id);
@@ -838,7 +841,7 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata,
 
        INIT_LIST_HEAD(&hwdev->tzdata);
 
-       if (dev && dev->of_node && chip && chip->ops->read &&
+       if (hdev->of_node && chip && chip->ops->read &&
            chip->info[0]->type == hwmon_chip &&
            (chip->info[0]->config[0] & HWMON_C_REGISTER_TZ)) {
                err = hwmon_thermal_register_sensors(hdev);
index e06186986444ee4853248deb4ec8424b616ed726..f3a4c5633b1ea6876336719a06ede4cad9207b30 100644 (file)
@@ -772,7 +772,7 @@ static int ina3221_probe_child_from_dt(struct device *dev,
                return ret;
        } else if (val > INA3221_CHANNEL3) {
                dev_err(dev, "invalid reg %d of %pOFn\n", val, child);
-               return ret;
+               return -EINVAL;
        }
 
        input = &ina->inputs[val];
index 66f7ceaa7c3f5fa6328c905f5ca64b8504f25b3c..e9614eb557d4eb44e16397419d988ef9a9dac1ad 100644 (file)
@@ -515,6 +515,8 @@ static const struct it87_devices it87_devices[] = {
 #define has_six_temp(data)     ((data)->features & FEAT_SIX_TEMP)
 #define has_vin3_5v(data)      ((data)->features & FEAT_VIN3_5V)
 #define has_conf_noexit(data)  ((data)->features & FEAT_CONF_NOEXIT)
+#define has_scaling(data)      ((data)->features & (FEAT_12MV_ADC | \
+                                                    FEAT_10_9MV_ADC))
 
 struct it87_sio_data {
        int sioaddr;
@@ -3134,7 +3136,7 @@ static int it87_probe(struct platform_device *pdev)
                         "Detected broken BIOS defaults, disabling PWM interface\n");
 
        /* Starting with IT8721F, we handle scaling of internal voltages */
-       if (has_12mv_adc(data)) {
+       if (has_scaling(data)) {
                if (sio_data->internal & BIT(0))
                        data->in_scaled |= BIT(3);      /* in3 is AVCC */
                if (sio_data->internal & BIT(1))
index 88514152d9306f98460fd8405ec48ad60c4fa025..69341de397cb93e4c0b741620712b55c42fd2acc 100644 (file)
@@ -323,6 +323,7 @@ static int ltc2992_config_gpio(struct ltc2992_state *st)
        st->gc.label = name;
        st->gc.parent = &st->client->dev;
        st->gc.owner = THIS_MODULE;
+       st->gc.can_sleep = true;
        st->gc.base = -1;
        st->gc.names = st->gpio_names;
        st->gc.ngpio = ARRAY_SIZE(st->gpio_names);
index 30850a479f61fdf96b5ae1cdd985b09802575bdc..87d56f0fc888c23fffac13ac67322639a4bbf409 100644 (file)
@@ -537,6 +537,12 @@ static const struct cpu_info cpu_hsx = {
        .thermal_margin_to_millidegree = &dts_eight_dot_eight_to_millidegree,
 };
 
+static const struct cpu_info cpu_skx = {
+       .reg            = &resolved_cores_reg_hsx,
+       .min_peci_revision = 0x33,
+       .thermal_margin_to_millidegree = &dts_ten_dot_six_to_millidegree,
+};
+
 static const struct cpu_info cpu_icx = {
        .reg            = &resolved_cores_reg_icx,
        .min_peci_revision = 0x40,
@@ -558,7 +564,7 @@ static const struct auxiliary_device_id peci_cputemp_ids[] = {
        },
        {
                .name = "peci_cpu.cputemp.skx",
-               .driver_data = (kernel_ulong_t)&cpu_hsx,
+               .driver_data = (kernel_ulong_t)&cpu_skx,
        },
        {
                .name = "peci_cpu.cputemp.icx",
index ec5f932fc6f0fb6d489418f25beaa1816710759e..1ac2b2f4c5705f5a142579e3085c703675d5b01b 100644 (file)
@@ -301,6 +301,7 @@ static int adm1266_config_gpio(struct adm1266_data *data)
        data->gc.label = name;
        data->gc.parent = &data->client->dev;
        data->gc.owner = THIS_MODULE;
+       data->gc.can_sleep = true;
        data->gc.base = -1;
        data->gc.names = data->gpio_names;
        data->gc.ngpio = ARRAY_SIZE(data->gpio_names);
index 75fc770c9e4035b2b982b34b543b5e51f6dd3378..3daaf22378322f6c2d0074bcad0f96220e227003 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/debugfs.h>
+#include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
@@ -16,6 +17,7 @@
 #include <linux/i2c.h>
 #include <linux/pmbus.h>
 #include <linux/gpio/driver.h>
+#include <linux/timekeeping.h>
 #include "pmbus.h"
 
 enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd90320, ucd9090,
@@ -65,6 +67,7 @@ struct ucd9000_data {
        struct gpio_chip gpio;
 #endif
        struct dentry *debugfs;
+       ktime_t write_time;
 };
 #define to_ucd9000_data(_info) container_of(_info, struct ucd9000_data, info)
 
@@ -73,6 +76,73 @@ struct ucd9000_debugfs_entry {
        u8 index;
 };
 
+/*
+ * It has been observed that the UCD90320 randomly fails register access when
+ * doing another access right on the back of a register write. To mitigate this
+ * make sure that there is a minimum delay between a write access and the
+ * following access. The 250us is based on experimental data. At a delay of
+ * 200us the issue seems to go away. Add a bit of extra margin to allow for
+ * system to system differences.
+ */
+#define UCD90320_WAIT_DELAY_US 250
+
+static inline void ucd90320_wait(const struct ucd9000_data *data)
+{
+       s64 delta = ktime_us_delta(ktime_get(), data->write_time);
+
+       if (delta < UCD90320_WAIT_DELAY_US)
+               udelay(UCD90320_WAIT_DELAY_US - delta);
+}
+
+static int ucd90320_read_word_data(struct i2c_client *client, int page,
+                                  int phase, int reg)
+{
+       const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
+       struct ucd9000_data *data = to_ucd9000_data(info);
+
+       if (reg >= PMBUS_VIRT_BASE)
+               return -ENXIO;
+
+       ucd90320_wait(data);
+       return pmbus_read_word_data(client, page, phase, reg);
+}
+
+static int ucd90320_read_byte_data(struct i2c_client *client, int page, int reg)
+{
+       const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
+       struct ucd9000_data *data = to_ucd9000_data(info);
+
+       ucd90320_wait(data);
+       return pmbus_read_byte_data(client, page, reg);
+}
+
+static int ucd90320_write_word_data(struct i2c_client *client, int page,
+                                   int reg, u16 word)
+{
+       const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
+       struct ucd9000_data *data = to_ucd9000_data(info);
+       int ret;
+
+       ucd90320_wait(data);
+       ret = pmbus_write_word_data(client, page, reg, word);
+       data->write_time = ktime_get();
+
+       return ret;
+}
+
+static int ucd90320_write_byte(struct i2c_client *client, int page, u8 value)
+{
+       const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
+       struct ucd9000_data *data = to_ucd9000_data(info);
+       int ret;
+
+       ucd90320_wait(data);
+       ret = pmbus_write_byte(client, page, value);
+       data->write_time = ktime_get();
+
+       return ret;
+}
+
 static int ucd9000_get_fan_config(struct i2c_client *client, int fan)
 {
        int fan_config = 0;
@@ -598,6 +668,11 @@ static int ucd9000_probe(struct i2c_client *client)
                info->read_byte_data = ucd9000_read_byte_data;
                info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12
                  | PMBUS_HAVE_FAN34 | PMBUS_HAVE_STATUS_FAN34;
+       } else if (mid->driver_data == ucd90320) {
+               info->read_byte_data = ucd90320_read_byte_data;
+               info->read_word_data = ucd90320_read_word_data;
+               info->write_byte = ucd90320_write_byte;
+               info->write_word_data = ucd90320_write_word_data;
        }
 
        ucd9000_probe_gpio(client, mid, data);
index 47bbe47e062fd7a20e27f843b625f07e005722ee..7d5f7441aceb1040f8b8bcfedb8695c162c0acf1 100644 (file)
@@ -758,7 +758,7 @@ static int tmp51x_probe(struct i2c_client *client)
 static struct i2c_driver tmp51x_driver = {
        .driver = {
                .name   = "tmp51x",
-               .of_match_table = of_match_ptr(tmp51x_of_match),
+               .of_match_table = tmp51x_of_match,
        },
        .probe_new      = tmp51x_probe,
        .id_table       = tmp51x_id,
index 5cde837bfd094c57a3cf719b0fe0e4c2645dce8e..78d9f52e2a7194f9e0bc8714394ea9311a006379 100644 (file)
@@ -698,14 +698,14 @@ static int xgene_hwmon_probe(struct platform_device *pdev)
                ctx->comm_base_addr = pcc_chan->shmem_base_addr;
                if (ctx->comm_base_addr) {
                        if (version == XGENE_HWMON_V2)
-                               ctx->pcc_comm_addr = (void __force *)ioremap(
-                                                       ctx->comm_base_addr,
-                                                       pcc_chan->shmem_size);
+                               ctx->pcc_comm_addr = (void __force *)devm_ioremap(&pdev->dev,
+                                                                 ctx->comm_base_addr,
+                                                                 pcc_chan->shmem_size);
                        else
-                               ctx->pcc_comm_addr = memremap(
-                                                       ctx->comm_base_addr,
-                                                       pcc_chan->shmem_size,
-                                                       MEMREMAP_WB);
+                               ctx->pcc_comm_addr = devm_memremap(&pdev->dev,
+                                                                  ctx->comm_base_addr,
+                                                                  pcc_chan->shmem_size,
+                                                                  MEMREMAP_WB);
                } else {
                        dev_err(&pdev->dev, "Failed to get PCC comm region\n");
                        rc = -ENODEV;
@@ -761,6 +761,7 @@ static int xgene_hwmon_remove(struct platform_device *pdev)
 {
        struct xgene_hwmon_dev *ctx = platform_get_drvdata(pdev);
 
+       cancel_work_sync(&ctx->workq);
        hwmon_device_unregister(ctx->hwmon_dev);
        kfifo_free(&ctx->async_msg_fifo);
        if (acpi_disabled)
index 1ea8f173cca0d9d4561fae5b2e885f581ff6f31c..4c15fae534f3a353c814610647f55e132c4a76a2 100644 (file)
@@ -472,7 +472,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
                if (etm4x_sspcicrn_present(drvdata, i))
                        etm4x_relaxed_write32(csa, config->ss_pe_cmp[i], TRCSSPCICRn(i));
        }
-       for (i = 0; i < drvdata->nr_addr_cmp; i++) {
+       for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {
                etm4x_relaxed_write64(csa, config->addr_val[i], TRCACVRn(i));
                etm4x_relaxed_write64(csa, config->addr_acc[i], TRCACATRn(i));
        }
@@ -1070,25 +1070,21 @@ static bool etm4_init_iomem_access(struct etmv4_drvdata *drvdata,
                                   struct csdev_access *csa)
 {
        u32 devarch = readl_relaxed(drvdata->base + TRCDEVARCH);
-       u32 idr1 = readl_relaxed(drvdata->base + TRCIDR1);
 
        /*
         * All ETMs must implement TRCDEVARCH to indicate that
-        * the component is an ETMv4. To support any broken
-        * implementations we fall back to TRCIDR1 check, which
-        * is not really reliable.
+        * the component is an ETMv4. Even though TRCIDR1 also
+        * contains the information, it is part of the "Trace"
+        * register and must be accessed with the OSLK cleared,
+        * with MMIO. But we cannot touch the OSLK until we are
+        * sure this is an ETM. So rely only on the TRCDEVARCH.
         */
-       if ((devarch & ETM_DEVARCH_ID_MASK) == ETM_DEVARCH_ETMv4x_ARCH) {
-               drvdata->arch = etm_devarch_to_arch(devarch);
-       } else {
-               pr_warn("CPU%d: ETM4x incompatible TRCDEVARCH: %x, falling back to TRCIDR1\n",
-                       smp_processor_id(), devarch);
-
-               if (ETM_TRCIDR1_ARCH_MAJOR(idr1) != ETM_TRCIDR1_ARCH_ETMv4)
-                       return false;
-               drvdata->arch = etm_trcidr_to_arch(idr1);
+       if ((devarch & ETM_DEVARCH_ID_MASK) != ETM_DEVARCH_ETMv4x_ARCH) {
+               pr_warn_once("TRCDEVARCH doesn't match ETMv4 architecture\n");
+               return false;
        }
 
+       drvdata->arch = etm_devarch_to_arch(devarch);
        *csa = CSDEV_ACCESS_IOMEM(drvdata->base);
        return true;
 }
index 434f4e95ee17bb5de869884f94558a113e1ff511..27c8a99018680c1f321172c0db1fd466b74d652d 100644 (file)
  * TRCDEVARCH  - CoreSight architected register
  *                - Bits[15:12] - Major version
  *                - Bits[19:16] - Minor version
- * TRCIDR1     - ETM architected register
- *                - Bits[11:8] - Major version
- *                - Bits[7:4]  - Minor version
- * We must rely on TRCDEVARCH for the version information,
- * however we don't want to break the support for potential
- * old implementations which might not implement it. Thus
- * we fall back to TRCIDR1 if TRCDEVARCH is not implemented
- * for memory mapped components.
+ *
+ * We must rely only on TRCDEVARCH for the version information. Even though,
+ * TRCIDR1 also provides the architecture version, it is a "Trace" register
+ * and as such must be accessed only with Trace power domain ON. This may
+ * not be available at probe time.
+ *
  * Now to make certain decisions easier based on the version
  * we use an internal representation of the version in the
  * driver, as follows :
@@ -786,12 +784,6 @@ static inline u8 etm_devarch_to_arch(u32 devarch)
                                ETM_DEVARCH_REVISION(devarch));
 }
 
-static inline u8 etm_trcidr_to_arch(u32 trcidr1)
-{
-       return ETM_ARCH_VERSION(ETM_TRCIDR1_ARCH_MAJOR(trcidr1),
-                               ETM_TRCIDR1_ARCH_MINOR(trcidr1));
-}
-
 enum etm_impdef_type {
        ETM4_IMPDEF_HISI_CORE_COMMIT,
        ETM4_IMPDEF_FEATURE_MAX,
index 8c6c7075c765c502e194d222934b294ba966de89..e067671b3ce2eebed4eab2cb51301aaaa3890529 100644 (file)
@@ -316,6 +316,13 @@ static void hisi_i2c_xfer_msg(struct hisi_i2c_controller *ctlr)
                    max_write == 0)
                        break;
        }
+
+       /*
+        * Disable the TX_EMPTY interrupt after finishing all the messages to
+        * avoid overwhelming the CPU.
+        */
+       if (ctlr->msg_tx_idx == ctlr->msg_num)
+               hisi_i2c_disable_int(ctlr, HISI_I2C_INT_TX_EMPTY);
 }
 
 static irqreturn_t hisi_i2c_irq(int irq, void *context)
@@ -341,7 +348,11 @@ static irqreturn_t hisi_i2c_irq(int irq, void *context)
                hisi_i2c_read_rx_fifo(ctlr);
 
 out:
-       if (int_stat & HISI_I2C_INT_TRANS_CPLT || ctlr->xfer_err) {
+       /*
+        * Only use TRANS_CPLT to indicate the completion. On error cases we'll
+        * get two interrupts, INT_ERR first then TRANS_CPLT.
+        */
+       if (int_stat & HISI_I2C_INT_TRANS_CPLT) {
                hisi_i2c_disable_int(ctlr, HISI_I2C_INT_ALL);
                hisi_i2c_clear_int(ctlr, HISI_I2C_INT_ALL);
                complete(ctlr->completion);
index 188f2a36d2fd61bb3ffb943f8d879e8bba6bbe52..a49b14d52a98614bd5745baba5048ec24c43438a 100644 (file)
@@ -463,6 +463,8 @@ static int lpi2c_imx_xfer(struct i2c_adapter *adapter,
                if (num == 1 && msgs[0].len == 0)
                        goto stop;
 
+               lpi2c_imx->rx_buf = NULL;
+               lpi2c_imx->tx_buf = NULL;
                lpi2c_imx->delivered = 0;
                lpi2c_imx->msglen = msgs[i].len;
                init_completion(&lpi2c_imx->complete);
@@ -503,10 +505,14 @@ disable:
 static irqreturn_t lpi2c_imx_isr(int irq, void *dev_id)
 {
        struct lpi2c_imx_struct *lpi2c_imx = dev_id;
+       unsigned int enabled;
        unsigned int temp;
 
+       enabled = readl(lpi2c_imx->base + LPI2C_MIER);
+
        lpi2c_imx_intctrl(lpi2c_imx, 0);
        temp = readl(lpi2c_imx->base + LPI2C_MSR);
+       temp &= enabled;
 
        if (temp & MSR_RDF)
                lpi2c_imx_read_rxfifo(lpi2c_imx);
index 09af7592114789a924c8bef1cc095df192367151..b21ffd6df9276b34ec14267d6db6fe9cd93c9c66 100644 (file)
@@ -48,9 +48,9 @@
  * SR_HOLD_TIME_XK_TICKS field will indicate the number of ticks of the
  * baud clock required to program 'Hold Time' at X KHz.
  */
-#define SR_HOLD_TIME_100K_TICKS        133
-#define SR_HOLD_TIME_400K_TICKS        20
-#define SR_HOLD_TIME_1000K_TICKS       11
+#define SR_HOLD_TIME_100K_TICKS                150
+#define SR_HOLD_TIME_400K_TICKS                20
+#define SR_HOLD_TIME_1000K_TICKS       12
 
 #define SMB_CORE_COMPLETION_REG_OFF3   (SMBUS_MAST_CORE_ADDR_BASE + 0x23)
 
  * the baud clock required to program 'fair idle delay' at X KHz. Fair idle
  * delay establishes the MCTP T(IDLE_DELAY) period.
  */
-#define FAIR_BUS_IDLE_MIN_100K_TICKS           969
-#define FAIR_BUS_IDLE_MIN_400K_TICKS           157
-#define FAIR_BUS_IDLE_MIN_1000K_TICKS          157
+#define FAIR_BUS_IDLE_MIN_100K_TICKS           992
+#define FAIR_BUS_IDLE_MIN_400K_TICKS           500
+#define FAIR_BUS_IDLE_MIN_1000K_TICKS          500
 
 /*
  * FAIR_IDLE_DELAY_XK_TICKS field will indicate the number of ticks of the
  * baud clock required to satisfy the fairness protocol at X KHz.
  */
-#define FAIR_IDLE_DELAY_100K_TICKS     1000
-#define FAIR_IDLE_DELAY_400K_TICKS     500
-#define FAIR_IDLE_DELAY_1000K_TICKS    500
+#define FAIR_IDLE_DELAY_100K_TICKS     963
+#define FAIR_IDLE_DELAY_400K_TICKS     156
+#define FAIR_IDLE_DELAY_1000K_TICKS    156
 
 #define SMB_IDLE_SCALING_100K          \
        ((FAIR_IDLE_DELAY_100K_TICKS << 16) | FAIR_BUS_IDLE_MIN_100K_TICKS)
  */
 #define BUS_CLK_100K_LOW_PERIOD_TICKS          156
 #define BUS_CLK_400K_LOW_PERIOD_TICKS          41
-#define BUS_CLK_1000K_LOW_PERIOD_TICKS 15
+#define BUS_CLK_1000K_LOW_PERIOD_TICKS         15
 
 /*
  * BUS_CLK_XK_HIGH_PERIOD_TICKS field defines the number of I2C Baud Clock
  */
 #define CLK_SYNC_100K                  4
 #define CLK_SYNC_400K                  4
-#define CLK_SYNC_1000K         4
+#define CLK_SYNC_1000K                 4
 
 #define SMB_CORE_DATA_TIMING_REG_OFF   (SMBUS_MAST_CORE_ADDR_BASE + 0x40)
 
  * determines the SCLK hold time following SDAT driven low during the first
  * START bit in a transfer.
  */
-#define FIRST_START_HOLD_100K_TICKS    22
-#define FIRST_START_HOLD_400K_TICKS    16
-#define FIRST_START_HOLD_1000K_TICKS   6
+#define FIRST_START_HOLD_100K_TICKS    23
+#define FIRST_START_HOLD_400K_TICKS    8
+#define FIRST_START_HOLD_1000K_TICKS   12
 
 /*
  * STOP_SETUP_XK_TICKS will indicate the number of ticks of the baud clock
  * required to program 'STOP_SETUP' timer at X KHz. This timer determines the
  * SDAT setup time from the rising edge of SCLK for a STOP condition.
  */
-#define STOP_SETUP_100K_TICKS          157
+#define STOP_SETUP_100K_TICKS          150
 #define STOP_SETUP_400K_TICKS          20
-#define STOP_SETUP_1000K_TICKS 12
+#define STOP_SETUP_1000K_TICKS         12
 
 /*
  * RESTART_SETUP_XK_TICKS will indicate the number of ticks of the baud clock
  * required to program 'RESTART_SETUP' timer at X KHz. This timer determines the
  * SDAT setup time from the rising edge of SCLK for a repeated START condition.
  */
-#define RESTART_SETUP_100K_TICKS       157
+#define RESTART_SETUP_100K_TICKS       156
 #define RESTART_SETUP_400K_TICKS       20
 #define RESTART_SETUP_1000K_TICKS      12
 
  * required to program 'DATA_HOLD' timer at X KHz. This timer determines the
  * SDAT hold time following SCLK driven low.
  */
-#define DATA_HOLD_100K_TICKS           2
+#define DATA_HOLD_100K_TICKS           12
 #define DATA_HOLD_400K_TICKS           2
 #define DATA_HOLD_1000K_TICKS          2
 
  * Bus Idle Minimum time = BUS_IDLE_MIN[7:0] x Baud_Clock_Period x
  * (BUS_IDLE_MIN_XK_TICKS[7] ? 4,1)
  */
-#define BUS_IDLE_MIN_100K_TICKS                167UL
-#define BUS_IDLE_MIN_400K_TICKS                139UL
-#define BUS_IDLE_MIN_1000K_TICKS               133UL
+#define BUS_IDLE_MIN_100K_TICKS                36UL
+#define BUS_IDLE_MIN_400K_TICKS                10UL
+#define BUS_IDLE_MIN_1000K_TICKS       4UL
 
 /*
  * CTRL_CUM_TIME_OUT_XK_TICKS defines SMBus Controller Cumulative Time-Out.
  * SMBus Controller Cumulative Time-Out duration =
  * CTRL_CUM_TIME_OUT_XK_TICKS[7:0] x Baud_Clock_Period x 2048
  */
-#define CTRL_CUM_TIME_OUT_100K_TICKS           159
-#define CTRL_CUM_TIME_OUT_400K_TICKS           159
-#define CTRL_CUM_TIME_OUT_1000K_TICKS          159
+#define CTRL_CUM_TIME_OUT_100K_TICKS           76
+#define CTRL_CUM_TIME_OUT_400K_TICKS           76
+#define CTRL_CUM_TIME_OUT_1000K_TICKS          76
 
 /*
  * TARGET_CUM_TIME_OUT_XK_TICKS defines SMBus Target Cumulative Time-Out duration.
  * SMBus Target Cumulative Time-Out duration = TARGET_CUM_TIME_OUT_XK_TICKS[7:0] x
  * Baud_Clock_Period x 4096
  */
-#define TARGET_CUM_TIME_OUT_100K_TICKS 199
-#define TARGET_CUM_TIME_OUT_400K_TICKS 199
-#define TARGET_CUM_TIME_OUT_1000K_TICKS        199
+#define TARGET_CUM_TIME_OUT_100K_TICKS 95
+#define TARGET_CUM_TIME_OUT_400K_TICKS 95
+#define TARGET_CUM_TIME_OUT_1000K_TICKS        95
 
 /*
  * CLOCK_HIGH_TIME_OUT_XK defines Clock High time out period.
  * Clock High time out period = CLOCK_HIGH_TIME_OUT_XK[7:0] x Baud_Clock_Period x 8
  */
-#define CLOCK_HIGH_TIME_OUT_100K_TICKS 204
-#define CLOCK_HIGH_TIME_OUT_400K_TICKS 204
-#define CLOCK_HIGH_TIME_OUT_1000K_TICKS        204
+#define CLOCK_HIGH_TIME_OUT_100K_TICKS 97
+#define CLOCK_HIGH_TIME_OUT_400K_TICKS 97
+#define CLOCK_HIGH_TIME_OUT_1000K_TICKS        97
 
 #define TO_SCALING_100K                \
        ((BUS_IDLE_MIN_100K_TICKS << 24) | (CTRL_CUM_TIME_OUT_100K_TICKS << 16) | \
index d113bed7954526e1cb9afff96b8df98be26d1f15..e0f3b3545cfe4984dad9c582c419737ce448b506 100644 (file)
@@ -171,7 +171,7 @@ static void mxs_i2c_dma_irq_callback(void *param)
 }
 
 static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
-                       struct i2c_msg *msg, uint32_t flags)
+                       struct i2c_msg *msg, u8 *buf, uint32_t flags)
 {
        struct dma_async_tx_descriptor *desc;
        struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
@@ -226,7 +226,7 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
                }
 
                /* Queue the DMA data transfer. */
-               sg_init_one(&i2c->sg_io[1], msg->buf, msg->len);
+               sg_init_one(&i2c->sg_io[1], buf, msg->len);
                dma_map_sg(i2c->dev, &i2c->sg_io[1], 1, DMA_FROM_DEVICE);
                desc = dmaengine_prep_slave_sg(i2c->dmach, &i2c->sg_io[1], 1,
                                        DMA_DEV_TO_MEM,
@@ -259,7 +259,7 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
                /* Queue the DMA data transfer. */
                sg_init_table(i2c->sg_io, 2);
                sg_set_buf(&i2c->sg_io[0], &i2c->addr_data, 1);
-               sg_set_buf(&i2c->sg_io[1], msg->buf, msg->len);
+               sg_set_buf(&i2c->sg_io[1], buf, msg->len);
                dma_map_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE);
                desc = dmaengine_prep_slave_sg(i2c->dmach, i2c->sg_io, 2,
                                        DMA_MEM_TO_DEV,
@@ -563,6 +563,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
        struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
        int ret;
        int flags;
+       u8 *dma_buf;
        int use_pio = 0;
        unsigned long time_left;
 
@@ -588,13 +589,20 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
                if (ret && (ret != -ENXIO))
                        mxs_i2c_reset(i2c);
        } else {
+               dma_buf = i2c_get_dma_safe_msg_buf(msg, 1);
+               if (!dma_buf)
+                       return -ENOMEM;
+
                reinit_completion(&i2c->cmd_complete);
-               ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);
-               if (ret)
+               ret = mxs_i2c_dma_setup_xfer(adap, msg, dma_buf, flags);
+               if (ret) {
+                       i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
                        return ret;
+               }
 
                time_left = wait_for_completion_timeout(&i2c->cmd_complete,
                                                msecs_to_jiffies(1000));
+               i2c_put_dma_safe_msg_buf(dma_buf, msg, true);
                if (!time_left)
                        goto timeout;
 
index a0af027db04c11b98fef28be555ceb7804d92eb6..2e575856c5cd5dfa57a7fa28bce0ac17d62bfa30 100644 (file)
@@ -342,18 +342,18 @@ static int ocores_poll_wait(struct ocores_i2c *i2c)
  * ocores_isr(), we just add our polling code around it.
  *
  * It can run in atomic context
+ *
+ * Return: 0 on success, -ETIMEDOUT on timeout
  */
-static void ocores_process_polling(struct ocores_i2c *i2c)
+static int ocores_process_polling(struct ocores_i2c *i2c)
 {
-       while (1) {
-               irqreturn_t ret;
-               int err;
+       irqreturn_t ret;
+       int err = 0;
 
+       while (1) {
                err = ocores_poll_wait(i2c);
-               if (err) {
-                       i2c->state = STATE_ERROR;
+               if (err)
                        break; /* timeout */
-               }
 
                ret = ocores_isr(-1, i2c);
                if (ret == IRQ_NONE)
@@ -364,13 +364,15 @@ static void ocores_process_polling(struct ocores_i2c *i2c)
                                        break;
                }
        }
+
+       return err;
 }
 
 static int ocores_xfer_core(struct ocores_i2c *i2c,
                            struct i2c_msg *msgs, int num,
                            bool polling)
 {
-       int ret;
+       int ret = 0;
        u8 ctrl;
 
        ctrl = oc_getreg(i2c, OCI2C_CONTROL);
@@ -388,15 +390,16 @@ static int ocores_xfer_core(struct ocores_i2c *i2c,
        oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START);
 
        if (polling) {
-               ocores_process_polling(i2c);
+               ret = ocores_process_polling(i2c);
        } else {
-               ret = wait_event_timeout(i2c->wait,
-                                        (i2c->state == STATE_ERROR) ||
-                                        (i2c->state == STATE_DONE), HZ);
-               if (ret == 0) {
-                       ocores_process_timeout(i2c);
-                       return -ETIMEDOUT;
-               }
+               if (wait_event_timeout(i2c->wait,
+                                      (i2c->state == STATE_ERROR) ||
+                                      (i2c->state == STATE_DONE), HZ) == 0)
+                       ret = -ETIMEDOUT;
+       }
+       if (ret) {
+               ocores_process_timeout(i2c);
+               return ret;
        }
 
        return (i2c->state == STATE_DONE) ? num : -EIO;
index 63259b3ea5abd7aa43de6b22d0ec7861a47e7489..3538d36368a90b5fcf5f8e18e01826908c2198ec 100644 (file)
@@ -308,6 +308,9 @@ static int slimpro_i2c_blkwr(struct slimpro_i2c_dev *ctx, u32 chip,
        u32 msg[3];
        int rc;
 
+       if (writelen > I2C_SMBUS_BLOCK_MAX)
+               return -EINVAL;
+
        memcpy(ctx->dma_buffer, data, writelen);
        paddr = dma_map_single(ctx->dev, ctx->dma_buffer, writelen,
                               DMA_TO_DEVICE);
index cb5fa971d67e2a004a2be854e4b94387fff0404b..ae3af738b03f5cf73c54eb893ccec45d28ef627d 100644 (file)
@@ -561,15 +561,8 @@ static int i2c_device_probe(struct device *dev)
                goto err_detach_pm_domain;
        }
 
-       /*
-        * When there are no more users of probe(),
-        * rename probe_new to probe.
-        */
-       if (driver->probe_new)
-               status = driver->probe_new(client);
-       else if (driver->probe)
-               status = driver->probe(client,
-                                      i2c_match_id(driver->id_table, client));
+       if (driver->probe)
+               status = driver->probe(client);
        else
                status = -EINVAL;
 
@@ -1057,7 +1050,7 @@ static int dummy_probe(struct i2c_client *client)
 
 static struct i2c_driver dummy_driver = {
        .driver.name    = "dummy",
-       .probe_new      = dummy_probe,
+       .probe          = dummy_probe,
        .id_table       = dummy_id,
 };
 
index bce6b796e04c2ca0523bf1fc83117b13b4bc2c43..545436b7dd5355a5505f1c4348241d58a6157470 100644 (file)
@@ -178,6 +178,11 @@ static int of_i2c_notify(struct notifier_block *nb, unsigned long action,
                        return NOTIFY_OK;
                }
 
+               /*
+                * Clear the flag before adding the device so that fw_devlink
+                * doesn't skip adding consumers to this device.
+                */
+               rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
                client = of_i2c_register_device(adap, rd->dn);
                if (IS_ERR(client)) {
                        dev_err(&adap->dev, "failed to create client for '%pOF'\n",
index 107623c4cc14aaf95e5bf930f45ca8a179884d51..95a0b63ac560cf336a6c5204a79c65838e9a9962 100644 (file)
@@ -646,7 +646,7 @@ static void i2cdev_dev_release(struct device *dev)
        kfree(i2c_dev);
 }
 
-static int i2cdev_attach_adapter(struct device *dev, void *dummy)
+static int i2cdev_attach_adapter(struct device *dev)
 {
        struct i2c_adapter *adap;
        struct i2c_dev *i2c_dev;
@@ -685,7 +685,7 @@ err_put_i2c_dev:
        return NOTIFY_DONE;
 }
 
-static int i2cdev_detach_adapter(struct device *dev, void *dummy)
+static int i2cdev_detach_adapter(struct device *dev)
 {
        struct i2c_adapter *adap;
        struct i2c_dev *i2c_dev;
@@ -711,9 +711,9 @@ static int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action,
 
        switch (action) {
        case BUS_NOTIFY_ADD_DEVICE:
-               return i2cdev_attach_adapter(dev, NULL);
+               return i2cdev_attach_adapter(dev);
        case BUS_NOTIFY_DEL_DEVICE:
-               return i2cdev_detach_adapter(dev, NULL);
+               return i2cdev_detach_adapter(dev);
        }
 
        return NOTIFY_DONE;
@@ -725,6 +725,18 @@ static struct notifier_block i2cdev_notifier = {
 
 /* ------------------------------------------------------------------------- */
 
+static int __init i2c_dev_attach_adapter(struct device *dev, void *dummy)
+{
+       i2cdev_attach_adapter(dev);
+       return 0;
+}
+
+static int __exit i2c_dev_detach_adapter(struct device *dev, void *dummy)
+{
+       i2cdev_detach_adapter(dev);
+       return 0;
+}
+
 /*
  * module load/unload record keeping
  */
@@ -752,7 +764,7 @@ static int __init i2c_dev_init(void)
                goto out_unreg_class;
 
        /* Bind to already existing adapters right away */
-       i2c_for_each_dev(NULL, i2cdev_attach_adapter);
+       i2c_for_each_dev(NULL, i2c_dev_attach_adapter);
 
        return 0;
 
@@ -768,7 +780,7 @@ out:
 static void __exit i2c_dev_exit(void)
 {
        bus_unregister_notifier(&i2c_bus_type, &i2cdev_notifier);
-       i2c_for_each_dev(NULL, i2cdev_detach_adapter);
+       i2c_for_each_dev(NULL, i2c_dev_detach_adapter);
        class_destroy(i2c_dev_class);
        unregister_chrdev_region(MKDEV(I2C_MAJOR, 0), I2C_MINORS);
 }
index 5f25f23c4ff8cb3d3573c39f5f52118bb84e4d05..5946c0d0aef991aaa280a2df1d74d8a2ef09120f 100644 (file)
@@ -207,7 +207,7 @@ static struct i2c_driver i2c_slave_eeprom_driver = {
        .driver = {
                .name = "i2c-slave-eeprom",
        },
-       .probe_new = i2c_slave_eeprom_probe,
+       .probe = i2c_slave_eeprom_probe,
        .remove = i2c_slave_eeprom_remove,
        .id_table = i2c_slave_eeprom_id,
 };
index 75ee7ebdb614feb03436fd532e5f302bbe1199d1..a49642bbae4b7077f7fa3af34f9423d6dba58045 100644 (file)
@@ -171,7 +171,7 @@ static struct i2c_driver i2c_slave_testunit_driver = {
        .driver = {
                .name = "i2c-slave-testunit",
        },
-       .probe_new = i2c_slave_testunit_probe,
+       .probe = i2c_slave_testunit_probe,
        .remove = i2c_slave_testunit_remove,
        .id_table = i2c_slave_testunit_id,
 };
index cd19546d31fcb0f9735f432ee9f15c86d2998b01..138c3f5e0093a5c2f8ceeb6ddeca991dd70fbad6 100644 (file)
@@ -169,7 +169,7 @@ static struct i2c_driver smbalert_driver = {
        .driver = {
                .name   = "smbus_alert",
        },
-       .probe_new      = smbalert_probe,
+       .probe          = smbalert_probe,
        .remove         = smbalert_remove,
        .id_table       = smbalert_ids,
 };
index 70835825083f529d6b58fdbeb3f86b82e33ae8d9..5a03031519bee0e44eae93352142965c1f58291f 100644 (file)
@@ -306,7 +306,7 @@ static struct i2c_driver ltc4306_driver = {
                .name   = "ltc4306",
                .of_match_table = of_match_ptr(ltc4306_of_match),
        },
-       .probe_new      = ltc4306_probe,
+       .probe          = ltc4306_probe,
        .remove         = ltc4306_remove,
        .id_table       = ltc4306_id,
 };
index 09d1d9e67e31f39e5b863ced5e9a43e40de23312..ce0fb69249a8fa4a7f696ba4bbe0e7ca461717be 100644 (file)
@@ -336,7 +336,7 @@ static struct i2c_driver pca9541_driver = {
                   .name = "pca9541",
                   .of_match_table = of_match_ptr(pca9541_of_match),
                   },
-       .probe_new = pca9541_probe,
+       .probe = pca9541_probe,
        .remove = pca9541_remove,
        .id_table = pca9541_id,
 };
index 3639e6d7304cd2a13ce83420ab64cc474bf1a044..0ccee2ae57204aa7af9979f7dbd8d6495ad91981 100644 (file)
@@ -554,7 +554,7 @@ static struct i2c_driver pca954x_driver = {
                .pm     = &pca954x_pm,
                .of_match_table = pca954x_of_match,
        },
-       .probe_new      = pca954x_probe,
+       .probe          = pca954x_probe,
        .remove         = pca954x_remove,
        .id_table       = pca954x_id,
 };
index f866859855cddc9433a421829b023952808013c8..1c3a72380fb85dd8e7945e2e141996fddf947cca 100644 (file)
@@ -864,7 +864,7 @@ static irqreturn_t kx022a_trigger_handler(int irq, void *p)
        if (ret < 0)
                goto err_read;
 
-       iio_push_to_buffers_with_timestamp(idev, data->buffer, pf->timestamp);
+       iio_push_to_buffers_with_timestamp(idev, data->buffer, data->timestamp);
 err_read:
        iio_trigger_notify_done(idev->trig);
 
index fee8d129a5f0806530a98b8ab9e6681006337797..86effe8501b440fefe53636ab50dfa751200215f 100644 (file)
@@ -253,7 +253,7 @@ static const struct ad_sigma_delta_info ad7791_sigma_delta_info = {
        .has_registers = true,
        .addr_shift = 4,
        .read_mask = BIT(3),
-       .irq_flags = IRQF_TRIGGER_LOW,
+       .irq_flags = IRQF_TRIGGER_FALLING,
 };
 
 static int ad7791_read_raw(struct iio_dev *indio_dev,
index 50d02e5fc6fc125177e47805d3487badb8ef67f0..7258912fe17b758f279de776b420c206ed313f4a 100644 (file)
@@ -1409,7 +1409,7 @@ static struct iio_trigger *at91_adc_allocate_trigger(struct iio_dev *indio,
        trig = devm_iio_trigger_alloc(&indio->dev, "%s-dev%d-%s", indio->name,
                                iio_device_id(indio), trigger_name);
        if (!trig)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        trig->dev.parent = indio->dev.parent;
        iio_trigger_set_drvdata(trig, indio);
index 17370c5eb6fe32d7e164358d0d0a6a405b06d26c..ec198c6f13d6bc9a1aaafedb590ff64feca4aa75 100644 (file)
@@ -28,7 +28,6 @@ struct ltc2497_driverdata {
        struct ltc2497core_driverdata common_ddata;
        struct i2c_client *client;
        u32 recv_size;
-       u32 sub_lsb;
        /*
         * DMA (thus cache coherency maintenance) may require the
         * transfer buffers to live in their own cache lines.
@@ -65,10 +64,10 @@ static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata,
                 * equivalent to a sign extension.
                 */
                if (st->recv_size == 3) {
-                       *val = (get_unaligned_be24(st->data.d8) >> st->sub_lsb)
+                       *val = (get_unaligned_be24(st->data.d8) >> 6)
                                - BIT(ddata->chip_info->resolution + 1);
                } else {
-                       *val = (be32_to_cpu(st->data.d32) >> st->sub_lsb)
+                       *val = (be32_to_cpu(st->data.d32) >> 6)
                                - BIT(ddata->chip_info->resolution + 1);
                }
 
@@ -122,7 +121,6 @@ static int ltc2497_probe(struct i2c_client *client)
        st->common_ddata.chip_info = chip_info;
 
        resolution = chip_info->resolution;
-       st->sub_lsb = 31 - (resolution + 1);
        st->recv_size = BITS_TO_BYTES(resolution) + 1;
 
        return ltc2497core_probe(dev, indio_dev);
index b74b689ee7de7003e0996c27d49ea2a33e374c41..f6895bc9fc4b6cd6918dfb3ed515c9eb69f49b43 100644 (file)
@@ -414,13 +414,17 @@ static int max11410_sample(struct max11410_state *st, int *sample_raw,
                if (!ret)
                        return -ETIMEDOUT;
        } else {
+               int ret2;
+
                /* Wait for status register Conversion Ready flag */
-               ret = read_poll_timeout(max11410_read_reg, ret,
-                                       ret || (val & MAX11410_STATUS_CONV_READY_BIT),
+               ret = read_poll_timeout(max11410_read_reg, ret2,
+                                       ret2 || (val & MAX11410_STATUS_CONV_READY_BIT),
                                        5000, MAX11410_CONVERSION_TIMEOUT_MS * 1000,
                                        true, st, MAX11410_REG_STATUS, &val);
                if (ret)
                        return ret;
+               if (ret2)
+                       return ret2;
        }
 
        /* Read ADC Data */
@@ -851,17 +855,21 @@ static int max11410_init_vref(struct device *dev,
 
 static int max11410_calibrate(struct max11410_state *st, u32 cal_type)
 {
-       int ret, val;
+       int ret, ret2, val;
 
        ret = max11410_write_reg(st, MAX11410_REG_CAL_START, cal_type);
        if (ret)
                return ret;
 
        /* Wait for status register Calibration Ready flag */
-       return read_poll_timeout(max11410_read_reg, ret,
-                                ret || (val & MAX11410_STATUS_CAL_READY_BIT),
-                                50000, MAX11410_CALIB_TIMEOUT_MS * 1000, true,
-                                st, MAX11410_REG_STATUS, &val);
+       ret = read_poll_timeout(max11410_read_reg, ret2,
+                               ret2 || (val & MAX11410_STATUS_CAL_READY_BIT),
+                               50000, MAX11410_CALIB_TIMEOUT_MS * 1000, true,
+                               st, MAX11410_REG_STATUS, &val);
+       if (ret)
+               return ret;
+
+       return ret2;
 }
 
 static int max11410_self_calibrate(struct max11410_state *st)
index fd000345ec5cff0b1201092453547e0356446876..849a697a467e58689b7ba1ac72a8c650400852af 100644 (file)
@@ -639,7 +639,7 @@ out:
 
 static int palmas_gpadc_remove(struct platform_device *pdev)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(&pdev->dev);
+       struct iio_dev *indio_dev = dev_get_drvdata(&pdev->dev);
        struct palmas_gpadc *adc = iio_priv(indio_dev);
 
        if (adc->wakeup1_enable || adc->wakeup2_enable)
index e90c299c913a2aa9d4033cb833872370c23d2655..c2d5e06f137a7e64f66a112b9cc47c5de2e6d309 100644 (file)
@@ -628,12 +628,20 @@ static int adc5_get_fw_channel_data(struct adc5_chip *adc,
                                    struct fwnode_handle *fwnode,
                                    const struct adc5_data *data)
 {
-       const char *name = fwnode_get_name(fwnode), *channel_name;
+       const char *channel_name;
+       char *name;
        u32 chan, value, varr[2];
        u32 sid = 0;
        int ret;
        struct device *dev = adc->dev;
 
+       name = devm_kasprintf(dev, GFP_KERNEL, "%pfwP", fwnode);
+       if (!name)
+               return -ENOMEM;
+
+       /* Cut the address part */
+       name[strchrnul(name, '@') - name] = '\0';
+
        ret = fwnode_property_read_u32(fwnode, "reg", &chan);
        if (ret) {
                dev_err(dev, "invalid channel number %s\n", name);
index 2cc9a9bd9db60f97b857f6d726f3af176556a898..263fc3a1b87e1d97f215e39b489264eefdfa8442 100644 (file)
@@ -634,6 +634,7 @@ static int ti_ads7950_probe(struct spi_device *spi)
        st->chip.label = dev_name(&st->spi->dev);
        st->chip.parent = &st->spi->dev;
        st->chip.owner = THIS_MODULE;
+       st->chip.can_sleep = true;
        st->chip.base = -1;
        st->chip.ngpio = TI_ADS7950_NUM_GPIOS;
        st->chip.get_direction = ti_ads7950_get_direction;
index beadfa938d2da856d4d11e2ed322fac52ec433f2..404865e354602cb077393479b77d5e32d45c6b51 100644 (file)
@@ -802,6 +802,7 @@ static struct ad5755_platform_data *ad5755_parse_fw(struct device *dev)
        return pdata;
 
  error_out:
+       fwnode_handle_put(pp);
        devm_kfree(dev, pdata);
        return NULL;
 }
index 791dd999cf291ec5394ec196f0ca6d2b16e98c45..18a64f72fc188dbb0d47ed84860e7e07ba8e2a78 100644 (file)
@@ -66,8 +66,8 @@ static int cio_dac_write_raw(struct iio_dev *indio_dev,
        if (mask != IIO_CHAN_INFO_RAW)
                return -EINVAL;
 
-       /* DAC can only accept up to a 16-bit value */
-       if ((unsigned int)val > 65535)
+       /* DAC can only accept up to a 12-bit value */
+       if ((unsigned int)val > 4095)
                return -EINVAL;
 
        priv->chan_out_states[chan->channel] = val;
index f1d7d4b5e22243134967418b491fbf2cc5ccda47..c2f97629e9cdb6f726ecd7b9053b9b5e9137f825 100644 (file)
@@ -47,6 +47,7 @@ config ADIS16480
        depends on SPI
        select IIO_ADIS_LIB
        select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
+       select CRC32
        help
          Say yes here to build support for Analog Devices ADIS16375, ADIS16480,
          ADIS16485, ADIS16488 inertial sensors.
index 80c78bd6bbef4970fe39149bddd06b361ad9c74c..a7a080bed1808f1f763bdb6dfff7c939c95a2bc8 100644 (file)
@@ -203,24 +203,27 @@ static ssize_t iio_buffer_write(struct file *filp, const char __user *buf,
                                break;
                        }
 
+                       if (filp->f_flags & O_NONBLOCK) {
+                               if (!written)
+                                       ret = -EAGAIN;
+                               break;
+                       }
+
                        wait_woken(&wait, TASK_INTERRUPTIBLE,
                                        MAX_SCHEDULE_TIMEOUT);
                        continue;
                }
 
                ret = rb->access->write(rb, n - written, buf + written);
-               if (ret == 0 && (filp->f_flags & O_NONBLOCK))
-                       ret = -EAGAIN;
+               if (ret < 0)
+                       break;
 
-               if (ret > 0) {
-                       written += ret;
-                       if (written != n && !(filp->f_flags & O_NONBLOCK))
-                               continue;
-               }
-       } while (ret == 0);
+               written += ret;
+
+       } while (written != n);
        remove_wait_queue(&rb->pollq, &wait);
 
-       return ret < 0 ? ret : n;
+       return ret < 0 ? ret : written;
 }
 
 /**
index b1674a5bfa368d048b9c3629148e7daec8f0a3f0..d4a34a3bf00d9503fbeff879f1a86278ad159d4e 100644 (file)
@@ -429,6 +429,14 @@ static const struct iio_info cm32181_info = {
        .attrs                  = &cm32181_attribute_group,
 };
 
+static void cm32181_unregister_dummy_client(void *data)
+{
+       struct i2c_client *client = data;
+
+       /* Unregister the dummy client */
+       i2c_unregister_device(client);
+}
+
 static int cm32181_probe(struct i2c_client *client)
 {
        struct device *dev = &client->dev;
@@ -460,6 +468,10 @@ static int cm32181_probe(struct i2c_client *client)
                client = i2c_acpi_new_device(dev, 1, &board_info);
                if (IS_ERR(client))
                        return PTR_ERR(client);
+
+               ret = devm_add_action_or_reset(dev, cm32181_unregister_dummy_client, client);
+               if (ret)
+                       return ret;
        }
 
        cm32181 = iio_priv(indio_dev);
index ad50baa0202cceda80600b8fdd187d478c4351fb..e823c145f6792ee4204697f902d238c0a1b9f440 100644 (file)
@@ -601,6 +601,7 @@ static int tsl2772_read_prox_diodes(struct tsl2772_chip *chip)
                        return -EINVAL;
                }
        }
+       chip->settings.prox_diode = prox_diode_mask;
 
        return 0;
 }
index 6bdfce9747f926088ba9b0f2468e772174c39397..5c44a36ab5b3951896e05c412164d3ead97e4766 100644 (file)
@@ -208,7 +208,6 @@ static int vcnl4000_init(struct vcnl4000_data *data)
 
        data->rev = ret & 0xf;
        data->al_scale = 250000;
-       mutex_init(&data->vcnl4000_lock);
 
        return data->chip_spec->set_power_state(data, true);
 };
@@ -1367,6 +1366,8 @@ static int vcnl4000_probe(struct i2c_client *client)
        data->id = id->driver_data;
        data->chip_spec = &vcnl4000_chip_spec_cfg[data->id];
 
+       mutex_init(&data->vcnl4000_lock);
+
        ret = data->chip_spec->init(data);
        if (ret < 0)
                return ret;
index 3081559377133e4df5f55789435130e48c415d52..6b9563d4f23c94dfab6dbff02a601942a7b315d4 100644 (file)
@@ -624,22 +624,11 @@ static inline unsigned short cma_family(struct rdma_id_private *id_priv)
        return id_priv->id.route.addr.src_addr.ss_family;
 }
 
-static int cma_set_qkey(struct rdma_id_private *id_priv, u32 qkey)
+static int cma_set_default_qkey(struct rdma_id_private *id_priv)
 {
        struct ib_sa_mcmember_rec rec;
        int ret = 0;
 
-       if (id_priv->qkey) {
-               if (qkey && id_priv->qkey != qkey)
-                       return -EINVAL;
-               return 0;
-       }
-
-       if (qkey) {
-               id_priv->qkey = qkey;
-               return 0;
-       }
-
        switch (id_priv->id.ps) {
        case RDMA_PS_UDP:
        case RDMA_PS_IB:
@@ -659,6 +648,16 @@ static int cma_set_qkey(struct rdma_id_private *id_priv, u32 qkey)
        return ret;
 }
 
+static int cma_set_qkey(struct rdma_id_private *id_priv, u32 qkey)
+{
+       if (!qkey ||
+           (id_priv->qkey && (id_priv->qkey != qkey)))
+               return -EINVAL;
+
+       id_priv->qkey = qkey;
+       return 0;
+}
+
 static void cma_translate_ib(struct sockaddr_ib *sib, struct rdma_dev_addr *dev_addr)
 {
        dev_addr->dev_type = ARPHRD_INFINIBAND;
@@ -1229,7 +1228,7 @@ static int cma_ib_init_qp_attr(struct rdma_id_private *id_priv,
        *qp_attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT;
 
        if (id_priv->id.qp_type == IB_QPT_UD) {
-               ret = cma_set_qkey(id_priv, 0);
+               ret = cma_set_default_qkey(id_priv);
                if (ret)
                        return ret;
 
@@ -4569,7 +4568,10 @@ static int cma_send_sidr_rep(struct rdma_id_private *id_priv,
        memset(&rep, 0, sizeof rep);
        rep.status = status;
        if (status == IB_SIDR_SUCCESS) {
-               ret = cma_set_qkey(id_priv, qkey);
+               if (qkey)
+                       ret = cma_set_qkey(id_priv, qkey);
+               else
+                       ret = cma_set_default_qkey(id_priv);
                if (ret)
                        return ret;
                rep.qp_num = id_priv->qp_num;
@@ -4774,9 +4776,7 @@ static void cma_make_mc_event(int status, struct rdma_id_private *id_priv,
        enum ib_gid_type gid_type;
        struct net_device *ndev;
 
-       if (!status)
-               status = cma_set_qkey(id_priv, be32_to_cpu(multicast->rec.qkey));
-       else
+       if (status)
                pr_debug_ratelimited("RDMA CM: MULTICAST_ERROR: failed to join multicast. status %d\n",
                                     status);
 
@@ -4804,7 +4804,7 @@ static void cma_make_mc_event(int status, struct rdma_id_private *id_priv,
        }
 
        event->param.ud.qp_num = 0xFFFFFF;
-       event->param.ud.qkey = be32_to_cpu(multicast->rec.qkey);
+       event->param.ud.qkey = id_priv->qkey;
 
 out:
        if (ndev)
@@ -4823,8 +4823,11 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast)
            READ_ONCE(id_priv->state) == RDMA_CM_DESTROYING)
                goto out;
 
-       cma_make_mc_event(status, id_priv, multicast, &event, mc);
-       ret = cma_cm_event_handler(id_priv, &event);
+       ret = cma_set_qkey(id_priv, be32_to_cpu(multicast->rec.qkey));
+       if (!ret) {
+               cma_make_mc_event(status, id_priv, multicast, &event, mc);
+               ret = cma_cm_event_handler(id_priv, &event);
+       }
        rdma_destroy_ah_attr(&event.param.ud.ah_attr);
        WARN_ON(ret);
 
@@ -4877,9 +4880,11 @@ static int cma_join_ib_multicast(struct rdma_id_private *id_priv,
        if (ret)
                return ret;
 
-       ret = cma_set_qkey(id_priv, 0);
-       if (ret)
-               return ret;
+       if (!id_priv->qkey) {
+               ret = cma_set_default_qkey(id_priv);
+               if (ret)
+                       return ret;
+       }
 
        cma_set_mgid(id_priv, (struct sockaddr *) &mc->addr, &rec.mgid);
        rec.qkey = cpu_to_be32(id_priv->qkey);
@@ -4956,9 +4961,6 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
        cma_iboe_set_mgid(addr, &ib.rec.mgid, gid_type);
 
        ib.rec.pkey = cpu_to_be16(0xffff);
-       if (id_priv->id.ps == RDMA_PS_UDP)
-               ib.rec.qkey = cpu_to_be32(RDMA_UDP_QKEY);
-
        if (dev_addr->bound_dev_if)
                ndev = dev_get_by_index(dev_addr->net, dev_addr->bound_dev_if);
        if (!ndev)
@@ -4984,6 +4986,9 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
        if (err || !ib.rec.mtu)
                return err ?: -EINVAL;
 
+       if (!id_priv->qkey)
+               cma_set_default_qkey(id_priv);
+
        rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.src_addr,
                    &ib.rec.port_gid);
        INIT_WORK(&mc->iboe_join.work, cma_iboe_join_work_handler);
@@ -5009,6 +5014,9 @@ int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,
                            READ_ONCE(id_priv->state) != RDMA_CM_ADDR_RESOLVED))
                return -EINVAL;
 
+       if (id_priv->id.qp_type != IB_QPT_UD)
+               return -EINVAL;
+
        mc = kzalloc(sizeof(*mc), GFP_KERNEL);
        if (!mc)
                return -ENOMEM;
index 11b1c1603aeb44e6d0dcbc3904a57a5bf314d03e..b99b3cc283b650b9d001bccbfe0bcfdee6100573 100644 (file)
@@ -532,6 +532,8 @@ static struct ib_ah *_rdma_create_ah(struct ib_pd *pd,
        else
                ret = device->ops.create_ah(ah, &init_attr, NULL);
        if (ret) {
+               if (ah->sgid_attr)
+                       rdma_put_gid_attr(ah->sgid_attr);
                kfree(ah);
                return ERR_PTR(ret);
        }
index cabd8678b3558963b3069304ba5372ea0233b3a0..7bc354273d4ec00542efeeca47c384aa7431ad43 100644 (file)
@@ -65,7 +65,7 @@ static const enum ib_wc_opcode wc_mapping_table[ERDMA_NUM_OPCODES] = {
        [ERDMA_OP_LOCAL_INV] = IB_WC_LOCAL_INV,
        [ERDMA_OP_READ_WITH_INV] = IB_WC_RDMA_READ,
        [ERDMA_OP_ATOMIC_CAS] = IB_WC_COMP_SWAP,
-       [ERDMA_OP_ATOMIC_FAD] = IB_WC_FETCH_ADD,
+       [ERDMA_OP_ATOMIC_FAA] = IB_WC_FETCH_ADD,
 };
 
 static const struct {
index 4c38d99c73f1cb1b7044e94d9999da51605fe5d7..37ad1bb1917c4931dd74b1fb3e2ab55784aa8d73 100644 (file)
@@ -441,7 +441,7 @@ struct erdma_reg_mr_sqe {
 };
 
 /* EQ related. */
-#define ERDMA_DEFAULT_EQ_DEPTH 256
+#define ERDMA_DEFAULT_EQ_DEPTH 4096
 
 /* ceqe */
 #define ERDMA_CEQE_HDR_DB_MASK BIT_ULL(63)
@@ -491,7 +491,7 @@ enum erdma_opcode {
        ERDMA_OP_LOCAL_INV = 15,
        ERDMA_OP_READ_WITH_INV = 16,
        ERDMA_OP_ATOMIC_CAS = 17,
-       ERDMA_OP_ATOMIC_FAD = 18,
+       ERDMA_OP_ATOMIC_FAA = 18,
        ERDMA_NUM_OPCODES = 19,
        ERDMA_OP_INVALID = ERDMA_NUM_OPCODES + 1
 };
index 5dc31e5df5cba78ca1025120186fbe891e4551c3..4a29a53a6652eacde0bf5619a3b63850cf9faf2a 100644 (file)
@@ -56,7 +56,7 @@ done:
 static int erdma_enum_and_get_netdev(struct erdma_dev *dev)
 {
        struct net_device *netdev;
-       int ret = -ENODEV;
+       int ret = -EPROBE_DEFER;
 
        /* Already binded to a net_device, so we skip. */
        if (dev->netdev)
index d088d6bef431afa8c6936219dd2f60a6ce46942e..44923c51a01b44d7dc322fd472e0a0988d8dec2b 100644 (file)
@@ -405,7 +405,7 @@ static int erdma_push_one_sqe(struct erdma_qp *qp, u16 *pi,
                        FIELD_PREP(ERDMA_SQE_MR_MTT_CNT_MASK,
                                   mr->mem.mtt_nents);
 
-               if (mr->mem.mtt_nents < ERDMA_MAX_INLINE_MTT_ENTRIES) {
+               if (mr->mem.mtt_nents <= ERDMA_MAX_INLINE_MTT_ENTRIES) {
                        attrs |= FIELD_PREP(ERDMA_SQE_MR_MTT_TYPE_MASK, 0);
                        /* Copy SGLs to SQE content to accelerate */
                        memcpy(get_queue_entry(qp->kern_qp.sq_buf, idx + 1,
@@ -439,7 +439,7 @@ static int erdma_push_one_sqe(struct erdma_qp *qp, u16 *pi,
                                cpu_to_le64(atomic_wr(send_wr)->compare_add);
                } else {
                        wqe_hdr |= FIELD_PREP(ERDMA_SQE_HDR_OPCODE_MASK,
-                                             ERDMA_OP_ATOMIC_FAD);
+                                             ERDMA_OP_ATOMIC_FAA);
                        atomic_sqe->fetchadd_swap_data =
                                cpu_to_le64(atomic_wr(send_wr)->compare_add);
                }
index e0a993bc032a44aaa76e399ead33ccf8f6f0734e..131cf5f409822cb50daa57a8a24b17d4136dd393 100644 (file)
@@ -11,7 +11,7 @@
 
 /* RDMA Capability. */
 #define ERDMA_MAX_PD (128 * 1024)
-#define ERDMA_MAX_SEND_WR 4096
+#define ERDMA_MAX_SEND_WR 8192
 #define ERDMA_MAX_ORD 128
 #define ERDMA_MAX_IRD 128
 #define ERDMA_MAX_SGE_RD 1
index b1d6ca7e970830aef6eedee06f069ad8f5a0984b..f3d6ce45c3974764f3d8956f98e4133b35ef6d22 100644 (file)
@@ -267,6 +267,8 @@ static ssize_t hfi1_write_iter(struct kiocb *kiocb, struct iov_iter *from)
 
        if (!HFI1_CAP_IS_KSET(SDMA))
                return -EINVAL;
+       if (!from->user_backed)
+               return -EINVAL;
        idx = srcu_read_lock(&fd->pq_srcu);
        pq = srcu_dereference(fd->pq, &fd->pq_srcu);
        if (!cq || !pq) {
@@ -274,11 +276,6 @@ static ssize_t hfi1_write_iter(struct kiocb *kiocb, struct iov_iter *from)
                return -EIO;
        }
 
-       if (!iter_is_iovec(from) || !dim) {
-               srcu_read_unlock(&fd->pq_srcu, idx);
-               return -EINVAL;
-       }
-
        trace_hfi1_sdma_request(fd->dd, fd->uctxt->ctxt, fd->subctxt, dim);
 
        if (atomic_read(&pq->n_reqs) == pq->n_max_reqs) {
@@ -287,11 +284,12 @@ static ssize_t hfi1_write_iter(struct kiocb *kiocb, struct iov_iter *from)
        }
 
        while (dim) {
+               const struct iovec *iov = iter_iov(from);
                int ret;
                unsigned long count = 0;
 
                ret = hfi1_user_sdma_process_request(
-                       fd, (struct iovec *)(from->iov + done),
+                       fd, (struct iovec *)(iov + done),
                        dim, &count);
                if (ret) {
                        reqs = ret;
index 195aa9ea18b6ca74c24dc7c45a24d693cedece9b..8817864154af1f079eda127f648085b2d9107999 100644 (file)
@@ -1458,13 +1458,15 @@ static int irdma_send_fin(struct irdma_cm_node *cm_node)
  * irdma_find_listener - find a cm node listening on this addr-port pair
  * @cm_core: cm's core
  * @dst_addr: listener ip addr
+ * @ipv4: flag indicating IPv4 when true
  * @dst_port: listener tcp port num
  * @vlan_id: virtual LAN ID
  * @listener_state: state to match with listen node's
  */
 static struct irdma_cm_listener *
-irdma_find_listener(struct irdma_cm_core *cm_core, u32 *dst_addr, u16 dst_port,
-                   u16 vlan_id, enum irdma_cm_listener_state listener_state)
+irdma_find_listener(struct irdma_cm_core *cm_core, u32 *dst_addr, bool ipv4,
+                   u16 dst_port, u16 vlan_id,
+                   enum irdma_cm_listener_state listener_state)
 {
        struct irdma_cm_listener *listen_node;
        static const u32 ip_zero[4] = { 0, 0, 0, 0 };
@@ -1477,7 +1479,7 @@ irdma_find_listener(struct irdma_cm_core *cm_core, u32 *dst_addr, u16 dst_port,
        list_for_each_entry (listen_node, &cm_core->listen_list, list) {
                memcpy(listen_addr, listen_node->loc_addr, sizeof(listen_addr));
                listen_port = listen_node->loc_port;
-               if (listen_port != dst_port ||
+               if (listen_node->ipv4 != ipv4 || listen_port != dst_port ||
                    !(listener_state & listen_node->listener_state))
                        continue;
                /* compare node pair, return node handle if a match */
@@ -2902,9 +2904,10 @@ irdma_make_listen_node(struct irdma_cm_core *cm_core,
        unsigned long flags;
 
        /* cannot have multiple matching listeners */
-       listener = irdma_find_listener(cm_core, cm_info->loc_addr,
-                                      cm_info->loc_port, cm_info->vlan_id,
-                                      IRDMA_CM_LISTENER_EITHER_STATE);
+       listener =
+               irdma_find_listener(cm_core, cm_info->loc_addr, cm_info->ipv4,
+                                   cm_info->loc_port, cm_info->vlan_id,
+                                   IRDMA_CM_LISTENER_EITHER_STATE);
        if (listener &&
            listener->listener_state == IRDMA_CM_LISTENER_ACTIVE_STATE) {
                refcount_dec(&listener->refcnt);
@@ -3153,6 +3156,7 @@ void irdma_receive_ilq(struct irdma_sc_vsi *vsi, struct irdma_puda_buf *rbuf)
 
                listener = irdma_find_listener(cm_core,
                                               cm_info.loc_addr,
+                                              cm_info.ipv4,
                                               cm_info.loc_port,
                                               cm_info.vlan_id,
                                               IRDMA_CM_LISTENER_ACTIVE_STATE);
index 19c284975fc7c874cc62d1253d4b60664c1a8aa9..7feadb3e1eda343c1fcfc1d6a47ff035317ae94c 100644 (file)
@@ -41,7 +41,7 @@
 #define TCP_OPTIONS_PADDING    3
 
 #define IRDMA_DEFAULT_RETRYS   64
-#define IRDMA_DEFAULT_RETRANS  8
+#define IRDMA_DEFAULT_RETRANS  32
 #define IRDMA_DEFAULT_TTL              0x40
 #define IRDMA_DEFAULT_RTT_VAR          6
 #define IRDMA_DEFAULT_SS_THRESH                0x3fffffff
index 2e1e2bad04011a42e4e025eb46774d2feaf7307b..43dfa4761f0698e5530ae403dcc68a9cff85a9cf 100644 (file)
@@ -41,6 +41,7 @@ static enum irdma_hmc_rsrc_type iw_hmc_obj_types[] = {
        IRDMA_HMC_IW_XFFL,
        IRDMA_HMC_IW_Q1,
        IRDMA_HMC_IW_Q1FL,
+       IRDMA_HMC_IW_PBLE,
        IRDMA_HMC_IW_TIMER,
        IRDMA_HMC_IW_FSIMC,
        IRDMA_HMC_IW_FSIAV,
@@ -827,6 +828,8 @@ static int irdma_create_hmc_objs(struct irdma_pci_f *rf, bool privileged,
        info.entry_type = rf->sd_type;
 
        for (i = 0; i < IW_HMC_OBJ_TYPE_NUM; i++) {
+               if (iw_hmc_obj_types[i] == IRDMA_HMC_IW_PBLE)
+                       continue;
                if (dev->hmc_info->hmc_obj[iw_hmc_obj_types[i]].cnt) {
                        info.rsrc_type = iw_hmc_obj_types[i];
                        info.count = dev->hmc_info->hmc_obj[info.rsrc_type].cnt;
index 445e69e864097ef85adbf351387eccd08150ffcb..7887230c867b1efd784ff5415e9704eff96044c6 100644 (file)
@@ -2595,7 +2595,10 @@ void irdma_generate_flush_completions(struct irdma_qp *iwqp)
                        /* remove the SQ WR by moving SQ tail*/
                        IRDMA_RING_SET_TAIL(*sq_ring,
                                sq_ring->tail + qp->sq_wrtrk_array[sq_ring->tail].quanta);
-
+                       if (cmpl->cpi.op_type == IRDMAQP_OP_NOP) {
+                               kfree(cmpl);
+                               continue;
+                       }
                        ibdev_dbg(iwqp->iwscq->ibcq.device,
                                  "DEV: %s: adding wr_id = 0x%llx SQ Completion to list qp_id=%d\n",
                                  __func__, cmpl->cpi.wr_id, qp->qp_id);
index 5b988db66b8fdb90c8c9303bbe29d4d3ec6f0a54..5d45de223c43a9afed62a70265b9e32d75db4e10 100644 (file)
@@ -442,6 +442,10 @@ static int translate_eth_ext_proto_oper(u32 eth_proto_oper, u16 *active_speed,
                *active_width = IB_WIDTH_2X;
                *active_speed = IB_SPEED_NDR;
                break;
+       case MLX5E_PROT_MASK(MLX5E_400GAUI_8):
+               *active_width = IB_WIDTH_8X;
+               *active_speed = IB_SPEED_HDR;
+               break;
        case MLX5E_PROT_MASK(MLX5E_400GAUI_4_400GBASE_CR4_KR4):
                *active_width = IB_WIDTH_4X;
                *active_speed = IB_SPEED_NDR;
index 80fe92a21f960e341eb85e3c27b6fb2ae89d66cd..815ea72ad4739836eb299ab482c621aaf795e716 100644 (file)
@@ -2245,10 +2245,10 @@ static ssize_t qib_write_iter(struct kiocb *iocb, struct iov_iter *from)
        struct qib_ctxtdata *rcd = ctxt_fp(iocb->ki_filp);
        struct qib_user_sdma_queue *pq = fp->pq;
 
-       if (!iter_is_iovec(from) || !from->nr_segs || !pq)
+       if (!from->user_backed || !from->nr_segs || !pq)
                return -EINVAL;
 
-       return qib_user_sdma_writev(rcd, pq, from->iov, from->nr_segs);
+       return qib_user_sdma_writev(rcd, pq, iter_iov(from), from->nr_segs);
 }
 
 static struct class *qib_class;
index 3acab569fbb94aa668b18e1c06c190ce199970f9..9b4c0389d2c006c41ae6967420ed77fa42ca285b 100644 (file)
@@ -97,7 +97,7 @@ static void cacheless_memcpy(void *dst, void *src, size_t n)
         * there are no security issues.  The extra fault recovery machinery
         * is not invoked.
         */
-       __copy_user_nocache(dst, (void __user *)src, n, 0);
+       __copy_user_nocache(dst, (void __user *)src, n);
 }
 
 void rvt_wss_exit(struct rvt_dev_info *rdi)
index f642ec8e92ddd4bacebbf0046256af54ef363348..29131f1a2f067166eef3638d60546304c941e786 100644 (file)
@@ -781,9 +781,6 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
        input_report_key(dev, BTN_C, data[8]);
        input_report_key(dev, BTN_Z, data[9]);
 
-       /* Profile button has a value of 0-3, so it is reported as an axis */
-       if (xpad->mapping & MAP_PROFILE_BUTTON)
-               input_report_abs(dev, ABS_PROFILE, data[34]);
 
        input_sync(dev);
 }
@@ -1061,6 +1058,10 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char
                                        (__u16) le16_to_cpup((__le16 *)(data + 8)));
                }
 
+               /* Profile button has a value of 0-3, so it is reported as an axis */
+               if (xpad->mapping & MAP_PROFILE_BUTTON)
+                       input_report_abs(dev, ABS_PROFILE, data[34]);
+
                /* paddle handling */
                /* based on SDL's SDL_hidapi_xboxone.c */
                if (xpad->mapping & MAP_PADDLES) {
index 989228b5a0a44d050fa83f291d7c2bd32b576a1e..e2c11d9f3868f3ea2ec05a4230472070e32d20a4 100644 (file)
@@ -852,8 +852,8 @@ static void alps_process_packet_v6(struct psmouse *psmouse)
                        x = y = z = 0;
 
                /* Divide 4 since trackpoint's speed is too fast */
-               input_report_rel(dev2, REL_X, (char)x / 4);
-               input_report_rel(dev2, REL_Y, -((char)y / 4));
+               input_report_rel(dev2, REL_X, (s8)x / 4);
+               input_report_rel(dev2, REL_Y, -((s8)y / 4));
 
                psmouse_report_standard_buttons(dev2, packet[3]);
 
@@ -1104,8 +1104,8 @@ static void alps_process_trackstick_packet_v7(struct psmouse *psmouse)
            ((packet[3] & 0x20) << 1);
        z = (packet[5] & 0x3f) | ((packet[3] & 0x80) >> 1);
 
-       input_report_rel(dev2, REL_X, (char)x);
-       input_report_rel(dev2, REL_Y, -((char)y));
+       input_report_rel(dev2, REL_X, (s8)x);
+       input_report_rel(dev2, REL_Y, -((s8)y));
        input_report_abs(dev2, ABS_PRESSURE, z);
 
        psmouse_report_standard_buttons(dev2, packet[1]);
@@ -2294,20 +2294,20 @@ static int alps_get_v3_v7_resolution(struct psmouse *psmouse, int reg_pitch)
        if (reg < 0)
                return reg;
 
-       x_pitch = (char)(reg << 4) >> 4; /* sign extend lower 4 bits */
+       x_pitch = (s8)(reg << 4) >> 4; /* sign extend lower 4 bits */
        x_pitch = 50 + 2 * x_pitch; /* In 0.1 mm units */
 
-       y_pitch = (char)reg >> 4; /* sign extend upper 4 bits */
+       y_pitch = (s8)reg >> 4; /* sign extend upper 4 bits */
        y_pitch = 36 + 2 * y_pitch; /* In 0.1 mm units */
 
        reg = alps_command_mode_read_reg(psmouse, reg_pitch + 1);
        if (reg < 0)
                return reg;
 
-       x_electrode = (char)(reg << 4) >> 4; /* sign extend lower 4 bits */
+       x_electrode = (s8)(reg << 4) >> 4; /* sign extend lower 4 bits */
        x_electrode = 17 + x_electrode;
 
-       y_electrode = (char)reg >> 4; /* sign extend upper 4 bits */
+       y_electrode = (s8)reg >> 4; /* sign extend upper 4 bits */
        y_electrode = 13 + y_electrode;
 
        x_phys = x_pitch * (x_electrode - 1); /* In 0.1 mm units */
index 6fd5fff0cbfffd752748d995bab8256c12c9e258..c74b99077d16a35637c1d0c015a772cea687c13b 100644 (file)
@@ -202,8 +202,8 @@ static void focaltech_process_rel_packet(struct psmouse *psmouse,
        state->pressed = packet[0] >> 7;
        finger1 = ((packet[0] >> 4) & 0x7) - 1;
        if (finger1 < FOC_MAX_FINGERS) {
-               state->fingers[finger1].x += (char)packet[1];
-               state->fingers[finger1].y += (char)packet[2];
+               state->fingers[finger1].x += (s8)packet[1];
+               state->fingers[finger1].y += (s8)packet[2];
        } else {
                psmouse_err(psmouse, "First finger in rel packet invalid: %d\n",
                            finger1);
@@ -218,8 +218,8 @@ static void focaltech_process_rel_packet(struct psmouse *psmouse,
         */
        finger2 = ((packet[3] >> 4) & 0x7) - 1;
        if (finger2 < FOC_MAX_FINGERS) {
-               state->fingers[finger2].x += (char)packet[4];
-               state->fingers[finger2].y += (char)packet[5];
+               state->fingers[finger2].x += (s8)packet[4];
+               state->fingers[finger2].y += (s8)packet[5];
        }
 }
 
index efc61736099b9a606951b8274a6deebbd8488fa0..028e45bd050bf3f151cee382b666bfce86775ee7 100644 (file)
@@ -610,6 +610,14 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
                },
                .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
+       {
+               /* Fujitsu Lifebook A574/H */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "FMVA0501PZ"),
+               },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
+       },
        {
                /* Gigabyte M912 */
                .matches = {
@@ -1116,6 +1124,20 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
                .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
                                        SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
+       {
+               /*
+                * Setting SERIO_QUIRK_NOMUX or SERIO_QUIRK_RESET_ALWAYS makes
+                * the keyboard very laggy for ~5 seconds after boot and
+                * sometimes also after resume.
+                * However both are required for the keyboard to not fail
+                * completely sometimes after boot or resume.
+                */
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_NAME, "N150CU"),
+               },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
+       },
        {
                .matches = {
                        DMI_MATCH(DMI_BOARD_NAME, "NH5xAx"),
@@ -1123,6 +1145,20 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
                .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
                                        SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
+       {
+               /*
+                * Setting SERIO_QUIRK_NOMUX or SERIO_QUIRK_RESET_ALWAYS makes
+                * the keyboard very laggy for ~5 seconds after boot and
+                * sometimes also after resume.
+                * However both are required for the keyboard to not fail
+                * completely sometimes after boot or resume.
+                */
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_NAME, "NHxxRZQ"),
+               },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
+       },
        {
                .matches = {
                        DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
index d836d3dcc6a2491905535f0c8fcab35d5ae6b541..a68da2988f9cd828942b5a23eed5efd5576cb7f5 100644 (file)
@@ -296,6 +296,12 @@ static int pegasus_probe(struct usb_interface *intf,
        pegasus->intf = intf;
 
        pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
+       /* Sanity check that pipe's type matches endpoint's type */
+       if (usb_pipe_type_check(dev, pipe)) {
+               error = -EINVAL;
+               goto err_free_mem;
+       }
+
        pegasus->data_len = usb_maxpacket(dev, pipe);
 
        pegasus->data = usb_alloc_coherent(dev, pegasus->data_len, GFP_KERNEL,
index 16caffa35dd99ed0cf7944b68298d2b46f5cab1c..30102cb80fac823ae47a27cc64a540a78211e656 100644 (file)
@@ -111,6 +111,7 @@ struct cyttsp5_sensing_conf_data_dev {
        __le16 max_z;
        u8 origin_x;
        u8 origin_y;
+       u8 panel_id;
        u8 btn;
        u8 scan_mode;
        u8 max_num_of_tch_per_refresh_cycle;
index b348172f19c3de1ae79c70b1a1fccfebfacd17db..d77f116680a0a098ffaa06f8c33666dff092fd4a 100644 (file)
@@ -124,10 +124,18 @@ static const unsigned long goodix_irq_flags[] = {
 static const struct dmi_system_id nine_bytes_report[] = {
 #if defined(CONFIG_DMI) && defined(CONFIG_X86)
        {
-               .ident = "Lenovo YogaBook",
-               /* YB1-X91L/F and YB1-X90L/F */
+               /* Lenovo Yoga Book X90F / X90L */
                .matches = {
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9")
+                       DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"),
+               }
+       },
+       {
+               /* Lenovo Yoga Book X91F / X91L */
+               .matches = {
+                       /* Non exact match to match F + L versions */
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"),
                }
        },
 #endif
index 0f392f59b1353142188dcc12774b9c53dcb181f0..7a24c1444ace3c50e4727dd757c123c74fc05b17 100644 (file)
@@ -850,6 +850,10 @@ void icc_node_destroy(int id)
 
        mutex_unlock(&icc_lock);
 
+       if (!node)
+               return;
+
+       kfree(node->links);
        kfree(node);
 }
 EXPORT_SYMBOL_GPL(icc_node_destroy);
@@ -1029,54 +1033,68 @@ int icc_nodes_remove(struct icc_provider *provider)
 EXPORT_SYMBOL_GPL(icc_nodes_remove);
 
 /**
- * icc_provider_add() - add a new interconnect provider
- * @provider: the interconnect provider that will be added into topology
+ * icc_provider_init() - initialize a new interconnect provider
+ * @provider: the interconnect provider to initialize
+ *
+ * Must be called before adding nodes to the provider.
+ */
+void icc_provider_init(struct icc_provider *provider)
+{
+       WARN_ON(!provider->set);
+
+       INIT_LIST_HEAD(&provider->nodes);
+}
+EXPORT_SYMBOL_GPL(icc_provider_init);
+
+/**
+ * icc_provider_register() - register a new interconnect provider
+ * @provider: the interconnect provider to register
  *
  * Return: 0 on success, or an error code otherwise
  */
-int icc_provider_add(struct icc_provider *provider)
+int icc_provider_register(struct icc_provider *provider)
 {
-       if (WARN_ON(!provider->set))
-               return -EINVAL;
        if (WARN_ON(!provider->xlate && !provider->xlate_extended))
                return -EINVAL;
 
        mutex_lock(&icc_lock);
-
-       INIT_LIST_HEAD(&provider->nodes);
        list_add_tail(&provider->provider_list, &icc_providers);
-
        mutex_unlock(&icc_lock);
 
-       dev_dbg(provider->dev, "interconnect provider added to topology\n");
+       dev_dbg(provider->dev, "interconnect provider registered\n");
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(icc_provider_add);
+EXPORT_SYMBOL_GPL(icc_provider_register);
 
 /**
- * icc_provider_del() - delete previously added interconnect provider
- * @provider: the interconnect provider that will be removed from topology
+ * icc_provider_deregister() - deregister an interconnect provider
+ * @provider: the interconnect provider to deregister
  */
-void icc_provider_del(struct icc_provider *provider)
+void icc_provider_deregister(struct icc_provider *provider)
 {
        mutex_lock(&icc_lock);
-       if (provider->users) {
-               pr_warn("interconnect provider still has %d users\n",
-                       provider->users);
-               mutex_unlock(&icc_lock);
-               return;
-       }
-
-       if (!list_empty(&provider->nodes)) {
-               pr_warn("interconnect provider still has nodes\n");
-               mutex_unlock(&icc_lock);
-               return;
-       }
+       WARN_ON(provider->users);
 
        list_del(&provider->provider_list);
        mutex_unlock(&icc_lock);
 }
+EXPORT_SYMBOL_GPL(icc_provider_deregister);
+
+int icc_provider_add(struct icc_provider *provider)
+{
+       icc_provider_init(provider);
+
+       return icc_provider_register(provider);
+}
+EXPORT_SYMBOL_GPL(icc_provider_add);
+
+void icc_provider_del(struct icc_provider *provider)
+{
+       WARN_ON(!list_empty(&provider->nodes));
+
+       icc_provider_deregister(provider);
+}
 EXPORT_SYMBOL_GPL(icc_provider_del);
 
 static const struct of_device_id __maybe_unused ignore_list[] = {
index 823d9be9771a1c70a3d3db7d3b844a68c868854c..979ed610f704b576d346547deba78a2ea2b2a4d5 100644 (file)
@@ -295,6 +295,9 @@ int imx_icc_register(struct platform_device *pdev,
        provider->xlate = of_icc_xlate_onecell;
        provider->data = data;
        provider->dev = dev->parent;
+
+       icc_provider_init(provider);
+
        platform_set_drvdata(pdev, imx_provider);
 
        if (settings) {
@@ -306,20 +309,18 @@ int imx_icc_register(struct platform_device *pdev,
                }
        }
 
-       ret = icc_provider_add(provider);
-       if (ret) {
-               dev_err(dev, "error adding interconnect provider: %d\n", ret);
+       ret = imx_icc_register_nodes(imx_provider, nodes, nodes_count, settings);
+       if (ret)
                return ret;
-       }
 
-       ret = imx_icc_register_nodes(imx_provider, nodes, nodes_count, settings);
+       ret = icc_provider_register(provider);
        if (ret)
-               goto provider_del;
+               goto err_unregister_nodes;
 
        return 0;
 
-provider_del:
-       icc_provider_del(provider);
+err_unregister_nodes:
+       imx_icc_unregister_nodes(&imx_provider->provider);
        return ret;
 }
 EXPORT_SYMBOL_GPL(imx_icc_register);
@@ -328,9 +329,8 @@ void imx_icc_unregister(struct platform_device *pdev)
 {
        struct imx_icc_provider *imx_provider = platform_get_drvdata(pdev);
 
+       icc_provider_deregister(&imx_provider->provider);
        imx_icc_unregister_nodes(&imx_provider->provider);
-
-       icc_provider_del(&imx_provider->provider);
 }
 EXPORT_SYMBOL_GPL(imx_icc_unregister);
 
index df3196f7253687248bbd00fe2099e6d531171f38..4180a06681b2b9aca3134ee1aeb57e2c0ca6df20 100644 (file)
@@ -503,7 +503,6 @@ regmap_done:
        }
 
        provider = &qp->provider;
-       INIT_LIST_HEAD(&provider->nodes);
        provider->dev = dev;
        provider->set = qcom_icc_set;
        provider->pre_aggregate = qcom_icc_pre_bw_aggregate;
@@ -511,12 +510,7 @@ regmap_done:
        provider->xlate_extended = qcom_icc_xlate_extended;
        provider->data = data;
 
-       ret = icc_provider_add(provider);
-       if (ret) {
-               dev_err(dev, "error adding interconnect provider: %d\n", ret);
-               clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
-               return ret;
-       }
+       icc_provider_init(provider);
 
        for (i = 0; i < num_nodes; i++) {
                size_t j;
@@ -524,7 +518,7 @@ regmap_done:
                node = icc_node_create(qnodes[i]->id);
                if (IS_ERR(node)) {
                        ret = PTR_ERR(node);
-                       goto err;
+                       goto err_remove_nodes;
                }
 
                node->name = qnodes[i]->name;
@@ -538,17 +532,26 @@ regmap_done:
        }
        data->num_nodes = num_nodes;
 
+       ret = icc_provider_register(provider);
+       if (ret)
+               goto err_remove_nodes;
+
        platform_set_drvdata(pdev, qp);
 
        /* Populate child NoC devices if any */
-       if (of_get_child_count(dev->of_node) > 0)
-               return of_platform_populate(dev->of_node, NULL, NULL, dev);
+       if (of_get_child_count(dev->of_node) > 0) {
+               ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
+               if (ret)
+                       goto err_deregister_provider;
+       }
 
        return 0;
-err:
+
+err_deregister_provider:
+       icc_provider_deregister(provider);
+err_remove_nodes:
        icc_nodes_remove(provider);
        clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
-       icc_provider_del(provider);
 
        return ret;
 }
@@ -558,9 +561,9 @@ int qnoc_remove(struct platform_device *pdev)
 {
        struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
 
+       icc_provider_deregister(&qp->provider);
        icc_nodes_remove(&qp->provider);
        clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
-       icc_provider_del(&qp->provider);
 
        return 0;
 }
index fd17291c61eb96b5b9480669c1f1f090b41c2825..fdb5e58e408b4da8d42f614fad20805cc9c09ca0 100644 (file)
@@ -192,9 +192,10 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev)
        provider->pre_aggregate = qcom_icc_pre_aggregate;
        provider->aggregate = qcom_icc_aggregate;
        provider->xlate_extended = qcom_icc_xlate_extended;
-       INIT_LIST_HEAD(&provider->nodes);
        provider->data = data;
 
+       icc_provider_init(provider);
+
        qp->dev = dev;
        qp->bcms = desc->bcms;
        qp->num_bcms = desc->num_bcms;
@@ -203,10 +204,6 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev)
        if (IS_ERR(qp->voter))
                return PTR_ERR(qp->voter);
 
-       ret = icc_provider_add(provider);
-       if (ret)
-               return ret;
-
        for (i = 0; i < qp->num_bcms; i++)
                qcom_icc_bcm_init(qp->bcms[i], dev);
 
@@ -218,7 +215,7 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev)
                node = icc_node_create(qn->id);
                if (IS_ERR(node)) {
                        ret = PTR_ERR(node);
-                       goto err;
+                       goto err_remove_nodes;
                }
 
                node->name = qn->name;
@@ -232,16 +229,27 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev)
        }
 
        data->num_nodes = num_nodes;
+
+       ret = icc_provider_register(provider);
+       if (ret)
+               goto err_remove_nodes;
+
        platform_set_drvdata(pdev, qp);
 
        /* Populate child NoC devices if any */
-       if (of_get_child_count(dev->of_node) > 0)
-               return of_platform_populate(dev->of_node, NULL, NULL, dev);
+       if (of_get_child_count(dev->of_node) > 0) {
+               ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
+               if (ret)
+                       goto err_deregister_provider;
+       }
 
        return 0;
-err:
+
+err_deregister_provider:
+       icc_provider_deregister(provider);
+err_remove_nodes:
        icc_nodes_remove(provider);
-       icc_provider_del(provider);
+
        return ret;
 }
 EXPORT_SYMBOL_GPL(qcom_icc_rpmh_probe);
@@ -250,8 +258,8 @@ int qcom_icc_rpmh_remove(struct platform_device *pdev)
 {
        struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
 
+       icc_provider_deregister(&qp->provider);
        icc_nodes_remove(&qp->provider);
-       icc_provider_del(&qp->provider);
 
        return 0;
 }
index 5ea192f1141dc42f4cee48fb6c28cc51bcd65430..1828deaca44326249d0e29da7c5cf9456a5b2315 100644 (file)
@@ -692,7 +692,6 @@ static int msm8974_icc_probe(struct platform_device *pdev)
                return ret;
 
        provider = &qp->provider;
-       INIT_LIST_HEAD(&provider->nodes);
        provider->dev = dev;
        provider->set = msm8974_icc_set;
        provider->aggregate = icc_std_aggregate;
@@ -700,11 +699,7 @@ static int msm8974_icc_probe(struct platform_device *pdev)
        provider->data = data;
        provider->get_bw = msm8974_get_bw;
 
-       ret = icc_provider_add(provider);
-       if (ret) {
-               dev_err(dev, "error adding interconnect provider: %d\n", ret);
-               goto err_disable_clks;
-       }
+       icc_provider_init(provider);
 
        for (i = 0; i < num_nodes; i++) {
                size_t j;
@@ -712,7 +707,7 @@ static int msm8974_icc_probe(struct platform_device *pdev)
                node = icc_node_create(qnodes[i]->id);
                if (IS_ERR(node)) {
                        ret = PTR_ERR(node);
-                       goto err_del_icc;
+                       goto err_remove_nodes;
                }
 
                node->name = qnodes[i]->name;
@@ -729,15 +724,16 @@ static int msm8974_icc_probe(struct platform_device *pdev)
        }
        data->num_nodes = num_nodes;
 
+       ret = icc_provider_register(provider);
+       if (ret)
+               goto err_remove_nodes;
+
        platform_set_drvdata(pdev, qp);
 
        return 0;
 
-err_del_icc:
+err_remove_nodes:
        icc_nodes_remove(provider);
-       icc_provider_del(provider);
-
-err_disable_clks:
        clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
 
        return ret;
@@ -747,9 +743,9 @@ static int msm8974_icc_remove(struct platform_device *pdev)
 {
        struct msm8974_icc_provider *qp = platform_get_drvdata(pdev);
 
+       icc_provider_deregister(&qp->provider);
        icc_nodes_remove(&qp->provider);
        clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
-       icc_provider_del(&qp->provider);
 
        return 0;
 }
index 5fa1710874258926ac8c31a7b8b70e0880a538d8..1bafb54f1432912a6fdbc4846ca5549390de031c 100644 (file)
@@ -158,8 +158,8 @@ static int qcom_osm_l3_remove(struct platform_device *pdev)
 {
        struct qcom_osm_l3_icc_provider *qp = platform_get_drvdata(pdev);
 
+       icc_provider_deregister(&qp->provider);
        icc_nodes_remove(&qp->provider);
-       icc_provider_del(&qp->provider);
 
        return 0;
 }
@@ -236,7 +236,7 @@ static int qcom_osm_l3_probe(struct platform_device *pdev)
        qnodes = desc->nodes;
        num_nodes = desc->num_nodes;
 
-       data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
+       data = devm_kzalloc(&pdev->dev, struct_size(data, nodes, num_nodes), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
@@ -245,14 +245,9 @@ static int qcom_osm_l3_probe(struct platform_device *pdev)
        provider->set = qcom_osm_l3_set;
        provider->aggregate = icc_std_aggregate;
        provider->xlate = of_icc_xlate_onecell;
-       INIT_LIST_HEAD(&provider->nodes);
        provider->data = data;
 
-       ret = icc_provider_add(provider);
-       if (ret) {
-               dev_err(&pdev->dev, "error adding interconnect provider\n");
-               return ret;
-       }
+       icc_provider_init(provider);
 
        for (i = 0; i < num_nodes; i++) {
                size_t j;
@@ -275,12 +270,15 @@ static int qcom_osm_l3_probe(struct platform_device *pdev)
        }
        data->num_nodes = num_nodes;
 
+       ret = icc_provider_register(provider);
+       if (ret)
+               goto err;
+
        platform_set_drvdata(pdev, qp);
 
        return 0;
 err:
        icc_nodes_remove(provider);
-       icc_provider_del(provider);
 
        return ret;
 }
index 0da612d6398c54874f6b97f674e50edabc5247a5..a29cdb4fac03faec3c376bd68e0a7a5c86c0404a 100644 (file)
@@ -147,9 +147,9 @@ static struct qcom_icc_node mas_snoc_bimc_nrt = {
        .name = "mas_snoc_bimc_nrt",
        .buswidth = 16,
        .qos.ap_owned = true,
-       .qos.qos_port = 2,
+       .qos.qos_port = 3,
        .qos.qos_mode = NOC_QOS_MODE_BYPASS,
-       .mas_rpm_id = 163,
+       .mas_rpm_id = 164,
        .slv_rpm_id = -1,
        .num_links = ARRAY_SIZE(mas_snoc_bimc_nrt_links),
        .links = mas_snoc_bimc_nrt_links,
index e3a12e3d6e0619275670d3d41a69680f8c61d667..2d7a8e7b85ec29e94684ee7cc172be46109f89ec 100644 (file)
@@ -1844,100 +1844,6 @@ static const struct qcom_icc_desc sm8450_system_noc = {
        .num_bcms = ARRAY_SIZE(system_noc_bcms),
 };
 
-static int qnoc_probe(struct platform_device *pdev)
-{
-       const struct qcom_icc_desc *desc;
-       struct icc_onecell_data *data;
-       struct icc_provider *provider;
-       struct qcom_icc_node * const *qnodes;
-       struct qcom_icc_provider *qp;
-       struct icc_node *node;
-       size_t num_nodes, i;
-       int ret;
-
-       desc = device_get_match_data(&pdev->dev);
-       if (!desc)
-               return -EINVAL;
-
-       qnodes = desc->nodes;
-       num_nodes = desc->num_nodes;
-
-       qp = devm_kzalloc(&pdev->dev, sizeof(*qp), GFP_KERNEL);
-       if (!qp)
-               return -ENOMEM;
-
-       data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
-       if (!data)
-               return -ENOMEM;
-
-       provider = &qp->provider;
-       provider->dev = &pdev->dev;
-       provider->set = qcom_icc_set;
-       provider->pre_aggregate = qcom_icc_pre_aggregate;
-       provider->aggregate = qcom_icc_aggregate;
-       provider->xlate_extended = qcom_icc_xlate_extended;
-       INIT_LIST_HEAD(&provider->nodes);
-       provider->data = data;
-
-       qp->dev = &pdev->dev;
-       qp->bcms = desc->bcms;
-       qp->num_bcms = desc->num_bcms;
-
-       qp->voter = of_bcm_voter_get(qp->dev, NULL);
-       if (IS_ERR(qp->voter))
-               return PTR_ERR(qp->voter);
-
-       ret = icc_provider_add(provider);
-       if (ret) {
-               dev_err(&pdev->dev, "error adding interconnect provider\n");
-               return ret;
-       }
-
-       for (i = 0; i < qp->num_bcms; i++)
-               qcom_icc_bcm_init(qp->bcms[i], &pdev->dev);
-
-       for (i = 0; i < num_nodes; i++) {
-               size_t j;
-
-               if (!qnodes[i])
-                       continue;
-
-               node = icc_node_create(qnodes[i]->id);
-               if (IS_ERR(node)) {
-                       ret = PTR_ERR(node);
-                       goto err;
-               }
-
-               node->name = qnodes[i]->name;
-               node->data = qnodes[i];
-               icc_node_add(node, provider);
-
-               for (j = 0; j < qnodes[i]->num_links; j++)
-                       icc_link_create(node, qnodes[i]->links[j]);
-
-               data->nodes[i] = node;
-       }
-       data->num_nodes = num_nodes;
-
-       platform_set_drvdata(pdev, qp);
-
-       return 0;
-err:
-       icc_nodes_remove(provider);
-       icc_provider_del(provider);
-       return ret;
-}
-
-static int qnoc_remove(struct platform_device *pdev)
-{
-       struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
-
-       icc_nodes_remove(&qp->provider);
-       icc_provider_del(&qp->provider);
-
-       return 0;
-}
-
 static const struct of_device_id qnoc_of_match[] = {
        { .compatible = "qcom,sm8450-aggre1-noc",
          .data = &sm8450_aggre1_noc},
@@ -1966,8 +1872,8 @@ static const struct of_device_id qnoc_of_match[] = {
 MODULE_DEVICE_TABLE(of, qnoc_of_match);
 
 static struct platform_driver qnoc_driver = {
-       .probe = qnoc_probe,
-       .remove = qnoc_remove,
+       .probe = qcom_icc_rpmh_probe,
+       .remove = qcom_icc_rpmh_remove,
        .driver = {
                .name = "qnoc-sm8450",
                .of_match_table = qnoc_of_match,
index 54fa027ab961f7c86a1208538f0d1c9c7d052338..d823ba988ef68c75a976de744c0e04750364bc2b 100644 (file)
@@ -2165,101 +2165,6 @@ static const struct qcom_icc_desc sm8550_system_noc = {
        .num_bcms = ARRAY_SIZE(system_noc_bcms),
 };
 
-static int qnoc_probe(struct platform_device *pdev)
-{
-       const struct qcom_icc_desc *desc;
-       struct icc_onecell_data *data;
-       struct icc_provider *provider;
-       struct qcom_icc_node * const *qnodes;
-       struct qcom_icc_provider *qp;
-       struct icc_node *node;
-       size_t num_nodes, i;
-       int ret;
-
-       desc = device_get_match_data(&pdev->dev);
-       if (!desc)
-               return -EINVAL;
-
-       qnodes = desc->nodes;
-       num_nodes = desc->num_nodes;
-
-       qp = devm_kzalloc(&pdev->dev, sizeof(*qp), GFP_KERNEL);
-       if (!qp)
-               return -ENOMEM;
-
-       data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
-       if (!data)
-               return -ENOMEM;
-
-       provider = &qp->provider;
-       provider->dev = &pdev->dev;
-       provider->set = qcom_icc_set;
-       provider->pre_aggregate = qcom_icc_pre_aggregate;
-       provider->aggregate = qcom_icc_aggregate;
-       provider->xlate_extended = qcom_icc_xlate_extended;
-       INIT_LIST_HEAD(&provider->nodes);
-       provider->data = data;
-
-       qp->dev = &pdev->dev;
-       qp->bcms = desc->bcms;
-       qp->num_bcms = desc->num_bcms;
-
-       qp->voter = of_bcm_voter_get(qp->dev, NULL);
-       if (IS_ERR(qp->voter))
-               return PTR_ERR(qp->voter);
-
-       ret = icc_provider_add(provider);
-       if (ret) {
-               dev_err_probe(&pdev->dev, ret,
-                             "error adding interconnect provider\n");
-               return ret;
-       }
-
-       for (i = 0; i < qp->num_bcms; i++)
-               qcom_icc_bcm_init(qp->bcms[i], &pdev->dev);
-
-       for (i = 0; i < num_nodes; i++) {
-               size_t j;
-
-               if (!qnodes[i])
-                       continue;
-
-               node = icc_node_create(qnodes[i]->id);
-               if (IS_ERR(node)) {
-                       ret = PTR_ERR(node);
-                       goto err;
-               }
-
-               node->name = qnodes[i]->name;
-               node->data = qnodes[i];
-               icc_node_add(node, provider);
-
-               for (j = 0; j < qnodes[i]->num_links; j++)
-                       icc_link_create(node, qnodes[i]->links[j]);
-
-               data->nodes[i] = node;
-       }
-       data->num_nodes = num_nodes;
-
-       platform_set_drvdata(pdev, qp);
-
-       return 0;
-err:
-       icc_nodes_remove(provider);
-       icc_provider_del(provider);
-       return ret;
-}
-
-static int qnoc_remove(struct platform_device *pdev)
-{
-       struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
-
-       icc_nodes_remove(&qp->provider);
-       icc_provider_del(&qp->provider);
-
-       return 0;
-}
-
 static const struct of_device_id qnoc_of_match[] = {
        { .compatible = "qcom,sm8550-aggre1-noc",
          .data = &sm8550_aggre1_noc},
@@ -2294,8 +2199,8 @@ static const struct of_device_id qnoc_of_match[] = {
 MODULE_DEVICE_TABLE(of, qnoc_of_match);
 
 static struct platform_driver qnoc_driver = {
-       .probe = qnoc_probe,
-       .remove = qnoc_remove,
+       .probe = qcom_icc_rpmh_probe,
+       .remove = qcom_icc_rpmh_remove,
        .driver = {
                .name = "qnoc-sm8550",
                .of_match_table = qnoc_of_match,
index 6559d8cf80687bf8d4034f52ea1f150c33c5f13c..ebf09bbf725bd117195eec5457b5495b12305105 100644 (file)
@@ -96,14 +96,9 @@ static struct icc_node *exynos_generic_icc_xlate(struct of_phandle_args *spec,
 static int exynos_generic_icc_remove(struct platform_device *pdev)
 {
        struct exynos_icc_priv *priv = platform_get_drvdata(pdev);
-       struct icc_node *parent_node, *node = priv->node;
-
-       parent_node = exynos_icc_get_parent(priv->dev->parent->of_node);
-       if (parent_node && !IS_ERR(parent_node))
-               icc_link_destroy(node, parent_node);
 
+       icc_provider_deregister(&priv->provider);
        icc_nodes_remove(&priv->provider);
-       icc_provider_del(&priv->provider);
 
        return 0;
 }
@@ -132,15 +127,11 @@ static int exynos_generic_icc_probe(struct platform_device *pdev)
        provider->inter_set = true;
        provider->data = priv;
 
-       ret = icc_provider_add(provider);
-       if (ret < 0)
-               return ret;
+       icc_provider_init(provider);
 
        icc_node = icc_node_create(pdev->id);
-       if (IS_ERR(icc_node)) {
-               ret = PTR_ERR(icc_node);
-               goto err_prov_del;
-       }
+       if (IS_ERR(icc_node))
+               return PTR_ERR(icc_node);
 
        priv->node = icc_node;
        icc_node->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOFn",
@@ -149,6 +140,9 @@ static int exynos_generic_icc_probe(struct platform_device *pdev)
                                 &priv->bus_clk_ratio))
                priv->bus_clk_ratio = EXYNOS_ICC_DEFAULT_BUS_CLK_RATIO;
 
+       icc_node->data = priv;
+       icc_node_add(icc_node, provider);
+
        /*
         * Register a PM QoS request for the parent (devfreq) device.
         */
@@ -157,9 +151,6 @@ static int exynos_generic_icc_probe(struct platform_device *pdev)
        if (ret < 0)
                goto err_node_del;
 
-       icc_node->data = priv;
-       icc_node_add(icc_node, provider);
-
        icc_parent_node = exynos_icc_get_parent(bus_dev->of_node);
        if (IS_ERR(icc_parent_node)) {
                ret = PTR_ERR(icc_parent_node);
@@ -171,14 +162,17 @@ static int exynos_generic_icc_probe(struct platform_device *pdev)
                        goto err_pmqos_del;
        }
 
+       ret = icc_provider_register(provider);
+       if (ret < 0)
+               goto err_pmqos_del;
+
        return 0;
 
 err_pmqos_del:
        dev_pm_qos_remove_request(&priv->qos_req);
 err_node_del:
        icc_nodes_remove(provider);
-err_prov_del:
-       icc_provider_del(provider);
+
        return ret;
 }
 
index 483aaaeb6daeac685dbead517c6409f54b2db807..1abd187c6075e4bedce585fd6c4c24794f1b0e84 100644 (file)
@@ -1415,23 +1415,26 @@ static struct iommu_device *exynos_iommu_probe_device(struct device *dev)
        return &data->iommu;
 }
 
-static void exynos_iommu_release_device(struct device *dev)
+static void exynos_iommu_set_platform_dma(struct device *dev)
 {
        struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev);
-       struct sysmmu_drvdata *data;
 
        if (owner->domain) {
                struct iommu_group *group = iommu_group_get(dev);
 
                if (group) {
-#ifndef CONFIG_ARM
-                       WARN_ON(owner->domain !=
-                               iommu_group_default_domain(group));
-#endif
                        exynos_iommu_detach_device(owner->domain, dev);
                        iommu_group_put(group);
                }
        }
+}
+
+static void exynos_iommu_release_device(struct device *dev)
+{
+       struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev);
+       struct sysmmu_drvdata *data;
+
+       exynos_iommu_set_platform_dma(dev);
 
        list_for_each_entry(data, &owner->controllers, owner_node)
                device_link_del(data->link);
@@ -1479,7 +1482,7 @@ static const struct iommu_ops exynos_iommu_ops = {
        .domain_alloc = exynos_iommu_domain_alloc,
        .device_group = generic_device_group,
 #ifdef CONFIG_ARM
-       .set_platform_dma_ops = exynos_iommu_release_device,
+       .set_platform_dma_ops = exynos_iommu_set_platform_dma,
 #endif
        .probe_device = exynos_iommu_probe_device,
        .release_device = exynos_iommu_release_device,
index 6acfe879589cb75f625c8b9715838b193ba44e4b..23828d189c2a609cff3145afd951faae6bdee17c 100644 (file)
@@ -1071,7 +1071,8 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
        }
 
        err = -EINVAL;
-       if (cap_sagaw(iommu->cap) == 0) {
+       if (!cap_sagaw(iommu->cap) &&
+           (!ecap_smts(iommu->ecap) || ecap_slts(iommu->ecap))) {
                pr_info("%s: No supported address widths. Not attempting DMA translation.\n",
                        iommu->name);
                drhd->ignored = 1;
index d6df3b8658129a39721b4a011c6272b5ca574b38..694ab9b7d3e95a0ff98a750f622279dace3b86d8 100644 (file)
@@ -641,6 +641,8 @@ struct iommu_pmu {
        DECLARE_BITMAP(used_mask, IOMMU_PMU_IDX_MAX);
        struct perf_event       *event_list[IOMMU_PMU_IDX_MAX];
        unsigned char           irq_name[16];
+       struct hlist_node       cpuhp_node;
+       int                     cpu;
 };
 
 #define IOMMU_IRQ_ID_OFFSET_PRQ                (DMAR_UNITS_SUPPORTED)
index 6d01fa078c36fcaea0cf5fcde3bca84a061ffd3b..df9e261af0b564e8a999612f83029cf41ca22cd0 100644 (file)
@@ -311,14 +311,12 @@ static int set_ioapic_sid(struct irte *irte, int apic)
        if (!irte)
                return -1;
 
-       down_read(&dmar_global_lock);
        for (i = 0; i < MAX_IO_APICS; i++) {
                if (ir_ioapic[i].iommu && ir_ioapic[i].id == apic) {
                        sid = (ir_ioapic[i].bus << 8) | ir_ioapic[i].devfn;
                        break;
                }
        }
-       up_read(&dmar_global_lock);
 
        if (sid == 0) {
                pr_warn("Failed to set source-id of IOAPIC (%d)\n", apic);
@@ -338,14 +336,12 @@ static int set_hpet_sid(struct irte *irte, u8 id)
        if (!irte)
                return -1;
 
-       down_read(&dmar_global_lock);
        for (i = 0; i < MAX_HPET_TBS; i++) {
                if (ir_hpet[i].iommu && ir_hpet[i].id == id) {
                        sid = (ir_hpet[i].bus << 8) | ir_hpet[i].devfn;
                        break;
                }
        }
-       up_read(&dmar_global_lock);
 
        if (sid == 0) {
                pr_warn("Failed to set source-id of HPET block (%d)\n", id);
@@ -1339,9 +1335,7 @@ static int intel_irq_remapping_alloc(struct irq_domain *domain,
        if (!data)
                goto out_free_parent;
 
-       down_read(&dmar_global_lock);
        index = alloc_irte(iommu, &data->irq_2_iommu, nr_irqs);
-       up_read(&dmar_global_lock);
        if (index < 0) {
                pr_warn("Failed to allocate IRTE\n");
                kfree(data);
index e17d9743a0d8c3abaf805030c070960016ab5512..cf43e798eca49936e79a20ea5397a6b0e9f1cc82 100644 (file)
@@ -773,19 +773,34 @@ static void iommu_pmu_unset_interrupt(struct intel_iommu *iommu)
        iommu->perf_irq = 0;
 }
 
-static int iommu_pmu_cpu_online(unsigned int cpu)
+static int iommu_pmu_cpu_online(unsigned int cpu, struct hlist_node *node)
 {
+       struct iommu_pmu *iommu_pmu = hlist_entry_safe(node, typeof(*iommu_pmu), cpuhp_node);
+
        if (cpumask_empty(&iommu_pmu_cpu_mask))
                cpumask_set_cpu(cpu, &iommu_pmu_cpu_mask);
 
+       if (cpumask_test_cpu(cpu, &iommu_pmu_cpu_mask))
+               iommu_pmu->cpu = cpu;
+
        return 0;
 }
 
-static int iommu_pmu_cpu_offline(unsigned int cpu)
+static int iommu_pmu_cpu_offline(unsigned int cpu, struct hlist_node *node)
 {
-       struct dmar_drhd_unit *drhd;
-       struct intel_iommu *iommu;
-       int target;
+       struct iommu_pmu *iommu_pmu = hlist_entry_safe(node, typeof(*iommu_pmu), cpuhp_node);
+       int target = cpumask_first(&iommu_pmu_cpu_mask);
+
+       /*
+        * The iommu_pmu_cpu_mask has been updated when offline the CPU
+        * for the first iommu_pmu. Migrate the other iommu_pmu to the
+        * new target.
+        */
+       if (target < nr_cpu_ids && target != iommu_pmu->cpu) {
+               perf_pmu_migrate_context(&iommu_pmu->pmu, cpu, target);
+               iommu_pmu->cpu = target;
+               return 0;
+       }
 
        if (!cpumask_test_and_clear_cpu(cpu, &iommu_pmu_cpu_mask))
                return 0;
@@ -795,45 +810,50 @@ static int iommu_pmu_cpu_offline(unsigned int cpu)
        if (target < nr_cpu_ids)
                cpumask_set_cpu(target, &iommu_pmu_cpu_mask);
        else
-               target = -1;
+               return 0;
 
-       rcu_read_lock();
-
-       for_each_iommu(iommu, drhd) {
-               if (!iommu->pmu)
-                       continue;
-               perf_pmu_migrate_context(&iommu->pmu->pmu, cpu, target);
-       }
-       rcu_read_unlock();
+       perf_pmu_migrate_context(&iommu_pmu->pmu, cpu, target);
+       iommu_pmu->cpu = target;
 
        return 0;
 }
 
 static int nr_iommu_pmu;
+static enum cpuhp_state iommu_cpuhp_slot;
 
 static int iommu_pmu_cpuhp_setup(struct iommu_pmu *iommu_pmu)
 {
        int ret;
 
-       if (nr_iommu_pmu++)
-               return 0;
+       if (!nr_iommu_pmu) {
+               ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
+                                             "driver/iommu/intel/perfmon:online",
+                                             iommu_pmu_cpu_online,
+                                             iommu_pmu_cpu_offline);
+               if (ret < 0)
+                       return ret;
+               iommu_cpuhp_slot = ret;
+       }
 
-       ret = cpuhp_setup_state(CPUHP_AP_PERF_X86_IOMMU_PERF_ONLINE,
-                               "driver/iommu/intel/perfmon:online",
-                               iommu_pmu_cpu_online,
-                               iommu_pmu_cpu_offline);
-       if (ret)
-               nr_iommu_pmu = 0;
+       ret = cpuhp_state_add_instance(iommu_cpuhp_slot, &iommu_pmu->cpuhp_node);
+       if (ret) {
+               if (!nr_iommu_pmu)
+                       cpuhp_remove_multi_state(iommu_cpuhp_slot);
+               return ret;
+       }
+       nr_iommu_pmu++;
 
-       return ret;
+       return 0;
 }
 
 static void iommu_pmu_cpuhp_free(struct iommu_pmu *iommu_pmu)
 {
+       cpuhp_state_remove_instance(iommu_cpuhp_slot, &iommu_pmu->cpuhp_node);
+
        if (--nr_iommu_pmu)
                return;
 
-       cpuhp_remove_state(CPUHP_AP_PERF_X86_IOMMU_PERF_ONLINE);
+       cpuhp_remove_multi_state(iommu_cpuhp_slot);
 }
 
 void iommu_pmu_register(struct intel_iommu *iommu)
index f8d92c9bb65b603add9596e9040907c587843035..3c47846cc5efe8f49c26b283e10f3ae42c42d641 100644 (file)
@@ -294,9 +294,9 @@ static void batch_clear_carry(struct pfn_batch *batch, unsigned int keep_pfns)
                        batch->npfns[batch->end - 1] < keep_pfns);
 
        batch->total_pfns = keep_pfns;
-       batch->npfns[0] = keep_pfns;
        batch->pfns[0] = batch->pfns[batch->end - 1] +
                         (batch->npfns[batch->end - 1] - keep_pfns);
+       batch->npfns[0] = keep_pfns;
        batch->end = 0;
 }
 
@@ -1142,6 +1142,7 @@ struct iopt_pages *iopt_alloc_pages(void __user *uptr, unsigned long length,
                                    bool writable)
 {
        struct iopt_pages *pages;
+       unsigned long end;
 
        /*
         * The iommu API uses size_t as the length, and protect the DIV_ROUND_UP
@@ -1150,6 +1151,9 @@ struct iopt_pages *iopt_alloc_pages(void __user *uptr, unsigned long length,
        if (length > SIZE_MAX - PAGE_SIZE || length == 0)
                return ERR_PTR(-EINVAL);
 
+       if (check_add_overflow((unsigned long)uptr, length, &end))
+               return ERR_PTR(-EOVERFLOW);
+
        pages = kzalloc(sizeof(*pages), GFP_KERNEL_ACCOUNT);
        if (!pages)
                return ERR_PTR(-ENOMEM);
@@ -1203,13 +1207,21 @@ iopt_area_unpin_domain(struct pfn_batch *batch, struct iopt_area *area,
                        unsigned long start =
                                max(start_index, *unmapped_end_index);
 
+                       if (IS_ENABLED(CONFIG_IOMMUFD_TEST) &&
+                           batch->total_pfns)
+                               WARN_ON(*unmapped_end_index -
+                                               batch->total_pfns !=
+                                       start_index);
                        batch_from_domain(batch, domain, area, start,
                                          last_index);
-                       batch_last_index = start + batch->total_pfns - 1;
+                       batch_last_index = start_index + batch->total_pfns - 1;
                } else {
                        batch_last_index = last_index;
                }
 
+               if (IS_ENABLED(CONFIG_IOMMUFD_TEST))
+                       WARN_ON(batch_last_index > real_last_index);
+
                /*
                 * unmaps must always 'cut' at a place where the pfns are not
                 * contiguous to pair with the maps that always install
index 5f1e2593fad7ec4feb9667a9c790cbb1b35123de..b0a22e99bade37148914492b26ec75d5523088d7 100644 (file)
@@ -15,6 +15,10 @@ if MD
 config BLK_DEV_MD
        tristate "RAID support"
        select BLOCK_HOLDER_DEPRECATED if SYSFS
+       # BLOCK_LEGACY_AUTOLOAD requirement should be removed
+       # after relevant mdadm enhancements - to make "names=yes"
+       # the default - are widely available.
+       select BLOCK_LEGACY_AUTOLOAD
        help
          This driver lets you combine several hard disk partitions into one
          logical block device. This can be used to simply append one
index 40cb1719ae4d526b2fbe40a93f5f36fe7e25ec28..3ba53dc3cc3f627218941a61a9bdd6d948c87f43 100644 (file)
@@ -72,7 +72,9 @@ struct dm_crypt_io {
        struct crypt_config *cc;
        struct bio *base_bio;
        u8 *integrity_metadata;
-       bool integrity_metadata_from_pool;
+       bool integrity_metadata_from_pool:1;
+       bool in_tasklet:1;
+
        struct work_struct work;
        struct tasklet_struct tasklet;
 
@@ -1730,6 +1732,7 @@ static void crypt_io_init(struct dm_crypt_io *io, struct crypt_config *cc,
        io->ctx.r.req = NULL;
        io->integrity_metadata = NULL;
        io->integrity_metadata_from_pool = false;
+       io->in_tasklet = false;
        atomic_set(&io->io_pending, 0);
 }
 
@@ -1776,14 +1779,13 @@ static void crypt_dec_pending(struct dm_crypt_io *io)
         * our tasklet. In this case we need to delay bio_endio()
         * execution to after the tasklet is done and dequeued.
         */
-       if (tasklet_trylock(&io->tasklet)) {
-               tasklet_unlock(&io->tasklet);
-               bio_endio(base_bio);
+       if (io->in_tasklet) {
+               INIT_WORK(&io->work, kcryptd_io_bio_endio);
+               queue_work(cc->io_queue, &io->work);
                return;
        }
 
-       INIT_WORK(&io->work, kcryptd_io_bio_endio);
-       queue_work(cc->io_queue, &io->work);
+       bio_endio(base_bio);
 }
 
 /*
@@ -1936,6 +1938,7 @@ pop_from_list:
                        io = crypt_io_from_node(rb_first(&write_tree));
                        rb_erase(&io->rb_node, &write_tree);
                        kcryptd_io_write(io);
+                       cond_resched();
                } while (!RB_EMPTY_ROOT(&write_tree));
                blk_finish_plug(&plug);
        }
@@ -2230,6 +2233,7 @@ static void kcryptd_queue_crypt(struct dm_crypt_io *io)
                 * it is being executed with irqs disabled.
                 */
                if (in_hardirq() || irqs_disabled()) {
+                       io->in_tasklet = true;
                        tasklet_init(&io->tasklet, kcryptd_crypt_tasklet, (unsigned long)&io->work);
                        tasklet_schedule(&io->tasklet);
                        return;
index c21a19ab73f705d791e611101e79b467fe329bf0..db2d997a6c1815ce6f7f72fa0fed51572afae856 100644 (file)
@@ -188,7 +188,7 @@ static int dm_stat_in_flight(struct dm_stat_shared *shared)
               atomic_read(&shared->in_flight[WRITE]);
 }
 
-void dm_stats_init(struct dm_stats *stats)
+int dm_stats_init(struct dm_stats *stats)
 {
        int cpu;
        struct dm_stats_last_position *last;
@@ -197,11 +197,16 @@ void dm_stats_init(struct dm_stats *stats)
        INIT_LIST_HEAD(&stats->list);
        stats->precise_timestamps = false;
        stats->last = alloc_percpu(struct dm_stats_last_position);
+       if (!stats->last)
+               return -ENOMEM;
+
        for_each_possible_cpu(cpu) {
                last = per_cpu_ptr(stats->last, cpu);
                last->last_sector = (sector_t)ULLONG_MAX;
                last->last_rw = UINT_MAX;
        }
+
+       return 0;
 }
 
 void dm_stats_cleanup(struct dm_stats *stats)
index 0bc152c8e4f310282845a30d65a0528d029af254..c6728c8b41594bd1a9cac425be013d8a03f085d3 100644 (file)
@@ -21,7 +21,7 @@ struct dm_stats_aux {
        unsigned long long duration_ns;
 };
 
-void dm_stats_init(struct dm_stats *st);
+int dm_stats_init(struct dm_stats *st);
 void dm_stats_cleanup(struct dm_stats *st);
 
 struct mapped_device;
index 6cd105c1cef35cc51defa05a16684b361ef1ac12..13d4677baafd176065a8e218695910205606245f 100644 (file)
@@ -3369,6 +3369,7 @@ static int pool_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        pt->low_water_blocks = low_water_blocks;
        pt->adjusted_pf = pt->requested_pf = pf;
        ti->num_flush_bios = 1;
+       ti->limit_swap_bios = true;
 
        /*
         * Only need to enable discards if the pool should pass
@@ -4249,6 +4250,7 @@ static int thin_ctr(struct dm_target *ti, unsigned int argc, char **argv)
                goto bad;
 
        ti->num_flush_bios = 1;
+       ti->limit_swap_bios = true;
        ti->flush_supported = true;
        ti->accounts_remapped_io = true;
        ti->per_io_data_size = sizeof(struct dm_thin_endio_hook);
index eace45a18d45611e70e1b4a988d674535925a30a..dfde0088147a1e5bd7be946d330f30b2b4684dcf 100644 (file)
@@ -512,10 +512,10 @@ static void dm_io_acct(struct dm_io *io, bool end)
                sectors = io->sectors;
 
        if (!end)
-               bdev_start_io_acct(bio->bi_bdev, sectors, bio_op(bio),
-                                  start_time);
+               bdev_start_io_acct(bio->bi_bdev, bio_op(bio), start_time);
        else
-               bdev_end_io_acct(bio->bi_bdev, bio_op(bio), start_time);
+               bdev_end_io_acct(bio->bi_bdev, bio_op(bio), sectors,
+                                start_time);
 
        if (static_branch_unlikely(&stats_enabled) &&
            unlikely(dm_stats_used(&md->stats))) {
@@ -1467,7 +1467,8 @@ static void setup_split_accounting(struct clone_info *ci, unsigned int len)
 }
 
 static void alloc_multiple_bios(struct bio_list *blist, struct clone_info *ci,
-                               struct dm_target *ti, unsigned int num_bios)
+                               struct dm_target *ti, unsigned int num_bios,
+                               unsigned *len)
 {
        struct bio *bio;
        int try;
@@ -1478,7 +1479,7 @@ static void alloc_multiple_bios(struct bio_list *blist, struct clone_info *ci,
                if (try)
                        mutex_lock(&ci->io->md->table_devices_lock);
                for (bio_nr = 0; bio_nr < num_bios; bio_nr++) {
-                       bio = alloc_tio(ci, ti, bio_nr, NULL,
+                       bio = alloc_tio(ci, ti, bio_nr, len,
                                        try ? GFP_NOIO : GFP_NOWAIT);
                        if (!bio)
                                break;
@@ -1513,8 +1514,10 @@ static int __send_duplicate_bios(struct clone_info *ci, struct dm_target *ti,
                ret = 1;
                break;
        default:
+               if (len)
+                       setup_split_accounting(ci, *len);
                /* dm_accept_partial_bio() is not supported with shared tio->len_ptr */
-               alloc_multiple_bios(&blist, ci, ti, num_bios);
+               alloc_multiple_bios(&blist, ci, ti, num_bios, len);
                while ((clone = bio_list_pop(&blist))) {
                        dm_tio_set_flag(clone_to_tio(clone), DM_TIO_IS_DUPLICATE_BIO);
                        __map_bio(clone);
@@ -2097,7 +2100,9 @@ static struct mapped_device *alloc_dev(int minor)
        if (!md->pending_io)
                goto bad;
 
-       dm_stats_init(&md->stats);
+       r = dm_stats_init(&md->stats);
+       if (r < 0)
+               goto bad;
 
        /* Populate the mapping, nobody knows we exist yet */
        spin_lock(&_minor_lock);
index 927a43db5dfbb98fd0702163e0962201e111fe68..13321dbb5fbcf0fd65b17f88a76b14cfc3b135f9 100644 (file)
@@ -3128,6 +3128,9 @@ slot_store(struct md_rdev *rdev, const char *buf, size_t len)
                err = kstrtouint(buf, 10, (unsigned int *)&slot);
                if (err < 0)
                        return err;
+               if (slot < 0)
+                       /* overflow */
+                       return -ENOSPC;
        }
        if (rdev->mddev->pers && slot == -1) {
                /* Setting 'slot' on an active array requires also
@@ -6256,6 +6259,10 @@ static void __md_stop(struct mddev *mddev)
                mddev->to_remove = &md_redundancy_group;
        module_put(pers->owner);
        clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+
+       percpu_ref_exit(&mddev->active_io);
+       bioset_exit(&mddev->bio_set);
+       bioset_exit(&mddev->sync_set);
 }
 
 void md_stop(struct mddev *mddev)
@@ -6266,9 +6273,6 @@ void md_stop(struct mddev *mddev)
        __md_stop_writes(mddev);
        __md_stop(mddev);
        percpu_ref_exit(&mddev->writes_pending);
-       percpu_ref_exit(&mddev->active_io);
-       bioset_exit(&mddev->bio_set);
-       bioset_exit(&mddev->sync_set);
 }
 
 EXPORT_SYMBOL_GPL(md_stop);
@@ -7840,10 +7844,6 @@ static void md_free_disk(struct gendisk *disk)
        struct mddev *mddev = disk->private_data;
 
        percpu_ref_exit(&mddev->writes_pending);
-       percpu_ref_exit(&mddev->active_io);
-       bioset_exit(&mddev->bio_set);
-       bioset_exit(&mddev->sync_set);
-
        mddev_free(mddev);
 }
 
index 49d6c8bdec412ab2beb7f7dbc3e7b43400518900..48ae2e0adf9ea84615f00fa0d50a13a7ccdad860 100644 (file)
@@ -1098,7 +1098,7 @@ static int imx290_runtime_suspend(struct device *dev)
 }
 
 static const struct dev_pm_ops imx290_pm_ops = {
-       SET_RUNTIME_PM_OPS(imx290_runtime_suspend, imx290_runtime_resume, NULL)
+       RUNTIME_PM_OPS(imx290_runtime_suspend, imx290_runtime_resume, NULL)
 };
 
 /* ----------------------------------------------------------------------------
@@ -1362,8 +1362,8 @@ static struct i2c_driver imx290_i2c_driver = {
        .remove = imx290_remove,
        .driver = {
                .name  = "imx290",
-               .pm = &imx290_pm_ops,
-               .of_match_table = of_match_ptr(imx290_of_match),
+               .pm = pm_ptr(&imx290_pm_ops),
+               .of_match_table = imx290_of_match,
        },
 };
 
index 2b01873ba0db51c9c999a2d578591a85c944f0e1..5c2336f318d9a132d18b815f505da78bc033ab92 100644 (file)
@@ -488,7 +488,7 @@ static enum m5mols_restype __find_restype(u32 code)
        do {
                if (code == m5mols_default_ffmt[type].code)
                        return type;
-       } while (type++ != SIZE_DEFAULT_FFMT);
+       } while (++type != SIZE_DEFAULT_FFMT);
 
        return 0;
 }
index a3b524f15d89afcd00e20d27b3cd1cb64d64ccf0..1c80b121e7d6d0d67ae372eb8229ad35a31e3b2b 100644 (file)
@@ -707,8 +707,7 @@ static int ov2685_configure_regulators(struct ov2685 *ov2685)
                                       ov2685->supplies);
 }
 
-static int ov2685_probe(struct i2c_client *client,
-                       const struct i2c_device_id *id)
+static int ov2685_probe(struct i2c_client *client)
 {
        struct device *dev = &client->dev;
        struct ov2685 *ov2685;
@@ -830,7 +829,7 @@ static struct i2c_driver ov2685_i2c_driver = {
                .pm = &ov2685_pm_ops,
                .of_match_table = of_match_ptr(ov2685_of_match),
        },
-       .probe          = &ov2685_probe,
+       .probe_new      = &ov2685_probe,
        .remove         = &ov2685_remove,
 };
 
index 61906fc54e370d32d3f01852e2b0a8a68a1ddde1..b287c28920a687bad19633ce79e0620c3d472820 100644 (file)
@@ -1267,8 +1267,7 @@ static int ov5695_configure_regulators(struct ov5695 *ov5695)
                                       ov5695->supplies);
 }
 
-static int ov5695_probe(struct i2c_client *client,
-                       const struct i2c_device_id *id)
+static int ov5695_probe(struct i2c_client *client)
 {
        struct device *dev = &client->dev;
        struct ov5695 *ov5695;
@@ -1393,7 +1392,7 @@ static struct i2c_driver ov5695_i2c_driver = {
                .pm = &ov5695_pm_ops,
                .of_match_table = of_match_ptr(ov5695_of_match),
        },
-       .probe          = &ov5695_probe,
+       .probe_new      = &ov5695_probe,
        .remove         = &ov5695_remove,
 };
 
index 61ff20a7e935e14b88ca8b81db66b64922508474..cfb11c551167ce72f3261a2bdd4c6fd994368977 100644 (file)
@@ -38,8 +38,8 @@ static void venus_reset_cpu(struct venus_core *core)
        writel(fw_size, wrapper_base + WRAPPER_FW_END_ADDR);
        writel(0, wrapper_base + WRAPPER_CPA_START_ADDR);
        writel(fw_size, wrapper_base + WRAPPER_CPA_END_ADDR);
-       writel(0, wrapper_base + WRAPPER_NONPIX_START_ADDR);
-       writel(0, wrapper_base + WRAPPER_NONPIX_END_ADDR);
+       writel(fw_size, wrapper_base + WRAPPER_NONPIX_START_ADDR);
+       writel(fw_size, wrapper_base + WRAPPER_NONPIX_END_ADDR);
 
        if (IS_V6(core)) {
                /* Bring XTSS out of reset */
index 592907546ee64a7acc48e65980ecb8e695f24bf4..5cd28619ea9fbcc360ddfafbea9753221ef8aefa 100644 (file)
@@ -794,16 +794,12 @@ static int tegra_mc_interconnect_setup(struct tegra_mc *mc)
        mc->provider.aggregate = mc->soc->icc_ops->aggregate;
        mc->provider.xlate_extended = mc->soc->icc_ops->xlate_extended;
 
-       err = icc_provider_add(&mc->provider);
-       if (err)
-               return err;
+       icc_provider_init(&mc->provider);
 
        /* create Memory Controller node */
        node = icc_node_create(TEGRA_ICC_MC);
-       if (IS_ERR(node)) {
-               err = PTR_ERR(node);
-               goto del_provider;
-       }
+       if (IS_ERR(node))
+               return PTR_ERR(node);
 
        node->name = "Memory Controller";
        icc_node_add(node, &mc->provider);
@@ -830,12 +826,14 @@ static int tegra_mc_interconnect_setup(struct tegra_mc *mc)
                        goto remove_nodes;
        }
 
+       err = icc_provider_register(&mc->provider);
+       if (err)
+               goto remove_nodes;
+
        return 0;
 
 remove_nodes:
        icc_nodes_remove(&mc->provider);
-del_provider:
-       icc_provider_del(&mc->provider);
 
        return err;
 }
index 85bc936c02f9401eb71b11e070757345c9b45553..00ed2b6a0d1b27e0466bd2ab14e82b7efc6c1ae0 100644 (file)
@@ -1351,15 +1351,13 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc)
        emc->provider.aggregate = soc->icc_ops->aggregate;
        emc->provider.xlate_extended = emc_of_icc_xlate_extended;
 
-       err = icc_provider_add(&emc->provider);
-       if (err)
-               goto err_msg;
+       icc_provider_init(&emc->provider);
 
        /* create External Memory Controller node */
        node = icc_node_create(TEGRA_ICC_EMC);
        if (IS_ERR(node)) {
                err = PTR_ERR(node);
-               goto del_provider;
+               goto err_msg;
        }
 
        node->name = "External Memory Controller";
@@ -1380,12 +1378,14 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc)
        node->name = "External Memory (DRAM)";
        icc_node_add(node, &emc->provider);
 
+       err = icc_provider_register(&emc->provider);
+       if (err)
+               goto remove_nodes;
+
        return 0;
 
 remove_nodes:
        icc_nodes_remove(&emc->provider);
-del_provider:
-       icc_provider_del(&emc->provider);
 err_msg:
        dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
 
index bd4e37b6552de5d5a426ac963f0116352ca6590d..fd595c851a27865bb9044818596062e797ed80f6 100644 (file)
@@ -1021,15 +1021,13 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc)
        emc->provider.aggregate = soc->icc_ops->aggregate;
        emc->provider.xlate_extended = emc_of_icc_xlate_extended;
 
-       err = icc_provider_add(&emc->provider);
-       if (err)
-               goto err_msg;
+       icc_provider_init(&emc->provider);
 
        /* create External Memory Controller node */
        node = icc_node_create(TEGRA_ICC_EMC);
        if (IS_ERR(node)) {
                err = PTR_ERR(node);
-               goto del_provider;
+               goto err_msg;
        }
 
        node->name = "External Memory Controller";
@@ -1050,12 +1048,14 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc)
        node->name = "External Memory (DRAM)";
        icc_node_add(node, &emc->provider);
 
+       err = icc_provider_register(&emc->provider);
+       if (err)
+               goto remove_nodes;
+
        return 0;
 
 remove_nodes:
        icc_nodes_remove(&emc->provider);
-del_provider:
-       icc_provider_del(&emc->provider);
 err_msg:
        dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
 
index 77706e9bc5433917712a5c52e68f80134b7fd322..c91e9b7e2e019cf4af40fb0e5253f55455e984c1 100644 (file)
@@ -1533,15 +1533,13 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc)
        emc->provider.aggregate = soc->icc_ops->aggregate;
        emc->provider.xlate_extended = emc_of_icc_xlate_extended;
 
-       err = icc_provider_add(&emc->provider);
-       if (err)
-               goto err_msg;
+       icc_provider_init(&emc->provider);
 
        /* create External Memory Controller node */
        node = icc_node_create(TEGRA_ICC_EMC);
        if (IS_ERR(node)) {
                err = PTR_ERR(node);
-               goto del_provider;
+               goto err_msg;
        }
 
        node->name = "External Memory Controller";
@@ -1562,12 +1560,14 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc)
        node->name = "External Memory (DRAM)";
        icc_node_add(node, &emc->provider);
 
+       err = icc_provider_register(&emc->provider);
+       if (err)
+               goto remove_nodes;
+
        return 0;
 
 remove_nodes:
        icc_nodes_remove(&emc->provider);
-del_provider:
-       icc_provider_del(&emc->provider);
 err_msg:
        dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
 
index bf766784545916a6068932ed4ea925e94a240aef..bbfaf6536903d35c704fced42859fb4fb3e54afe 100644 (file)
@@ -410,6 +410,7 @@ static struct memstick_dev *memstick_alloc_card(struct memstick_host *host)
        return card;
 err_out:
        host->card = old_card;
+       kfree_const(card->dev.kobj.name);
        kfree(card);
        return NULL;
 }
@@ -468,8 +469,10 @@ static void memstick_check(struct work_struct *work)
                                put_device(&card->dev);
                                host->card = NULL;
                        }
-               } else
+               } else {
+                       kfree_const(card->dev.kobj.name);
                        kfree(card);
+               }
        }
 
 out_power_off:
index 28ffb4377d98992600c905088b6da5ffbc88b494..3856d5c04c5fdca66df37d175e785b7a7208afe1 100644 (file)
@@ -50,9 +50,9 @@ static const struct ad_dpot_bus_ops bops = {
        .write_r8d16    = write_r8d16,
 };
 
-static int ad_dpot_i2c_probe(struct i2c_client *client,
-                                     const struct i2c_device_id *id)
+static int ad_dpot_i2c_probe(struct i2c_client *client)
 {
+       const struct i2c_device_id *id = i2c_client_get_device_id(client);
        struct ad_dpot_bus_data bdata = {
                .client = client,
                .bops = &bops,
@@ -106,7 +106,7 @@ static struct i2c_driver ad_dpot_i2c_driver = {
        .driver = {
                .name   = "ad_dpot",
        },
-       .probe          = ad_dpot_i2c_probe,
+       .probe_new      = ad_dpot_i2c_probe,
        .remove         = ad_dpot_i2c_remove,
        .id_table       = ad_dpot_id,
 };
index 172696abce31b0d7dc3e922028c77666b0b37feb..f22b44827e9295e7628aaf322392758f5f32c057 100644 (file)
@@ -687,7 +687,7 @@ int vmci_ctx_remove_notification(u32 context_id, u32 remote_cid)
        spin_unlock(&context->lock);
 
        if (notifier)
-               kvfree_rcu(notifier);
+               kvfree_rcu_mightsleep(notifier);
 
        vmci_ctx_put(context);
 
index 2100297c94ad02ef18c9e06e0f3bd1938d396536..5d7ac07623c27330d42a37686329293b2761ef67 100644 (file)
@@ -209,7 +209,7 @@ int vmci_event_unsubscribe(u32 sub_id)
        if (!s)
                return VMCI_ERROR_NOT_FOUND;
 
-       kvfree_rcu(s);
+       kvfree_rcu_mightsleep(s);
 
        return VMCI_SUCCESS;
 }
index 40f5969b07a6678cdaae9734931c6e7f1d775e73..dab1508bf83c67ea8cbcf3d07d6f3a207930735a 100644 (file)
@@ -51,7 +51,7 @@ static int dw_mci_starfive_execute_tuning(struct dw_mci_slot *slot,
        struct dw_mci *host = slot->host;
        struct starfive_priv *priv = host->priv;
        int rise_point = -1, fall_point = -1;
-       int err, prev_err;
+       int err, prev_err = 0;
        int i;
        bool found = 0;
        u32 regval;
index 7ef828942df359c53339b59ae6ecda11e6ed2d04..672d37ea98d0f39771f2c90039f8cba75312a2b6 100644 (file)
@@ -351,8 +351,6 @@ static void sdhci_am654_write_b(struct sdhci_host *host, u8 val, int reg)
                 */
                case MMC_TIMING_SD_HS:
                case MMC_TIMING_MMC_HS:
-               case MMC_TIMING_UHS_SDR12:
-               case MMC_TIMING_UHS_SDR25:
                        val &= ~SDHCI_CTRL_HISPD;
                }
        }
@@ -369,7 +367,7 @@ static void sdhci_am654_write_b(struct sdhci_host *host, u8 val, int reg)
                                        MAX_POWER_ON_TIMEOUT, false, host, val,
                                        reg);
                if (ret)
-                       dev_warn(mmc_dev(host->mmc), "Power on failed\n");
+                       dev_info(mmc_dev(host->mmc), "Power on failed\n");
        }
 }
 
index 5fcefcd0bacac165c481bdddd2eb6be1391a4518..3e0fff3f129e7cbc6bc18963b046824e7ce2caaa 100644 (file)
@@ -206,8 +206,7 @@ static void pismo_remove(struct i2c_client *client)
        kfree(pismo);
 }
 
-static int pismo_probe(struct i2c_client *client,
-                      const struct i2c_device_id *id)
+static int pismo_probe(struct i2c_client *client)
 {
        struct pismo_pdata *pdata = client->dev.platform_data;
        struct pismo_eeprom eeprom;
@@ -260,7 +259,7 @@ static struct i2c_driver pismo_driver = {
        .driver = {
                .name   = "pismo",
        },
-       .probe          = pismo_probe,
+       .probe_new      = pismo_probe,
        .remove         = pismo_remove,
        .id_table       = pismo_id,
 };
index 1e94e7d10b8be64172d222b3136948133391d1d3..a0a1194dc1d902579f79b7befdad1d61b4a671a4 100644 (file)
@@ -153,7 +153,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
                                mtdblk->cache_state = STATE_EMPTY;
                                ret = mtd_read(mtd, sect_start, sect_size,
                                               &retlen, mtdblk->cache_data);
-                               if (ret)
+                               if (ret && !mtd_is_bitflip(ret))
                                        return ret;
                                if (retlen != sect_size)
                                        return -EIO;
@@ -188,8 +188,12 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
        pr_debug("mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
                        mtd->name, pos, len);
 
-       if (!sect_size)
-               return mtd_read(mtd, pos, len, &retlen, buf);
+       if (!sect_size) {
+               ret = mtd_read(mtd, pos, len, &retlen, buf);
+               if (ret && !mtd_is_bitflip(ret))
+                       return ret;
+               return 0;
+       }
 
        while (len > 0) {
                unsigned long sect_start = (pos/sect_size)*sect_size;
@@ -209,7 +213,7 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
                        memcpy (buf, mtdblk->cache_data + offset, size);
                } else {
                        ret = mtd_read(mtd, pos, size, &retlen, buf);
-                       if (ret)
+                       if (ret && !mtd_is_bitflip(ret))
                                return ret;
                        if (retlen != size)
                                return -EIO;
index 8afdca731b87496e5b9ef77029668ba24494122c..6b487ffe2f2dc4dd6b0344080cf665ccaab4198b 100644 (file)
@@ -429,6 +429,7 @@ static int mxic_ecc_data_xfer_wait_for_completion(struct mxic_ecc_engine *mxic)
                mxic_ecc_enable_int(mxic);
                ret = wait_for_completion_timeout(&mxic->complete,
                                                  msecs_to_jiffies(1000));
+               ret = ret ? 0 : -ETIMEDOUT;
                mxic_ecc_disable_int(mxic);
        } else {
                ret = readl_poll_timeout(mxic->regs + INTRPT_STS, val,
index 5ee01231ac4cdc5dbb156851a2fdb6c13a402e07..074e14225c06a07e0ceba491d14b5272472860d7 100644 (file)
@@ -176,6 +176,7 @@ struct meson_nfc {
 
        dma_addr_t daddr;
        dma_addr_t iaddr;
+       u32 info_bytes;
 
        unsigned long assigned_cs;
 };
@@ -279,7 +280,7 @@ static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir,
 
        if (raw) {
                len = mtd->writesize + mtd->oobsize;
-               cmd = (len & GENMASK(5, 0)) | scrambler | DMA_DIR(dir);
+               cmd = (len & GENMASK(13, 0)) | scrambler | DMA_DIR(dir);
                writel(cmd, nfc->reg_base + NFC_REG_CMD);
                return;
        }
@@ -503,6 +504,7 @@ static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf,
                                         nfc->daddr, datalen, dir);
                        return ret;
                }
+               nfc->info_bytes = infolen;
                cmd = GENCMDIADDRL(NFC_CMD_AIL, nfc->iaddr);
                writel(cmd, nfc->reg_base + NFC_REG_CMD);
 
@@ -520,8 +522,10 @@ static void meson_nfc_dma_buffer_release(struct nand_chip *nand,
        struct meson_nfc *nfc = nand_get_controller_data(nand);
 
        dma_unmap_single(nfc->dev, nfc->daddr, datalen, dir);
-       if (infolen)
+       if (infolen) {
                dma_unmap_single(nfc->dev, nfc->iaddr, infolen, dir);
+               nfc->info_bytes = 0;
+       }
 }
 
 static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len)
@@ -540,7 +544,7 @@ static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len)
        if (ret)
                goto out;
 
-       cmd = NFC_CMD_N2M | (len & GENMASK(5, 0));
+       cmd = NFC_CMD_N2M | (len & GENMASK(13, 0));
        writel(cmd, nfc->reg_base + NFC_REG_CMD);
 
        meson_nfc_drain_cmd(nfc);
@@ -564,7 +568,7 @@ static int meson_nfc_write_buf(struct nand_chip *nand, u8 *buf, int len)
        if (ret)
                return ret;
 
-       cmd = NFC_CMD_M2N | (len & GENMASK(5, 0));
+       cmd = NFC_CMD_M2N | (len & GENMASK(13, 0));
        writel(cmd, nfc->reg_base + NFC_REG_CMD);
 
        meson_nfc_drain_cmd(nfc);
@@ -710,6 +714,8 @@ static void meson_nfc_check_ecc_pages_valid(struct meson_nfc *nfc,
                usleep_range(10, 15);
                /* info is updated by nfc dma engine*/
                smp_rmb();
+               dma_sync_single_for_cpu(nfc->dev, nfc->iaddr, nfc->info_bytes,
+                                       DMA_FROM_DEVICE);
                ret = *info & ECC_COMPLETE;
        } while (!ret);
 }
@@ -991,7 +997,7 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
 
 static int meson_nfc_clk_init(struct meson_nfc *nfc)
 {
-       struct clk_parent_data nfc_divider_parent_data[1];
+       struct clk_parent_data nfc_divider_parent_data[1] = {0};
        struct clk_init_data init = {0};
        int ret;
 
index c21abf7489481a5b230fc67b6361456eaa6e07a5..179b28459b4bdd5a158534b69b180dee9cedd5b2 100644 (file)
@@ -2160,8 +2160,23 @@ static int ns_exec_op(struct nand_chip *chip, const struct nand_operation *op,
        const struct nand_op_instr *instr = NULL;
        struct nandsim *ns = nand_get_controller_data(chip);
 
-       if (check_only)
+       if (check_only) {
+               /* The current implementation of nandsim needs to know the
+                * ongoing operation when performing the address cycles. This
+                * means it cannot make the difference between a regular read
+                * and a continuous read. Hence, this hack to manually refuse
+                * supporting sequential cached operations.
+                */
+               for (op_id = 0; op_id < op->ninstrs; op_id++) {
+                       instr = &op->instrs[op_id];
+                       if (instr->type == NAND_OP_CMD_INSTR &&
+                           (instr->ctx.cmd.opcode == NAND_CMD_READCACHEEND ||
+                            instr->ctx.cmd.opcode == NAND_CMD_READCACHESEQ))
+                               return -EOPNOTSUPP;
+               }
+
                return 0;
+       }
 
        ns->lines.ce = 1;
 
index 5d627048c420de5d2516b2135736bb2aec65780b..9e74bcd90aaa2e216a74fee29476bc0b7f209e2c 100644 (file)
@@ -1531,6 +1531,9 @@ static int stm32_fmc2_nfc_setup_interface(struct nand_chip *chip, int chipnr,
        if (IS_ERR(sdrt))
                return PTR_ERR(sdrt);
 
+       if (conf->timings.mode > 3)
+               return -EOPNOTSUPP;
+
        if (chipnr == NAND_DATA_IFACE_CHECK_ONLY)
                return 0;
 
index 0a78045ca1d94ea184d295bfdb3af8bb1f41894b..522d375aeccff6be0397ce2df10e33261358307e 100644 (file)
@@ -3343,7 +3343,19 @@ static struct spi_mem_driver spi_nor_driver = {
        .remove = spi_nor_remove,
        .shutdown = spi_nor_shutdown,
 };
-module_spi_mem_driver(spi_nor_driver);
+
+static int __init spi_nor_module_init(void)
+{
+       return spi_mem_driver_register(&spi_nor_driver);
+}
+module_init(spi_nor_module_init);
+
+static void __exit spi_nor_module_exit(void)
+{
+       spi_mem_driver_unregister(&spi_nor_driver);
+       spi_nor_debugfs_shutdown();
+}
+module_exit(spi_nor_module_exit);
 
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Huang Shijie <shijie8@gmail.com>");
index 25423225c29d33f1817a1872106c54e4a00ad5c8..e0cc42a4a0c8410a0148a649b58684ae6eb8940d 100644 (file)
@@ -711,8 +711,10 @@ static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
 
 #ifdef CONFIG_DEBUG_FS
 void spi_nor_debugfs_register(struct spi_nor *nor);
+void spi_nor_debugfs_shutdown(void);
 #else
 static inline void spi_nor_debugfs_register(struct spi_nor *nor) {}
+static inline void spi_nor_debugfs_shutdown(void) {}
 #endif
 
 #endif /* __LINUX_MTD_SPI_NOR_INTERNAL_H */
index 845b78c7ecc7a27f6fa18a6afd982adf63a0fea6..fc7ad203df12802b0f5aa5c386a5077b3844143e 100644 (file)
@@ -226,13 +226,13 @@ static void spi_nor_debugfs_unregister(void *data)
        nor->debugfs_root = NULL;
 }
 
+static struct dentry *rootdir;
+
 void spi_nor_debugfs_register(struct spi_nor *nor)
 {
-       struct dentry *rootdir, *d;
+       struct dentry *d;
        int ret;
 
-       /* Create rootdir once. Will never be deleted again. */
-       rootdir = debugfs_lookup(SPI_NOR_DEBUGFS_ROOT, NULL);
        if (!rootdir)
                rootdir = debugfs_create_dir(SPI_NOR_DEBUGFS_ROOT, NULL);
 
@@ -247,3 +247,8 @@ void spi_nor_debugfs_register(struct spi_nor *nor)
        debugfs_create_file("capabilities", 0444, d, nor,
                            &spi_nor_capabilities_fops);
 }
+
+void spi_nor_debugfs_shutdown(void)
+{
+       debugfs_remove(rootdir);
+}
index 1de87062c67b9b54ca6664abeadefaf4971dbafb..3711d7f746003d3902a3b7b41865f81aea0c97b3 100644 (file)
@@ -221,7 +221,10 @@ static blk_status_t ubiblock_read(struct request *req)
 
        rq_for_each_segment(bvec, req, iter)
                flush_dcache_page(bvec.bv_page);
-       return errno_to_blk_status(ret);
+
+       blk_mq_end_request(req, errno_to_blk_status(ret));
+
+       return BLK_STS_OK;
 }
 
 static int ubiblock_open(struct block_device *bdev, fmode_t mode)
index 0904eb40c95fa133c1cdc4454beb6d4d3d90fc6a..ad025b2ee41773397f7dac35d34dbcba763eb5cf 100644 (file)
@@ -666,12 +666,6 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024)
        ubi->ec_hdr_alsize = ALIGN(UBI_EC_HDR_SIZE, ubi->hdrs_min_io_size);
        ubi->vid_hdr_alsize = ALIGN(UBI_VID_HDR_SIZE, ubi->hdrs_min_io_size);
 
-       if (ubi->vid_hdr_offset && ((ubi->vid_hdr_offset + UBI_VID_HDR_SIZE) >
-           ubi->vid_hdr_alsize)) {
-               ubi_err(ubi, "VID header offset %d too large.", ubi->vid_hdr_offset);
-               return -EINVAL;
-       }
-
        dbg_gen("min_io_size      %d", ubi->min_io_size);
        dbg_gen("max_write_size   %d", ubi->max_write_size);
        dbg_gen("hdrs_min_io_size %d", ubi->hdrs_min_io_size);
@@ -689,6 +683,21 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024)
                                                ubi->vid_hdr_aloffset;
        }
 
+       /*
+        * Memory allocation for VID header is ubi->vid_hdr_alsize
+        * which is described in comments in io.c.
+        * Make sure VID header shift + UBI_VID_HDR_SIZE not exceeds
+        * ubi->vid_hdr_alsize, so that all vid header operations
+        * won't access memory out of bounds.
+        */
+       if ((ubi->vid_hdr_shift + UBI_VID_HDR_SIZE) > ubi->vid_hdr_alsize) {
+               ubi_err(ubi, "Invalid VID header offset %d, VID header shift(%d)"
+                       " + VID header size(%zu) > VID header aligned size(%d).",
+                       ubi->vid_hdr_offset, ubi->vid_hdr_shift,
+                       UBI_VID_HDR_SIZE, ubi->vid_hdr_alsize);
+               return -EINVAL;
+       }
+
        /* Similar for the data offset */
        ubi->leb_start = ubi->vid_hdr_offset + UBI_VID_HDR_SIZE;
        ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size);
index 40f39e5d6dfcc068519598452bd8787c7b143c39..26a214f016c18448469c4bb3988ac09af224ab95 100644 (file)
@@ -575,7 +575,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
  * @vol_id: the volume ID that last used this PEB
  * @lnum: the last used logical eraseblock number for the PEB
  * @torture: if the physical eraseblock has to be tortured
- * @nested: denotes whether the work_sem is already held in read mode
+ * @nested: denotes whether the work_sem is already held
  *
  * This function returns zero in case of success and a %-ENOMEM in case of
  * failure.
@@ -1131,7 +1131,7 @@ static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk)
                int err1;
 
                /* Re-schedule the LEB for erasure */
-               err1 = schedule_erase(ubi, e, vol_id, lnum, 0, false);
+               err1 = schedule_erase(ubi, e, vol_id, lnum, 0, true);
                if (err1) {
                        spin_lock(&ubi->wl_lock);
                        wl_entry_destroy(ubi, e);
index 00646aa315c307f6708f179b5180a9c24813da59..7a7d584f378a5ae441d41ab5c804a31601ec9453 100644 (file)
@@ -1775,6 +1775,20 @@ void bond_lower_state_changed(struct slave *slave)
                slave_err(bond_dev, slave_dev, "Error: %s\n", errmsg);  \
 } while (0)
 
+/* The bonding driver uses ether_setup() to convert a master bond device
+ * to ARPHRD_ETHER, that resets the target netdevice's flags so we always
+ * have to restore the IFF_MASTER flag, and only restore IFF_SLAVE and IFF_UP
+ * if they were set
+ */
+static void bond_ether_setup(struct net_device *bond_dev)
+{
+       unsigned int flags = bond_dev->flags & (IFF_SLAVE | IFF_UP);
+
+       ether_setup(bond_dev);
+       bond_dev->flags |= IFF_MASTER | flags;
+       bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+}
+
 /* enslave device <slave> to bond device <master> */
 int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
                 struct netlink_ext_ack *extack)
@@ -1866,10 +1880,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
 
                        if (slave_dev->type != ARPHRD_ETHER)
                                bond_setup_by_slave(bond_dev, slave_dev);
-                       else {
-                               ether_setup(bond_dev);
-                               bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING;
-                       }
+                       else
+                               bond_ether_setup(bond_dev);
 
                        call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE,
                                                 bond_dev);
@@ -2289,9 +2301,7 @@ err_undo_flags:
                        eth_hw_addr_random(bond_dev);
                if (bond_dev->type != ARPHRD_ETHER) {
                        dev_close(bond_dev);
-                       ether_setup(bond_dev);
-                       bond_dev->flags |= IFF_MASTER;
-                       bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+                       bond_ether_setup(bond_dev);
                }
        }
 
@@ -3260,7 +3270,8 @@ static int bond_na_rcv(const struct sk_buff *skb, struct bonding *bond,
 
        combined = skb_header_pointer(skb, 0, sizeof(_combined), &_combined);
        if (!combined || combined->ip6.nexthdr != NEXTHDR_ICMP ||
-           combined->icmp6.icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT)
+           (combined->icmp6.icmp6_type != NDISC_NEIGHBOUR_SOLICITATION &&
+            combined->icmp6.icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT))
                goto out;
 
        saddr = &combined->ip6.saddr;
@@ -3282,7 +3293,7 @@ static int bond_na_rcv(const struct sk_buff *skb, struct bonding *bond,
        else if (curr_active_slave &&
                 time_after(slave_last_rx(bond, curr_active_slave),
                            curr_active_slave->last_link_up))
-               bond_validate_na(bond, slave, saddr, daddr);
+               bond_validate_na(bond, slave, daddr, saddr);
        else if (curr_arp_slave &&
                 bond_time_in_interval(bond, slave_last_tx(curr_arp_slave), 1))
                bond_validate_na(bond, slave, saddr, daddr);
index 8d916e2ee6c252e22a200376787e4f84351c7363..8dcc32e4e30efac4f655cf9f28d856758d97252a 100644 (file)
@@ -93,20 +93,20 @@ static int cc770_get_of_node_data(struct platform_device *pdev,
        if (priv->can.clock.freq > 8000000)
                priv->cpu_interface |= CPUIF_DMC;
 
-       if (of_get_property(np, "bosch,divide-memory-clock", NULL))
+       if (of_property_read_bool(np, "bosch,divide-memory-clock"))
                priv->cpu_interface |= CPUIF_DMC;
-       if (of_get_property(np, "bosch,iso-low-speed-mux", NULL))
+       if (of_property_read_bool(np, "bosch,iso-low-speed-mux"))
                priv->cpu_interface |= CPUIF_MUX;
 
        if (!of_get_property(np, "bosch,no-comperator-bypass", NULL))
                priv->bus_config |= BUSCFG_CBY;
-       if (of_get_property(np, "bosch,disconnect-rx0-input", NULL))
+       if (of_property_read_bool(np, "bosch,disconnect-rx0-input"))
                priv->bus_config |= BUSCFG_DR0;
-       if (of_get_property(np, "bosch,disconnect-rx1-input", NULL))
+       if (of_property_read_bool(np, "bosch,disconnect-rx1-input"))
                priv->bus_config |= BUSCFG_DR1;
-       if (of_get_property(np, "bosch,disconnect-tx1-output", NULL))
+       if (of_property_read_bool(np, "bosch,disconnect-tx1-output"))
                priv->bus_config |= BUSCFG_DT1;
-       if (of_get_property(np, "bosch,polarity-dominant", NULL))
+       if (of_property_read_bool(np, "bosch,polarity-dominant"))
                priv->bus_config |= BUSCFG_POL;
 
        prop = of_get_property(np, "bosch,clock-out-frequency", &prop_size);
index e968322dfbf0b262e23cd55fa482d5eb268fd2dc..d9434ed9450dfe0e3921e890f1ebe7d629690334 100644 (file)
@@ -216,6 +216,18 @@ static int b53_mmap_write64(struct b53_device *dev, u8 page, u8 reg,
        return 0;
 }
 
+static int b53_mmap_phy_read16(struct b53_device *dev, int addr, int reg,
+                              u16 *value)
+{
+       return -EIO;
+}
+
+static int b53_mmap_phy_write16(struct b53_device *dev, int addr, int reg,
+                               u16 value)
+{
+       return -EIO;
+}
+
 static const struct b53_io_ops b53_mmap_ops = {
        .read8 = b53_mmap_read8,
        .read16 = b53_mmap_read16,
@@ -227,6 +239,8 @@ static const struct b53_io_ops b53_mmap_ops = {
        .write32 = b53_mmap_write32,
        .write48 = b53_mmap_write48,
        .write64 = b53_mmap_write64,
+       .phy_read16 = b53_mmap_phy_read16,
+       .phy_write16 = b53_mmap_phy_write16,
 };
 
 static int b53_mmap_probe_of(struct platform_device *pdev,
@@ -263,7 +277,7 @@ static int b53_mmap_probe_of(struct platform_device *pdev,
                if (of_property_read_u32(of_port, "reg", &reg))
                        continue;
 
-               if (reg < B53_CPU_PORT)
+               if (reg < B53_N_PORTS)
                        pdata->enabled_ports |= BIT(reg);
        }
 
index 003b0ac2854c97c5c9f4c8c84ca20c642dab1259..ffcad057d0650c7fbd44aa494bc68896f8b5829a 100644 (file)
@@ -96,7 +96,7 @@ static int ksz8795_change_mtu(struct ksz_device *dev, int frame_size)
 
        if (frame_size > KSZ8_LEGAL_PACKET_SIZE)
                ctrl2 |= SW_LEGAL_PACKET_DISABLE;
-       else if (frame_size > KSZ8863_NORMAL_PACKET_SIZE)
+       if (frame_size > KSZ8863_NORMAL_PACKET_SIZE)
                ctrl1 |= SW_HUGE_PACKET;
 
        ret = ksz_rmw8(dev, REG_SW_CTRL_1, SW_HUGE_PACKET, ctrl1);
@@ -958,15 +958,14 @@ int ksz8_fdb_dump(struct ksz_device *dev, int port,
        u16 entries = 0;
        u8 timestamp = 0;
        u8 fid;
-       u8 member;
-       struct alu_struct alu;
+       u8 src_port;
+       u8 mac[ETH_ALEN];
 
        do {
-               alu.is_static = false;
-               ret = ksz8_r_dyn_mac_table(dev, i, alu.mac, &fid, &member,
+               ret = ksz8_r_dyn_mac_table(dev, i, mac, &fid, &src_port,
                                           &timestamp, &entries);
-               if (!ret && (member & BIT(port))) {
-                       ret = cb(alu.mac, alu.fid, alu.is_static, data);
+               if (!ret && port == src_port) {
+                       ret = cb(mac, fid, false, data);
                        if (ret)
                                break;
                }
index 2f4623f3bd852a81253375175af18efb1ef7e8a3..3698112138b78b33a1205690b3d9a35e5ab6c557 100644 (file)
@@ -82,22 +82,16 @@ static const struct regmap_bus regmap_smi[] = {
        {
                .read = ksz8863_mdio_read,
                .write = ksz8863_mdio_write,
-               .max_raw_read = 1,
-               .max_raw_write = 1,
        },
        {
                .read = ksz8863_mdio_read,
                .write = ksz8863_mdio_write,
                .val_format_endian_default = REGMAP_ENDIAN_BIG,
-               .max_raw_read = 2,
-               .max_raw_write = 2,
        },
        {
                .read = ksz8863_mdio_read,
                .write = ksz8863_mdio_write,
                .val_format_endian_default = REGMAP_ENDIAN_BIG,
-               .max_raw_read = 4,
-               .max_raw_write = 4,
        }
 };
 
@@ -108,7 +102,6 @@ static const struct regmap_config ksz8863_regmap_config[] = {
                .pad_bits = 24,
                .val_bits = 8,
                .cache_type = REGCACHE_NONE,
-               .use_single_read = 1,
                .lock = ksz_regmap_lock,
                .unlock = ksz_regmap_unlock,
        },
@@ -118,7 +111,6 @@ static const struct regmap_config ksz8863_regmap_config[] = {
                .pad_bits = 24,
                .val_bits = 16,
                .cache_type = REGCACHE_NONE,
-               .use_single_read = 1,
                .lock = ksz_regmap_lock,
                .unlock = ksz_regmap_unlock,
        },
@@ -128,7 +120,6 @@ static const struct regmap_config ksz8863_regmap_config[] = {
                .pad_bits = 24,
                .val_bits = 32,
                .cache_type = REGCACHE_NONE,
-               .use_single_read = 1,
                .lock = ksz_regmap_lock,
                .unlock = ksz_regmap_unlock,
        }
index 729b36eeb2c46acacf9312f1af6fd7a68f40455e..74c56d05ab0b9d582eb32c45480b5c6fd8df5ecd 100644 (file)
@@ -319,7 +319,7 @@ static const u16 ksz8795_regs[] = {
        [S_BROADCAST_CTRL]              = 0x06,
        [S_MULTICAST_CTRL]              = 0x04,
        [P_XMII_CTRL_0]                 = 0x06,
-       [P_XMII_CTRL_1]                 = 0x56,
+       [P_XMII_CTRL_1]                 = 0x06,
 };
 
 static const u32 ksz8795_masks[] = {
@@ -404,13 +404,13 @@ static const u32 ksz8863_masks[] = {
        [VLAN_TABLE_VALID]              = BIT(19),
        [STATIC_MAC_TABLE_VALID]        = BIT(19),
        [STATIC_MAC_TABLE_USE_FID]      = BIT(21),
-       [STATIC_MAC_TABLE_FID]          = GENMASK(29, 26),
+       [STATIC_MAC_TABLE_FID]          = GENMASK(25, 22),
        [STATIC_MAC_TABLE_OVERRIDE]     = BIT(20),
        [STATIC_MAC_TABLE_FWD_PORTS]    = GENMASK(18, 16),
-       [DYNAMIC_MAC_TABLE_ENTRIES_H]   = GENMASK(5, 0),
-       [DYNAMIC_MAC_TABLE_MAC_EMPTY]   = BIT(7),
+       [DYNAMIC_MAC_TABLE_ENTRIES_H]   = GENMASK(1, 0),
+       [DYNAMIC_MAC_TABLE_MAC_EMPTY]   = BIT(2),
        [DYNAMIC_MAC_TABLE_NOT_READY]   = BIT(7),
-       [DYNAMIC_MAC_TABLE_ENTRIES]     = GENMASK(31, 28),
+       [DYNAMIC_MAC_TABLE_ENTRIES]     = GENMASK(31, 24),
        [DYNAMIC_MAC_TABLE_FID]         = GENMASK(19, 16),
        [DYNAMIC_MAC_TABLE_SRC_PORT]    = GENMASK(21, 20),
        [DYNAMIC_MAC_TABLE_TIMESTAMP]   = GENMASK(23, 22),
@@ -420,10 +420,10 @@ static u8 ksz8863_shifts[] = {
        [VLAN_TABLE_MEMBERSHIP_S]       = 16,
        [STATIC_MAC_FWD_PORTS]          = 16,
        [STATIC_MAC_FID]                = 22,
-       [DYNAMIC_MAC_ENTRIES_H]         = 3,
+       [DYNAMIC_MAC_ENTRIES_H]         = 8,
        [DYNAMIC_MAC_ENTRIES]           = 24,
        [DYNAMIC_MAC_FID]               = 16,
-       [DYNAMIC_MAC_TIMESTAMP]         = 24,
+       [DYNAMIC_MAC_TIMESTAMP]         = 22,
        [DYNAMIC_MAC_SRC_PORT]          = 20,
 };
 
index 3a15015bc409eb72f76aeb81668ae4ffbd717d6d..02410ac439b76c18c915562ebddd35aec685364a 100644 (file)
@@ -393,12 +393,38 @@ mt7530_fdb_write(struct mt7530_priv *priv, u16 vid,
                mt7530_write(priv, MT7530_ATA1 + (i * 4), reg[i]);
 }
 
-/* Setup TX circuit including relevant PAD and driving */
+/* Set up switch core clock for MT7530 */
+static void mt7530_pll_setup(struct mt7530_priv *priv)
+{
+       /* Disable core clock */
+       core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
+
+       /* Disable PLL */
+       core_write(priv, CORE_GSWPLL_GRP1, 0);
+
+       /* Set core clock into 500Mhz */
+       core_write(priv, CORE_GSWPLL_GRP2,
+                  RG_GSWPLL_POSDIV_500M(1) |
+                  RG_GSWPLL_FBKDIV_500M(25));
+
+       /* Enable PLL */
+       core_write(priv, CORE_GSWPLL_GRP1,
+                  RG_GSWPLL_EN_PRE |
+                  RG_GSWPLL_POSDIV_200M(2) |
+                  RG_GSWPLL_FBKDIV_200M(32));
+
+       udelay(20);
+
+       /* Enable core clock */
+       core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
+}
+
+/* Setup port 6 interface mode and TRGMII TX circuit */
 static int
 mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
 {
        struct mt7530_priv *priv = ds->priv;
-       u32 ncpo1, ssc_delta, trgint, i, xtal;
+       u32 ncpo1, ssc_delta, trgint, xtal;
 
        xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
 
@@ -412,11 +438,13 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
        switch (interface) {
        case PHY_INTERFACE_MODE_RGMII:
                trgint = 0;
-               /* PLL frequency: 125MHz */
-               ncpo1 = 0x0c80;
                break;
        case PHY_INTERFACE_MODE_TRGMII:
                trgint = 1;
+               if (xtal == HWTRAP_XTAL_25MHZ)
+                       ssc_delta = 0x57;
+               else
+                       ssc_delta = 0x87;
                if (priv->id == ID_MT7621) {
                        /* PLL frequency: 150MHz: 1.2GBit */
                        if (xtal == HWTRAP_XTAL_40MHZ)
@@ -436,61 +464,32 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
                return -EINVAL;
        }
 
-       if (xtal == HWTRAP_XTAL_25MHZ)
-               ssc_delta = 0x57;
-       else
-               ssc_delta = 0x87;
-
        mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK,
                   P6_INTF_MODE(trgint));
 
-       /* Lower Tx Driving for TRGMII path */
-       for (i = 0 ; i < NUM_TRGMII_CTRL ; i++)
-               mt7530_write(priv, MT7530_TRGMII_TD_ODT(i),
-                            TD_DM_DRVP(8) | TD_DM_DRVN(8));
-
-       /* Disable MT7530 core and TRGMII Tx clocks */
-       core_clear(priv, CORE_TRGMII_GSW_CLK_CG,
-                  REG_GSWCK_EN | REG_TRGMIICK_EN);
-
-       /* Setup core clock for MT7530 */
-       /* Disable PLL */
-       core_write(priv, CORE_GSWPLL_GRP1, 0);
-
-       /* Set core clock into 500Mhz */
-       core_write(priv, CORE_GSWPLL_GRP2,
-                  RG_GSWPLL_POSDIV_500M(1) |
-                  RG_GSWPLL_FBKDIV_500M(25));
-
-       /* Enable PLL */
-       core_write(priv, CORE_GSWPLL_GRP1,
-                  RG_GSWPLL_EN_PRE |
-                  RG_GSWPLL_POSDIV_200M(2) |
-                  RG_GSWPLL_FBKDIV_200M(32));
+       if (trgint) {
+               /* Disable the MT7530 TRGMII clocks */
+               core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
+
+               /* Setup the MT7530 TRGMII Tx Clock */
+               core_write(priv, CORE_PLL_GROUP5, RG_LCDDS_PCW_NCPO1(ncpo1));
+               core_write(priv, CORE_PLL_GROUP6, RG_LCDDS_PCW_NCPO0(0));
+               core_write(priv, CORE_PLL_GROUP10, RG_LCDDS_SSC_DELTA(ssc_delta));
+               core_write(priv, CORE_PLL_GROUP11, RG_LCDDS_SSC_DELTA1(ssc_delta));
+               core_write(priv, CORE_PLL_GROUP4,
+                          RG_SYSPLL_DDSFBK_EN | RG_SYSPLL_BIAS_EN |
+                          RG_SYSPLL_BIAS_LPF_EN);
+               core_write(priv, CORE_PLL_GROUP2,
+                          RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN |
+                          RG_SYSPLL_POSDIV(1));
+               core_write(priv, CORE_PLL_GROUP7,
+                          RG_LCDDS_PCW_NCPO_CHG | RG_LCCDS_C(3) |
+                          RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
+
+               /* Enable the MT7530 TRGMII clocks */
+               core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
+       }
 
-       /* Setup the MT7530 TRGMII Tx Clock */
-       core_write(priv, CORE_PLL_GROUP5, RG_LCDDS_PCW_NCPO1(ncpo1));
-       core_write(priv, CORE_PLL_GROUP6, RG_LCDDS_PCW_NCPO0(0));
-       core_write(priv, CORE_PLL_GROUP10, RG_LCDDS_SSC_DELTA(ssc_delta));
-       core_write(priv, CORE_PLL_GROUP11, RG_LCDDS_SSC_DELTA1(ssc_delta));
-       core_write(priv, CORE_PLL_GROUP4,
-                  RG_SYSPLL_DDSFBK_EN | RG_SYSPLL_BIAS_EN |
-                  RG_SYSPLL_BIAS_LPF_EN);
-       core_write(priv, CORE_PLL_GROUP2,
-                  RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN |
-                  RG_SYSPLL_POSDIV(1));
-       core_write(priv, CORE_PLL_GROUP7,
-                  RG_LCDDS_PCW_NCPO_CHG | RG_LCCDS_C(3) |
-                  RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
-
-       /* Enable MT7530 core and TRGMII Tx clocks */
-       core_set(priv, CORE_TRGMII_GSW_CLK_CG,
-                REG_GSWCK_EN | REG_TRGMIICK_EN);
-
-       if (!trgint)
-               for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
-                       mt7530_rmw(priv, MT7530_TRGMII_RD(i),
-                                  RD_TAP_MASK, RD_TAP(16));
        return 0;
 }
 
@@ -2196,7 +2195,18 @@ mt7530_setup(struct dsa_switch *ds)
                     SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
                     SYS_CTRL_REG_RST);
 
-       /* Enable Port 6 only; P5 as GMAC5 which currently is not supported */
+       mt7530_pll_setup(priv);
+
+       /* Lower Tx driving for TRGMII path */
+       for (i = 0; i < NUM_TRGMII_CTRL; i++)
+               mt7530_write(priv, MT7530_TRGMII_TD_ODT(i),
+                            TD_DM_DRVP(8) | TD_DM_DRVN(8));
+
+       for (i = 0; i < NUM_TRGMII_CTRL; i++)
+               mt7530_rmw(priv, MT7530_TRGMII_RD(i),
+                          RD_TAP_MASK, RD_TAP(16));
+
+       /* Enable port 6 */
        val = mt7530_read(priv, MT7530_MHWTRAP);
        val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS;
        val |= MHWTRAP_MANUAL;
index 0a5d6c7bb128dfd8dab5b200f72d0a1f6c7396b1..7108f745fbf010b78bea87f5155eb61b17651175 100644 (file)
@@ -3354,9 +3354,14 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
         * If this is the upstream port for this switch, enable
         * forwarding of unknown unicasts and multicasts.
         */
-       reg = MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP |
-               MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP |
+       reg = MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP |
                MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
+       /* Forward any IPv4 IGMP or IPv6 MLD frames received
+        * by a USER port to the CPU port to allow snooping.
+        */
+       if (dsa_is_user_port(ds, port))
+               reg |= MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP;
+
        err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
        if (err)
                return err;
@@ -3549,7 +3554,7 @@ static int mv88e6xxx_get_max_mtu(struct dsa_switch *ds, int port)
                return 10240 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
        else if (chip->info->ops->set_max_frame_size)
                return 1632 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
-       return 1522 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
+       return ETH_DATA_LEN;
 }
 
 static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
@@ -3557,6 +3562,17 @@ static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
        struct mv88e6xxx_chip *chip = ds->priv;
        int ret = 0;
 
+       /* For families where we don't know how to alter the MTU,
+        * just accept any value up to ETH_DATA_LEN
+        */
+       if (!chip->info->ops->port_set_jumbo_size &&
+           !chip->info->ops->set_max_frame_size) {
+               if (new_mtu > ETH_DATA_LEN)
+                       return -EINVAL;
+
+               return 0;
+       }
+
        if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
                new_mtu += EDSA_HLEN;
 
@@ -3565,9 +3581,6 @@ static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
                ret = chip->info->ops->port_set_jumbo_size(chip, port, new_mtu);
        else if (chip->info->ops->set_max_frame_size)
                ret = chip->info->ops->set_max_frame_size(chip, new_mtu);
-       else
-               if (new_mtu > 1522)
-                       ret = -EINVAL;
        mv88e6xxx_reg_unlock(chip);
 
        return ret;
@@ -5588,7 +5601,7 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = {
         * .port_set_upstream_port method.
         */
        .set_egress_port = mv88e6393x_set_egress_port,
-       .watchdog_ops = &mv88e6390_watchdog_ops,
+       .watchdog_ops = &mv88e6393x_watchdog_ops,
        .mgmt_rsvd2cpu = mv88e6393x_port_mgmt_rsvd2cpu,
        .pot_clear = mv88e6xxx_g2_pot_clear,
        .reset = mv88e6352_g1_reset,
index ed3b2f88e7835d7b7449d4b1f7c8e6ce80f188cd..a7af3cebae97c9a1ce67893fb44c53202cb4af59 100644 (file)
@@ -943,6 +943,26 @@ const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops = {
        .irq_free = mv88e6390_watchdog_free,
 };
 
+static int mv88e6393x_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
+{
+       mv88e6390_watchdog_action(chip, irq);
+
+       /* Fix for clearing the force WD event bit.
+        * Unreleased erratum on mv88e6393x.
+        */
+       mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
+                          MV88E6390_G2_WDOG_CTL_UPDATE |
+                          MV88E6390_G2_WDOG_CTL_PTR_EVENT);
+
+       return IRQ_HANDLED;
+}
+
+const struct mv88e6xxx_irq_ops mv88e6393x_watchdog_ops = {
+       .irq_action = mv88e6393x_watchdog_action,
+       .irq_setup = mv88e6390_watchdog_setup,
+       .irq_free = mv88e6390_watchdog_free,
+};
+
 static irqreturn_t mv88e6xxx_g2_watchdog_thread_fn(int irq, void *dev_id)
 {
        struct mv88e6xxx_chip *chip = dev_id;
index e973114d689069998c6934787d614d779910db7b..7e091965582b75254b3dd6b0fed781a77f637d75 100644 (file)
@@ -369,6 +369,7 @@ int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target,
 extern const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops;
 extern const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops;
 extern const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops;
+extern const struct mv88e6xxx_irq_ops mv88e6393x_watchdog_ops;
 
 extern const struct mv88e6xxx_avb_ops mv88e6165_avb_ops;
 extern const struct mv88e6xxx_avb_ops mv88e6352_avb_ops;
index 3e54fac5f9027ca1ae3d11f39f3735a102b0d17d..5a8fe707ca25ef7bafa7f1c7448ef8b158018fdf 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/overflow.h>
 #include <linux/regmap.h>
 
 #include "realtek.h"
@@ -152,7 +153,9 @@ static int realtek_mdio_probe(struct mdio_device *mdiodev)
        if (!var)
                return -EINVAL;
 
-       priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
+       priv = devm_kzalloc(&mdiodev->dev,
+                           size_add(sizeof(*priv), var->chip_data_sz),
+                           GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
index 323ec56e8a74c37f1ce859a564d08b14b32545ca..1917da784191988ea5c0cbc995ec946f647a4b29 100644 (file)
@@ -132,6 +132,16 @@ source "drivers/net/ethernet/mscc/Kconfig"
 source "drivers/net/ethernet/microsoft/Kconfig"
 source "drivers/net/ethernet/moxa/Kconfig"
 source "drivers/net/ethernet/myricom/Kconfig"
+
+config FEALNX
+       tristate "Myson MTD-8xx PCI Ethernet support"
+       depends on PCI
+       select CRC32
+       select MII
+       help
+         Say Y here to support the Myson MTD-800 family of PCI-based Ethernet
+         cards. <http://www.myson.com.tw/>
+
 source "drivers/net/ethernet/ni/Kconfig"
 source "drivers/net/ethernet/natsemi/Kconfig"
 source "drivers/net/ethernet/neterion/Kconfig"
index 2fedbaa545eb1cb4aa7de091335733f8d0f12148..0d872d4efcd10b1d29752e7fcd6aede2ec657902 100644 (file)
@@ -64,6 +64,7 @@ obj-$(CONFIG_NET_VENDOR_MICROCHIP) += microchip/
 obj-$(CONFIG_NET_VENDOR_MICROSEMI) += mscc/
 obj-$(CONFIG_NET_VENDOR_MOXART) += moxa/
 obj-$(CONFIG_NET_VENDOR_MYRI) += myricom/
+obj-$(CONFIG_FEALNX) += fealnx.o
 obj-$(CONFIG_NET_VENDOR_NATSEMI) += natsemi/
 obj-$(CONFIG_NET_VENDOR_NETERION) += neterion/
 obj-$(CONFIG_NET_VENDOR_NETRONOME) += netronome/
index 8da79eedc057c2f68dbbe5cd3ff6656934f915b7..1d4f2f4d10f2967fda9d4a1a17f5b7e7b17111f8 100644 (file)
@@ -850,11 +850,20 @@ static int ena_set_channels(struct net_device *netdev,
        struct ena_adapter *adapter = netdev_priv(netdev);
        u32 count = channels->combined_count;
        /* The check for max value is already done in ethtool */
-       if (count < ENA_MIN_NUM_IO_QUEUES ||
-           (ena_xdp_present(adapter) &&
-           !ena_xdp_legal_queue_count(adapter, count)))
+       if (count < ENA_MIN_NUM_IO_QUEUES)
                return -EINVAL;
 
+       if (!ena_xdp_legal_queue_count(adapter, count)) {
+               if (ena_xdp_present(adapter))
+                       return -EINVAL;
+
+               xdp_clear_features_flag(netdev);
+       } else {
+               xdp_set_features_flag(netdev,
+                                     NETDEV_XDP_ACT_BASIC |
+                                     NETDEV_XDP_ACT_REDIRECT);
+       }
+
        return ena_update_queue_count(adapter, count);
 }
 
index d3999db7c6a29d1f6677ca9de4ff197ee28fda4b..cbfe7f977270f7f5134d766b552449a35bd65927 100644 (file)
@@ -4105,8 +4105,6 @@ static void ena_set_conf_feat_params(struct ena_adapter *adapter,
        /* Set offload features */
        ena_set_dev_offloads(feat, netdev);
 
-       netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT;
-
        adapter->max_mtu = feat->dev_attr.max_mtu;
        netdev->max_mtu = adapter->max_mtu;
        netdev->min_mtu = ENA_MIN_MTU;
@@ -4393,6 +4391,10 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        ena_config_debug_area(adapter);
 
+       if (ena_xdp_legal_queue_count(adapter, adapter->num_io_queues))
+               netdev->xdp_features = NETDEV_XDP_ACT_BASIC |
+                                      NETDEV_XDP_ACT_REDIRECT;
+
        memcpy(adapter->netdev->perm_addr, adapter->mac_addr, netdev->addr_len);
 
        netif_carrier_off(netdev);
index 1e8d902e1c8eaa45df1ad5231299f10247919958..7f933175cbdac9aa643246190a0f6b297af19414 100644 (file)
@@ -412,6 +412,25 @@ int aq_xdp_xmit(struct net_device *dev, int num_frames,
        return num_frames - drop;
 }
 
+static struct sk_buff *aq_xdp_build_skb(struct xdp_buff *xdp,
+                                       struct net_device *dev,
+                                       struct aq_ring_buff_s *buff)
+{
+       struct xdp_frame *xdpf;
+       struct sk_buff *skb;
+
+       xdpf = xdp_convert_buff_to_frame(xdp);
+       if (unlikely(!xdpf))
+               return NULL;
+
+       skb = xdp_build_skb_from_frame(xdpf, dev);
+       if (!skb)
+               return NULL;
+
+       aq_get_rxpages_xdp(buff, xdp);
+       return skb;
+}
+
 static struct sk_buff *aq_xdp_run_prog(struct aq_nic_s *aq_nic,
                                       struct xdp_buff *xdp,
                                       struct aq_ring_s *rx_ring,
@@ -431,7 +450,7 @@ static struct sk_buff *aq_xdp_run_prog(struct aq_nic_s *aq_nic,
 
        prog = READ_ONCE(rx_ring->xdp_prog);
        if (!prog)
-               goto pass;
+               return aq_xdp_build_skb(xdp, aq_nic->ndev, buff);
 
        prefetchw(xdp->data_hard_start); /* xdp_frame write */
 
@@ -442,17 +461,12 @@ static struct sk_buff *aq_xdp_run_prog(struct aq_nic_s *aq_nic,
        act = bpf_prog_run_xdp(prog, xdp);
        switch (act) {
        case XDP_PASS:
-pass:
-               xdpf = xdp_convert_buff_to_frame(xdp);
-               if (unlikely(!xdpf))
-                       goto out_aborted;
-               skb = xdp_build_skb_from_frame(xdpf, aq_nic->ndev);
+               skb = aq_xdp_build_skb(xdp, aq_nic->ndev, buff);
                if (!skb)
                        goto out_aborted;
                u64_stats_update_begin(&rx_ring->stats.rx.syncp);
                ++rx_ring->stats.rx.xdp_pass;
                u64_stats_update_end(&rx_ring->stats.rx.syncp);
-               aq_get_rxpages_xdp(buff, xdp);
                return skb;
        case XDP_TX:
                xdpf = xdp_convert_buff_to_frame(xdp);
index 3038386a5afd8c4297c801fb9c1642eb6a25f7c5..1761df8fb7f96888017e0a4f7cad0c22aad67c77 100644 (file)
@@ -890,13 +890,13 @@ static void bgmac_chip_reset_idm_config(struct bgmac *bgmac)
 
                if (iost & BGMAC_BCMA_IOST_ATTACHED) {
                        flags = BGMAC_BCMA_IOCTL_SW_CLKEN;
-                       if (!bgmac->has_robosw)
+                       if (bgmac->in_init || !bgmac->has_robosw)
                                flags |= BGMAC_BCMA_IOCTL_SW_RESET;
                }
                bgmac_clk_enable(bgmac, flags);
        }
 
-       if (iost & BGMAC_BCMA_IOST_ATTACHED && !bgmac->has_robosw)
+       if (iost & BGMAC_BCMA_IOST_ATTACHED && (bgmac->in_init || !bgmac->has_robosw))
                bgmac_idm_write(bgmac, BCMA_IOCTL,
                                bgmac_idm_read(bgmac, BCMA_IOCTL) &
                                ~BGMAC_BCMA_IOCTL_SW_RESET);
@@ -1490,6 +1490,8 @@ int bgmac_enet_probe(struct bgmac *bgmac)
        struct net_device *net_dev = bgmac->net_dev;
        int err;
 
+       bgmac->in_init = true;
+
        bgmac_chip_intrs_off(bgmac);
 
        net_dev->irq = bgmac->irq;
@@ -1542,6 +1544,8 @@ int bgmac_enet_probe(struct bgmac *bgmac)
        /* Omit FCS from max MTU size */
        net_dev->max_mtu = BGMAC_RX_MAX_FRAME_SIZE - ETH_FCS_LEN;
 
+       bgmac->in_init = false;
+
        err = register_netdev(bgmac->net_dev);
        if (err) {
                dev_err(bgmac->dev, "Cannot register net device\n");
index e05ac92c0650406012915460ea22c96743bcf128..d73ef262991d61a13ddedaf288678386ebb4d256 100644 (file)
@@ -472,6 +472,8 @@ struct bgmac {
        int irq;
        u32 int_mask;
 
+       bool in_init;
+
        /* Current MAC state */
        int mac_speed;
        int mac_duplex;
index 16c490692f4221aa5fa415fa045e3a67fd2c4d2c..12083b9679b54988bb61643962377f313738256b 100644 (file)
@@ -672,6 +672,18 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,
        return 0;
 }
 
+static struct sk_buff *
+bnx2x_build_skb(const struct bnx2x_fastpath *fp, void *data)
+{
+       struct sk_buff *skb;
+
+       if (fp->rx_frag_size)
+               skb = build_skb(data, fp->rx_frag_size);
+       else
+               skb = slab_build_skb(data);
+       return skb;
+}
+
 static void bnx2x_frag_free(const struct bnx2x_fastpath *fp, void *data)
 {
        if (fp->rx_frag_size)
@@ -779,7 +791,7 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
        dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping),
                         fp->rx_buf_size, DMA_FROM_DEVICE);
        if (likely(new_data))
-               skb = build_skb(data, fp->rx_frag_size);
+               skb = bnx2x_build_skb(fp, data);
 
        if (likely(skb)) {
 #ifdef BNX2X_STOP_ON_ERROR
@@ -1046,7 +1058,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
                                                 dma_unmap_addr(rx_buf, mapping),
                                                 fp->rx_buf_size,
                                                 DMA_FROM_DEVICE);
-                               skb = build_skb(data, fp->rx_frag_size);
+                               skb = bnx2x_build_skb(fp, data);
                                if (unlikely(!skb)) {
                                        bnx2x_frag_free(fp, data);
                                        bnx2x_fp_qstats(bp, fp)->
index 5d4b1f2ebeac7c844e8778656ab16264358fd6d5..651b79ce5d80c628e3c9625de2a56b4253c286a7 100644 (file)
@@ -175,12 +175,12 @@ static const struct pci_device_id bnxt_pci_tbl[] = {
        { PCI_VDEVICE(BROADCOM, 0x1750), .driver_data = BCM57508 },
        { PCI_VDEVICE(BROADCOM, 0x1751), .driver_data = BCM57504 },
        { PCI_VDEVICE(BROADCOM, 0x1752), .driver_data = BCM57502 },
-       { PCI_VDEVICE(BROADCOM, 0x1800), .driver_data = BCM57508_NPAR },
+       { PCI_VDEVICE(BROADCOM, 0x1800), .driver_data = BCM57502_NPAR },
        { PCI_VDEVICE(BROADCOM, 0x1801), .driver_data = BCM57504_NPAR },
-       { PCI_VDEVICE(BROADCOM, 0x1802), .driver_data = BCM57502_NPAR },
-       { PCI_VDEVICE(BROADCOM, 0x1803), .driver_data = BCM57508_NPAR },
+       { PCI_VDEVICE(BROADCOM, 0x1802), .driver_data = BCM57508_NPAR },
+       { PCI_VDEVICE(BROADCOM, 0x1803), .driver_data = BCM57502_NPAR },
        { PCI_VDEVICE(BROADCOM, 0x1804), .driver_data = BCM57504_NPAR },
-       { PCI_VDEVICE(BROADCOM, 0x1805), .driver_data = BCM57502_NPAR },
+       { PCI_VDEVICE(BROADCOM, 0x1805), .driver_data = BCM57508_NPAR },
        { PCI_VDEVICE(BROADCOM, 0xd802), .driver_data = BCM58802 },
        { PCI_VDEVICE(BROADCOM, 0xd804), .driver_data = BCM58804 },
 #ifdef CONFIG_BNXT_SRIOV
@@ -2388,7 +2388,7 @@ static int bnxt_async_event_process(struct bnxt *bp,
        case ASYNC_EVENT_CMPL_EVENT_ID_PHC_UPDATE: {
                switch (BNXT_EVENT_PHC_EVENT_TYPE(data1)) {
                case ASYNC_EVENT_CMPL_PHC_UPDATE_EVENT_DATA1_FLAGS_PHC_RTC_UPDATE:
-                       if (bp->fw_cap & BNXT_FW_CAP_PTP_RTC) {
+                       if (BNXT_PTP_USE_RTC(bp)) {
                                struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
                                u64 ns;
 
@@ -3145,7 +3145,7 @@ static int bnxt_alloc_ring(struct bnxt *bp, struct bnxt_ring_mem_info *rmem)
 
 static void bnxt_free_tpa_info(struct bnxt *bp)
 {
-       int i;
+       int i, j;
 
        for (i = 0; i < bp->rx_nr_rings; i++) {
                struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i];
@@ -3153,8 +3153,10 @@ static void bnxt_free_tpa_info(struct bnxt *bp)
                kfree(rxr->rx_tpa_idx_map);
                rxr->rx_tpa_idx_map = NULL;
                if (rxr->rx_tpa) {
-                       kfree(rxr->rx_tpa[0].agg_arr);
-                       rxr->rx_tpa[0].agg_arr = NULL;
+                       for (j = 0; j < bp->max_tpa; j++) {
+                               kfree(rxr->rx_tpa[j].agg_arr);
+                               rxr->rx_tpa[j].agg_arr = NULL;
+                       }
                }
                kfree(rxr->rx_tpa);
                rxr->rx_tpa = NULL;
@@ -3163,14 +3165,13 @@ static void bnxt_free_tpa_info(struct bnxt *bp)
 
 static int bnxt_alloc_tpa_info(struct bnxt *bp)
 {
-       int i, j, total_aggs = 0;
+       int i, j;
 
        bp->max_tpa = MAX_TPA;
        if (bp->flags & BNXT_FLAG_CHIP_P5) {
                if (!bp->max_tpa_v2)
                        return 0;
                bp->max_tpa = max_t(u16, bp->max_tpa_v2, MAX_TPA_P5);
-               total_aggs = bp->max_tpa * MAX_SKB_FRAGS;
        }
 
        for (i = 0; i < bp->rx_nr_rings; i++) {
@@ -3184,12 +3185,12 @@ static int bnxt_alloc_tpa_info(struct bnxt *bp)
 
                if (!(bp->flags & BNXT_FLAG_CHIP_P5))
                        continue;
-               agg = kcalloc(total_aggs, sizeof(*agg), GFP_KERNEL);
-               rxr->rx_tpa[0].agg_arr = agg;
-               if (!agg)
-                       return -ENOMEM;
-               for (j = 1; j < bp->max_tpa; j++)
-                       rxr->rx_tpa[j].agg_arr = agg + j * MAX_SKB_FRAGS;
+               for (j = 0; j < bp->max_tpa; j++) {
+                       agg = kcalloc(MAX_SKB_FRAGS, sizeof(*agg), GFP_KERNEL);
+                       if (!agg)
+                               return -ENOMEM;
+                       rxr->rx_tpa[j].agg_arr = agg;
+               }
                rxr->rx_tpa_idx_map = kzalloc(sizeof(*rxr->rx_tpa_idx_map),
                                              GFP_KERNEL);
                if (!rxr->rx_tpa_idx_map)
@@ -6989,11 +6990,9 @@ static int bnxt_hwrm_func_qcfg(struct bnxt *bp)
                if (flags & FUNC_QCFG_RESP_FLAGS_FW_DCBX_AGENT_ENABLED)
                        bp->fw_cap |= BNXT_FW_CAP_DCBX_AGENT;
        }
-       if (BNXT_PF(bp) && (flags & FUNC_QCFG_RESP_FLAGS_MULTI_HOST)) {
+       if (BNXT_PF(bp) && (flags & FUNC_QCFG_RESP_FLAGS_MULTI_HOST))
                bp->flags |= BNXT_FLAG_MULTI_HOST;
-               if (bp->fw_cap & BNXT_FW_CAP_PTP_RTC)
-                       bp->fw_cap &= ~BNXT_FW_CAP_PTP_RTC;
-       }
+
        if (flags & FUNC_QCFG_RESP_FLAGS_RING_MONITOR_ENABLED)
                bp->fw_cap |= BNXT_FW_CAP_RING_MONITOR;
 
@@ -7628,7 +7627,7 @@ static int __bnxt_hwrm_ptp_qcfg(struct bnxt *bp)
        u8 flags;
        int rc;
 
-       if (bp->hwrm_spec_code < 0x10801) {
+       if (bp->hwrm_spec_code < 0x10801 || !BNXT_CHIP_P5_THOR(bp)) {
                rc = -ENODEV;
                goto no_ptp;
        }
@@ -13204,8 +13203,6 @@ static void bnxt_remove_one(struct pci_dev *pdev)
        bnxt_free_hwrm_resources(bp);
        bnxt_ethtool_free(bp);
        bnxt_dcb_free(bp);
-       kfree(bp->edev);
-       bp->edev = NULL;
        kfree(bp->ptp_cfg);
        bp->ptp_cfg = NULL;
        kfree(bp->fw_health);
index dcb09fbe4007814ab9fec7bb03f06c4d0460ebe5..5928430f6f518eef02c19ea950497a178e114731 100644 (file)
@@ -1226,6 +1226,7 @@ struct bnxt_link_info {
 #define BNXT_LINK_SPEED_40GB   PORT_PHY_QCFG_RESP_LINK_SPEED_40GB
 #define BNXT_LINK_SPEED_50GB   PORT_PHY_QCFG_RESP_LINK_SPEED_50GB
 #define BNXT_LINK_SPEED_100GB  PORT_PHY_QCFG_RESP_LINK_SPEED_100GB
+#define BNXT_LINK_SPEED_200GB  PORT_PHY_QCFG_RESP_LINK_SPEED_200GB
        u16                     support_speeds;
        u16                     support_pam4_speeds;
        u16                     auto_link_speeds;       /* fw adv setting */
@@ -2000,6 +2001,8 @@ struct bnxt {
        u32                     fw_dbg_cap;
 
 #define BNXT_NEW_RM(bp)                ((bp)->fw_cap & BNXT_FW_CAP_NEW_RM)
+#define BNXT_PTP_USE_RTC(bp)   (!BNXT_MH(bp) && \
+                                ((bp)->fw_cap & BNXT_FW_CAP_PTP_RTC))
        u32                     hwrm_spec_code;
        u16                     hwrm_cmd_seq;
        u16                     hwrm_cmd_kong_seq;
index ec573127b70762fd6b26f5108b28a4318f045d92..6bd18eb5137f44c8cf7ac7e41a4d128da10704f7 100644 (file)
@@ -1714,6 +1714,8 @@ u32 bnxt_fw_to_ethtool_speed(u16 fw_link_speed)
                return SPEED_50000;
        case BNXT_LINK_SPEED_100GB:
                return SPEED_100000;
+       case BNXT_LINK_SPEED_200GB:
+               return SPEED_200000;
        default:
                return SPEED_UNKNOWN;
        }
@@ -3738,6 +3740,7 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
                bnxt_ulp_stop(bp);
                rc = bnxt_close_nic(bp, true, false);
                if (rc) {
+                       etest->flags |= ETH_TEST_FL_FAILED;
                        bnxt_ulp_start(bp, rc);
                        return;
                }
index 4ec8bba18cdd2c8abd58fc4649d1516f2507669a..a3a3978a4d1c257d343b425b1350dbef66c318ae 100644 (file)
@@ -63,7 +63,7 @@ static int bnxt_ptp_settime(struct ptp_clock_info *ptp_info,
                                                ptp_info);
        u64 ns = timespec64_to_ns(ts);
 
-       if (ptp->bp->fw_cap & BNXT_FW_CAP_PTP_RTC)
+       if (BNXT_PTP_USE_RTC(ptp->bp))
                return bnxt_ptp_cfg_settime(ptp->bp, ns);
 
        spin_lock_bh(&ptp->ptp_lock);
@@ -196,7 +196,7 @@ static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
        struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
                                                ptp_info);
 
-       if (ptp->bp->fw_cap & BNXT_FW_CAP_PTP_RTC)
+       if (BNXT_PTP_USE_RTC(ptp->bp))
                return bnxt_ptp_adjphc(ptp, delta);
 
        spin_lock_bh(&ptp->ptp_lock);
@@ -205,34 +205,39 @@ static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
        return 0;
 }
 
+static int bnxt_ptp_adjfine_rtc(struct bnxt *bp, long scaled_ppm)
+{
+       s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
+       struct hwrm_port_mac_cfg_input *req;
+       int rc;
+
+       rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
+       if (rc)
+               return rc;
+
+       req->ptp_freq_adj_ppb = cpu_to_le32(ppb);
+       req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB);
+       rc = hwrm_req_send(bp, req);
+       if (rc)
+               netdev_err(bp->dev,
+                          "ptp adjfine failed. rc = %d\n", rc);
+       return rc;
+}
+
 static int bnxt_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm)
 {
        struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
                                                ptp_info);
-       struct hwrm_port_mac_cfg_input *req;
        struct bnxt *bp = ptp->bp;
-       int rc = 0;
 
-       if (!(ptp->bp->fw_cap & BNXT_FW_CAP_PTP_RTC)) {
-               spin_lock_bh(&ptp->ptp_lock);
-               timecounter_read(&ptp->tc);
-               ptp->cc.mult = adjust_by_scaled_ppm(ptp->cmult, scaled_ppm);
-               spin_unlock_bh(&ptp->ptp_lock);
-       } else {
-               s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
-
-               rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
-               if (rc)
-                       return rc;
+       if (BNXT_PTP_USE_RTC(bp))
+               return bnxt_ptp_adjfine_rtc(bp, scaled_ppm);
 
-               req->ptp_freq_adj_ppb = cpu_to_le32(ppb);
-               req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB);
-               rc = hwrm_req_send(ptp->bp, req);
-               if (rc)
-                       netdev_err(ptp->bp->dev,
-                                  "ptp adjfine failed. rc = %d\n", rc);
-       }
-       return rc;
+       spin_lock_bh(&ptp->ptp_lock);
+       timecounter_read(&ptp->tc);
+       ptp->cc.mult = adjust_by_scaled_ppm(ptp->cmult, scaled_ppm);
+       spin_unlock_bh(&ptp->ptp_lock);
+       return 0;
 }
 
 void bnxt_ptp_pps_event(struct bnxt *bp, u32 data1, u32 data2)
@@ -879,7 +884,7 @@ int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg)
        u64 ns;
        int rc;
 
-       if (!bp->ptp_cfg || !(bp->fw_cap & BNXT_FW_CAP_PTP_RTC))
+       if (!bp->ptp_cfg || !BNXT_PTP_USE_RTC(bp))
                return -ENODEV;
 
        if (!phc_cfg) {
@@ -932,13 +937,14 @@ int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg)
        atomic_set(&ptp->tx_avail, BNXT_MAX_TX_TS);
        spin_lock_init(&ptp->ptp_lock);
 
-       if (bp->fw_cap & BNXT_FW_CAP_PTP_RTC) {
+       if (BNXT_PTP_USE_RTC(bp)) {
                bnxt_ptp_timecounter_init(bp, false);
                rc = bnxt_ptp_init_rtc(bp, phc_cfg);
                if (rc)
                        goto out;
        } else {
                bnxt_ptp_timecounter_init(bp, true);
+               bnxt_ptp_adjfine_rtc(bp, 0);
        }
 
        ptp->ptp_info = bnxt_ptp_caps;
index d4cc9c371e7bcb820af7afe77fd57a1a25b9fc5e..852eb449ccae222c74e147de17e1aeec63b90ca7 100644 (file)
@@ -304,7 +304,7 @@ void bnxt_rdma_aux_device_uninit(struct bnxt *bp)
        struct auxiliary_device *adev;
 
        /* Skip if no auxiliary device init was done. */
-       if (!(bp->flags & BNXT_FLAG_ROCE_CAP))
+       if (!bp->aux_priv)
                return;
 
        aux_priv = bp->aux_priv;
@@ -317,11 +317,14 @@ static void bnxt_aux_dev_release(struct device *dev)
 {
        struct bnxt_aux_priv *aux_priv =
                container_of(dev, struct bnxt_aux_priv, aux_dev.dev);
+       struct bnxt *bp = netdev_priv(aux_priv->edev->net);
 
        ida_free(&bnxt_aux_dev_ids, aux_priv->id);
        kfree(aux_priv->edev->ulp_tbl);
+       bp->edev = NULL;
        kfree(aux_priv->edev);
        kfree(aux_priv);
+       bp->aux_priv = NULL;
 }
 
 static void bnxt_set_edev_info(struct bnxt_en_dev *edev, struct bnxt *bp)
@@ -357,19 +360,18 @@ void bnxt_rdma_aux_device_init(struct bnxt *bp)
        if (!(bp->flags & BNXT_FLAG_ROCE_CAP))
                return;
 
-       bp->aux_priv = kzalloc(sizeof(*bp->aux_priv), GFP_KERNEL);
-       if (!bp->aux_priv)
+       aux_priv = kzalloc(sizeof(*bp->aux_priv), GFP_KERNEL);
+       if (!aux_priv)
                goto exit;
 
-       bp->aux_priv->id = ida_alloc(&bnxt_aux_dev_ids, GFP_KERNEL);
-       if (bp->aux_priv->id < 0) {
+       aux_priv->id = ida_alloc(&bnxt_aux_dev_ids, GFP_KERNEL);
+       if (aux_priv->id < 0) {
                netdev_warn(bp->dev,
                            "ida alloc failed for ROCE auxiliary device\n");
-               kfree(bp->aux_priv);
+               kfree(aux_priv);
                goto exit;
        }
 
-       aux_priv = bp->aux_priv;
        aux_dev = &aux_priv->aux_dev;
        aux_dev->id = aux_priv->id;
        aux_dev->name = "rdma";
@@ -378,10 +380,11 @@ void bnxt_rdma_aux_device_init(struct bnxt *bp)
 
        rc = auxiliary_device_init(aux_dev);
        if (rc) {
-               ida_free(&bnxt_aux_dev_ids, bp->aux_priv->id);
-               kfree(bp->aux_priv);
+               ida_free(&bnxt_aux_dev_ids, aux_priv->id);
+               kfree(aux_priv);
                goto exit;
        }
+       bp->aux_priv = aux_priv;
 
        /* From this point, all cleanup will happen via the .release callback &
         * any error unwinding will need to include a call to
index 6e141a8bbf43cbcc36d6bd9eee78eb9d32d599d8..e43d99ec50ba2c9c547bdfa1daed5b894fee2992 100644 (file)
@@ -1064,6 +1064,10 @@ static dma_addr_t macb_get_addr(struct macb *bp, struct macb_dma_desc *desc)
        }
 #endif
        addr |= MACB_BF(RX_WADDR, MACB_BFEXT(RX_WADDR, desc->addr));
+#ifdef CONFIG_MACB_USE_HWSTAMP
+       if (bp->hw_dma_cap & HW_DMA_CAP_PTP)
+               addr &= ~GEM_BIT(DMA_RXVALID);
+#endif
        return addr;
 }
 
@@ -4990,7 +4994,7 @@ static int macb_probe(struct platform_device *pdev)
                bp->jumbo_max_len = macb_config->jumbo_max_len;
 
        bp->wol = 0;
-       if (of_get_property(np, "magic-packet", NULL))
+       if (of_property_read_bool(np, "magic-packet"))
                bp->wol |= MACB_WOL_HAS_MAGIC_PACKET;
        device_set_wakeup_capable(&pdev->dev, bp->wol & MACB_WOL_HAS_MAGIC_PACKET);
 
index e5c71f90785237348ab57924037dea3e85f04f09..d8d71bf97983b859c68c95899f65fc90dc66bb69 100644 (file)
@@ -735,12 +735,17 @@ static int nicvf_set_channels(struct net_device *dev,
        if (channel->tx_count > nic->max_queues)
                return -EINVAL;
 
-       if (nic->xdp_prog &&
-           ((channel->tx_count + channel->rx_count) > nic->max_queues)) {
-               netdev_err(nic->netdev,
-                          "XDP mode, RXQs + TXQs > Max %d\n",
-                          nic->max_queues);
-               return -EINVAL;
+       if (channel->tx_count + channel->rx_count > nic->max_queues) {
+               if (nic->xdp_prog) {
+                       netdev_err(nic->netdev,
+                                  "XDP mode, RXQs + TXQs > Max %d\n",
+                                  nic->max_queues);
+                       return -EINVAL;
+               }
+
+               xdp_clear_features_flag(nic->netdev);
+       } else if (!pass1_silicon(nic->pdev)) {
+               xdp_set_features_flag(dev, NETDEV_XDP_ACT_BASIC);
        }
 
        if (if_up)
index 8b25313c7f6b8fa28d58cbfb50ff46515880c1f0..eff350e0bc2a8ec7d1f3584028d21762afecfe3d 100644 (file)
@@ -2218,7 +2218,9 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        netdev->netdev_ops = &nicvf_netdev_ops;
        netdev->watchdog_timeo = NICVF_TX_TIMEOUT;
 
-       netdev->xdp_features = NETDEV_XDP_ACT_BASIC;
+       if (!pass1_silicon(nic->pdev) &&
+           nic->rx_queues + nic->tx_queues <= nic->max_queues)
+               netdev->xdp_features = NETDEV_XDP_ACT_BASIC;
 
        /* MTU range: 64 - 9200 */
        netdev->min_mtu = NIC_HW_MIN_FRS;
index dd9be229819a594701b52e039b6afd7ffb466b8a..d3541159487dd04ca9978e8270fad8c7eacf37b9 100644 (file)
@@ -1135,7 +1135,7 @@ void cxgb4_cleanup_tc_flower(struct adapter *adap)
                return;
 
        if (adap->flower_stats_timer.function)
-               del_timer_sync(&adap->flower_stats_timer);
+               timer_shutdown_sync(&adap->flower_stats_timer);
        cancel_work_sync(&adap->flower_stats_work);
        rhashtable_destroy(&adap->flower_tbl);
        adap->tc_flower_initialized = false;
index b21e56de61671a90ef3906a03f98ff7c879a988d..05a89ab6766c4161d48ec9af79997bba1bc31f14 100644 (file)
@@ -1393,9 +1393,9 @@ static struct dm9000_plat_data *dm9000_parse_dt(struct device *dev)
        if (!pdata)
                return ERR_PTR(-ENOMEM);
 
-       if (of_find_property(np, "davicom,ext-phy", NULL))
+       if (of_property_read_bool(np, "davicom,ext-phy"))
                pdata->flags |= DM9000_PLATF_EXT_PHY;
-       if (of_find_property(np, "davicom,no-eeprom", NULL))
+       if (of_property_read_bool(np, "davicom,no-eeprom"))
                pdata->flags |= DM9000_PLATF_NO_EEPROM;
 
        ret = of_get_mac_address(np, pdata->dev_addr);
diff --git a/drivers/net/ethernet/fealnx.c b/drivers/net/ethernet/fealnx.c
new file mode 100644 (file)
index 0000000..ed18450
--- /dev/null
@@ -0,0 +1,1953 @@
+/*
+       Written 1998-2000 by Donald Becker.
+
+       This software may be used and distributed according to the terms of
+       the GNU General Public License (GPL), incorporated herein by reference.
+       Drivers based on or derived from this code fall under the GPL and must
+       retain the authorship, copyright and license notice.  This file is not
+       a complete program and may only be used when the entire operating
+       system is licensed under the GPL.
+
+       The author may be reached as becker@scyld.com, or C/O
+       Scyld Computing Corporation
+       410 Severn Ave., Suite 210
+       Annapolis MD 21403
+
+       Support information and updates available at
+       http://www.scyld.com/network/pci-skeleton.html
+
+       Linux kernel updates:
+
+       Version 2.51, Nov 17, 2001 (jgarzik):
+       - Add ethtool support
+       - Replace some MII-related magic numbers with constants
+
+*/
+
+#define DRV_NAME       "fealnx"
+
+static int debug;              /* 1-> print debug message */
+static int max_interrupt_work = 20;
+
+/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). */
+static int multicast_filter_limit = 32;
+
+/* Set the copy breakpoint for the copy-only-tiny-frames scheme. */
+/* Setting to > 1518 effectively disables this feature.          */
+static int rx_copybreak;
+
+/* Used to pass the media type, etc.                            */
+/* Both 'options[]' and 'full_duplex[]' should exist for driver */
+/* interoperability.                                            */
+/* The media type is usually passed in 'options[]'.             */
+#define MAX_UNITS 8            /* More are supported, limit only on options */
+static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
+static int full_duplex[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
+
+/* Operational parameters that are set at compile time.                 */
+/* Keep the ring sizes a power of two for compile efficiency.           */
+/* The compiler will convert <unsigned>'%'<2^N> into a bit mask.        */
+/* Making the Tx ring too large decreases the effectiveness of channel  */
+/* bonding and packet priority.                                         */
+/* There are no ill effects from too-large receive rings.               */
+// 88-12-9 modify,
+// #define TX_RING_SIZE    16
+// #define RX_RING_SIZE    32
+#define TX_RING_SIZE    6
+#define RX_RING_SIZE    12
+#define TX_TOTAL_SIZE  TX_RING_SIZE*sizeof(struct fealnx_desc)
+#define RX_TOTAL_SIZE  RX_RING_SIZE*sizeof(struct fealnx_desc)
+
+/* Operational parameters that usually are not changed. */
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT      (2*HZ)
+
+#define PKT_BUF_SZ      1536   /* Size of each temporary Rx buffer. */
+
+
+/* Include files, designed to support most kernel versions 2.0.0 and later. */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/crc32.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+
+#include <asm/processor.h>     /* Processor type for cache alignment. */
+#include <asm/io.h>
+#include <linux/uaccess.h>
+#include <asm/byteorder.h>
+
+/* This driver was written to use PCI memory space, however some x86 systems
+   work only with I/O space accesses. */
+#ifndef __alpha__
+#define USE_IO_OPS
+#endif
+
+/* Kernel compatibility defines, some common to David Hinds' PCMCIA package. */
+/* This is only in the support-all-kernels source code. */
+
+#define RUN_AT(x) (jiffies + (x))
+
+MODULE_AUTHOR("Myson or whoever");
+MODULE_DESCRIPTION("Myson MTD-8xx 100/10M Ethernet PCI Adapter Driver");
+MODULE_LICENSE("GPL");
+module_param(max_interrupt_work, int, 0);
+module_param(debug, int, 0);
+module_param(rx_copybreak, int, 0);
+module_param(multicast_filter_limit, int, 0);
+module_param_array(options, int, NULL, 0);
+module_param_array(full_duplex, int, NULL, 0);
+MODULE_PARM_DESC(max_interrupt_work, "fealnx maximum events handled per interrupt");
+MODULE_PARM_DESC(debug, "fealnx enable debugging (0-1)");
+MODULE_PARM_DESC(rx_copybreak, "fealnx copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(multicast_filter_limit, "fealnx maximum number of filtered multicast addresses");
+MODULE_PARM_DESC(options, "fealnx: Bits 0-3: media type, bit 17: full duplex");
+MODULE_PARM_DESC(full_duplex, "fealnx full duplex setting(s) (1)");
+
+enum {
+       MIN_REGION_SIZE         = 136,
+};
+
+/* A chip capabilities table, matching the entries in pci_tbl[] above. */
+enum chip_capability_flags {
+       HAS_MII_XCVR,
+       HAS_CHIP_XCVR,
+};
+
+/* 89/6/13 add, */
+/* for different PHY */
+enum phy_type_flags {
+       MysonPHY = 1,
+       AhdocPHY = 2,
+       SeeqPHY = 3,
+       MarvellPHY = 4,
+       Myson981 = 5,
+       LevelOnePHY = 6,
+       OtherPHY = 10,
+};
+
+struct chip_info {
+       char *chip_name;
+       int flags;
+};
+
+static const struct chip_info skel_netdrv_tbl[] = {
+       { "100/10M Ethernet PCI Adapter",       HAS_MII_XCVR },
+       { "100/10M Ethernet PCI Adapter",       HAS_CHIP_XCVR },
+       { "1000/100/10M Ethernet PCI Adapter",  HAS_MII_XCVR },
+};
+
+/* Offsets to the Command and Status Registers. */
+enum fealnx_offsets {
+       PAR0 = 0x0,             /* physical address 0-3 */
+       PAR1 = 0x04,            /* physical address 4-5 */
+       MAR0 = 0x08,            /* multicast address 0-3 */
+       MAR1 = 0x0C,            /* multicast address 4-7 */
+       FAR0 = 0x10,            /* flow-control address 0-3 */
+       FAR1 = 0x14,            /* flow-control address 4-5 */
+       TCRRCR = 0x18,          /* receive & transmit configuration */
+       BCR = 0x1C,             /* bus command */
+       TXPDR = 0x20,           /* transmit polling demand */
+       RXPDR = 0x24,           /* receive polling demand */
+       RXCWP = 0x28,           /* receive current word pointer */
+       TXLBA = 0x2C,           /* transmit list base address */
+       RXLBA = 0x30,           /* receive list base address */
+       ISR = 0x34,             /* interrupt status */
+       IMR = 0x38,             /* interrupt mask */
+       FTH = 0x3C,             /* flow control high/low threshold */
+       MANAGEMENT = 0x40,      /* bootrom/eeprom and mii management */
+       TALLY = 0x44,           /* tally counters for crc and mpa */
+       TSR = 0x48,             /* tally counter for transmit status */
+       BMCRSR = 0x4c,          /* basic mode control and status */
+       PHYIDENTIFIER = 0x50,   /* phy identifier */
+       ANARANLPAR = 0x54,      /* auto-negotiation advertisement and link
+                                  partner ability */
+       ANEROCR = 0x58,         /* auto-negotiation expansion and pci conf. */
+       BPREMRPSR = 0x5c,       /* bypass & receive error mask and phy status */
+};
+
+/* Bits in the interrupt status/enable registers. */
+/* The bits in the Intr Status/Enable registers, mostly interrupt sources. */
+enum intr_status_bits {
+       RFCON = 0x00020000,     /* receive flow control xon packet */
+       RFCOFF = 0x00010000,    /* receive flow control xoff packet */
+       LSCStatus = 0x00008000, /* link status change */
+       ANCStatus = 0x00004000, /* autonegotiation completed */
+       FBE = 0x00002000,       /* fatal bus error */
+       FBEMask = 0x00001800,   /* mask bit12-11 */
+       ParityErr = 0x00000000, /* parity error */
+       TargetErr = 0x00001000, /* target abort */
+       MasterErr = 0x00000800, /* master error */
+       TUNF = 0x00000400,      /* transmit underflow */
+       ROVF = 0x00000200,      /* receive overflow */
+       ETI = 0x00000100,       /* transmit early int */
+       ERI = 0x00000080,       /* receive early int */
+       CNTOVF = 0x00000040,    /* counter overflow */
+       RBU = 0x00000020,       /* receive buffer unavailable */
+       TBU = 0x00000010,       /* transmit buffer unavilable */
+       TI = 0x00000008,        /* transmit interrupt */
+       RI = 0x00000004,        /* receive interrupt */
+       RxErr = 0x00000002,     /* receive error */
+};
+
+/* Bits in the NetworkConfig register, W for writing, R for reading */
+/* FIXME: some names are invented by me. Marked with (name?) */
+/* If you have docs and know bit names, please fix 'em */
+enum rx_mode_bits {
+       CR_W_ENH        = 0x02000000,   /* enhanced mode (name?) */
+       CR_W_FD         = 0x00100000,   /* full duplex */
+       CR_W_PS10       = 0x00080000,   /* 10 mbit */
+       CR_W_TXEN       = 0x00040000,   /* tx enable (name?) */
+       CR_W_PS1000     = 0x00010000,   /* 1000 mbit */
+     /* CR_W_RXBURSTMASK= 0x00000e00, Im unsure about this */
+       CR_W_RXMODEMASK = 0x000000e0,
+       CR_W_PROM       = 0x00000080,   /* promiscuous mode */
+       CR_W_AB         = 0x00000040,   /* accept broadcast */
+       CR_W_AM         = 0x00000020,   /* accept mutlicast */
+       CR_W_ARP        = 0x00000008,   /* receive runt pkt */
+       CR_W_ALP        = 0x00000004,   /* receive long pkt */
+       CR_W_SEP        = 0x00000002,   /* receive error pkt */
+       CR_W_RXEN       = 0x00000001,   /* rx enable (unicast?) (name?) */
+
+       CR_R_TXSTOP     = 0x04000000,   /* tx stopped (name?) */
+       CR_R_FD         = 0x00100000,   /* full duplex detected */
+       CR_R_PS10       = 0x00080000,   /* 10 mbit detected */
+       CR_R_RXSTOP     = 0x00008000,   /* rx stopped (name?) */
+};
+
+/* The Tulip Rx and Tx buffer descriptors. */
+struct fealnx_desc {
+       s32 status;
+       s32 control;
+       u32 buffer;
+       u32 next_desc;
+       struct fealnx_desc *next_desc_logical;
+       struct sk_buff *skbuff;
+       u32 reserved1;
+       u32 reserved2;
+};
+
+/* Bits in network_desc.status */
+enum rx_desc_status_bits {
+       RXOWN = 0x80000000,     /* own bit */
+       FLNGMASK = 0x0fff0000,  /* frame length */
+       FLNGShift = 16,
+       MARSTATUS = 0x00004000, /* multicast address received */
+       BARSTATUS = 0x00002000, /* broadcast address received */
+       PHYSTATUS = 0x00001000, /* physical address received */
+       RXFSD = 0x00000800,     /* first descriptor */
+       RXLSD = 0x00000400,     /* last descriptor */
+       ErrorSummary = 0x80,    /* error summary */
+       RUNTPKT = 0x40,         /* runt packet received */
+       LONGPKT = 0x20,         /* long packet received */
+       FAE = 0x10,             /* frame align error */
+       CRC = 0x08,             /* crc error */
+       RXER = 0x04,            /* receive error */
+};
+
+enum rx_desc_control_bits {
+       RXIC = 0x00800000,      /* interrupt control */
+       RBSShift = 0,
+};
+
+enum tx_desc_status_bits {
+       TXOWN = 0x80000000,     /* own bit */
+       JABTO = 0x00004000,     /* jabber timeout */
+       CSL = 0x00002000,       /* carrier sense lost */
+       LC = 0x00001000,        /* late collision */
+       EC = 0x00000800,        /* excessive collision */
+       UDF = 0x00000400,       /* fifo underflow */
+       DFR = 0x00000200,       /* deferred */
+       HF = 0x00000100,        /* heartbeat fail */
+       NCRMask = 0x000000ff,   /* collision retry count */
+       NCRShift = 0,
+};
+
+enum tx_desc_control_bits {
+       TXIC = 0x80000000,      /* interrupt control */
+       ETIControl = 0x40000000,        /* early transmit interrupt */
+       TXLD = 0x20000000,      /* last descriptor */
+       TXFD = 0x10000000,      /* first descriptor */
+       CRCEnable = 0x08000000, /* crc control */
+       PADEnable = 0x04000000, /* padding control */
+       RetryTxLC = 0x02000000, /* retry late collision */
+       PKTSMask = 0x3ff800,    /* packet size bit21-11 */
+       PKTSShift = 11,
+       TBSMask = 0x000007ff,   /* transmit buffer bit 10-0 */
+       TBSShift = 0,
+};
+
+/* BootROM/EEPROM/MII Management Register */
+#define MASK_MIIR_MII_READ       0x00000000
+#define MASK_MIIR_MII_WRITE      0x00000008
+#define MASK_MIIR_MII_MDO        0x00000004
+#define MASK_MIIR_MII_MDI        0x00000002
+#define MASK_MIIR_MII_MDC        0x00000001
+
+/* ST+OP+PHYAD+REGAD+TA */
+#define OP_READ             0x6000     /* ST:01+OP:10+PHYAD+REGAD+TA:Z0 */
+#define OP_WRITE            0x5002     /* ST:01+OP:01+PHYAD+REGAD+TA:10 */
+
+/* ------------------------------------------------------------------------- */
+/*      Constants for Myson PHY                                              */
+/* ------------------------------------------------------------------------- */
+#define MysonPHYID      0xd0000302
+/* 89-7-27 add, (begin) */
+#define MysonPHYID0     0x0302
+#define StatusRegister  18
+#define SPEED100        0x0400 // bit10
+#define FULLMODE        0x0800 // bit11
+/* 89-7-27 add, (end) */
+
+/* ------------------------------------------------------------------------- */
+/*      Constants for Seeq 80225 PHY                                         */
+/* ------------------------------------------------------------------------- */
+#define SeeqPHYID0      0x0016
+
+#define MIIRegister18   18
+#define SPD_DET_100     0x80
+#define DPLX_DET_FULL   0x40
+
+/* ------------------------------------------------------------------------- */
+/*      Constants for Ahdoc 101 PHY                                          */
+/* ------------------------------------------------------------------------- */
+#define AhdocPHYID0     0x0022
+
+#define DiagnosticReg   18
+#define DPLX_FULL       0x0800
+#define Speed_100       0x0400
+
+/* 89/6/13 add, */
+/* -------------------------------------------------------------------------- */
+/*      Constants                                                             */
+/* -------------------------------------------------------------------------- */
+#define MarvellPHYID0           0x0141
+#define LevelOnePHYID0         0x0013
+
+#define MII1000BaseTControlReg  9
+#define MII1000BaseTStatusReg   10
+#define SpecificReg            17
+
+/* for 1000BaseT Control Register */
+#define PHYAbletoPerform1000FullDuplex  0x0200
+#define PHYAbletoPerform1000HalfDuplex  0x0100
+#define PHY1000AbilityMask              0x300
+
+// for phy specific status register, marvell phy.
+#define SpeedMask       0x0c000
+#define Speed_1000M     0x08000
+#define Speed_100M      0x4000
+#define Speed_10M       0
+#define Full_Duplex     0x2000
+
+// 89/12/29 add, for phy specific status register, levelone phy, (begin)
+#define LXT1000_100M    0x08000
+#define LXT1000_1000M   0x0c000
+#define LXT1000_Full    0x200
+// 89/12/29 add, for phy specific status register, levelone phy, (end)
+
+/* for 3-in-1 case, BMCRSR register */
+#define LinkIsUp2      0x00040000
+
+/* for PHY */
+#define LinkIsUp        0x0004
+
+
+struct netdev_private {
+       /* Descriptor rings first for alignment. */
+       struct fealnx_desc *rx_ring;
+       struct fealnx_desc *tx_ring;
+
+       dma_addr_t rx_ring_dma;
+       dma_addr_t tx_ring_dma;
+
+       spinlock_t lock;
+
+       /* Media monitoring timer. */
+       struct timer_list timer;
+
+       /* Reset timer */
+       struct timer_list reset_timer;
+       int reset_timer_armed;
+       unsigned long crvalue_sv;
+       unsigned long imrvalue_sv;
+
+       /* Frequently used values: keep some adjacent for cache effect. */
+       int flags;
+       struct pci_dev *pci_dev;
+       unsigned long crvalue;
+       unsigned long bcrvalue;
+       unsigned long imrvalue;
+       struct fealnx_desc *cur_rx;
+       struct fealnx_desc *lack_rxbuf;
+       int really_rx_count;
+       struct fealnx_desc *cur_tx;
+       struct fealnx_desc *cur_tx_copy;
+       int really_tx_count;
+       int free_tx_count;
+       unsigned int rx_buf_sz; /* Based on MTU+slack. */
+
+       /* These values are keep track of the transceiver/media in use. */
+       unsigned int linkok;
+       unsigned int line_speed;
+       unsigned int duplexmode;
+       unsigned int default_port:4;    /* Last dev->if_port value. */
+       unsigned int PHYType;
+
+       /* MII transceiver section. */
+       int mii_cnt;            /* MII device addresses. */
+       unsigned char phys[2];  /* MII device addresses. */
+       struct mii_if_info mii;
+       void __iomem *mem;
+};
+
+
+static int mdio_read(struct net_device *dev, int phy_id, int location);
+static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
+static int netdev_open(struct net_device *dev);
+static void getlinktype(struct net_device *dev);
+static void getlinkstatus(struct net_device *dev);
+static void netdev_timer(struct timer_list *t);
+static void reset_timer(struct timer_list *t);
+static void fealnx_tx_timeout(struct net_device *dev, unsigned int txqueue);
+static void init_ring(struct net_device *dev);
+static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev);
+static irqreturn_t intr_handler(int irq, void *dev_instance);
+static int netdev_rx(struct net_device *dev);
+static void set_rx_mode(struct net_device *dev);
+static void __set_rx_mode(struct net_device *dev);
+static struct net_device_stats *get_stats(struct net_device *dev);
+static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static const struct ethtool_ops netdev_ethtool_ops;
+static int netdev_close(struct net_device *dev);
+static void reset_rx_descriptors(struct net_device *dev);
+static void reset_tx_descriptors(struct net_device *dev);
+
+static void stop_nic_rx(void __iomem *ioaddr, long crvalue)
+{
+       int delay = 0x1000;
+       iowrite32(crvalue & ~(CR_W_RXEN), ioaddr + TCRRCR);
+       while (--delay) {
+               if ( (ioread32(ioaddr + TCRRCR) & CR_R_RXSTOP) == CR_R_RXSTOP)
+                       break;
+       }
+}
+
+
+static void stop_nic_rxtx(void __iomem *ioaddr, long crvalue)
+{
+       int delay = 0x1000;
+       iowrite32(crvalue & ~(CR_W_RXEN+CR_W_TXEN), ioaddr + TCRRCR);
+       while (--delay) {
+               if ( (ioread32(ioaddr + TCRRCR) & (CR_R_RXSTOP+CR_R_TXSTOP))
+                                           == (CR_R_RXSTOP+CR_R_TXSTOP) )
+                       break;
+       }
+}
+
+static const struct net_device_ops netdev_ops = {
+       .ndo_open               = netdev_open,
+       .ndo_stop               = netdev_close,
+       .ndo_start_xmit         = start_tx,
+       .ndo_get_stats          = get_stats,
+       .ndo_set_rx_mode        = set_rx_mode,
+       .ndo_eth_ioctl          = mii_ioctl,
+       .ndo_tx_timeout         = fealnx_tx_timeout,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
+static int fealnx_init_one(struct pci_dev *pdev,
+                          const struct pci_device_id *ent)
+{
+       struct netdev_private *np;
+       int i, option, err, irq;
+       static int card_idx = -1;
+       char boardname[12];
+       void __iomem *ioaddr;
+       unsigned long len;
+       unsigned int chip_id = ent->driver_data;
+       struct net_device *dev;
+       void *ring_space;
+       dma_addr_t ring_dma;
+       u8 addr[ETH_ALEN];
+#ifdef USE_IO_OPS
+       int bar = 0;
+#else
+       int bar = 1;
+#endif
+
+       card_idx++;
+       sprintf(boardname, "fealnx%d", card_idx);
+
+       option = card_idx < MAX_UNITS ? options[card_idx] : 0;
+
+       i = pci_enable_device(pdev);
+       if (i) return i;
+       pci_set_master(pdev);
+
+       len = pci_resource_len(pdev, bar);
+       if (len < MIN_REGION_SIZE) {
+               dev_err(&pdev->dev,
+                          "region size %ld too small, aborting\n", len);
+               return -ENODEV;
+       }
+
+       i = pci_request_regions(pdev, boardname);
+       if (i)
+               return i;
+
+       irq = pdev->irq;
+
+       ioaddr = pci_iomap(pdev, bar, len);
+       if (!ioaddr) {
+               err = -ENOMEM;
+               goto err_out_res;
+       }
+
+       dev = alloc_etherdev(sizeof(struct netdev_private));
+       if (!dev) {
+               err = -ENOMEM;
+               goto err_out_unmap;
+       }
+       SET_NETDEV_DEV(dev, &pdev->dev);
+
+       /* read ethernet id */
+       for (i = 0; i < 6; ++i)
+               addr[i] = ioread8(ioaddr + PAR0 + i);
+       eth_hw_addr_set(dev, addr);
+
+       /* Reset the chip to erase previous misconfiguration. */
+       iowrite32(0x00000001, ioaddr + BCR);
+
+       /* Make certain the descriptor lists are aligned. */
+       np = netdev_priv(dev);
+       np->mem = ioaddr;
+       spin_lock_init(&np->lock);
+       np->pci_dev = pdev;
+       np->flags = skel_netdrv_tbl[chip_id].flags;
+       pci_set_drvdata(pdev, dev);
+       np->mii.dev = dev;
+       np->mii.mdio_read = mdio_read;
+       np->mii.mdio_write = mdio_write;
+       np->mii.phy_id_mask = 0x1f;
+       np->mii.reg_num_mask = 0x1f;
+
+       ring_space = dma_alloc_coherent(&pdev->dev, RX_TOTAL_SIZE, &ring_dma,
+                                       GFP_KERNEL);
+       if (!ring_space) {
+               err = -ENOMEM;
+               goto err_out_free_dev;
+       }
+       np->rx_ring = ring_space;
+       np->rx_ring_dma = ring_dma;
+
+       ring_space = dma_alloc_coherent(&pdev->dev, TX_TOTAL_SIZE, &ring_dma,
+                                       GFP_KERNEL);
+       if (!ring_space) {
+               err = -ENOMEM;
+               goto err_out_free_rx;
+       }
+       np->tx_ring = ring_space;
+       np->tx_ring_dma = ring_dma;
+
+       /* find the connected MII xcvrs */
+       if (np->flags == HAS_MII_XCVR) {
+               int phy, phy_idx = 0;
+
+               for (phy = 1; phy < 32 && phy_idx < ARRAY_SIZE(np->phys);
+                              phy++) {
+                       int mii_status = mdio_read(dev, phy, 1);
+
+                       if (mii_status != 0xffff && mii_status != 0x0000) {
+                               np->phys[phy_idx++] = phy;
+                               dev_info(&pdev->dev,
+                                      "MII PHY found at address %d, status "
+                                      "0x%4.4x.\n", phy, mii_status);
+                               /* get phy type */
+                               {
+                                       unsigned int data;
+
+                                       data = mdio_read(dev, np->phys[0], 2);
+                                       if (data == SeeqPHYID0)
+                                               np->PHYType = SeeqPHY;
+                                       else if (data == AhdocPHYID0)
+                                               np->PHYType = AhdocPHY;
+                                       else if (data == MarvellPHYID0)
+                                               np->PHYType = MarvellPHY;
+                                       else if (data == MysonPHYID0)
+                                               np->PHYType = Myson981;
+                                       else if (data == LevelOnePHYID0)
+                                               np->PHYType = LevelOnePHY;
+                                       else
+                                               np->PHYType = OtherPHY;
+                               }
+                       }
+               }
+
+               np->mii_cnt = phy_idx;
+               if (phy_idx == 0)
+                       dev_warn(&pdev->dev,
+                               "MII PHY not found -- this device may "
+                              "not operate correctly.\n");
+       } else {
+               np->phys[0] = 32;
+/* 89/6/23 add, (begin) */
+               /* get phy type */
+               if (ioread32(ioaddr + PHYIDENTIFIER) == MysonPHYID)
+                       np->PHYType = MysonPHY;
+               else
+                       np->PHYType = OtherPHY;
+       }
+       np->mii.phy_id = np->phys[0];
+
+       if (dev->mem_start)
+               option = dev->mem_start;
+
+       /* The lower four bits are the media type. */
+       if (option > 0) {
+               if (option & 0x200)
+                       np->mii.full_duplex = 1;
+               np->default_port = option & 15;
+       }
+
+       if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0)
+               np->mii.full_duplex = full_duplex[card_idx];
+
+       if (np->mii.full_duplex) {
+               dev_info(&pdev->dev, "Media type forced to Full Duplex.\n");
+/* 89/6/13 add, (begin) */
+//      if (np->PHYType==MarvellPHY)
+               if ((np->PHYType == MarvellPHY) || (np->PHYType == LevelOnePHY)) {
+                       unsigned int data;
+
+                       data = mdio_read(dev, np->phys[0], 9);
+                       data = (data & 0xfcff) | 0x0200;
+                       mdio_write(dev, np->phys[0], 9, data);
+               }
+/* 89/6/13 add, (end) */
+               if (np->flags == HAS_MII_XCVR)
+                       mdio_write(dev, np->phys[0], MII_ADVERTISE, ADVERTISE_FULL);
+               else
+                       iowrite32(ADVERTISE_FULL, ioaddr + ANARANLPAR);
+               np->mii.force_media = 1;
+       }
+
+       dev->netdev_ops = &netdev_ops;
+       dev->ethtool_ops = &netdev_ethtool_ops;
+       dev->watchdog_timeo = TX_TIMEOUT;
+
+       err = register_netdev(dev);
+       if (err)
+               goto err_out_free_tx;
+
+       printk(KERN_INFO "%s: %s at %p, %pM, IRQ %d.\n",
+              dev->name, skel_netdrv_tbl[chip_id].chip_name, ioaddr,
+              dev->dev_addr, irq);
+
+       return 0;
+
+err_out_free_tx:
+       dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE, np->tx_ring,
+                         np->tx_ring_dma);
+err_out_free_rx:
+       dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE, np->rx_ring,
+                         np->rx_ring_dma);
+err_out_free_dev:
+       free_netdev(dev);
+err_out_unmap:
+       pci_iounmap(pdev, ioaddr);
+err_out_res:
+       pci_release_regions(pdev);
+       return err;
+}
+
+
+static void fealnx_remove_one(struct pci_dev *pdev)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+
+       if (dev) {
+               struct netdev_private *np = netdev_priv(dev);
+
+               dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE, np->tx_ring,
+                                 np->tx_ring_dma);
+               dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE, np->rx_ring,
+                                 np->rx_ring_dma);
+               unregister_netdev(dev);
+               pci_iounmap(pdev, np->mem);
+               free_netdev(dev);
+               pci_release_regions(pdev);
+       } else
+               printk(KERN_ERR "fealnx: remove for unknown device\n");
+}
+
+
+static ulong m80x_send_cmd_to_phy(void __iomem *miiport, int opcode, int phyad, int regad)
+{
+       ulong miir;
+       int i;
+       unsigned int mask, data;
+
+       /* enable MII output */
+       miir = (ulong) ioread32(miiport);
+       miir &= 0xfffffff0;
+
+       miir |= MASK_MIIR_MII_WRITE + MASK_MIIR_MII_MDO;
+
+       /* send 32 1's preamble */
+       for (i = 0; i < 32; i++) {
+               /* low MDC; MDO is already high (miir) */
+               miir &= ~MASK_MIIR_MII_MDC;
+               iowrite32(miir, miiport);
+
+               /* high MDC */
+               miir |= MASK_MIIR_MII_MDC;
+               iowrite32(miir, miiport);
+       }
+
+       /* calculate ST+OP+PHYAD+REGAD+TA */
+       data = opcode | (phyad << 7) | (regad << 2);
+
+       /* sent out */
+       mask = 0x8000;
+       while (mask) {
+               /* low MDC, prepare MDO */
+               miir &= ~(MASK_MIIR_MII_MDC + MASK_MIIR_MII_MDO);
+               if (mask & data)
+                       miir |= MASK_MIIR_MII_MDO;
+
+               iowrite32(miir, miiport);
+               /* high MDC */
+               miir |= MASK_MIIR_MII_MDC;
+               iowrite32(miir, miiport);
+               udelay(30);
+
+               /* next */
+               mask >>= 1;
+               if (mask == 0x2 && opcode == OP_READ)
+                       miir &= ~MASK_MIIR_MII_WRITE;
+       }
+       return miir;
+}
+
+
+static int mdio_read(struct net_device *dev, int phyad, int regad)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       void __iomem *miiport = np->mem + MANAGEMENT;
+       ulong miir;
+       unsigned int mask, data;
+
+       miir = m80x_send_cmd_to_phy(miiport, OP_READ, phyad, regad);
+
+       /* read data */
+       mask = 0x8000;
+       data = 0;
+       while (mask) {
+               /* low MDC */
+               miir &= ~MASK_MIIR_MII_MDC;
+               iowrite32(miir, miiport);
+
+               /* read MDI */
+               miir = ioread32(miiport);
+               if (miir & MASK_MIIR_MII_MDI)
+                       data |= mask;
+
+               /* high MDC, and wait */
+               miir |= MASK_MIIR_MII_MDC;
+               iowrite32(miir, miiport);
+               udelay(30);
+
+               /* next */
+               mask >>= 1;
+       }
+
+       /* low MDC */
+       miir &= ~MASK_MIIR_MII_MDC;
+       iowrite32(miir, miiport);
+
+       return data & 0xffff;
+}
+
+
+static void mdio_write(struct net_device *dev, int phyad, int regad, int data)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       void __iomem *miiport = np->mem + MANAGEMENT;
+       ulong miir;
+       unsigned int mask;
+
+       miir = m80x_send_cmd_to_phy(miiport, OP_WRITE, phyad, regad);
+
+       /* write data */
+       mask = 0x8000;
+       while (mask) {
+               /* low MDC, prepare MDO */
+               miir &= ~(MASK_MIIR_MII_MDC + MASK_MIIR_MII_MDO);
+               if (mask & data)
+                       miir |= MASK_MIIR_MII_MDO;
+               iowrite32(miir, miiport);
+
+               /* high MDC */
+               miir |= MASK_MIIR_MII_MDC;
+               iowrite32(miir, miiport);
+
+               /* next */
+               mask >>= 1;
+       }
+
+       /* low MDC */
+       miir &= ~MASK_MIIR_MII_MDC;
+       iowrite32(miir, miiport);
+}
+
+
+static int netdev_open(struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       void __iomem *ioaddr = np->mem;
+       const int irq = np->pci_dev->irq;
+       int rc, i;
+
+       iowrite32(0x00000001, ioaddr + BCR);    /* Reset */
+
+       rc = request_irq(irq, intr_handler, IRQF_SHARED, dev->name, dev);
+       if (rc)
+               return -EAGAIN;
+
+       for (i = 0; i < 3; i++)
+               iowrite16(((const unsigned short *)dev->dev_addr)[i],
+                               ioaddr + PAR0 + i*2);
+
+       init_ring(dev);
+
+       iowrite32(np->rx_ring_dma, ioaddr + RXLBA);
+       iowrite32(np->tx_ring_dma, ioaddr + TXLBA);
+
+       /* Initialize other registers. */
+       /* Configure the PCI bus bursts and FIFO thresholds.
+          486: Set 8 longword burst.
+          586: no burst limit.
+          Burst length 5:3
+          0 0 0   1
+          0 0 1   4
+          0 1 0   8
+          0 1 1   16
+          1 0 0   32
+          1 0 1   64
+          1 1 0   128
+          1 1 1   256
+          Wait the specified 50 PCI cycles after a reset by initializing
+          Tx and Rx queues and the address filter list.
+          FIXME (Ueimor): optimistic for alpha + posted writes ? */
+
+       np->bcrvalue = 0x10;    /* little-endian, 8 burst length */
+#ifdef __BIG_ENDIAN
+       np->bcrvalue |= 0x04;   /* big-endian */
+#endif
+
+#if defined(__i386__) && !defined(MODULE) && !defined(CONFIG_UML)
+       if (boot_cpu_data.x86 <= 4)
+               np->crvalue = 0xa00;
+       else
+#endif
+               np->crvalue = 0xe00;    /* rx 128 burst length */
+
+
+// 89/12/29 add,
+// 90/1/16 modify,
+//   np->imrvalue=FBE|TUNF|CNTOVF|RBU|TI|RI;
+       np->imrvalue = TUNF | CNTOVF | RBU | TI | RI;
+       if (np->pci_dev->device == 0x891) {
+               np->bcrvalue |= 0x200;  /* set PROG bit */
+               np->crvalue |= CR_W_ENH;        /* set enhanced bit */
+               np->imrvalue |= ETI;
+       }
+       iowrite32(np->bcrvalue, ioaddr + BCR);
+
+       if (dev->if_port == 0)
+               dev->if_port = np->default_port;
+
+       iowrite32(0, ioaddr + RXPDR);
+// 89/9/1 modify,
+//   np->crvalue = 0x00e40001;    /* tx store and forward, tx/rx enable */
+       np->crvalue |= 0x00e40001;      /* tx store and forward, tx/rx enable */
+       np->mii.full_duplex = np->mii.force_media;
+       getlinkstatus(dev);
+       if (np->linkok)
+               getlinktype(dev);
+       __set_rx_mode(dev);
+
+       netif_start_queue(dev);
+
+       /* Clear and Enable interrupts by setting the interrupt mask. */
+       iowrite32(FBE | TUNF | CNTOVF | RBU | TI | RI, ioaddr + ISR);
+       iowrite32(np->imrvalue, ioaddr + IMR);
+
+       if (debug)
+               printk(KERN_DEBUG "%s: Done netdev_open().\n", dev->name);
+
+       /* Set the timer to check for link beat. */
+       timer_setup(&np->timer, netdev_timer, 0);
+       np->timer.expires = RUN_AT(3 * HZ);
+
+       /* timer handler */
+       add_timer(&np->timer);
+
+       timer_setup(&np->reset_timer, reset_timer, 0);
+       np->reset_timer_armed = 0;
+       return rc;
+}
+
+
+static void getlinkstatus(struct net_device *dev)
+/* function: Routine will read MII Status Register to get link status.       */
+/* input   : dev... pointer to the adapter block.                            */
+/* output  : none.                                                           */
+{
+       struct netdev_private *np = netdev_priv(dev);
+       unsigned int i, DelayTime = 0x1000;
+
+       np->linkok = 0;
+
+       if (np->PHYType == MysonPHY) {
+               for (i = 0; i < DelayTime; ++i) {
+                       if (ioread32(np->mem + BMCRSR) & LinkIsUp2) {
+                               np->linkok = 1;
+                               return;
+                       }
+                       udelay(100);
+               }
+       } else {
+               for (i = 0; i < DelayTime; ++i) {
+                       if (mdio_read(dev, np->phys[0], MII_BMSR) & BMSR_LSTATUS) {
+                               np->linkok = 1;
+                               return;
+                       }
+                       udelay(100);
+               }
+       }
+}
+
+
+static void getlinktype(struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+
+       if (np->PHYType == MysonPHY) {  /* 3-in-1 case */
+               if (ioread32(np->mem + TCRRCR) & CR_R_FD)
+                       np->duplexmode = 2;     /* full duplex */
+               else
+                       np->duplexmode = 1;     /* half duplex */
+               if (ioread32(np->mem + TCRRCR) & CR_R_PS10)
+                       np->line_speed = 1;     /* 10M */
+               else
+                       np->line_speed = 2;     /* 100M */
+       } else {
+               if (np->PHYType == SeeqPHY) {   /* this PHY is SEEQ 80225 */
+                       unsigned int data;
+
+                       data = mdio_read(dev, np->phys[0], MIIRegister18);
+                       if (data & SPD_DET_100)
+                               np->line_speed = 2;     /* 100M */
+                       else
+                               np->line_speed = 1;     /* 10M */
+                       if (data & DPLX_DET_FULL)
+                               np->duplexmode = 2;     /* full duplex mode */
+                       else
+                               np->duplexmode = 1;     /* half duplex mode */
+               } else if (np->PHYType == AhdocPHY) {
+                       unsigned int data;
+
+                       data = mdio_read(dev, np->phys[0], DiagnosticReg);
+                       if (data & Speed_100)
+                               np->line_speed = 2;     /* 100M */
+                       else
+                               np->line_speed = 1;     /* 10M */
+                       if (data & DPLX_FULL)
+                               np->duplexmode = 2;     /* full duplex mode */
+                       else
+                               np->duplexmode = 1;     /* half duplex mode */
+               }
+/* 89/6/13 add, (begin) */
+               else if (np->PHYType == MarvellPHY) {
+                       unsigned int data;
+
+                       data = mdio_read(dev, np->phys[0], SpecificReg);
+                       if (data & Full_Duplex)
+                               np->duplexmode = 2;     /* full duplex mode */
+                       else
+                               np->duplexmode = 1;     /* half duplex mode */
+                       data &= SpeedMask;
+                       if (data == Speed_1000M)
+                               np->line_speed = 3;     /* 1000M */
+                       else if (data == Speed_100M)
+                               np->line_speed = 2;     /* 100M */
+                       else
+                               np->line_speed = 1;     /* 10M */
+               }
+/* 89/6/13 add, (end) */
+/* 89/7/27 add, (begin) */
+               else if (np->PHYType == Myson981) {
+                       unsigned int data;
+
+                       data = mdio_read(dev, np->phys[0], StatusRegister);
+
+                       if (data & SPEED100)
+                               np->line_speed = 2;
+                       else
+                               np->line_speed = 1;
+
+                       if (data & FULLMODE)
+                               np->duplexmode = 2;
+                       else
+                               np->duplexmode = 1;
+               }
+/* 89/7/27 add, (end) */
+/* 89/12/29 add */
+               else if (np->PHYType == LevelOnePHY) {
+                       unsigned int data;
+
+                       data = mdio_read(dev, np->phys[0], SpecificReg);
+                       if (data & LXT1000_Full)
+                               np->duplexmode = 2;     /* full duplex mode */
+                       else
+                               np->duplexmode = 1;     /* half duplex mode */
+                       data &= SpeedMask;
+                       if (data == LXT1000_1000M)
+                               np->line_speed = 3;     /* 1000M */
+                       else if (data == LXT1000_100M)
+                               np->line_speed = 2;     /* 100M */
+                       else
+                               np->line_speed = 1;     /* 10M */
+               }
+               np->crvalue &= (~CR_W_PS10) & (~CR_W_FD) & (~CR_W_PS1000);
+               if (np->line_speed == 1)
+                       np->crvalue |= CR_W_PS10;
+               else if (np->line_speed == 3)
+                       np->crvalue |= CR_W_PS1000;
+               if (np->duplexmode == 2)
+                       np->crvalue |= CR_W_FD;
+       }
+}
+
+
+/* Take lock before calling this */
+static void allocate_rx_buffers(struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+
+       /*  allocate skb for rx buffers */
+       while (np->really_rx_count != RX_RING_SIZE) {
+               struct sk_buff *skb;
+
+               skb = netdev_alloc_skb(dev, np->rx_buf_sz);
+               if (skb == NULL)
+                       break;  /* Better luck next round. */
+
+               while (np->lack_rxbuf->skbuff)
+                       np->lack_rxbuf = np->lack_rxbuf->next_desc_logical;
+
+               np->lack_rxbuf->skbuff = skb;
+               np->lack_rxbuf->buffer = dma_map_single(&np->pci_dev->dev,
+                                                       skb->data,
+                                                       np->rx_buf_sz,
+                                                       DMA_FROM_DEVICE);
+               np->lack_rxbuf->status = RXOWN;
+               ++np->really_rx_count;
+       }
+}
+
+
+static void netdev_timer(struct timer_list *t)
+{
+       struct netdev_private *np = from_timer(np, t, timer);
+       struct net_device *dev = np->mii.dev;
+       void __iomem *ioaddr = np->mem;
+       int old_crvalue = np->crvalue;
+       unsigned int old_linkok = np->linkok;
+       unsigned long flags;
+
+       if (debug)
+               printk(KERN_DEBUG "%s: Media selection timer tick, status %8.8x "
+                      "config %8.8x.\n", dev->name, ioread32(ioaddr + ISR),
+                      ioread32(ioaddr + TCRRCR));
+
+       spin_lock_irqsave(&np->lock, flags);
+
+       if (np->flags == HAS_MII_XCVR) {
+               getlinkstatus(dev);
+               if ((old_linkok == 0) && (np->linkok == 1)) {   /* we need to detect the media type again */
+                       getlinktype(dev);
+                       if (np->crvalue != old_crvalue) {
+                               stop_nic_rxtx(ioaddr, np->crvalue);
+                               iowrite32(np->crvalue, ioaddr + TCRRCR);
+                       }
+               }
+       }
+
+       allocate_rx_buffers(dev);
+
+       spin_unlock_irqrestore(&np->lock, flags);
+
+       np->timer.expires = RUN_AT(10 * HZ);
+       add_timer(&np->timer);
+}
+
+
+/* Take lock before calling */
+/* Reset chip and disable rx, tx and interrupts */
+static void reset_and_disable_rxtx(struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       void __iomem *ioaddr = np->mem;
+       int delay=51;
+
+       /* Reset the chip's Tx and Rx processes. */
+       stop_nic_rxtx(ioaddr, 0);
+
+       /* Disable interrupts by clearing the interrupt mask. */
+       iowrite32(0, ioaddr + IMR);
+
+       /* Reset the chip to erase previous misconfiguration. */
+       iowrite32(0x00000001, ioaddr + BCR);
+
+       /* Ueimor: wait for 50 PCI cycles (and flush posted writes btw).
+          We surely wait too long (address+data phase). Who cares? */
+       while (--delay) {
+               ioread32(ioaddr + BCR);
+               rmb();
+       }
+}
+
+
+/* Take lock before calling */
+/* Restore chip after reset */
+static void enable_rxtx(struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       void __iomem *ioaddr = np->mem;
+
+       reset_rx_descriptors(dev);
+
+       iowrite32(np->tx_ring_dma + ((char*)np->cur_tx - (char*)np->tx_ring),
+               ioaddr + TXLBA);
+       iowrite32(np->rx_ring_dma + ((char*)np->cur_rx - (char*)np->rx_ring),
+               ioaddr + RXLBA);
+
+       iowrite32(np->bcrvalue, ioaddr + BCR);
+
+       iowrite32(0, ioaddr + RXPDR);
+       __set_rx_mode(dev); /* changes np->crvalue, writes it into TCRRCR */
+
+       /* Clear and Enable interrupts by setting the interrupt mask. */
+       iowrite32(FBE | TUNF | CNTOVF | RBU | TI | RI, ioaddr + ISR);
+       iowrite32(np->imrvalue, ioaddr + IMR);
+
+       iowrite32(0, ioaddr + TXPDR);
+}
+
+
+static void reset_timer(struct timer_list *t)
+{
+       struct netdev_private *np = from_timer(np, t, reset_timer);
+       struct net_device *dev = np->mii.dev;
+       unsigned long flags;
+
+       printk(KERN_WARNING "%s: resetting tx and rx machinery\n", dev->name);
+
+       spin_lock_irqsave(&np->lock, flags);
+       np->crvalue = np->crvalue_sv;
+       np->imrvalue = np->imrvalue_sv;
+
+       reset_and_disable_rxtx(dev);
+       /* works for me without this:
+       reset_tx_descriptors(dev); */
+       enable_rxtx(dev);
+       netif_start_queue(dev); /* FIXME: or netif_wake_queue(dev); ? */
+
+       np->reset_timer_armed = 0;
+
+       spin_unlock_irqrestore(&np->lock, flags);
+}
+
+
+static void fealnx_tx_timeout(struct net_device *dev, unsigned int txqueue)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       void __iomem *ioaddr = np->mem;
+       unsigned long flags;
+       int i;
+
+       printk(KERN_WARNING
+              "%s: Transmit timed out, status %8.8x, resetting...\n",
+              dev->name, ioread32(ioaddr + ISR));
+
+       {
+               printk(KERN_DEBUG "  Rx ring %p: ", np->rx_ring);
+               for (i = 0; i < RX_RING_SIZE; i++)
+                       printk(KERN_CONT " %8.8x",
+                              (unsigned int) np->rx_ring[i].status);
+               printk(KERN_CONT "\n");
+               printk(KERN_DEBUG "  Tx ring %p: ", np->tx_ring);
+               for (i = 0; i < TX_RING_SIZE; i++)
+                       printk(KERN_CONT " %4.4x", np->tx_ring[i].status);
+               printk(KERN_CONT "\n");
+       }
+
+       spin_lock_irqsave(&np->lock, flags);
+
+       reset_and_disable_rxtx(dev);
+       reset_tx_descriptors(dev);
+       enable_rxtx(dev);
+
+       spin_unlock_irqrestore(&np->lock, flags);
+
+       netif_trans_update(dev); /* prevent tx timeout */
+       dev->stats.tx_errors++;
+       netif_wake_queue(dev); /* or .._start_.. ?? */
+}
+
+
+/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
+static void init_ring(struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       int i;
+
+       /* initialize rx variables */
+       np->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
+       np->cur_rx = &np->rx_ring[0];
+       np->lack_rxbuf = np->rx_ring;
+       np->really_rx_count = 0;
+
+       /* initial rx descriptors. */
+       for (i = 0; i < RX_RING_SIZE; i++) {
+               np->rx_ring[i].status = 0;
+               np->rx_ring[i].control = np->rx_buf_sz << RBSShift;
+               np->rx_ring[i].next_desc = np->rx_ring_dma +
+                       (i + 1)*sizeof(struct fealnx_desc);
+               np->rx_ring[i].next_desc_logical = &np->rx_ring[i + 1];
+               np->rx_ring[i].skbuff = NULL;
+       }
+
+       /* for the last rx descriptor */
+       np->rx_ring[i - 1].next_desc = np->rx_ring_dma;
+       np->rx_ring[i - 1].next_desc_logical = np->rx_ring;
+
+       /* allocate skb for rx buffers */
+       for (i = 0; i < RX_RING_SIZE; i++) {
+               struct sk_buff *skb = netdev_alloc_skb(dev, np->rx_buf_sz);
+
+               if (skb == NULL) {
+                       np->lack_rxbuf = &np->rx_ring[i];
+                       break;
+               }
+
+               ++np->really_rx_count;
+               np->rx_ring[i].skbuff = skb;
+               np->rx_ring[i].buffer = dma_map_single(&np->pci_dev->dev,
+                                                      skb->data,
+                                                      np->rx_buf_sz,
+                                                      DMA_FROM_DEVICE);
+               np->rx_ring[i].status = RXOWN;
+               np->rx_ring[i].control |= RXIC;
+       }
+
+       /* initialize tx variables */
+       np->cur_tx = &np->tx_ring[0];
+       np->cur_tx_copy = &np->tx_ring[0];
+       np->really_tx_count = 0;
+       np->free_tx_count = TX_RING_SIZE;
+
+       for (i = 0; i < TX_RING_SIZE; i++) {
+               np->tx_ring[i].status = 0;
+               /* do we need np->tx_ring[i].control = XXX; ?? */
+               np->tx_ring[i].next_desc = np->tx_ring_dma +
+                       (i + 1)*sizeof(struct fealnx_desc);
+               np->tx_ring[i].next_desc_logical = &np->tx_ring[i + 1];
+               np->tx_ring[i].skbuff = NULL;
+       }
+
+       /* for the last tx descriptor */
+       np->tx_ring[i - 1].next_desc = np->tx_ring_dma;
+       np->tx_ring[i - 1].next_desc_logical = &np->tx_ring[0];
+}
+
+
+static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       unsigned long flags;
+
+       spin_lock_irqsave(&np->lock, flags);
+
+       np->cur_tx_copy->skbuff = skb;
+
+#define one_buffer
+#define BPT 1022
+#if defined(one_buffer)
+       np->cur_tx_copy->buffer = dma_map_single(&np->pci_dev->dev, skb->data,
+                                                skb->len, DMA_TO_DEVICE);
+       np->cur_tx_copy->control = TXIC | TXLD | TXFD | CRCEnable | PADEnable;
+       np->cur_tx_copy->control |= (skb->len << PKTSShift);    /* pkt size */
+       np->cur_tx_copy->control |= (skb->len << TBSShift);     /* buffer size */
+// 89/12/29 add,
+       if (np->pci_dev->device == 0x891)
+               np->cur_tx_copy->control |= ETIControl | RetryTxLC;
+       np->cur_tx_copy->status = TXOWN;
+       np->cur_tx_copy = np->cur_tx_copy->next_desc_logical;
+       --np->free_tx_count;
+#elif defined(two_buffer)
+       if (skb->len > BPT) {
+               struct fealnx_desc *next;
+
+               /* for the first descriptor */
+               np->cur_tx_copy->buffer = dma_map_single(&np->pci_dev->dev,
+                                                        skb->data, BPT,
+                                                        DMA_TO_DEVICE);
+               np->cur_tx_copy->control = TXIC | TXFD | CRCEnable | PADEnable;
+               np->cur_tx_copy->control |= (skb->len << PKTSShift);    /* pkt size */
+               np->cur_tx_copy->control |= (BPT << TBSShift);  /* buffer size */
+
+               /* for the last descriptor */
+               next = np->cur_tx_copy->next_desc_logical;
+               next->skbuff = skb;
+               next->control = TXIC | TXLD | CRCEnable | PADEnable;
+               next->control |= (skb->len << PKTSShift);       /* pkt size */
+               next->control |= ((skb->len - BPT) << TBSShift);        /* buf size */
+// 89/12/29 add,
+               if (np->pci_dev->device == 0x891)
+                       np->cur_tx_copy->control |= ETIControl | RetryTxLC;
+               next->buffer = dma_map_single(&ep->pci_dev->dev,
+                                             skb->data + BPT, skb->len - BPT,
+                                             DMA_TO_DEVICE);
+
+               next->status = TXOWN;
+               np->cur_tx_copy->status = TXOWN;
+
+               np->cur_tx_copy = next->next_desc_logical;
+               np->free_tx_count -= 2;
+       } else {
+               np->cur_tx_copy->buffer = dma_map_single(&np->pci_dev->dev,
+                                                        skb->data, skb->len,
+                                                        DMA_TO_DEVICE);
+               np->cur_tx_copy->control = TXIC | TXLD | TXFD | CRCEnable | PADEnable;
+               np->cur_tx_copy->control |= (skb->len << PKTSShift);    /* pkt size */
+               np->cur_tx_copy->control |= (skb->len << TBSShift);     /* buffer size */
+// 89/12/29 add,
+               if (np->pci_dev->device == 0x891)
+                       np->cur_tx_copy->control |= ETIControl | RetryTxLC;
+               np->cur_tx_copy->status = TXOWN;
+               np->cur_tx_copy = np->cur_tx_copy->next_desc_logical;
+               --np->free_tx_count;
+       }
+#endif
+
+       if (np->free_tx_count < 2)
+               netif_stop_queue(dev);
+       ++np->really_tx_count;
+       iowrite32(0, np->mem + TXPDR);
+
+       spin_unlock_irqrestore(&np->lock, flags);
+       return NETDEV_TX_OK;
+}
+
+
+/* Take lock before calling */
+/* Chip probably hosed tx ring. Clean up. */
+static void reset_tx_descriptors(struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       struct fealnx_desc *cur;
+       int i;
+
+       /* initialize tx variables */
+       np->cur_tx = &np->tx_ring[0];
+       np->cur_tx_copy = &np->tx_ring[0];
+       np->really_tx_count = 0;
+       np->free_tx_count = TX_RING_SIZE;
+
+       for (i = 0; i < TX_RING_SIZE; i++) {
+               cur = &np->tx_ring[i];
+               if (cur->skbuff) {
+                       dma_unmap_single(&np->pci_dev->dev, cur->buffer,
+                                        cur->skbuff->len, DMA_TO_DEVICE);
+                       dev_kfree_skb_any(cur->skbuff);
+                       cur->skbuff = NULL;
+               }
+               cur->status = 0;
+               cur->control = 0;       /* needed? */
+               /* probably not needed. We do it for purely paranoid reasons */
+               cur->next_desc = np->tx_ring_dma +
+                       (i + 1)*sizeof(struct fealnx_desc);
+               cur->next_desc_logical = &np->tx_ring[i + 1];
+       }
+       /* for the last tx descriptor */
+       np->tx_ring[TX_RING_SIZE - 1].next_desc = np->tx_ring_dma;
+       np->tx_ring[TX_RING_SIZE - 1].next_desc_logical = &np->tx_ring[0];
+}
+
+
+/* Take lock and stop rx before calling this */
+static void reset_rx_descriptors(struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       struct fealnx_desc *cur = np->cur_rx;
+       int i;
+
+       allocate_rx_buffers(dev);
+
+       for (i = 0; i < RX_RING_SIZE; i++) {
+               if (cur->skbuff)
+                       cur->status = RXOWN;
+               cur = cur->next_desc_logical;
+       }
+
+       iowrite32(np->rx_ring_dma + ((char*)np->cur_rx - (char*)np->rx_ring),
+               np->mem + RXLBA);
+}
+
+
+/* The interrupt handler does all of the Rx thread work and cleans up
+   after the Tx thread. */
+static irqreturn_t intr_handler(int irq, void *dev_instance)
+{
+       struct net_device *dev = (struct net_device *) dev_instance;
+       struct netdev_private *np = netdev_priv(dev);
+       void __iomem *ioaddr = np->mem;
+       long boguscnt = max_interrupt_work;
+       unsigned int num_tx = 0;
+       int handled = 0;
+
+       spin_lock(&np->lock);
+
+       iowrite32(0, ioaddr + IMR);
+
+       do {
+               u32 intr_status = ioread32(ioaddr + ISR);
+
+               /* Acknowledge all of the current interrupt sources ASAP. */
+               iowrite32(intr_status, ioaddr + ISR);
+
+               if (debug)
+                       printk(KERN_DEBUG "%s: Interrupt, status %4.4x.\n", dev->name,
+                              intr_status);
+
+               if (!(intr_status & np->imrvalue))
+                       break;
+
+               handled = 1;
+
+// 90/1/16 delete,
+//
+//      if (intr_status & FBE)
+//      {   /* fatal error */
+//          stop_nic_tx(ioaddr, 0);
+//          stop_nic_rx(ioaddr, 0);
+//          break;
+//      };
+
+               if (intr_status & TUNF)
+                       iowrite32(0, ioaddr + TXPDR);
+
+               if (intr_status & CNTOVF) {
+                       /* missed pkts */
+                       dev->stats.rx_missed_errors +=
+                               ioread32(ioaddr + TALLY) & 0x7fff;
+
+                       /* crc error */
+                       dev->stats.rx_crc_errors +=
+                           (ioread32(ioaddr + TALLY) & 0x7fff0000) >> 16;
+               }
+
+               if (intr_status & (RI | RBU)) {
+                       if (intr_status & RI)
+                               netdev_rx(dev);
+                       else {
+                               stop_nic_rx(ioaddr, np->crvalue);
+                               reset_rx_descriptors(dev);
+                               iowrite32(np->crvalue, ioaddr + TCRRCR);
+                       }
+               }
+
+               while (np->really_tx_count) {
+                       long tx_status = np->cur_tx->status;
+                       long tx_control = np->cur_tx->control;
+
+                       if (!(tx_control & TXLD)) {     /* this pkt is combined by two tx descriptors */
+                               struct fealnx_desc *next;
+
+                               next = np->cur_tx->next_desc_logical;
+                               tx_status = next->status;
+                               tx_control = next->control;
+                       }
+
+                       if (tx_status & TXOWN)
+                               break;
+
+                       if (!(np->crvalue & CR_W_ENH)) {
+                               if (tx_status & (CSL | LC | EC | UDF | HF)) {
+                                       dev->stats.tx_errors++;
+                                       if (tx_status & EC)
+                                               dev->stats.tx_aborted_errors++;
+                                       if (tx_status & CSL)
+                                               dev->stats.tx_carrier_errors++;
+                                       if (tx_status & LC)
+                                               dev->stats.tx_window_errors++;
+                                       if (tx_status & UDF)
+                                               dev->stats.tx_fifo_errors++;
+                                       if ((tx_status & HF) && np->mii.full_duplex == 0)
+                                               dev->stats.tx_heartbeat_errors++;
+
+                               } else {
+                                       dev->stats.tx_bytes +=
+                                           ((tx_control & PKTSMask) >> PKTSShift);
+
+                                       dev->stats.collisions +=
+                                           ((tx_status & NCRMask) >> NCRShift);
+                                       dev->stats.tx_packets++;
+                               }
+                       } else {
+                               dev->stats.tx_bytes +=
+                                   ((tx_control & PKTSMask) >> PKTSShift);
+                               dev->stats.tx_packets++;
+                       }
+
+                       /* Free the original skb. */
+                       dma_unmap_single(&np->pci_dev->dev,
+                                        np->cur_tx->buffer,
+                                        np->cur_tx->skbuff->len,
+                                        DMA_TO_DEVICE);
+                       dev_consume_skb_irq(np->cur_tx->skbuff);
+                       np->cur_tx->skbuff = NULL;
+                       --np->really_tx_count;
+                       if (np->cur_tx->control & TXLD) {
+                               np->cur_tx = np->cur_tx->next_desc_logical;
+                               ++np->free_tx_count;
+                       } else {
+                               np->cur_tx = np->cur_tx->next_desc_logical;
+                               np->cur_tx = np->cur_tx->next_desc_logical;
+                               np->free_tx_count += 2;
+                       }
+                       num_tx++;
+               }               /* end of for loop */
+
+               if (num_tx && np->free_tx_count >= 2)
+                       netif_wake_queue(dev);
+
+               /* read transmit status for enhanced mode only */
+               if (np->crvalue & CR_W_ENH) {
+                       long data;
+
+                       data = ioread32(ioaddr + TSR);
+                       dev->stats.tx_errors += (data & 0xff000000) >> 24;
+                       dev->stats.tx_aborted_errors +=
+                               (data & 0xff000000) >> 24;
+                       dev->stats.tx_window_errors +=
+                               (data & 0x00ff0000) >> 16;
+                       dev->stats.collisions += (data & 0x0000ffff);
+               }
+
+               if (--boguscnt < 0) {
+                       printk(KERN_WARNING "%s: Too much work at interrupt, "
+                              "status=0x%4.4x.\n", dev->name, intr_status);
+                       if (!np->reset_timer_armed) {
+                               np->reset_timer_armed = 1;
+                               np->reset_timer.expires = RUN_AT(HZ/2);
+                               add_timer(&np->reset_timer);
+                               stop_nic_rxtx(ioaddr, 0);
+                               netif_stop_queue(dev);
+                               /* or netif_tx_disable(dev); ?? */
+                               /* Prevent other paths from enabling tx,rx,intrs */
+                               np->crvalue_sv = np->crvalue;
+                               np->imrvalue_sv = np->imrvalue;
+                               np->crvalue &= ~(CR_W_TXEN | CR_W_RXEN); /* or simply = 0? */
+                               np->imrvalue = 0;
+                       }
+
+                       break;
+               }
+       } while (1);
+
+       /* read the tally counters */
+       /* missed pkts */
+       dev->stats.rx_missed_errors += ioread32(ioaddr + TALLY) & 0x7fff;
+
+       /* crc error */
+       dev->stats.rx_crc_errors +=
+               (ioread32(ioaddr + TALLY) & 0x7fff0000) >> 16;
+
+       if (debug)
+               printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
+                      dev->name, ioread32(ioaddr + ISR));
+
+       iowrite32(np->imrvalue, ioaddr + IMR);
+
+       spin_unlock(&np->lock);
+
+       return IRQ_RETVAL(handled);
+}
+
+
+/* This routine is logically part of the interrupt handler, but separated
+   for clarity and better register allocation. */
+static int netdev_rx(struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       void __iomem *ioaddr = np->mem;
+
+       /* If EOP is set on the next entry, it's a new packet. Send it up. */
+       while (!(np->cur_rx->status & RXOWN) && np->cur_rx->skbuff) {
+               s32 rx_status = np->cur_rx->status;
+
+               if (np->really_rx_count == 0)
+                       break;
+
+               if (debug)
+                       printk(KERN_DEBUG "  netdev_rx() status was %8.8x.\n", rx_status);
+
+               if ((!((rx_status & RXFSD) && (rx_status & RXLSD))) ||
+                   (rx_status & ErrorSummary)) {
+                       if (rx_status & ErrorSummary) { /* there was a fatal error */
+                               if (debug)
+                                       printk(KERN_DEBUG
+                                              "%s: Receive error, Rx status %8.8x.\n",
+                                              dev->name, rx_status);
+
+                               dev->stats.rx_errors++; /* end of a packet. */
+                               if (rx_status & (LONGPKT | RUNTPKT))
+                                       dev->stats.rx_length_errors++;
+                               if (rx_status & RXER)
+                                       dev->stats.rx_frame_errors++;
+                               if (rx_status & CRC)
+                                       dev->stats.rx_crc_errors++;
+                       } else {
+                               int need_to_reset = 0;
+                               int desno = 0;
+
+                               if (rx_status & RXFSD) {        /* this pkt is too long, over one rx buffer */
+                                       struct fealnx_desc *cur;
+
+                                       /* check this packet is received completely? */
+                                       cur = np->cur_rx;
+                                       while (desno <= np->really_rx_count) {
+                                               ++desno;
+                                               if ((!(cur->status & RXOWN)) &&
+                                                   (cur->status & RXLSD))
+                                                       break;
+                                               /* goto next rx descriptor */
+                                               cur = cur->next_desc_logical;
+                                       }
+                                       if (desno > np->really_rx_count)
+                                               need_to_reset = 1;
+                               } else  /* RXLSD did not find, something error */
+                                       need_to_reset = 1;
+
+                               if (need_to_reset == 0) {
+                                       int i;
+
+                                       dev->stats.rx_length_errors++;
+
+                                       /* free all rx descriptors related this long pkt */
+                                       for (i = 0; i < desno; ++i) {
+                                               if (!np->cur_rx->skbuff) {
+                                                       printk(KERN_DEBUG
+                                                               "%s: I'm scared\n", dev->name);
+                                                       break;
+                                               }
+                                               np->cur_rx->status = RXOWN;
+                                               np->cur_rx = np->cur_rx->next_desc_logical;
+                                       }
+                                       continue;
+                               } else {        /* rx error, need to reset this chip */
+                                       stop_nic_rx(ioaddr, np->crvalue);
+                                       reset_rx_descriptors(dev);
+                                       iowrite32(np->crvalue, ioaddr + TCRRCR);
+                               }
+                               break;  /* exit the while loop */
+                       }
+               } else {        /* this received pkt is ok */
+
+                       struct sk_buff *skb;
+                       /* Omit the four octet CRC from the length. */
+                       short pkt_len = ((rx_status & FLNGMASK) >> FLNGShift) - 4;
+
+#ifndef final_version
+                       if (debug)
+                               printk(KERN_DEBUG "  netdev_rx() normal Rx pkt length %d"
+                                      " status %x.\n", pkt_len, rx_status);
+#endif
+
+                       /* Check if the packet is long enough to accept without copying
+                          to a minimally-sized skbuff. */
+                       if (pkt_len < rx_copybreak &&
+                           (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) {
+                               skb_reserve(skb, 2);    /* 16 byte align the IP header */
+                               dma_sync_single_for_cpu(&np->pci_dev->dev,
+                                                       np->cur_rx->buffer,
+                                                       np->rx_buf_sz,
+                                                       DMA_FROM_DEVICE);
+                               /* Call copy + cksum if available. */
+
+#if ! defined(__alpha__)
+                               skb_copy_to_linear_data(skb,
+                                       np->cur_rx->skbuff->data, pkt_len);
+                               skb_put(skb, pkt_len);
+#else
+                               skb_put_data(skb, np->cur_rx->skbuff->data,
+                                            pkt_len);
+#endif
+                               dma_sync_single_for_device(&np->pci_dev->dev,
+                                                          np->cur_rx->buffer,
+                                                          np->rx_buf_sz,
+                                                          DMA_FROM_DEVICE);
+                       } else {
+                               dma_unmap_single(&np->pci_dev->dev,
+                                                np->cur_rx->buffer,
+                                                np->rx_buf_sz,
+                                                DMA_FROM_DEVICE);
+                               skb_put(skb = np->cur_rx->skbuff, pkt_len);
+                               np->cur_rx->skbuff = NULL;
+                               --np->really_rx_count;
+                       }
+                       skb->protocol = eth_type_trans(skb, dev);
+                       netif_rx(skb);
+                       dev->stats.rx_packets++;
+                       dev->stats.rx_bytes += pkt_len;
+               }
+
+               np->cur_rx = np->cur_rx->next_desc_logical;
+       }                       /* end of while loop */
+
+       /*  allocate skb for rx buffers */
+       allocate_rx_buffers(dev);
+
+       return 0;
+}
+
+
+static struct net_device_stats *get_stats(struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       void __iomem *ioaddr = np->mem;
+
+       /* The chip only need report frame silently dropped. */
+       if (netif_running(dev)) {
+               dev->stats.rx_missed_errors +=
+                       ioread32(ioaddr + TALLY) & 0x7fff;
+               dev->stats.rx_crc_errors +=
+                       (ioread32(ioaddr + TALLY) & 0x7fff0000) >> 16;
+       }
+
+       return &dev->stats;
+}
+
+
+/* for dev->set_multicast_list */
+static void set_rx_mode(struct net_device *dev)
+{
+       spinlock_t *lp = &((struct netdev_private *)netdev_priv(dev))->lock;
+       unsigned long flags;
+       spin_lock_irqsave(lp, flags);
+       __set_rx_mode(dev);
+       spin_unlock_irqrestore(lp, flags);
+}
+
+
+/* Take lock before calling */
+static void __set_rx_mode(struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       void __iomem *ioaddr = np->mem;
+       u32 mc_filter[2];       /* Multicast hash filter */
+       u32 rx_mode;
+
+       if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
+               memset(mc_filter, 0xff, sizeof(mc_filter));
+               rx_mode = CR_W_PROM | CR_W_AB | CR_W_AM;
+       } else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
+                  (dev->flags & IFF_ALLMULTI)) {
+               /* Too many to match, or accept all multicasts. */
+               memset(mc_filter, 0xff, sizeof(mc_filter));
+               rx_mode = CR_W_AB | CR_W_AM;
+       } else {
+               struct netdev_hw_addr *ha;
+
+               memset(mc_filter, 0, sizeof(mc_filter));
+               netdev_for_each_mc_addr(ha, dev) {
+                       unsigned int bit;
+                       bit = (ether_crc(ETH_ALEN, ha->addr) >> 26) ^ 0x3F;
+                       mc_filter[bit >> 5] |= (1 << bit);
+               }
+               rx_mode = CR_W_AB | CR_W_AM;
+       }
+
+       stop_nic_rxtx(ioaddr, np->crvalue);
+
+       iowrite32(mc_filter[0], ioaddr + MAR0);
+       iowrite32(mc_filter[1], ioaddr + MAR1);
+       np->crvalue &= ~CR_W_RXMODEMASK;
+       np->crvalue |= rx_mode;
+       iowrite32(np->crvalue, ioaddr + TCRRCR);
+}
+
+static void netdev_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+       struct netdev_private *np = netdev_priv(dev);
+
+       strscpy(info->driver, DRV_NAME, sizeof(info->driver));
+       strscpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info));
+}
+
+static int netdev_get_link_ksettings(struct net_device *dev,
+                                    struct ethtool_link_ksettings *cmd)
+{
+       struct netdev_private *np = netdev_priv(dev);
+
+       spin_lock_irq(&np->lock);
+       mii_ethtool_get_link_ksettings(&np->mii, cmd);
+       spin_unlock_irq(&np->lock);
+
+       return 0;
+}
+
+static int netdev_set_link_ksettings(struct net_device *dev,
+                                    const struct ethtool_link_ksettings *cmd)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       int rc;
+
+       spin_lock_irq(&np->lock);
+       rc = mii_ethtool_set_link_ksettings(&np->mii, cmd);
+       spin_unlock_irq(&np->lock);
+
+       return rc;
+}
+
+static int netdev_nway_reset(struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       return mii_nway_restart(&np->mii);
+}
+
+static u32 netdev_get_link(struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       return mii_link_ok(&np->mii);
+}
+
+static u32 netdev_get_msglevel(struct net_device *dev)
+{
+       return debug;
+}
+
+static void netdev_set_msglevel(struct net_device *dev, u32 value)
+{
+       debug = value;
+}
+
+static const struct ethtool_ops netdev_ethtool_ops = {
+       .get_drvinfo            = netdev_get_drvinfo,
+       .nway_reset             = netdev_nway_reset,
+       .get_link               = netdev_get_link,
+       .get_msglevel           = netdev_get_msglevel,
+       .set_msglevel           = netdev_set_msglevel,
+       .get_link_ksettings     = netdev_get_link_ksettings,
+       .set_link_ksettings     = netdev_set_link_ksettings,
+};
+
+static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       int rc;
+
+       if (!netif_running(dev))
+               return -EINVAL;
+
+       spin_lock_irq(&np->lock);
+       rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
+       spin_unlock_irq(&np->lock);
+
+       return rc;
+}
+
+
+static int netdev_close(struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       void __iomem *ioaddr = np->mem;
+       int i;
+
+       netif_stop_queue(dev);
+
+       /* Disable interrupts by clearing the interrupt mask. */
+       iowrite32(0x0000, ioaddr + IMR);
+
+       /* Stop the chip's Tx and Rx processes. */
+       stop_nic_rxtx(ioaddr, 0);
+
+       del_timer_sync(&np->timer);
+       del_timer_sync(&np->reset_timer);
+
+       free_irq(np->pci_dev->irq, dev);
+
+       /* Free all the skbuffs in the Rx queue. */
+       for (i = 0; i < RX_RING_SIZE; i++) {
+               struct sk_buff *skb = np->rx_ring[i].skbuff;
+
+               np->rx_ring[i].status = 0;
+               if (skb) {
+                       dma_unmap_single(&np->pci_dev->dev,
+                                        np->rx_ring[i].buffer, np->rx_buf_sz,
+                                        DMA_FROM_DEVICE);
+                       dev_kfree_skb(skb);
+                       np->rx_ring[i].skbuff = NULL;
+               }
+       }
+
+       for (i = 0; i < TX_RING_SIZE; i++) {
+               struct sk_buff *skb = np->tx_ring[i].skbuff;
+
+               if (skb) {
+                       dma_unmap_single(&np->pci_dev->dev,
+                                        np->tx_ring[i].buffer, skb->len,
+                                        DMA_TO_DEVICE);
+                       dev_kfree_skb(skb);
+                       np->tx_ring[i].skbuff = NULL;
+               }
+       }
+
+       return 0;
+}
+
+static const struct pci_device_id fealnx_pci_tbl[] = {
+       {0x1516, 0x0800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {0x1516, 0x0803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+       {0x1516, 0x0891, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
+       {} /* terminate list */
+};
+MODULE_DEVICE_TABLE(pci, fealnx_pci_tbl);
+
+
+static struct pci_driver fealnx_driver = {
+       .name           = "fealnx",
+       .id_table       = fealnx_pci_tbl,
+       .probe          = fealnx_init_one,
+       .remove         = fealnx_remove_one,
+};
+
+module_pci_driver(fealnx_driver);
index bca68edfbe9cd53c8128d91d1de9ac0fde2e1570..838750a03cf68a3d4da7d6c3be7cc45fc3c1a708 100644 (file)
@@ -370,8 +370,7 @@ static const struct ethtool_rmon_hist_range enetc_rmon_ranges[] = {
 };
 
 static void enetc_rmon_stats(struct enetc_hw *hw, int mac,
-                            struct ethtool_rmon_stats *s,
-                            const struct ethtool_rmon_hist_range **ranges)
+                            struct ethtool_rmon_stats *s)
 {
        s->undersize_pkts = enetc_port_rd(hw, ENETC_PM_RUND(mac));
        s->oversize_pkts = enetc_port_rd(hw, ENETC_PM_ROVR(mac));
@@ -393,8 +392,6 @@ static void enetc_rmon_stats(struct enetc_hw *hw, int mac,
        s->hist_tx[4] = enetc_port_rd(hw, ENETC_PM_T1023(mac));
        s->hist_tx[5] = enetc_port_rd(hw, ENETC_PM_T1522(mac));
        s->hist_tx[6] = enetc_port_rd(hw, ENETC_PM_T1523X(mac));
-
-       *ranges = enetc_rmon_ranges;
 }
 
 static void enetc_get_eth_mac_stats(struct net_device *ndev,
@@ -447,13 +444,15 @@ static void enetc_get_rmon_stats(struct net_device *ndev,
        struct enetc_hw *hw = &priv->si->hw;
        struct enetc_si *si = priv->si;
 
+       *ranges = enetc_rmon_ranges;
+
        switch (rmon_stats->src) {
        case ETHTOOL_MAC_STATS_SRC_EMAC:
-               enetc_rmon_stats(hw, 0, rmon_stats, ranges);
+               enetc_rmon_stats(hw, 0, rmon_stats);
                break;
        case ETHTOOL_MAC_STATS_SRC_PMAC:
                if (si->hw_features & ENETC_SI_F_QBU)
-                       enetc_rmon_stats(hw, 1, rmon_stats, ranges);
+                       enetc_rmon_stats(hw, 1, rmon_stats);
                break;
        case ETHTOOL_MAC_STATS_SRC_AGGREGATE:
                ethtool_aggregate_rmon_stats(ndev, rmon_stats);
@@ -990,6 +989,20 @@ static int enetc_get_mm(struct net_device *ndev, struct ethtool_mm_state *state)
        return 0;
 }
 
+/* FIXME: Workaround for the link partner's verification failing if ENETC
+ * priorly received too much express traffic. The documentation doesn't
+ * suggest this is needed.
+ */
+static void enetc_restart_emac_rx(struct enetc_si *si)
+{
+       u32 val = enetc_port_rd(&si->hw, ENETC_PM0_CMD_CFG);
+
+       enetc_port_wr(&si->hw, ENETC_PM0_CMD_CFG, val & ~ENETC_PM0_RX_EN);
+
+       if (val & ENETC_PM0_RX_EN)
+               enetc_port_wr(&si->hw, ENETC_PM0_CMD_CFG, val);
+}
+
 static int enetc_set_mm(struct net_device *ndev, struct ethtool_mm_cfg *cfg,
                        struct netlink_ext_ack *extack)
 {
@@ -1041,6 +1054,8 @@ static int enetc_set_mm(struct net_device *ndev, struct ethtool_mm_cfg *cfg,
 
        enetc_port_wr(hw, ENETC_MMCSR, val);
 
+       enetc_restart_emac_rx(priv->si);
+
        mutex_unlock(&priv->mm_lock);
 
        return 0;
index 5ba1e0d71c687892bb7578d9aea42a344c9fc2fc..9939ccafb556609f8b6931ef42bb49f267aadea8 100644 (file)
@@ -507,6 +507,11 @@ struct bufdesc_ex {
 /* i.MX6Q adds pm_qos support */
 #define FEC_QUIRK_HAS_PMQOS                    BIT(23)
 
+/* Not all FEC hardware block MDIOs support accesses in C45 mode.
+ * Older blocks in the ColdFire parts do not support it.
+ */
+#define FEC_QUIRK_HAS_MDIO_C45         BIT(24)
+
 struct bufdesc_prop {
        int qid;
        /* Address of Rx and Tx buffers */
index c73e25f8995eb9b0a95ba118a1ce007110e6f8ff..160c1b3525f5bd4d9001626f27be1308fc6ba385 100644 (file)
@@ -100,18 +100,19 @@ struct fec_devinfo {
 
 static const struct fec_devinfo fec_imx25_info = {
        .quirks = FEC_QUIRK_USE_GASKET | FEC_QUIRK_MIB_CLEAR |
-                 FEC_QUIRK_HAS_FRREG,
+                 FEC_QUIRK_HAS_FRREG | FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static const struct fec_devinfo fec_imx27_info = {
-       .quirks = FEC_QUIRK_MIB_CLEAR | FEC_QUIRK_HAS_FRREG,
+       .quirks = FEC_QUIRK_MIB_CLEAR | FEC_QUIRK_HAS_FRREG |
+                 FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static const struct fec_devinfo fec_imx28_info = {
        .quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME |
                  FEC_QUIRK_SINGLE_MDIO | FEC_QUIRK_HAS_RACC |
                  FEC_QUIRK_HAS_FRREG | FEC_QUIRK_CLEAR_SETUP_MII |
-                 FEC_QUIRK_NO_HARD_RESET,
+                 FEC_QUIRK_NO_HARD_RESET | FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static const struct fec_devinfo fec_imx6q_info = {
@@ -119,11 +120,12 @@ static const struct fec_devinfo fec_imx6q_info = {
                  FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
                  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 |
                  FEC_QUIRK_HAS_RACC | FEC_QUIRK_CLEAR_SETUP_MII |
-                 FEC_QUIRK_HAS_PMQOS,
+                 FEC_QUIRK_HAS_PMQOS | FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static const struct fec_devinfo fec_mvf600_info = {
-       .quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_RACC,
+       .quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_RACC |
+                 FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static const struct fec_devinfo fec_imx6x_info = {
@@ -132,7 +134,8 @@ static const struct fec_devinfo fec_imx6x_info = {
                  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
                  FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
                  FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
-                 FEC_QUIRK_CLEAR_SETUP_MII | FEC_QUIRK_HAS_MULTI_QUEUES,
+                 FEC_QUIRK_CLEAR_SETUP_MII | FEC_QUIRK_HAS_MULTI_QUEUES |
+                 FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static const struct fec_devinfo fec_imx6ul_info = {
@@ -140,7 +143,8 @@ static const struct fec_devinfo fec_imx6ul_info = {
                  FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
                  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR007885 |
                  FEC_QUIRK_BUG_CAPTURE | FEC_QUIRK_HAS_RACC |
-                 FEC_QUIRK_HAS_COALESCE | FEC_QUIRK_CLEAR_SETUP_MII,
+                 FEC_QUIRK_HAS_COALESCE | FEC_QUIRK_CLEAR_SETUP_MII |
+                 FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static const struct fec_devinfo fec_imx8mq_info = {
@@ -150,7 +154,8 @@ static const struct fec_devinfo fec_imx8mq_info = {
                  FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
                  FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
                  FEC_QUIRK_CLEAR_SETUP_MII | FEC_QUIRK_HAS_MULTI_QUEUES |
-                 FEC_QUIRK_HAS_EEE | FEC_QUIRK_WAKEUP_FROM_INT2,
+                 FEC_QUIRK_HAS_EEE | FEC_QUIRK_WAKEUP_FROM_INT2 |
+                 FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static const struct fec_devinfo fec_imx8qm_info = {
@@ -160,14 +165,15 @@ static const struct fec_devinfo fec_imx8qm_info = {
                  FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
                  FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
                  FEC_QUIRK_CLEAR_SETUP_MII | FEC_QUIRK_HAS_MULTI_QUEUES |
-                 FEC_QUIRK_DELAYED_CLKS_SUPPORT,
+                 FEC_QUIRK_DELAYED_CLKS_SUPPORT | FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static const struct fec_devinfo fec_s32v234_info = {
        .quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
                  FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
                  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
-                 FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE,
+                 FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
+                 FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static struct platform_device_id fec_devtype[] = {
@@ -2434,8 +2440,10 @@ static int fec_enet_mii_init(struct platform_device *pdev)
        fep->mii_bus->name = "fec_enet_mii_bus";
        fep->mii_bus->read = fec_enet_mdio_read_c22;
        fep->mii_bus->write = fec_enet_mdio_write_c22;
-       fep->mii_bus->read_c45 = fec_enet_mdio_read_c45;
-       fep->mii_bus->write_c45 = fec_enet_mdio_write_c45;
+       if (fep->quirks & FEC_QUIRK_HAS_MDIO_C45) {
+               fep->mii_bus->read_c45 = fec_enet_mdio_read_c45;
+               fep->mii_bus->write_c45 = fec_enet_mdio_write_c45;
+       }
        snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
                pdev->name, fep->dev_id + 1);
        fep->mii_bus->priv = fep;
@@ -4251,7 +4259,7 @@ fec_probe(struct platform_device *pdev)
        if (ret)
                goto failed_ipc_init;
 
-       if (of_get_property(np, "fsl,magic-packet", NULL))
+       if (of_property_read_bool(np, "fsl,magic-packet"))
                fep->wol_flag |= FEC_WOL_HAS_MAGIC_PACKET;
 
        ret = fec_enet_init_stop_mode(fep, np);
index a7f4c3c29f3e41965609aed79e1a145478755b20..b88816b71ddff3dca52753d24d90817014d9924b 100644 (file)
@@ -937,7 +937,7 @@ static int mpc52xx_fec_probe(struct platform_device *op)
        priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
 
        /* the 7-wire property means don't use MII mode */
-       if (of_find_property(np, "fsl,7-wire-mode", NULL)) {
+       if (of_property_read_bool(np, "fsl,7-wire-mode")) {
                priv->seven_wire_mode = 1;
                dev_info(&ndev->dev, "using 7-wire PHY mode\n");
        }
index b2def295523ab5ce23b547fae1a21b7662c25f17..38d5013c6fedf5a654cf67eadbdae8eed5fb8ac1 100644 (file)
@@ -787,10 +787,10 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
        else
                priv->interface = gfar_get_interface(dev);
 
-       if (of_find_property(np, "fsl,magic-packet", NULL))
+       if (of_property_read_bool(np, "fsl,magic-packet"))
                priv->device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET;
 
-       if (of_get_property(np, "fsl,wake-on-filer", NULL))
+       if (of_property_read_bool(np, "fsl,wake-on-filer"))
                priv->device_flags |= FSL_GIANFAR_DEV_HAS_WAKE_ON_FILER;
 
        priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
index 64eb0442c82fd3ce485d4a326403940c79d29df7..005cb9dfe078bc588acc6d15e0c47a7c903d9da9 100644 (file)
@@ -47,6 +47,8 @@
 
 #define GVE_RX_BUFFER_SIZE_DQO 2048
 
+#define GVE_GQ_TX_MIN_PKT_DESC_BYTES 182
+
 /* Each slot in the desc ring has a 1:1 mapping to a slot in the data ring */
 struct gve_rx_desc_queue {
        struct gve_rx_desc *desc_ring; /* the descriptor ring */
index ce574d097e280f9dbf52663661ebeffa4f7b8ba9..5f81470843b49658b882658eea8f75e109e9e5bc 100644 (file)
@@ -537,7 +537,10 @@ static int gve_get_link_ksettings(struct net_device *netdev,
                                  struct ethtool_link_ksettings *cmd)
 {
        struct gve_priv *priv = netdev_priv(netdev);
-       int err = gve_adminq_report_link_speed(priv);
+       int err = 0;
+
+       if (priv->link_speed == 0)
+               err = gve_adminq_report_link_speed(priv);
 
        cmd->base.speed = priv->link_speed;
        return err;
index 4888bf05fbedb5b84aa18648547e5c878359e991..5e11b823675454ab4f3c63951c80e3da4f45cec5 100644 (file)
@@ -284,8 +284,8 @@ static inline int gve_skb_fifo_bytes_required(struct gve_tx_ring *tx,
        int bytes;
        int hlen;
 
-       hlen = skb_is_gso(skb) ? skb_checksum_start_offset(skb) +
-                                tcp_hdrlen(skb) : skb_headlen(skb);
+       hlen = skb_is_gso(skb) ? skb_checksum_start_offset(skb) + tcp_hdrlen(skb) :
+                                min_t(int, GVE_GQ_TX_MIN_PKT_DESC_BYTES, skb->len);
 
        pad_bytes = gve_tx_fifo_pad_alloc_one_frag(&tx->tx_fifo,
                                                   hlen);
@@ -454,13 +454,11 @@ static int gve_tx_add_skb_copy(struct gve_priv *priv, struct gve_tx_ring *tx, st
        pkt_desc = &tx->desc[idx];
 
        l4_hdr_offset = skb_checksum_start_offset(skb);
-       /* If the skb is gso, then we want the tcp header in the first segment
-        * otherwise we want the linear portion of the skb (which will contain
-        * the checksum because skb->csum_start and skb->csum_offset are given
-        * relative to skb->head) in the first segment.
+       /* If the skb is gso, then we want the tcp header alone in the first segment
+        * otherwise we want the minimum required by the gVNIC spec.
         */
        hlen = is_gso ? l4_hdr_offset + tcp_hdrlen(skb) :
-                       skb_headlen(skb);
+                       min_t(int, GVE_GQ_TX_MIN_PKT_DESC_BYTES, skb->len);
 
        info->skb =  skb;
        /* We don't want to split the header, so if necessary, pad to the end
index daec9ce04531be2531a24d5b44bc83ad5dae3a2c..54bb4d9a0d1ea4230d8269dfc0184a0f7df93ff0 100644 (file)
@@ -78,6 +78,7 @@ static int sni_82596_probe(struct platform_device *dev)
        void __iomem *mpu_addr;
        void __iomem *ca_addr;
        u8 __iomem *eth_addr;
+       u8 mac[ETH_ALEN];
 
        res = platform_get_resource(dev, IORESOURCE_MEM, 0);
        ca = platform_get_resource(dev, IORESOURCE_MEM, 1);
@@ -109,12 +110,13 @@ static int sni_82596_probe(struct platform_device *dev)
                goto probe_failed;
 
        /* someone seems to like messed up stuff */
-       netdevice->dev_addr[0] = readb(eth_addr + 0x0b);
-       netdevice->dev_addr[1] = readb(eth_addr + 0x0a);
-       netdevice->dev_addr[2] = readb(eth_addr + 0x09);
-       netdevice->dev_addr[3] = readb(eth_addr + 0x08);
-       netdevice->dev_addr[4] = readb(eth_addr + 0x07);
-       netdevice->dev_addr[5] = readb(eth_addr + 0x06);
+       mac[0] = readb(eth_addr + 0x0b);
+       mac[1] = readb(eth_addr + 0x0a);
+       mac[2] = readb(eth_addr + 0x09);
+       mac[3] = readb(eth_addr + 0x08);
+       mac[4] = readb(eth_addr + 0x07);
+       mac[5] = readb(eth_addr + 0x06);
+       eth_hw_addr_set(netdevice, mac);
        iounmap(eth_addr);
 
        if (netdevice->irq < 0) {
index 9b08e41ccc294dae821d17a438b0f82b6d15182b..c97095abd26abcd88c6ac40cb9307a9ac90a3a94 100644 (file)
@@ -2939,9 +2939,9 @@ static int emac_init_config(struct emac_instance *dev)
        }
 
        /* Fixup some feature bits based on the device tree */
-       if (of_get_property(np, "has-inverted-stacr-oc", NULL))
+       if (of_property_read_bool(np, "has-inverted-stacr-oc"))
                dev->features |= EMAC_FTR_STACR_OC_INVERT;
-       if (of_get_property(np, "has-new-stacr-staopc", NULL))
+       if (of_property_read_bool(np, "has-new-stacr-staopc"))
                dev->features |= EMAC_FTR_HAS_NEW_STACR;
 
        /* CAB lacks the appropriate properties */
@@ -3042,7 +3042,7 @@ static int emac_probe(struct platform_device *ofdev)
         * property here for now, but new flat device trees should set a
         * status property to "disabled" instead.
         */
-       if (of_get_property(np, "unused", NULL) || !of_device_is_available(np))
+       if (of_property_read_bool(np, "unused") || !of_device_is_available(np))
                return -ENODEV;
 
        /* Find ourselves in the bootlist if we are there */
@@ -3333,7 +3333,7 @@ static void __init emac_make_bootlist(void)
 
                if (of_match_node(emac_match, np) == NULL)
                        continue;
-               if (of_get_property(np, "unused", NULL))
+               if (of_property_read_bool(np, "unused"))
                        continue;
                idx = of_get_property(np, "cell-index", NULL);
                if (idx == NULL)
index 242ef976fd15e6bf7a9ed9ffd4b87a2d4ccee694..50358cf0013068c45749b3cd905d71cc8cd92ba1 100644 (file)
@@ -242,7 +242,7 @@ static int rgmii_probe(struct platform_device *ofdev)
        }
 
        /* Check for RGMII flags */
-       if (of_get_property(ofdev->dev.of_node, "has-mdio", NULL))
+       if (of_property_read_bool(ofdev->dev.of_node, "has-mdio"))
                dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO;
 
        /* CAB lacks the right properties, fix this up */
index e1eb1de88bf928b98ad8a6b4bad8d8ff47e9c9aa..e14d1e45318f824180979043b269694c47c84d36 100644 (file)
@@ -5288,31 +5288,6 @@ static void e1000_watchdog_task(struct work_struct *work)
                                ew32(TARC(0), tarc0);
                        }
 
-                       /* disable TSO for pcie and 10/100 speeds, to avoid
-                        * some hardware issues
-                        */
-                       if (!(adapter->flags & FLAG_TSO_FORCE)) {
-                               switch (adapter->link_speed) {
-                               case SPEED_10:
-                               case SPEED_100:
-                                       e_info("10/100 speed: disabling TSO\n");
-                                       netdev->features &= ~NETIF_F_TSO;
-                                       netdev->features &= ~NETIF_F_TSO6;
-                                       break;
-                               case SPEED_1000:
-                                       netdev->features |= NETIF_F_TSO;
-                                       netdev->features |= NETIF_F_TSO6;
-                                       break;
-                               default:
-                                       /* oops */
-                                       break;
-                               }
-                               if (hw->mac.type == e1000_pch_spt) {
-                                       netdev->features &= ~NETIF_F_TSO;
-                                       netdev->features &= ~NETIF_F_TSO6;
-                               }
-                       }
-
                        /* enable transmits in the hardware, need to do this
                         * after setting TARC(0)
                         */
@@ -7526,6 +7501,32 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                            NETIF_F_RXCSUM |
                            NETIF_F_HW_CSUM);
 
+       /* disable TSO for pcie and 10/100 speeds to avoid
+        * some hardware issues and for i219 to fix transfer
+        * speed being capped at 60%
+        */
+       if (!(adapter->flags & FLAG_TSO_FORCE)) {
+               switch (adapter->link_speed) {
+               case SPEED_10:
+               case SPEED_100:
+                       e_info("10/100 speed: disabling TSO\n");
+                       netdev->features &= ~NETIF_F_TSO;
+                       netdev->features &= ~NETIF_F_TSO6;
+                       break;
+               case SPEED_1000:
+                       netdev->features |= NETIF_F_TSO;
+                       netdev->features |= NETIF_F_TSO6;
+                       break;
+               default:
+                       /* oops */
+                       break;
+               }
+               if (hw->mac.type == e1000_pch_spt) {
+                       netdev->features &= ~NETIF_F_TSO;
+                       netdev->features &= ~NETIF_F_TSO6;
+               }
+       }
+
        /* Set user-changeable features (subset of all device features) */
        netdev->hw_features = netdev->features;
        netdev->hw_features |= NETIF_F_RXFCS;
index 5b3519c6e362ebacab5c4c6b426cc30f03901b7b..97fe1787a8f4aa4f1388cce893e47932fe23333a 100644 (file)
@@ -44,7 +44,7 @@ static int i40e_diag_reg_pattern_test(struct i40e_hw *hw,
        return 0;
 }
 
-struct i40e_diag_reg_test_info i40e_reg_list[] = {
+const struct i40e_diag_reg_test_info i40e_reg_list[] = {
        /* offset               mask         elements   stride */
        {I40E_QTX_CTL(0),       0x0000FFBF, 1,
                I40E_QTX_CTL(1) - I40E_QTX_CTL(0)},
@@ -78,27 +78,28 @@ int i40e_diag_reg_test(struct i40e_hw *hw)
 {
        int ret_code = 0;
        u32 reg, mask;
+       u32 elements;
        u32 i, j;
 
        for (i = 0; i40e_reg_list[i].offset != 0 &&
                                             !ret_code; i++) {
 
+               elements = i40e_reg_list[i].elements;
                /* set actual reg range for dynamically allocated resources */
                if (i40e_reg_list[i].offset == I40E_QTX_CTL(0) &&
                    hw->func_caps.num_tx_qp != 0)
-                       i40e_reg_list[i].elements = hw->func_caps.num_tx_qp;
+                       elements = hw->func_caps.num_tx_qp;
                if ((i40e_reg_list[i].offset == I40E_PFINT_ITRN(0, 0) ||
                     i40e_reg_list[i].offset == I40E_PFINT_ITRN(1, 0) ||
                     i40e_reg_list[i].offset == I40E_PFINT_ITRN(2, 0) ||
                     i40e_reg_list[i].offset == I40E_QINT_TQCTL(0) ||
                     i40e_reg_list[i].offset == I40E_QINT_RQCTL(0)) &&
                    hw->func_caps.num_msix_vectors != 0)
-                       i40e_reg_list[i].elements =
-                               hw->func_caps.num_msix_vectors - 1;
+                       elements = hw->func_caps.num_msix_vectors - 1;
 
                /* test register access */
                mask = i40e_reg_list[i].mask;
-               for (j = 0; j < i40e_reg_list[i].elements && !ret_code; j++) {
+               for (j = 0; j < elements && !ret_code; j++) {
                        reg = i40e_reg_list[i].offset +
                              (j * i40e_reg_list[i].stride);
                        ret_code = i40e_diag_reg_pattern_test(hw, reg, mask);
index e641035c7297dcc12dfb5fcf6937ffdfb5f82deb..c3ce5f35211f03220b1cc6169a31a8e3c7000fdb 100644 (file)
@@ -20,7 +20,7 @@ struct i40e_diag_reg_test_info {
        u32 stride;     /* bytes between each element */
 };
 
-extern struct i40e_diag_reg_test_info i40e_reg_list[];
+extern const struct i40e_diag_reg_test_info i40e_reg_list[];
 
 int i40e_diag_reg_test(struct i40e_hw *hw);
 int i40e_diag_eeprom_test(struct i40e_hw *hw);
index 467001db5070ed568a9d4be4f5e3c6d957c526cb..7c30abd0dfc22720415f8f649ae732de73a099b3 100644 (file)
@@ -11059,8 +11059,11 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
                                             pf->hw.aq.asq_last_status));
        }
        /* reinit the misc interrupt */
-       if (pf->flags & I40E_FLAG_MSIX_ENABLED)
+       if (pf->flags & I40E_FLAG_MSIX_ENABLED) {
                ret = i40e_setup_misc_vector(pf);
+               if (ret)
+                       goto end_unlock;
+       }
 
        /* Add a filter to drop all Flow control frames from any VSI from being
         * transmitted. By doing so we stop a malicious VF from sending out
@@ -14133,15 +14136,15 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
                vsi->id = ctxt.vsi_number;
        }
 
-       vsi->active_filters = 0;
-       clear_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);
        spin_lock_bh(&vsi->mac_filter_hash_lock);
+       vsi->active_filters = 0;
        /* If macvlan filters already exist, force them to get loaded */
        hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) {
                f->state = I40E_FILTER_NEW;
                f_count++;
        }
        spin_unlock_bh(&vsi->mac_filter_hash_lock);
+       clear_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);
 
        if (f_count) {
                vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED;
@@ -15525,6 +15528,7 @@ static int i40e_init_recovery_mode(struct i40e_pf *pf, struct i40e_hw *hw)
        int err;
        int v_idx;
 
+       pci_set_drvdata(pf->pdev, pf);
        pci_save_state(pf->pdev);
 
        /* set up periodic task facility */
index 924f972b91faf2f69ce78ff5c8bd1f208a048da0..72b091f2509d8b0330d2f26e311b3acbce4e3547 100644 (file)
@@ -171,10 +171,10 @@ static char *i40e_create_dummy_packet(u8 *dummy_packet, bool ipv4, u8 l4proto,
                                      struct i40e_fdir_filter *data)
 {
        bool is_vlan = !!data->vlan_tag;
-       struct vlan_hdr vlan;
-       struct ipv6hdr ipv6;
-       struct ethhdr eth;
-       struct iphdr ip;
+       struct vlan_hdr vlan = {};
+       struct ipv6hdr ipv6 = {};
+       struct ethhdr eth = {};
+       struct iphdr ip = {};
        u8 *tmp;
 
        if (ipv4) {
index 232bc61d9eee9ce6c2eb7a6a3c758ac22cfe20b3..746ff76f2fb1e648882b9a393415823be12d0c9c 100644 (file)
@@ -59,8 +59,6 @@ enum iavf_vsi_state_t {
 struct iavf_vsi {
        struct iavf_adapter *back;
        struct net_device *netdev;
-       unsigned long active_cvlans[BITS_TO_LONGS(VLAN_N_VID)];
-       unsigned long active_svlans[BITS_TO_LONGS(VLAN_N_VID)];
        u16 seid;
        u16 id;
        DECLARE_BITMAP(state, __IAVF_VSI_STATE_SIZE__);
@@ -158,15 +156,20 @@ struct iavf_vlan {
        u16 tpid;
 };
 
+enum iavf_vlan_state_t {
+       IAVF_VLAN_INVALID,
+       IAVF_VLAN_ADD,          /* filter needs to be added */
+       IAVF_VLAN_IS_NEW,       /* filter is new, wait for PF answer */
+       IAVF_VLAN_ACTIVE,       /* filter is accepted by PF */
+       IAVF_VLAN_DISABLE,      /* filter needs to be deleted by PF, then marked INACTIVE */
+       IAVF_VLAN_INACTIVE,     /* filter is inactive, we are in IFF_DOWN */
+       IAVF_VLAN_REMOVE,       /* filter needs to be removed from list */
+};
+
 struct iavf_vlan_filter {
        struct list_head list;
        struct iavf_vlan vlan;
-       struct {
-               u8 is_new_vlan:1;       /* filter is new, wait for PF answer */
-               u8 remove:1;            /* filter needs to be removed */
-               u8 add:1;               /* filter needs to be added */
-               u8 padding:5;
-       };
+       enum iavf_vlan_state_t state;
 };
 
 #define IAVF_MAX_TRAFFIC_CLASS 4
@@ -258,6 +261,7 @@ struct iavf_adapter {
        wait_queue_head_t vc_waitqueue;
        struct iavf_q_vector *q_vectors;
        struct list_head vlan_filter_list;
+       int num_vlan_filters;
        struct list_head mac_filter_list;
        struct mutex crit_lock;
        struct mutex client_lock;
index 16c490965b61a58843ddaeeaef0601524ab6a7e3..dd11dbbd5551a2c1d9f8a431d972655d9cabe79c 100644 (file)
@@ -661,7 +661,7 @@ struct iavf_rx_ptype_decoded iavf_ptype_lookup[BIT(8)] = {
        /* Non Tunneled IPv6 */
        IAVF_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3),
        IAVF_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3),
-       IAVF_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP,  PAY3),
+       IAVF_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP,  PAY4),
        IAVF_PTT_UNUSED_ENTRY(91),
        IAVF_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP,  PAY4),
        IAVF_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4),
index 3273aeb8fa67631421def6a71bab6faaef0e5d91..2de4baff4c20501baab55b7ffddb84b6f8e20aee 100644 (file)
@@ -791,7 +791,8 @@ iavf_vlan_filter *iavf_add_vlan(struct iavf_adapter *adapter,
                f->vlan = vlan;
 
                list_add_tail(&f->list, &adapter->vlan_filter_list);
-               f->add = true;
+               f->state = IAVF_VLAN_ADD;
+               adapter->num_vlan_filters++;
                adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;
        }
 
@@ -813,7 +814,7 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, struct iavf_vlan vlan)
 
        f = iavf_find_vlan(adapter, vlan);
        if (f) {
-               f->remove = true;
+               f->state = IAVF_VLAN_REMOVE;
                adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER;
        }
 
@@ -828,14 +829,18 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, struct iavf_vlan vlan)
  **/
 static void iavf_restore_filters(struct iavf_adapter *adapter)
 {
-       u16 vid;
+       struct iavf_vlan_filter *f;
 
        /* re-add all VLAN filters */
-       for_each_set_bit(vid, adapter->vsi.active_cvlans, VLAN_N_VID)
-               iavf_add_vlan(adapter, IAVF_VLAN(vid, ETH_P_8021Q));
+       spin_lock_bh(&adapter->mac_vlan_list_lock);
+
+       list_for_each_entry(f, &adapter->vlan_filter_list, list) {
+               if (f->state == IAVF_VLAN_INACTIVE)
+                       f->state = IAVF_VLAN_ADD;
+       }
 
-       for_each_set_bit(vid, adapter->vsi.active_svlans, VLAN_N_VID)
-               iavf_add_vlan(adapter, IAVF_VLAN(vid, ETH_P_8021AD));
+       spin_unlock_bh(&adapter->mac_vlan_list_lock);
+       adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;
 }
 
 /**
@@ -844,8 +849,7 @@ static void iavf_restore_filters(struct iavf_adapter *adapter)
  */
 u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter)
 {
-       return bitmap_weight(adapter->vsi.active_cvlans, VLAN_N_VID) +
-               bitmap_weight(adapter->vsi.active_svlans, VLAN_N_VID);
+       return adapter->num_vlan_filters;
 }
 
 /**
@@ -893,6 +897,10 @@ static int iavf_vlan_rx_add_vid(struct net_device *netdev,
 {
        struct iavf_adapter *adapter = netdev_priv(netdev);
 
+       /* Do not track VLAN 0 filter, always added by the PF on VF init */
+       if (!vid)
+               return 0;
+
        if (!VLAN_FILTERING_ALLOWED(adapter))
                return -EIO;
 
@@ -919,12 +927,11 @@ static int iavf_vlan_rx_kill_vid(struct net_device *netdev,
 {
        struct iavf_adapter *adapter = netdev_priv(netdev);
 
-       iavf_del_vlan(adapter, IAVF_VLAN(vid, be16_to_cpu(proto)));
-       if (proto == cpu_to_be16(ETH_P_8021Q))
-               clear_bit(vid, adapter->vsi.active_cvlans);
-       else
-               clear_bit(vid, adapter->vsi.active_svlans);
+       /* We do not track VLAN 0 filter */
+       if (!vid)
+               return 0;
 
+       iavf_del_vlan(adapter, IAVF_VLAN(vid, be16_to_cpu(proto)));
        return 0;
 }
 
@@ -1285,16 +1292,11 @@ static void iavf_clear_mac_vlan_filters(struct iavf_adapter *adapter)
                }
        }
 
-       /* remove all VLAN filters */
+       /* disable all VLAN filters */
        list_for_each_entry_safe(vlf, vlftmp, &adapter->vlan_filter_list,
-                                list) {
-               if (vlf->add) {
-                       list_del(&vlf->list);
-                       kfree(vlf);
-               } else {
-                       vlf->remove = true;
-               }
-       }
+                                list)
+               vlf->state = IAVF_VLAN_DISABLE;
+
        spin_unlock_bh(&adapter->mac_vlan_list_lock);
 }
 
@@ -2906,6 +2908,7 @@ static void iavf_disable_vf(struct iavf_adapter *adapter)
                list_del(&fv->list);
                kfree(fv);
        }
+       adapter->num_vlan_filters = 0;
 
        spin_unlock_bh(&adapter->mac_vlan_list_lock);
 
@@ -3123,9 +3126,6 @@ continue_reset:
        adapter->aq_required |= IAVF_FLAG_AQ_ADD_CLOUD_FILTER;
        iavf_misc_irq_enable(adapter);
 
-       bitmap_clear(adapter->vsi.active_cvlans, 0, VLAN_N_VID);
-       bitmap_clear(adapter->vsi.active_svlans, 0, VLAN_N_VID);
-
        mod_delayed_work(adapter->wq, &adapter->watchdog_task, 2);
 
        /* We were running when the reset started, so we need to restore some
@@ -5066,6 +5066,11 @@ static void iavf_remove(struct pci_dev *pdev)
                        mutex_unlock(&adapter->crit_lock);
                        break;
                }
+               /* Simply return if we already went through iavf_shutdown */
+               if (adapter->state == __IAVF_REMOVE) {
+                       mutex_unlock(&adapter->crit_lock);
+                       return;
+               }
 
                mutex_unlock(&adapter->crit_lock);
                usleep_range(500, 1000);
index 18b6a702a1d6dff9e9aeac001526444a6ca38736..e989feda133c1e63447f005437f09ba248084fdb 100644 (file)
@@ -1096,7 +1096,7 @@ static inline void iavf_rx_hash(struct iavf_ring *ring,
                cpu_to_le64((u64)IAVF_RX_DESC_FLTSTAT_RSS_HASH <<
                            IAVF_RX_DESC_STATUS_FLTSTAT_SHIFT);
 
-       if (ring->netdev->features & NETIF_F_RXHASH)
+       if (!(ring->netdev->features & NETIF_F_RXHASH))
                return;
 
        if ((rx_desc->wb.qword1.status_error_len & rss_mask) == rss_mask) {
index 6d23338604bb33e07f2df55f3656296ed4db24b0..9afbbdac35903f1ae018c00fe28213ece3227d3f 100644 (file)
@@ -642,16 +642,10 @@ static void iavf_vlan_add_reject(struct iavf_adapter *adapter)
 
        spin_lock_bh(&adapter->mac_vlan_list_lock);
        list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
-               if (f->is_new_vlan) {
-                       if (f->vlan.tpid == ETH_P_8021Q)
-                               clear_bit(f->vlan.vid,
-                                         adapter->vsi.active_cvlans);
-                       else
-                               clear_bit(f->vlan.vid,
-                                         adapter->vsi.active_svlans);
-
+               if (f->state == IAVF_VLAN_IS_NEW) {
                        list_del(&f->list);
                        kfree(f);
+                       adapter->num_vlan_filters--;
                }
        }
        spin_unlock_bh(&adapter->mac_vlan_list_lock);
@@ -679,7 +673,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
        spin_lock_bh(&adapter->mac_vlan_list_lock);
 
        list_for_each_entry(f, &adapter->vlan_filter_list, list) {
-               if (f->add)
+               if (f->state == IAVF_VLAN_ADD)
                        count++;
        }
        if (!count || !VLAN_FILTERING_ALLOWED(adapter)) {
@@ -710,11 +704,10 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
                vvfl->vsi_id = adapter->vsi_res->vsi_id;
                vvfl->num_elements = count;
                list_for_each_entry(f, &adapter->vlan_filter_list, list) {
-                       if (f->add) {
+                       if (f->state == IAVF_VLAN_ADD) {
                                vvfl->vlan_id[i] = f->vlan.vid;
                                i++;
-                               f->add = false;
-                               f->is_new_vlan = true;
+                               f->state = IAVF_VLAN_IS_NEW;
                                if (i == count)
                                        break;
                        }
@@ -760,7 +753,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
                vvfl_v2->vport_id = adapter->vsi_res->vsi_id;
                vvfl_v2->num_elements = count;
                list_for_each_entry(f, &adapter->vlan_filter_list, list) {
-                       if (f->add) {
+                       if (f->state == IAVF_VLAN_ADD) {
                                struct virtchnl_vlan_supported_caps *filtering_support =
                                        &adapter->vlan_v2_caps.filtering.filtering_support;
                                struct virtchnl_vlan *vlan;
@@ -778,8 +771,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
                                vlan->tpid = f->vlan.tpid;
 
                                i++;
-                               f->add = false;
-                               f->is_new_vlan = true;
+                               f->state = IAVF_VLAN_IS_NEW;
                        }
                }
 
@@ -822,10 +814,16 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
                 * filters marked for removal to enable bailing out before
                 * sending a virtchnl message
                 */
-               if (f->remove && !VLAN_FILTERING_ALLOWED(adapter)) {
+               if (f->state == IAVF_VLAN_REMOVE &&
+                   !VLAN_FILTERING_ALLOWED(adapter)) {
                        list_del(&f->list);
                        kfree(f);
-               } else if (f->remove) {
+                       adapter->num_vlan_filters--;
+               } else if (f->state == IAVF_VLAN_DISABLE &&
+                   !VLAN_FILTERING_ALLOWED(adapter)) {
+                       f->state = IAVF_VLAN_INACTIVE;
+               } else if (f->state == IAVF_VLAN_REMOVE ||
+                          f->state == IAVF_VLAN_DISABLE) {
                        count++;
                }
        }
@@ -857,11 +855,18 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
                vvfl->vsi_id = adapter->vsi_res->vsi_id;
                vvfl->num_elements = count;
                list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
-                       if (f->remove) {
+                       if (f->state == IAVF_VLAN_DISABLE) {
                                vvfl->vlan_id[i] = f->vlan.vid;
+                               f->state = IAVF_VLAN_INACTIVE;
                                i++;
+                               if (i == count)
+                                       break;
+                       } else if (f->state == IAVF_VLAN_REMOVE) {
+                               vvfl->vlan_id[i] = f->vlan.vid;
                                list_del(&f->list);
                                kfree(f);
+                               adapter->num_vlan_filters--;
+                               i++;
                                if (i == count)
                                        break;
                        }
@@ -901,7 +906,8 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
                vvfl_v2->vport_id = adapter->vsi_res->vsi_id;
                vvfl_v2->num_elements = count;
                list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
-                       if (f->remove) {
+                       if (f->state == IAVF_VLAN_DISABLE ||
+                           f->state == IAVF_VLAN_REMOVE) {
                                struct virtchnl_vlan_supported_caps *filtering_support =
                                        &adapter->vlan_v2_caps.filtering.filtering_support;
                                struct virtchnl_vlan *vlan;
@@ -915,8 +921,13 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
                                vlan->tci = f->vlan.vid;
                                vlan->tpid = f->vlan.tpid;
 
-                               list_del(&f->list);
-                               kfree(f);
+                               if (f->state == IAVF_VLAN_DISABLE) {
+                                       f->state = IAVF_VLAN_INACTIVE;
+                               } else {
+                                       list_del(&f->list);
+                                       kfree(f);
+                                       adapter->num_vlan_filters--;
+                               }
                                i++;
                                if (i == count)
                                        break;
@@ -2192,7 +2203,7 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
                                list_for_each_entry(vlf,
                                                    &adapter->vlan_filter_list,
                                                    list)
-                                       vlf->add = true;
+                                       vlf->state = IAVF_VLAN_ADD;
 
                                adapter->aq_required |=
                                        IAVF_FLAG_AQ_ADD_VLAN_FILTER;
@@ -2260,7 +2271,7 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
                                list_for_each_entry(vlf,
                                                    &adapter->vlan_filter_list,
                                                    list)
-                                       vlf->add = true;
+                                       vlf->state = IAVF_VLAN_ADD;
 
                                aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;
                        }
@@ -2444,17 +2455,8 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
 
                spin_lock_bh(&adapter->mac_vlan_list_lock);
                list_for_each_entry(f, &adapter->vlan_filter_list, list) {
-                       if (f->is_new_vlan) {
-                               f->is_new_vlan = false;
-                               if (!f->vlan.vid)
-                                       continue;
-                               if (f->vlan.tpid == ETH_P_8021Q)
-                                       set_bit(f->vlan.vid,
-                                               adapter->vsi.active_cvlans);
-                               else
-                                       set_bit(f->vlan.vid,
-                                               adapter->vsi.active_svlans);
-                       }
+                       if (f->state == IAVF_VLAN_IS_NEW)
+                               f->state = IAVF_VLAN_ACTIVE;
                }
                spin_unlock_bh(&adapter->mac_vlan_list_lock);
                }
index b0e29e34240185b3b4aa1d6bc32c74f95adedc4b..e809249500e18b15b4a339289bf7a8fca0bc323c 100644 (file)
@@ -509,6 +509,7 @@ enum ice_pf_flags {
        ICE_FLAG_VF_VLAN_PRUNING,
        ICE_FLAG_LINK_LENIENT_MODE_ENA,
        ICE_FLAG_PLUG_AUX_DEV,
+       ICE_FLAG_UNPLUG_AUX_DEV,
        ICE_FLAG_MTU_CHANGED,
        ICE_FLAG_GNSS,                  /* GNSS successfully initialized */
        ICE_PF_FLAGS_NBITS              /* must be last */
@@ -955,16 +956,11 @@ static inline void ice_set_rdma_cap(struct ice_pf *pf)
  */
 static inline void ice_clear_rdma_cap(struct ice_pf *pf)
 {
-       /* We can directly unplug aux device here only if the flag bit
-        * ICE_FLAG_PLUG_AUX_DEV is not set because ice_unplug_aux_dev()
-        * could race with ice_plug_aux_dev() called from
-        * ice_service_task(). In this case we only clear that bit now and
-        * aux device will be unplugged later once ice_plug_aux_device()
-        * called from ice_service_task() finishes (see ice_service_task()).
+       /* defer unplug to service task to avoid RTNL lock and
+        * clear PLUG bit so that pending plugs don't interfere
         */
-       if (!test_and_clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags))
-               ice_unplug_aux_dev(pf);
-
+       clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags);
+       set_bit(ICE_FLAG_UNPLUG_AUX_DEV, pf->flags);
        clear_bit(ICE_FLAG_RDMA_ENA, pf->flags);
 }
 #endif /* _ICE_H_ */
index c557dfc50aadd4511df9fe73ecb08197664e35fe..396e555023aae06b9e62ef090fa60283f9b27d08 100644 (file)
@@ -1411,7 +1411,7 @@ ice_add_dscp_pfc_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg)
        tlv->ouisubtype = htonl(ouisubtype);
 
        buf[0] = dcbcfg->pfc.pfccap & 0xF;
-       buf[1] = dcbcfg->pfc.pfcena & 0xF;
+       buf[1] = dcbcfg->pfc.pfcena;
 }
 
 /**
index b360bd8f15998b2d5c54df7f11b4f4da00231c14..f86e814354a311b1fb70fe339aa96d153d222508 100644 (file)
@@ -4331,6 +4331,8 @@ ice_get_module_eeprom(struct net_device *netdev,
                 * SFP modules only ever use page 0.
                 */
                if (page == 0 || !(data[0x2] & 0x4)) {
+                       u32 copy_len;
+
                        /* If i2c bus is busy due to slow page change or
                         * link management access, call can fail. This is normal.
                         * So we retry this a few times.
@@ -4354,8 +4356,8 @@ ice_get_module_eeprom(struct net_device *netdev,
                        }
 
                        /* Make sure we have enough room for the new block */
-                       if ((i + SFF_READ_BLOCK_SIZE) < ee->len)
-                               memcpy(data + i, value, SFF_READ_BLOCK_SIZE);
+                       copy_len = min_t(u32, SFF_READ_BLOCK_SIZE, ee->len - i);
+                       memcpy(data + i, value, copy_len);
                }
        }
        return 0;
index 781475480ff2700762b0ab1ce2da2b9c6dac4553..450317dfcca7360cb1acdfca470bd4295d11e3db 100644 (file)
@@ -291,6 +291,7 @@ static void ice_vsi_delete_from_hw(struct ice_vsi *vsi)
        struct ice_vsi_ctx *ctxt;
        int status;
 
+       ice_fltr_remove_all(vsi);
        ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
        if (!ctxt)
                return;
@@ -2126,7 +2127,7 @@ int ice_vsi_cfg_xdp_txqs(struct ice_vsi *vsi)
        ice_for_each_rxq(vsi, i)
                ice_tx_xsk_pool(vsi, i);
 
-       return ret;
+       return 0;
 }
 
 /**
@@ -2693,12 +2694,14 @@ ice_vsi_cfg_def(struct ice_vsi *vsi, struct ice_vsi_cfg_params *params)
                return ret;
 
        /* allocate memory for Tx/Rx ring stat pointers */
-       if (ice_vsi_alloc_stat_arrays(vsi))
+       ret = ice_vsi_alloc_stat_arrays(vsi);
+       if (ret)
                goto unroll_vsi_alloc;
 
        ice_alloc_fd_res(vsi);
 
-       if (ice_vsi_get_qs(vsi)) {
+       ret = ice_vsi_get_qs(vsi);
+       if (ret) {
                dev_err(dev, "Failed to allocate queues. vsi->idx = %d\n",
                        vsi->idx);
                goto unroll_vsi_alloc_stat;
@@ -2811,6 +2814,7 @@ ice_vsi_cfg_def(struct ice_vsi *vsi, struct ice_vsi_cfg_params *params)
                break;
        default:
                /* clean up the resources and exit */
+               ret = -EINVAL;
                goto unroll_vsi_init;
        }
 
@@ -2889,7 +2893,6 @@ void ice_vsi_decfg(struct ice_vsi *vsi)
            !test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags))
                ice_cfg_sw_lldp(vsi, false, false);
 
-       ice_fltr_remove_all(vsi);
        ice_rm_vsi_lan_cfg(vsi->port_info, vsi->idx);
        err = ice_rm_vsi_rdma_cfg(vsi->port_info, vsi->idx);
        if (err)
@@ -3508,10 +3511,10 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags)
                if (vsi_flags & ICE_VSI_FLAG_INIT) {
                        ret = -EIO;
                        goto err_vsi_cfg_tc_lan;
-               } else {
-                       kfree(coalesce);
-                       return ice_schedule_reset(pf, ICE_RESET_PFR);
                }
+
+               kfree(coalesce);
+               return ice_schedule_reset(pf, ICE_RESET_PFR);
        }
 
        ice_vsi_realloc_stat_arrays(vsi, prev_txq, prev_rxq);
@@ -3759,7 +3762,7 @@ int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc)
        dev = ice_pf_to_dev(pf);
        if (vsi->tc_cfg.ena_tc == ena_tc &&
            vsi->mqprio_qopt.mode != TC_MQPRIO_MODE_CHANNEL)
-               return ret;
+               return 0;
 
        ice_for_each_traffic_class(i) {
                /* build bitmap of enabled TCs */
index 567694bf098ba52684899ad593e6df448653a68b..0d8b8c6f9bd35184467df4680f9f5bc42e14760e 100644 (file)
@@ -2316,18 +2316,15 @@ static void ice_service_task(struct work_struct *work)
                }
        }
 
-       if (test_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags)) {
-               /* Plug aux device per request */
-               ice_plug_aux_dev(pf);
+       /* unplug aux dev per request, if an unplug request came in
+        * while processing a plug request, this will handle it
+        */
+       if (test_and_clear_bit(ICE_FLAG_UNPLUG_AUX_DEV, pf->flags))
+               ice_unplug_aux_dev(pf);
 
-               /* Mark plugging as done but check whether unplug was
-                * requested during ice_plug_aux_dev() call
-                * (e.g. from ice_clear_rdma_cap()) and if so then
-                * plug aux device.
-                */
-               if (!test_and_clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags))
-                       ice_unplug_aux_dev(pf);
-       }
+       /* Plug aux device per request */
+       if (test_and_clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags))
+               ice_plug_aux_dev(pf);
 
        if (test_and_clear_bit(ICE_FLAG_MTU_CHANGED, pf->flags)) {
                struct iidc_event *event;
@@ -4644,6 +4641,12 @@ static int ice_start_eth(struct ice_vsi *vsi)
        return err;
 }
 
+static void ice_stop_eth(struct ice_vsi *vsi)
+{
+       ice_fltr_remove_all(vsi);
+       ice_vsi_close(vsi);
+}
+
 static int ice_init_eth(struct ice_pf *pf)
 {
        struct ice_vsi *vsi = ice_get_main_vsi(pf);
@@ -5132,7 +5135,7 @@ void ice_unload(struct ice_pf *pf)
 {
        ice_deinit_features(pf);
        ice_deinit_rdma(pf);
-       ice_vsi_close(ice_get_main_vsi(pf));
+       ice_stop_eth(ice_get_main_vsi(pf));
        ice_vsi_decfg(ice_get_main_vsi(pf));
        ice_deinit_dev(pf);
 }
index 4eca8d195ef04391422120aafcac1277881eda10..b7682de0ae0578c19ac16b9bb373d8d4004f9d9e 100644 (file)
@@ -2788,7 +2788,7 @@ static int
 ice_sched_assoc_vsi_to_agg(struct ice_port_info *pi, u32 agg_id,
                           u16 vsi_handle, unsigned long *tc_bitmap)
 {
-       struct ice_sched_agg_vsi_info *agg_vsi_info, *old_agg_vsi_info = NULL;
+       struct ice_sched_agg_vsi_info *agg_vsi_info, *iter, *old_agg_vsi_info = NULL;
        struct ice_sched_agg_info *agg_info, *old_agg_info;
        struct ice_hw *hw = pi->hw;
        int status = 0;
@@ -2806,11 +2806,13 @@ ice_sched_assoc_vsi_to_agg(struct ice_port_info *pi, u32 agg_id,
        if (old_agg_info && old_agg_info != agg_info) {
                struct ice_sched_agg_vsi_info *vtmp;
 
-               list_for_each_entry_safe(old_agg_vsi_info, vtmp,
+               list_for_each_entry_safe(iter, vtmp,
                                         &old_agg_info->agg_vsi_list,
                                         list_entry)
-                       if (old_agg_vsi_info->vsi_handle == vsi_handle)
+                       if (iter->vsi_handle == vsi_handle) {
+                               old_agg_vsi_info = iter;
                                break;
+                       }
        }
 
        /* check if entry already exist */
index 96a64c25e2ef7f7d796c55bbd46e6a68bc84fd74..0cc05e54a78154307bf7d9ed32f8ce6e4c31be35 100644 (file)
@@ -1341,15 +1341,15 @@ int ice_set_vf_trust(struct net_device *netdev, int vf_id, bool trusted)
        struct ice_vf *vf;
        int ret;
 
+       vf = ice_get_vf_by_id(pf, vf_id);
+       if (!vf)
+               return -EINVAL;
+
        if (ice_is_eswitch_mode_switchdev(pf)) {
                dev_info(ice_pf_to_dev(pf), "Trusted VF is forbidden in switchdev mode\n");
                return -EOPNOTSUPP;
        }
 
-       vf = ice_get_vf_by_id(pf, vf_id);
-       if (!vf)
-               return -EINVAL;
-
        ret = ice_check_vf_ready_for_cfg(vf);
        if (ret)
                goto out_put_vf;
index 61f844d2251235f9f81a0dfd358ae5e944210f06..46b36851af460e2f39e0685f3d7043cda0eec351 100644 (file)
@@ -1780,18 +1780,36 @@ ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
 int
 ice_cfg_rdma_fltr(struct ice_hw *hw, u16 vsi_handle, bool enable)
 {
-       struct ice_vsi_ctx *ctx;
+       struct ice_vsi_ctx *ctx, *cached_ctx;
+       int status;
+
+       cached_ctx = ice_get_vsi_ctx(hw, vsi_handle);
+       if (!cached_ctx)
+               return -ENOENT;
 
-       ctx = ice_get_vsi_ctx(hw, vsi_handle);
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
        if (!ctx)
-               return -EIO;
+               return -ENOMEM;
+
+       ctx->info.q_opt_rss = cached_ctx->info.q_opt_rss;
+       ctx->info.q_opt_tc = cached_ctx->info.q_opt_tc;
+       ctx->info.q_opt_flags = cached_ctx->info.q_opt_flags;
+
+       ctx->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_Q_OPT_VALID);
 
        if (enable)
                ctx->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
        else
                ctx->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
 
-       return ice_update_vsi(hw, vsi_handle, ctx, NULL);
+       status = ice_update_vsi(hw, vsi_handle, ctx, NULL);
+       if (!status) {
+               cached_ctx->info.q_opt_flags = ctx->info.q_opt_flags;
+               cached_ctx->info.valid_sections |= ctx->info.valid_sections;
+       }
+
+       kfree(ctx);
+       return status;
 }
 
 /**
index 6b48cbc049c67178bbecfbfb12683770dada4b07..76f29a5bf8d73d6bc25f376370e17087c59f7f1f 100644 (file)
@@ -1455,8 +1455,8 @@ ice_parse_cls_flower(struct net_device *filter_dev, struct ice_vsi *vsi,
                if (match.mask->vlan_priority) {
                        fltr->flags |= ICE_TC_FLWR_FIELD_VLAN_PRIO;
                        headers->vlan_hdr.vlan_prio =
-                               cpu_to_be16((match.key->vlan_priority <<
-                                            VLAN_PRIO_SHIFT) & VLAN_PRIO_MASK);
+                               be16_encode_bits(match.key->vlan_priority,
+                                                VLAN_PRIO_MASK);
                }
 
                if (match.mask->vlan_tpid)
@@ -1489,8 +1489,8 @@ ice_parse_cls_flower(struct net_device *filter_dev, struct ice_vsi *vsi,
                if (match.mask->vlan_priority) {
                        fltr->flags |= ICE_TC_FLWR_FIELD_CVLAN_PRIO;
                        headers->cvlan_hdr.vlan_prio =
-                               cpu_to_be16((match.key->vlan_priority <<
-                                            VLAN_PRIO_SHIFT) & VLAN_PRIO_MASK);
+                               be16_encode_bits(match.key->vlan_priority,
+                                                VLAN_PRIO_MASK);
                }
        }
 
index dfd22862e926ba28a163c765a6f287ffb9b5e611..4fcf2d07eb853b10be4b5b483b33e0f95db9446a 100644 (file)
@@ -938,6 +938,7 @@ ice_reuse_rx_page(struct ice_rx_ring *rx_ring, struct ice_rx_buf *old_buf)
  * ice_get_rx_buf - Fetch Rx buffer and synchronize data for use
  * @rx_ring: Rx descriptor ring to transact packets on
  * @size: size of buffer to add to skb
+ * @ntc: index of next to clean element
  *
  * This function will pull an Rx buffer from the ring and synchronize it
  * for use by the CPU.
@@ -1026,7 +1027,6 @@ ice_build_skb(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp)
 /**
  * ice_construct_skb - Allocate skb and populate it
  * @rx_ring: Rx descriptor ring to transact packets on
- * @rx_buf: Rx buffer to pull data from
  * @xdp: xdp_buff pointing to the data
  *
  * This function allocates an skb. It then populates it with the page
@@ -1210,6 +1210,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
                                ice_vc_fdir_irq_handler(ctrl_vsi, rx_desc);
                        if (++ntc == cnt)
                                ntc = 0;
+                       rx_ring->first_desc = ntc;
                        continue;
                }
 
index 7bc5aa340c7df746d89e1462716a868e989695df..c8322fb6f2b37f710e3da7119c70d60ef61365e1 100644 (file)
@@ -438,6 +438,7 @@ busy:
  * ice_finalize_xdp_rx - Bump XDP Tx tail and/or flush redirect map
  * @xdp_ring: XDP ring
  * @xdp_res: Result of the receive batch
+ * @first_idx: index to write from caller
  *
  * This function bumps XDP Tx tail and/or flush redirect map, and
  * should be called when a batch of packets has been processed in the
index e6ef6b303222d17a5b15101ec6034738ef4bcb85..daa6a1e894cfc2c2ad056e5f3e24f1133381f97c 100644 (file)
@@ -541,6 +541,87 @@ static void ice_vc_fdir_rem_prof_all(struct ice_vf *vf)
        }
 }
 
+/**
+ * ice_vc_fdir_reset_cnt_all - reset all FDIR counters for this VF FDIR
+ * @fdir: pointer to the VF FDIR structure
+ */
+static void ice_vc_fdir_reset_cnt_all(struct ice_vf_fdir *fdir)
+{
+       enum ice_fltr_ptype flow;
+
+       for (flow = ICE_FLTR_PTYPE_NONF_NONE;
+            flow < ICE_FLTR_PTYPE_MAX; flow++) {
+               fdir->fdir_fltr_cnt[flow][0] = 0;
+               fdir->fdir_fltr_cnt[flow][1] = 0;
+       }
+}
+
+/**
+ * ice_vc_fdir_has_prof_conflict
+ * @vf: pointer to the VF structure
+ * @conf: FDIR configuration for each filter
+ *
+ * Check if @conf has conflicting profile with existing profiles
+ *
+ * Return: true on success, and false on error.
+ */
+static bool
+ice_vc_fdir_has_prof_conflict(struct ice_vf *vf,
+                             struct virtchnl_fdir_fltr_conf *conf)
+{
+       struct ice_fdir_fltr *desc;
+
+       list_for_each_entry(desc, &vf->fdir.fdir_rule_list, fltr_node) {
+               struct virtchnl_fdir_fltr_conf *existing_conf;
+               enum ice_fltr_ptype flow_type_a, flow_type_b;
+               struct ice_fdir_fltr *a, *b;
+
+               existing_conf = to_fltr_conf_from_desc(desc);
+               a = &existing_conf->input;
+               b = &conf->input;
+               flow_type_a = a->flow_type;
+               flow_type_b = b->flow_type;
+
+               /* No need to compare two rules with different tunnel types or
+                * with the same protocol type.
+                */
+               if (existing_conf->ttype != conf->ttype ||
+                   flow_type_a == flow_type_b)
+                       continue;
+
+               switch (flow_type_a) {
+               case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
+               case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
+               case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
+                       if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
+                               return true;
+                       break;
+               case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
+                       if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
+                           flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
+                           flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_SCTP)
+                               return true;
+                       break;
+               case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
+               case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
+               case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
+                       if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_OTHER)
+                               return true;
+                       break;
+               case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
+                       if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_UDP ||
+                           flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_TCP ||
+                           flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_SCTP)
+                               return true;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       return false;
+}
+
 /**
  * ice_vc_fdir_write_flow_prof
  * @vf: pointer to the VF structure
@@ -677,6 +758,13 @@ ice_vc_fdir_config_input_set(struct ice_vf *vf, struct virtchnl_fdir_add *fltr,
        enum ice_fltr_ptype flow;
        int ret;
 
+       ret = ice_vc_fdir_has_prof_conflict(vf, conf);
+       if (ret) {
+               dev_dbg(dev, "Found flow profile conflict for VF %d\n",
+                       vf->vf_id);
+               return ret;
+       }
+
        flow = input->flow_type;
        ret = ice_vc_fdir_alloc_prof(vf, flow);
        if (ret) {
@@ -1798,7 +1886,7 @@ int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg)
                v_ret = VIRTCHNL_STATUS_SUCCESS;
                stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
                dev_dbg(dev, "VF %d: set FDIR context failed\n", vf->vf_id);
-               goto err_free_conf;
+               goto err_rem_entry;
        }
 
        ret = ice_vc_fdir_write_fltr(vf, conf, true, is_tun);
@@ -1807,15 +1895,16 @@ int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg)
                stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
                dev_err(dev, "VF %d: writing FDIR rule failed, ret:%d\n",
                        vf->vf_id, ret);
-               goto err_rem_entry;
+               goto err_clr_irq;
        }
 
 exit:
        kfree(stat);
        return ret;
 
-err_rem_entry:
+err_clr_irq:
        ice_vc_fdir_clear_irq_ctx(vf);
+err_rem_entry:
        ice_vc_fdir_remove_entry(vf, conf, conf->flow_id);
 err_free_conf:
        devm_kfree(dev, conf);
@@ -1924,6 +2013,7 @@ void ice_vf_fdir_init(struct ice_vf *vf)
        spin_lock_init(&fdir->ctx_lock);
        fdir->ctx_irq.flags = 0;
        fdir->ctx_done.flags = 0;
+       ice_vc_fdir_reset_cnt_all(fdir);
 }
 
 /**
index 31565bbafa224f9cf2035f8c6439ed58f7bcd65a..d1e489da7363f26ecfb723fcc75423a8faa1efdd 100644 (file)
@@ -184,8 +184,6 @@ static int ice_qp_dis(struct ice_vsi *vsi, u16 q_idx)
        }
        netif_tx_stop_queue(netdev_get_tx_queue(vsi->netdev, q_idx));
 
-       ice_qvec_dis_irq(vsi, rx_ring, q_vector);
-
        ice_fill_txq_meta(vsi, tx_ring, &txq_meta);
        err = ice_vsi_stop_tx_ring(vsi, ICE_NO_RESET, 0, tx_ring, &txq_meta);
        if (err)
@@ -200,10 +198,11 @@ static int ice_qp_dis(struct ice_vsi *vsi, u16 q_idx)
                if (err)
                        return err;
        }
+       ice_qvec_dis_irq(vsi, rx_ring, q_vector);
+
        err = ice_vsi_ctrl_one_rx_ring(vsi, false, q_idx, true);
        if (err)
                return err;
-       ice_clean_rx_ring(rx_ring);
 
        ice_qvec_toggle_napi(vsi, q_vector, false);
        ice_qp_clean_rings(vsi, q_idx);
index 03bc1e8af575f72a6fd3a97cad6b15c2cf5dad09..274c781b554739fce9a98a551f9dfe4776515c29 100644 (file)
@@ -109,6 +109,7 @@ static void igb_free_all_rx_resources(struct igb_adapter *);
 static void igb_setup_mrqc(struct igb_adapter *);
 static int igb_probe(struct pci_dev *, const struct pci_device_id *);
 static void igb_remove(struct pci_dev *pdev);
+static void igb_init_queue_configuration(struct igb_adapter *adapter);
 static int igb_sw_init(struct igb_adapter *);
 int igb_open(struct net_device *);
 int igb_close(struct net_device *);
@@ -175,9 +176,7 @@ static void igb_nfc_filter_restore(struct igb_adapter *adapter);
 
 #ifdef CONFIG_PCI_IOV
 static int igb_vf_configure(struct igb_adapter *adapter, int vf);
-static int igb_pci_enable_sriov(struct pci_dev *dev, int num_vfs);
-static int igb_disable_sriov(struct pci_dev *dev);
-static int igb_pci_disable_sriov(struct pci_dev *dev);
+static int igb_disable_sriov(struct pci_dev *dev, bool reinit);
 #endif
 
 static int igb_suspend(struct device *);
@@ -3665,7 +3664,7 @@ err_sw_init:
        kfree(adapter->shadow_vfta);
        igb_clear_interrupt_scheme(adapter);
 #ifdef CONFIG_PCI_IOV
-       igb_disable_sriov(pdev);
+       igb_disable_sriov(pdev, false);
 #endif
        pci_iounmap(pdev, adapter->io_addr);
 err_ioremap:
@@ -3679,7 +3678,38 @@ err_dma:
 }
 
 #ifdef CONFIG_PCI_IOV
-static int igb_disable_sriov(struct pci_dev *pdev)
+static int igb_sriov_reinit(struct pci_dev *dev)
+{
+       struct net_device *netdev = pci_get_drvdata(dev);
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct pci_dev *pdev = adapter->pdev;
+
+       rtnl_lock();
+
+       if (netif_running(netdev))
+               igb_close(netdev);
+       else
+               igb_reset(adapter);
+
+       igb_clear_interrupt_scheme(adapter);
+
+       igb_init_queue_configuration(adapter);
+
+       if (igb_init_interrupt_scheme(adapter, true)) {
+               rtnl_unlock();
+               dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
+               return -ENOMEM;
+       }
+
+       if (netif_running(netdev))
+               igb_open(netdev);
+
+       rtnl_unlock();
+
+       return 0;
+}
+
+static int igb_disable_sriov(struct pci_dev *pdev, bool reinit)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct igb_adapter *adapter = netdev_priv(netdev);
@@ -3713,10 +3743,10 @@ static int igb_disable_sriov(struct pci_dev *pdev)
                adapter->flags |= IGB_FLAG_DMAC;
        }
 
-       return 0;
+       return reinit ? igb_sriov_reinit(pdev) : 0;
 }
 
-static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs)
+static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs, bool reinit)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct igb_adapter *adapter = netdev_priv(netdev);
@@ -3781,12 +3811,6 @@ static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs)
                        "Unable to allocate memory for VF MAC filter list\n");
        }
 
-       /* only call pci_enable_sriov() if no VFs are allocated already */
-       if (!old_vfs) {
-               err = pci_enable_sriov(pdev, adapter->vfs_allocated_count);
-               if (err)
-                       goto err_out;
-       }
        dev_info(&pdev->dev, "%d VFs allocated\n",
                 adapter->vfs_allocated_count);
        for (i = 0; i < adapter->vfs_allocated_count; i++)
@@ -3794,6 +3818,17 @@ static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs)
 
        /* DMA Coalescing is not supported in IOV mode. */
        adapter->flags &= ~IGB_FLAG_DMAC;
+
+       if (reinit) {
+               err = igb_sriov_reinit(pdev);
+               if (err)
+                       goto err_out;
+       }
+
+       /* only call pci_enable_sriov() if no VFs are allocated already */
+       if (!old_vfs)
+               err = pci_enable_sriov(pdev, adapter->vfs_allocated_count);
+
        goto out;
 
 err_out:
@@ -3863,9 +3898,7 @@ static void igb_remove(struct pci_dev *pdev)
        igb_release_hw_control(adapter);
 
 #ifdef CONFIG_PCI_IOV
-       rtnl_lock();
-       igb_disable_sriov(pdev);
-       rtnl_unlock();
+       igb_disable_sriov(pdev, false);
 #endif
 
        unregister_netdev(netdev);
@@ -3911,7 +3944,7 @@ static void igb_probe_vfs(struct igb_adapter *adapter)
        igb_reset_interrupt_capability(adapter);
 
        pci_sriov_set_totalvfs(pdev, 7);
-       igb_enable_sriov(pdev, max_vfs);
+       igb_enable_sriov(pdev, max_vfs, false);
 
 #endif /* CONFIG_PCI_IOV */
 }
@@ -9520,71 +9553,17 @@ static void igb_shutdown(struct pci_dev *pdev)
        }
 }
 
-#ifdef CONFIG_PCI_IOV
-static int igb_sriov_reinit(struct pci_dev *dev)
-{
-       struct net_device *netdev = pci_get_drvdata(dev);
-       struct igb_adapter *adapter = netdev_priv(netdev);
-       struct pci_dev *pdev = adapter->pdev;
-
-       rtnl_lock();
-
-       if (netif_running(netdev))
-               igb_close(netdev);
-       else
-               igb_reset(adapter);
-
-       igb_clear_interrupt_scheme(adapter);
-
-       igb_init_queue_configuration(adapter);
-
-       if (igb_init_interrupt_scheme(adapter, true)) {
-               rtnl_unlock();
-               dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
-               return -ENOMEM;
-       }
-
-       if (netif_running(netdev))
-               igb_open(netdev);
-
-       rtnl_unlock();
-
-       return 0;
-}
-
-static int igb_pci_disable_sriov(struct pci_dev *dev)
-{
-       int err = igb_disable_sriov(dev);
-
-       if (!err)
-               err = igb_sriov_reinit(dev);
-
-       return err;
-}
-
-static int igb_pci_enable_sriov(struct pci_dev *dev, int num_vfs)
-{
-       int err = igb_enable_sriov(dev, num_vfs);
-
-       if (err)
-               goto out;
-
-       err = igb_sriov_reinit(dev);
-       if (!err)
-               return num_vfs;
-
-out:
-       return err;
-}
-
-#endif
 static int igb_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
 {
 #ifdef CONFIG_PCI_IOV
-       if (num_vfs == 0)
-               return igb_pci_disable_sriov(dev);
-       else
-               return igb_pci_enable_sriov(dev, num_vfs);
+       int err;
+
+       if (num_vfs == 0) {
+               return igb_disable_sriov(dev, true);
+       } else {
+               err = igb_enable_sriov(dev, num_vfs, true);
+               return err ? err : num_vfs;
+       }
 #endif
        return 0;
 }
index 3a32809510fc6b771c2a350e5bed9aa3a5bb1a48..72cb1b56e9f2400b5408d4a722171ffcb363e4b9 100644 (file)
@@ -1074,7 +1074,7 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter)
                          igbvf_intr_msix_rx, 0, adapter->rx_ring->name,
                          netdev);
        if (err)
-               goto out;
+               goto free_irq_tx;
 
        adapter->rx_ring->itr_register = E1000_EITR(vector);
        adapter->rx_ring->itr_val = adapter->current_itr;
@@ -1083,10 +1083,14 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter)
        err = request_irq(adapter->msix_entries[vector].vector,
                          igbvf_msix_other, 0, netdev->name, netdev);
        if (err)
-               goto out;
+               goto free_irq_rx;
 
        igbvf_configure_msix(adapter);
        return 0;
+free_irq_rx:
+       free_irq(adapter->msix_entries[--vector].vector, netdev);
+free_irq_tx:
+       free_irq(adapter->msix_entries[--vector].vector, netdev);
 out:
        return err;
 }
index b8ba3f94c363229b230d3c8dbe1a882149e6e265..a47a2e3e548cf3f2e5241ca3180e816f7ebb626a 100644 (file)
@@ -1,6 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Copyright(c) 2009 - 2018 Intel Corporation. */
 
+#include <linux/etherdevice.h>
+
 #include "vf.h"
 
 static s32 e1000_check_for_link_vf(struct e1000_hw *hw);
@@ -131,11 +133,16 @@ static s32 e1000_reset_hw_vf(struct e1000_hw *hw)
                /* set our "perm_addr" based on info provided by PF */
                ret_val = mbx->ops.read_posted(hw, msgbuf, 3);
                if (!ret_val) {
-                       if (msgbuf[0] == (E1000_VF_RESET |
-                                         E1000_VT_MSGTYPE_ACK))
+                       switch (msgbuf[0]) {
+                       case E1000_VF_RESET | E1000_VT_MSGTYPE_ACK:
                                memcpy(hw->mac.perm_addr, addr, ETH_ALEN);
-                       else
+                               break;
+                       case E1000_VF_RESET | E1000_VT_MSGTYPE_NACK:
+                               eth_zero_addr(hw->mac.perm_addr);
+                               break;
+                       default:
                                ret_val = -E1000_ERR_MAC_INIT;
+                       }
                }
        }
 
index 2928a6c73692871a225cab659a0c0c5adf99af8b..25fc6c65209bf948887311ab10ae65d02a2b0ae9 100644 (file)
@@ -6010,18 +6010,18 @@ static bool validate_schedule(struct igc_adapter *adapter,
                if (e->command != TC_TAPRIO_CMD_SET_GATES)
                        return false;
 
-               for (i = 0; i < adapter->num_tx_queues; i++) {
-                       if (e->gate_mask & BIT(i))
+               for (i = 0; i < adapter->num_tx_queues; i++)
+                       if (e->gate_mask & BIT(i)) {
                                queue_uses[i]++;
 
-                       /* There are limitations: A single queue cannot be
-                        * opened and closed multiple times per cycle unless the
-                        * gate stays open. Check for it.
-                        */
-                       if (queue_uses[i] > 1 &&
-                           !(prev->gate_mask & BIT(i)))
-                               return false;
-               }
+                               /* There are limitations: A single queue cannot
+                                * be opened and closed multiple times per cycle
+                                * unless the gate stays open. Check for it.
+                                */
+                               if (queue_uses[i] > 1 &&
+                                   !(prev->gate_mask & BIT(i)))
+                                       return false;
+                       }
        }
 
        return true;
index 0e39d199ff06158f3aac6ca1665f25d5304942bc..2cad76d0a50ef6fab802bb929948f1136451084d 100644 (file)
@@ -3549,6 +3549,8 @@ static void mvneta_txq_sw_deinit(struct mvneta_port *pp,
 
        netdev_tx_reset_queue(nq);
 
+       txq->buf               = NULL;
+       txq->tso_hdrs          = NULL;
        txq->descs             = NULL;
        txq->last_desc         = 0;
        txq->next_desc_to_proc = 0;
index 41d935d1aaf6ff075e51b13e065d565a2ced4ae7..40aeaa7bd739fa722ea059968810380a690619ea 100644 (file)
@@ -62,35 +62,38 @@ static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = {
        MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_UNTAG,
                       MVPP22_CLS_HEK_IP4_2T,
                       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4 |
-                      MVPP2_PRS_RI_L4_TCP,
+                      MVPP2_PRS_RI_IP_FRAG_TRUE | MVPP2_PRS_RI_L4_TCP,
                       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
 
        MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_UNTAG,
                       MVPP22_CLS_HEK_IP4_2T,
                       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4_OPT |
-                      MVPP2_PRS_RI_L4_TCP,
+                      MVPP2_PRS_RI_IP_FRAG_TRUE | MVPP2_PRS_RI_L4_TCP,
                       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
 
        MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_UNTAG,
                       MVPP22_CLS_HEK_IP4_2T,
                       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4_OTHER |
-                      MVPP2_PRS_RI_L4_TCP,
+                      MVPP2_PRS_RI_IP_FRAG_TRUE | MVPP2_PRS_RI_L4_TCP,
                       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
 
        /* TCP over IPv4 flows, fragmented, with vlan tag */
        MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_TAG,
                       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,
-                      MVPP2_PRS_RI_L3_IP4 | MVPP2_PRS_RI_L4_TCP,
+                      MVPP2_PRS_RI_L3_IP4 | MVPP2_PRS_RI_IP_FRAG_TRUE |
+                          MVPP2_PRS_RI_L4_TCP,
                       MVPP2_PRS_IP_MASK),
 
        MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_TAG,
                       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,
-                      MVPP2_PRS_RI_L3_IP4_OPT | MVPP2_PRS_RI_L4_TCP,
+                      MVPP2_PRS_RI_L3_IP4_OPT | MVPP2_PRS_RI_IP_FRAG_TRUE |
+                          MVPP2_PRS_RI_L4_TCP,
                       MVPP2_PRS_IP_MASK),
 
        MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_TAG,
                       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,
-                      MVPP2_PRS_RI_L3_IP4_OTHER | MVPP2_PRS_RI_L4_TCP,
+                      MVPP2_PRS_RI_L3_IP4_OTHER | MVPP2_PRS_RI_IP_FRAG_TRUE |
+                          MVPP2_PRS_RI_L4_TCP,
                       MVPP2_PRS_IP_MASK),
 
        /* UDP over IPv4 flows, Not fragmented, no vlan tag */
@@ -132,35 +135,38 @@ static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = {
        MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_UNTAG,
                       MVPP22_CLS_HEK_IP4_2T,
                       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4 |
-                      MVPP2_PRS_RI_L4_UDP,
+                      MVPP2_PRS_RI_IP_FRAG_TRUE | MVPP2_PRS_RI_L4_UDP,
                       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
 
        MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_UNTAG,
                       MVPP22_CLS_HEK_IP4_2T,
                       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4_OPT |
-                      MVPP2_PRS_RI_L4_UDP,
+                      MVPP2_PRS_RI_IP_FRAG_TRUE | MVPP2_PRS_RI_L4_UDP,
                       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
 
        MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_UNTAG,
                       MVPP22_CLS_HEK_IP4_2T,
                       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4_OTHER |
-                      MVPP2_PRS_RI_L4_UDP,
+                      MVPP2_PRS_RI_IP_FRAG_TRUE | MVPP2_PRS_RI_L4_UDP,
                       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
 
        /* UDP over IPv4 flows, fragmented, with vlan tag */
        MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_TAG,
                       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,
-                      MVPP2_PRS_RI_L3_IP4 | MVPP2_PRS_RI_L4_UDP,
+                      MVPP2_PRS_RI_L3_IP4 | MVPP2_PRS_RI_IP_FRAG_TRUE |
+                          MVPP2_PRS_RI_L4_UDP,
                       MVPP2_PRS_IP_MASK),
 
        MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_TAG,
                       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,
-                      MVPP2_PRS_RI_L3_IP4_OPT | MVPP2_PRS_RI_L4_UDP,
+                      MVPP2_PRS_RI_L3_IP4_OPT | MVPP2_PRS_RI_IP_FRAG_TRUE |
+                          MVPP2_PRS_RI_L4_UDP,
                       MVPP2_PRS_IP_MASK),
 
        MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_TAG,
                       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,
-                      MVPP2_PRS_RI_L3_IP4_OTHER | MVPP2_PRS_RI_L4_UDP,
+                      MVPP2_PRS_RI_L3_IP4_OTHER | MVPP2_PRS_RI_IP_FRAG_TRUE |
+                          MVPP2_PRS_RI_L4_UDP,
                       MVPP2_PRS_IP_MASK),
 
        /* TCP over IPv6 flows, not fragmented, no vlan tag */
index 9b4ecbe4f36d41b3855b70243de9e4a4994b0ea7..3ea00bc9b91caf1fcf293e11448281f48fe3edee 100644 (file)
@@ -4996,6 +4996,14 @@ static int mvpp2_bm_switch_buffers(struct mvpp2 *priv, bool percpu)
 
        for (i = 0; i < priv->port_count; i++) {
                port = priv->port_list[i];
+               if (percpu && port->ntxqs >= num_possible_cpus() * 2)
+                       xdp_set_features_flag(port->dev,
+                                             NETDEV_XDP_ACT_BASIC |
+                                             NETDEV_XDP_ACT_REDIRECT |
+                                             NETDEV_XDP_ACT_NDO_XMIT);
+               else
+                       xdp_clear_features_flag(port->dev);
+
                mvpp2_swf_bm_pool_init(port);
                if (status[i])
                        mvpp2_open(port->dev);
@@ -6863,13 +6871,14 @@ static int mvpp2_port_probe(struct platform_device *pdev,
 
        if (!port->priv->percpu_pools)
                mvpp2_set_hw_csum(port, port->pool_long->id);
+       else if (port->ntxqs >= num_possible_cpus() * 2)
+               dev->xdp_features = NETDEV_XDP_ACT_BASIC |
+                                   NETDEV_XDP_ACT_REDIRECT |
+                                   NETDEV_XDP_ACT_NDO_XMIT;
 
        dev->vlan_features |= features;
        netif_set_tso_max_segs(dev, MVPP2_MAX_TSO_SEGS);
 
-       dev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
-                           NETDEV_XDP_ACT_NDO_XMIT;
-
        dev->priv_flags |= IFF_UNICAST_FLT;
 
        /* MTU range: 68 - 9704 */
index 75ba57bd1d46d85f163c3568f45b0f3708474d7f..9af22f497a40f50ea275af75d165a1635a14f65c 100644 (file)
@@ -1539,8 +1539,8 @@ static int mvpp2_prs_vlan_init(struct platform_device *pdev, struct mvpp2 *priv)
        if (!priv->prs_double_vlans)
                return -ENOMEM;
 
-       /* Double VLAN: 0x8100, 0x88A8 */
-       err = mvpp2_prs_double_vlan_add(priv, ETH_P_8021Q, ETH_P_8021AD,
+       /* Double VLAN: 0x88A8, 0x8100 */
+       err = mvpp2_prs_double_vlan_add(priv, ETH_P_8021AD, ETH_P_8021Q,
                                        MVPP2_PRS_PORT_MASK);
        if (err)
                return err;
@@ -1607,59 +1607,45 @@ static int mvpp2_prs_vlan_init(struct platform_device *pdev, struct mvpp2 *priv)
 static int mvpp2_prs_pppoe_init(struct mvpp2 *priv)
 {
        struct mvpp2_prs_entry pe;
-       int tid;
-
-       /* IPv4 over PPPoE with options */
-       tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
-                                       MVPP2_PE_LAST_FREE_TID);
-       if (tid < 0)
-               return tid;
-
-       memset(&pe, 0, sizeof(pe));
-       mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_PPPOE);
-       pe.index = tid;
-
-       mvpp2_prs_match_etype(&pe, 0, PPP_IP);
-
-       mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4);
-       mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4_OPT,
-                                MVPP2_PRS_RI_L3_PROTO_MASK);
-       /* goto ipv4 dest-address (skip eth_type + IP-header-size - 4) */
-       mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN +
-                                sizeof(struct iphdr) - 4,
-                                MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
-       /* Set L3 offset */
-       mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
-                                 MVPP2_ETH_TYPE_LEN,
-                                 MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
-
-       /* Update shadow table and hw entry */
-       mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_PPPOE);
-       mvpp2_prs_hw_write(priv, &pe);
+       int tid, ihl;
 
-       /* IPv4 over PPPoE without options */
-       tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
-                                       MVPP2_PE_LAST_FREE_TID);
-       if (tid < 0)
-               return tid;
+       /* IPv4 over PPPoE with header length >= 5 */
+       for (ihl = MVPP2_PRS_IPV4_IHL_MIN; ihl <= MVPP2_PRS_IPV4_IHL_MAX; ihl++) {
+               tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+                                               MVPP2_PE_LAST_FREE_TID);
+               if (tid < 0)
+                       return tid;
 
-       pe.index = tid;
+               memset(&pe, 0, sizeof(pe));
+               mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_PPPOE);
+               pe.index = tid;
 
-       mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN,
-                                    MVPP2_PRS_IPV4_HEAD |
-                                    MVPP2_PRS_IPV4_IHL_MIN,
-                                    MVPP2_PRS_IPV4_HEAD_MASK |
-                                    MVPP2_PRS_IPV4_IHL_MASK);
+               mvpp2_prs_match_etype(&pe, 0, PPP_IP);
+               mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN,
+                                            MVPP2_PRS_IPV4_HEAD | ihl,
+                                            MVPP2_PRS_IPV4_HEAD_MASK |
+                                            MVPP2_PRS_IPV4_IHL_MASK);
 
-       /* Clear ri before updating */
-       pe.sram[MVPP2_PRS_SRAM_RI_WORD] = 0x0;
-       pe.sram[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0;
-       mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4,
-                                MVPP2_PRS_RI_L3_PROTO_MASK);
+               mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4);
+               mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4,
+                                        MVPP2_PRS_RI_L3_PROTO_MASK);
+               /* goto ipv4 dst-address (skip eth_type + IP-header-size - 4) */
+               mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN +
+                                        sizeof(struct iphdr) - 4,
+                                        MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+               /* Set L3 offset */
+               mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
+                                         MVPP2_ETH_TYPE_LEN,
+                                         MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+               /* Set L4 offset */
+               mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4,
+                                         MVPP2_ETH_TYPE_LEN + (ihl * 4),
+                                         MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
 
-       /* Update shadow table and hw entry */
-       mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_PPPOE);
-       mvpp2_prs_hw_write(priv, &pe);
+               /* Update shadow table and hw entry */
+               mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_PPPOE);
+               mvpp2_prs_hw_write(priv, &pe);
+       }
 
        /* IPv6 over PPPoE */
        tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
index 389663a13d1d1536a7c0f40267896e1951ef8959..ef721caeac49b1b9872cdf2aebbdc67515c9ad6d 100644 (file)
@@ -884,6 +884,9 @@ int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int lf,
 int rvu_cpt_ctx_flush(struct rvu *rvu, u16 pcifunc);
 int rvu_cpt_init(struct rvu *rvu);
 
+#define NDC_AF_BANK_MASK       GENMASK_ULL(7, 0)
+#define NDC_AF_BANK_LINE_MASK  GENMASK_ULL(31, 16)
+
 /* CN10K RVU */
 int rvu_set_channels_base(struct rvu *rvu);
 void rvu_program_channels(struct rvu *rvu);
@@ -902,6 +905,8 @@ static inline void rvu_dbg_init(struct rvu *rvu) {}
 static inline void rvu_dbg_exit(struct rvu *rvu) {}
 #endif
 
+int rvu_ndc_fix_locked_cacheline(struct rvu *rvu, int blkaddr);
+
 /* RVU Switch */
 void rvu_switch_enable(struct rvu *rvu);
 void rvu_switch_disable(struct rvu *rvu);
index fa280ebd3052b8ddd6bc7fe90a417f48643af6e7..26cfa501f1a112dd166b4260faeccd0cc65d1b17 100644 (file)
@@ -198,9 +198,6 @@ enum cpt_eng_type {
        CPT_IE_TYPE = 3,
 };
 
-#define NDC_MAX_BANK(rvu, blk_addr) (rvu_read64(rvu, \
-                                               blk_addr, NDC_AF_CONST) & 0xFF)
-
 #define rvu_dbg_NULL NULL
 #define rvu_dbg_open_NULL NULL
 
@@ -1448,6 +1445,7 @@ static int ndc_blk_hits_miss_stats(struct seq_file *s, int idx, int blk_addr)
        struct nix_hw *nix_hw;
        struct rvu *rvu;
        int bank, max_bank;
+       u64 ndc_af_const;
 
        if (blk_addr == BLKADDR_NDC_NPA0) {
                rvu = s->private;
@@ -1456,7 +1454,8 @@ static int ndc_blk_hits_miss_stats(struct seq_file *s, int idx, int blk_addr)
                rvu = nix_hw->rvu;
        }
 
-       max_bank = NDC_MAX_BANK(rvu, blk_addr);
+       ndc_af_const = rvu_read64(rvu, blk_addr, NDC_AF_CONST);
+       max_bank = FIELD_GET(NDC_AF_BANK_MASK, ndc_af_const);
        for (bank = 0; bank < max_bank; bank++) {
                seq_printf(s, "BANK:%d\n", bank);
                seq_printf(s, "\tHits:\t%lld\n",
index 26e639e57dae372d530009e8f46e87ff8977214e..4ad707e758b9f700cd675f0f093b59f5b088779d 100644 (file)
@@ -790,6 +790,7 @@ static int nix_aq_enqueue_wait(struct rvu *rvu, struct rvu_block *block,
        struct nix_aq_res_s *result;
        int timeout = 1000;
        u64 reg, head;
+       int ret;
 
        result = (struct nix_aq_res_s *)aq->res->base;
 
@@ -813,9 +814,22 @@ static int nix_aq_enqueue_wait(struct rvu *rvu, struct rvu_block *block,
                        return -EBUSY;
        }
 
-       if (result->compcode != NIX_AQ_COMP_GOOD)
+       if (result->compcode != NIX_AQ_COMP_GOOD) {
                /* TODO: Replace this with some error code */
+               if (result->compcode == NIX_AQ_COMP_CTX_FAULT ||
+                   result->compcode == NIX_AQ_COMP_LOCKERR ||
+                   result->compcode == NIX_AQ_COMP_CTX_POISON) {
+                       ret = rvu_ndc_fix_locked_cacheline(rvu, BLKADDR_NDC_NIX0_RX);
+                       ret |= rvu_ndc_fix_locked_cacheline(rvu, BLKADDR_NDC_NIX0_TX);
+                       ret |= rvu_ndc_fix_locked_cacheline(rvu, BLKADDR_NDC_NIX1_RX);
+                       ret |= rvu_ndc_fix_locked_cacheline(rvu, BLKADDR_NDC_NIX1_TX);
+                       if (ret)
+                               dev_err(rvu->dev,
+                                       "%s: Not able to unlock cachelines\n", __func__);
+               }
+
                return -EBUSY;
+       }
 
        return 0;
 }
index 70bd036ed76e42f184775fe7a5556ea0ead0dc66..4f5ca5ab13a40640578aed38f6ef1eea59609f56 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 2018 Marvell.
  *
  */
-
+#include <linux/bitfield.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 
@@ -42,9 +42,18 @@ static int npa_aq_enqueue_wait(struct rvu *rvu, struct rvu_block *block,
                        return -EBUSY;
        }
 
-       if (result->compcode != NPA_AQ_COMP_GOOD)
+       if (result->compcode != NPA_AQ_COMP_GOOD) {
                /* TODO: Replace this with some error code */
+               if (result->compcode == NPA_AQ_COMP_CTX_FAULT ||
+                   result->compcode == NPA_AQ_COMP_LOCKERR ||
+                   result->compcode == NPA_AQ_COMP_CTX_POISON) {
+                       if (rvu_ndc_fix_locked_cacheline(rvu, BLKADDR_NDC_NPA0))
+                               dev_err(rvu->dev,
+                                       "%s: Not able to unlock cachelines\n", __func__);
+               }
+
                return -EBUSY;
+       }
 
        return 0;
 }
@@ -545,3 +554,48 @@ void rvu_npa_lf_teardown(struct rvu *rvu, u16 pcifunc, int npalf)
 
        npa_ctx_free(rvu, pfvf);
 }
+
+/* Due to an Hardware errata, in some corner cases, AQ context lock
+ * operations can result in a NDC way getting into an illegal state
+ * of not valid but locked.
+ *
+ * This API solves the problem by clearing the lock bit of the NDC block.
+ * The operation needs to be done for each line of all the NDC banks.
+ */
+int rvu_ndc_fix_locked_cacheline(struct rvu *rvu, int blkaddr)
+{
+       int bank, max_bank, line, max_line, err;
+       u64 reg, ndc_af_const;
+
+       /* Set the ENABLE bit(63) to '0' */
+       reg = rvu_read64(rvu, blkaddr, NDC_AF_CAMS_RD_INTERVAL);
+       rvu_write64(rvu, blkaddr, NDC_AF_CAMS_RD_INTERVAL, reg & GENMASK_ULL(62, 0));
+
+       /* Poll until the BUSY bits(47:32) are set to '0' */
+       err = rvu_poll_reg(rvu, blkaddr, NDC_AF_CAMS_RD_INTERVAL, GENMASK_ULL(47, 32), true);
+       if (err) {
+               dev_err(rvu->dev, "Timed out while polling for NDC CAM busy bits.\n");
+               return err;
+       }
+
+       ndc_af_const = rvu_read64(rvu, blkaddr, NDC_AF_CONST);
+       max_bank = FIELD_GET(NDC_AF_BANK_MASK, ndc_af_const);
+       max_line = FIELD_GET(NDC_AF_BANK_LINE_MASK, ndc_af_const);
+       for (bank = 0; bank < max_bank; bank++) {
+               for (line = 0; line < max_line; line++) {
+                       /* Check if 'cache line valid bit(63)' is not set
+                        * but 'cache line lock bit(60)' is set and on
+                        * success, reset the lock bit(60).
+                        */
+                       reg = rvu_read64(rvu, blkaddr,
+                                        NDC_AF_BANKX_LINEX_METADATA(bank, line));
+                       if (!(reg & BIT_ULL(63)) && (reg & BIT_ULL(60))) {
+                               rvu_write64(rvu, blkaddr,
+                                           NDC_AF_BANKX_LINEX_METADATA(bank, line),
+                                           reg & ~BIT_ULL(60));
+                       }
+               }
+       }
+
+       return 0;
+}
index 1729b22580ce1cd595290bc2ca7918a68d3a0332..7007f0b8e6591ab89a8871aff8fe5a49e80c1241 100644 (file)
 #define NDC_AF_INTR_ENA_W1S            (0x00068)
 #define NDC_AF_INTR_ENA_W1C            (0x00070)
 #define NDC_AF_ACTIVE_PC               (0x00078)
+#define NDC_AF_CAMS_RD_INTERVAL                (0x00080)
 #define NDC_AF_BP_TEST_ENABLE          (0x001F8)
 #define NDC_AF_BP_TEST(a)              (0x00200 | (a) << 3)
 #define NDC_AF_BLK_RST                 (0x002F0)
                (0x00F00 | (a) << 5 | (b) << 4)
 #define NDC_AF_BANKX_HIT_PC(a)         (0x01000 | (a) << 3)
 #define NDC_AF_BANKX_MISS_PC(a)                (0x01100 | (a) << 3)
+#define NDC_AF_BANKX_LINEX_METADATA(a, b) \
+               (0x10000 | (a) << 12 | (b) << 3)
 
 /* LBK */
 #define LBK_CONST                      (0x10ull)
index 7f8ffbf79cf742905b2d6e5cfbd426a18b8f7bd8..ab126f8706c7491b1aee2e22c366ee1cb63ed1a2 100644 (file)
@@ -709,6 +709,7 @@ err_unreg_netdev:
 err_ptp_destroy:
        otx2_ptp_destroy(vf);
 err_detach_rsrc:
+       free_percpu(vf->hw.lmt_info);
        if (test_bit(CN10K_LMTST, &vf->hw.cap_flag))
                qmem_free(vf->dev, vf->dync_lmt);
        otx2_detach_resources(&vf->mbox);
@@ -762,6 +763,7 @@ static void otx2vf_remove(struct pci_dev *pdev)
        otx2_shutdown_tc(vf);
        otx2vf_disable_mbox_intr(vf);
        otx2_detach_resources(&vf->mbox);
+       free_percpu(vf->hw.lmt_info);
        if (test_bit(CN10K_LMTST, &vf->hw.cap_flag))
                qmem_free(vf->dev, vf->dync_lmt);
        otx2vf_vfaf_mbox_destroy(vf);
index 14be6ea51b889f070874dafe3888afdff5b40290..e14050e178624752c8c15f1f8e3a0347f40d4092 100644 (file)
@@ -616,7 +616,8 @@ static int mtk_mac_finish(struct phylink_config *config, unsigned int mode,
        mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
        mcr_new = mcr_cur;
        mcr_new |= MAC_MCR_IPG_CFG | MAC_MCR_FORCE_MODE |
-                  MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_LINK;
+                  MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_LINK |
+                  MAC_MCR_RX_FIFO_CLR_DIS;
 
        /* Only update control register when needed! */
        if (mcr_new != mcr_cur)
@@ -752,6 +753,7 @@ static void mtk_mac_link_up(struct phylink_config *config,
                 MAC_MCR_FORCE_RX_FC);
 
        /* Configure speed */
+       mac->speed = speed;
        switch (speed) {
        case SPEED_2500:
        case SPEED_1000:
@@ -762,8 +764,6 @@ static void mtk_mac_link_up(struct phylink_config *config,
                break;
        }
 
-       mtk_set_queue_speed(mac->hw, mac->id, speed);
-
        /* Configure duplex */
        if (duplex == DUPLEX_FULL)
                mcr |= MAC_MCR_FORCE_DPX;
@@ -2058,9 +2058,6 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
                        skb_checksum_none_assert(skb);
                skb->protocol = eth_type_trans(skb, netdev);
 
-               if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
-                       mtk_ppe_check_skb(eth->ppe[0], skb, hash);
-
                if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
                        if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
                                if (trxd.rxd3 & RX_DMA_VTAG_V2) {
@@ -2088,6 +2085,9 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
                        __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan_tci);
                }
 
+               if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
+                       mtk_ppe_check_skb(eth->ppe[0], skb, hash);
+
                skb_record_rx_queue(skb, 0);
                napi_gro_receive(napi, skb);
 
@@ -3236,6 +3236,9 @@ found:
        if (dp->index >= MTK_QDMA_NUM_QUEUES)
                return NOTIFY_DONE;
 
+       if (mac->speed > 0 && mac->speed <= s.base.speed)
+               s.base.speed = 0;
+
        mtk_set_queue_speed(eth, dp->index + 3, s.base.speed);
 
        return NOTIFY_DONE;
index afc9d52e79bfc673dbd7006807226771025a5304..084a6badef6d9b4973a7413f474c6f9b68e31fb3 100644 (file)
 #define MAC_MCR_FORCE_MODE     BIT(15)
 #define MAC_MCR_TX_EN          BIT(14)
 #define MAC_MCR_RX_EN          BIT(13)
+#define MAC_MCR_RX_FIFO_CLR_DIS        BIT(12)
 #define MAC_MCR_BACKOFF_EN     BIT(9)
 #define MAC_MCR_BACKPR_EN      BIT(8)
 #define MAC_MCR_FORCE_RX_FC    BIT(5)
 #define SGMII_SEND_AN_ERROR_EN         BIT(11)
 #define SGMII_IF_MODE_MASK             GENMASK(5, 1)
 
+/* Register to reset SGMII design */
+#define SGMII_RESERVED_0       0x34
+#define SGMII_SW_RESET         BIT(0)
+
 /* Register to set SGMII speed, ANA RG_ Control Signals III*/
 #define SGMSYS_ANA_RG_CS3      0x2028
 #define RG_PHY_SPEED_MASK      (BIT(2) | BIT(3))
index 6883eb34cd8b437864b3e00575dad2afbc2972b5..fd07d6e142733445d9c5e398af2f258796a91e53 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/platform_device.h>
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
+#include <net/dst_metadata.h>
 #include <net/dsa.h>
 #include "mtk_eth_soc.h"
 #include "mtk_ppe.h"
@@ -458,6 +459,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
                hwe->ib1 &= ~MTK_FOE_IB1_STATE;
                hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
                dma_wmb();
+               mtk_ppe_cache_clear(ppe);
        }
        entry->hash = 0xffff;
 
@@ -699,7 +701,9 @@ void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
                    skb->dev->dsa_ptr->tag_ops->proto != DSA_TAG_PROTO_MTK)
                        goto out;
 
-               tag += 4;
+               if (!skb_metadata_dst(skb))
+                       tag += 4;
+
                if (get_unaligned_be16(tag) != ETH_P_8021Q)
                        break;
 
index 81afd5ee3fbf171fde7b76310ae7126f9f8d3daa..161751bb36c9c5736a7f4c1bc4883d780f6b04e8 100644 (file)
@@ -576,6 +576,7 @@ mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f)
                if (IS_ERR(block_cb))
                        return PTR_ERR(block_cb);
 
+               flow_block_cb_incref(block_cb);
                flow_block_cb_add(block_cb, f);
                list_add_tail(&block_cb->driver_list, &block_cb_list);
                return 0;
@@ -584,7 +585,7 @@ mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f)
                if (!block_cb)
                        return -ENOENT;
 
-               if (flow_block_cb_decref(block_cb)) {
+               if (!flow_block_cb_decref(block_cb)) {
                        flow_block_cb_remove(block_cb, f);
                        list_del(&block_cb->driver_list);
                }
index bb00de1003ac4355808b6805b3221270a7bfb909..83976dc86887589488e9769a4e7fc1f582523609 100644 (file)
@@ -38,20 +38,16 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
                          const unsigned long *advertising,
                          bool permit_pause_to_mac)
 {
+       bool mode_changed = false, changed, use_an;
        struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
        unsigned int rgc3, sgm_mode, bmcr;
        int advertise, link_timer;
-       bool changed, use_an;
 
        advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
                                                             advertising);
        if (advertise < 0)
                return advertise;
 
-       link_timer = phylink_get_link_timer_ns(interface);
-       if (link_timer < 0)
-               return link_timer;
-
        /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
         * we assume that fixes it's speed at bitrate = line rate (in
         * other words, 1000Mbps or 2500Mbps).
@@ -77,17 +73,24 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
        }
 
        if (use_an) {
-               /* FIXME: Do we need to set AN_RESTART here? */
-               bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE;
+               bmcr = SGMII_AN_ENABLE;
        } else {
                bmcr = 0;
        }
 
        if (mpcs->interface != interface) {
+               link_timer = phylink_get_link_timer_ns(interface);
+               if (link_timer < 0)
+                       return link_timer;
+
                /* PHYA power down */
                regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
                                   SGMII_PHYA_PWD, SGMII_PHYA_PWD);
 
+               /* Reset SGMII PCS state */
+               regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
+                                  SGMII_SW_RESET, SGMII_SW_RESET);
+
                if (interface == PHY_INTERFACE_MODE_2500BASEX)
                        rgc3 = RG_PHY_SPEED_3_125G;
                else
@@ -97,16 +100,17 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
                regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
                                   RG_PHY_SPEED_3_125G, rgc3);
 
+               /* Setup the link timer */
+               regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
+
                mpcs->interface = interface;
+               mode_changed = true;
        }
 
        /* Update the advertisement, noting whether it has changed */
        regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
                                 SGMII_ADVERTISE, advertise, &changed);
 
-       /* Setup the link timer and QPHY power up inside SGMIISYS */
-       regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
-
        /* Update the sgmsys mode register */
        regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
                           SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
@@ -114,7 +118,7 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
 
        /* Update the BMCR */
        regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-                          SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
+                          SGMII_AN_ENABLE, bmcr);
 
        /* Release PHYA power down state
         * Only removing bit SGMII_PHYA_PWD isn't enough.
@@ -128,7 +132,7 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
        usleep_range(50, 100);
        regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
 
-       return changed;
+       return changed || mode_changed;
 }
 
 static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
index 0869d4fff17b1aa49dff0d4a6b21a8868afbd30d..332472fe49902e3f5ee17faf8ca4b5bcd2ac4cf7 100644 (file)
@@ -674,21 +674,39 @@ int mlx4_en_xdp_rx_timestamp(const struct xdp_md *ctx, u64 *timestamp)
        struct mlx4_en_xdp_buff *_ctx = (void *)ctx;
 
        if (unlikely(_ctx->ring->hwtstamp_rx_filter != HWTSTAMP_FILTER_ALL))
-               return -EOPNOTSUPP;
+               return -ENODATA;
 
        *timestamp = mlx4_en_get_hwtstamp(_ctx->mdev,
                                          mlx4_en_get_cqe_ts(_ctx->cqe));
        return 0;
 }
 
-int mlx4_en_xdp_rx_hash(const struct xdp_md *ctx, u32 *hash)
+int mlx4_en_xdp_rx_hash(const struct xdp_md *ctx, u32 *hash,
+                       enum xdp_rss_hash_type *rss_type)
 {
        struct mlx4_en_xdp_buff *_ctx = (void *)ctx;
+       struct mlx4_cqe *cqe = _ctx->cqe;
+       enum xdp_rss_hash_type xht = 0;
+       __be16 status;
 
        if (unlikely(!(_ctx->dev->features & NETIF_F_RXHASH)))
-               return -EOPNOTSUPP;
+               return -ENODATA;
+
+       *hash = be32_to_cpu(cqe->immed_rss_invalid);
+       status = cqe->status;
+       if (status & cpu_to_be16(MLX4_CQE_STATUS_TCP))
+               xht = XDP_RSS_L4_TCP;
+       if (status & cpu_to_be16(MLX4_CQE_STATUS_UDP))
+               xht = XDP_RSS_L4_UDP;
+       if (status & cpu_to_be16(MLX4_CQE_STATUS_IPV4 | MLX4_CQE_STATUS_IPV4F))
+               xht |= XDP_RSS_L3_IPV4;
+       if (status & cpu_to_be16(MLX4_CQE_STATUS_IPV6)) {
+               xht |= XDP_RSS_L3_IPV6;
+               if (cqe->ipv6_ext_mask)
+                       xht |= XDP_RSS_L3_DYNHDR;
+       }
+       *rss_type = xht;
 
-       *hash = be32_to_cpu(_ctx->cqe->immed_rss_invalid);
        return 0;
 }
 
index 544e09b97483cb4a09ff8957f12e35001c802d77..4ac4d883047b1c7b12317c62e705382c7e4d2d12 100644 (file)
@@ -798,7 +798,8 @@ int mlx4_en_netdev_event(struct notifier_block *this,
 
 struct xdp_md;
 int mlx4_en_xdp_rx_timestamp(const struct xdp_md *ctx, u64 *timestamp);
-int mlx4_en_xdp_rx_hash(const struct xdp_md *ctx, u32 *hash);
+int mlx4_en_xdp_rx_hash(const struct xdp_md *ctx, u32 *hash,
+                       enum xdp_rss_hash_type *rss_type);
 
 /*
  * Functions for time stamping
index 445fe30c3d0bc5aa149f366408cea2bd9fc23497..2e7806001fdc5fad2a86987877863eb35d479dad 100644 (file)
@@ -59,9 +59,6 @@ bool mlx5_eth_supported(struct mlx5_core_dev *dev)
        if (!IS_ENABLED(CONFIG_MLX5_CORE_EN))
                return false;
 
-       if (mlx5_core_is_management_pf(dev))
-               return false;
-
        if (MLX5_CAP_GEN(dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
                return false;
 
@@ -201,9 +198,6 @@ bool mlx5_rdma_supported(struct mlx5_core_dev *dev)
        if (!IS_ENABLED(CONFIG_MLX5_INFINIBAND))
                return false;
 
-       if (mlx5_core_is_management_pf(dev))
-               return false;
-
        if (dev->priv.flags & MLX5_PRIV_FLAGS_DISABLE_IB_ADEV)
                return false;
 
index 7c9c4e40c019b027e094091a1dff19830747873e..d000236ddbac5a0a4384bd4b8b1149db449f1da1 100644 (file)
@@ -75,10 +75,6 @@ int mlx5_ec_init(struct mlx5_core_dev *dev)
        if (!mlx5_core_is_ecpf(dev))
                return 0;
 
-       /* Management PF don't have a peer PF */
-       if (mlx5_core_is_management_pf(dev))
-               return 0;
-
        return mlx5_host_pf_init(dev);
 }
 
@@ -89,10 +85,6 @@ void mlx5_ec_cleanup(struct mlx5_core_dev *dev)
        if (!mlx5_core_is_ecpf(dev))
                return;
 
-       /* Management PF don't have a peer PF */
-       if (mlx5_core_is_management_pf(dev))
-               return;
-
        mlx5_host_pf_cleanup(dev);
 
        err = mlx5_wait_for_pages(dev, &dev->priv.page_counters[MLX5_HOST_PF]);
index 88460b7796e5574176a1e4f229cd0541050ac02d..4a19ef4a9811066988897c632e19e37e45d38b2e 100644 (file)
@@ -313,7 +313,6 @@ struct mlx5e_params {
                } channel;
        } mqprio;
        bool rx_cqe_compress_def;
-       bool tunneled_offload_en;
        struct dim_cq_moder rx_cq_moderation;
        struct dim_cq_moder tx_cq_moderation;
        struct mlx5e_packet_merge_param packet_merge;
@@ -1243,6 +1242,7 @@ void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16
 void mlx5e_rx_dim_work(struct work_struct *work);
 void mlx5e_tx_dim_work(struct work_struct *work);
 
+void mlx5e_set_xdp_feature(struct net_device *netdev);
 netdev_features_t mlx5e_features_check(struct sk_buff *skb,
                                       struct net_device *netdev,
                                       netdev_features_t features);
index c4378afdec09e43c02813e3a2f88ccc93170e56e..1bd1c94fb977669ee01600feff6091247fcafbc7 100644 (file)
@@ -178,7 +178,6 @@ tc_act_police_stats(struct mlx5e_priv *priv,
        meter = mlx5e_tc_meter_get(priv->mdev, &params);
        if (IS_ERR(meter)) {
                NL_SET_ERR_MSG_MOD(fl_act->extack, "Failed to get flow meter");
-               mlx5_core_err(priv->mdev, "Failed to get flow meter %d\n", params.index);
                return PTR_ERR(meter);
        }
 
index 626cb7470fa572bb540ff1d83b300b6fccc3e950..07c1895a2b23414f2a9b5bf5e1454757951624c3 100644 (file)
@@ -64,6 +64,7 @@ mlx5e_tc_act_stats_add(struct mlx5e_tc_act_stats_handle *handle,
 {
        struct mlx5e_tc_act_stats *act_stats, *old_act_stats;
        struct rhashtable *ht = &handle->ht;
+       u64 lastused;
        int err = 0;
 
        act_stats = kvzalloc(sizeof(*act_stats), GFP_KERNEL);
@@ -73,6 +74,10 @@ mlx5e_tc_act_stats_add(struct mlx5e_tc_act_stats_handle *handle,
        act_stats->tc_act_cookie = act_cookie;
        act_stats->counter = counter;
 
+       mlx5_fc_query_cached_raw(counter,
+                                &act_stats->lastbytes,
+                                &act_stats->lastpackets, &lastused);
+
        rcu_read_lock();
        old_act_stats = rhashtable_lookup_get_insert_fast(ht,
                                                          &act_stats->hash,
index ca834bbcb44f1953b42c9a1e6db21856aa2d5aa5..8afcec0c5d3cafda3f00bbc5b7a99d815c58a9b4 100644 (file)
@@ -242,7 +242,7 @@ mlx5e_int_port_remove(struct mlx5e_tc_int_port_priv *priv,
                mlx5_del_flow_rules(int_port->rx_rule);
        mapping_remove(ctx, int_port->mapping);
        mlx5e_int_port_metadata_free(priv, int_port->match_metadata);
-       kfree_rcu(int_port);
+       kfree_rcu_mightsleep(int_port);
        priv->num_ports--;
 }
 
index bcd6370de440f2d3c9f22509750c51c3899c382b..d9d3b9e1f15aa7e31a63df3226cb66b65062d2e3 100644 (file)
@@ -34,6 +34,7 @@
 #include <net/xdp_sock_drv.h>
 #include "en/xdp.h"
 #include "en/params.h"
+#include <linux/bitfield.h>
 
 int mlx5e_xdp_max_mtu(struct mlx5e_params *params, struct mlx5e_xsk_param *xsk)
 {
@@ -162,21 +163,79 @@ static int mlx5e_xdp_rx_timestamp(const struct xdp_md *ctx, u64 *timestamp)
        const struct mlx5e_xdp_buff *_ctx = (void *)ctx;
 
        if (unlikely(!mlx5e_rx_hw_stamp(_ctx->rq->tstamp)))
-               return -EOPNOTSUPP;
+               return -ENODATA;
 
        *timestamp =  mlx5e_cqe_ts_to_ns(_ctx->rq->ptp_cyc2time,
                                         _ctx->rq->clock, get_cqe_ts(_ctx->cqe));
        return 0;
 }
 
-static int mlx5e_xdp_rx_hash(const struct xdp_md *ctx, u32 *hash)
+/* Mapping HW RSS Type bits CQE_RSS_HTYPE_IP + CQE_RSS_HTYPE_L4 into 4-bits*/
+#define RSS_TYPE_MAX_TABLE     16 /* 4-bits max 16 entries */
+#define RSS_L4         GENMASK(1, 0)
+#define RSS_L3         GENMASK(3, 2) /* Same as CQE_RSS_HTYPE_IP */
+
+/* Valid combinations of CQE_RSS_HTYPE_IP + CQE_RSS_HTYPE_L4 sorted numerical */
+enum mlx5_rss_hash_type {
+       RSS_TYPE_NO_HASH        = (FIELD_PREP_CONST(RSS_L3, CQE_RSS_IP_NONE) |
+                                  FIELD_PREP_CONST(RSS_L4, CQE_RSS_L4_NONE)),
+       RSS_TYPE_L3_IPV4        = (FIELD_PREP_CONST(RSS_L3, CQE_RSS_IPV4) |
+                                  FIELD_PREP_CONST(RSS_L4, CQE_RSS_L4_NONE)),
+       RSS_TYPE_L4_IPV4_TCP    = (FIELD_PREP_CONST(RSS_L3, CQE_RSS_IPV4) |
+                                  FIELD_PREP_CONST(RSS_L4, CQE_RSS_L4_TCP)),
+       RSS_TYPE_L4_IPV4_UDP    = (FIELD_PREP_CONST(RSS_L3, CQE_RSS_IPV4) |
+                                  FIELD_PREP_CONST(RSS_L4, CQE_RSS_L4_UDP)),
+       RSS_TYPE_L4_IPV4_IPSEC  = (FIELD_PREP_CONST(RSS_L3, CQE_RSS_IPV4) |
+                                  FIELD_PREP_CONST(RSS_L4, CQE_RSS_L4_IPSEC)),
+       RSS_TYPE_L3_IPV6        = (FIELD_PREP_CONST(RSS_L3, CQE_RSS_IPV6) |
+                                  FIELD_PREP_CONST(RSS_L4, CQE_RSS_L4_NONE)),
+       RSS_TYPE_L4_IPV6_TCP    = (FIELD_PREP_CONST(RSS_L3, CQE_RSS_IPV6) |
+                                  FIELD_PREP_CONST(RSS_L4, CQE_RSS_L4_TCP)),
+       RSS_TYPE_L4_IPV6_UDP    = (FIELD_PREP_CONST(RSS_L3, CQE_RSS_IPV6) |
+                                  FIELD_PREP_CONST(RSS_L4, CQE_RSS_L4_UDP)),
+       RSS_TYPE_L4_IPV6_IPSEC  = (FIELD_PREP_CONST(RSS_L3, CQE_RSS_IPV6) |
+                                  FIELD_PREP_CONST(RSS_L4, CQE_RSS_L4_IPSEC)),
+};
+
+/* Invalid combinations will simply return zero, allows no boundary checks */
+static const enum xdp_rss_hash_type mlx5_xdp_rss_type[RSS_TYPE_MAX_TABLE] = {
+       [RSS_TYPE_NO_HASH]       = XDP_RSS_TYPE_NONE,
+       [1]                      = XDP_RSS_TYPE_NONE, /* Implicit zero */
+       [2]                      = XDP_RSS_TYPE_NONE, /* Implicit zero */
+       [3]                      = XDP_RSS_TYPE_NONE, /* Implicit zero */
+       [RSS_TYPE_L3_IPV4]       = XDP_RSS_TYPE_L3_IPV4,
+       [RSS_TYPE_L4_IPV4_TCP]   = XDP_RSS_TYPE_L4_IPV4_TCP,
+       [RSS_TYPE_L4_IPV4_UDP]   = XDP_RSS_TYPE_L4_IPV4_UDP,
+       [RSS_TYPE_L4_IPV4_IPSEC] = XDP_RSS_TYPE_L4_IPV4_IPSEC,
+       [RSS_TYPE_L3_IPV6]       = XDP_RSS_TYPE_L3_IPV6,
+       [RSS_TYPE_L4_IPV6_TCP]   = XDP_RSS_TYPE_L4_IPV6_TCP,
+       [RSS_TYPE_L4_IPV6_UDP]   = XDP_RSS_TYPE_L4_IPV6_UDP,
+       [RSS_TYPE_L4_IPV6_IPSEC] = XDP_RSS_TYPE_L4_IPV6_IPSEC,
+       [12]                     = XDP_RSS_TYPE_NONE, /* Implicit zero */
+       [13]                     = XDP_RSS_TYPE_NONE, /* Implicit zero */
+       [14]                     = XDP_RSS_TYPE_NONE, /* Implicit zero */
+       [15]                     = XDP_RSS_TYPE_NONE, /* Implicit zero */
+};
+
+static int mlx5e_xdp_rx_hash(const struct xdp_md *ctx, u32 *hash,
+                            enum xdp_rss_hash_type *rss_type)
 {
        const struct mlx5e_xdp_buff *_ctx = (void *)ctx;
+       const struct mlx5_cqe64 *cqe = _ctx->cqe;
+       u32 hash_type, l4_type, ip_type, lookup;
 
        if (unlikely(!(_ctx->xdp.rxq->dev->features & NETIF_F_RXHASH)))
-               return -EOPNOTSUPP;
+               return -ENODATA;
+
+       *hash = be32_to_cpu(cqe->rss_hash_result);
+
+       hash_type = cqe->rss_hash_type;
+       BUILD_BUG_ON(CQE_RSS_HTYPE_IP != RSS_L3); /* same mask */
+       ip_type = hash_type & CQE_RSS_HTYPE_IP;
+       l4_type = FIELD_GET(CQE_RSS_HTYPE_L4, hash_type);
+       lookup = ip_type | l4_type;
+       *rss_type = mlx5_xdp_rss_type[lookup];
 
-       *hash = be32_to_cpu(_ctx->cqe->rss_hash_result);
        return 0;
 }
 
index 4be770443b0cd2a22df63c07c34ebbec4847678a..9b597cb2459851aa9a3dd46f4757e94ba87c7f70 100644 (file)
@@ -621,15 +621,6 @@ int mlx5e_ktls_add_rx(struct net_device *netdev, struct sock *sk,
        if (unlikely(!priv_rx))
                return -ENOMEM;
 
-       dek = mlx5_ktls_create_key(priv->tls->dek_pool, crypto_info);
-       if (IS_ERR(dek)) {
-               err = PTR_ERR(dek);
-               goto err_create_key;
-       }
-       priv_rx->dek = dek;
-
-       INIT_LIST_HEAD(&priv_rx->list);
-       spin_lock_init(&priv_rx->lock);
        switch (crypto_info->cipher_type) {
        case TLS_CIPHER_AES_GCM_128:
                priv_rx->crypto_info.crypto_info_128 =
@@ -642,9 +633,20 @@ int mlx5e_ktls_add_rx(struct net_device *netdev, struct sock *sk,
        default:
                WARN_ONCE(1, "Unsupported cipher type %u\n",
                          crypto_info->cipher_type);
-               return -EOPNOTSUPP;
+               err = -EOPNOTSUPP;
+               goto err_cipher_type;
        }
 
+       dek = mlx5_ktls_create_key(priv->tls->dek_pool, crypto_info);
+       if (IS_ERR(dek)) {
+               err = PTR_ERR(dek);
+               goto err_cipher_type;
+       }
+       priv_rx->dek = dek;
+
+       INIT_LIST_HEAD(&priv_rx->list);
+       spin_lock_init(&priv_rx->lock);
+
        rxq = mlx5e_ktls_sk_get_rxq(sk);
        priv_rx->rxq = rxq;
        priv_rx->sk = sk;
@@ -677,7 +679,7 @@ err_post_wqes:
        mlx5e_tir_destroy(&priv_rx->tir);
 err_create_tir:
        mlx5_ktls_destroy_key(priv->tls->dek_pool, priv_rx->dek);
-err_create_key:
+err_cipher_type:
        kfree(priv_rx);
        return err;
 }
index 60b3e08a10286e2285262a6435dacb0ea5265d07..0e4c0a093293a7e8872a7c751bfd8d5373f80935 100644 (file)
@@ -469,14 +469,6 @@ int mlx5e_ktls_add_tx(struct net_device *netdev, struct sock *sk,
        if (IS_ERR(priv_tx))
                return PTR_ERR(priv_tx);
 
-       dek = mlx5_ktls_create_key(priv->tls->dek_pool, crypto_info);
-       if (IS_ERR(dek)) {
-               err = PTR_ERR(dek);
-               goto err_create_key;
-       }
-       priv_tx->dek = dek;
-
-       priv_tx->expected_seq = start_offload_tcp_sn;
        switch (crypto_info->cipher_type) {
        case TLS_CIPHER_AES_GCM_128:
                priv_tx->crypto_info.crypto_info_128 =
@@ -489,8 +481,18 @@ int mlx5e_ktls_add_tx(struct net_device *netdev, struct sock *sk,
        default:
                WARN_ONCE(1, "Unsupported cipher type %u\n",
                          crypto_info->cipher_type);
-               return -EOPNOTSUPP;
+               err = -EOPNOTSUPP;
+               goto err_pool_push;
        }
+
+       dek = mlx5_ktls_create_key(priv->tls->dek_pool, crypto_info);
+       if (IS_ERR(dek)) {
+               err = PTR_ERR(dek);
+               goto err_pool_push;
+       }
+
+       priv_tx->dek = dek;
+       priv_tx->expected_seq = start_offload_tcp_sn;
        priv_tx->tx_ctx = tls_offload_ctx_tx(tls_ctx);
 
        mlx5e_set_ktls_tx_priv_ctx(tls_ctx, priv_tx);
@@ -500,7 +502,7 @@ int mlx5e_ktls_add_tx(struct net_device *netdev, struct sock *sk,
 
        return 0;
 
-err_create_key:
+err_pool_push:
        pool_push(pool, priv_tx);
        return err;
 }
index 08d0929e82603679709d4d425d50a8ff3a95bdc9..51f1cd8364c241585360f8ad1976f0535b8dd4a8 100644 (file)
@@ -89,8 +89,8 @@ struct mlx5e_macsec_rx_sc {
 };
 
 struct mlx5e_macsec_umr {
+       u8 __aligned(64) ctx[MLX5_ST_SZ_BYTES(macsec_aso)];
        dma_addr_t dma_addr;
-       u8 ctx[MLX5_ST_SZ_BYTES(macsec_aso)];
        u32 mkey;
 };
 
@@ -670,7 +670,7 @@ static int mlx5e_macsec_del_txsa(struct macsec_context *ctx)
 
        mlx5e_macsec_cleanup_sa(macsec, tx_sa, true);
        mlx5_destroy_encryption_key(macsec->mdev, tx_sa->enc_key_id);
-       kfree_rcu(tx_sa);
+       kfree_rcu_mightsleep(tx_sa);
        macsec_device->tx_sa[assoc_num] = NULL;
 
 out:
@@ -849,7 +849,7 @@ static void macsec_del_rxsc_ctx(struct mlx5e_macsec *macsec, struct mlx5e_macsec
        xa_erase(&macsec->sc_xarray, rx_sc->sc_xarray_element->fs_id);
        metadata_dst_free(rx_sc->md_dst);
        kfree(rx_sc->sc_xarray_element);
-       kfree_rcu(rx_sc);
+       kfree_rcu_mightsleep(rx_sc);
 }
 
 static int mlx5e_macsec_del_rxsc(struct macsec_context *ctx)
@@ -1412,6 +1412,7 @@ static int macsec_aso_query(struct mlx5_core_dev *mdev, struct mlx5e_macsec *mac
        struct mlx5e_macsec_aso *aso;
        struct mlx5_aso_wqe *aso_wqe;
        struct mlx5_aso *maso;
+       unsigned long expires;
        int err;
 
        aso = &macsec->aso;
@@ -1425,7 +1426,13 @@ static int macsec_aso_query(struct mlx5_core_dev *mdev, struct mlx5e_macsec *mac
        macsec_aso_build_wqe_ctrl_seg(aso, &aso_wqe->aso_ctrl, NULL);
 
        mlx5_aso_post_wqe(maso, false, &aso_wqe->ctrl);
-       err = mlx5_aso_poll_cq(maso, false);
+       expires = jiffies + msecs_to_jiffies(10);
+       do {
+               err = mlx5_aso_poll_cq(maso, false);
+               if (err)
+                       usleep_range(2, 10);
+       } while (err && time_is_after_jiffies(expires));
+
        if (err)
                goto err_out;
 
index 2449731b7d79a715c3d07a923bb4719cf299bd25..89de92d0648363a899793f1aa5ea4fb324a9ddc8 100644 (file)
@@ -117,12 +117,14 @@ static int mlx5e_dcbnl_ieee_getets(struct net_device *netdev,
        if (!MLX5_CAP_GEN(priv->mdev, ets))
                return -EOPNOTSUPP;
 
-       ets->ets_cap = mlx5_max_tc(priv->mdev) + 1;
-       for (i = 0; i < ets->ets_cap; i++) {
+       for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
                err = mlx5_query_port_prio_tc(mdev, i, &ets->prio_tc[i]);
                if (err)
                        return err;
+       }
 
+       ets->ets_cap = mlx5_max_tc(priv->mdev) + 1;
+       for (i = 0; i < ets->ets_cap; i++) {
                err = mlx5_query_port_tc_group(mdev, i, &tc_group[i]);
                if (err)
                        return err;
index 7708acc9b2ab3a274f444e63bdfbb7278ded6ed5..79fd21ecb9cbc70c7ff47d54e7433265b608439e 100644 (file)
@@ -1985,6 +1985,7 @@ static int set_pflag_rx_striding_rq(struct net_device *netdev, bool enable)
        struct mlx5e_priv *priv = netdev_priv(netdev);
        struct mlx5_core_dev *mdev = priv->mdev;
        struct mlx5e_params new_params;
+       int err;
 
        if (enable) {
                /* Checking the regular RQ here; mlx5e_validate_xsk_param called
@@ -2005,7 +2006,14 @@ static int set_pflag_rx_striding_rq(struct net_device *netdev, bool enable)
        MLX5E_SET_PFLAG(&new_params, MLX5E_PFLAG_RX_STRIDING_RQ, enable);
        mlx5e_set_rq_type(mdev, &new_params);
 
-       return mlx5e_safe_switch_params(priv, &new_params, NULL, NULL, true);
+       err = mlx5e_safe_switch_params(priv, &new_params, NULL, NULL, true);
+       if (err)
+               return err;
+
+       /* update XDP supported features */
+       mlx5e_set_xdp_feature(netdev);
+
+       return 0;
 }
 
 static int set_pflag_rx_no_csum_complete(struct net_device *netdev, bool enable)
index 76a9c5194a7046a6867414d9240ae9dbc97db68f..7ca7e9b57607fdfa2484cf374d5b2cfa7f731bf3 100644 (file)
@@ -4004,6 +4004,25 @@ static int mlx5e_handle_feature(struct net_device *netdev,
        return 0;
 }
 
+void mlx5e_set_xdp_feature(struct net_device *netdev)
+{
+       struct mlx5e_priv *priv = netdev_priv(netdev);
+       struct mlx5e_params *params = &priv->channels.params;
+       xdp_features_t val;
+
+       if (params->packet_merge.type != MLX5E_PACKET_MERGE_NONE) {
+               xdp_clear_features_flag(netdev);
+               return;
+       }
+
+       val = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+             NETDEV_XDP_ACT_XSK_ZEROCOPY |
+             NETDEV_XDP_ACT_NDO_XMIT;
+       if (params->rq_wq_type == MLX5_WQ_TYPE_CYCLIC)
+               val |= NETDEV_XDP_ACT_RX_SG;
+       xdp_set_features_flag(netdev, val);
+}
+
 int mlx5e_set_features(struct net_device *netdev, netdev_features_t features)
 {
        netdev_features_t oper_features = features;
@@ -4030,6 +4049,9 @@ int mlx5e_set_features(struct net_device *netdev, netdev_features_t features)
                return -EINVAL;
        }
 
+       /* update XDP supported features */
+       mlx5e_set_xdp_feature(netdev);
+
        return 0;
 }
 
@@ -4128,8 +4150,12 @@ static netdev_features_t mlx5e_fix_features(struct net_device *netdev,
                }
        }
 
-       if (mlx5e_is_uplink_rep(priv))
+       if (mlx5e_is_uplink_rep(priv)) {
                features = mlx5e_fix_uplink_rep_features(netdev, features);
+               features |= NETIF_F_NETNS_LOCAL;
+       } else {
+               features &= ~NETIF_F_NETNS_LOCAL;
+       }
 
        mutex_unlock(&priv->state_lock);
 
@@ -4147,13 +4173,17 @@ static bool mlx5e_xsk_validate_mtu(struct net_device *netdev,
                struct xsk_buff_pool *xsk_pool =
                        mlx5e_xsk_get_pool(&chs->params, chs->params.xsk, ix);
                struct mlx5e_xsk_param xsk;
+               int max_xdp_mtu;
 
                if (!xsk_pool)
                        continue;
 
                mlx5e_build_xsk_param(xsk_pool, &xsk);
+               max_xdp_mtu = mlx5e_xdp_max_mtu(new_params, &xsk);
 
-               if (!mlx5e_validate_xsk_param(new_params, &xsk, mdev)) {
+               /* Validate XSK params and XDP MTU in advance */
+               if (!mlx5e_validate_xsk_param(new_params, &xsk, mdev) ||
+                   new_params->sw_mtu > max_xdp_mtu) {
                        u32 hr = mlx5e_get_linear_rq_headroom(new_params, &xsk);
                        int max_mtu_frame, max_mtu_page, max_mtu;
 
@@ -4163,9 +4193,9 @@ static bool mlx5e_xsk_validate_mtu(struct net_device *netdev,
                         */
                        max_mtu_frame = MLX5E_HW2SW_MTU(new_params, xsk.chunk_size - hr);
                        max_mtu_page = MLX5E_HW2SW_MTU(new_params, SKB_MAX_HEAD(0));
-                       max_mtu = min(max_mtu_frame, max_mtu_page);
+                       max_mtu = min3(max_mtu_frame, max_mtu_page, max_xdp_mtu);
 
-                       netdev_err(netdev, "MTU %d is too big for an XSK running on channel %u. Try MTU <= %d\n",
+                       netdev_err(netdev, "MTU %d is too big for an XSK running on channel %u or its redirection XDP program. Try MTU <= %d\n",
                                   new_params->sw_mtu, ix, max_mtu);
                        return false;
                }
@@ -4761,13 +4791,6 @@ static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog)
        if (old_prog)
                bpf_prog_put(old_prog);
 
-       if (reset) {
-               if (prog)
-                       xdp_features_set_redirect_target(netdev, true);
-               else
-                       xdp_features_clear_redirect_target(netdev);
-       }
-
        if (!test_bit(MLX5E_STATE_OPENED, &priv->state) || reset)
                goto unlock;
 
@@ -4964,8 +4987,6 @@ void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16
        /* TX inline */
        mlx5_query_min_inline(mdev, &params->tx_min_inline_mode);
 
-       params->tunneled_offload_en = mlx5_tunnel_inner_ft_supported(mdev);
-
        /* AF_XDP */
        params->xsk = xsk;
 
@@ -5163,13 +5184,10 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
        netdev->features         |= NETIF_F_HIGHDMA;
        netdev->features         |= NETIF_F_HW_VLAN_STAG_FILTER;
 
-       netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
-                              NETDEV_XDP_ACT_XSK_ZEROCOPY |
-                              NETDEV_XDP_ACT_RX_SG;
-
        netdev->priv_flags       |= IFF_UNICAST_FLT;
 
        netif_set_tso_max_size(netdev, GSO_MAX_SIZE);
+       mlx5e_set_xdp_feature(netdev);
        mlx5e_set_netdev_dev_addr(netdev);
        mlx5e_macsec_build_netdev(priv);
        mlx5e_ipsec_build_netdev(priv);
@@ -5241,6 +5259,9 @@ static int mlx5e_nic_init(struct mlx5_core_dev *mdev,
                mlx5_core_err(mdev, "TLS initialization failed, %d\n", err);
 
        mlx5e_health_create_reporters(priv);
+       /* update XDP supported features */
+       mlx5e_set_xdp_feature(netdev);
+
        return 0;
 }
 
@@ -5270,7 +5291,7 @@ static int mlx5e_init_nic_rx(struct mlx5e_priv *priv)
        }
 
        features = MLX5E_RX_RES_FEATURE_PTP;
-       if (priv->channels.params.tunneled_offload_en)
+       if (mlx5_tunnel_inner_ft_supported(mdev))
                features |= MLX5E_RX_RES_FEATURE_INNER_FT;
        err = mlx5e_rx_res_init(priv->rx_res, priv->mdev, features,
                                priv->max_nch, priv->drop_rq.rqn,
index 9b92034430854759bc1d50c002c1b3810c99a542..8ff654b4e9e14101a5e0e65e0e6a32e22c48431a 100644 (file)
@@ -747,12 +747,14 @@ static void mlx5e_build_rep_params(struct net_device *netdev)
        /* RQ */
        mlx5e_build_rq_params(mdev, params);
 
+       /* update XDP supported features */
+       mlx5e_set_xdp_feature(netdev);
+
        /* CQ moderation params */
        params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
        mlx5e_set_rx_cq_mode_params(params, cq_period_mode);
 
        params->mqprio.num_tc       = 1;
-       params->tunneled_offload_en = false;
        if (rep->vport != MLX5_VPORT_UPLINK)
                params->vlan_strip_disable = true;
 
index 70b8d2dfa751f92267ebd5b7e094f95d181ca93a..87a2850b32d09baa5d0dc945825f1178118ba975 100644 (file)
@@ -1103,8 +1103,8 @@ static void
 mlx5e_hairpin_params_init(struct mlx5e_hairpin_params *hairpin_params,
                          struct mlx5_core_dev *mdev)
 {
+       u32 link_speed = 0;
        u64 link_speed64;
-       u32 link_speed;
 
        hairpin_params->mdev = mdev;
        /* set hairpin pair per each 50Gbs share of the link */
@@ -3752,7 +3752,7 @@ mlx5e_clone_flow_attr_for_post_act(struct mlx5_flow_attr *attr,
        parse_attr->filter_dev = attr->parse_attr->filter_dev;
        attr2->action = 0;
        attr2->counter = NULL;
-       attr->tc_act_cookies_count = 0;
+       attr2->tc_act_cookies_count = 0;
        attr2->flags = 0;
        attr2->parse_attr = parse_attr;
        attr2->dest_chain = 0;
@@ -4304,6 +4304,7 @@ int mlx5e_set_fwd_to_int_port_actions(struct mlx5e_priv *priv,
 
        esw_attr->dest_int_port = dest_int_port;
        esw_attr->dests[out_index].flags |= MLX5_ESW_DEST_CHAIN_WITH_SRC_PORT_CHANGE;
+       esw_attr->split_count = out_index;
 
        /* Forward to root fdb for matching against the new source vport */
        attr->dest_chain = 0;
@@ -5304,8 +5305,10 @@ int mlx5e_tc_nic_init(struct mlx5e_priv *priv)
        mlx5e_tc_debugfs_init(tc, mlx5e_fs_get_debugfs_root(priv->fs));
 
        tc->action_stats_handle = mlx5e_tc_act_stats_create();
-       if (IS_ERR(tc->action_stats_handle))
+       if (IS_ERR(tc->action_stats_handle)) {
+               err = PTR_ERR(tc->action_stats_handle);
                goto err_act_stats;
+       }
 
        return 0;
 
@@ -5440,8 +5443,10 @@ int mlx5e_tc_esw_init(struct mlx5_rep_uplink_priv *uplink_priv)
        }
 
        uplink_priv->action_stats_handle = mlx5e_tc_act_stats_create();
-       if (IS_ERR(uplink_priv->action_stats_handle))
+       if (IS_ERR(uplink_priv->action_stats_handle)) {
+               err = PTR_ERR(uplink_priv->action_stats_handle);
                goto err_action_counter;
+       }
 
        return 0;
 
@@ -5463,6 +5468,16 @@ err_tun_mapping:
 
 void mlx5e_tc_esw_cleanup(struct mlx5_rep_uplink_priv *uplink_priv)
 {
+       struct mlx5e_rep_priv *rpriv;
+       struct mlx5_eswitch *esw;
+       struct mlx5e_priv *priv;
+
+       rpriv = container_of(uplink_priv, struct mlx5e_rep_priv, uplink_priv);
+       priv = netdev_priv(rpriv->netdev);
+       esw = priv->mdev->priv.eswitch;
+
+       mlx5e_tc_clean_fdb_peer_flows(esw);
+
        mlx5e_tc_tun_cleanup(uplink_priv->encap);
 
        mapping_destroy(uplink_priv->tunnel_enc_opts_mapping);
index d55775627a473a698638b2b2fff4e0c7e55a195b..50d2ea32397982884bb6618d1b1da53bf7ca53d5 100644 (file)
@@ -364,8 +364,7 @@ int mlx5_esw_acl_ingress_vport_metadata_update(struct mlx5_eswitch *esw, u16 vpo
 
        if (WARN_ON_ONCE(IS_ERR(vport))) {
                esw_warn(esw->dev, "vport(%d) invalid!\n", vport_num);
-               err = PTR_ERR(vport);
-               goto out;
+               return PTR_ERR(vport);
        }
 
        esw_acl_ingress_ofld_rules_destroy(esw, vport);
index 0f052513fefa104d882355dece4fdbb264d8277d..19fed514fc1734fb2fb44d4000c782b6cbe55879 100644 (file)
@@ -959,6 +959,7 @@ void mlx5_esw_vport_disable(struct mlx5_eswitch *esw, u16 vport_num)
         */
        esw_vport_change_handle_locked(vport);
        vport->enabled_events = 0;
+       esw_apply_vport_rx_mode(esw, vport, false, false);
        esw_vport_cleanup(esw, vport);
        esw->enabled_vports--;
 
@@ -1487,7 +1488,7 @@ int mlx5_esw_sf_max_hpf_functions(struct mlx5_core_dev *dev, u16 *max_sfs, u16 *
        void *hca_caps;
        int err;
 
-       if (!mlx5_core_is_ecpf(dev) || mlx5_core_is_management_pf(dev)) {
+       if (!mlx5_core_is_ecpf(dev)) {
                *max_sfs = 0;
                return 0;
        }
index d766a64b18234ea810e1e268991fedfb2d5cbbe3..25a8076a77bff081900591d1748773983018594d 100644 (file)
@@ -723,11 +723,11 @@ mlx5_eswitch_add_fwd_rule(struct mlx5_eswitch *esw,
 
        flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
        for (i = 0; i < esw_attr->split_count; i++) {
-               if (esw_is_indir_table(esw, attr))
-                       err = esw_setup_indir_table(dest, &flow_act, esw, attr, false, &i);
-               else if (esw_is_chain_src_port_rewrite(esw, esw_attr))
-                       err = esw_setup_chain_src_port_rewrite(dest, &flow_act, esw, chains, attr,
-                                                              &i);
+               if (esw_attr->dests[i].flags & MLX5_ESW_DEST_CHAIN_WITH_SRC_PORT_CHANGE)
+                       /* Source port rewrite (forward to ovs internal port or statck device) isn't
+                        * supported in the rule of split action.
+                        */
+                       err = -EOPNOTSUPP;
                else
                        esw_setup_vport_dest(dest, &flow_act, esw, esw_attr, i, i, false);
 
@@ -3405,6 +3405,18 @@ static int esw_inline_mode_to_devlink(u8 mlx5_mode, u8 *mode)
        return 0;
 }
 
+static bool esw_offloads_devlink_ns_eq_netdev_ns(struct devlink *devlink)
+{
+       struct net *devl_net, *netdev_net;
+       struct mlx5_eswitch *esw;
+
+       esw = mlx5_devlink_eswitch_get(devlink);
+       netdev_net = dev_net(esw->dev->mlx5e_res.uplink_netdev);
+       devl_net = devlink_net(devlink);
+
+       return net_eq(devl_net, netdev_net);
+}
+
 int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
                                  struct netlink_ext_ack *extack)
 {
@@ -3419,6 +3431,13 @@ int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
        if (esw_mode_from_devlink(mode, &mlx5_mode))
                return -EINVAL;
 
+       if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV &&
+           !esw_offloads_devlink_ns_eq_netdev_ns(devlink)) {
+               NL_SET_ERR_MSG_MOD(extack,
+                                  "Can't change E-Switch mode to switchdev when netdev net namespace has diverged from the devlink's.");
+               return -EPERM;
+       }
+
        mlx5_lag_disable_change(esw->dev);
        err = mlx5_esw_try_lock(esw);
        if (err < 0) {
index c2a4f86bc8909526703840ff8566e2d7a74a0971..baa7ef812313996be093323cb1465af85ef8a5f1 100644 (file)
@@ -70,7 +70,6 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev,
 
        params->packet_merge.type = MLX5E_PACKET_MERGE_NONE;
        params->hard_mtu = MLX5_IB_GRH_BYTES + MLX5_IPOIB_HARD_LEN;
-       params->tunneled_offload_en = false;
 
        /* CQE compression is not supported for IPoIB */
        params->rx_cqe_compress_def = false;
index 540840e80493b083e9d784caa40ef78df4b4f731..f1de152a61135844f291af44a69d04df60a96bb6 100644 (file)
@@ -1364,8 +1364,8 @@ static void mlx5_unload(struct mlx5_core_dev *dev)
 {
        mlx5_devlink_traps_unregister(priv_to_devlink(dev));
        mlx5_sf_dev_table_destroy(dev);
-       mlx5_sriov_detach(dev);
        mlx5_eswitch_disable(dev->priv.eswitch);
+       mlx5_sriov_detach(dev);
        mlx5_lag_remove_mdev(dev);
        mlx5_ec_cleanup(dev);
        mlx5_sf_hw_table_destroy(dev);
@@ -1789,11 +1789,11 @@ static void remove_one(struct pci_dev *pdev)
        struct mlx5_core_dev *dev  = pci_get_drvdata(pdev);
        struct devlink *devlink = priv_to_devlink(dev);
 
+       set_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state);
        /* mlx5_drain_fw_reset() is using devlink APIs. Hence, we must drain
         * fw_reset before unregistering the devlink.
         */
        mlx5_drain_fw_reset(dev);
-       set_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state);
        devlink_unregister(devlink);
        mlx5_sriov_disable(pdev);
        mlx5_crdump_disable(dev);
index 64d4e7125e9bb5e1da1246a8af27a2bab1bb0f4b..95dc67fb300157aa8071d40ce667d0e43dd1b7af 100644 (file)
@@ -82,6 +82,16 @@ static u16 func_id_to_type(struct mlx5_core_dev *dev, u16 func_id, bool ec_funct
        return func_id <= mlx5_core_max_vfs(dev) ?  MLX5_VF : MLX5_SF;
 }
 
+static u32 mlx5_get_ec_function(u32 function)
+{
+       return function >> 16;
+}
+
+static u32 mlx5_get_func_id(u32 function)
+{
+       return function & 0xffff;
+}
+
 static struct rb_root *page_root_per_function(struct mlx5_core_dev *dev, u32 function)
 {
        struct rb_root *root;
@@ -665,20 +675,22 @@ static int optimal_reclaimed_pages(void)
 }
 
 static int mlx5_reclaim_root_pages(struct mlx5_core_dev *dev,
-                                  struct rb_root *root, u16 func_id)
+                                  struct rb_root *root, u32 function)
 {
        u64 recl_pages_to_jiffies = msecs_to_jiffies(mlx5_tout_ms(dev, RECLAIM_PAGES));
        unsigned long end = jiffies + recl_pages_to_jiffies;
 
        while (!RB_EMPTY_ROOT(root)) {
+               u32 ec_function = mlx5_get_ec_function(function);
+               u32 function_id = mlx5_get_func_id(function);
                int nclaimed;
                int err;
 
-               err = reclaim_pages(dev, func_id, optimal_reclaimed_pages(),
-                                   &nclaimed, false, mlx5_core_is_ecpf(dev));
+               err = reclaim_pages(dev, function_id, optimal_reclaimed_pages(),
+                                   &nclaimed, false, ec_function);
                if (err) {
-                       mlx5_core_warn(dev, "failed reclaiming pages (%d) for func id 0x%x\n",
-                                      err, func_id);
+                       mlx5_core_warn(dev, "reclaim_pages err (%d) func_id=0x%x ec_func=0x%x\n",
+                                      err, function_id, ec_function);
                        return err;
                }
 
index 017d68f1e1232c394aa4b2ac209300256fbbab51..972c571b41587a14518b71d8bacce2172f82a081 100644 (file)
@@ -31,6 +31,8 @@ mlxfw_mfa2_tlv_next(const struct mlxfw_mfa2_file *mfa2_file,
 
        if (tlv->type == MLXFW_MFA2_TLV_MULTI_PART) {
                multi = mlxfw_mfa2_tlv_multi_get(mfa2_file, tlv);
+               if (!multi)
+                       return NULL;
                tlv_len = NLA_ALIGN(tlv_len + be16_to_cpu(multi->total_len));
        }
 
index c5240d38c9dbd83ca87f4b8802144cb7ed4a2018..09ed6e5fa6c34e6db76d160d36cb5df28b67ac8d 100644 (file)
@@ -105,7 +105,6 @@ struct mlxsw_thermal {
        struct thermal_zone_device *tzdev;
        int polling_delay;
        struct thermal_cooling_device *cdevs[MLXSW_MFCR_PWMS_MAX];
-       u8 cooling_levels[MLXSW_THERMAL_MAX_STATE + 1];
        struct thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
        struct mlxsw_cooling_states cooling_states[MLXSW_THERMAL_NUM_TRIPS];
        struct mlxsw_thermal_area line_cards[];
@@ -468,7 +467,7 @@ static int mlxsw_thermal_set_cur_state(struct thermal_cooling_device *cdev,
                return idx;
 
        /* Normalize the state to the valid speed range. */
-       state = thermal->cooling_levels[state];
+       state = max_t(unsigned long, MLXSW_THERMAL_MIN_STATE, state);
        mlxsw_reg_mfsc_pack(mfsc_pl, idx, mlxsw_state_to_duty(state));
        err = mlxsw_reg_write(thermal->core, MLXSW_REG(mfsc), mfsc_pl);
        if (err) {
@@ -859,10 +858,6 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
                }
        }
 
-       /* Initialize cooling levels per PWM state. */
-       for (i = 0; i < MLXSW_THERMAL_MAX_STATE; i++)
-               thermal->cooling_levels[i] = max(MLXSW_THERMAL_MIN_STATE, i);
-
        thermal->polling_delay = bus_info->low_frequency ?
                                 MLXSW_THERMAL_SLOW_POLL_INT :
                                 MLXSW_THERMAL_POLL_INT;
index 48dbfea0a2a1d5db3fea9050fe55f5ade0efce69..7cdf0ce24f288cf0fc867d463ee924007f0242ba 100644 (file)
@@ -26,7 +26,7 @@
 #define MLXSW_PCI_CIR_TIMEOUT_MSECS            1000
 
 #define MLXSW_PCI_SW_RESET_TIMEOUT_MSECS       900000
-#define MLXSW_PCI_SW_RESET_WAIT_MSECS          200
+#define MLXSW_PCI_SW_RESET_WAIT_MSECS          400
 #define MLXSW_PCI_FW_READY                     0xA1844
 #define MLXSW_PCI_FW_READY_MASK                        0xFFFF
 #define MLXSW_PCI_FW_READY_MAGIC               0x5E
index a8f94b7544eeab04c8c53d74337245f7e6ebaf17..02a327744a61b6c84319b7d79804966e612e7dcc 100644 (file)
@@ -2937,6 +2937,7 @@ static int mlxsw_sp_netdevice_event(struct notifier_block *unused,
 
 static void mlxsw_sp_parsing_init(struct mlxsw_sp *mlxsw_sp)
 {
+       refcount_set(&mlxsw_sp->parsing.parsing_depth_ref, 0);
        mlxsw_sp->parsing.parsing_depth = MLXSW_SP_DEFAULT_PARSING_DEPTH;
        mlxsw_sp->parsing.vxlan_udp_dport = MLXSW_SP_DEFAULT_VXLAN_UDP_DPORT;
        mutex_init(&mlxsw_sp->parsing.lock);
@@ -2945,6 +2946,7 @@ static void mlxsw_sp_parsing_init(struct mlxsw_sp *mlxsw_sp)
 static void mlxsw_sp_parsing_fini(struct mlxsw_sp *mlxsw_sp)
 {
        mutex_destroy(&mlxsw_sp->parsing.lock);
+       WARN_ON_ONCE(refcount_read(&mlxsw_sp->parsing.parsing_depth_ref));
 }
 
 struct mlxsw_sp_ipv6_addr_node {
index 045a24cacfa517e5ef79add5528876e2da93a8dd..b6ee2d658b0c43970a921e8cb73519fc9d046b16 100644 (file)
@@ -1354,7 +1354,7 @@ static int mlxsw_sp_fid_8021q_port_vid_map(struct mlxsw_sp_fid *fid,
                                           u16 vid)
 {
        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
-       u8 local_port = mlxsw_sp_port->local_port;
+       u16 local_port = mlxsw_sp_port->local_port;
        int err;
 
        /* In case there are no {Port, VID} => FID mappings on the port,
@@ -1391,7 +1391,7 @@ mlxsw_sp_fid_8021q_port_vid_unmap(struct mlxsw_sp_fid *fid,
                                  struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
 {
        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
-       u8 local_port = mlxsw_sp_port->local_port;
+       u16 local_port = mlxsw_sp_port->local_port;
 
        mlxsw_sp_fid_port_vid_list_del(fid, mlxsw_sp_port->local_port, vid);
        mlxsw_sp_fid_evid_map(fid, local_port, vid, false);
index 09e32778b012d18c4a15de40b025dbbd901abf8c..4a73e2fe95ef90422ea4bf7efaf7fd05942bd1ac 100644 (file)
@@ -10381,11 +10381,23 @@ err_reg_write:
                                              old_inc_parsing_depth);
        return err;
 }
+
+static void mlxsw_sp_mp_hash_fini(struct mlxsw_sp *mlxsw_sp)
+{
+       bool old_inc_parsing_depth = mlxsw_sp->router->inc_parsing_depth;
+
+       mlxsw_sp_mp_hash_parsing_depth_adjust(mlxsw_sp, old_inc_parsing_depth,
+                                             false);
+}
 #else
 static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp)
 {
        return 0;
 }
+
+static void mlxsw_sp_mp_hash_fini(struct mlxsw_sp *mlxsw_sp)
+{
+}
 #endif
 
 static int mlxsw_sp_dscp_init(struct mlxsw_sp *mlxsw_sp)
@@ -10615,6 +10627,7 @@ err_register_inet6addr_notifier:
 err_register_inetaddr_notifier:
        mlxsw_core_flush_owq();
 err_dscp_init:
+       mlxsw_sp_mp_hash_fini(mlxsw_sp);
 err_mp_hash_init:
        mlxsw_sp_neigh_fini(mlxsw_sp);
 err_neigh_init:
@@ -10655,6 +10668,7 @@ void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)
        unregister_inet6addr_notifier(&mlxsw_sp->router->inet6addr_nb);
        unregister_inetaddr_notifier(&mlxsw_sp->router->inetaddr_nb);
        mlxsw_core_flush_owq();
+       mlxsw_sp_mp_hash_fini(mlxsw_sp);
        mlxsw_sp_neigh_fini(mlxsw_sp);
        mlxsw_sp_lb_rif_fini(mlxsw_sp);
        mlxsw_sp_vrs_fini(mlxsw_sp);
index a9aec900d608dd426496c642477b6250d4469f78..7d66fe75cd3bfcd1eb980d9929a68b55cfdbbfe4 100644 (file)
@@ -194,7 +194,7 @@ int lan966x_police_port_del(struct lan966x_port *port,
                return -EINVAL;
        }
 
-       err = lan966x_police_del(port, port->tc.police_id);
+       err = lan966x_police_del(port, POL_IDX_PORT + port->chip_port);
        if (err) {
                NL_SET_ERR_MSG_MOD(extack,
                                   "Failed to add policer to port");
index 871a3e62f85270c7f801ea8352c6a5c9e04b06e5..2d763664dcda18e1c67b5637a707e88984e3ee7d 100644 (file)
@@ -249,6 +249,21 @@ static int sparx5_dcb_ieee_dscp_setdel(struct net_device *dev,
        return 0;
 }
 
+static int sparx5_dcb_ieee_delapp(struct net_device *dev, struct dcb_app *app)
+{
+       int err;
+
+       if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP)
+               err = sparx5_dcb_ieee_dscp_setdel(dev, app, dcb_ieee_delapp);
+       else
+               err = dcb_ieee_delapp(dev, app);
+
+       if (err < 0)
+               return err;
+
+       return sparx5_dcb_app_update(dev);
+}
+
 static int sparx5_dcb_ieee_setapp(struct net_device *dev, struct dcb_app *app)
 {
        struct dcb_app app_itr;
@@ -264,7 +279,7 @@ static int sparx5_dcb_ieee_setapp(struct net_device *dev, struct dcb_app *app)
        if (prio) {
                app_itr = *app;
                app_itr.priority = prio;
-               dcb_ieee_delapp(dev, &app_itr);
+               sparx5_dcb_ieee_delapp(dev, &app_itr);
        }
 
        if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP)
@@ -281,21 +296,6 @@ out:
        return err;
 }
 
-static int sparx5_dcb_ieee_delapp(struct net_device *dev, struct dcb_app *app)
-{
-       int err;
-
-       if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP)
-               err = sparx5_dcb_ieee_dscp_setdel(dev, app, dcb_ieee_delapp);
-       else
-               err = dcb_ieee_delapp(dev, app);
-
-       if (err < 0)
-               return err;
-
-       return sparx5_dcb_app_update(dev);
-}
-
 static int sparx5_dcb_setapptrust(struct net_device *dev, u8 *selectors,
                                  int nselectors)
 {
index bdb893476832bd6da6032f23742be033fa741f52..d0e6cd8dbe5c94c666823be41f670bd8bc02c827 100644 (file)
@@ -258,6 +258,7 @@ struct ocelot_stat_layout {
 struct ocelot_stats_region {
        struct list_head node;
        u32 base;
+       enum ocelot_stat first_stat;
        int count;
        u32 *buf;
 };
@@ -273,6 +274,7 @@ static const struct ocelot_stat_layout ocelot_mm_stats_layout[OCELOT_NUM_STATS]
        OCELOT_STAT(RX_ASSEMBLY_OK),
        OCELOT_STAT(RX_MERGE_FRAGMENTS),
        OCELOT_STAT(TX_MERGE_FRAGMENTS),
+       OCELOT_STAT(TX_MM_HOLD),
        OCELOT_STAT(RX_PMAC_OCTETS),
        OCELOT_STAT(RX_PMAC_UNICAST),
        OCELOT_STAT(RX_PMAC_MULTICAST),
@@ -341,11 +343,12 @@ static int ocelot_port_update_stats(struct ocelot *ocelot, int port)
  */
 static void ocelot_port_transfer_stats(struct ocelot *ocelot, int port)
 {
-       unsigned int idx = port * OCELOT_NUM_STATS;
        struct ocelot_stats_region *region;
        int j;
 
        list_for_each_entry(region, &ocelot->stats_regions, node) {
+               unsigned int idx = port * OCELOT_NUM_STATS + region->first_stat;
+
                for (j = 0; j < region->count; j++) {
                        u64 *stat = &ocelot->stats[idx + j];
                        u64 val = region->buf[j];
@@ -355,8 +358,6 @@ static void ocelot_port_transfer_stats(struct ocelot *ocelot, int port)
 
                        *stat = (*stat & ~(u64)U32_MAX) + val;
                }
-
-               idx += region->count;
        }
 }
 
@@ -899,7 +900,8 @@ static int ocelot_prepare_stats_regions(struct ocelot *ocelot)
                if (!layout[i].reg)
                        continue;
 
-               if (region && layout[i].reg == last + 4) {
+               if (region && ocelot->map[SYS][layout[i].reg & REG_MASK] ==
+                   ocelot->map[SYS][last & REG_MASK] + 4) {
                        region->count++;
                } else {
                        region = devm_kzalloc(ocelot->dev, sizeof(*region),
@@ -914,6 +916,7 @@ static int ocelot_prepare_stats_regions(struct ocelot *ocelot)
                        WARN_ON(last >= layout[i].reg);
 
                        region->base = layout[i].reg;
+                       region->first_stat = i;
                        region->count = 1;
                        list_add_tail(&region->node, &ocelot->stats_regions);
                }
index d17d1b4f2585fed3e16ab0208a441a3aaf5bc025..825356ee3492ec62375f85255009bb51a04317ce 100644 (file)
@@ -292,7 +292,7 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev)
         */
 
        laddr = dma_map_single(lp->device, skb->data, length, DMA_TO_DEVICE);
-       if (!laddr) {
+       if (dma_mapping_error(lp->device, laddr)) {
                pr_err_ratelimited("%s: failed to map tx DMA buffer.\n", dev->name);
                dev_kfree_skb_any(skb);
                return NETDEV_TX_OK;
@@ -509,7 +509,7 @@ static bool sonic_alloc_rb(struct net_device *dev, struct sonic_local *lp,
 
        *new_addr = dma_map_single(lp->device, skb_put(*new_skb, SONIC_RBSIZE),
                                   SONIC_RBSIZE, DMA_FROM_DEVICE);
-       if (!*new_addr) {
+       if (dma_mapping_error(lp->device, *new_addr)) {
                dev_kfree_skb(*new_skb);
                *new_skb = NULL;
                return false;
index 59fb0583cc080530af616167dd56375b4c8f351b..0cc026b0aefd47d33f665b43e64ccd731cccc9af 100644 (file)
@@ -324,14 +324,15 @@ netdev_tx_t nfp_nfd3_tx(struct sk_buff *skb, struct net_device *netdev)
 
        /* Do not reorder - tso may adjust pkt cnt, vlan may override fields */
        nfp_nfd3_tx_tso(r_vec, txbuf, txd, skb, md_bytes);
-       nfp_nfd3_tx_csum(dp, r_vec, txbuf, txd, skb);
+       if (ipsec)
+               nfp_nfd3_ipsec_tx(txd, skb);
+       else
+               nfp_nfd3_tx_csum(dp, r_vec, txbuf, txd, skb);
        if (skb_vlan_tag_present(skb) && dp->ctrl & NFP_NET_CFG_CTRL_TXVLAN) {
                txd->flags |= NFD3_DESC_TX_VLAN;
                txd->vlan = cpu_to_le16(skb_vlan_tag_get(skb));
        }
 
-       if (ipsec)
-               nfp_nfd3_ipsec_tx(txd, skb);
        /* Gather DMA */
        if (nr_frags > 0) {
                __le64 second_half;
index e90f8c975903bd3c2cb6c802c878b3131d8e43b3..51087693072c289671a40fb8930d037c4913d301 100644 (file)
 void nfp_nfd3_ipsec_tx(struct nfp_nfd3_tx_desc *txd, struct sk_buff *skb)
 {
        struct xfrm_state *x = xfrm_input_state(skb);
+       struct xfrm_offload *xo = xfrm_offload(skb);
+       struct iphdr *iph = ip_hdr(skb);
+       int l4_proto;
 
        if (x->xso.dev && (x->xso.dev->features & NETIF_F_HW_ESP_TX_CSUM)) {
-               txd->flags |= NFD3_DESC_TX_CSUM | NFD3_DESC_TX_IP4_CSUM |
-                             NFD3_DESC_TX_TCP_CSUM | NFD3_DESC_TX_UDP_CSUM;
+               txd->flags |= NFD3_DESC_TX_CSUM;
+
+               if (iph->version == 4)
+                       txd->flags |= NFD3_DESC_TX_IP4_CSUM;
+
+               if (x->props.mode == XFRM_MODE_TRANSPORT)
+                       l4_proto = xo->proto;
+               else if (x->props.mode == XFRM_MODE_TUNNEL)
+                       l4_proto = xo->inner_ipproto;
+               else
+                       return;
+
+               switch (l4_proto) {
+               case IPPROTO_UDP:
+                       txd->flags |= NFD3_DESC_TX_UDP_CSUM;
+                       return;
+               case IPPROTO_TCP:
+                       txd->flags |= NFD3_DESC_TX_TCP_CSUM;
+                       return;
+               }
        }
 }
index d60c0e991a91cf3503c44d41f3cfbdf4ed419ac6..33b6d74adb4b55a90b0d98895860de8c4cbacafa 100644 (file)
@@ -387,7 +387,8 @@ netdev_tx_t nfp_nfdk_tx(struct sk_buff *skb, struct net_device *netdev)
        if (!skb_is_gso(skb)) {
                real_len = skb->len;
                /* Metadata desc */
-               metadata = nfp_nfdk_tx_csum(dp, r_vec, 1, skb, metadata);
+               if (!ipsec)
+                       metadata = nfp_nfdk_tx_csum(dp, r_vec, 1, skb, metadata);
                txd->raw = cpu_to_le64(metadata);
                txd++;
        } else {
@@ -395,7 +396,8 @@ netdev_tx_t nfp_nfdk_tx(struct sk_buff *skb, struct net_device *netdev)
                (txd + 1)->raw = nfp_nfdk_tx_tso(r_vec, txbuf, skb);
                real_len = txbuf->real_len;
                /* Metadata desc */
-               metadata = nfp_nfdk_tx_csum(dp, r_vec, txbuf->pkt_cnt, skb, metadata);
+               if (!ipsec)
+                       metadata = nfp_nfdk_tx_csum(dp, r_vec, txbuf->pkt_cnt, skb, metadata);
                txd->raw = cpu_to_le64(metadata);
                txd += 2;
                txbuf++;
index 58d8f59eb88543491e3e3d146283c086465366b3..cec199f4c852ff33e1132d21a1c09e9877ae0bea 100644 (file)
@@ -9,9 +9,13 @@
 u64 nfp_nfdk_ipsec_tx(u64 flags, struct sk_buff *skb)
 {
        struct xfrm_state *x = xfrm_input_state(skb);
+       struct iphdr *iph = ip_hdr(skb);
 
-       if (x->xso.dev && (x->xso.dev->features & NETIF_F_HW_ESP_TX_CSUM))
-               flags |= NFDK_DESC_TX_L3_CSUM | NFDK_DESC_TX_L4_CSUM;
+       if (x->xso.dev && (x->xso.dev->features & NETIF_F_HW_ESP_TX_CSUM)) {
+               if (iph->version == 4)
+                       flags |= NFDK_DESC_TX_L3_CSUM;
+               flags |= NFDK_DESC_TX_L4_CSUM;
+       }
 
        return flags;
 }
index 81b7ca0ad222eb897f9ab9085cb2d3d1052416ed..62f0bf91d1e1e52d9686bc7f6fa5249fdefd86c5 100644 (file)
@@ -38,6 +38,7 @@
 #include <net/tls.h>
 #include <net/vxlan.h>
 #include <net/xdp_sock_drv.h>
+#include <net/xfrm.h>
 
 #include "nfpcore/nfp_dev.h"
 #include "nfpcore/nfp_nsp.h"
@@ -1897,6 +1898,9 @@ nfp_net_features_check(struct sk_buff *skb, struct net_device *dev,
                        features &= ~NETIF_F_GSO_MASK;
        }
 
+       if (xfrm_offload(skb))
+               return features;
+
        /* VXLAN/GRE check */
        switch (vlan_get_protocol(skb)) {
        case htons(ETH_P_IP):
index d61cd32ec3b6575d15b399de16d222314f794c55..86a93cac26470d9ae9feff3cf70006123892ea1e 100644 (file)
@@ -5083,6 +5083,11 @@ static int qed_init_wfq_param(struct qed_hwfn *p_hwfn,
 
        num_vports = p_hwfn->qm_info.num_vports;
 
+       if (num_vports < 2) {
+               DP_NOTICE(p_hwfn, "Unexpected num_vports: %d\n", num_vports);
+               return -EINVAL;
+       }
+
        /* Accounting for the vports which are configured for WFQ explicitly */
        for (i = 0; i < num_vports; i++) {
                u32 tmp_speed;
index 6190adf965bcab448a81a474d4faec0f6bb4eaa5..f55eed092f25d293a6ed567a3c93ad7da1af3429 100644 (file)
@@ -422,7 +422,7 @@ qed_mfw_get_tlv_time_value(struct qed_mfw_tlv_time *p_time,
        if (p_time->hour > 23)
                p_time->hour = 0;
        if (p_time->min > 59)
-               p_time->hour = 0;
+               p_time->min = 0;
        if (p_time->msec > 999)
                p_time->msec = 0;
        if (p_time->usec > 999)
index 2bf18748581d3d155775a0bc23c0ec2fd32c6f98..fa167b1aa01909a84719d3fe126d49648566a225 100644 (file)
@@ -4404,6 +4404,9 @@ qed_iov_configure_min_tx_rate(struct qed_dev *cdev, int vfid, u32 rate)
        }
 
        vf = qed_iov_get_vf_info(QED_LEADING_HWFN(cdev), (u16)vfid, true);
+       if (!vf)
+               return -EINVAL;
+
        vport_id = vf->vport_id;
 
        return qed_configure_vport_wfq(cdev, vport_id, rate);
@@ -5152,7 +5155,7 @@ static void qed_iov_handle_trust_change(struct qed_hwfn *hwfn)
 
                /* Validate that the VF has a configured vport */
                vf = qed_iov_get_vf_info(hwfn, i, true);
-               if (!vf->vport_instance)
+               if (!vf || !vf->vport_instance)
                        continue;
 
                memset(&params, 0, sizeof(params));
index 87f76bac2e463af4162eefb6eec6c39ac4add088..eb827b86ecae8130a0565cd75db3a729991c3a42 100644 (file)
@@ -628,7 +628,13 @@ int qlcnic_fw_create_ctx(struct qlcnic_adapter *dev)
        int i, err, ring;
 
        if (dev->flags & QLCNIC_NEED_FLR) {
-               pci_reset_function(dev->pdev);
+               err = pci_reset_function(dev->pdev);
+               if (err) {
+                       dev_err(&dev->pdev->dev,
+                               "Adapter reset failed (%d). Please reboot\n",
+                               err);
+                       return err;
+               }
                dev->flags &= ~QLCNIC_NEED_FLR;
        }
 
index 3115b2c128980db23bf85851fa9724a5359f0509..eaa50050aa0b798a4ab1cfa201a388d32f88b527 100644 (file)
@@ -724,9 +724,15 @@ static int emac_remove(struct platform_device *pdev)
        struct net_device *netdev = dev_get_drvdata(&pdev->dev);
        struct emac_adapter *adpt = netdev_priv(netdev);
 
+       netif_carrier_off(netdev);
+       netif_tx_disable(netdev);
+
        unregister_netdev(netdev);
        netif_napi_del(&adpt->rx_q.napi);
 
+       free_irq(adpt->irq.irq, &adpt->irq);
+       cancel_work_sync(&adpt->work_thread);
+
        emac_clks_teardown(adpt);
 
        put_device(&adpt->phydev->mdio.dev);
index 930496cd34ed00c61d4b37d11b9008d777fe0609..b50f16786c246abbe25553103ae699f7e5f10592 100644 (file)
@@ -826,6 +826,9 @@ static void rtl8168h_2_hw_phy_config(struct rtl8169_private *tp,
        /* disable phy pfm mode */
        phy_modify_paged(phydev, 0x0a44, 0x11, BIT(7), 0);
 
+       /* disable 10m pll off */
+       phy_modify_paged(phydev, 0x0a43, 0x10, BIT(0), 0);
+
        rtl8168g_disable_aldps(phydev);
        rtl8168g_config_eee_phy(phydev);
 }
index 0f54849a38235fe7e564f7fe870d501201f6fbc5..894e2690c64372a2beb3ab13907722e823b3ffef 100644 (file)
@@ -1455,8 +1455,6 @@ static int ravb_phy_init(struct net_device *ndev)
                phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
        }
 
-       /* Indicate that the MAC is responsible for managing PHY PM */
-       phydev->mac_managed_pm = true;
        phy_attached_info(phydev);
 
        return 0;
@@ -2379,6 +2377,8 @@ static int ravb_mdio_init(struct ravb_private *priv)
 {
        struct platform_device *pdev = priv->pdev;
        struct device *dev = &pdev->dev;
+       struct phy_device *phydev;
+       struct device_node *pn;
        int error;
 
        /* Bitbang init */
@@ -2400,6 +2400,14 @@ static int ravb_mdio_init(struct ravb_private *priv)
        if (error)
                goto out_free_bus;
 
+       pn = of_parse_phandle(dev->of_node, "phy-handle", 0);
+       phydev = of_phy_find_device(pn);
+       if (phydev) {
+               phydev->mac_managed_pm = true;
+               put_device(&phydev->mdio.dev);
+       }
+       of_node_put(pn);
+
        return 0;
 
 out_free_bus:
index 853394e5bb8b9834959003ec23e014d960930f84..c4f93d24c6a4231589ed390dcaf862fb22314eba 100644 (file)
@@ -702,13 +702,14 @@ static bool rswitch_rx(struct net_device *ndev, int *quota)
        u16 pkt_len;
        u32 get_ts;
 
+       if (*quota <= 0)
+               return true;
+
        boguscnt = min_t(int, gq->ring_size, *quota);
        limit = boguscnt;
 
        desc = &gq->rx_ring[gq->cur];
        while ((desc->desc.die_dt & DT_MASK) != DT_FEMPTY) {
-               if (--boguscnt < 0)
-                       break;
                dma_rmb();
                pkt_len = le16_to_cpu(desc->desc.info_ds) & RX_DS;
                skb = gq->skbs[gq->cur];
@@ -734,6 +735,9 @@ static bool rswitch_rx(struct net_device *ndev, int *quota)
 
                gq->cur = rswitch_next_queue_index(gq, true, 1);
                desc = &gq->rx_ring[gq->cur];
+
+               if (--boguscnt <= 0)
+                       break;
        }
 
        num = rswitch_get_num_cur_queues(gq);
@@ -745,7 +749,7 @@ static bool rswitch_rx(struct net_device *ndev, int *quota)
                goto err;
        gq->dirty = rswitch_next_queue_index(gq, false, num);
 
-       *quota -= limit - (++boguscnt);
+       *quota -= limit - boguscnt;
 
        return boguscnt <= 0;
 
@@ -1437,7 +1441,10 @@ static int rswitch_open(struct net_device *ndev)
        rswitch_enadis_data_irq(rdev->priv, rdev->tx_queue->index, true);
        rswitch_enadis_data_irq(rdev->priv, rdev->rx_queue->index, true);
 
-       iowrite32(GWCA_TS_IRQ_BIT, rdev->priv->addr + GWTSDIE);
+       if (bitmap_empty(rdev->priv->opened_ports, RSWITCH_NUM_PORTS))
+               iowrite32(GWCA_TS_IRQ_BIT, rdev->priv->addr + GWTSDIE);
+
+       bitmap_set(rdev->priv->opened_ports, rdev->port, 1);
 
        return 0;
 };
@@ -1448,8 +1455,10 @@ static int rswitch_stop(struct net_device *ndev)
        struct rswitch_gwca_ts_info *ts_info, *ts_info2;
 
        netif_tx_stop_all_queues(ndev);
+       bitmap_clear(rdev->priv->opened_ports, rdev->port, 1);
 
-       iowrite32(GWCA_TS_IRQ_BIT, rdev->priv->addr + GWTSDID);
+       if (bitmap_empty(rdev->priv->opened_ports, RSWITCH_NUM_PORTS))
+               iowrite32(GWCA_TS_IRQ_BIT, rdev->priv->addr + GWTSDID);
 
        list_for_each_entry_safe(ts_info, ts_info2, &rdev->priv->gwca.ts_info_list, list) {
                if (ts_info->port != rdev->port)
index 27d3d38c055f0643897e2756d5fb4ca6618bd6b6..b3e0411b408ef887b72c2ad0f343273a1f085178 100644 (file)
@@ -998,6 +998,7 @@ struct rswitch_private {
        struct rcar_gen4_ptp_private *ptp_priv;
 
        struct rswitch_device *rdev[RSWITCH_NUM_PORTS];
+       DECLARE_BITMAP(opened_ports, RSWITCH_NUM_PORTS);
 
        struct rswitch_gwca gwca;
        struct rswitch_etha etha[RSWITCH_NUM_PORTS];
index ed17163d781144f7d41aca9a356f66e4f6ca3879..d8ec729825be44fe5735eb0333100ef0eebab260 100644 (file)
@@ -2029,8 +2029,6 @@ static int sh_eth_phy_init(struct net_device *ndev)
        if (mdp->cd->register_type != SH_ETH_REG_GIGABIT)
                phy_set_max_speed(phydev, SPEED_100);
 
-       /* Indicate that the MAC is responsible for managing PHY PM */
-       phydev->mac_managed_pm = true;
        phy_attached_info(phydev);
 
        return 0;
@@ -3097,6 +3095,8 @@ static int sh_mdio_init(struct sh_eth_private *mdp,
        struct bb_info *bitbang;
        struct platform_device *pdev = mdp->pdev;
        struct device *dev = &mdp->pdev->dev;
+       struct phy_device *phydev;
+       struct device_node *pn;
 
        /* create bit control struct for PHY */
        bitbang = devm_kzalloc(dev, sizeof(struct bb_info), GFP_KERNEL);
@@ -3133,6 +3133,14 @@ static int sh_mdio_init(struct sh_eth_private *mdp,
        if (ret)
                goto out_free_bus;
 
+       pn = of_parse_phandle(dev->of_node, "phy-handle", 0);
+       phydev = of_phy_find_device(pn);
+       if (phydev) {
+               phydev->mac_managed_pm = true;
+               put_device(&phydev->mdio.dev);
+       }
+       of_node_put(pn);
+
        return 0;
 
 out_free_bus:
index 7022fb2005a2f6214ea07c6fecf83efdc7697c6f..d30459dbfe8f838e7677d26038824484353f5eff 100644 (file)
@@ -1304,7 +1304,8 @@ static void efx_ef10_fini_nic(struct efx_nic *efx)
 static int efx_ef10_init_nic(struct efx_nic *efx)
 {
        struct efx_ef10_nic_data *nic_data = efx->nic_data;
-       netdev_features_t hw_enc_features = 0;
+       struct net_device *net_dev = efx->net_dev;
+       netdev_features_t tun_feats, tso_feats;
        int rc;
 
        if (nic_data->must_check_datapath_caps) {
@@ -1349,20 +1350,30 @@ static int efx_ef10_init_nic(struct efx_nic *efx)
                nic_data->must_restore_piobufs = false;
        }
 
-       /* add encapsulated checksum offload features */
+       /* encap features might change during reset if fw variant changed */
        if (efx_has_cap(efx, VXLAN_NVGRE) && !efx_ef10_is_vf(efx))
-               hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
-       /* add encapsulated TSO features */
-       if (efx_has_cap(efx, TX_TSO_V2_ENCAP)) {
-               netdev_features_t encap_tso_features;
+               net_dev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+       else
+               net_dev->hw_enc_features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
 
-               encap_tso_features = NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
-                       NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM;
+       tun_feats = NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
+                   NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM;
+       tso_feats = NETIF_F_TSO | NETIF_F_TSO6;
 
-               hw_enc_features |= encap_tso_features | NETIF_F_TSO;
-               efx->net_dev->features |= encap_tso_features;
+       if (efx_has_cap(efx, TX_TSO_V2_ENCAP)) {
+               /* If this is first nic_init, or if it is a reset and a new fw
+                * variant has added new features, enable them by default.
+                * If the features are not new, maintain their current value.
+                */
+               if (!(net_dev->hw_features & tun_feats))
+                       net_dev->features |= tun_feats;
+               net_dev->hw_enc_features |= tun_feats | tso_feats;
+               net_dev->hw_features |= tun_feats;
+       } else {
+               net_dev->hw_enc_features &= ~(tun_feats | tso_feats);
+               net_dev->hw_features &= ~tun_feats;
+               net_dev->features &= ~tun_feats;
        }
-       efx->net_dev->hw_enc_features = hw_enc_features;
 
        /* don't fail init if RSS setup doesn't work */
        rc = efx->type->rx_push_rss_config(efx, false,
@@ -4021,7 +4032,10 @@ static unsigned int efx_ef10_recycle_ring_size(const struct efx_nic *efx)
         NETIF_F_HW_VLAN_CTAG_FILTER |  \
         NETIF_F_IPV6_CSUM |            \
         NETIF_F_RXHASH |               \
-        NETIF_F_NTUPLE)
+        NETIF_F_NTUPLE |               \
+        NETIF_F_SG |                   \
+        NETIF_F_RXCSUM |               \
+        NETIF_F_RXALL)
 
 const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
        .is_vf = true,
index 02c2adeb0a12007d2cbf4f5b2349c1051ea578f1..1eceffa02b557a4f271697a7ae36d5a20afc2450 100644 (file)
@@ -541,7 +541,6 @@ int efx_net_open(struct net_device *net_dev)
        else
                efx->state = STATE_NET_UP;
 
-       efx_selftest_async_start(efx);
        return 0;
 }
 
@@ -1001,21 +1000,18 @@ static int efx_pci_probe_post_io(struct efx_nic *efx)
        }
 
        /* Determine netdevice features */
-       net_dev->features |= (efx->type->offload_features | NETIF_F_SG |
-                             NETIF_F_TSO | NETIF_F_RXCSUM | NETIF_F_RXALL);
-       if (efx->type->offload_features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM)) {
-               net_dev->features |= NETIF_F_TSO6;
-               if (efx_has_cap(efx, TX_TSO_V2_ENCAP))
-                       net_dev->hw_enc_features |= NETIF_F_TSO6;
-       }
-       /* Check whether device supports TSO */
-       if (!efx->type->tso_versions || !efx->type->tso_versions(efx))
-               net_dev->features &= ~NETIF_F_ALL_TSO;
+       net_dev->features |= efx->type->offload_features;
+
+       /* Add TSO features */
+       if (efx->type->tso_versions && efx->type->tso_versions(efx))
+               net_dev->features |= NETIF_F_TSO | NETIF_F_TSO6;
+
        /* Mask for features that also apply to VLAN devices */
        net_dev->vlan_features |= (NETIF_F_HW_CSUM | NETIF_F_SG |
                                   NETIF_F_HIGHDMA | NETIF_F_ALL_TSO |
                                   NETIF_F_RXCSUM);
 
+       /* Determine user configurable features */
        net_dev->hw_features |= net_dev->features & ~efx->fixed_features;
 
        /* Disable receiving frames with bad FCS, by default. */
index cc30524c2fe45c9f49857ac6af7d5629166992e2..361687de308dceedce7b68105e32173840d6f9d4 100644 (file)
@@ -544,6 +544,8 @@ void efx_start_all(struct efx_nic *efx)
        /* Start the hardware monitor if there is one */
        efx_start_monitor(efx);
 
+       efx_selftest_async_start(efx);
+
        /* Link state detection is normally event-driven; we have
         * to poll now because we could have missed a change
         */
index a2e511912e6a9f0d1476170f4adbfff5b6a9a07d..a690d139e1770f8b796c1fb72c3fae61639f5ac8 100644 (file)
@@ -1037,8 +1037,6 @@ static int smsc911x_mii_probe(struct net_device *dev)
                return ret;
        }
 
-       /* Indicate that the MAC is responsible for managing PHY PM */
-       phydev->mac_managed_pm = true;
        phy_attached_info(phydev);
 
        phy_set_max_speed(phydev, SPEED_100);
@@ -1066,6 +1064,7 @@ static int smsc911x_mii_init(struct platform_device *pdev,
                             struct net_device *dev)
 {
        struct smsc911x_data *pdata = netdev_priv(dev);
+       struct phy_device *phydev;
        int err = -ENXIO;
 
        pdata->mii_bus = mdiobus_alloc();
@@ -1108,6 +1107,10 @@ static int smsc911x_mii_init(struct platform_device *pdev,
                goto err_out_free_bus_2;
        }
 
+       phydev = phy_find_first(pdata->mii_bus);
+       if (phydev)
+               phydev->mac_managed_pm = true;
+
        return 0;
 
 err_out_free_bus_2:
index 6b5d96bced475f5aac8eab8130988c7451bf6b72..54bb072aeb2d3c39950b96aca0203dc0b367cf95 100644 (file)
@@ -418,6 +418,7 @@ struct dma_features {
        unsigned int frpbs;
        unsigned int frpes;
        unsigned int addr64;
+       unsigned int host_dma_width;
        unsigned int rssen;
        unsigned int vlhash;
        unsigned int sphen;
@@ -531,7 +532,6 @@ struct mac_device_info {
        unsigned int xlgmac;
        unsigned int num_vlan;
        u32 vlan_filter[32];
-       unsigned int promisc;
        bool vlan_fail_q_en;
        u8 vlan_fail_q;
 };
index ac8580f501e2ef07d2db27f5185e8ace9d5cdb3d..2a2be65d65a03c37d1ba182fe42e9efd125b4087 100644 (file)
@@ -213,8 +213,7 @@ imx_dwmac_parse_dt(struct imx_priv_data *dwmac, struct device *dev)
        struct device_node *np = dev->of_node;
        int err = 0;
 
-       if (of_get_property(np, "snps,rmii_refclk_ext", NULL))
-               dwmac->rmii_refclk_ext = true;
+       dwmac->rmii_refclk_ext = of_property_read_bool(np, "snps,rmii_refclk_ext");
 
        dwmac->clk_tx = devm_clk_get(dev, "tx");
        if (IS_ERR(dwmac->clk_tx)) {
@@ -289,7 +288,7 @@ static int imx_dwmac_probe(struct platform_device *pdev)
                goto err_parse_dt;
        }
 
-       plat_dat->addr64 = dwmac->ops->addr_width;
+       plat_dat->host_dma_width = dwmac->ops->addr_width;
        plat_dat->init = imx_dwmac_init;
        plat_dat->exit = imx_dwmac_exit;
        plat_dat->clks_config = imx_dwmac_clks_config;
index 7deb1f817dacc564fb9c4453a4fba3a6fb6c51bd..ab9f876b6df7e901076968187c47919c13e2feb8 100644 (file)
@@ -251,7 +251,6 @@ static void intel_speed_mode_2500(struct net_device *ndev, void *intel_data)
                priv->plat->mdio_bus_data->xpcs_an_inband = false;
        } else {
                priv->plat->max_speed = 1000;
-               priv->plat->mdio_bus_data->xpcs_an_inband = true;
        }
 }
 
@@ -684,7 +683,7 @@ static int ehl_pse0_common_data(struct pci_dev *pdev,
 
        intel_priv->is_pse = true;
        plat->bus_id = 2;
-       plat->addr64 = 32;
+       plat->host_dma_width = 32;
 
        plat->clk_ptp_rate = 200000000;
 
@@ -725,7 +724,7 @@ static int ehl_pse1_common_data(struct pci_dev *pdev,
 
        intel_priv->is_pse = true;
        plat->bus_id = 3;
-       plat->addr64 = 32;
+       plat->host_dma_width = 32;
 
        plat->clk_ptp_rate = 200000000;
 
index 2f7d8e4561d920cf8e2dc7524c6eed9b9dbcbb00..9ae31e3dc82187c8abd6fe3fcaa959d36c84f207 100644 (file)
@@ -591,7 +591,7 @@ static int mediatek_dwmac_common_data(struct platform_device *pdev,
        plat->use_phy_wol = priv_plat->mac_wol ? 0 : 1;
        plat->riwt_off = 1;
        plat->maxmtu = ETH_DATA_LEN;
-       plat->addr64 = priv_plat->variant->dma_bit_mask;
+       plat->host_dma_width = priv_plat->variant->dma_bit_mask;
        plat->bsp_priv = priv_plat;
        plat->init = mediatek_dwmac_init;
        plat->clks_config = mediatek_dwmac_clks_config;
index 8c7a0b7c99520ac593285b6a22b669313a4068da..36251ec2589c99d117c78e73129e8c17a99be844 100644 (file)
@@ -472,12 +472,6 @@ static int dwmac4_add_hw_vlan_rx_fltr(struct net_device *dev,
        if (vid > 4095)
                return -EINVAL;
 
-       if (hw->promisc) {
-               netdev_err(dev,
-                          "Adding VLAN in promisc mode not supported\n");
-               return -EPERM;
-       }
-
        /* Single Rx VLAN Filter */
        if (hw->num_vlan == 1) {
                /* For single VLAN filter, VID 0 means VLAN promiscuous */
@@ -527,12 +521,6 @@ static int dwmac4_del_hw_vlan_rx_fltr(struct net_device *dev,
 {
        int i, ret = 0;
 
-       if (hw->promisc) {
-               netdev_err(dev,
-                          "Deleting VLAN in promisc mode not supported\n");
-               return -EPERM;
-       }
-
        /* Single Rx VLAN Filter */
        if (hw->num_vlan == 1) {
                if ((hw->vlan_filter[0] & GMAC_VLAN_TAG_VID) == vid) {
@@ -557,39 +545,6 @@ static int dwmac4_del_hw_vlan_rx_fltr(struct net_device *dev,
        return ret;
 }
 
-static void dwmac4_vlan_promisc_enable(struct net_device *dev,
-                                      struct mac_device_info *hw)
-{
-       void __iomem *ioaddr = hw->pcsr;
-       u32 value;
-       u32 hash;
-       u32 val;
-       int i;
-
-       /* Single Rx VLAN Filter */
-       if (hw->num_vlan == 1) {
-               dwmac4_write_single_vlan(dev, 0);
-               return;
-       }
-
-       /* Extended Rx VLAN Filter Enable */
-       for (i = 0; i < hw->num_vlan; i++) {
-               if (hw->vlan_filter[i] & GMAC_VLAN_TAG_DATA_VEN) {
-                       val = hw->vlan_filter[i] & ~GMAC_VLAN_TAG_DATA_VEN;
-                       dwmac4_write_vlan_filter(dev, hw, i, val);
-               }
-       }
-
-       hash = readl(ioaddr + GMAC_VLAN_HASH_TABLE);
-       if (hash & GMAC_VLAN_VLHT) {
-               value = readl(ioaddr + GMAC_VLAN_TAG);
-               if (value & GMAC_VLAN_VTHM) {
-                       value &= ~GMAC_VLAN_VTHM;
-                       writel(value, ioaddr + GMAC_VLAN_TAG);
-               }
-       }
-}
-
 static void dwmac4_restore_hw_vlan_rx_fltr(struct net_device *dev,
                                           struct mac_device_info *hw)
 {
@@ -709,22 +664,12 @@ static void dwmac4_set_filter(struct mac_device_info *hw,
        }
 
        /* VLAN filtering */
-       if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
+       if (dev->flags & IFF_PROMISC && !hw->vlan_fail_q_en)
+               value &= ~GMAC_PACKET_FILTER_VTFE;
+       else if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
                value |= GMAC_PACKET_FILTER_VTFE;
 
        writel(value, ioaddr + GMAC_PACKET_FILTER);
-
-       if (dev->flags & IFF_PROMISC && !hw->vlan_fail_q_en) {
-               if (!hw->promisc) {
-                       hw->promisc = 1;
-                       dwmac4_vlan_promisc_enable(dev, hw);
-               }
-       } else {
-               if (hw->promisc) {
-                       hw->promisc = 0;
-                       dwmac4_restore_hw_vlan_rx_fltr(dev, hw);
-               }
-       }
 }
 
 static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
index e4902a7bb61eddad5bc7cc32f50854e301168756..d7fcab0570322382599f3627e7a26041cfaf311f 100644 (file)
@@ -1134,20 +1134,26 @@ static void stmmac_check_pcs_mode(struct stmmac_priv *priv)
 static int stmmac_init_phy(struct net_device *dev)
 {
        struct stmmac_priv *priv = netdev_priv(dev);
+       struct fwnode_handle *phy_fwnode;
        struct fwnode_handle *fwnode;
        int ret;
 
+       if (!phylink_expects_phy(priv->phylink))
+               return 0;
+
        fwnode = of_fwnode_handle(priv->plat->phylink_node);
        if (!fwnode)
                fwnode = dev_fwnode(priv->device);
 
        if (fwnode)
-               ret = phylink_fwnode_phy_connect(priv->phylink, fwnode, 0);
+               phy_fwnode = fwnode_get_phy_node(fwnode);
+       else
+               phy_fwnode = NULL;
 
        /* Some DT bindings do not set-up the PHY handle. Let's try to
         * manually parse it
         */
-       if (!fwnode || ret) {
+       if (!phy_fwnode || IS_ERR(phy_fwnode)) {
                int addr = priv->plat->phy_addr;
                struct phy_device *phydev;
 
@@ -1163,6 +1169,9 @@ static int stmmac_init_phy(struct net_device *dev)
                }
 
                ret = phylink_connect_phy(priv->phylink, phydev);
+       } else {
+               fwnode_handle_put(phy_fwnode);
+               ret = phylink_fwnode_phy_connect(priv->phylink, fwnode, 0);
        }
 
        if (!priv->plat->pmt) {
@@ -1170,6 +1179,7 @@ static int stmmac_init_phy(struct net_device *dev)
 
                phylink_ethtool_get_wol(priv->phylink, &wol);
                device_set_wakeup_capable(priv->device, !!wol.supported);
+               device_set_wakeup_enable(priv->device, !!wol.wolopts);
        }
 
        return ret;
@@ -1430,7 +1440,7 @@ static int stmmac_init_rx_buffers(struct stmmac_priv *priv,
        struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
        gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
 
-       if (priv->dma_cap.addr64 <= 32)
+       if (priv->dma_cap.host_dma_width <= 32)
                gfp |= GFP_DMA32;
 
        if (!buf->page) {
@@ -4586,7 +4596,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
        unsigned int entry = rx_q->dirty_rx;
        gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
 
-       if (priv->dma_cap.addr64 <= 32)
+       if (priv->dma_cap.host_dma_width <= 32)
                gfp |= GFP_DMA32;
 
        while (dirty-- > 0) {
@@ -6204,7 +6214,7 @@ static int stmmac_dma_cap_show(struct seq_file *seq, void *v)
        seq_printf(seq, "\tFlexible RX Parser: %s\n",
                   priv->dma_cap.frpsel ? "Y" : "N");
        seq_printf(seq, "\tEnhanced Addressing: %d\n",
-                  priv->dma_cap.addr64);
+                  priv->dma_cap.host_dma_width);
        seq_printf(seq, "\tReceive Side Scaling: %s\n",
                   priv->dma_cap.rssen ? "Y" : "N");
        seq_printf(seq, "\tVLAN Hash Filtering: %s\n",
@@ -6621,6 +6631,8 @@ int stmmac_xdp_open(struct net_device *dev)
                goto init_error;
        }
 
+       stmmac_reset_queues_param(priv);
+
        /* DMA CSR Channel configuration */
        for (chan = 0; chan < dma_csr_ch; chan++) {
                stmmac_init_chan(priv, priv->ioaddr, priv->plat->dma_cfg, chan);
@@ -6947,7 +6959,7 @@ static void stmmac_napi_del(struct net_device *dev)
 int stmmac_reinit_queues(struct net_device *dev, u32 rx_cnt, u32 tx_cnt)
 {
        struct stmmac_priv *priv = netdev_priv(dev);
-       int ret = 0;
+       int ret = 0, i;
 
        if (netif_running(dev))
                stmmac_release(dev);
@@ -6956,6 +6968,10 @@ int stmmac_reinit_queues(struct net_device *dev, u32 rx_cnt, u32 tx_cnt)
 
        priv->plat->rx_queues_to_use = rx_cnt;
        priv->plat->tx_queues_to_use = tx_cnt;
+       if (!netif_is_rxfh_configured(dev))
+               for (i = 0; i < ARRAY_SIZE(priv->rss.table); i++)
+                       priv->rss.table[i] = ethtool_rxfh_indir_default(i,
+                                                                       rx_cnt);
 
        stmmac_napi_add(dev);
 
@@ -7177,20 +7193,22 @@ int stmmac_dvr_probe(struct device *device,
                dev_info(priv->device, "SPH feature enabled\n");
        }
 
-       /* The current IP register MAC_HW_Feature1[ADDR64] only define
-        * 32/40/64 bit width, but some SOC support others like i.MX8MP
-        * support 34 bits but it map to 40 bits width in MAC_HW_Feature1[ADDR64].
-        * So overwrite dma_cap.addr64 according to HW real design.
+       /* Ideally our host DMA address width is the same as for the
+        * device. However, it may differ and then we have to use our
+        * host DMA width for allocation and the device DMA width for
+        * register handling.
         */
-       if (priv->plat->addr64)
-               priv->dma_cap.addr64 = priv->plat->addr64;
+       if (priv->plat->host_dma_width)
+               priv->dma_cap.host_dma_width = priv->plat->host_dma_width;
+       else
+               priv->dma_cap.host_dma_width = priv->dma_cap.addr64;
 
-       if (priv->dma_cap.addr64) {
+       if (priv->dma_cap.host_dma_width) {
                ret = dma_set_mask_and_coherent(device,
-                               DMA_BIT_MASK(priv->dma_cap.addr64));
+                               DMA_BIT_MASK(priv->dma_cap.host_dma_width));
                if (!ret) {
-                       dev_info(priv->device, "Using %d bits DMA width\n",
-                                priv->dma_cap.addr64);
+                       dev_info(priv->device, "Using %d/%d bits DMA host/device width\n",
+                                priv->dma_cap.host_dma_width, priv->dma_cap.addr64);
 
                        /*
                         * If more than 32 bits can be addressed, make sure to
@@ -7205,7 +7223,7 @@ int stmmac_dvr_probe(struct device *device,
                                goto error_hw_init;
                        }
 
-                       priv->dma_cap.addr64 = 32;
+                       priv->dma_cap.host_dma_width = 32;
                }
        }
 
index 8addee6d04bd803636c0e14577220332371632c2..734a817d3c945ed5e6c5ff349760508ff6c5c670 100644 (file)
@@ -287,6 +287,9 @@ static int vsw_port_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 
        hp = mdesc_grab();
 
+       if (!hp)
+               return -ENODEV;
+
        rmac = mdesc_get_property(hp, vdev->mp, remote_macaddr_prop, &len);
        err = -ENODEV;
        if (!rmac) {
index e6144d963eaaadb3343906fac020b38f1734533f..7a2e767762974cf9dc63d03c17a822630f8783ca 100644 (file)
@@ -4522,7 +4522,7 @@ static int niu_alloc_channels(struct niu *np)
 
                err = niu_rbr_fill(np, rp, GFP_KERNEL);
                if (err)
-                       return err;
+                       goto out_err;
        }
 
        tx_rings = kcalloc(num_tx_rings, sizeof(struct tx_ring_info),
@@ -9271,7 +9271,7 @@ static int niu_get_of_props(struct niu *np)
        if (model)
                strcpy(np->vpd.model, model);
 
-       if (of_find_property(dp, "hot-swappable-phy", NULL)) {
+       if (of_property_read_bool(dp, "hot-swappable-phy")) {
                np->flags |= (NIU_FLAGS_10G | NIU_FLAGS_FIBER |
                        NIU_FLAGS_HOTPLUG_PHY);
        }
index fe86fbd585861c6069533d50c9e8d7f9f0b3a814..e220620d0ffc9070cf07c063a09ccbe1ced18a37 100644 (file)
@@ -433,6 +433,9 @@ static int vnet_port_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 
        hp = mdesc_grab();
 
+       if (!hp)
+               return -ENODEV;
+
        vp = vnet_find_parent(hp, vdev->mp, vdev);
        if (IS_ERR(vp)) {
                pr_err("Cannot find port parent vnet\n");
index 4e3861c47708c9e2af4d5912a3dc2c7c8e9feb99..bcea87b7151c0b1245fd9c60eccbcf7885852449 100644 (file)
@@ -2926,7 +2926,8 @@ err_free_phylink:
        am65_cpsw_nuss_phylink_cleanup(common);
        am65_cpts_release(common->cpts);
 err_of_clear:
-       of_platform_device_destroy(common->mdio_dev, NULL);
+       if (common->mdio_dev)
+               of_platform_device_destroy(common->mdio_dev, NULL);
 err_pm_clear:
        pm_runtime_put_sync(dev);
        pm_runtime_disable(dev);
@@ -2956,7 +2957,8 @@ static int am65_cpsw_nuss_remove(struct platform_device *pdev)
        am65_cpts_release(common->cpts);
        am65_cpsw_disable_serdes_phy(common);
 
-       of_platform_device_destroy(common->mdio_dev, NULL);
+       if (common->mdio_dev)
+               of_platform_device_destroy(common->mdio_dev, NULL);
 
        pm_runtime_put_sync(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
index 16ee9c29cb35a5c77bfc186d7903a70519060b7b..8caf85acbb6af1221a6b4a9d35bb99ac3c0645d5 100644 (file)
@@ -636,6 +636,10 @@ static void am65_cpts_perout_enable_hw(struct am65_cpts *cpts,
                val = lower_32_bits(cycles);
                am65_cpts_write32(cpts, val, genf[req->index].length);
 
+               am65_cpts_write32(cpts, 0, genf[req->index].control);
+               am65_cpts_write32(cpts, 0, genf[req->index].ppm_hi);
+               am65_cpts_write32(cpts, 0, genf[req->index].ppm_low);
+
                cpts->genf_enable |= BIT(req->index);
        } else {
                am65_cpts_write32(cpts, 0, genf[req->index].length);
index e8f38e3f7706eb69e11bf4b82cbba9afbb938b09..25e707d7b87ce320e7b3f68328890ec610d39b6b 100644 (file)
@@ -226,8 +226,7 @@ static int cpsw_phy_sel_probe(struct platform_device *pdev)
        if (IS_ERR(priv->gmii_sel))
                return PTR_ERR(priv->gmii_sel);
 
-       if (of_find_property(pdev->dev.of_node, "rmii-clock-ext", NULL))
-               priv->rmii_clock_external = true;
+       priv->rmii_clock_external = of_property_read_bool(pdev->dev.of_node, "rmii-clock-ext");
 
        dev_set_drvdata(&pdev->dev, priv);
 
index 37f0b62ec5d6a3bc99914fcee1681d9e3ff1bfdb..f9cd566d1c9b588e5cd547ca4109567dc50114e4 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/of.h>
 #include <linux/of_mdio.h>
 #include <linux/of_net.h>
-#include <linux/of_device.h>
+#include <linux/of_platform.h>
 #include <linux/if_vlan.h>
 #include <linux/kmemleak.h>
 #include <linux/sys_soc.h>
index 35128dd45ffceb27a6dafea19a2c9d342feb95c1..c61e4e44a78f06ddbd28e94ce65e2af410291fe7 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/io.h>
 #include <linux/clk.h>
+#include <linux/platform_device.h>
 #include <linux/timer.h>
 #include <linux/module.h>
 #include <linux/irqreturn.h>
@@ -23,7 +24,7 @@
 #include <linux/of.h>
 #include <linux/of_mdio.h>
 #include <linux/of_net.h>
-#include <linux/of_device.h>
+#include <linux/of_platform.h>
 #include <linux/if_vlan.h>
 #include <linux/kmemleak.h>
 #include <linux/sys_soc.h>
index 751fb0bc65c501cb7b4df87c44a453bc10e05c5d..2adf82a32bf6a6b90e4461325c2964fe52eacd0d 100644 (file)
@@ -3583,13 +3583,11 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
        /* init the hw stats lock */
        spin_lock_init(&gbe_dev->hw_stats_lock);
 
-       if (of_find_property(node, "enable-ale", NULL)) {
-               gbe_dev->enable_ale = true;
+       gbe_dev->enable_ale = of_property_read_bool(node, "enable-ale");
+       if (gbe_dev->enable_ale)
                dev_info(dev, "ALE enabled\n");
-       } else {
-               gbe_dev->enable_ale = false;
+       else
                dev_dbg(dev, "ALE bypass enabled*\n");
-       }
 
        ret = of_property_read_u32(node, "tx-queue",
                                   &gbe_dev->tx_queue_id);
index cf8de8a7a8a1eb0ef0c79ebd69daeb6305783ffc..9d535ae5962662106654894dca8bd81b4455e3b5 100644 (file)
@@ -317,15 +317,17 @@ static int gelic_card_init_chain(struct gelic_card *card,
 
        /* set up the hardware pointers in each descriptor */
        for (i = 0; i < no; i++, descr++) {
+               dma_addr_t cpu_addr;
+
                gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);
-               descr->bus_addr =
-                       dma_map_single(ctodev(card), descr,
-                                      GELIC_DESCR_SIZE,
-                                      DMA_BIDIRECTIONAL);
 
-               if (!descr->bus_addr)
+               cpu_addr = dma_map_single(ctodev(card), descr,
+                                         GELIC_DESCR_SIZE, DMA_BIDIRECTIONAL);
+
+               if (dma_mapping_error(ctodev(card), cpu_addr))
                        goto iommu_error;
 
+               descr->bus_addr = cpu_to_be32(cpu_addr);
                descr->next = descr + 1;
                descr->prev = descr - 1;
        }
@@ -365,26 +367,28 @@ iommu_error:
  *
  * allocates a new rx skb, iommu-maps it and attaches it to the descriptor.
  * Activate the descriptor state-wise
+ *
+ * Gelic RX sk_buffs must be aligned to GELIC_NET_RXBUF_ALIGN and the length
+ * must be a multiple of GELIC_NET_RXBUF_ALIGN.
  */
 static int gelic_descr_prepare_rx(struct gelic_card *card,
                                  struct gelic_descr *descr)
 {
+       static const unsigned int rx_skb_size =
+               ALIGN(GELIC_NET_MAX_FRAME, GELIC_NET_RXBUF_ALIGN) +
+               GELIC_NET_RXBUF_ALIGN - 1;
+       dma_addr_t cpu_addr;
        int offset;
-       unsigned int bufsize;
 
        if (gelic_descr_get_status(descr) !=  GELIC_DESCR_DMA_NOT_IN_USE)
                dev_info(ctodev(card), "%s: ERROR status\n", __func__);
-       /* we need to round up the buffer size to a multiple of 128 */
-       bufsize = ALIGN(GELIC_NET_MAX_MTU, GELIC_NET_RXBUF_ALIGN);
 
-       /* and we need to have it 128 byte aligned, therefore we allocate a
-        * bit more */
-       descr->skb = dev_alloc_skb(bufsize + GELIC_NET_RXBUF_ALIGN - 1);
+       descr->skb = netdev_alloc_skb(*card->netdev, rx_skb_size);
        if (!descr->skb) {
                descr->buf_addr = 0; /* tell DMAC don't touch memory */
                return -ENOMEM;
        }
-       descr->buf_size = cpu_to_be32(bufsize);
+       descr->buf_size = cpu_to_be32(rx_skb_size);
        descr->dmac_cmd_status = 0;
        descr->result_size = 0;
        descr->valid_size = 0;
@@ -395,11 +399,10 @@ static int gelic_descr_prepare_rx(struct gelic_card *card,
        if (offset)
                skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset);
        /* io-mmu-map the skb */
-       descr->buf_addr = cpu_to_be32(dma_map_single(ctodev(card),
-                                                    descr->skb->data,
-                                                    GELIC_NET_MAX_MTU,
-                                                    DMA_FROM_DEVICE));
-       if (!descr->buf_addr) {
+       cpu_addr = dma_map_single(ctodev(card), descr->skb->data,
+                                 GELIC_NET_MAX_FRAME, DMA_FROM_DEVICE);
+       descr->buf_addr = cpu_to_be32(cpu_addr);
+       if (dma_mapping_error(ctodev(card), cpu_addr)) {
                dev_kfree_skb_any(descr->skb);
                descr->skb = NULL;
                dev_info(ctodev(card),
@@ -779,7 +782,7 @@ static int gelic_descr_prepare_tx(struct gelic_card *card,
 
        buf = dma_map_single(ctodev(card), skb->data, skb->len, DMA_TO_DEVICE);
 
-       if (!buf) {
+       if (dma_mapping_error(ctodev(card), buf)) {
                dev_err(ctodev(card),
                        "dma map 2 failed (%p, %i). Dropping packet\n",
                        skb->data, skb->len);
@@ -915,7 +918,7 @@ static void gelic_net_pass_skb_up(struct gelic_descr *descr,
        data_error = be32_to_cpu(descr->data_error);
        /* unmap skb buffer */
        dma_unmap_single(ctodev(card), be32_to_cpu(descr->buf_addr),
-                        GELIC_NET_MAX_MTU,
+                        GELIC_NET_MAX_FRAME,
                         DMA_FROM_DEVICE);
 
        skb_put(skb, be32_to_cpu(descr->valid_size)?
index 68f324ed4eaf0841072efd46c999455c6c11a8e6..0d98defb011ed7976c88be928f656c634ef3c23f 100644 (file)
@@ -19,8 +19,9 @@
 #define GELIC_NET_RX_DESCRIPTORS        128 /* num of descriptors */
 #define GELIC_NET_TX_DESCRIPTORS        128 /* num of descriptors */
 
-#define GELIC_NET_MAX_MTU               VLAN_ETH_FRAME_LEN
-#define GELIC_NET_MIN_MTU               VLAN_ETH_ZLEN
+#define GELIC_NET_MAX_FRAME             2312
+#define GELIC_NET_MAX_MTU               2294
+#define GELIC_NET_MIN_MTU               64
 #define GELIC_NET_RXBUF_ALIGN           128
 #define GELIC_CARD_RX_CSUM_DEFAULT      1 /* hw chksum */
 #define GELIC_NET_WATCHDOG_TIMEOUT      5*HZ
index a502812ac418a6e26aab5d03a4ead85a0ce38900..86f7843b4591c6a8e48e6225059bd68d76b91da7 100644 (file)
@@ -2709,8 +2709,7 @@ static int velocity_get_platform_info(struct velocity_info *vptr)
        struct resource res;
        int ret;
 
-       if (of_get_property(vptr->dev->of_node, "no-eeprom", NULL))
-               vptr->no_eeprom = 1;
+       vptr->no_eeprom = of_property_read_bool(vptr->dev->of_node, "no-eeprom");
 
        ret = of_address_to_resource(vptr->dev->of_node, 0, &res);
        if (ret) {
index ffdac6fac05499d993debc1fec9f125960b04253..f64ed39b93d8312a5711515243c1408aa2944e46 100644 (file)
@@ -1383,7 +1383,7 @@ struct velocity_info {
        struct device *dev;
        struct pci_dev *pdev;
        struct net_device *netdev;
-       int no_eeprom;
+       bool no_eeprom;
 
        unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
        u8 ip_addr[4];
index 77d8d7f1707e9678e04869109a728388f221b620..97e2c1e13b8067864f5a6800bca146b1e977b3f1 100644 (file)
 #define WX_PX_INTA                   0x110
 #define WX_PX_GPIE                   0x118
 #define WX_PX_GPIE_MODEL             BIT(0)
-#define WX_PX_IC                     0x120
+#define WX_PX_IC(_i)                 (0x120 + (_i) * 4)
 #define WX_PX_IMS(_i)                (0x140 + (_i) * 4)
 #define WX_PX_IMC(_i)                (0x150 + (_i) * 4)
 #define WX_PX_ISB_ADDR_L             0x160
index 5b564d348c091a9f91346fb4e49c566b922ec4d0..17412e5282dedd094dea634d7a3de0fc1329facf 100644 (file)
@@ -352,7 +352,7 @@ static void ngbe_up(struct wx *wx)
        netif_tx_start_all_queues(wx->netdev);
 
        /* clear any pending interrupts, may auto mask */
-       rd32(wx, WX_PX_IC);
+       rd32(wx, WX_PX_IC(0));
        rd32(wx, WX_PX_MISC_IC);
        ngbe_irq_enable(wx, true);
        if (wx->gpio_ctrl)
index 6c0a982305576997459682b19f4c62936005be70..a58ce5463686a34f37b2b47c1641ea420b55ff58 100644 (file)
@@ -229,7 +229,8 @@ static void txgbe_up_complete(struct wx *wx)
        wx_napi_enable_all(wx);
 
        /* clear any pending interrupts, may auto mask */
-       rd32(wx, WX_PX_IC);
+       rd32(wx, WX_PX_IC(0));
+       rd32(wx, WX_PX_IC(1));
        rd32(wx, WX_PX_MISC_IC);
        txgbe_irq_enable(wx, true);
 
index 1066420d6a83aa55ff6689329b44c0b57ffa37a4..e0ac1bcd9925c2ebfe122ff1faf9a40479a0afdb 100644 (file)
@@ -1455,12 +1455,11 @@ static int temac_probe(struct platform_device *pdev)
         * endianness mode.  Default for OF devices is big-endian.
         */
        little_endian = false;
-       if (temac_np) {
-               if (of_get_property(temac_np, "little-endian", NULL))
-                       little_endian = true;
-       } else if (pdata) {
+       if (temac_np)
+               little_endian = of_property_read_bool(temac_np, "little-endian");
+       else if (pdata)
                little_endian = pdata->reg_little_endian;
-       }
+
        if (little_endian) {
                lp->temac_ior = _temac_ior_le;
                lp->temac_iow = _temac_iow_le;
index 894e92ef415b98b761af99fa917838b0f640e8fb..9f505cf02d9651d63e3c393ad954690f41a595ee 100644 (file)
@@ -503,6 +503,11 @@ static void
 xirc2ps_detach(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
+    struct local_info *local = netdev_priv(dev);
+
+    netif_carrier_off(dev);
+    netif_tx_disable(dev);
+    cancel_work_sync(&local->tx_timeout_task);
 
     dev_dbg(&link->dev, "detach\n");
 
index a9c44f08199d0c5ac160c24c0411cedbfe1926ed..a94c7bd5db2ea3143ca800eff3275d91f76526ac 100644 (file)
@@ -47,7 +47,7 @@ config BPQETHER
 
 config SCC
        tristate "Z8530 SCC driver"
-       depends on ISA && AX25 && ISA_DMA_API
+       depends on ISA && AX25
        help
          These cards are used to connect your Linux box to an amateur radio
          in order to communicate with other computers. If you want to use
index e1a569b99e4a6a071acf0488070298134bd40aab..d0b5129439ed6c02b61f21773ed0bf9e65ea422a 100644 (file)
@@ -1902,10 +1902,9 @@ static int ca8210_skb_tx(
        struct ca8210_priv  *priv
 )
 {
-       int status;
        struct ieee802154_hdr header = { };
        struct secspec secspec;
-       unsigned int mac_len;
+       int mac_len, status;
 
        dev_dbg(&priv->spi->dev, "%s called\n", __func__);
 
@@ -1913,6 +1912,8 @@ static int ca8210_skb_tx(
         * packet
         */
        mac_len = ieee802154_hdr_peek_addrs(skb, &header);
+       if (mac_len < 0)
+               return mac_len;
 
        secspec.security_level = header.sec.level;
        secspec.key_id_mode = header.sec.key_id_mode;
index 1412b67304c8e9a12671d84a51c428b2a39660cb..1651fbad4bd54afa42301ba08f5d1bb0c4e01f15 100644 (file)
@@ -15,6 +15,14 @@ static bool gsi_reg_id_valid(struct gsi *gsi, enum gsi_reg_id reg_id)
        switch (reg_id) {
        case INTER_EE_SRC_CH_IRQ_MSK:
        case INTER_EE_SRC_EV_CH_IRQ_MSK:
+               return gsi->version >= IPA_VERSION_3_5;
+
+       case HW_PARAM_2:
+               return gsi->version >= IPA_VERSION_3_5_1;
+
+       case HW_PARAM_4:
+               return gsi->version >= IPA_VERSION_5_0;
+
        case CH_C_CNTXT_0:
        case CH_C_CNTXT_1:
        case CH_C_CNTXT_2:
@@ -43,7 +51,6 @@ static bool gsi_reg_id_valid(struct gsi *gsi, enum gsi_reg_id reg_id)
        case CH_CMD:
        case EV_CH_CMD:
        case GENERIC_CMD:
-       case HW_PARAM_2:
        case CNTXT_TYPE_IRQ:
        case CNTXT_TYPE_IRQ_MSK:
        case CNTXT_SRC_CH_IRQ:
index f62f0a5c653d1a6689f898bf6c67124147e8ac7d..48fde65fa2e8a59d8ed82e3535f0d7cff4677380 100644 (file)
 
 #include <linux/bits.h>
 
+struct platform_device;
+
+struct gsi;
+
 /**
  * DOC: GSI Registers
  *
index 0f52c068c46d635954e78c1796b1c63041cdd36b..ee6fb00b71eb620178cca6a5045580944db13aaf 100644 (file)
@@ -156,7 +156,7 @@ int gsi_trans_pool_init_dma(struct device *dev, struct gsi_trans_pool *pool,
         * gsi_trans_pool_exit_dma() can assume the total allocated
         * size is exactly (count * size).
         */
-       total_size = get_order(total_size) << PAGE_SHIFT;
+       total_size = PAGE_SIZE << get_order(total_size);
 
        virt = dma_alloc_coherent(dev, total_size, &addr, GFP_KERNEL);
        if (!virt)
index 735fa659160979316feaeb3ffd3e89d41e48a2f5..3f475428ddddb467fe287be3b11d77423b99af0d 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
- * Copyright (C) 2019-2022 Linaro Ltd.
+ * Copyright (C) 2019-2023 Linaro Ltd.
  */
 
 #include <linux/io.h>
@@ -15,6 +15,17 @@ static bool ipa_reg_id_valid(struct ipa *ipa, enum ipa_reg_id reg_id)
        enum ipa_version version = ipa->version;
 
        switch (reg_id) {
+       case FILT_ROUT_HASH_EN:
+               return version == IPA_VERSION_4_2;
+
+       case FILT_ROUT_HASH_FLUSH:
+               return version < IPA_VERSION_5_0 && version != IPA_VERSION_4_2;
+
+       case FILT_ROUT_CACHE_FLUSH:
+       case ENDP_FILTER_CACHE_CFG:
+       case ENDP_ROUTER_CACHE_CFG:
+               return version >= IPA_VERSION_5_0;
+
        case IPA_BCR:
        case COUNTER_CFG:
                return version < IPA_VERSION_4_5;
@@ -32,14 +43,17 @@ static bool ipa_reg_id_valid(struct ipa *ipa, enum ipa_reg_id reg_id)
        case SRC_RSRC_GRP_45_RSRC_TYPE:
        case DST_RSRC_GRP_45_RSRC_TYPE:
                return version <= IPA_VERSION_3_1 ||
-                      version == IPA_VERSION_4_5;
+                      version == IPA_VERSION_4_5 ||
+                      version == IPA_VERSION_5_0;
 
        case SRC_RSRC_GRP_67_RSRC_TYPE:
        case DST_RSRC_GRP_67_RSRC_TYPE:
-               return version <= IPA_VERSION_3_1;
+               return version <= IPA_VERSION_3_1 ||
+                      version == IPA_VERSION_5_0;
 
        case ENDP_FILTER_ROUTER_HSH_CFG:
-               return version != IPA_VERSION_4_2;
+               return version < IPA_VERSION_5_0 &&
+                       version != IPA_VERSION_4_2;
 
        case IRQ_SUSPEND_EN:
        case IRQ_SUSPEND_CLR:
@@ -51,10 +65,6 @@ static bool ipa_reg_id_valid(struct ipa *ipa, enum ipa_reg_id reg_id)
        case SHARED_MEM_SIZE:
        case QSB_MAX_WRITES:
        case QSB_MAX_READS:
-       case FILT_ROUT_HASH_EN:
-       case FILT_ROUT_CACHE_CFG:
-       case FILT_ROUT_HASH_FLUSH:
-       case FILT_ROUT_CACHE_FLUSH:
        case STATE_AGGR_ACTIVE:
        case LOCAL_PKT_PROC_CNTXT:
        case AGGR_FORCE_CLOSE:
@@ -76,8 +86,6 @@ static bool ipa_reg_id_valid(struct ipa *ipa, enum ipa_reg_id reg_id)
        case ENDP_INIT_RSRC_GRP:
        case ENDP_INIT_SEQ:
        case ENDP_STATUS:
-       case ENDP_FILTER_CACHE_CFG:
-       case ENDP_ROUTER_CACHE_CFG:
        case IPA_IRQ_STTS:
        case IPA_IRQ_EN:
        case IPA_IRQ_CLR:
index 28aa1351dd4880e4f9e0ac6bb43ccb785cd83b66..7dd65d39333ddaefb0e3cff1e22421f41bed8eec 100644 (file)
@@ -60,9 +60,8 @@ enum ipa_reg_id {
        SHARED_MEM_SIZE,
        QSB_MAX_WRITES,
        QSB_MAX_READS,
-       FILT_ROUT_HASH_EN,                              /* Not IPA v5.0+ */
-       FILT_ROUT_CACHE_CFG,                            /* IPA v5.0+ */
-       FILT_ROUT_HASH_FLUSH,                           /* Not IPA v5.0+ */
+       FILT_ROUT_HASH_EN,                              /* IPA v4.2 */
+       FILT_ROUT_HASH_FLUSH,                   /* Not IPA v4.2 nor IPA v5.0+ */
        FILT_ROUT_CACHE_FLUSH,                          /* IPA v5.0+ */
        STATE_AGGR_ACTIVE,
        IPA_BCR,                                        /* Not IPA v4.5+ */
@@ -77,12 +76,12 @@ enum ipa_reg_id {
        TIMERS_PULSE_GRAN_CFG,                          /* IPA v4.5+ */
        SRC_RSRC_GRP_01_RSRC_TYPE,
        SRC_RSRC_GRP_23_RSRC_TYPE,
-       SRC_RSRC_GRP_45_RSRC_TYPE,              /* Not IPA v3.5+, IPA v4.5 */
-       SRC_RSRC_GRP_67_RSRC_TYPE,                      /* Not IPA v3.5+ */
+       SRC_RSRC_GRP_45_RSRC_TYPE,      /* Not IPA v3.5+; IPA v4.5, IPA v5.0 */
+       SRC_RSRC_GRP_67_RSRC_TYPE,              /* Not IPA v3.5+; IPA v5.0 */
        DST_RSRC_GRP_01_RSRC_TYPE,
        DST_RSRC_GRP_23_RSRC_TYPE,
-       DST_RSRC_GRP_45_RSRC_TYPE,              /* Not IPA v3.5+, IPA v4.5 */
-       DST_RSRC_GRP_67_RSRC_TYPE,                      /* Not IPA v3.5+ */
+       DST_RSRC_GRP_45_RSRC_TYPE,      /* Not IPA v3.5+; IPA v4.5, IPA v5.0 */
+       DST_RSRC_GRP_67_RSRC_TYPE,              /* Not IPA v3.5+; IPA v5.0 */
        ENDP_INIT_CTRL,         /* Not IPA v4.2+ for TX, not IPA v4.0+ for RX */
        ENDP_INIT_CFG,
        ENDP_INIT_NAT,                  /* TX only */
@@ -206,14 +205,6 @@ enum ipa_reg_qsb_max_reads_field_id {
        GEN_QMB_1_MAX_READS_BEATS,                      /* IPA v4.0+ */
 };
 
-/* FILT_ROUT_CACHE_CFG register */
-enum ipa_reg_filt_rout_cache_cfg_field_id {
-       ROUTER_CACHE_EN,
-       FILTER_CACHE_EN,
-       LOW_PRI_HASH_HIT_DISABLE,
-       LRU_EVICTION_THRESHOLD,
-};
-
 /* FILT_ROUT_HASH_EN and FILT_ROUT_HASH_FLUSH registers */
 enum ipa_reg_filt_rout_hash_field_id {
        IPV6_ROUTER_HASH,
index 57b457f39b6e2b24c309d0849ce119ecfee838ea..2ee07eebca6774fc9fe60e9b2c51efb0a2f37101 100644 (file)
@@ -6,7 +6,8 @@
 #define _REG_H_
 
 #include <linux/types.h>
-#include <linux/bits.h>
+#include <linux/log2.h>
+#include <linux/bug.h>
 
 /**
  * struct reg - A register descriptor
index 648b51b88d4e862335f2a9db6f9fd1e135d1895f..2900e5c3ff88833574d92cbea552c0ba57759536 100644 (file)
@@ -137,17 +137,17 @@ REG_STRIDE(EV_CH_E_SCRATCH_1, ev_ch_e_scratch_1,
           0x0001004c + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(CH_C_DOORBELL_0, ch_c_doorbell_0,
-          0x0001e000 + 0x4000 * GSI_EE_AP, 0x08);
+          0x00011000 + 0x4000 * GSI_EE_AP, 0x08);
 
 REG_STRIDE(EV_CH_E_DOORBELL_0, ev_ch_e_doorbell_0,
-          0x0001e100 + 0x4000 * GSI_EE_AP, 0x08);
+          0x00011100 + 0x4000 * GSI_EE_AP, 0x08);
 
 static const u32 reg_gsi_status_fmask[] = {
        [ENABLED]                                       = BIT(0),
                                                /* Bits 1-31 reserved */
 };
 
-REG_FIELDS(GSI_STATUS, gsi_status, 0x0001f000 + 0x4000 * GSI_EE_AP);
+REG_FIELDS(GSI_STATUS, gsi_status, 0x00012000 + 0x4000 * GSI_EE_AP);
 
 static const u32 reg_ch_cmd_fmask[] = {
        [CH_CHID]                                       = GENMASK(7, 0),
@@ -155,7 +155,7 @@ static const u32 reg_ch_cmd_fmask[] = {
        [CH_OPCODE]                                     = GENMASK(31, 24),
 };
 
-REG_FIELDS(CH_CMD, ch_cmd, 0x0001f008 + 0x4000 * GSI_EE_AP);
+REG_FIELDS(CH_CMD, ch_cmd, 0x00012008 + 0x4000 * GSI_EE_AP);
 
 static const u32 reg_ev_ch_cmd_fmask[] = {
        [EV_CHID]                                       = GENMASK(7, 0),
@@ -163,7 +163,7 @@ static const u32 reg_ev_ch_cmd_fmask[] = {
        [EV_OPCODE]                                     = GENMASK(31, 24),
 };
 
-REG_FIELDS(EV_CH_CMD, ev_ch_cmd, 0x0001f010 + 0x4000 * GSI_EE_AP);
+REG_FIELDS(EV_CH_CMD, ev_ch_cmd, 0x00012010 + 0x4000 * GSI_EE_AP);
 
 static const u32 reg_generic_cmd_fmask[] = {
        [GENERIC_OPCODE]                                = GENMASK(4, 0),
@@ -172,7 +172,7 @@ static const u32 reg_generic_cmd_fmask[] = {
                                                /* Bits 14-31 reserved */
 };
 
-REG_FIELDS(GENERIC_CMD, generic_cmd, 0x0001f018 + 0x4000 * GSI_EE_AP);
+REG_FIELDS(GENERIC_CMD, generic_cmd, 0x00012018 + 0x4000 * GSI_EE_AP);
 
 static const u32 reg_hw_param_2_fmask[] = {
        [IRAM_SIZE]                                     = GENMASK(2, 0),
@@ -188,58 +188,58 @@ static const u32 reg_hw_param_2_fmask[] = {
        [GSI_USE_INTER_EE]                              = BIT(31),
 };
 
-REG_FIELDS(HW_PARAM_2, hw_param_2, 0x0001f040 + 0x4000 * GSI_EE_AP);
+REG_FIELDS(HW_PARAM_2, hw_param_2, 0x00012040 + 0x4000 * GSI_EE_AP);
 
-REG(CNTXT_TYPE_IRQ, cntxt_type_irq, 0x0001f080 + 0x4000 * GSI_EE_AP);
+REG(CNTXT_TYPE_IRQ, cntxt_type_irq, 0x00012080 + 0x4000 * GSI_EE_AP);
 
-REG(CNTXT_TYPE_IRQ_MSK, cntxt_type_irq_msk, 0x0001f088 + 0x4000 * GSI_EE_AP);
+REG(CNTXT_TYPE_IRQ_MSK, cntxt_type_irq_msk, 0x00012088 + 0x4000 * GSI_EE_AP);
 
-REG(CNTXT_SRC_CH_IRQ, cntxt_src_ch_irq, 0x0001f090 + 0x4000 * GSI_EE_AP);
+REG(CNTXT_SRC_CH_IRQ, cntxt_src_ch_irq, 0x00012090 + 0x4000 * GSI_EE_AP);
 
-REG(CNTXT_SRC_EV_CH_IRQ, cntxt_src_ev_ch_irq, 0x0001f094 + 0x4000 * GSI_EE_AP);
+REG(CNTXT_SRC_EV_CH_IRQ, cntxt_src_ev_ch_irq, 0x00012094 + 0x4000 * GSI_EE_AP);
 
 REG(CNTXT_SRC_CH_IRQ_MSK, cntxt_src_ch_irq_msk,
-    0x0001f098 + 0x4000 * GSI_EE_AP);
+    0x00012098 + 0x4000 * GSI_EE_AP);
 
 REG(CNTXT_SRC_EV_CH_IRQ_MSK, cntxt_src_ev_ch_irq_msk,
-    0x0001f09c + 0x4000 * GSI_EE_AP);
+    0x0001209c + 0x4000 * GSI_EE_AP);
 
 REG(CNTXT_SRC_CH_IRQ_CLR, cntxt_src_ch_irq_clr,
-    0x0001f0a0 + 0x4000 * GSI_EE_AP);
+    0x000120a0 + 0x4000 * GSI_EE_AP);
 
 REG(CNTXT_SRC_EV_CH_IRQ_CLR, cntxt_src_ev_ch_irq_clr,
-    0x0001f0a4 + 0x4000 * GSI_EE_AP);
+    0x000120a4 + 0x4000 * GSI_EE_AP);
 
-REG(CNTXT_SRC_IEOB_IRQ, cntxt_src_ieob_irq, 0x0001f0b0 + 0x4000 * GSI_EE_AP);
+REG(CNTXT_SRC_IEOB_IRQ, cntxt_src_ieob_irq, 0x000120b0 + 0x4000 * GSI_EE_AP);
 
 REG(CNTXT_SRC_IEOB_IRQ_MSK, cntxt_src_ieob_irq_msk,
-    0x0001f0b8 + 0x4000 * GSI_EE_AP);
+    0x000120b8 + 0x4000 * GSI_EE_AP);
 
 REG(CNTXT_SRC_IEOB_IRQ_CLR, cntxt_src_ieob_irq_clr,
-    0x0001f0c0 + 0x4000 * GSI_EE_AP);
+    0x000120c0 + 0x4000 * GSI_EE_AP);
 
-REG(CNTXT_GLOB_IRQ_STTS, cntxt_glob_irq_stts, 0x0001f100 + 0x4000 * GSI_EE_AP);
+REG(CNTXT_GLOB_IRQ_STTS, cntxt_glob_irq_stts, 0x00012100 + 0x4000 * GSI_EE_AP);
 
-REG(CNTXT_GLOB_IRQ_EN, cntxt_glob_irq_en, 0x0001f108 + 0x4000 * GSI_EE_AP);
+REG(CNTXT_GLOB_IRQ_EN, cntxt_glob_irq_en, 0x00012108 + 0x4000 * GSI_EE_AP);
 
-REG(CNTXT_GLOB_IRQ_CLR, cntxt_glob_irq_clr, 0x0001f110 + 0x4000 * GSI_EE_AP);
+REG(CNTXT_GLOB_IRQ_CLR, cntxt_glob_irq_clr, 0x00012110 + 0x4000 * GSI_EE_AP);
 
-REG(CNTXT_GSI_IRQ_STTS, cntxt_gsi_irq_stts, 0x0001f118 + 0x4000 * GSI_EE_AP);
+REG(CNTXT_GSI_IRQ_STTS, cntxt_gsi_irq_stts, 0x00012118 + 0x4000 * GSI_EE_AP);
 
-REG(CNTXT_GSI_IRQ_EN, cntxt_gsi_irq_en, 0x0001f120 + 0x4000 * GSI_EE_AP);
+REG(CNTXT_GSI_IRQ_EN, cntxt_gsi_irq_en, 0x00012120 + 0x4000 * GSI_EE_AP);
 
-REG(CNTXT_GSI_IRQ_CLR, cntxt_gsi_irq_clr, 0x0001f128 + 0x4000 * GSI_EE_AP);
+REG(CNTXT_GSI_IRQ_CLR, cntxt_gsi_irq_clr, 0x00012128 + 0x4000 * GSI_EE_AP);
 
 static const u32 reg_cntxt_intset_fmask[] = {
        [INTYPE]                                        = BIT(0)
                                                /* Bits 1-31 reserved */
 };
 
-REG_FIELDS(CNTXT_INTSET, cntxt_intset, 0x0001f180 + 0x4000 * GSI_EE_AP);
+REG_FIELDS(CNTXT_INTSET, cntxt_intset, 0x00012180 + 0x4000 * GSI_EE_AP);
 
-REG_FIELDS(ERROR_LOG, error_log, 0x0001f200 + 0x4000 * GSI_EE_AP);
+REG_FIELDS(ERROR_LOG, error_log, 0x00012200 + 0x4000 * GSI_EE_AP);
 
-REG(ERROR_LOG_CLR, error_log_clr, 0x0001f210 + 0x4000 * GSI_EE_AP);
+REG(ERROR_LOG_CLR, error_log_clr, 0x00012210 + 0x4000 * GSI_EE_AP);
 
 static const u32 reg_cntxt_scratch_0_fmask[] = {
        [INTER_EE_RESULT]                               = GENMASK(2, 0),
@@ -248,7 +248,7 @@ static const u32 reg_cntxt_scratch_0_fmask[] = {
                                                /* Bits 8-31 reserved */
 };
 
-REG_FIELDS(CNTXT_SCRATCH_0, cntxt_scratch_0, 0x0001f400 + 0x4000 * GSI_EE_AP);
+REG_FIELDS(CNTXT_SCRATCH_0, cntxt_scratch_0, 0x00012400 + 0x4000 * GSI_EE_AP);
 
 static const struct reg *reg_array[] = {
        [INTER_EE_SRC_CH_IRQ_MSK]       = &reg_inter_ee_src_ch_irq_msk,
index 4bf45d264d6b914133bf13148fb3a154727be7f5..8b5d95425a766c97f97f3d2646fe1bc104d7412b 100644 (file)
@@ -27,7 +27,7 @@ static const u32 reg_ch_c_cntxt_0_fmask[] = {
 };
 
 REG_STRIDE_FIELDS(CH_C_CNTXT_0, ch_c_cntxt_0,
-                 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80);
+                 0x0000f000 + 0x4000 * GSI_EE_AP, 0x80);
 
 static const u32 reg_ch_c_cntxt_1_fmask[] = {
        [CH_R_LENGTH]                                   = GENMASK(19, 0),
@@ -35,11 +35,11 @@ static const u32 reg_ch_c_cntxt_1_fmask[] = {
 };
 
 REG_STRIDE_FIELDS(CH_C_CNTXT_1, ch_c_cntxt_1,
-                 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80);
+                 0x0000f004 + 0x4000 * GSI_EE_AP, 0x80);
 
-REG_STRIDE(CH_C_CNTXT_2, ch_c_cntxt_2, 0x0001c008 + 0x4000 * GSI_EE_AP, 0x80);
+REG_STRIDE(CH_C_CNTXT_2, ch_c_cntxt_2, 0x0000f008 + 0x4000 * GSI_EE_AP, 0x80);
 
-REG_STRIDE(CH_C_CNTXT_3, ch_c_cntxt_3, 0x0001c00c + 0x4000 * GSI_EE_AP, 0x80);
+REG_STRIDE(CH_C_CNTXT_3, ch_c_cntxt_3, 0x0000f00c + 0x4000 * GSI_EE_AP, 0x80);
 
 static const u32 reg_ch_c_qos_fmask[] = {
        [WRR_WEIGHT]                                    = GENMASK(3, 0),
@@ -53,7 +53,7 @@ static const u32 reg_ch_c_qos_fmask[] = {
                                                /* Bits 25-31 reserved */
 };
 
-REG_STRIDE_FIELDS(CH_C_QOS, ch_c_qos, 0x0001c05c + 0x4000 * GSI_EE_AP, 0x80);
+REG_STRIDE_FIELDS(CH_C_QOS, ch_c_qos, 0x0000f05c + 0x4000 * GSI_EE_AP, 0x80);
 
 static const u32 reg_error_log_fmask[] = {
        [ERR_ARG3]                                      = GENMASK(3, 0),
@@ -67,16 +67,16 @@ static const u32 reg_error_log_fmask[] = {
 };
 
 REG_STRIDE(CH_C_SCRATCH_0, ch_c_scratch_0,
-          0x0001c060 + 0x4000 * GSI_EE_AP, 0x80);
+          0x0000f060 + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(CH_C_SCRATCH_1, ch_c_scratch_1,
-          0x0001c064 + 0x4000 * GSI_EE_AP, 0x80);
+          0x0000f064 + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(CH_C_SCRATCH_2, ch_c_scratch_2,
-          0x0001c068 + 0x4000 * GSI_EE_AP, 0x80);
+          0x0000f068 + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(CH_C_SCRATCH_3, ch_c_scratch_3,
-          0x0001c06c + 0x4000 * GSI_EE_AP, 0x80);
+          0x0000f06c + 0x4000 * GSI_EE_AP, 0x80);
 
 static const u32 reg_ev_ch_e_cntxt_0_fmask[] = {
        [EV_CHTYPE]                                     = GENMASK(3, 0),
@@ -89,23 +89,23 @@ static const u32 reg_ev_ch_e_cntxt_0_fmask[] = {
 };
 
 REG_STRIDE_FIELDS(EV_CH_E_CNTXT_0, ev_ch_e_cntxt_0,
-                 0x0001d000 + 0x4000 * GSI_EE_AP, 0x80);
+                 0x00010000 + 0x4000 * GSI_EE_AP, 0x80);
 
 static const u32 reg_ev_ch_e_cntxt_1_fmask[] = {
        [R_LENGTH]                                      = GENMASK(15, 0),
 };
 
 REG_STRIDE_FIELDS(EV_CH_E_CNTXT_1, ev_ch_e_cntxt_1,
-                 0x0001d004 + 0x4000 * GSI_EE_AP, 0x80);
+                 0x00010004 + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(EV_CH_E_CNTXT_2, ev_ch_e_cntxt_2,
-          0x0001d008 + 0x4000 * GSI_EE_AP, 0x80);
+          0x00010008 + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(EV_CH_E_CNTXT_3, ev_ch_e_cntxt_3,
-          0x0001d00c + 0x4000 * GSI_EE_AP, 0x80);
+          0x0001000c + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(EV_CH_E_CNTXT_4, ev_ch_e_cntxt_4,
-          0x0001d010 + 0x4000 * GSI_EE_AP, 0x80);
+          0x00010010 + 0x4000 * GSI_EE_AP, 0x80);
 
 static const u32 reg_ev_ch_e_cntxt_8_fmask[] = {
        [EV_MODT]                                       = GENMASK(15, 0),
@@ -114,28 +114,28 @@ static const u32 reg_ev_ch_e_cntxt_8_fmask[] = {
 };
 
 REG_STRIDE_FIELDS(EV_CH_E_CNTXT_8, ev_ch_e_cntxt_8,
-                 0x0001d020 + 0x4000 * GSI_EE_AP, 0x80);
+                 0x00010020 + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(EV_CH_E_CNTXT_9, ev_ch_e_cntxt_9,
-          0x0001d024 + 0x4000 * GSI_EE_AP, 0x80);
+          0x00010024 + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(EV_CH_E_CNTXT_10, ev_ch_e_cntxt_10,
-          0x0001d028 + 0x4000 * GSI_EE_AP, 0x80);
+          0x00010028 + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(EV_CH_E_CNTXT_11, ev_ch_e_cntxt_11,
-          0x0001d02c + 0x4000 * GSI_EE_AP, 0x80);
+          0x0001002c + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(EV_CH_E_CNTXT_12, ev_ch_e_cntxt_12,
-          0x0001d030 + 0x4000 * GSI_EE_AP, 0x80);
+          0x00010030 + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(EV_CH_E_CNTXT_13, ev_ch_e_cntxt_13,
-          0x0001d034 + 0x4000 * GSI_EE_AP, 0x80);
+          0x00010034 + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(EV_CH_E_SCRATCH_0, ev_ch_e_scratch_0,
-          0x0001d048 + 0x4000 * GSI_EE_AP, 0x80);
+          0x00010048 + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(EV_CH_E_SCRATCH_1, ev_ch_e_scratch_1,
-          0x0001d04c + 0x4000 * GSI_EE_AP, 0x80);
+          0x0001004c + 0x4000 * GSI_EE_AP, 0x80);
 
 REG_STRIDE(CH_C_DOORBELL_0, ch_c_doorbell_0,
           0x00011000 + 0x4000 * GSI_EE_AP, 0x08);
index 943d26cbf39f5d8d14ed247f4918d51b5104f31f..71712ea25403dd71322f36297bb54f782d789f2c 100644 (file)
@@ -101,6 +101,7 @@ static unsigned int ipvlan_nf_input(void *priv, struct sk_buff *skb,
                goto out;
 
        skb->dev = addr->master->dev;
+       skb->skb_iif = skb->dev->ifindex;
        len = skb->len + ETH_HLEN;
        ipvlan_count_rx(addr->master, len, true, false);
 out:
index d77c987fda9cd1270022a657b37aa61ec870b249..4630dde019749a7a4de81c27b9f6af902bad1c2f 100644 (file)
@@ -18,16 +18,18 @@ MODULE_AUTHOR("Calvin Johnson <calvin.johnson@oss.nxp.com>");
 MODULE_LICENSE("GPL");
 
 /**
- * acpi_mdiobus_register - Register mii_bus and create PHYs from the ACPI ASL.
+ * __acpi_mdiobus_register - Register mii_bus and create PHYs from the ACPI ASL.
  * @mdio: pointer to mii_bus structure
  * @fwnode: pointer to fwnode of MDIO bus. This fwnode is expected to represent
+ * @owner: module owning this @mdio object.
  * an ACPI device object corresponding to the MDIO bus and its children are
  * expected to correspond to the PHY devices on that bus.
  *
  * This function registers the mii_bus structure and registers a phy_device
  * for each child node of @fwnode.
  */
-int acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode)
+int __acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode,
+                           struct module *owner)
 {
        struct fwnode_handle *child;
        u32 addr;
@@ -35,7 +37,7 @@ int acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode)
 
        /* Mask out all PHYs from auto probing. */
        mdio->phy_mask = GENMASK(31, 0);
-       ret = mdiobus_register(mdio);
+       ret = __mdiobus_register(mdio, owner);
        if (ret)
                return ret;
 
@@ -55,4 +57,4 @@ int acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode)
        }
        return 0;
 }
-EXPORT_SYMBOL(acpi_mdiobus_register);
+EXPORT_SYMBOL(__acpi_mdiobus_register);
index 3847ee92c1096c1569442acea2120c279ad2dc60..6067d96b2b7bf030a09a67bfad7490fea60d219f 100644 (file)
@@ -106,6 +106,7 @@ static int thunder_mdiobus_pci_probe(struct pci_dev *pdev,
                if (i >= ARRAY_SIZE(nexus->buses))
                        break;
        }
+       fwnode_handle_put(fwn);
        return 0;
 
 err_release_regions:
index 510822d6d0d90ce4fe012388e71733846c57c115..1e46e39f5f46a0857570682a86e23d876ef77704 100644 (file)
@@ -139,21 +139,23 @@ bool of_mdiobus_child_is_phy(struct device_node *child)
 EXPORT_SYMBOL(of_mdiobus_child_is_phy);
 
 /**
- * of_mdiobus_register - Register mii_bus and create PHYs from the device tree
+ * __of_mdiobus_register - Register mii_bus and create PHYs from the device tree
  * @mdio: pointer to mii_bus structure
  * @np: pointer to device_node of MDIO bus.
+ * @owner: module owning the @mdio object.
  *
  * This function registers the mii_bus structure and registers a phy_device
  * for each child node of @np.
  */
-int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
+int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np,
+                         struct module *owner)
 {
        struct device_node *child;
        bool scanphys = false;
        int addr, rc;
 
        if (!np)
-               return mdiobus_register(mdio);
+               return __mdiobus_register(mdio, owner);
 
        /* Do not continue if the node is disabled */
        if (!of_device_is_available(np))
@@ -172,7 +174,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
        of_property_read_u32(np, "reset-post-delay-us", &mdio->reset_post_delay_us);
 
        /* Register the MDIO bus */
-       rc = mdiobus_register(mdio);
+       rc = __mdiobus_register(mdio, owner);
        if (rc)
                return rc;
 
@@ -236,7 +238,7 @@ unregister:
        mdiobus_unregister(mdio);
        return rc;
 }
-EXPORT_SYMBOL(of_mdiobus_register);
+EXPORT_SYMBOL(__of_mdiobus_register);
 
 /**
  * of_mdio_find_device - Given a device tree node, find the mdio_device
index 7a28e082436e4a3a5a9e11a3711b666e5735c406..d0c916a53d7ce4689e51eeffdfdaa5dd997ae529 100644 (file)
@@ -130,14 +130,10 @@ static u16 net_failover_select_queue(struct net_device *dev,
                        txq = ops->ndo_select_queue(primary_dev, skb, sb_dev);
                else
                        txq = netdev_pick_tx(primary_dev, skb, NULL);
-
-               qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping;
-
-               return txq;
+       } else {
+               txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0;
        }
 
-       txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0;
-
        /* Save the original txq to restore before passing to the driver */
        qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping;
 
index b4ff9c5073a3c485e6bba87284eb386152bdf09b..9ab5eff502b71640b1022baf1d6b7567a65c240f 100644 (file)
@@ -588,15 +588,13 @@ static int dp83869_of_init(struct phy_device *phydev)
                                                       &dp83869_internal_delay[0],
                                                       delay_size, true);
        if (dp83869->rx_int_delay < 0)
-               dp83869->rx_int_delay =
-                               dp83869_internal_delay[DP83869_CLK_DELAY_DEF];
+               dp83869->rx_int_delay = DP83869_CLK_DELAY_DEF;
 
        dp83869->tx_int_delay = phy_get_internal_delay(phydev, dev,
                                                       &dp83869_internal_delay[0],
                                                       delay_size, false);
        if (dp83869->tx_int_delay < 0)
-               dp83869->tx_int_delay =
-                               dp83869_internal_delay[DP83869_CLK_DELAY_DEF];
+               dp83869->tx_int_delay = DP83869_CLK_DELAY_DEF;
 
        return ret;
 }
index b560e99695dfd3f4ca3db7a8f9080a1629a26408..69b829e6ab35b84a07f0063f3a6f7b48ea1a6de1 100644 (file)
@@ -98,13 +98,14 @@ EXPORT_SYMBOL(__devm_mdiobus_register);
 
 #if IS_ENABLED(CONFIG_OF_MDIO)
 /**
- * devm_of_mdiobus_register - Resource managed variant of of_mdiobus_register()
+ * __devm_of_mdiobus_register - Resource managed variant of of_mdiobus_register()
  * @dev:       Device to register mii_bus for
  * @mdio:      MII bus structure to register
  * @np:                Device node to parse
+ * @owner:     Owning module
  */
-int devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio,
-                            struct device_node *np)
+int __devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio,
+                              struct device_node *np, struct module *owner)
 {
        struct mdiobus_devres *dr;
        int ret;
@@ -117,7 +118,7 @@ int devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio,
        if (!dr)
                return -ENOMEM;
 
-       ret = of_mdiobus_register(mdio, np);
+       ret = __of_mdiobus_register(mdio, np, owner);
        if (ret) {
                devres_free(dr);
                return ret;
@@ -127,7 +128,7 @@ int devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio,
        devres_add(dev, dr);
        return 0;
 }
-EXPORT_SYMBOL(devm_of_mdiobus_register);
+EXPORT_SYMBOL(__devm_of_mdiobus_register);
 #endif /* CONFIG_OF_MDIO */
 
 MODULE_LICENSE("GPL");
index 2c84fccef4f644585ac4ec25d23c833e67726430..4e884e4ba0ead7c72efccbb7b079196f8a50ab1e 100644 (file)
@@ -4151,6 +4151,7 @@ static struct phy_driver ksphy_driver[] = {
        .resume         = kszphy_resume,
        .cable_test_start       = ksz9x31_cable_test_start,
        .cable_test_get_status  = ksz9x31_cable_test_get_status,
+       .get_features   = ksz9477_get_features,
 }, {
        .phy_id         = PHY_ID_KSZ8873MLL,
        .phy_id_mask    = MICREL_PHY_ID_MASK,
index ccecee2524ce6216189cf7cabf5f7cded2205bf4..0b88635f4fbca98b7e2f9e553f69fa6f465dd770 100644 (file)
@@ -342,6 +342,37 @@ static int lan88xx_config_aneg(struct phy_device *phydev)
        return genphy_config_aneg(phydev);
 }
 
+static void lan88xx_link_change_notify(struct phy_device *phydev)
+{
+       int temp;
+
+       /* At forced 100 F/H mode, chip may fail to set mode correctly
+        * when cable is switched between long(~50+m) and short one.
+        * As workaround, set to 10 before setting to 100
+        * at forced 100 F/H mode.
+        */
+       if (!phydev->autoneg && phydev->speed == 100) {
+               /* disable phy interrupt */
+               temp = phy_read(phydev, LAN88XX_INT_MASK);
+               temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_;
+               phy_write(phydev, LAN88XX_INT_MASK, temp);
+
+               temp = phy_read(phydev, MII_BMCR);
+               temp &= ~(BMCR_SPEED100 | BMCR_SPEED1000);
+               phy_write(phydev, MII_BMCR, temp); /* set to 10 first */
+               temp |= BMCR_SPEED100;
+               phy_write(phydev, MII_BMCR, temp); /* set to 100 later */
+
+               /* clear pending interrupt generated while workaround */
+               temp = phy_read(phydev, LAN88XX_INT_STS);
+
+               /* enable phy interrupt back */
+               temp = phy_read(phydev, LAN88XX_INT_MASK);
+               temp |= LAN88XX_INT_MASK_MDINTPIN_EN_;
+               phy_write(phydev, LAN88XX_INT_MASK, temp);
+       }
+}
+
 static struct phy_driver microchip_phy_driver[] = {
 {
        .phy_id         = 0x0007c132,
@@ -359,6 +390,7 @@ static struct phy_driver microchip_phy_driver[] = {
 
        .config_init    = lan88xx_config_init,
        .config_aneg    = lan88xx_config_aneg,
+       .link_change_notify = lan88xx_link_change_notify,
 
        .config_intr    = lan88xx_phy_config_intr,
        .handle_interrupt = lan88xx_handle_interrupt,
index 8a13b1ad9a330b599742fc40a5d540ec3dcc0c3f..62bf99e45af16d86ff80428af812e34183888715 100644 (file)
@@ -280,12 +280,9 @@ static int vsc85xx_wol_set(struct phy_device *phydev,
        u16 pwd[3] = {0, 0, 0};
        struct ethtool_wolinfo *wol_conf = wol;
 
-       mutex_lock(&phydev->lock);
        rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
-       if (rc < 0) {
-               rc = phy_restore_page(phydev, rc, rc);
-               goto out_unlock;
-       }
+       if (rc < 0)
+               return phy_restore_page(phydev, rc, rc);
 
        if (wol->wolopts & WAKE_MAGIC) {
                /* Store the device address for the magic packet */
@@ -323,7 +320,7 @@ static int vsc85xx_wol_set(struct phy_device *phydev,
 
        rc = phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
        if (rc < 0)
-               goto out_unlock;
+               return rc;
 
        if (wol->wolopts & WAKE_MAGIC) {
                /* Enable the WOL interrupt */
@@ -331,22 +328,19 @@ static int vsc85xx_wol_set(struct phy_device *phydev,
                reg_val |= MII_VSC85XX_INT_MASK_WOL;
                rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
                if (rc)
-                       goto out_unlock;
+                       return rc;
        } else {
                /* Disable the WOL interrupt */
                reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
                reg_val &= (~MII_VSC85XX_INT_MASK_WOL);
                rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
                if (rc)
-                       goto out_unlock;
+                       return rc;
        }
        /* Clear WOL iterrupt status */
        reg_val = phy_read(phydev, MII_VSC85XX_INT_STATUS);
 
-out_unlock:
-       mutex_unlock(&phydev->lock);
-
-       return rc;
+       return 0;
 }
 
 static void vsc85xx_wol_get(struct phy_device *phydev,
@@ -358,10 +352,9 @@ static void vsc85xx_wol_get(struct phy_device *phydev,
        u16 pwd[3] = {0, 0, 0};
        struct ethtool_wolinfo *wol_conf = wol;
 
-       mutex_lock(&phydev->lock);
        rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
        if (rc < 0)
-               goto out_unlock;
+               goto out_restore_page;
 
        reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
        if (reg_val & SECURE_ON_ENABLE)
@@ -377,9 +370,8 @@ static void vsc85xx_wol_get(struct phy_device *phydev,
                }
        }
 
-out_unlock:
+out_restore_page:
        phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
-       mutex_unlock(&phydev->lock);
 }
 
 #if IS_ENABLED(CONFIG_OF_MDIO)
index 047c581457e34510236133a6ff4ff292a6c06385..029875a59ff89083e82e9f2b735b9585a25cea26 100644 (file)
@@ -79,7 +79,7 @@
 #define SGMII_ABILITY                  BIT(0)
 
 #define VEND1_MII_BASIC_CONFIG         0xAFC6
-#define MII_BASIC_CONFIG_REV           BIT(8)
+#define MII_BASIC_CONFIG_REV           BIT(4)
 #define MII_BASIC_CONFIG_SGMII         0x9
 #define MII_BASIC_CONFIG_RGMII         0x7
 #define MII_BASIC_CONFIG_RMII          0x5
 #define MAX_ID_PS                      2260U
 #define DEFAULT_ID_PS                  2000U
 
-#define PPM_TO_SUBNS_INC(ppb)  div_u64(GENMASK(31, 0) * (ppb) * \
+#define PPM_TO_SUBNS_INC(ppb)  div_u64(GENMASK_ULL(31, 0) * (ppb) * \
                                        PTP_CLK_PERIOD_100BT1, NSEC_PER_SEC)
 
 #define NXP_C45_SKB_CB(skb)    ((struct nxp_c45_skb_cb *)(skb)->cb)
@@ -1337,6 +1337,17 @@ no_ptp_support:
        return ret;
 }
 
+static void nxp_c45_remove(struct phy_device *phydev)
+{
+       struct nxp_c45_phy *priv = phydev->priv;
+
+       if (priv->ptp_clock)
+               ptp_clock_unregister(priv->ptp_clock);
+
+       skb_queue_purge(&priv->tx_queue);
+       skb_queue_purge(&priv->rx_queue);
+}
+
 static struct phy_driver nxp_c45_driver[] = {
        {
                PHY_ID_MATCH_MODEL(PHY_ID_TJA_1103),
@@ -1359,6 +1370,7 @@ static struct phy_driver nxp_c45_driver[] = {
                .set_loopback           = genphy_c45_loopback,
                .get_sqi                = nxp_c45_get_sqi,
                .get_sqi_max            = nxp_c45_get_sqi_max,
+               .remove                 = nxp_c45_remove,
        },
 };
 
index b33e55a7364e6e697088cf97de5c110c2a2c20af..99a07eb54c441cec6c4ea7e24b3e89ec3618f516 100644 (file)
@@ -57,6 +57,18 @@ static const char *phy_state_to_str(enum phy_state st)
        return NULL;
 }
 
+static void phy_process_state_change(struct phy_device *phydev,
+                                    enum phy_state old_state)
+{
+       if (old_state != phydev->state) {
+               phydev_dbg(phydev, "PHY state change %s -> %s\n",
+                          phy_state_to_str(old_state),
+                          phy_state_to_str(phydev->state));
+               if (phydev->drv && phydev->drv->link_change_notify)
+                       phydev->drv->link_change_notify(phydev);
+       }
+}
+
 static void phy_link_up(struct phy_device *phydev)
 {
        phydev->phy_link_change(phydev, true);
@@ -1301,6 +1313,7 @@ EXPORT_SYMBOL(phy_free_interrupt);
 void phy_stop(struct phy_device *phydev)
 {
        struct net_device *dev = phydev->attached_dev;
+       enum phy_state old_state;
 
        if (!phy_is_started(phydev) && phydev->state != PHY_DOWN) {
                WARN(1, "called from state %s\n",
@@ -1309,6 +1322,7 @@ void phy_stop(struct phy_device *phydev)
        }
 
        mutex_lock(&phydev->lock);
+       old_state = phydev->state;
 
        if (phydev->state == PHY_CABLETEST) {
                phy_abort_cable_test(phydev);
@@ -1319,6 +1333,7 @@ void phy_stop(struct phy_device *phydev)
                sfp_upstream_stop(phydev->sfp_bus);
 
        phydev->state = PHY_HALTED;
+       phy_process_state_change(phydev, old_state);
 
        mutex_unlock(&phydev->lock);
 
@@ -1436,13 +1451,7 @@ void phy_state_machine(struct work_struct *work)
        if (err < 0)
                phy_error(phydev);
 
-       if (old_state != phydev->state) {
-               phydev_dbg(phydev, "PHY state change %s -> %s\n",
-                          phy_state_to_str(old_state),
-                          phy_state_to_str(phydev->state));
-               if (phydev->drv && phydev->drv->link_change_notify)
-                       phydev->drv->link_change_notify(phydev);
-       }
+       phy_process_state_change(phydev, old_state);
 
        /* Only re-schedule a PHY state machine change if we are polling the
         * PHY, if PHY_MAC_INTERRUPT is set, then we will be moving
index 3f8a64fb9d71284092f2877608214817bfdf38a0..1de3e339b31a5215dc0598a8175454a34632fca5 100644 (file)
@@ -3057,7 +3057,7 @@ EXPORT_SYMBOL_GPL(device_phy_find_device);
  * and "phy-device" are not supported in ACPI. DT supports all the three
  * named references to the phy node.
  */
-struct fwnode_handle *fwnode_get_phy_node(struct fwnode_handle *fwnode)
+struct fwnode_handle *fwnode_get_phy_node(const struct fwnode_handle *fwnode)
 {
        struct fwnode_handle *phy_node;
 
@@ -3098,8 +3098,6 @@ static int phy_probe(struct device *dev)
        if (phydrv->flags & PHY_IS_INTERNAL)
                phydev->is_internal = true;
 
-       mutex_lock(&phydev->lock);
-
        /* Deassert the reset signal */
        phy_device_reset(phydev, 0);
 
@@ -3146,7 +3144,7 @@ static int phy_probe(struct device *dev)
         */
        err = genphy_c45_read_eee_adv(phydev, phydev->advertising_eee);
        if (err)
-               return err;
+               goto out;
 
        /* There is no "enabled" flag. If PHY is advertising, assume it is
         * kind of enabled.
@@ -3188,12 +3186,10 @@ static int phy_probe(struct device *dev)
        phydev->state = PHY_READY;
 
 out:
-       /* Assert the reset signal */
+       /* Re-assert the reset signal on error */
        if (err)
                phy_device_reset(phydev, 1);
 
-       mutex_unlock(&phydev->lock);
-
        return err;
 }
 
@@ -3203,9 +3199,7 @@ static int phy_remove(struct device *dev)
 
        cancel_delayed_work_sync(&phydev->state_queue);
 
-       mutex_lock(&phydev->lock);
        phydev->state = PHY_DOWN;
-       mutex_unlock(&phydev->lock);
 
        sfp_bus_del_upstream(phydev->sfp_bus);
        phydev->sfp_bus = NULL;
index 1a2f074685fa9f386f30b87a5b3fe750009b8696..30c166b334686723bbe2fae46211639bdebf9174 100644 (file)
@@ -1586,6 +1586,25 @@ void phylink_destroy(struct phylink *pl)
 }
 EXPORT_SYMBOL_GPL(phylink_destroy);
 
+/**
+ * phylink_expects_phy() - Determine if phylink expects a phy to be attached
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ *
+ * When using fixed-link mode, or in-band mode with 1000base-X or 2500base-X,
+ * no PHY is needed.
+ *
+ * Returns true if phylink will be expecting a PHY.
+ */
+bool phylink_expects_phy(struct phylink *pl)
+{
+       if (pl->cfg_link_an_mode == MLO_AN_FIXED ||
+           (pl->cfg_link_an_mode == MLO_AN_INBAND &&
+            phy_interface_mode_is_8023z(pl->link_config.interface)))
+               return false;
+       return true;
+}
+EXPORT_SYMBOL_GPL(phylink_expects_phy);
+
 static void phylink_phy_change(struct phy_device *phydev, bool up)
 {
        struct phylink *pl = phydev->phylink;
index daac293e8edece7e594ca35582ff2483a817b6a3..9fc50fcc8fc99263330b7b84df839b82223d56d8 100644 (file)
@@ -17,7 +17,7 @@ struct sfp_bus {
        /* private: */
        struct kref kref;
        struct list_head node;
-       struct fwnode_handle *fwnode;
+       const struct fwnode_handle *fwnode;
 
        const struct sfp_socket_ops *socket_ops;
        struct device *sfp_dev;
@@ -390,7 +390,7 @@ static const struct sfp_upstream_ops *sfp_get_upstream_ops(struct sfp_bus *bus)
        return bus->registered ? bus->upstream_ops : NULL;
 }
 
-static struct sfp_bus *sfp_bus_get(struct fwnode_handle *fwnode)
+static struct sfp_bus *sfp_bus_get(const struct fwnode_handle *fwnode)
 {
        struct sfp_bus *sfp, *new, *found = NULL;
 
@@ -593,7 +593,7 @@ static void sfp_upstream_clear(struct sfp_bus *bus)
  *     - %-ENOMEM if we failed to allocate the bus.
  *     - an error from the upstream's connect_phy() method.
  */
-struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode)
+struct sfp_bus *sfp_bus_find_fwnode(const struct fwnode_handle *fwnode)
 {
        struct fwnode_reference_args ref;
        struct sfp_bus *bus;
index c02cad6478a816f3a9c9818fd2af9ff3eec783e7..bf345032d450c9ae3949d1a4485c1b76bfd30f1f 100644 (file)
@@ -210,6 +210,12 @@ static const enum gpiod_flags gpio_flags[] = {
 #define SFP_PHY_ADDR           22
 #define SFP_PHY_ADDR_ROLLBALL  17
 
+/* SFP_EEPROM_BLOCK_SIZE is the size of data chunk to read the EEPROM
+ * at a time. Some SFP modules and also some Linux I2C drivers do not like
+ * reads longer than 16 bytes.
+ */
+#define SFP_EEPROM_BLOCK_SIZE  16
+
 struct sff_data {
        unsigned int gpios;
        bool (*module_supported)(const struct sfp_eeprom_id *id);
@@ -387,6 +393,10 @@ static const struct sfp_quirk sfp_quirks[] = {
 
        SFP_QUIRK_F("HALNy", "HL-GSFP", sfp_fixup_halny_gsfp),
 
+       // HG MXPD-483II-F 2.5G supports 2500Base-X, but incorrectly reports
+       // 2600MBd in their EERPOM
+       SFP_QUIRK_M("HG GENUINE", "MXPD-483II", sfp_quirk_2500basex),
+
        // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd NRZ in
        // their EEPROM
        SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex,
@@ -1925,11 +1935,7 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
        u8 check;
        int ret;
 
-       /* Some SFP modules and also some Linux I2C drivers do not like reads
-        * longer than 16 bytes, so read the EEPROM in chunks of 16 bytes at
-        * a time.
-        */
-       sfp->i2c_block_size = 16;
+       sfp->i2c_block_size = SFP_EEPROM_BLOCK_SIZE;
 
        ret = sfp_read(sfp, false, 0, &id.base, sizeof(id.base));
        if (ret < 0) {
@@ -2190,6 +2196,11 @@ static void sfp_sm_module(struct sfp *sfp, unsigned int event)
                        break;
                }
 
+               /* Force a poll to re-read the hardware signal state after
+                * sfp_sm_mod_probe() changed state_hw_mask.
+                */
+               mod_delayed_work(system_wq, &sfp->poll, 1);
+
                err = sfp_hwmon_insert(sfp);
                if (err)
                        dev_warn(sfp->dev, "hwmon probe failed: %pe\n",
@@ -2476,6 +2487,9 @@ static int sfp_module_eeprom(struct sfp *sfp, struct ethtool_eeprom *ee,
        unsigned int first, last, len;
        int ret;
 
+       if (!(sfp->state & SFP_F_PRESENT))
+               return -ENODEV;
+
        if (ee->len == 0)
                return -EINVAL;
 
@@ -2508,6 +2522,9 @@ static int sfp_module_eeprom_by_page(struct sfp *sfp,
                                     const struct ethtool_module_eeprom *page,
                                     struct netlink_ext_ack *extack)
 {
+       if (!(sfp->state & SFP_F_PRESENT))
+               return -ENODEV;
+
        if (page->bank) {
                NL_SET_ERR_MSG(extack, "Banks not supported");
                return -EOPNOTSUPP;
@@ -2612,6 +2629,7 @@ static struct sfp *sfp_alloc(struct device *dev)
                return ERR_PTR(-ENOMEM);
 
        sfp->dev = dev;
+       sfp->i2c_block_size = SFP_EEPROM_BLOCK_SIZE;
 
        mutex_init(&sfp->sm_mutex);
        mutex_init(&sfp->st_mutex);
index ac7481ce2fc16c1a68d964396cb43d861f32cc4b..df2c5435c5c49ee828d625c36e39f4e2d2af0216 100644 (file)
@@ -44,7 +44,6 @@ static struct smsc_hw_stat smsc_hw_stats[] = {
 };
 
 struct smsc_phy_priv {
-       u16 intmask;
        bool energy_enable;
 };
 
@@ -57,7 +56,6 @@ static int smsc_phy_ack_interrupt(struct phy_device *phydev)
 
 static int smsc_phy_config_intr(struct phy_device *phydev)
 {
-       struct smsc_phy_priv *priv = phydev->priv;
        int rc;
 
        if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
@@ -65,14 +63,9 @@ static int smsc_phy_config_intr(struct phy_device *phydev)
                if (rc)
                        return rc;
 
-               priv->intmask = MII_LAN83C185_ISF_INT4 | MII_LAN83C185_ISF_INT6;
-               if (priv->energy_enable)
-                       priv->intmask |= MII_LAN83C185_ISF_INT7;
-
-               rc = phy_write(phydev, MII_LAN83C185_IM, priv->intmask);
+               rc = phy_write(phydev, MII_LAN83C185_IM,
+                              MII_LAN83C185_ISF_INT_PHYLIB_EVENTS);
        } else {
-               priv->intmask = 0;
-
                rc = phy_write(phydev, MII_LAN83C185_IM, 0);
                if (rc)
                        return rc;
@@ -85,7 +78,6 @@ static int smsc_phy_config_intr(struct phy_device *phydev)
 
 static irqreturn_t smsc_phy_handle_interrupt(struct phy_device *phydev)
 {
-       struct smsc_phy_priv *priv = phydev->priv;
        int irq_status;
 
        irq_status = phy_read(phydev, MII_LAN83C185_ISF);
@@ -96,7 +88,7 @@ static irqreturn_t smsc_phy_handle_interrupt(struct phy_device *phydev)
                return IRQ_NONE;
        }
 
-       if (!(irq_status & priv->intmask))
+       if (!(irq_status & MII_LAN83C185_ISF_INT_PHYLIB_EVENTS))
                return IRQ_NONE;
 
        phy_trigger_machine(phydev);
@@ -207,8 +199,11 @@ static int lan95xx_config_aneg_ext(struct phy_device *phydev)
 static int lan87xx_read_status(struct phy_device *phydev)
 {
        struct smsc_phy_priv *priv = phydev->priv;
+       int err;
 
-       int err = genphy_read_status(phydev);
+       err = genphy_read_status(phydev);
+       if (err)
+               return err;
 
        if (!phydev->link && priv->energy_enable && phydev->irq == PHY_POLL) {
                /* Disable EDPD to wake up PHY */
index ad653b32b2f0043d9264c7b22d7275f95630b0a3..5df1eba7b30a3f675e5521c8fa2e36affb75b195 100644 (file)
@@ -1486,7 +1486,8 @@ static struct sk_buff *tun_napi_alloc_frags(struct tun_file *tfile,
        skb->truesize += skb->data_len;
 
        for (i = 1; i < it->nr_segs; i++) {
-               size_t fragsz = it->iov[i].iov_len;
+               const struct iovec *iov = iter_iov(it);
+               size_t fragsz = iov->iov_len;
                struct page *page;
                void *frag;
 
index 743cbf5d662c99c9d5ea390478d9516c2f4a871d..f7cff58fe0449313748237d53ff69191b85e5e5e 100644 (file)
@@ -666,8 +666,9 @@ static int asix_resume(struct usb_interface *intf)
 static int ax88772_init_mdio(struct usbnet *dev)
 {
        struct asix_common_private *priv = dev->driver_priv;
+       int ret;
 
-       priv->mdio = devm_mdiobus_alloc(&dev->udev->dev);
+       priv->mdio = mdiobus_alloc();
        if (!priv->mdio)
                return -ENOMEM;
 
@@ -679,7 +680,20 @@ static int ax88772_init_mdio(struct usbnet *dev)
        snprintf(priv->mdio->id, MII_BUS_ID_SIZE, "usb-%03d:%03d",
                 dev->udev->bus->busnum, dev->udev->devnum);
 
-       return devm_mdiobus_register(&dev->udev->dev, priv->mdio);
+       ret = mdiobus_register(priv->mdio);
+       if (ret) {
+               netdev_err(dev->net, "Could not register MDIO bus (err %d)\n", ret);
+               mdiobus_free(priv->mdio);
+               priv->mdio = NULL;
+       }
+
+       return ret;
+}
+
+static void ax88772_mdio_unregister(struct asix_common_private *priv)
+{
+       mdiobus_unregister(priv->mdio);
+       mdiobus_free(priv->mdio);
 }
 
 static int ax88772_init_phy(struct usbnet *dev)
@@ -896,16 +910,23 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
 
        ret = ax88772_init_mdio(dev);
        if (ret)
-               return ret;
+               goto mdio_err;
 
        ret = ax88772_phylink_setup(dev);
        if (ret)
-               return ret;
+               goto phylink_err;
 
        ret = ax88772_init_phy(dev);
        if (ret)
-               phylink_destroy(priv->phylink);
+               goto initphy_err;
 
+       return 0;
+
+initphy_err:
+       phylink_destroy(priv->phylink);
+phylink_err:
+       ax88772_mdio_unregister(priv);
+mdio_err:
        return ret;
 }
 
@@ -926,6 +947,7 @@ static void ax88772_unbind(struct usbnet *dev, struct usb_interface *intf)
        phylink_disconnect_phy(priv->phylink);
        rtnl_unlock();
        phylink_destroy(priv->phylink);
+       ax88772_mdio_unregister(priv);
        asix_rx_fixup_common_free(dev->driver_priv);
 }
 
index c89639381eca3e847387834d64fcb5d5a803c063..cd4083e0b3b9e6bf8c8fa08ce5b6006d33d9bedd 100644 (file)
@@ -665,6 +665,11 @@ static const struct usb_device_id mbim_devs[] = {
          .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle,
        },
 
+       /* Telit FE990 */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x1081, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
+         .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle,
+       },
+
        /* default entry */
        { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
          .driver_info = (unsigned long)&cdc_mbim_info_zlp,
index f18ab8e220db72787bffef62c598e7c65e1e1c6e..c458c030fadf6cbaa7a55a4e35344bf2a01122a4 100644 (file)
@@ -2115,33 +2115,8 @@ static void lan78xx_remove_mdio(struct lan78xx_net *dev)
 static void lan78xx_link_status_change(struct net_device *net)
 {
        struct phy_device *phydev = net->phydev;
-       int temp;
-
-       /* At forced 100 F/H mode, chip may fail to set mode correctly
-        * when cable is switched between long(~50+m) and short one.
-        * As workaround, set to 10 before setting to 100
-        * at forced 100 F/H mode.
-        */
-       if (!phydev->autoneg && (phydev->speed == 100)) {
-               /* disable phy interrupt */
-               temp = phy_read(phydev, LAN88XX_INT_MASK);
-               temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_;
-               phy_write(phydev, LAN88XX_INT_MASK, temp);
 
-               temp = phy_read(phydev, MII_BMCR);
-               temp &= ~(BMCR_SPEED100 | BMCR_SPEED1000);
-               phy_write(phydev, MII_BMCR, temp); /* set to 10 first */
-               temp |= BMCR_SPEED100;
-               phy_write(phydev, MII_BMCR, temp); /* set to 100 later */
-
-               /* clear pending interrupt generated while workaround */
-               temp = phy_read(phydev, LAN88XX_INT_STS);
-
-               /* enable phy interrupt back */
-               temp = phy_read(phydev, LAN88XX_INT_MASK);
-               temp |= LAN88XX_INT_MASK_MDINTPIN_EN_;
-               phy_write(phydev, LAN88XX_INT_MASK, temp);
-       }
+       phy_print_status(phydev);
 }
 
 static int irq_map(struct irq_domain *d, unsigned int irq,
@@ -3604,13 +3579,29 @@ static int lan78xx_rx(struct lan78xx_net *dev, struct sk_buff *skb,
                size = (rx_cmd_a & RX_CMD_A_LEN_MASK_);
                align_count = (4 - ((size + RXW_PADDING) % 4)) % 4;
 
+               if (unlikely(size > skb->len)) {
+                       netif_dbg(dev, rx_err, dev->net,
+                                 "size err rx_cmd_a=0x%08x\n",
+                                 rx_cmd_a);
+                       return 0;
+               }
+
                if (unlikely(rx_cmd_a & RX_CMD_A_RED_)) {
                        netif_dbg(dev, rx_err, dev->net,
                                  "Error rx_cmd_a=0x%08x", rx_cmd_a);
                } else {
-                       u32 frame_len = size - ETH_FCS_LEN;
+                       u32 frame_len;
                        struct sk_buff *skb2;
 
+                       if (unlikely(size < ETH_FCS_LEN)) {
+                               netif_dbg(dev, rx_err, dev->net,
+                                         "size err rx_cmd_a=0x%08x\n",
+                                         rx_cmd_a);
+                               return 0;
+                       }
+
+                       frame_len = size - ETH_FCS_LEN;
+
                        skb2 = napi_alloc_skb(&dev->napi, frame_len);
                        if (!skb2)
                                return 0;
index 7a2b0094de51f53dd2161fce0ff04193a1f85654..2894114858a295aaea4f04666db198cff5e6b3cb 100644 (file)
@@ -61,12 +61,6 @@ pl_vendor_req(struct usbnet *dev, u8 req, u8 val, u8 index)
                                val, index, NULL, 0);
 }
 
-static inline int
-pl_clear_QuickLink_features(struct usbnet *dev, int val)
-{
-       return pl_vendor_req(dev, 1, (u8) val, 0);
-}
-
 static inline int
 pl_set_QuickLink_features(struct usbnet *dev, int val)
 {
index a808d718c0123ca76fbf152e22cf845bdb0bd647..571e37e67f9ce1706de16d3f4a4f9c883a6e8992 100644 (file)
@@ -1364,6 +1364,7 @@ static const struct usb_device_id products[] = {
        {QMI_QUIRK_SET_DTR(0x1bc7, 0x1057, 2)}, /* Telit FN980 */
        {QMI_QUIRK_SET_DTR(0x1bc7, 0x1060, 2)}, /* Telit LN920 */
        {QMI_QUIRK_SET_DTR(0x1bc7, 0x1070, 2)}, /* Telit FN990 */
+       {QMI_QUIRK_SET_DTR(0x1bc7, 0x1080, 2)}, /* Telit FE990 */
        {QMI_FIXED_INTF(0x1bc7, 0x1100, 3)},    /* Telit ME910 */
        {QMI_FIXED_INTF(0x1bc7, 0x1101, 3)},    /* Telit ME910 dual modem */
        {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},    /* Telit LE920 */
index decb5ba56a25941d1b5f58495d26e8320607bf43..0fc4b959edc18e6bdd156ff1ec642a7dce8c343e 100644 (file)
@@ -1943,7 +1943,7 @@ static struct rx_agg *alloc_rx_agg(struct r8152 *tp, gfp_t mflags)
        if (!rx_agg)
                return NULL;
 
-       rx_agg->page = alloc_pages(mflags | __GFP_COMP, order);
+       rx_agg->page = alloc_pages(mflags | __GFP_COMP | __GFP_NOWARN, order);
        if (!rx_agg->page)
                goto free_rx;
 
index 95de452ff4dad58f05e571b1e569a4d46a9129e2..5d6454fedb3f17707f7cd8a3b963da08e67c76c9 100644 (file)
@@ -2200,6 +2200,13 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
                size = (rx_cmd_a & RX_CMD_A_LEN) - RXW_PADDING;
                align_count = (4 - ((size + RXW_PADDING) % 4)) % 4;
 
+               if (unlikely(size > skb->len)) {
+                       netif_dbg(dev, rx_err, dev->net,
+                                 "size err rx_cmd_a=0x%08x\n",
+                                 rx_cmd_a);
+                       return 0;
+               }
+
                if (unlikely(rx_cmd_a & RX_CMD_A_RED)) {
                        netif_dbg(dev, rx_err, dev->net,
                                  "Error rx_cmd_a=0x%08x\n", rx_cmd_a);
index 32d2c60d334dc75abb495cca3b752b2aa64aad9a..563ecd27b93ea56441daf150aecfa2f51219e6cc 100644 (file)
@@ -1833,6 +1833,12 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
                size = (u16)((header & RX_STS_FL_) >> 16);
                align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4;
 
+               if (unlikely(size > skb->len)) {
+                       netif_dbg(dev, rx_err, dev->net,
+                                 "size err header=0x%08x\n", header);
+                       return 0;
+               }
+
                if (unlikely(header & RX_STS_ES_)) {
                        netif_dbg(dev, rx_err, dev->net,
                                  "Error header=0x%08x\n", header);
index 1bb54de7124d95e4974c158017ac6611a370c4d8..4b3c6647edc669413ccd0bccb70e406a43e9320c 100644 (file)
@@ -708,7 +708,8 @@ static int veth_convert_skb_to_xdp_buff(struct veth_rq *rq,
        u32 frame_sz;
 
        if (skb_shared(skb) || skb_head_is_locked(skb) ||
-           skb_shinfo(skb)->nr_frags) {
+           skb_shinfo(skb)->nr_frags ||
+           skb_headroom(skb) < XDP_PACKET_HEADROOM) {
                u32 size, len, max_head_size, off;
                struct sk_buff *nskb;
                struct page *page;
@@ -773,9 +774,6 @@ static int veth_convert_skb_to_xdp_buff(struct veth_rq *rq,
 
                consume_skb(skb);
                skb = nskb;
-       } else if (skb_headroom(skb) < XDP_PACKET_HEADROOM &&
-                  pskb_expand_head(skb, VETH_XDP_HEADROOM, 0, GFP_ATOMIC)) {
-               goto drop;
        }
 
        /* SKB "head" area always have tailroom for skb_shared_info */
@@ -1257,6 +1255,27 @@ static int veth_enable_range_safe(struct net_device *dev, int start, int end)
        return 0;
 }
 
+static void veth_set_xdp_features(struct net_device *dev)
+{
+       struct veth_priv *priv = netdev_priv(dev);
+       struct net_device *peer;
+
+       peer = rtnl_dereference(priv->peer);
+       if (peer && peer->real_num_tx_queues <= dev->real_num_rx_queues) {
+               struct veth_priv *priv_peer = netdev_priv(peer);
+               xdp_features_t val = NETDEV_XDP_ACT_BASIC |
+                                    NETDEV_XDP_ACT_REDIRECT |
+                                    NETDEV_XDP_ACT_RX_SG;
+
+               if (priv_peer->_xdp_prog || veth_gro_requested(peer))
+                       val |= NETDEV_XDP_ACT_NDO_XMIT |
+                              NETDEV_XDP_ACT_NDO_XMIT_SG;
+               xdp_set_features_flag(dev, val);
+       } else {
+               xdp_clear_features_flag(dev);
+       }
+}
+
 static int veth_set_channels(struct net_device *dev,
                             struct ethtool_channels *ch)
 {
@@ -1323,6 +1342,12 @@ out:
                if (peer)
                        netif_carrier_on(peer);
        }
+
+       /* update XDP supported features */
+       veth_set_xdp_features(dev);
+       if (peer)
+               veth_set_xdp_features(peer);
+
        return err;
 
 revert:
@@ -1480,16 +1505,23 @@ static int veth_set_features(struct net_device *dev,
 {
        netdev_features_t changed = features ^ dev->features;
        struct veth_priv *priv = netdev_priv(dev);
+       struct net_device *peer;
        int err;
 
        if (!(changed & NETIF_F_GRO) || !(dev->flags & IFF_UP) || priv->_xdp_prog)
                return 0;
 
+       peer = rtnl_dereference(priv->peer);
        if (features & NETIF_F_GRO) {
                err = veth_napi_enable(dev);
                if (err)
                        return err;
+
+               if (peer)
+                       xdp_features_set_redirect_target(peer, true);
        } else {
+               if (peer)
+                       xdp_features_clear_redirect_target(peer);
                veth_napi_del(dev);
        }
        return 0;
@@ -1570,10 +1602,15 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog,
                        peer->hw_features &= ~NETIF_F_GSO_SOFTWARE;
                        peer->max_mtu = max_mtu;
                }
+
+               xdp_features_set_redirect_target(peer, true);
        }
 
        if (old_prog) {
                if (!prog) {
+                       if (peer && !veth_gro_requested(dev))
+                               xdp_features_clear_redirect_target(peer);
+
                        if (dev->flags & IFF_UP)
                                veth_disable_xdp(dev);
 
@@ -1610,20 +1647,24 @@ static int veth_xdp_rx_timestamp(const struct xdp_md *ctx, u64 *timestamp)
        struct veth_xdp_buff *_ctx = (void *)ctx;
 
        if (!_ctx->skb)
-               return -EOPNOTSUPP;
+               return -ENODATA;
 
        *timestamp = skb_hwtstamps(_ctx->skb)->hwtstamp;
        return 0;
 }
 
-static int veth_xdp_rx_hash(const struct xdp_md *ctx, u32 *hash)
+static int veth_xdp_rx_hash(const struct xdp_md *ctx, u32 *hash,
+                           enum xdp_rss_hash_type *rss_type)
 {
        struct veth_xdp_buff *_ctx = (void *)ctx;
+       struct sk_buff *skb = _ctx->skb;
 
-       if (!_ctx->skb)
-               return -EOPNOTSUPP;
+       if (!skb)
+               return -ENODATA;
+
+       *hash = skb_get_hash(skb);
+       *rss_type = skb->l4_hash ? XDP_RSS_TYPE_L4_ANY : XDP_RSS_TYPE_NONE;
 
-       *hash = skb_get_hash(_ctx->skb);
        return 0;
 }
 
@@ -1686,10 +1727,6 @@ static void veth_setup(struct net_device *dev)
        dev->hw_enc_features = VETH_FEATURES;
        dev->mpls_features = NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE;
        netif_set_tso_max_size(dev, GSO_MAX_SIZE);
-
-       dev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
-                           NETDEV_XDP_ACT_NDO_XMIT | NETDEV_XDP_ACT_RX_SG |
-                           NETDEV_XDP_ACT_NDO_XMIT_SG;
 }
 
 /*
@@ -1857,6 +1894,10 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
                goto err_queues;
 
        veth_disable_gro(dev);
+       /* update XDP supported features */
+       veth_set_xdp_features(dev);
+       veth_set_xdp_features(peer);
+
        return 0;
 
 err_queues:
index fb5e68ed3ec27c1895f96108e35ee7b4832595b6..ea1bd4bb326d1690c2b01ee0ef3179dc7674a411 100644 (file)
@@ -446,7 +446,8 @@ static unsigned int mergeable_ctx_to_truesize(void *mrg_ctx)
 static struct sk_buff *page_to_skb(struct virtnet_info *vi,
                                   struct receive_queue *rq,
                                   struct page *page, unsigned int offset,
-                                  unsigned int len, unsigned int truesize)
+                                  unsigned int len, unsigned int truesize,
+                                  unsigned int headroom)
 {
        struct sk_buff *skb;
        struct virtio_net_hdr_mrg_rxbuf *hdr;
@@ -464,11 +465,11 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
        else
                hdr_padded_len = sizeof(struct padded_vnet_hdr);
 
-       buf = p;
+       buf = p - headroom;
        len -= hdr_len;
        offset += hdr_padded_len;
        p += hdr_padded_len;
-       tailroom = truesize - hdr_padded_len - len;
+       tailroom = truesize - headroom  - hdr_padded_len - len;
 
        shinfo_size = SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 
@@ -545,6 +546,87 @@ ok:
        return skb;
 }
 
+static void free_old_xmit_skbs(struct send_queue *sq, bool in_napi)
+{
+       unsigned int len;
+       unsigned int packets = 0;
+       unsigned int bytes = 0;
+       void *ptr;
+
+       while ((ptr = virtqueue_get_buf(sq->vq, &len)) != NULL) {
+               if (likely(!is_xdp_frame(ptr))) {
+                       struct sk_buff *skb = ptr;
+
+                       pr_debug("Sent skb %p\n", skb);
+
+                       bytes += skb->len;
+                       napi_consume_skb(skb, in_napi);
+               } else {
+                       struct xdp_frame *frame = ptr_to_xdp(ptr);
+
+                       bytes += xdp_get_frame_len(frame);
+                       xdp_return_frame(frame);
+               }
+               packets++;
+       }
+
+       /* Avoid overhead when no packets have been processed
+        * happens when called speculatively from start_xmit.
+        */
+       if (!packets)
+               return;
+
+       u64_stats_update_begin(&sq->stats.syncp);
+       sq->stats.bytes += bytes;
+       sq->stats.packets += packets;
+       u64_stats_update_end(&sq->stats.syncp);
+}
+
+static bool is_xdp_raw_buffer_queue(struct virtnet_info *vi, int q)
+{
+       if (q < (vi->curr_queue_pairs - vi->xdp_queue_pairs))
+               return false;
+       else if (q < vi->curr_queue_pairs)
+               return true;
+       else
+               return false;
+}
+
+static void check_sq_full_and_disable(struct virtnet_info *vi,
+                                     struct net_device *dev,
+                                     struct send_queue *sq)
+{
+       bool use_napi = sq->napi.weight;
+       int qnum;
+
+       qnum = sq - vi->sq;
+
+       /* If running out of space, stop queue to avoid getting packets that we
+        * are then unable to transmit.
+        * An alternative would be to force queuing layer to requeue the skb by
+        * returning NETDEV_TX_BUSY. However, NETDEV_TX_BUSY should not be
+        * returned in a normal path of operation: it means that driver is not
+        * maintaining the TX queue stop/start state properly, and causes
+        * the stack to do a non-trivial amount of useless work.
+        * Since most packets only take 1 or 2 ring slots, stopping the queue
+        * early means 16 slots are typically wasted.
+        */
+       if (sq->vq->num_free < 2+MAX_SKB_FRAGS) {
+               netif_stop_subqueue(dev, qnum);
+               if (use_napi) {
+                       if (unlikely(!virtqueue_enable_cb_delayed(sq->vq)))
+                               virtqueue_napi_schedule(&sq->napi, sq->vq);
+               } else if (unlikely(!virtqueue_enable_cb_delayed(sq->vq))) {
+                       /* More just got used, free them then recheck. */
+                       free_old_xmit_skbs(sq, false);
+                       if (sq->vq->num_free >= 2+MAX_SKB_FRAGS) {
+                               netif_start_subqueue(dev, qnum);
+                               virtqueue_disable_cb(sq->vq);
+                       }
+               }
+       }
+}
+
 static int __virtnet_xdp_xmit_one(struct virtnet_info *vi,
                                   struct send_queue *sq,
                                   struct xdp_frame *xdpf)
@@ -686,6 +768,9 @@ static int virtnet_xdp_xmit(struct net_device *dev,
        }
        ret = nxmit;
 
+       if (!is_xdp_raw_buffer_queue(vi, sq - vi->sq))
+               check_sq_full_and_disable(vi, dev, sq);
+
        if (flags & XDP_XMIT_FLUSH) {
                if (virtqueue_kick_prepare(sq->vq) && virtqueue_notify(sq->vq))
                        kicks = 1;
@@ -729,8 +814,13 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
                                       int page_off,
                                       unsigned int *len)
 {
-       struct page *page = alloc_page(GFP_ATOMIC);
+       int tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+       struct page *page;
+
+       if (page_off + *len + tailroom > PAGE_SIZE)
+               return NULL;
 
+       page = alloc_page(GFP_ATOMIC);
        if (!page)
                return NULL;
 
@@ -738,7 +828,6 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
        page_off += *len;
 
        while (--*num_buf) {
-               int tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
                unsigned int buflen;
                void *buf;
                int off;
@@ -925,7 +1014,7 @@ static struct sk_buff *receive_big(struct net_device *dev,
 {
        struct page *page = buf;
        struct sk_buff *skb =
-               page_to_skb(vi, rq, page, 0, len, PAGE_SIZE);
+               page_to_skb(vi, rq, page, 0, len, PAGE_SIZE, 0);
 
        stats->bytes += len - vi->hdr_len;
        if (unlikely(!skb))
@@ -1188,9 +1277,12 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 
                switch (act) {
                case XDP_PASS:
+                       head_skb = build_skb_from_xdp_buff(dev, vi, &xdp, xdp_frags_truesz);
+                       if (unlikely(!head_skb))
+                               goto err_xdp_frags;
+
                        if (unlikely(xdp_page != page))
                                put_page(page);
-                       head_skb = build_skb_from_xdp_buff(dev, vi, &xdp, xdp_frags_truesz);
                        rcu_read_unlock();
                        return head_skb;
                case XDP_TX:
@@ -1248,7 +1340,7 @@ err_xdp_frags:
        rcu_read_unlock();
 
 skip_xdp:
-       head_skb = page_to_skb(vi, rq, page, offset, len, truesize);
+       head_skb = page_to_skb(vi, rq, page, offset, len, truesize, headroom);
        curr_skb = head_skb;
 
        if (unlikely(!curr_skb))
@@ -1714,52 +1806,6 @@ static int virtnet_receive(struct receive_queue *rq, int budget,
        return stats.packets;
 }
 
-static void free_old_xmit_skbs(struct send_queue *sq, bool in_napi)
-{
-       unsigned int len;
-       unsigned int packets = 0;
-       unsigned int bytes = 0;
-       void *ptr;
-
-       while ((ptr = virtqueue_get_buf(sq->vq, &len)) != NULL) {
-               if (likely(!is_xdp_frame(ptr))) {
-                       struct sk_buff *skb = ptr;
-
-                       pr_debug("Sent skb %p\n", skb);
-
-                       bytes += skb->len;
-                       napi_consume_skb(skb, in_napi);
-               } else {
-                       struct xdp_frame *frame = ptr_to_xdp(ptr);
-
-                       bytes += xdp_get_frame_len(frame);
-                       xdp_return_frame(frame);
-               }
-               packets++;
-       }
-
-       /* Avoid overhead when no packets have been processed
-        * happens when called speculatively from start_xmit.
-        */
-       if (!packets)
-               return;
-
-       u64_stats_update_begin(&sq->stats.syncp);
-       sq->stats.bytes += bytes;
-       sq->stats.packets += packets;
-       u64_stats_update_end(&sq->stats.syncp);
-}
-
-static bool is_xdp_raw_buffer_queue(struct virtnet_info *vi, int q)
-{
-       if (q < (vi->curr_queue_pairs - vi->xdp_queue_pairs))
-               return false;
-       else if (q < vi->curr_queue_pairs)
-               return true;
-       else
-               return false;
-}
-
 static void virtnet_poll_cleantx(struct receive_queue *rq)
 {
        struct virtnet_info *vi = rq->vq->vdev->priv;
@@ -1989,30 +2035,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
                nf_reset_ct(skb);
        }
 
-       /* If running out of space, stop queue to avoid getting packets that we
-        * are then unable to transmit.
-        * An alternative would be to force queuing layer to requeue the skb by
-        * returning NETDEV_TX_BUSY. However, NETDEV_TX_BUSY should not be
-        * returned in a normal path of operation: it means that driver is not
-        * maintaining the TX queue stop/start state properly, and causes
-        * the stack to do a non-trivial amount of useless work.
-        * Since most packets only take 1 or 2 ring slots, stopping the queue
-        * early means 16 slots are typically wasted.
-        */
-       if (sq->vq->num_free < 2+MAX_SKB_FRAGS) {
-               netif_stop_subqueue(dev, qnum);
-               if (use_napi) {
-                       if (unlikely(!virtqueue_enable_cb_delayed(sq->vq)))
-                               virtqueue_napi_schedule(&sq->napi, sq->vq);
-               } else if (unlikely(!virtqueue_enable_cb_delayed(sq->vq))) {
-                       /* More just got used, free them then recheck. */
-                       free_old_xmit_skbs(sq, false);
-                       if (sq->vq->num_free >= 2+MAX_SKB_FRAGS) {
-                               netif_start_subqueue(dev, qnum);
-                               virtqueue_disable_cb(sq->vq);
-                       }
-               }
-       }
+       check_sq_full_and_disable(vi, dev, sq);
 
        if (kick || netif_xmit_stopped(txq)) {
                if (virtqueue_kick_prepare(sq->vq) && virtqueue_notify(sq->vq)) {
index 682987040ea821e74d2d732a77d93d546f803006..f2b76ee866a4a80154591bab17a4483d9897fcb8 100644 (file)
@@ -1504,7 +1504,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
                                goto rcd_done;
                        }
 
-                       if (rxDataRingUsed) {
+                       if (rxDataRingUsed && adapter->rxdataring_enabled) {
                                size_t sz;
 
                                BUG_ON(rcd->len > rq->data_ring.desc_size);
@@ -1688,7 +1688,9 @@ not_lro:
                        if (unlikely(rcd->ts))
                                __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), rcd->tci);
 
-                       if (adapter->netdev->features & NETIF_F_LRO)
+                       /* Use GRO callback if UPT is enabled */
+                       if ((adapter->netdev->features & NETIF_F_LRO) &&
+                           !rq->shared->updateRxProd)
                                netif_receive_skb(skb);
                        else
                                napi_gro_receive(&rq->napi, skb);
index 1c53b5546927052a336bcefabd6876c999f6f1c2..47c2ad7a3e429ae03fc732024728b113fe77d87e 100644 (file)
@@ -1177,14 +1177,9 @@ static int ucc_hdlc_probe(struct platform_device *pdev)
        uhdlc_priv->dev = &pdev->dev;
        uhdlc_priv->ut_info = ut_info;
 
-       if (of_get_property(np, "fsl,tdm-interface", NULL))
-               uhdlc_priv->tsa = 1;
-
-       if (of_get_property(np, "fsl,ucc-internal-loopback", NULL))
-               uhdlc_priv->loopback = 1;
-
-       if (of_get_property(np, "fsl,hdlc-bus", NULL))
-               uhdlc_priv->hdlc_bus = 1;
+       uhdlc_priv->tsa = of_property_read_bool(np, "fsl,tdm-interface");
+       uhdlc_priv->loopback = of_property_read_bool(np, "fsl,ucc-internal-loopback");
+       uhdlc_priv->hdlc_bus = of_property_read_bool(np, "fsl,hdlc-bus");
 
        if (uhdlc_priv->tsa == 1) {
                utdm = kzalloc(sizeof(*utdm), GFP_KERNEL);
index 583adb37ee1e31e6f03858f6893b631e0d26d147..125284b346a7765f264c9e8ebaaeb0885c4bad91 100644 (file)
@@ -106,7 +106,7 @@ static inline int wg_cpumask_choose_online(int *stored_cpu, unsigned int id)
 {
        unsigned int cpu = *stored_cpu, cpu_index, i;
 
-       if (unlikely(cpu == nr_cpumask_bits ||
+       if (unlikely(cpu >= nr_cpu_ids ||
                     !cpumask_test_cpu(cpu, cpu_online_mask))) {
                cpu_index = id % cpumask_weight(cpu_online_mask);
                cpu = cpumask_first(cpu_online_mask);
index 86995e8dc9135162233959920827b615534845df..a62ee05c54097253d3514ffbc1c2c7e95e1141d7 100644 (file)
@@ -16,7 +16,7 @@
 #include "pci.h"
 #include "pcic.h"
 
-#define MHI_TIMEOUT_DEFAULT_MS 90000
+#define MHI_TIMEOUT_DEFAULT_MS 20000
 #define RDDM_DUMP_SIZE 0x420000
 
 static struct mhi_channel_config ath11k_mhi_channels_qca6390[] = {
index 3363fc4e89661a98d1e1a96a7b3cccf5dafd15fb..a0845002d6fe325584e6c35030809fabf15c4207 100644 (file)
@@ -646,9 +646,7 @@ void ath9k_mci_update_wlan_channels(struct ath_softc *sc, bool allow_all)
        struct ath_hw *ah = sc->sc_ah;
        struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
        struct ath9k_channel *chan = ah->curchan;
-       static const u32 channelmap[] = {
-               0x00000000, 0xffff0000, 0xffffffff, 0x7fffffff
-       };
+       u32 channelmap[] = {0x00000000, 0xffff0000, 0xffffffff, 0x7fffffff};
        int i;
        s16 chan_start, chan_end;
        u16 wlan_chan;
index b7c918f241c91e77ce30876232f25f5ba80fe031..65d4799a5658404cfad861367d7ba69559db7635 100644 (file)
@@ -994,15 +994,34 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = {
 MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
 
 
-static void brcmf_sdiod_acpi_set_power_manageable(struct device *dev,
-                                                 int val)
+static void brcmf_sdiod_acpi_save_power_manageable(struct brcmf_sdio_dev *sdiodev)
 {
 #if IS_ENABLED(CONFIG_ACPI)
        struct acpi_device *adev;
 
-       adev = ACPI_COMPANION(dev);
+       adev = ACPI_COMPANION(&sdiodev->func1->dev);
        if (adev)
-               adev->flags.power_manageable = 0;
+               sdiodev->func1_power_manageable = adev->flags.power_manageable;
+
+       adev = ACPI_COMPANION(&sdiodev->func2->dev);
+       if (adev)
+               sdiodev->func2_power_manageable = adev->flags.power_manageable;
+#endif
+}
+
+static void brcmf_sdiod_acpi_set_power_manageable(struct brcmf_sdio_dev *sdiodev,
+                                                 int enable)
+{
+#if IS_ENABLED(CONFIG_ACPI)
+       struct acpi_device *adev;
+
+       adev = ACPI_COMPANION(&sdiodev->func1->dev);
+       if (adev)
+               adev->flags.power_manageable = enable ? sdiodev->func1_power_manageable : 0;
+
+       adev = ACPI_COMPANION(&sdiodev->func2->dev);
+       if (adev)
+               adev->flags.power_manageable = enable ? sdiodev->func2_power_manageable : 0;
 #endif
 }
 
@@ -1012,7 +1031,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
        int err;
        struct brcmf_sdio_dev *sdiodev;
        struct brcmf_bus *bus_if;
-       struct device *dev;
 
        brcmf_dbg(SDIO, "Enter\n");
        brcmf_dbg(SDIO, "Class=%x\n", func->class);
@@ -1020,14 +1038,9 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
        brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
        brcmf_dbg(SDIO, "Function#: %d\n", func->num);
 
-       dev = &func->dev;
-
        /* Set MMC_QUIRK_LENIENT_FN0 for this card */
        func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
 
-       /* prohibit ACPI power management for this device */
-       brcmf_sdiod_acpi_set_power_manageable(dev, 0);
-
        /* Consume func num 1 but dont do anything with it. */
        if (func->num == 1)
                return 0;
@@ -1059,6 +1072,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
        dev_set_drvdata(&sdiodev->func1->dev, bus_if);
        sdiodev->dev = &sdiodev->func1->dev;
 
+       brcmf_sdiod_acpi_save_power_manageable(sdiodev);
        brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_DOWN);
 
        brcmf_dbg(SDIO, "F2 found, calling brcmf_sdiod_probe...\n");
@@ -1124,6 +1138,8 @@ void brcmf_sdio_wowl_config(struct device *dev, bool enabled)
 
        if (sdiodev->settings->bus.sdio.oob_irq_supported ||
            pm_caps & MMC_PM_WAKE_SDIO_IRQ) {
+               /* Stop ACPI from turning off the device when wowl is enabled */
+               brcmf_sdiod_acpi_set_power_manageable(sdiodev, !enabled);
                sdiodev->wowl_enabled = enabled;
                brcmf_dbg(SDIO, "Configuring WOWL, enabled=%d\n", enabled);
                return;
index b76d34d36bde6435f11390a3c10e3f5ccb243acd..0d18ed15b4032a9925660384ff9918cd3f38e76b 100644 (file)
@@ -188,6 +188,8 @@ struct brcmf_sdio_dev {
        char nvram_name[BRCMF_FW_NAME_LEN];
        char clm_name[BRCMF_FW_NAME_LEN];
        bool wowl_enabled;
+       bool func1_power_manageable;
+       bool func2_power_manageable;
        enum brcmf_sdiod_state state;
        struct brcmf_sdiod_freezer *freezer;
        const struct firmware *clm_fw;
index 565522466eba5465f15be91a72b370f40afae71e..b55b1b17f4d197cf32775699087702bae2396bff 100644 (file)
@@ -732,7 +732,10 @@ void iwl_mvm_mac_itxq_xmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
 
        rcu_read_lock();
        do {
-               while (likely(!mvmtxq->stopped &&
+               while (likely(!test_bit(IWL_MVM_TXQ_STATE_STOP_FULL,
+                                       &mvmtxq->state) &&
+                             !test_bit(IWL_MVM_TXQ_STATE_STOP_REDIRECT,
+                                       &mvmtxq->state) &&
                              !test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status))) {
                        skb = ieee80211_tx_dequeue(hw, txq);
 
@@ -757,42 +760,25 @@ static void iwl_mvm_mac_wake_tx_queue(struct ieee80211_hw *hw,
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
        struct iwl_mvm_txq *mvmtxq = iwl_mvm_txq_from_mac80211(txq);
 
-       /*
-        * Please note that racing is handled very carefully here:
-        * mvmtxq->txq_id is updated during allocation, and mvmtxq->list is
-        * deleted afterwards.
-        * This means that if:
-        * mvmtxq->txq_id != INVALID_QUEUE && list_empty(&mvmtxq->list):
-        *      queue is allocated and we can TX.
-        * mvmtxq->txq_id != INVALID_QUEUE && !list_empty(&mvmtxq->list):
-        *      a race, should defer the frame.
-        * mvmtxq->txq_id == INVALID_QUEUE && list_empty(&mvmtxq->list):
-        *      need to allocate the queue and defer the frame.
-        * mvmtxq->txq_id == INVALID_QUEUE && !list_empty(&mvmtxq->list):
-        *      queue is already scheduled for allocation, no need to allocate,
-        *      should defer the frame.
-        */
-
-       /* If the queue is allocated TX and return. */
-       if (!txq->sta || mvmtxq->txq_id != IWL_MVM_INVALID_QUEUE) {
-               /*
-                * Check that list is empty to avoid a race where txq_id is
-                * already updated, but the queue allocation work wasn't
-                * finished
-                */
-               if (unlikely(txq->sta && !list_empty(&mvmtxq->list)))
-                       return;
-
+       if (likely(test_bit(IWL_MVM_TXQ_STATE_READY, &mvmtxq->state)) ||
+           !txq->sta) {
                iwl_mvm_mac_itxq_xmit(hw, txq);
                return;
        }
 
-       /* The list is being deleted only after the queue is fully allocated. */
-       if (!list_empty(&mvmtxq->list))
-               return;
+       /* iwl_mvm_mac_itxq_xmit() will later be called by the worker
+        * to handle any packets we leave on the txq now
+        */
 
-       list_add_tail(&mvmtxq->list, &mvm->add_stream_txqs);
-       schedule_work(&mvm->add_stream_wk);
+       spin_lock_bh(&mvm->add_stream_lock);
+       /* The list is being deleted only after the queue is fully allocated. */
+       if (list_empty(&mvmtxq->list) &&
+           /* recheck under lock */
+           !test_bit(IWL_MVM_TXQ_STATE_READY, &mvmtxq->state)) {
+               list_add_tail(&mvmtxq->list, &mvm->add_stream_txqs);
+               schedule_work(&mvm->add_stream_wk);
+       }
+       spin_unlock_bh(&mvm->add_stream_lock);
 }
 
 #define CHECK_BA_TRIGGER(_mvm, _trig, _tid_bm, _tid, _fmt...)          \
index 90bc95d96a78e8894a5b5bc6f0eba4d8ac9037da..f307c345dfa0b4b9b815daa717f51751d17cdf0d 100644 (file)
@@ -729,7 +729,10 @@ struct iwl_mvm_txq {
        struct list_head list;
        u16 txq_id;
        atomic_t tx_request;
-       bool stopped;
+#define IWL_MVM_TXQ_STATE_STOP_FULL    0
+#define IWL_MVM_TXQ_STATE_STOP_REDIRECT        1
+#define IWL_MVM_TXQ_STATE_READY                2
+       unsigned long state;
 };
 
 static inline struct iwl_mvm_txq *
@@ -827,6 +830,7 @@ struct iwl_mvm {
                struct iwl_mvm_tvqm_txq_info tvqm_info[IWL_MAX_TVQM_QUEUES];
        };
        struct work_struct add_stream_wk; /* To add streams to queues */
+       spinlock_t add_stream_lock;
 
        const char *nvm_file_name;
        struct iwl_nvm_data *nvm_data;
index f4e9446d9dc2d959b52fa6ab84ae12573f050141..9711841bb4564d33b8edaab378ced12db0a295b6 100644 (file)
@@ -1195,6 +1195,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
        INIT_DELAYED_WORK(&mvm->scan_timeout_dwork, iwl_mvm_scan_timeout_wk);
        INIT_WORK(&mvm->add_stream_wk, iwl_mvm_add_new_dqa_stream_wk);
        INIT_LIST_HEAD(&mvm->add_stream_txqs);
+       spin_lock_init(&mvm->add_stream_lock);
 
        init_waitqueue_head(&mvm->rx_sync_waitq);
 
@@ -1691,7 +1692,10 @@ static void iwl_mvm_queue_state_change(struct iwl_op_mode *op_mode,
 
                txq = sta->txq[tid];
                mvmtxq = iwl_mvm_txq_from_mac80211(txq);
-               mvmtxq->stopped = !start;
+               if (start)
+                       clear_bit(IWL_MVM_TXQ_STATE_STOP_FULL, &mvmtxq->state);
+               else
+                       set_bit(IWL_MVM_TXQ_STATE_STOP_FULL, &mvmtxq->state);
 
                if (start && mvmsta->sta_state != IEEE80211_STA_NOTEXIST)
                        iwl_mvm_mac_itxq_xmit(mvm->hw, txq);
index 69634fb82a9bf104530e04eac0d3e6f44dbff9c8..9caae77995ca933cdce204fac7663c51213f9389 100644 (file)
@@ -384,8 +384,11 @@ static int iwl_mvm_disable_txq(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
                struct iwl_mvm_txq *mvmtxq =
                        iwl_mvm_txq_from_tid(sta, tid);
 
-               mvmtxq->txq_id = IWL_MVM_INVALID_QUEUE;
+               spin_lock_bh(&mvm->add_stream_lock);
                list_del_init(&mvmtxq->list);
+               clear_bit(IWL_MVM_TXQ_STATE_READY, &mvmtxq->state);
+               mvmtxq->txq_id = IWL_MVM_INVALID_QUEUE;
+               spin_unlock_bh(&mvm->add_stream_lock);
        }
 
        /* Regardless if this is a reserved TXQ for a STA - mark it as false */
@@ -479,8 +482,11 @@ static int iwl_mvm_remove_sta_queue_marking(struct iwl_mvm *mvm, int queue)
                        disable_agg_tids |= BIT(tid);
                mvmsta->tid_data[tid].txq_id = IWL_MVM_INVALID_QUEUE;
 
-               mvmtxq->txq_id = IWL_MVM_INVALID_QUEUE;
+               spin_lock_bh(&mvm->add_stream_lock);
                list_del_init(&mvmtxq->list);
+               clear_bit(IWL_MVM_TXQ_STATE_READY, &mvmtxq->state);
+               mvmtxq->txq_id = IWL_MVM_INVALID_QUEUE;
+               spin_unlock_bh(&mvm->add_stream_lock);
        }
 
        mvmsta->tfd_queue_msk &= ~BIT(queue); /* Don't use this queue anymore */
@@ -693,7 +699,7 @@ static int iwl_mvm_redirect_queue(struct iwl_mvm *mvm, int queue, int tid,
                            queue, iwl_mvm_ac_to_tx_fifo[ac]);
 
        /* Stop the queue and wait for it to empty */
-       txq->stopped = true;
+       set_bit(IWL_MVM_TXQ_STATE_STOP_REDIRECT, &txq->state);
 
        ret = iwl_trans_wait_tx_queues_empty(mvm->trans, BIT(queue));
        if (ret) {
@@ -736,7 +742,7 @@ static int iwl_mvm_redirect_queue(struct iwl_mvm *mvm, int queue, int tid,
 
 out:
        /* Continue using the queue */
-       txq->stopped = false;
+       clear_bit(IWL_MVM_TXQ_STATE_STOP_REDIRECT, &txq->state);
 
        return ret;
 }
@@ -1444,12 +1450,22 @@ void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk)
                 * a queue in the function itself.
                 */
                if (iwl_mvm_sta_alloc_queue(mvm, txq->sta, txq->ac, tid)) {
+                       spin_lock_bh(&mvm->add_stream_lock);
                        list_del_init(&mvmtxq->list);
+                       spin_unlock_bh(&mvm->add_stream_lock);
                        continue;
                }
 
-               list_del_init(&mvmtxq->list);
+               /* now we're ready, any remaining races/concurrency will be
+                * handled in iwl_mvm_mac_itxq_xmit()
+                */
+               set_bit(IWL_MVM_TXQ_STATE_READY, &mvmtxq->state);
+
                local_bh_disable();
+               spin_lock(&mvm->add_stream_lock);
+               list_del_init(&mvmtxq->list);
+               spin_unlock(&mvm->add_stream_lock);
+
                iwl_mvm_mac_itxq_xmit(mvm->hw, txq);
                local_bh_enable();
        }
@@ -1864,8 +1880,11 @@ static void iwl_mvm_disable_sta_queues(struct iwl_mvm *mvm,
                struct iwl_mvm_txq *mvmtxq =
                        iwl_mvm_txq_from_mac80211(sta->txq[i]);
 
+               spin_lock_bh(&mvm->add_stream_lock);
                mvmtxq->txq_id = IWL_MVM_INVALID_QUEUE;
                list_del_init(&mvmtxq->list);
+               clear_bit(IWL_MVM_TXQ_STATE_READY, &mvmtxq->state);
+               spin_unlock_bh(&mvm->add_stream_lock);
        }
 }
 
index 5dcf61761a165ae0d1b9c19cd84f4e740c47a09a..9a698a16a8f38e8cde08ff078b3021cb042224db 100644 (file)
@@ -172,7 +172,7 @@ static const struct mwifiex_pcie_device mwifiex_pcie8997 = {
        .can_ext_scan = true,
 };
 
-static const struct of_device_id mwifiex_pcie_of_match_table[] = {
+static const struct of_device_id mwifiex_pcie_of_match_table[] __maybe_unused = {
        { .compatible = "pci11ab,2b42" },
        { .compatible = "pci1b4b,2b42" },
        { }
index c64e24c10ea659908cd697321ac6adc996ddf835..a24bd40dd41ab88cdc7bd3ddcee7927df796e0fc 100644 (file)
@@ -495,7 +495,7 @@ static struct memory_type_mapping mem_type_mapping_tbl[] = {
        {"EXTLAST", NULL, 0, 0xFE},
 };
 
-static const struct of_device_id mwifiex_sdio_of_match_table[] = {
+static const struct of_device_id mwifiex_sdio_of_match_table[] __maybe_unused = {
        { .compatible = "marvell,sd8787" },
        { .compatible = "marvell,sd8897" },
        { .compatible = "marvell,sd8978" },
index b117e4467c87033a130b9a9bd44c14eb1b5fb015..34abf70f44aff8cf45f0e8d0d706643d3a10a06c 100644 (file)
@@ -539,6 +539,7 @@ int mt76_register_phy(struct mt76_phy *phy, bool vht,
        if (ret)
                return ret;
 
+       set_bit(MT76_STATE_REGISTERED, &phy->state);
        phy->dev->phys[phy->band_idx] = phy;
 
        return 0;
@@ -549,6 +550,9 @@ void mt76_unregister_phy(struct mt76_phy *phy)
 {
        struct mt76_dev *dev = phy->dev;
 
+       if (!test_bit(MT76_STATE_REGISTERED, &phy->state))
+               return;
+
        if (IS_ENABLED(CONFIG_MT76_LEDS))
                mt76_led_cleanup(phy);
        mt76_tx_status_check(dev, true);
@@ -719,6 +723,7 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
                return ret;
 
        WARN_ON(mt76_worker_setup(hw, &dev->tx_worker, NULL, "tx"));
+       set_bit(MT76_STATE_REGISTERED, &phy->state);
        sched_set_fifo_low(dev->tx_worker.task);
 
        return 0;
@@ -729,6 +734,9 @@ void mt76_unregister_device(struct mt76_dev *dev)
 {
        struct ieee80211_hw *hw = dev->hw;
 
+       if (!test_bit(MT76_STATE_REGISTERED, &dev->phy.state))
+               return;
+
        if (IS_ENABLED(CONFIG_MT76_LEDS))
                mt76_led_cleanup(&dev->phy);
        mt76_tx_status_check(dev, true);
index ccca0162c8f82cd3983a43dffad4cef8daff4952..183b0fc5a2d48c61d7cd5f554cc4b95a5cd74b74 100644 (file)
@@ -402,6 +402,7 @@ struct mt76_tx_cb {
 
 enum {
        MT76_STATE_INITIALIZED,
+       MT76_STATE_REGISTERED,
        MT76_STATE_RUNNING,
        MT76_STATE_MCU_RUNNING,
        MT76_SCANNING,
index ca50feb0b3a9d31fb768df9d1c1d8791f69f2d38..1b1358c6bb4642602f190579e1f36c1fcd79d850 100644 (file)
@@ -512,15 +512,15 @@ mt7603_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
            !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
                return -EOPNOTSUPP;
 
-       if (cmd == SET_KEY) {
-               key->hw_key_idx = wcid->idx;
-               wcid->hw_key_idx = idx;
-       } else {
+       if (cmd != SET_KEY) {
                if (idx == wcid->hw_key_idx)
                        wcid->hw_key_idx = -1;
 
-               key = NULL;
+               return 0;
        }
+
+       key->hw_key_idx = wcid->idx;
+       wcid->hw_key_idx = idx;
        mt76_wcid_key_setup(&dev->mt76, wcid, key);
 
        return mt7603_wtbl_set_key(dev, wcid->idx, key);
index a95602473359e396f76107a6f022ff2d234405e8..51a968a6afdc9d17fdf290891f59ff2ccc6a0084 100644 (file)
@@ -1193,8 +1193,7 @@ EXPORT_SYMBOL_GPL(mt7615_mac_enable_rtscts);
 static int
 mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
                           struct ieee80211_key_conf *key,
-                          enum mt76_cipher_type cipher, u16 cipher_mask,
-                          enum set_key_cmd cmd)
+                          enum mt76_cipher_type cipher, u16 cipher_mask)
 {
        u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx) + 30 * 4;
        u8 data[32] = {};
@@ -1203,27 +1202,18 @@ mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
                return -EINVAL;
 
        mt76_rr_copy(dev, addr, data, sizeof(data));
-       if (cmd == SET_KEY) {
-               if (cipher == MT_CIPHER_TKIP) {
-                       /* Rx/Tx MIC keys are swapped */
-                       memcpy(data, key->key, 16);
-                       memcpy(data + 16, key->key + 24, 8);
-                       memcpy(data + 24, key->key + 16, 8);
-               } else {
-                       if (cipher_mask == BIT(cipher))
-                               memcpy(data, key->key, key->keylen);
-                       else if (cipher != MT_CIPHER_BIP_CMAC_128)
-                               memcpy(data, key->key, 16);
-                       if (cipher == MT_CIPHER_BIP_CMAC_128)
-                               memcpy(data + 16, key->key, 16);
-               }
+       if (cipher == MT_CIPHER_TKIP) {
+               /* Rx/Tx MIC keys are swapped */
+               memcpy(data, key->key, 16);
+               memcpy(data + 16, key->key + 24, 8);
+               memcpy(data + 24, key->key + 16, 8);
        } else {
+               if (cipher_mask == BIT(cipher))
+                       memcpy(data, key->key, key->keylen);
+               else if (cipher != MT_CIPHER_BIP_CMAC_128)
+                       memcpy(data, key->key, 16);
                if (cipher == MT_CIPHER_BIP_CMAC_128)
-                       memset(data + 16, 0, 16);
-               else if (cipher_mask)
-                       memset(data, 0, 16);
-               if (!cipher_mask)
-                       memset(data, 0, sizeof(data));
+                       memcpy(data + 16, key->key, 16);
        }
 
        mt76_wr_copy(dev, addr, data, sizeof(data));
@@ -1234,7 +1224,7 @@ mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
 static int
 mt7615_mac_wtbl_update_pk(struct mt7615_dev *dev, struct mt76_wcid *wcid,
                          enum mt76_cipher_type cipher, u16 cipher_mask,
-                         int keyidx, enum set_key_cmd cmd)
+                         int keyidx)
 {
        u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx), w0, w1;
 
@@ -1253,9 +1243,7 @@ mt7615_mac_wtbl_update_pk(struct mt7615_dev *dev, struct mt76_wcid *wcid,
        else
                w0 &= ~MT_WTBL_W0_RX_IK_VALID;
 
-       if (cmd == SET_KEY &&
-           (cipher != MT_CIPHER_BIP_CMAC_128 ||
-            cipher_mask == BIT(cipher))) {
+       if (cipher != MT_CIPHER_BIP_CMAC_128 || cipher_mask == BIT(cipher)) {
                w0 &= ~MT_WTBL_W0_KEY_IDX;
                w0 |= FIELD_PREP(MT_WTBL_W0_KEY_IDX, keyidx);
        }
@@ -1272,19 +1260,10 @@ mt7615_mac_wtbl_update_pk(struct mt7615_dev *dev, struct mt76_wcid *wcid,
 
 static void
 mt7615_mac_wtbl_update_cipher(struct mt7615_dev *dev, struct mt76_wcid *wcid,
-                             enum mt76_cipher_type cipher, u16 cipher_mask,
-                             enum set_key_cmd cmd)
+                             enum mt76_cipher_type cipher, u16 cipher_mask)
 {
        u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx);
 
-       if (!cipher_mask) {
-               mt76_clear(dev, addr + 2 * 4, MT_WTBL_W2_KEY_TYPE);
-               return;
-       }
-
-       if (cmd != SET_KEY)
-               return;
-
        if (cipher == MT_CIPHER_BIP_CMAC_128 &&
            cipher_mask & ~BIT(MT_CIPHER_BIP_CMAC_128))
                return;
@@ -1295,8 +1274,7 @@ mt7615_mac_wtbl_update_cipher(struct mt7615_dev *dev, struct mt76_wcid *wcid,
 
 int __mt7615_mac_wtbl_set_key(struct mt7615_dev *dev,
                              struct mt76_wcid *wcid,
-                             struct ieee80211_key_conf *key,
-                             enum set_key_cmd cmd)
+                             struct ieee80211_key_conf *key)
 {
        enum mt76_cipher_type cipher;
        u16 cipher_mask = wcid->cipher;
@@ -1306,19 +1284,14 @@ int __mt7615_mac_wtbl_set_key(struct mt7615_dev *dev,
        if (cipher == MT_CIPHER_NONE)
                return -EOPNOTSUPP;
 
-       if (cmd == SET_KEY)
-               cipher_mask |= BIT(cipher);
-       else
-               cipher_mask &= ~BIT(cipher);
-
-       mt7615_mac_wtbl_update_cipher(dev, wcid, cipher, cipher_mask, cmd);
-       err = mt7615_mac_wtbl_update_key(dev, wcid, key, cipher, cipher_mask,
-                                        cmd);
+       cipher_mask |= BIT(cipher);
+       mt7615_mac_wtbl_update_cipher(dev, wcid, cipher, cipher_mask);
+       err = mt7615_mac_wtbl_update_key(dev, wcid, key, cipher, cipher_mask);
        if (err < 0)
                return err;
 
        err = mt7615_mac_wtbl_update_pk(dev, wcid, cipher, cipher_mask,
-                                       key->keyidx, cmd);
+                                       key->keyidx);
        if (err < 0)
                return err;
 
@@ -1329,13 +1302,12 @@ int __mt7615_mac_wtbl_set_key(struct mt7615_dev *dev,
 
 int mt7615_mac_wtbl_set_key(struct mt7615_dev *dev,
                            struct mt76_wcid *wcid,
-                           struct ieee80211_key_conf *key,
-                           enum set_key_cmd cmd)
+                           struct ieee80211_key_conf *key)
 {
        int err;
 
        spin_lock_bh(&dev->mt76.lock);
-       err = __mt7615_mac_wtbl_set_key(dev, wcid, key, cmd);
+       err = __mt7615_mac_wtbl_set_key(dev, wcid, key);
        spin_unlock_bh(&dev->mt76.lock);
 
        return err;
index ab4c1b4478aa99df2b82ea4980af4f7d1a500674..dadb13f2ca09568b7f706661146b3b90a2e1cbce 100644 (file)
@@ -391,18 +391,17 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
        if (cmd == SET_KEY)
                *wcid_keyidx = idx;
-       else if (idx == *wcid_keyidx)
-               *wcid_keyidx = -1;
-       else
+       else {
+               if (idx == *wcid_keyidx)
+                       *wcid_keyidx = -1;
                goto out;
+       }
 
-       mt76_wcid_key_setup(&dev->mt76, wcid,
-                           cmd == SET_KEY ? key : NULL);
-
+       mt76_wcid_key_setup(&dev->mt76, wcid, key);
        if (mt76_is_mmio(&dev->mt76))
-               err = mt7615_mac_wtbl_set_key(dev, wcid, key, cmd);
+               err = mt7615_mac_wtbl_set_key(dev, wcid, key);
        else
-               err = __mt7615_mac_wtbl_set_key(dev, wcid, key, cmd);
+               err = __mt7615_mac_wtbl_set_key(dev, wcid, key);
 
 out:
        mt7615_mutex_release(dev);
index 43591b4c1d9afc38d516b62862a0995c9bc99a5e..9e58f6924493f6c3db605122b7c9aa8ef189c80c 100644 (file)
@@ -490,11 +490,9 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
 void mt7615_mac_set_timing(struct mt7615_phy *phy);
 int __mt7615_mac_wtbl_set_key(struct mt7615_dev *dev,
                              struct mt76_wcid *wcid,
-                             struct ieee80211_key_conf *key,
-                             enum set_key_cmd cmd);
+                             struct ieee80211_key_conf *key);
 int mt7615_mac_wtbl_set_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
-                           struct ieee80211_key_conf *key,
-                           enum set_key_cmd cmd);
+                           struct ieee80211_key_conf *key);
 void mt7615_mac_reset_work(struct work_struct *work);
 u32 mt7615_mac_get_sta_tid_sn(struct mt7615_dev *dev, int wcid, u8 tid);
 
index efb9bfaa187f295441f01ddf67ddcdf6eb314b62..008ece1b16f8ebc9b5c122c82723847aaac79ba7 100644 (file)
@@ -1221,6 +1221,9 @@ EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba_tlv);
 
 int mt76_connac_mcu_sta_wed_update(struct mt76_dev *dev, struct sk_buff *skb)
 {
+       if (!mt76_is_mmio(dev))
+               return 0;
+
        if (!mtk_wed_device_active(&dev->mmio.wed))
                return 0;
 
index 7451a63206a5f73da99b2c251b1d29c10e2677d1..dcbb5c605dfe69b450d8bae760e806b48142e9a1 100644 (file)
@@ -454,20 +454,20 @@ int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        msta = sta ? (struct mt76x02_sta *)sta->drv_priv : NULL;
        wcid = msta ? &msta->wcid : &mvif->group_wcid;
 
-       if (cmd == SET_KEY) {
-               key->hw_key_idx = wcid->idx;
-               wcid->hw_key_idx = idx;
-               if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) {
-                       key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
-                       wcid->sw_iv = true;
-               }
-       } else {
+       if (cmd != SET_KEY) {
                if (idx == wcid->hw_key_idx) {
                        wcid->hw_key_idx = -1;
                        wcid->sw_iv = false;
                }
 
-               key = NULL;
+               return 0;
+       }
+
+       key->hw_key_idx = wcid->idx;
+       wcid->hw_key_idx = idx;
+       if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) {
+               key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
+               wcid->sw_iv = true;
        }
        mt76_wcid_key_setup(&dev->mt76, wcid, key);
 
index 1ab768feccaac0f9511351d090e131d12e9d83b3..5e288116b1b010805269076eceaf8a7f82a2b4e9 100644 (file)
@@ -383,7 +383,6 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
        ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD);
        ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);
        ieee80211_hw_set(hw, WANT_MONITOR_VIF);
-       ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
 
        hw->max_tx_fragments = 4;
 
@@ -396,6 +395,9 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
        }
 
        if (phy->mt76->cap.has_5ghz) {
+               struct ieee80211_sta_vht_cap *vht_cap;
+
+               vht_cap = &phy->mt76->sband_5g.sband.vht_cap;
                phy->mt76->sband_5g.sband.ht_cap.cap |=
                        IEEE80211_HT_CAP_LDPC_CODING |
                        IEEE80211_HT_CAP_MAX_AMSDU;
@@ -403,19 +405,28 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
                        IEEE80211_HT_MPDU_DENSITY_4;
 
                if (is_mt7915(&dev->mt76)) {
-                       phy->mt76->sband_5g.sband.vht_cap.cap |=
+                       vht_cap->cap |=
                                IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 |
                                IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
+
+                       if (!dev->dbdc_support)
+                               vht_cap->cap |=
+                                       IEEE80211_VHT_CAP_SHORT_GI_160 |
+                                       IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
+                                       FIELD_PREP(IEEE80211_VHT_CAP_EXT_NSS_BW_MASK, 1);
                } else {
-                       phy->mt76->sband_5g.sband.vht_cap.cap |=
+                       vht_cap->cap |=
                                IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
                                IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
 
                        /* mt7916 dbdc with 2g 2x2 bw40 and 5g 2x2 bw160c */
-                       phy->mt76->sband_5g.sband.vht_cap.cap |=
+                       vht_cap->cap |=
                                IEEE80211_VHT_CAP_SHORT_GI_160 |
                                IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
                }
+
+               if (!is_mt7915(&dev->mt76) || !dev->dbdc_support)
+                       ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
        }
 
        mt76_set_stream_caps(phy->mt76, true);
@@ -841,9 +852,13 @@ mt7915_set_stream_he_txbf_caps(struct mt7915_phy *phy,
        int sts = hweight8(phy->mt76->chainmask);
        u8 c, sts_160 = sts;
 
-       /* mt7915 doesn't support bw160 */
-       if (is_mt7915(&dev->mt76))
-               sts_160 = 0;
+       /* Can do 1/2 of STS in 160Mhz mode for mt7915 */
+       if (is_mt7915(&dev->mt76)) {
+               if (!dev->dbdc_support)
+                       sts_160 /= 2;
+               else
+                       sts_160 = 0;
+       }
 
 #ifdef CONFIG_MAC80211_MESH
        if (vif == NL80211_IFTYPE_MESH_POINT)
@@ -944,10 +959,15 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
        int i, idx = 0, nss = hweight8(phy->mt76->antenna_mask);
        u16 mcs_map = 0;
        u16 mcs_map_160 = 0;
-       u8 nss_160 = nss;
+       u8 nss_160;
 
-       /* Can't do 160MHz with mt7915 */
-       if (is_mt7915(&dev->mt76))
+       if (!is_mt7915(&dev->mt76))
+               nss_160 = nss;
+       else if (!dev->dbdc_support)
+               /* Can do 1/2 of NSS streams in 160Mhz mode for mt7915 */
+               nss_160 = nss / 2;
+       else
+               /* Can't do 160MHz with mt7915 dbdc */
                nss_160 = 0;
 
        for (i = 0; i < 8; i++) {
index 3bbccbdfc5eb0ad5ee2f6c70959391bbfb085a38..784191ec48029150abd23912d4c166e8efbfc4d2 100644 (file)
@@ -410,16 +410,15 @@ static int mt7915_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                mt7915_mcu_add_bss_info(phy, vif, true);
        }
 
-       if (cmd == SET_KEY)
+       if (cmd == SET_KEY) {
                *wcid_keyidx = idx;
-       else if (idx == *wcid_keyidx)
-               *wcid_keyidx = -1;
-       else
+       } else {
+               if (idx == *wcid_keyidx)
+                       *wcid_keyidx = -1;
                goto out;
+       }
 
-       mt76_wcid_key_setup(&dev->mt76, wcid,
-                           cmd == SET_KEY ? key : NULL);
-
+       mt76_wcid_key_setup(&dev->mt76, wcid, key);
        err = mt76_connac_mcu_add_key(&dev->mt76, vif, &msta->bip,
                                      key, MCU_EXT_CMD(STA_REC_UPDATE),
                                      &msta->wcid, cmd);
index 80c71acfe1591cc0afd898c1e08fbd6e4b4cdeb9..cc94531185dac2b7a1fef4b333b469bb8e46c5c0 100644 (file)
@@ -171,12 +171,12 @@ mt7921_mac_init_band(struct mt7921_dev *dev, u8 band)
 
 u8 mt7921_check_offload_capability(struct device *dev, const char *fw_wm)
 {
-       struct mt7921_fw_features *features = NULL;
        const struct mt76_connac2_fw_trailer *hdr;
        struct mt7921_realease_info *rel_info;
        const struct firmware *fw;
        int ret, i, offset = 0;
        const u8 *data, *end;
+       u8 offload_caps = 0;
 
        ret = request_firmware(&fw, fw_wm, dev);
        if (ret)
@@ -208,7 +208,10 @@ u8 mt7921_check_offload_capability(struct device *dev, const char *fw_wm)
                data += sizeof(*rel_info);
 
                if (rel_info->tag == MT7921_FW_TAG_FEATURE) {
+                       struct mt7921_fw_features *features;
+
                        features = (struct mt7921_fw_features *)data;
+                       offload_caps = features->data;
                        break;
                }
 
@@ -218,7 +221,7 @@ u8 mt7921_check_offload_capability(struct device *dev, const char *fw_wm)
 out:
        release_firmware(fw);
 
-       return features ? features->data : 0;
+       return offload_caps;
 }
 EXPORT_SYMBOL_GPL(mt7921_check_offload_capability);
 
index 75eaf86c6a78e9ab287e4bbb3c73d9c0f8485522..42933a6b7334b391cf32dc873abbd08ef23742e0 100644 (file)
@@ -569,16 +569,15 @@ static int mt7921_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
        mt7921_mutex_acquire(dev);
 
-       if (cmd == SET_KEY)
+       if (cmd == SET_KEY) {
                *wcid_keyidx = idx;
-       else if (idx == *wcid_keyidx)
-               *wcid_keyidx = -1;
-       else
+       } else {
+               if (idx == *wcid_keyidx)
+                       *wcid_keyidx = -1;
                goto out;
+       }
 
-       mt76_wcid_key_setup(&dev->mt76, wcid,
-                           cmd == SET_KEY ? key : NULL);
-
+       mt76_wcid_key_setup(&dev->mt76, wcid, key);
        err = mt76_connac_mcu_add_key(&dev->mt76, vif, &msta->bip,
                                      key, MCU_UNI_CMD(STA_REC_UPDATE),
                                      &msta->wcid, cmd);
index cb72ded372564ea5bf52bea2f66e80cab767fe9a..5c23c827abe476df6f5f7f5b53aeeeb4af5313e5 100644 (file)
@@ -20,7 +20,7 @@ static const struct pci_device_id mt7921_pci_device_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x0608),
                .driver_data = (kernel_ulong_t)MT7921_FIRMWARE_WM },
        { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x0616),
-               .driver_data = (kernel_ulong_t)MT7921_FIRMWARE_WM },
+               .driver_data = (kernel_ulong_t)MT7922_FIRMWARE_WM },
        { },
 };
 
index 3e4da0350d965b282e3b722c1019f519479a0231..1ba22d147949bc9d995676c8602f1e465cd7ad99 100644 (file)
@@ -351,16 +351,15 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                mt7996_mcu_add_bss_info(phy, vif, true);
        }
 
-       if (cmd == SET_KEY)
+       if (cmd == SET_KEY) {
                *wcid_keyidx = idx;
-       else if (idx == *wcid_keyidx)
-               *wcid_keyidx = -1;
-       else
+       } else {
+               if (idx == *wcid_keyidx)
+                       *wcid_keyidx = -1;
                goto out;
+       }
 
-       mt76_wcid_key_setup(&dev->mt76, wcid,
-                           cmd == SET_KEY ? key : NULL);
-
+       mt76_wcid_key_setup(&dev->mt76, wcid, key);
        err = mt7996_mcu_add_key(&dev->mt76, vif, &msta->bip,
                                 key, MCU_WMWA_UNI_CMD(STA_REC_UPDATE),
                                 &msta->wcid, cmd);
index 2d2edddc77bdd146027b8ccaa73d3ff52b9a0b6c..3f88e6a0a510ed14f84a0d7a1e0147509293e262 100644 (file)
@@ -447,8 +447,7 @@ static int wlcore_probe_of(struct spi_device *spi, struct wl12xx_spi_glue *glue,
        dev_info(&spi->dev, "selected chip family is %s\n",
                 pdev_data->family->name);
 
-       if (of_find_property(dt_node, "clock-xtal", NULL))
-               pdev_data->ref_clock_xtal = true;
+       pdev_data->ref_clock_xtal = of_property_read_bool(dt_node, "clock-xtal");
 
        /* optional clock frequency params */
        of_property_read_u32(dt_node, "ref-clock-frequency",
index 1e6a47976642907ef9d2e606f4d07a485146ab55..c066b0040a3fe5fb6668bd35d45694495dc1647a 100644 (file)
@@ -587,6 +587,13 @@ static void ipc_imem_run_state_worker(struct work_struct *instance)
        while (ctrl_chl_idx < IPC_MEM_MAX_CHANNELS) {
                if (!ipc_chnl_cfg_get(&chnl_cfg_port, ctrl_chl_idx)) {
                        ipc_imem->ipc_port[ctrl_chl_idx] = NULL;
+
+                       if (ipc_imem->pcie->pci->device == INTEL_CP_DEVICE_7560_ID &&
+                           chnl_cfg_port.wwan_port_type == WWAN_PORT_XMMRPC) {
+                               ctrl_chl_idx++;
+                               continue;
+                       }
+
                        if (ipc_imem->pcie->pci->device == INTEL_CP_DEVICE_7360_ID &&
                            chnl_cfg_port.wwan_port_type == WWAN_PORT_MBIM) {
                                ctrl_chl_idx++;
index 5bf5a93937c9c4dd898d41407f26606742735a3a..04517bd3325a2abb3871f640aab0666d53467352 100644 (file)
@@ -295,7 +295,7 @@ static int ipc_pcie_probe(struct pci_dev *pci,
        ret = dma_set_mask(ipc_pcie->dev, DMA_BIT_MASK(64));
        if (ret) {
                dev_err(ipc_pcie->dev, "Could not set PCI DMA mask: %d", ret);
-               return ret;
+               goto set_mask_fail;
        }
 
        ipc_pcie_config_aspm(ipc_pcie);
@@ -323,6 +323,7 @@ static int ipc_pcie_probe(struct pci_dev *pci,
 imem_init_fail:
        ipc_pcie_resources_release(ipc_pcie);
 resources_req_fail:
+set_mask_fail:
        pci_disable_device(pci);
 pci_enable_fail:
        kfree(ipc_pcie);
index 268ff9e87e5b3069af67858dd762283d1199c8a1..2652cd00504e6eb943d4b13191dcfed21030565e 100644 (file)
@@ -1,7 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-ccflags-y += -Werror
-
 obj-${CONFIG_MTK_T7XX} := mtk_t7xx.o
 mtk_t7xx-y:=   t7xx_pci.o \
                t7xx_pcie_mac.o \
index 3dbfc8a6924ed33bb1700293d56fb11914bdc043..1fcbd83f7ff2e3e46e0c230da0ea60f0665e7e78 100644 (file)
@@ -166,7 +166,7 @@ struct xenvif_queue { /* Per-queue data for xenvif */
        struct pending_tx_info pending_tx_info[MAX_PENDING_REQS];
        grant_handle_t grant_tx_handle[MAX_PENDING_REQS];
 
-       struct gnttab_copy tx_copy_ops[MAX_PENDING_REQS];
+       struct gnttab_copy tx_copy_ops[2 * MAX_PENDING_REQS];
        struct gnttab_map_grant_ref tx_map_ops[MAX_PENDING_REQS];
        struct gnttab_unmap_grant_ref tx_unmap_ops[MAX_PENDING_REQS];
        /* passed to gnttab_[un]map_refs with pages under (un)mapping */
index 1b42676ca1418d274ee3a1c0ed805814659f6e72..c1501f41e2d825be75cf9b71a38cf1ecc64a2c6c 100644 (file)
@@ -334,6 +334,7 @@ static int xenvif_count_requests(struct xenvif_queue *queue,
 struct xenvif_tx_cb {
        u16 copy_pending_idx[XEN_NETBK_LEGACY_SLOTS_MAX + 1];
        u8 copy_count;
+       u32 split_mask;
 };
 
 #define XENVIF_TX_CB(skb) ((struct xenvif_tx_cb *)(skb)->cb)
@@ -361,6 +362,8 @@ static inline struct sk_buff *xenvif_alloc_skb(unsigned int size)
        struct sk_buff *skb =
                alloc_skb(size + NET_SKB_PAD + NET_IP_ALIGN,
                          GFP_ATOMIC | __GFP_NOWARN);
+
+       BUILD_BUG_ON(sizeof(*XENVIF_TX_CB(skb)) > sizeof(skb->cb));
        if (unlikely(skb == NULL))
                return NULL;
 
@@ -396,11 +399,13 @@ static void xenvif_get_requests(struct xenvif_queue *queue,
        nr_slots = shinfo->nr_frags + 1;
 
        copy_count(skb) = 0;
+       XENVIF_TX_CB(skb)->split_mask = 0;
 
        /* Create copy ops for exactly data_len bytes into the skb head. */
        __skb_put(skb, data_len);
        while (data_len > 0) {
                int amount = data_len > txp->size ? txp->size : data_len;
+               bool split = false;
 
                cop->source.u.ref = txp->gref;
                cop->source.domid = queue->vif->domid;
@@ -413,6 +418,13 @@ static void xenvif_get_requests(struct xenvif_queue *queue,
                cop->dest.u.gmfn = virt_to_gfn(skb->data + skb_headlen(skb)
                                               - data_len);
 
+               /* Don't cross local page boundary! */
+               if (cop->dest.offset + amount > XEN_PAGE_SIZE) {
+                       amount = XEN_PAGE_SIZE - cop->dest.offset;
+                       XENVIF_TX_CB(skb)->split_mask |= 1U << copy_count(skb);
+                       split = true;
+               }
+
                cop->len = amount;
                cop->flags = GNTCOPY_source_gref;
 
@@ -420,7 +432,8 @@ static void xenvif_get_requests(struct xenvif_queue *queue,
                pending_idx = queue->pending_ring[index];
                callback_param(queue, pending_idx).ctx = NULL;
                copy_pending_idx(skb, copy_count(skb)) = pending_idx;
-               copy_count(skb)++;
+               if (!split)
+                       copy_count(skb)++;
 
                cop++;
                data_len -= amount;
@@ -441,7 +454,8 @@ static void xenvif_get_requests(struct xenvif_queue *queue,
                        nr_slots--;
                } else {
                        /* The copy op partially covered the tx_request.
-                        * The remainder will be mapped.
+                        * The remainder will be mapped or copied in the next
+                        * iteration.
                         */
                        txp->offset += amount;
                        txp->size -= amount;
@@ -539,6 +553,13 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
                pending_idx = copy_pending_idx(skb, i);
 
                newerr = (*gopp_copy)->status;
+
+               /* Split copies need to be handled together. */
+               if (XENVIF_TX_CB(skb)->split_mask & (1U << i)) {
+                       (*gopp_copy)++;
+                       if (!newerr)
+                               newerr = (*gopp_copy)->status;
+               }
                if (likely(!newerr)) {
                        /* The first frag might still have this slot mapped */
                        if (i < copy_count(skb) - 1 || !sharedslot)
@@ -973,10 +994,8 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
 
                /* No crossing a page as the payload mustn't fragment. */
                if (unlikely((txreq.offset + txreq.size) > XEN_PAGE_SIZE)) {
-                       netdev_err(queue->vif->dev,
-                                  "txreq.offset: %u, size: %u, end: %lu\n",
-                                  txreq.offset, txreq.size,
-                                  (unsigned long)(txreq.offset&~XEN_PAGE_MASK) + txreq.size);
+                       netdev_err(queue->vif->dev, "Cross page boundary, txreq.offset: %u, size: %u\n",
+                                  txreq.offset, txreq.size);
                        xenvif_fatal_tx_err(queue->vif);
                        break;
                }
@@ -1061,10 +1080,6 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
                __skb_queue_tail(&queue->tx_queue, skb);
 
                queue->tx.req_cons = idx;
-
-               if ((*map_ops >= ARRAY_SIZE(queue->tx_map_ops)) ||
-                   (*copy_ops >= ARRAY_SIZE(queue->tx_copy_ops)))
-                       break;
        }
 
        return;
index 2d53e0f88d2f95a6cf0f781285ba499279f9f33c..1e0f2297f9c665820aabb2093ebd3c71fc8325aa 100644 (file)
@@ -247,6 +247,9 @@ static void fdp_nci_i2c_read_device_properties(struct device *dev,
                                           len, sizeof(**fw_vsc_cfg),
                                           GFP_KERNEL);
 
+               if (!*fw_vsc_cfg)
+                       goto alloc_err;
+
                r = device_property_read_u8_array(dev, FDP_DP_FW_VSC_CFG_NAME,
                                                  *fw_vsc_cfg, len);
 
@@ -260,6 +263,7 @@ vsc_read_err:
                *fw_vsc_cfg = NULL;
        }
 
+alloc_err:
        dev_dbg(dev, "Clock type: %d, clock frequency: %d, VSC: %s",
                *clock_type, *clock_freq, *fw_vsc_cfg != NULL ? "yes" : "no");
 }
index ed9c5e2cf3ad43feaa590820202ec844ee96ed6c..a187f0e0b0f7d1799f3f8d8d6ad36a801b7ca756 100644 (file)
@@ -175,6 +175,7 @@ static int pn533_usb_send_frame(struct pn533 *dev,
        print_hex_dump_debug("PN533 TX: ", DUMP_PREFIX_NONE, 16, 1,
                             out->data, out->len, false);
 
+       arg.phy = phy;
        init_completion(&arg.done);
        cntx = phy->out_urb->context;
        phy->out_urb->context = &arg;
index 755460a73c0dce184dbe1dbd42c93993b2b3aecd..d2aa9f766738ecfe898f19733f89cd459b5124aa 100644 (file)
@@ -282,13 +282,15 @@ EXPORT_SYMBOL(ndlc_probe);
 
 void ndlc_remove(struct llt_ndlc *ndlc)
 {
-       st_nci_remove(ndlc->ndev);
-
        /* cancel timers */
        del_timer_sync(&ndlc->t1_timer);
        del_timer_sync(&ndlc->t2_timer);
        ndlc->t2_active = false;
        ndlc->t1_active = false;
+       /* cancel work */
+       cancel_work_sync(&ndlc->sm_work);
+
+       st_nci_remove(ndlc->ndev);
 
        skb_queue_purge(&ndlc->rcv_q);
        skb_queue_purge(&ndlc->send_q);
index c2730b116dc680eac04df43a81c81a3826c5da16..d6a9bac91a4cda9a67d17935c0fd91c88f3119be 100644 (file)
@@ -781,16 +781,26 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req,
                range = page_address(ns->ctrl->discard_page);
        }
 
-       __rq_for_each_bio(bio, req) {
-               u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector);
-               u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift;
-
-               if (n < segments) {
-                       range[n].cattr = cpu_to_le32(0);
-                       range[n].nlb = cpu_to_le32(nlb);
-                       range[n].slba = cpu_to_le64(slba);
+       if (queue_max_discard_segments(req->q) == 1) {
+               u64 slba = nvme_sect_to_lba(ns, blk_rq_pos(req));
+               u32 nlb = blk_rq_sectors(req) >> (ns->lba_shift - 9);
+
+               range[0].cattr = cpu_to_le32(0);
+               range[0].nlb = cpu_to_le32(nlb);
+               range[0].slba = cpu_to_le64(slba);
+               n = 1;
+       } else {
+               __rq_for_each_bio(bio, req) {
+                       u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector);
+                       u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift;
+
+                       if (n < segments) {
+                               range[n].cattr = cpu_to_le32(0);
+                               range[n].nlb = cpu_to_le32(nlb);
+                               range[n].slba = cpu_to_le64(slba);
+                       }
+                       n++;
                }
-               n++;
        }
 
        if (WARN_ON_ONCE(n != segments)) {
@@ -1664,6 +1674,9 @@ static void nvme_config_discard(struct gendisk *disk, struct nvme_ns *ns)
        struct request_queue *queue = disk->queue;
        u32 size = queue_logical_block_size(queue);
 
+       if (ctrl->dmrsl && ctrl->dmrsl <= nvme_sect_to_lba(ns, UINT_MAX))
+               ctrl->max_discard_sectors = nvme_lba_to_sect(ns, ctrl->dmrsl);
+
        if (ctrl->max_discard_sectors == 0) {
                blk_queue_max_discard_sectors(queue, 0);
                return;
@@ -1678,9 +1691,6 @@ static void nvme_config_discard(struct gendisk *disk, struct nvme_ns *ns)
        if (queue->limits.max_discard_sectors)
                return;
 
-       if (ctrl->dmrsl && ctrl->dmrsl <= nvme_sect_to_lba(ns, UINT_MAX))
-               ctrl->max_discard_sectors = nvme_lba_to_sect(ns, ctrl->dmrsl);
-
        blk_queue_max_discard_sectors(queue, ctrl->max_discard_sectors);
        blk_queue_max_discard_segments(queue, ctrl->max_discard_segments);
 
@@ -3053,7 +3063,8 @@ static int nvme_init_non_mdts_limits(struct nvme_ctrl *ctrl)
        else
                ctrl->max_zeroes_sectors = 0;
 
-       if (nvme_ctrl_limited_cns(ctrl))
+       if (ctrl->subsys->subtype != NVME_NQN_NVME ||
+           nvme_ctrl_limited_cns(ctrl))
                return 0;
 
        id = kzalloc(sizeof(*id), GFP_KERNEL);
index 723e7d5b778f2c68aa3eb79decba51c8f2223f90..d24ea2e051564670254c44152de5660b32048a86 100644 (file)
@@ -464,7 +464,8 @@ static inline struct nvme_uring_cmd_pdu *nvme_uring_cmd_pdu(
        return (struct nvme_uring_cmd_pdu *)&ioucmd->pdu;
 }
 
-static void nvme_uring_task_meta_cb(struct io_uring_cmd *ioucmd)
+static void nvme_uring_task_meta_cb(struct io_uring_cmd *ioucmd,
+                                   unsigned issue_flags)
 {
        struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd);
        struct request *req = pdu->req;
@@ -485,17 +486,18 @@ static void nvme_uring_task_meta_cb(struct io_uring_cmd *ioucmd)
                blk_rq_unmap_user(req->bio);
        blk_mq_free_request(req);
 
-       io_uring_cmd_done(ioucmd, status, result);
+       io_uring_cmd_done(ioucmd, status, result, issue_flags);
 }
 
-static void nvme_uring_task_cb(struct io_uring_cmd *ioucmd)
+static void nvme_uring_task_cb(struct io_uring_cmd *ioucmd,
+                              unsigned issue_flags)
 {
        struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd);
 
        if (pdu->bio)
                blk_rq_unmap_user(pdu->bio);
 
-       io_uring_cmd_done(ioucmd, pdu->nvme_status, pdu->u.result);
+       io_uring_cmd_done(ioucmd, pdu->nvme_status, pdu->u.result, issue_flags);
 }
 
 static enum rq_end_io_ret nvme_uring_cmd_end_io(struct request *req,
@@ -517,7 +519,7 @@ static enum rq_end_io_ret nvme_uring_cmd_end_io(struct request *req,
         * Otherwise, move the completion to task work.
         */
        if (cookie != NULL && blk_rq_is_poll(req))
-               nvme_uring_task_cb(ioucmd);
+               nvme_uring_task_cb(ioucmd, IO_URING_F_UNLOCKED);
        else
                io_uring_cmd_complete_in_task(ioucmd, nvme_uring_task_cb);
 
@@ -539,7 +541,7 @@ static enum rq_end_io_ret nvme_uring_cmd_end_io_meta(struct request *req,
         * Otherwise, move the completion to task work.
         */
        if (cookie != NULL && blk_rq_is_poll(req))
-               nvme_uring_task_meta_cb(ioucmd);
+               nvme_uring_task_meta_cb(ioucmd, IO_URING_F_UNLOCKED);
        else
                io_uring_cmd_complete_in_task(ioucmd, nvme_uring_task_meta_cb);
 
index fc39d01e7b63be8a4f9e794f915715cbc2c8609b..9171452e2f6d4e2eed95d0c6ef9ec0cbf05bc7ef 100644 (file)
@@ -123,9 +123,8 @@ void nvme_mpath_start_request(struct request *rq)
                return;
 
        nvme_req(rq)->flags |= NVME_MPATH_IO_STATS;
-       nvme_req(rq)->start_time = bdev_start_io_acct(disk->part0,
-                                       blk_rq_bytes(rq) >> SECTOR_SHIFT,
-                                       req_op(rq), jiffies);
+       nvme_req(rq)->start_time = bdev_start_io_acct(disk->part0, req_op(rq),
+                                                     jiffies);
 }
 EXPORT_SYMBOL_GPL(nvme_mpath_start_request);
 
@@ -136,7 +135,8 @@ void nvme_mpath_end_request(struct request *rq)
        if (!(nvme_req(rq)->flags & NVME_MPATH_IO_STATS))
                return;
        bdev_end_io_acct(ns->head->disk->part0, req_op(rq),
-               nvme_req(rq)->start_time);
+                        blk_rq_bytes(rq) >> SECTOR_SHIFT,
+                        nvme_req(rq)->start_time);
 }
 
 void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl)
index 5b95c94ee40f209e8d1cef39ee65da67a0b1736a..cd7873de312154696079e390e83439983bc0762e 100644 (file)
@@ -3073,6 +3073,7 @@ out_dev_unmap:
        nvme_dev_unmap(dev);
 out_uninit_ctrl:
        nvme_uninit_ctrl(&dev->ctrl);
+       nvme_put_ctrl(&dev->ctrl);
        return result;
 }
 
@@ -3415,6 +3416,8 @@ static const struct pci_device_id nvme_id_table[] = {
                .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
        { PCI_DEVICE(0x2646, 0x501E),   /* KINGSTON OM3PGP4xxxxQ OS21011 NVMe SSD */
                .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
+       { PCI_DEVICE(0x1f40, 0x1202),   /* Netac Technologies Co. NV3000 NVMe SSD */
+               .driver_data = NVME_QUIRK_BOGUS_NID, },
        { PCI_DEVICE(0x1f40, 0x5236),   /* Netac Technologies Co. NV7000 NVMe SSD */
                .driver_data = NVME_QUIRK_BOGUS_NID, },
        { PCI_DEVICE(0x1e4B, 0x1001),   /* MAXIO MAP1001 */
@@ -3435,7 +3438,12 @@ static const struct pci_device_id nvme_id_table[] = {
                .driver_data = NVME_QUIRK_BOGUS_NID, },
        { PCI_DEVICE(0x1d97, 0x2263), /* Lexar NM610 */
                .driver_data = NVME_QUIRK_BOGUS_NID, },
+       { PCI_DEVICE(0x1d97, 0x1d97), /* Lexar NM620 */
+               .driver_data = NVME_QUIRK_BOGUS_NID, },
        { PCI_DEVICE(0x1d97, 0x2269), /* Lexar NM760 */
+               .driver_data = NVME_QUIRK_BOGUS_NID |
+                               NVME_QUIRK_IGNORE_DEV_SUBNQN, },
+       { PCI_DEVICE(0x10ec, 0x5763), /* TEAMGROUP T-FORCE CARDEA ZERO Z330 SSD */
                .driver_data = NVME_QUIRK_BOGUS_NID, },
        { PCI_DEVICE(PCI_VENDOR_ID_AMAZON, 0x0061),
                .driver_data = NVME_QUIRK_DMA_ADDRESS_BITS_48, },
index 7723a498952442c14c5346a5e30fd1383aa0940e..49c9e7bc9116be5651e50336c91e331fdf643aa1 100644 (file)
@@ -208,6 +208,18 @@ static inline u8 nvme_tcp_ddgst_len(struct nvme_tcp_queue *queue)
        return queue->data_digest ? NVME_TCP_DIGEST_LENGTH : 0;
 }
 
+static inline void *nvme_tcp_req_cmd_pdu(struct nvme_tcp_request *req)
+{
+       return req->pdu;
+}
+
+static inline void *nvme_tcp_req_data_pdu(struct nvme_tcp_request *req)
+{
+       /* use the pdu space in the back for the data pdu */
+       return req->pdu + sizeof(struct nvme_tcp_cmd_pdu) -
+               sizeof(struct nvme_tcp_data_pdu);
+}
+
 static inline size_t nvme_tcp_inline_data_size(struct nvme_tcp_request *req)
 {
        if (nvme_is_fabrics(req->req.cmd))
@@ -614,7 +626,7 @@ static int nvme_tcp_handle_comp(struct nvme_tcp_queue *queue,
 
 static void nvme_tcp_setup_h2c_data_pdu(struct nvme_tcp_request *req)
 {
-       struct nvme_tcp_data_pdu *data = req->pdu;
+       struct nvme_tcp_data_pdu *data = nvme_tcp_req_data_pdu(req);
        struct nvme_tcp_queue *queue = req->queue;
        struct request *rq = blk_mq_rq_from_pdu(req);
        u32 h2cdata_sent = req->pdu_len;
@@ -1038,7 +1050,7 @@ static int nvme_tcp_try_send_data(struct nvme_tcp_request *req)
 static int nvme_tcp_try_send_cmd_pdu(struct nvme_tcp_request *req)
 {
        struct nvme_tcp_queue *queue = req->queue;
-       struct nvme_tcp_cmd_pdu *pdu = req->pdu;
+       struct nvme_tcp_cmd_pdu *pdu = nvme_tcp_req_cmd_pdu(req);
        bool inline_data = nvme_tcp_has_inline_data(req);
        u8 hdgst = nvme_tcp_hdgst_len(queue);
        int len = sizeof(*pdu) + hdgst - req->offset;
@@ -1077,7 +1089,7 @@ static int nvme_tcp_try_send_cmd_pdu(struct nvme_tcp_request *req)
 static int nvme_tcp_try_send_data_pdu(struct nvme_tcp_request *req)
 {
        struct nvme_tcp_queue *queue = req->queue;
-       struct nvme_tcp_data_pdu *pdu = req->pdu;
+       struct nvme_tcp_data_pdu *pdu = nvme_tcp_req_data_pdu(req);
        u8 hdgst = nvme_tcp_hdgst_len(queue);
        int len = sizeof(*pdu) - req->offset + hdgst;
        int ret;
@@ -1608,22 +1620,7 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl, int qid)
        if (ret)
                goto err_init_connect;
 
-       queue->rd_enabled = true;
        set_bit(NVME_TCP_Q_ALLOCATED, &queue->flags);
-       nvme_tcp_init_recv_ctx(queue);
-
-       write_lock_bh(&queue->sock->sk->sk_callback_lock);
-       queue->sock->sk->sk_user_data = queue;
-       queue->state_change = queue->sock->sk->sk_state_change;
-       queue->data_ready = queue->sock->sk->sk_data_ready;
-       queue->write_space = queue->sock->sk->sk_write_space;
-       queue->sock->sk->sk_data_ready = nvme_tcp_data_ready;
-       queue->sock->sk->sk_state_change = nvme_tcp_state_change;
-       queue->sock->sk->sk_write_space = nvme_tcp_write_space;
-#ifdef CONFIG_NET_RX_BUSY_POLL
-       queue->sock->sk->sk_ll_usec = 1;
-#endif
-       write_unlock_bh(&queue->sock->sk->sk_callback_lock);
 
        return 0;
 
@@ -1643,7 +1640,7 @@ err_destroy_mutex:
        return ret;
 }
 
-static void nvme_tcp_restore_sock_calls(struct nvme_tcp_queue *queue)
+static void nvme_tcp_restore_sock_ops(struct nvme_tcp_queue *queue)
 {
        struct socket *sock = queue->sock;
 
@@ -1658,7 +1655,7 @@ static void nvme_tcp_restore_sock_calls(struct nvme_tcp_queue *queue)
 static void __nvme_tcp_stop_queue(struct nvme_tcp_queue *queue)
 {
        kernel_sock_shutdown(queue->sock, SHUT_RDWR);
-       nvme_tcp_restore_sock_calls(queue);
+       nvme_tcp_restore_sock_ops(queue);
        cancel_work_sync(&queue->io_work);
 }
 
@@ -1676,21 +1673,42 @@ static void nvme_tcp_stop_queue(struct nvme_ctrl *nctrl, int qid)
        mutex_unlock(&queue->queue_lock);
 }
 
+static void nvme_tcp_setup_sock_ops(struct nvme_tcp_queue *queue)
+{
+       write_lock_bh(&queue->sock->sk->sk_callback_lock);
+       queue->sock->sk->sk_user_data = queue;
+       queue->state_change = queue->sock->sk->sk_state_change;
+       queue->data_ready = queue->sock->sk->sk_data_ready;
+       queue->write_space = queue->sock->sk->sk_write_space;
+       queue->sock->sk->sk_data_ready = nvme_tcp_data_ready;
+       queue->sock->sk->sk_state_change = nvme_tcp_state_change;
+       queue->sock->sk->sk_write_space = nvme_tcp_write_space;
+#ifdef CONFIG_NET_RX_BUSY_POLL
+       queue->sock->sk->sk_ll_usec = 1;
+#endif
+       write_unlock_bh(&queue->sock->sk->sk_callback_lock);
+}
+
 static int nvme_tcp_start_queue(struct nvme_ctrl *nctrl, int idx)
 {
        struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl);
+       struct nvme_tcp_queue *queue = &ctrl->queues[idx];
        int ret;
 
+       queue->rd_enabled = true;
+       nvme_tcp_init_recv_ctx(queue);
+       nvme_tcp_setup_sock_ops(queue);
+
        if (idx)
                ret = nvmf_connect_io_queue(nctrl, idx);
        else
                ret = nvmf_connect_admin_queue(nctrl);
 
        if (!ret) {
-               set_bit(NVME_TCP_Q_LIVE, &ctrl->queues[idx].flags);
+               set_bit(NVME_TCP_Q_LIVE, &queue->flags);
        } else {
-               if (test_bit(NVME_TCP_Q_ALLOCATED, &ctrl->queues[idx].flags))
-                       __nvme_tcp_stop_queue(&ctrl->queues[idx]);
+               if (test_bit(NVME_TCP_Q_ALLOCATED, &queue->flags))
+                       __nvme_tcp_stop_queue(queue);
                dev_err(nctrl->device,
                        "failed to connect queue: %d ret=%d\n", idx, ret);
        }
@@ -2284,7 +2302,7 @@ static enum blk_eh_timer_return nvme_tcp_timeout(struct request *rq)
 {
        struct nvme_tcp_request *req = blk_mq_rq_to_pdu(rq);
        struct nvme_ctrl *ctrl = &req->queue->ctrl->ctrl;
-       struct nvme_tcp_cmd_pdu *pdu = req->pdu;
+       struct nvme_tcp_cmd_pdu *pdu = nvme_tcp_req_cmd_pdu(req);
        u8 opc = pdu->cmd.common.opcode, fctype = pdu->cmd.fabrics.fctype;
        int qid = nvme_tcp_queue_id(req->queue);
 
@@ -2323,7 +2341,7 @@ static blk_status_t nvme_tcp_map_data(struct nvme_tcp_queue *queue,
                        struct request *rq)
 {
        struct nvme_tcp_request *req = blk_mq_rq_to_pdu(rq);
-       struct nvme_tcp_cmd_pdu *pdu = req->pdu;
+       struct nvme_tcp_cmd_pdu *pdu = nvme_tcp_req_cmd_pdu(req);
        struct nvme_command *c = &pdu->cmd;
 
        c->common.flags |= NVME_CMD_SGL_METABUF;
@@ -2343,7 +2361,7 @@ static blk_status_t nvme_tcp_setup_cmd_pdu(struct nvme_ns *ns,
                struct request *rq)
 {
        struct nvme_tcp_request *req = blk_mq_rq_to_pdu(rq);
-       struct nvme_tcp_cmd_pdu *pdu = req->pdu;
+       struct nvme_tcp_cmd_pdu *pdu = nvme_tcp_req_cmd_pdu(req);
        struct nvme_tcp_queue *queue = req->queue;
        u8 hdgst = nvme_tcp_hdgst_len(queue), ddgst = 0;
        blk_status_t ret;
@@ -2682,6 +2700,15 @@ static struct nvmf_transport_ops nvme_tcp_transport = {
 
 static int __init nvme_tcp_init_module(void)
 {
+       BUILD_BUG_ON(sizeof(struct nvme_tcp_hdr) != 8);
+       BUILD_BUG_ON(sizeof(struct nvme_tcp_cmd_pdu) != 72);
+       BUILD_BUG_ON(sizeof(struct nvme_tcp_data_pdu) != 24);
+       BUILD_BUG_ON(sizeof(struct nvme_tcp_rsp_pdu) != 24);
+       BUILD_BUG_ON(sizeof(struct nvme_tcp_r2t_pdu) != 24);
+       BUILD_BUG_ON(sizeof(struct nvme_tcp_icreq_pdu) != 128);
+       BUILD_BUG_ON(sizeof(struct nvme_tcp_icresp_pdu) != 128);
+       BUILD_BUG_ON(sizeof(struct nvme_tcp_term_pdu) != 24);
+
        nvme_tcp_wq = alloc_workqueue("nvme_tcp_wq",
                        WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
        if (!nvme_tcp_wq)
index f66ed13d7c11deacbdfdd982ff8548f913f1b933..3935165048e74199cd4a9706811dd7d63fc39476 100644 (file)
@@ -756,8 +756,10 @@ static void __nvmet_req_complete(struct nvmet_req *req, u16 status)
 
 void nvmet_req_complete(struct nvmet_req *req, u16 status)
 {
+       struct nvmet_sq *sq = req->sq;
+
        __nvmet_req_complete(req, status);
-       percpu_ref_put(&req->sq->ref);
+       percpu_ref_put(&sq->ref);
 }
 EXPORT_SYMBOL_GPL(nvmet_req_complete);
 
index 174ef3574e07f5cb7e771d108deeb2e09056f971..22024b830788f86d23a213809222511c7ae6ea84 100644 (file)
@@ -1231,7 +1231,7 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, const char *id)
                                                  "#nvmem-cell-cells",
                                                  index, &cell_spec);
        if (ret)
-               return ERR_PTR(ret);
+               return ERR_PTR(-ENOENT);
 
        if (cell_spec.args_count > 1)
                return ERR_PTR(-EINVAL);
index 07d93753b12f5f4d2ccc0b6f00fa1e2aefef5bd6..e311d406b17053065b2f0699e92cda1c2e5db481 100644 (file)
@@ -226,6 +226,7 @@ static void __of_attach_node(struct device_node *np)
        np->sibling = np->parent->child;
        np->parent->child = np;
        of_node_clear_flag(np, OF_DETACHED);
+       np->fwnode.flags |= FWNODE_FLAG_NOT_DEVICE;
 }
 
 /**
index b2bd2e783445dd78e40beefb31d83bfa8c7eac6d..78ae8418744905c9b038378e78699a1aeb111a1c 100644 (file)
@@ -737,6 +737,11 @@ static int of_platform_notify(struct notifier_block *nb,
                if (of_node_check_flag(rd->dn, OF_POPULATED))
                        return NOTIFY_OK;
 
+               /*
+                * Clear the flag before adding the device so that fw_devlink
+                * doesn't skip adding consumers to this device.
+                */
+               rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
                /* pdev_parent may be NULL when no bus platform device */
                pdev_parent = of_find_device_by_node(rd->dn->parent);
                pdev = of_platform_device_create(rd->dn, NULL,
index 83ae838ceb5f0a3ea93750ea51568eb83bd91764..549c4bd5caecafd925692f308d45fa6c40a3387f 100644 (file)
@@ -76,6 +76,27 @@ struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n)
 }
 EXPORT_SYMBOL_GPL(pci_bus_resource_n);
 
+void pci_bus_remove_resource(struct pci_bus *bus, struct resource *res)
+{
+       struct pci_bus_resource *bus_res, *tmp;
+       int i;
+
+       for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) {
+               if (bus->resource[i] == res) {
+                       bus->resource[i] = NULL;
+                       return;
+               }
+       }
+
+       list_for_each_entry_safe(bus_res, tmp, &bus->resources, list) {
+               if (bus_res->res == res) {
+                       list_del(&bus_res->list);
+                       kfree(bus_res);
+                       return;
+               }
+       }
+}
+
 void pci_bus_remove_resources(struct pci_bus *bus)
 {
        int i;
index 53a16b8b6ac23ae796defd67dbacf56469acfb20..8e33e6e59e686b5d5e8462fdc737ca84ea349397 100644 (file)
@@ -1001,11 +1001,6 @@ void dw_pcie_setup(struct dw_pcie *pci)
                dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
        }
 
-       val = dw_pcie_readl_dbi(pci, PCIE_PORT_LINK_CONTROL);
-       val &= ~PORT_LINK_FAST_LINK_MODE;
-       val |= PORT_LINK_DLL_LINK_EN;
-       dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val);
-
        if (dw_pcie_cap_is(pci, CDM_CHECK)) {
                val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS);
                val |= PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS |
@@ -1013,6 +1008,11 @@ void dw_pcie_setup(struct dw_pcie *pci)
                dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, val);
        }
 
+       val = dw_pcie_readl_dbi(pci, PCIE_PORT_LINK_CONTROL);
+       val &= ~PORT_LINK_FAST_LINK_MODE;
+       val |= PORT_LINK_DLL_LINK_EN;
+       dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val);
+
        if (!pci->num_lanes) {
                dev_dbg(pci->dev, "Using h/w default number of lanes\n");
                return;
index 66d9ab2886468d02a32eb40353ad5bb24909f3ac..e5e9b287b9766e3c164bb2c2a6c1bcca72a59c96 100644 (file)
@@ -128,7 +128,7 @@ static int pci_doe_send_req(struct pci_doe_mb *doe_mb,
                return -EIO;
 
        /* Length is 2 DW of header + length of payload in DW */
-       length = 2 + task->request_pl_sz / sizeof(u32);
+       length = 2 + task->request_pl_sz / sizeof(__le32);
        if (length > PCI_DOE_MAX_LENGTH)
                return -EIO;
        if (length == PCI_DOE_MAX_LENGTH)
@@ -141,9 +141,9 @@ static int pci_doe_send_req(struct pci_doe_mb *doe_mb,
        pci_write_config_dword(pdev, offset + PCI_DOE_WRITE,
                               FIELD_PREP(PCI_DOE_DATA_OBJECT_HEADER_2_LENGTH,
                                          length));
-       for (i = 0; i < task->request_pl_sz / sizeof(u32); i++)
+       for (i = 0; i < task->request_pl_sz / sizeof(__le32); i++)
                pci_write_config_dword(pdev, offset + PCI_DOE_WRITE,
-                                      task->request_pl[i]);
+                                      le32_to_cpu(task->request_pl[i]));
 
        pci_doe_write_ctrl(doe_mb, PCI_DOE_CTRL_GO);
 
@@ -195,11 +195,11 @@ static int pci_doe_recv_resp(struct pci_doe_mb *doe_mb, struct pci_doe_task *tas
 
        /* First 2 dwords have already been read */
        length -= 2;
-       payload_length = min(length, task->response_pl_sz / sizeof(u32));
+       payload_length = min(length, task->response_pl_sz / sizeof(__le32));
        /* Read the rest of the response payload */
        for (i = 0; i < payload_length; i++) {
-               pci_read_config_dword(pdev, offset + PCI_DOE_READ,
-                                     &task->response_pl[i]);
+               pci_read_config_dword(pdev, offset + PCI_DOE_READ, &val);
+               task->response_pl[i] = cpu_to_le32(val);
                /* Prior to the last ack, ensure Data Object Ready */
                if (i == (payload_length - 1) && !pci_doe_data_obj_ready(doe_mb))
                        return -EIO;
@@ -217,13 +217,14 @@ static int pci_doe_recv_resp(struct pci_doe_mb *doe_mb, struct pci_doe_task *tas
        if (FIELD_GET(PCI_DOE_STATUS_ERROR, val))
                return -EIO;
 
-       return min(length, task->response_pl_sz / sizeof(u32)) * sizeof(u32);
+       return min(length, task->response_pl_sz / sizeof(__le32)) * sizeof(__le32);
 }
 
 static void signal_task_complete(struct pci_doe_task *task, int rv)
 {
        task->rv = rv;
        task->complete(task);
+       destroy_work_on_stack(&task->work);
 }
 
 static void signal_task_abort(struct pci_doe_task *task, int rv)
@@ -317,14 +318,16 @@ static int pci_doe_discovery(struct pci_doe_mb *doe_mb, u8 *index, u16 *vid,
 {
        u32 request_pl = FIELD_PREP(PCI_DOE_DATA_OBJECT_DISC_REQ_3_INDEX,
                                    *index);
+       __le32 request_pl_le = cpu_to_le32(request_pl);
+       __le32 response_pl_le;
        u32 response_pl;
        DECLARE_COMPLETION_ONSTACK(c);
        struct pci_doe_task task = {
                .prot.vid = PCI_VENDOR_ID_PCI_SIG,
                .prot.type = PCI_DOE_PROTOCOL_DISCOVERY,
-               .request_pl = &request_pl,
+               .request_pl = &request_pl_le,
                .request_pl_sz = sizeof(request_pl),
-               .response_pl = &response_pl,
+               .response_pl = &response_pl_le,
                .response_pl_sz = sizeof(response_pl),
                .complete = pci_doe_task_complete,
                .private = &c,
@@ -340,6 +343,7 @@ static int pci_doe_discovery(struct pci_doe_mb *doe_mb, u8 *index, u16 *vid,
        if (task.rv != sizeof(response_pl))
                return -EIO;
 
+       response_pl = le32_to_cpu(response_pl_le);
        *vid = FIELD_GET(PCI_DOE_DATA_OBJECT_DISC_RSP_3_VID, response_pl);
        *protocol = FIELD_GET(PCI_DOE_DATA_OBJECT_DISC_RSP_3_PROTOCOL,
                              response_pl);
@@ -520,6 +524,8 @@ EXPORT_SYMBOL_GPL(pci_doe_supports_prot);
  * task->complete will be called when the state machine is done processing this
  * task.
  *
+ * @task must be allocated on the stack.
+ *
  * Excess data will be discarded.
  *
  * RETURNS: 0 when task has been successfully queued, -ERRNO on error
@@ -533,15 +539,15 @@ int pci_doe_submit_task(struct pci_doe_mb *doe_mb, struct pci_doe_task *task)
         * DOE requests must be a whole number of DW and the response needs to
         * be big enough for at least 1 DW
         */
-       if (task->request_pl_sz % sizeof(u32) ||
-           task->response_pl_sz < sizeof(u32))
+       if (task->request_pl_sz % sizeof(__le32) ||
+           task->response_pl_sz < sizeof(__le32))
                return -EINVAL;
 
        if (test_bit(PCI_DOE_FLAG_DEAD, &doe_mb->flags))
                return -EIO;
 
        task->doe_mb = doe_mb;
-       INIT_WORK(&task->work, doe_statemachine_work);
+       INIT_WORK_ONSTACK(&task->work, doe_statemachine_work);
        queue_work(doe_mb->work_queue, &task->work);
        return 0;
 }
index 1f716624ca563421b4b6561150b33ff478f68fea..ef1d8857a51ba691701e049efb9c05d668e9dc27 100644 (file)
@@ -750,8 +750,7 @@ out_disable:
        return ret;
 }
 
-static bool pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *entries,
-                                     int nvec, int hwsize)
+static bool pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *entries, int nvec)
 {
        bool nogap;
        int i, j;
@@ -762,10 +761,6 @@ static bool pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *en
        nogap = pci_msi_domain_supports(dev, MSI_FLAG_MSIX_CONTIGUOUS, DENY_LEGACY);
 
        for (i = 0; i < nvec; i++) {
-               /* Entry within hardware limit? */
-               if (entries[i].entry >= hwsize)
-                       return false;
-
                /* Check for duplicate entries */
                for (j = i + 1; j < nvec; j++) {
                        if (entries[i].entry == entries[j].entry)
@@ -805,7 +800,7 @@ int __pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int
        if (hwsize < 0)
                return hwsize;
 
-       if (!pci_msix_validate_entries(dev, entries, nvec, hwsize))
+       if (!pci_msix_validate_entries(dev, entries, nvec))
                return -EINVAL;
 
        if (hwsize < nvec) {
index 196834ed44fe84595a696159dd42deb24ec42b71..4c2ef2e28fb5e9030a0e8ed41d2bcd883a00c16c 100644 (file)
 #include "pci.h"
 
 #ifdef CONFIG_PCI
-void pci_set_of_node(struct pci_dev *dev)
+/**
+ * pci_set_of_node - Find and set device's DT device_node
+ * @dev: the PCI device structure to fill
+ *
+ * Returns 0 on success with of_node set or when no device is described in the
+ * DT. Returns -ENODEV if the device is present, but disabled in the DT.
+ */
+int pci_set_of_node(struct pci_dev *dev)
 {
+       struct device_node *node;
+
        if (!dev->bus->dev.of_node)
-               return;
-       dev->dev.of_node = of_pci_find_child_device(dev->bus->dev.of_node,
-                                                   dev->devfn);
-       if (dev->dev.of_node)
-               dev->dev.fwnode = &dev->dev.of_node->fwnode;
+               return 0;
+
+       node = of_pci_find_child_device(dev->bus->dev.of_node, dev->devfn);
+       if (!node)
+               return 0;
+
+       if (!of_device_is_available(node)) {
+               of_node_put(node);
+               return -ENODEV;
+       }
+
+       dev->dev.of_node = node;
+       dev->dev.fwnode = &node->fwnode;
+       return 0;
 }
 
 void pci_release_of_node(struct pci_dev *dev)
index d2c08670a20ed77823e65a748365d15f0a0bf875..2b48a0aa8008e5547ee258ad83759fb3177e2dd4 100644 (file)
@@ -624,7 +624,7 @@ int of_pci_get_max_link_speed(struct device_node *node);
 u32 of_pci_get_slot_power_limit(struct device_node *node,
                                u8 *slot_power_limit_value,
                                u8 *slot_power_limit_scale);
-void pci_set_of_node(struct pci_dev *dev);
+int pci_set_of_node(struct pci_dev *dev);
 void pci_release_of_node(struct pci_dev *dev);
 void pci_set_bus_of_node(struct pci_bus *bus);
 void pci_release_bus_of_node(struct pci_bus *bus);
@@ -662,7 +662,7 @@ of_pci_get_slot_power_limit(struct device_node *node,
        return 0;
 }
 
-static inline void pci_set_of_node(struct pci_dev *dev) { }
+static inline int pci_set_of_node(struct pci_dev *dev) { return 0; }
 static inline void pci_release_of_node(struct pci_dev *dev) { }
 static inline void pci_set_bus_of_node(struct pci_bus *bus) { }
 static inline void pci_release_bus_of_node(struct pci_bus *bus) { }
index a3f68b6ba6ac2db4500e5f5f416b972e479746d9..f96fa83f2627386677a4efcf10c7a971873dbd99 100644 (file)
@@ -1826,7 +1826,7 @@ int pci_setup_device(struct pci_dev *dev)
        u32 class;
        u16 cmd;
        u8 hdr_type;
-       int pos = 0;
+       int err, pos = 0;
        struct pci_bus_region region;
        struct resource *res;
 
@@ -1840,10 +1840,10 @@ int pci_setup_device(struct pci_dev *dev)
        dev->error_state = pci_channel_io_normal;
        set_pcie_port_type(dev);
 
-       pci_set_of_node(dev);
+       err = pci_set_of_node(dev);
+       if (err)
+               return err;
        pci_set_acpi_fwnode(dev);
-       if (dev->dev.fwnode && !fwnode_device_is_available(dev->dev.fwnode))
-               return -ENODEV;
 
        pci_dev_assign_slot(dev);
 
index 0145aef1b9301823e3a406611353b596036e8a77..22d39e12b236a69901628e580bccc4b8ee403bcd 100644 (file)
@@ -157,8 +157,6 @@ void pci_remove_root_bus(struct pci_bus *bus)
        list_for_each_entry_safe(child, tmp,
                                 &bus->devices, bus_list)
                pci_remove_bus_device(child);
-       pci_remove_bus(bus);
-       host_bridge->bus = NULL;
 
 #ifdef CONFIG_PCI_DOMAINS_GENERIC
        /* Release domain_nr if it was dynamically allocated */
@@ -166,6 +164,9 @@ void pci_remove_root_bus(struct pci_bus *bus)
                pci_bus_release_domain_nr(bus, host_bridge->dev.parent);
 #endif
 
+       pci_remove_bus(bus);
+       host_bridge->bus = NULL;
+
        /* remove the host bridge */
        device_del(&host_bridge->dev);
 }
index a78fdb15e26c20fa8b7e39e4490bc59bfddbdfd5..8b643888d50369ebdf3be0d3796d05f394f6c990 100644 (file)
 #define DMC_QOS_IRQ            BIT(30)
 
 /* DMC bandwidth monitor register address offset */
-#define DMC_MON_G12_CTRL0              (0x20  << 2)
-#define DMC_MON_G12_CTRL1              (0x21  << 2)
-#define DMC_MON_G12_CTRL2              (0x22  << 2)
-#define DMC_MON_G12_CTRL3              (0x23  << 2)
-#define DMC_MON_G12_CTRL4              (0x24  << 2)
-#define DMC_MON_G12_CTRL5              (0x25  << 2)
-#define DMC_MON_G12_CTRL6              (0x26  << 2)
-#define DMC_MON_G12_CTRL7              (0x27  << 2)
-#define DMC_MON_G12_CTRL8              (0x28  << 2)
-
-#define DMC_MON_G12_ALL_REQ_CNT                (0x29  << 2)
-#define DMC_MON_G12_ALL_GRANT_CNT      (0x2a  << 2)
-#define DMC_MON_G12_ONE_GRANT_CNT      (0x2b  << 2)
-#define DMC_MON_G12_SEC_GRANT_CNT      (0x2c  << 2)
-#define DMC_MON_G12_THD_GRANT_CNT      (0x2d  << 2)
-#define DMC_MON_G12_FOR_GRANT_CNT      (0x2e  << 2)
-#define DMC_MON_G12_TIMER              (0x2f  << 2)
+#define DMC_MON_G12_CTRL0              (0x0  << 2)
+#define DMC_MON_G12_CTRL1              (0x1  << 2)
+#define DMC_MON_G12_CTRL2              (0x2  << 2)
+#define DMC_MON_G12_CTRL3              (0x3  << 2)
+#define DMC_MON_G12_CTRL4              (0x4  << 2)
+#define DMC_MON_G12_CTRL5              (0x5  << 2)
+#define DMC_MON_G12_CTRL6              (0x6  << 2)
+#define DMC_MON_G12_CTRL7              (0x7  << 2)
+#define DMC_MON_G12_CTRL8              (0x8  << 2)
+
+#define DMC_MON_G12_ALL_REQ_CNT                (0x9  << 2)
+#define DMC_MON_G12_ALL_GRANT_CNT      (0xa  << 2)
+#define DMC_MON_G12_ONE_GRANT_CNT      (0xb  << 2)
+#define DMC_MON_G12_SEC_GRANT_CNT      (0xc  << 2)
+#define DMC_MON_G12_THD_GRANT_CNT      (0xd  << 2)
+#define DMC_MON_G12_FOR_GRANT_CNT      (0xe  << 2)
+#define DMC_MON_G12_TIMER              (0xf  << 2)
 
 /* Each bit represent a axi line */
 PMU_FORMAT_ATTR(event, "config:0-7");
index f20c28334bcbf68e85665c31b49357d79508904c..a71874fed3d60d35c49cf78978468a288847cc36 100644 (file)
@@ -45,35 +45,35 @@ config PINCTRL_MTK_PARIS
 
 # For ARMv7 SoCs
 config PINCTRL_MT2701
-       bool "Mediatek MT2701 pin control"
+       bool "MediaTek MT2701 pin control"
        depends on MACH_MT7623 || MACH_MT2701 || COMPILE_TEST
        depends on OF
        default MACH_MT2701
        select PINCTRL_MTK
 
 config PINCTRL_MT7623
-       bool "Mediatek MT7623 pin control with generic binding"
+       bool "MediaTek MT7623 pin control with generic binding"
        depends on MACH_MT7623 || COMPILE_TEST
        depends on OF
        default MACH_MT7623
        select PINCTRL_MTK_MOORE
 
 config PINCTRL_MT7629
-       bool "Mediatek MT7629 pin control"
+       bool "MediaTek MT7629 pin control"
        depends on MACH_MT7629 || COMPILE_TEST
        depends on OF
        default MACH_MT7629
        select PINCTRL_MTK_MOORE
 
 config PINCTRL_MT8135
-       bool "Mediatek MT8135 pin control"
+       bool "MediaTek MT8135 pin control"
        depends on MACH_MT8135 || COMPILE_TEST
        depends on OF
        default MACH_MT8135
        select PINCTRL_MTK
 
 config PINCTRL_MT8127
-       bool "Mediatek MT8127 pin control"
+       bool "MediaTek MT8127 pin control"
        depends on MACH_MT8127 || COMPILE_TEST
        depends on OF
        default MACH_MT8127
@@ -88,33 +88,33 @@ config PINCTRL_MT2712
        select PINCTRL_MTK
 
 config PINCTRL_MT6765
-       tristate "Mediatek MT6765 pin control"
+       tristate "MediaTek MT6765 pin control"
        depends on OF
        depends on ARM64 || COMPILE_TEST
        default ARM64 && ARCH_MEDIATEK
        select PINCTRL_MTK_PARIS
 
 config PINCTRL_MT6779
-       tristate "Mediatek MT6779 pin control"
+       tristate "MediaTek MT6779 pin control"
        depends on OF
        depends on ARM64 || COMPILE_TEST
        default ARM64 && ARCH_MEDIATEK
        select PINCTRL_MTK_PARIS
        help
          Say yes here to support pin controller and gpio driver
-         on Mediatek MT6779 SoC.
+         on MediaTek MT6779 SoC.
          In MTK platform, we support virtual gpio and use it to
          map specific eint which doesn't have real gpio pin.
 
 config PINCTRL_MT6795
-       bool "Mediatek MT6795 pin control"
+       bool "MediaTek MT6795 pin control"
        depends on OF
        depends on ARM64 || COMPILE_TEST
        default ARM64 && ARCH_MEDIATEK
        select PINCTRL_MTK_PARIS
 
 config PINCTRL_MT6797
-       bool "Mediatek MT6797 pin control"
+       bool "MediaTek MT6797 pin control"
        depends on OF
        depends on ARM64 || COMPILE_TEST
        default ARM64 && ARCH_MEDIATEK
@@ -128,40 +128,42 @@ config PINCTRL_MT7622
        select PINCTRL_MTK_MOORE
 
 config PINCTRL_MT7981
-       bool "Mediatek MT7981 pin control"
+       bool "MediaTek MT7981 pin control"
        depends on OF
+       depends on ARM64 || COMPILE_TEST
+       default ARM64 && ARCH_MEDIATEK
        select PINCTRL_MTK_MOORE
 
 config PINCTRL_MT7986
-       bool "Mediatek MT7986 pin control"
+       bool "MediaTek MT7986 pin control"
        depends on OF
        depends on ARM64 || COMPILE_TEST
        default ARM64 && ARCH_MEDIATEK
        select PINCTRL_MTK_MOORE
 
 config PINCTRL_MT8167
-       bool "Mediatek MT8167 pin control"
+       bool "MediaTek MT8167 pin control"
        depends on OF
        depends on ARM64 || COMPILE_TEST
        default ARM64 && ARCH_MEDIATEK
        select PINCTRL_MTK
 
 config PINCTRL_MT8173
-       bool "Mediatek MT8173 pin control"
+       bool "MediaTek MT8173 pin control"
        depends on OF
        depends on ARM64 || COMPILE_TEST
        default ARM64 && ARCH_MEDIATEK
        select PINCTRL_MTK
 
 config PINCTRL_MT8183
-       bool "Mediatek MT8183 pin control"
+       bool "MediaTek MT8183 pin control"
        depends on OF
        depends on ARM64 || COMPILE_TEST
        default ARM64 && ARCH_MEDIATEK
        select PINCTRL_MTK_PARIS
 
 config PINCTRL_MT8186
-       bool "Mediatek MT8186 pin control"
+       bool "MediaTek MT8186 pin control"
        depends on OF
        depends on ARM64 || COMPILE_TEST
        default ARM64 && ARCH_MEDIATEK
@@ -180,28 +182,28 @@ config PINCTRL_MT8188
          map specific eint which doesn't have real gpio pin.
 
 config PINCTRL_MT8192
-       bool "Mediatek MT8192 pin control"
+       bool "MediaTek MT8192 pin control"
        depends on OF
        depends on ARM64 || COMPILE_TEST
        default ARM64 && ARCH_MEDIATEK
        select PINCTRL_MTK_PARIS
 
 config PINCTRL_MT8195
-       bool "Mediatek MT8195 pin control"
+       bool "MediaTek MT8195 pin control"
        depends on OF
        depends on ARM64 || COMPILE_TEST
        default ARM64 && ARCH_MEDIATEK
        select PINCTRL_MTK_PARIS
 
 config PINCTRL_MT8365
-       bool "Mediatek MT8365 pin control"
+       bool "MediaTek MT8365 pin control"
        depends on OF
        depends on ARM64 || COMPILE_TEST
        default ARM64 && ARCH_MEDIATEK
        select PINCTRL_MTK
 
 config PINCTRL_MT8516
-       bool "Mediatek MT8516 pin control"
+       bool "MediaTek MT8516 pin control"
        depends on OF
        depends on ARM64 || COMPILE_TEST
        default ARM64 && ARCH_MEDIATEK
@@ -209,7 +211,7 @@ config PINCTRL_MT8516
 
 # For PMIC
 config PINCTRL_MT6397
-       bool "Mediatek MT6397 pin control"
+       bool "MediaTek MT6397 pin control"
        depends on MFD_MT6397 || COMPILE_TEST
        depends on OF
        default MFD_MT6397
index 373eed8bc4be93db2a43069e015f6d208d8f6c88..c775d239444a6fcbf2dbcdf88c2a9aeb90e31edc 100644 (file)
@@ -1206,7 +1206,6 @@ static int atmel_pinctrl_probe(struct platform_device *pdev)
                dev_err(dev, "can't add the irq domain\n");
                return -ENODEV;
        }
-       atmel_pioctrl->irq_domain->name = "atmel gpio";
 
        for (i = 0; i < atmel_pioctrl->npins; i++) {
                int irq = irq_create_mapping(atmel_pioctrl->irq_domain, i);
index 29e4a6282a64140e0af3b7b867b96fb7a69b1bd5..1dcbd0937ef5ae3f5df98e3c0f4ab29dd736f70b 100644 (file)
@@ -1204,7 +1204,7 @@ static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev,
        regmap_update_bits(info->map, REG_ALT(0, info, pin->pin),
                           BIT(p), f << p);
        regmap_update_bits(info->map, REG_ALT(1, info, pin->pin),
-                          BIT(p), f << (p - 1));
+                          BIT(p), (f >> 1) << p);
 
        return 0;
 }
index cb33a23ab0c1120c7d30c4a1d01f3f41a08f11d3..04ace4c7bd5826ed7eaa4db68d5345841093223c 100644 (file)
@@ -1330,7 +1330,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
        if (fwnode_property_read_u32(fwnode, "st,bank-ioport", &bank_ioport_nr))
                bank_ioport_nr = bank_nr;
 
-       bank->gpio_chip.base = bank_nr * STM32_GPIO_PINS_PER_BANK;
+       bank->gpio_chip.base = -1;
 
        bank->gpio_chip.ngpio = npins;
        bank->gpio_chip.fwnode = fwnode;
index 0de7c255254e0ba7f4e33c4da8a7b7573e815bb5..d6de5a29412820d14e3a55dce951b94228bb60de 100644 (file)
@@ -284,7 +284,7 @@ static long cros_ec_chardev_ioctl_xcmd(struct cros_ec_dev *ec, void __user *arg)
            u_cmd.insize > EC_MAX_MSG_BYTES)
                return -EINVAL;
 
-       s_cmd = kmalloc(sizeof(*s_cmd) + max(u_cmd.outsize, u_cmd.insize),
+       s_cmd = kzalloc(sizeof(*s_cmd) + max(u_cmd.outsize, u_cmd.insize),
                        GFP_KERNEL);
        if (!s_cmd)
                return -ENOMEM;
index 09c7829e95c4b037947f573ff2045cf6cebbdd81..382793e73a60a8b3f4ade16b00768fc368eb50e2 100644 (file)
@@ -16,17 +16,17 @@ if MELLANOX_PLATFORM
 
 config MLXREG_HOTPLUG
        tristate "Mellanox platform hotplug driver support"
-       depends on REGMAP
        depends on HWMON
        depends on I2C
+       select REGMAP
        help
          This driver handles hot-plug events for the power suppliers, power
          cables and fans on the wide range Mellanox IB and Ethernet systems.
 
 config MLXREG_IO
        tristate "Mellanox platform register access driver support"
-       depends on REGMAP
        depends on HWMON
+       select REGMAP
        help
          This driver allows access to Mellanox programmable device register
          space through sysfs interface. The sets of registers for sysfs access
@@ -36,9 +36,9 @@ config MLXREG_IO
 
 config MLXREG_LC
        tristate "Mellanox line card platform driver support"
-       depends on REGMAP
        depends on HWMON
        depends on I2C
+       select REGMAP
        help
          This driver provides support for the Mellanox MSN4800-XX line cards,
          which are the part of MSN4800 Ethernet modular switch systems
@@ -80,10 +80,9 @@ config MLXBF_PMC
 
 config NVSW_SN2201
        tristate "Nvidia SN2201 platform driver support"
-       depends on REGMAP
        depends on HWMON
        depends on I2C
-       depends on REGMAP_I2C
+       select REGMAP_I2C
        help
          This driver provides support for the Nvidia SN2201 platform.
          The SN2201 is a highly integrated for one rack unit system with
index aaad41294200de2d1bca1ec1bf742bf166c3d171..42ccd7f1c9b9c3aac498af13878305724d8aa04b 100644 (file)
@@ -485,8 +485,10 @@ int __ssam_register_clients(struct device *parent, struct ssam_controller *ctrl,
                 * device, so ignore it and continue with the next one.
                 */
                status = ssam_add_client_device(parent, ctrl, child);
-               if (status && status != -ENODEV)
+               if (status && status != -ENODEV) {
+                       fwnode_handle_put(child);
                        goto err;
+               }
        }
 
        return 0;
index ec7c2b4e1721cd14cc000bd8bf3cd7d9587220b6..4a01b315e0a91ed5c6517407b4eb6250a42809b3 100644 (file)
@@ -955,7 +955,8 @@ config SERIAL_MULTI_INSTANTIATE
 
 config MLX_PLATFORM
        tristate "Mellanox Technologies platform support"
-       depends on I2C && REGMAP
+       depends on I2C
+       select REGMAP
        help
          This option enables system support for the Mellanox Technologies
          platform. The Mellanox systems provide data center networking
index ab05b9ee6655aa63a3ddf1023bd2f8a70047b635..2edaae04a6912a4bf6a2d377f1698dd5f9509584 100644 (file)
@@ -171,9 +171,7 @@ MODULE_PARM_DESC(disable_workarounds, "Disable workarounds for platform bugs");
 static struct amd_pmc_dev pmc;
 static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, u32 arg, u32 *data, u8 msg, bool ret);
 static int amd_pmc_read_stb(struct amd_pmc_dev *dev, u32 *buf);
-#ifdef CONFIG_SUSPEND
 static int amd_pmc_write_stb(struct amd_pmc_dev *dev, u32 data);
-#endif
 
 static inline u32 amd_pmc_reg_read(struct amd_pmc_dev *dev, int reg_offset)
 {
@@ -386,7 +384,6 @@ static int get_metrics_table(struct amd_pmc_dev *pdev, struct smu_metrics *table
        return 0;
 }
 
-#ifdef CONFIG_SUSPEND
 static void amd_pmc_validate_deepest(struct amd_pmc_dev *pdev)
 {
        struct smu_metrics table;
@@ -400,7 +397,6 @@ static void amd_pmc_validate_deepest(struct amd_pmc_dev *pdev)
                dev_dbg(pdev->dev, "Last suspend in deepest state for %lluus\n",
                         table.timein_s0i3_lastcapture);
 }
-#endif
 
 static int amd_pmc_get_smu_version(struct amd_pmc_dev *dev)
 {
@@ -673,7 +669,6 @@ out_unlock:
        return rc;
 }
 
-#ifdef CONFIG_SUSPEND
 static int amd_pmc_get_os_hint(struct amd_pmc_dev *dev)
 {
        switch (dev->cpu_id) {
@@ -861,9 +856,7 @@ static int __maybe_unused amd_pmc_suspend_handler(struct device *dev)
        return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(amd_pmc_pm, amd_pmc_suspend_handler, NULL);
-
-#endif
+static DEFINE_SIMPLE_DEV_PM_OPS(amd_pmc_pm, amd_pmc_suspend_handler, NULL);
 
 static const struct pci_device_id pmc_pci_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PS) },
@@ -905,7 +898,6 @@ static int amd_pmc_s2d_init(struct amd_pmc_dev *dev)
        return 0;
 }
 
-#ifdef CONFIG_SUSPEND
 static int amd_pmc_write_stb(struct amd_pmc_dev *dev, u32 data)
 {
        int err;
@@ -926,7 +918,6 @@ static int amd_pmc_write_stb(struct amd_pmc_dev *dev, u32 data)
 
        return 0;
 }
-#endif
 
 static int amd_pmc_read_stb(struct amd_pmc_dev *dev, u32 *buf)
 {
@@ -1017,11 +1008,11 @@ static int amd_pmc_probe(struct platform_device *pdev)
        }
 
        platform_set_drvdata(pdev, dev);
-#ifdef CONFIG_SUSPEND
-       err = acpi_register_lps0_dev(&amd_pmc_s2idle_dev_ops);
-       if (err)
-               dev_warn(dev->dev, "failed to register LPS0 sleep handler, expect increased power consumption\n");
-#endif
+       if (IS_ENABLED(CONFIG_SUSPEND)) {
+               err = acpi_register_lps0_dev(&amd_pmc_s2idle_dev_ops);
+               if (err)
+                       dev_warn(dev->dev, "failed to register LPS0 sleep handler, expect increased power consumption\n");
+       }
 
        amd_pmc_dbgfs_register(dev);
        return 0;
@@ -1035,9 +1026,8 @@ static int amd_pmc_remove(struct platform_device *pdev)
 {
        struct amd_pmc_dev *dev = platform_get_drvdata(pdev);
 
-#ifdef CONFIG_SUSPEND
-       acpi_unregister_lps0_dev(&amd_pmc_s2idle_dev_ops);
-#endif
+       if (IS_ENABLED(CONFIG_SUSPEND))
+               acpi_unregister_lps0_dev(&amd_pmc_s2idle_dev_ops);
        amd_pmc_dbgfs_unregister(dev);
        pci_dev_put(dev->rdev);
        mutex_destroy(&dev->lock);
@@ -1061,9 +1051,7 @@ static struct platform_driver amd_pmc_driver = {
                .name = "amd_pmc",
                .acpi_match_table = amd_pmc_acpi_ids,
                .dev_groups = pmc_groups,
-#ifdef CONFIG_SUSPEND
-               .pm = &amd_pmc_pm,
-#endif
+               .pm = pm_sleep_ptr(&amd_pmc_pm),
        },
        .probe = amd_pmc_probe,
        .remove = amd_pmc_remove,
index cb15acdf14a30a53a2cf5f53fbc618c3f1abbba2..e2c9a68d12df9cc00ce3deda7964fb12bfd23a0f 100644 (file)
@@ -464,7 +464,8 @@ static const struct dmi_system_id asus_quirks[] = {
                .ident = "ASUS ROG FLOW X13",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "GV301Q"),
+                       /* Match GV301** */
+                       DMI_MATCH(DMI_PRODUCT_NAME, "GV301"),
                },
                .driver_data = &quirk_asus_tablet_mode,
        },
index d547c9d097256f61ceffd52d15718b8d62157876..2750dee99c3e255a8821b591139775c1d4c641cf 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/kernel.h>
 #include <linux/hwmon.h>
 #include <linux/kstrtox.h>
-#include <linux/math.h>
 #include <linux/math64.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
@@ -96,6 +95,7 @@ struct combined_chip_info {
 };
 
 struct dell_wmi_ddv_sensors {
+       bool active;
        struct mutex lock;      /* protect caching */
        unsigned long timestamp;
        union acpi_object *obj;
@@ -520,6 +520,9 @@ static struct hwmon_channel_info *dell_wmi_ddv_channel_create(struct device *dev
 
 static void dell_wmi_ddv_hwmon_cache_invalidate(struct dell_wmi_ddv_sensors *sensors)
 {
+       if (!sensors->active)
+               return;
+
        mutex_lock(&sensors->lock);
        kfree(sensors->obj);
        sensors->obj = NULL;
@@ -530,6 +533,7 @@ static void dell_wmi_ddv_hwmon_cache_destroy(void *data)
 {
        struct dell_wmi_ddv_sensors *sensors = data;
 
+       sensors->active = false;
        mutex_destroy(&sensors->lock);
        kfree(sensors->obj);
 }
@@ -549,6 +553,7 @@ static struct hwmon_channel_info *dell_wmi_ddv_channel_init(struct wmi_device *w
                return ERR_PTR(ret);
 
        mutex_init(&sensors->lock);
+       sensors->active = true;
 
        ret = devm_add_action_or_reset(&wdev->dev, dell_wmi_ddv_hwmon_cache_destroy, sensors);
        if (ret < 0)
@@ -659,7 +664,8 @@ static ssize_t temp_show(struct device *dev, struct device_attribute *attr, char
        if (ret < 0)
                return ret;
 
-       return sysfs_emit(buf, "%d\n", DIV_ROUND_CLOSEST(value, 10));
+       /* Use 2731 instead of 2731.5 to avoid unnecessary rounding */
+       return sysfs_emit(buf, "%d\n", value - 2731);
 }
 
 static ssize_t eppid_show(struct device *dev, struct device_attribute *attr, char *buf)
@@ -852,7 +858,7 @@ static int dell_wmi_ddv_resume(struct device *dev)
 {
        struct dell_wmi_ddv_data *data = dev_get_drvdata(dev);
 
-       /* Force re-reading of all sensors */
+       /* Force re-reading of all active sensors */
        dell_wmi_ddv_hwmon_cache_invalidate(&data->fans);
        dell_wmi_ddv_hwmon_cache_invalidate(&data->temps);
 
index 322cfaeda17badd650ee3e74cee779e9f7cf6fb7..2a426040f749efec340301127caa9baf57adf17a 100644 (file)
@@ -140,6 +140,7 @@ static u8 gigabyte_wmi_detect_sensor_usability(struct wmi_device *wdev)
        }}
 
 static const struct dmi_system_id gigabyte_wmi_known_working_platforms[] = {
+       DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("A320M-S2H V2-CF"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B450M DS3H-CF"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B450M DS3H WIFI-CF"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B450M S2H V2"),
@@ -150,6 +151,7 @@ static const struct dmi_system_id gigabyte_wmi_known_working_platforms[] = {
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550I AORUS PRO AX"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550M AORUS PRO-P"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550M DS3H"),
+       DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B650 AORUS ELITE AX"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B660 GAMING X DDR4"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B660I AORUS PRO DDR4"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("Z390 I AORUS PRO WIFI-CF"),
@@ -159,6 +161,7 @@ static const struct dmi_system_id gigabyte_wmi_known_working_platforms[] = {
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 GAMING X"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 I AORUS PRO WIFI"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 UD"),
+       DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570S AORUS ELITE"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("Z690M AORUS ELITE AX DDR4"),
        { }
 };
index 0eb5bfdd823a1d58bd3d4e153048261ccd664221..959ec3c5f376e737f0b9d2c0e566b291160cd226 100644 (file)
@@ -1170,7 +1170,6 @@ static const struct key_entry ideapad_keymap[] = {
        { KE_KEY,  65, { KEY_PROG4 } },
        { KE_KEY,  66, { KEY_TOUCHPAD_OFF } },
        { KE_KEY,  67, { KEY_TOUCHPAD_ON } },
-       { KE_KEY,  68, { KEY_TOUCHPAD_TOGGLE } },
        { KE_KEY, 128, { KEY_ESC } },
 
        /*
@@ -1526,18 +1525,16 @@ static void ideapad_sync_touchpad_state(struct ideapad_private *priv, bool send_
        if (priv->features.ctrl_ps2_aux_port)
                i8042_command(&param, value ? I8042_CMD_AUX_ENABLE : I8042_CMD_AUX_DISABLE);
 
-       if (send_events) {
-               /*
-                * On older models the EC controls the touchpad and toggles it
-                * on/off itself, in this case we report KEY_TOUCHPAD_ON/_OFF.
-                * If the EC did not toggle, report KEY_TOUCHPAD_TOGGLE.
-                */
-               if (value != priv->r_touchpad_val) {
-                       ideapad_input_report(priv, value ? 67 : 66);
-                       sysfs_notify(&priv->platform_device->dev.kobj, NULL, "touchpad");
-               } else {
-                       ideapad_input_report(priv, 68);
-               }
+       /*
+        * On older models the EC controls the touchpad and toggles it on/off
+        * itself, in this case we report KEY_TOUCHPAD_ON/_OFF. Some models do
+        * an acpi-notify with VPC bit 5 set on resume, so this function get
+        * called with send_events=true on every resume. Therefor if the EC did
+        * not toggle, do nothing to avoid sending spurious KEY_TOUCHPAD_TOGGLE.
+        */
+       if (send_events && value != priv->r_touchpad_val) {
+               ideapad_input_report(priv, value ? 67 : 66);
+               sysfs_notify(&priv->platform_device->dev.kobj, NULL, "touchpad");
        }
 
        priv->r_touchpad_val = value;
index 309eab9c055888a7affde7ed898a131f072c5f9c..322237e056f32e585e342bf8c27934c39c6fce84 100644 (file)
@@ -159,9 +159,10 @@ static const struct int3472_tps68470_board_data surface_go_tps68470_board_data =
 static const struct int3472_tps68470_board_data surface_go3_tps68470_board_data = {
        .dev_name = "i2c-INT3472:01",
        .tps68470_regulator_pdata = &surface_go_tps68470_pdata,
-       .n_gpiod_lookups = 1,
+       .n_gpiod_lookups = 2,
        .tps68470_gpio_lookup_tables = {
-               &surface_go_int347a_gpios
+               &surface_go_int347a_gpios,
+               &surface_go_int347e_gpios,
        },
 };
 
index 3a15d32d7644c000e009c801261318cf9da794dd..b9591969e0fa119bf84710e2cee4cddf61541ee0 100644 (file)
@@ -66,7 +66,18 @@ static inline void pmc_core_reg_write(struct pmc_dev *pmcdev, int reg_offset,
 
 static inline u64 pmc_core_adjust_slp_s0_step(struct pmc_dev *pmcdev, u32 value)
 {
-       return (u64)value * pmcdev->map->slp_s0_res_counter_step;
+       /*
+        * ADL PCH does not have the SLP_S0 counter and LPM Residency counters are
+        * used as a workaround which uses 30.5 usec tick. All other client
+        * programs have the legacy SLP_S0 residency counter that is using the 122
+        * usec tick.
+        */
+       const int lpm_adj_x2 = pmcdev->map->lpm_res_counter_step_x2;
+
+       if (pmcdev->map == &adl_reg_map)
+               return (u64)value * GET_X2_COUNTER((u64)lpm_adj_x2);
+       else
+               return (u64)value * pmcdev->map->slp_s0_res_counter_step;
 }
 
 static int set_etr3(struct pmc_dev *pmcdev)
index a7e02b24a87ad7dc02c1533f1555d8362f49501d..0954a04623edfff38d91cde7f22d7d2d3464e7f2 100644 (file)
@@ -47,7 +47,7 @@ struct isst_cmd_set_req_type {
 
 static const struct isst_valid_cmd_ranges isst_valid_cmds[] = {
        {0xD0, 0x00, 0x03},
-       {0x7F, 0x00, 0x0B},
+       {0x7F, 0x00, 0x0C},
        {0x7F, 0x10, 0x12},
        {0x7F, 0x20, 0x23},
        {0x94, 0x03, 0x03},
@@ -112,6 +112,7 @@ static void isst_delete_hash(void)
  * isst_store_cmd() - Store command to a hash table
  * @cmd: Mailbox command.
  * @sub_cmd: Mailbox sub-command or MSR id.
+ * @cpu: Target CPU for the command
  * @mbox_cmd_type: Mailbox or MSR command.
  * @param: Mailbox parameter.
  * @data: Mailbox request data or MSR data.
@@ -363,7 +364,7 @@ static struct pci_dev *_isst_if_get_pci_dev(int cpu, int bus_no, int dev, int fn
 /**
  * isst_if_get_pci_dev() - Get the PCI device instance for a CPU
  * @cpu: Logical CPU number.
- * @bus_number: The bus number assigned by the hardware.
+ * @bus_no: The bus number assigned by the hardware.
  * @dev: The device number assigned by the hardware.
  * @fn: The function number assigned by the hardware.
  *
index fdecdae248d7787200c3e09077b4df74d3f70a67..35ff506b402e1110b31274a9df09b704ad521d47 100644 (file)
@@ -40,6 +40,7 @@
  * @offset:    Offset to the first valid member in command structure.
  *             This will be the offset of the start of the command
  *             after command count field
+ * @owner:     Registered module owner
  * @cmd_callback: Callback function to handle IOCTL. The callback has the
  *             command pointer with data for command. There is a pointer
  *             called write_only, which when set, will not copy the
index c60733261c89c9cf106088814126aca6cb70f438..a5227951decce90f3eaf95aedfa0383a1c2bf957 100644 (file)
@@ -203,20 +203,20 @@ static int tpmi_create_device(struct intel_tpmi_info *tpmi_info,
        struct intel_vsec_device *feature_vsec_dev;
        struct resource *res, *tmp;
        const char *name;
-       int ret, i;
+       int i;
 
        name = intel_tpmi_name(pfs->pfs_header.tpmi_id);
        if (!name)
                return -EOPNOTSUPP;
 
-       feature_vsec_dev = kzalloc(sizeof(*feature_vsec_dev), GFP_KERNEL);
-       if (!feature_vsec_dev)
+       res = kcalloc(pfs->pfs_header.num_entries, sizeof(*res), GFP_KERNEL);
+       if (!res)
                return -ENOMEM;
 
-       res = kcalloc(pfs->pfs_header.num_entries, sizeof(*res), GFP_KERNEL);
-       if (!res) {
-               ret = -ENOMEM;
-               goto free_vsec;
+       feature_vsec_dev = kzalloc(sizeof(*feature_vsec_dev), GFP_KERNEL);
+       if (!feature_vsec_dev) {
+               kfree(res);
+               return -ENOMEM;
        }
 
        snprintf(feature_id_name, sizeof(feature_id_name), "tpmi-%s", name);
@@ -239,20 +239,11 @@ static int tpmi_create_device(struct intel_tpmi_info *tpmi_info,
        /*
         * intel_vsec_add_aux() is resource managed, no explicit
         * delete is required on error or on module unload.
+        * feature_vsec_dev and res memory are also freed as part of
+        * device deletion.
         */
-       ret = intel_vsec_add_aux(vsec_dev->pcidev, &vsec_dev->auxdev.dev,
-                                feature_vsec_dev, feature_id_name);
-       if (ret)
-               goto free_res;
-
-       return 0;
-
-free_res:
-       kfree(res);
-free_vsec:
-       kfree(feature_vsec_dev);
-
-       return ret;
+       return intel_vsec_add_aux(vsec_dev->pcidev, &vsec_dev->auxdev.dev,
+                                 feature_vsec_dev, feature_id_name);
 }
 
 static int tpmi_create_devices(struct intel_tpmi_info *tpmi_info)
index 13decf36c6ded9740ce67b9adbd3c637e1829517..2311c16cb975de8b44f99d97b14e5dcfd3af5f48 100644 (file)
@@ -154,6 +154,7 @@ int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent,
        ret = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL);
        mutex_unlock(&vsec_ida_lock);
        if (ret < 0) {
+               kfree(intel_vsec_dev->resource);
                kfree(intel_vsec_dev);
                return ret;
        }
index 7b6779cdb13493887474f7fea868feda8d2f24ab..67367f010139e21fbde7b3a345c80c36ab1bc31a 100644 (file)
@@ -5980,7 +5980,7 @@ MODULE_DEVICE_TABLE(dmi, mlxplat_dmi_table);
 static int mlxplat_mlxcpld_verify_bus_topology(int *nr)
 {
        struct i2c_adapter *search_adap;
-       int shift, i;
+       int i, shift = 0;
 
        /* Scan adapters from expected id to verify it is free. */
        *nr = MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR;
index 86b33b74519bed079c0360381b3e45ee962e6abd..78dc82bda4ddeac371580b48aacbcc5a3ad6e5be 100644 (file)
@@ -920,7 +920,7 @@ static ssize_t display_name_show(struct kobject *kobj, struct kobj_attribute *at
 static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
 {
        struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
-       char *item, *value;
+       char *item, *value, *p;
        int ret;
 
        ret = tlmi_setting(setting->index, &item, LENOVO_BIOS_SETTING_GUID);
@@ -930,10 +930,15 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a
        /* validate and split from `item,value` -> `value` */
        value = strpbrk(item, ",");
        if (!value || value == item || !strlen(value + 1))
-               return -EINVAL;
-
-       ret = sysfs_emit(buf, "%s\n", value + 1);
+               ret = -EINVAL;
+       else {
+               /* On Workstations remove the Options part after the value */
+               p = strchrnul(value, ';');
+               *p = '\0';
+               ret = sysfs_emit(buf, "%s\n", value + 1);
+       }
        kfree(item);
+
        return ret;
 }
 
@@ -941,12 +946,23 @@ static ssize_t possible_values_show(struct kobject *kobj, struct kobj_attribute
 {
        struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
 
-       if (!tlmi_priv.can_get_bios_selections)
-               return -EOPNOTSUPP;
-
        return sysfs_emit(buf, "%s\n", setting->possible_values);
 }
 
+static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr,
+               char *buf)
+{
+       struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
+
+       if (setting->possible_values) {
+               /* Figure out what setting type is as BIOS does not return this */
+               if (strchr(setting->possible_values, ';'))
+                       return sysfs_emit(buf, "enumeration\n");
+       }
+       /* Anything else is going to be a string */
+       return sysfs_emit(buf, "string\n");
+}
+
 static ssize_t current_value_store(struct kobject *kobj,
                struct kobj_attribute *attr,
                const char *buf, size_t count)
@@ -1036,14 +1052,30 @@ static struct kobj_attribute attr_possible_values = __ATTR_RO(possible_values);
 
 static struct kobj_attribute attr_current_val = __ATTR_RW_MODE(current_value, 0600);
 
+static struct kobj_attribute attr_type = __ATTR_RO(type);
+
+static umode_t attr_is_visible(struct kobject *kobj,
+                                            struct attribute *attr, int n)
+{
+       struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
+
+       /* We don't want to display possible_values attributes if not available */
+       if ((attr == &attr_possible_values.attr) && (!setting->possible_values))
+               return 0;
+
+       return attr->mode;
+}
+
 static struct attribute *tlmi_attrs[] = {
        &attr_displ_name.attr,
        &attr_current_val.attr,
        &attr_possible_values.attr,
+       &attr_type.attr,
        NULL
 };
 
 static const struct attribute_group tlmi_attr_group = {
+       .is_visible = attr_is_visible,
        .attrs = tlmi_attrs,
 };
 
@@ -1423,7 +1455,35 @@ static int tlmi_analyze(void)
                        if (ret || !setting->possible_values)
                                pr_info("Error retrieving possible values for %d : %s\n",
                                                i, setting->display_name);
+               } else {
+                       /*
+                        * Older Thinkstations don't support the bios_selections API.
+                        * Instead they store this as a [Optional:Option1,Option2] section of the
+                        * name string.
+                        * Try and pull that out if it's available.
+                        */
+                       char *optitem, *optstart, *optend;
+
+                       if (!tlmi_setting(setting->index, &optitem, LENOVO_BIOS_SETTING_GUID)) {
+                               optstart = strstr(optitem, "[Optional:");
+                               if (optstart) {
+                                       optstart += strlen("[Optional:");
+                                       optend = strstr(optstart, "]");
+                                       if (optend)
+                                               setting->possible_values =
+                                                       kstrndup(optstart, optend - optstart,
+                                                                       GFP_KERNEL);
+                               }
+                               kfree(optitem);
+                       }
                }
+               /*
+                * firmware-attributes requires that possible_values are separated by ';' but
+                * Lenovo FW uses ','. Replace appropriately.
+                */
+               if (setting->possible_values)
+                       strreplace(setting->possible_values, ',', ';');
+
                kobject_init(&setting->kobj, &tlmi_attr_setting_ktype);
                tlmi_priv.setting[i] = setting;
                kfree(item);
index 32c10457399e442ac15ec28ada09d851155f34d8..7191ff2625b1ef8c223037d229485836dadb0952 100644 (file)
@@ -4478,6 +4478,14 @@ static const struct dmi_system_id fwbug_list[] __initconst = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "20UH"),
                }
        },
+       {
+               .ident = "T14s Gen1 AMD",
+               .driver_data = &quirk_s2idle_bug,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "20UJ"),
+               }
+       },
        {
                .ident = "P14s Gen1 AMD",
                .driver_data = &quirk_s2idle_bug,
index 8e6f8a655079066975acd420d230c7f5ff150511..05f41317846296b067f41d050abc66d26cf09ff0 100644 (file)
@@ -724,6 +724,8 @@ static int axp288_fuel_gauge_probe(struct platform_device *pdev)
 
        for (i = 0; i < AXP288_FG_INTR_NUM; i++) {
                pirq = platform_get_irq(pdev, i);
+               if (pirq < 0)
+                       continue;
                ret = regmap_irq_get_virq(axp20x->regmap_irqc, pirq);
                if (ret < 0)
                        return dev_err_probe(dev, ret, "getting vIRQ %d\n", pirq);
index be34b98484508a980db556af6352aaf12f622864..de67b985f0a913a355ea3c27e3897d7373b78db2 100644 (file)
@@ -1906,6 +1906,7 @@ static void bq24190_remove(struct i2c_client *client)
        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
        int error;
 
+       cancel_delayed_work_sync(&bdi->input_current_limit_work);
        error = pm_runtime_resume_and_get(bdi->dev);
        if (error < 0)
                dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
index cadb6a0c2cc7e0a5e0e4e91951e0b6c758c27f8e..b6c96376776a9aa36f3d06fa0654f3bd8ddd3e14 100644 (file)
@@ -276,7 +276,7 @@ static int cros_usbpd_charger_get_power_info(struct port_data *port)
                port->psy_current_max = 0;
                break;
        default:
-               dev_err(dev, "Port %d: default case!\n", port->port_number);
+               dev_dbg(dev, "Port %d: default case!\n", port->port_number);
                port->psy_usb_type = POWER_SUPPLY_USB_TYPE_SDP;
        }
 
index 14da5c595dd9f31a720118112395af87810fe32f..a87aeaea38e1395c142d2bfad50cec37d3bf919c 100644 (file)
@@ -657,6 +657,7 @@ static int da9150_charger_remove(struct platform_device *pdev)
 
        if (!IS_ERR_OR_NULL(charger->usb_phy))
                usb_unregister_notifier(charger->usb_phy, &charger->otg_nb);
+       cancel_work_sync(&charger->otg_work);
 
        power_supply_unregister(charger->battery);
        power_supply_unregister(charger->usb);
index 4f9c1c417916550d76706253347acc7e64d18f3d..36f807b5ec4425c30646d82f558b551cda19d9c7 100644 (file)
@@ -785,8 +785,6 @@ rk817_read_or_set_full_charge_on_boot(struct rk817_charger *charger,
                regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3,
                                 bulk_reg, 4);
                tmp = get_unaligned_be32(bulk_reg);
-               if (tmp < 0)
-                       tmp = 0;
                boot_charge_mah = ADC_TO_CHARGE_UAH(tmp,
                                                    charger->res_div) / 1000;
                /*
@@ -825,8 +823,6 @@ rk817_read_or_set_full_charge_on_boot(struct rk817_charger *charger,
        regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3,
                         bulk_reg, 4);
        tmp = get_unaligned_be32(bulk_reg);
-       if (tmp < 0)
-               tmp = 0;
        boot_charge_mah = ADC_TO_CHARGE_UAH(tmp, charger->res_div) / 1000;
        regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_OCV_VOL_H,
                         bulk_reg, 2);
index 61530167efe4afac332a8fc3b615c8afa9e183c8..350154e4c2b540ce0afbe2a8612331e3f33426e9 100644 (file)
@@ -637,7 +637,7 @@ static int ptp_qoriq_probe(struct platform_device *dev)
        return 0;
 
 no_clock:
-       iounmap(ptp_qoriq->base);
+       iounmap(base);
 no_ioremap:
        release_resource(ptp_qoriq->rsrc);
 no_resource:
index e01147f66e15aa752c8a1331372ffa0440c07d4c..474725714a05b74206dc412fe0cbca464fd4f505 100644 (file)
@@ -115,7 +115,14 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
        }
 
        if (pwm->chip->ops->get_state) {
-               struct pwm_state state;
+               /*
+                * Zero-initialize state because most drivers are unaware of
+                * .usage_power. The other members of state are supposed to be
+                * set by lowlevel drivers. We still initialize the whole
+                * structure for simplicity even though this might paper over
+                * faulty implementations of .get_state().
+                */
+               struct pwm_state state = { 0, };
 
                err = pwm->chip->ops->get_state(pwm->chip, pwm, &state);
                trace_pwm_get(pwm, &state, err);
@@ -448,7 +455,7 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
 {
        struct pwm_state *last = &pwm->last;
        struct pwm_chip *chip = pwm->chip;
-       struct pwm_state s1, s2;
+       struct pwm_state s1 = { 0 }, s2 = { 0 };
        int err;
 
        if (!IS_ENABLED(CONFIG_PWM_DEBUG))
@@ -530,6 +537,7 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
                return;
        }
 
+       *last = (struct pwm_state){ 0 };
        err = chip->ops->get_state(chip, pwm, last);
        trace_pwm_get(pwm, last, err);
        if (err)
index 86df6702cb8358233cdfa5cf45b7946837ceefbe..ad18b0ebe3f1ee3446d21d646412c69156f9859b 100644 (file)
@@ -198,6 +198,7 @@ static int cros_ec_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
 
        state->enabled = (ret > 0);
        state->period = EC_PWM_MAX_DUTY;
+       state->polarity = PWM_POLARITY_NORMAL;
 
        /*
         * Note that "disabled" and "duty cycle == 0" are treated the same. If
index 12c05c155cab0dbeda330fa080dc9dc040c50a93..1b9274c5ad8724c0419ea172266917c6568bdf42 100644 (file)
@@ -146,6 +146,7 @@ static int hibvt_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
 
        value = readl(base + PWM_CTRL_ADDR(pwm->hwpwm));
        state->enabled = (PWM_ENABLE_MASK & value);
+       state->polarity = (PWM_POLARITY_MASK & value) ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL;
 
        return 0;
 }
index 8362b4870c66c464b7012af7cb8be349f3760dc8..47b3141135f38eccdcde2c66330a72b6000fdb0a 100644 (file)
@@ -126,6 +126,7 @@ static int iqs620_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
        mutex_unlock(&iqs620_pwm->lock);
 
        state->period = IQS620_PWM_PERIOD_NS;
+       state->polarity = PWM_POLARITY_NORMAL;
 
        return 0;
 }
index 16d79ca5d8f5395d763432ad8f15801a54e5b113..5cd7b90872c627e29fb409968df1513226cc5fb8 100644 (file)
@@ -162,6 +162,12 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
        duty = state->duty_cycle;
        period = state->period;
 
+       /*
+        * Note this is wrong. The result is an output wave that isn't really
+        * inverted and so is wrongly identified by .get_state as normal.
+        * Fixing this needs some care however as some machines might rely on
+        * this.
+        */
        if (state->polarity == PWM_POLARITY_INVERSED)
                duty = period - duty;
 
@@ -358,6 +364,8 @@ static int meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
                state->duty_cycle = 0;
        }
 
+       state->polarity = PWM_POLARITY_NORMAL;
+
        return 0;
 }
 
index d866ce345f97707e9bd5f8943d5d62723802dcb0..bde579a338c270323703e045976c9546a888b0fb 100644 (file)
@@ -109,6 +109,7 @@ static int sprd_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
        duty = val & SPRD_PWM_DUTY_MSK;
        tmp = (prescale + 1) * NSEC_PER_SEC * duty;
        state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, chn->clk_rate);
+       state->polarity = PWM_POLARITY_NORMAL;
 
        /* Disable PWM clocks if the PWM channel is not in enable state. */
        if (!state->enabled)
index 529963a7e4f52b1e84ef3e51bfb05f461f40e320..41537c45f0367dd4b0301ecb8c445925d3c858c8 100644 (file)
@@ -8,18 +8,19 @@
 // Copyright (c) 2012 Marvell Technology Ltd.
 // Yunfan Zhang <yfzhang@marvell.com>
 
+#include <linux/bits.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/param.h>
-#include <linux/err.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 #include <linux/regulator/driver.h>
+#include <linux/regulator/fan53555.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/of_regulator.h>
-#include <linux/of_device.h>
-#include <linux/i2c.h>
 #include <linux/slab.h>
-#include <linux/regmap.h>
-#include <linux/regulator/fan53555.h>
 
 /* Voltage setting */
 #define FAN53555_VSEL0         0x00
@@ -60,7 +61,7 @@
 #define TCS_VSEL1_MODE         (1 << 6)
 
 #define TCS_SLEW_SHIFT         3
-#define TCS_SLEW_MASK          (0x3 < 3)
+#define TCS_SLEW_MASK          GENMASK(4, 3)
 
 enum fan53555_vendor {
        FAN53526_VENDOR_FAIRCHILD = 0,
index 2a9867abba20c256ea4304acd301ea988b7384ba..e6724a229d2374d521f56b7f8f326a264677dcaf 100644 (file)
@@ -215,7 +215,7 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
                drvdata->enable_clock = devm_clk_get(dev, NULL);
                if (IS_ERR(drvdata->enable_clock)) {
                        dev_err(dev, "Can't get enable-clock from devicetree\n");
-                       return -ENOENT;
+                       return PTR_ERR(drvdata->enable_clock);
                }
        } else if (drvtype && drvtype->has_performance_state) {
                drvdata->desc.ops = &fixed_voltage_domain_ops;
index 05ad28fc4da8cd4222af726bf1b18c44a2c029bb..229df7170792ce25cd1d4670243a93ea1898fc81 100644 (file)
@@ -42,6 +42,7 @@ static const int sm5703_buck_voltagemap[] = {
                .type = REGULATOR_VOLTAGE,                              \
                .id = SM5703_USBLDO ## _id,                             \
                .ops = &sm5703_regulator_ops_fixed,                     \
+               .n_voltages = 1,                                        \
                .fixed_uV = SM5703_USBLDO_MICROVOLT,                    \
                .enable_reg = SM5703_REG_USBLDO12,                      \
                .enable_mask = SM5703_REG_EN_USBLDO ##_id,              \
@@ -56,6 +57,7 @@ static const int sm5703_buck_voltagemap[] = {
                .type = REGULATOR_VOLTAGE,                              \
                .id = SM5703_VBUS,                                      \
                .ops = &sm5703_regulator_ops_fixed,                     \
+               .n_voltages = 1,                                        \
                .fixed_uV = SM5703_VBUS_MICROVOLT,                      \
                .enable_reg = SM5703_REG_CNTL,                          \
                .enable_mask = SM5703_OPERATION_MODE_MASK,              \
index 997b524bdd2b5bffbd01782e970e318c6d40c013..a48c6938ae68f256744ceecce22852c8bb586e57 100644 (file)
@@ -54,8 +54,9 @@ static struct ap_driver vfio_ap_drv = {
 
 static void vfio_ap_matrix_dev_release(struct device *dev)
 {
-       struct ap_matrix_dev *matrix_dev = dev_get_drvdata(dev);
+       struct ap_matrix_dev *matrix_dev;
 
+       matrix_dev = container_of(dev, struct ap_matrix_dev, device);
        kfree(matrix_dev);
 }
 
index e300cf26bc2a8724648a16b772bf14200327de22..d698ca506ccab73d698ba28665e78a2de2f2e85b 100644 (file)
@@ -18,7 +18,7 @@
  * the recommended way for applications to use the coprocessor, and
  * the driver interface is not intended for general use.
  *
- * See Documentation/sparc/oradax/oracle-dax.rst for more details.
+ * See Documentation/arch/sparc/oradax/oracle-dax.rst for more details.
  */
 
 #include <linux/uaccess.h>
index 362fa631f39b2654ee051209826fad0ff3648c36..a226dc1b65d715f03addcf638fa52510360b1272 100644 (file)
@@ -1145,10 +1145,12 @@ static int alua_activate(struct scsi_device *sdev,
        rcu_read_unlock();
        mutex_unlock(&h->init_mutex);
 
-       if (alua_rtpg_queue(pg, sdev, qdata, true))
+       if (alua_rtpg_queue(pg, sdev, qdata, true)) {
                fn = NULL;
-       else
+       } else {
+               kfree(qdata);
                err = SCSI_DH_DEV_OFFLINED;
+       }
        kref_put(&pg->kref, release_port_group);
 out:
        if (fn)
index 0c3fcb8078062b9ad7e44c7a987076042adfabb6..a63279f55d09607488d7784d2d8666375de62c3e 100644 (file)
@@ -2495,8 +2495,7 @@ static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba)
        hisi_hba->cq_nvecs = vectors - BASE_VECTORS_V3_HW;
        shost->nr_hw_queues = hisi_hba->cq_nvecs;
 
-       devm_add_action(&pdev->dev, hisi_sas_v3_free_vectors, pdev);
-       return 0;
+       return devm_add_action(&pdev->dev, hisi_sas_v3_free_vectors, pdev);
 }
 
 static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
index f7f62e56afcae6db20711357ed93242562ddcfed..9b6fbbe15d9226a0f48c842a781e59494540f7d3 100644 (file)
@@ -341,9 +341,6 @@ static void scsi_host_dev_release(struct device *dev)
        struct Scsi_Host *shost = dev_to_shost(dev);
        struct device *parent = dev->parent;
 
-       /* In case scsi_remove_host() has not been called. */
-       scsi_proc_hostdir_rm(shost->hostt);
-
        /* Wait for functions invoked through call_rcu(&scmd->rcu, ...) */
        rcu_barrier();
 
index c76f82fb8b6361263b4be1f597d0a6048b4ec902..15f4529089262099ff7c984e7f80350136ef4ab2 100644 (file)
@@ -771,13 +771,12 @@ static int iscsi_sw_tcp_conn_set_param(struct iscsi_cls_conn *cls_conn,
                iscsi_set_param(cls_conn, param, buf, buflen);
                break;
        case ISCSI_PARAM_DATADGST_EN:
-               iscsi_set_param(cls_conn, param, buf, buflen);
-
                mutex_lock(&tcp_sw_conn->sock_lock);
                if (!tcp_sw_conn->sock) {
                        mutex_unlock(&tcp_sw_conn->sock_lock);
                        return -ENOTCONN;
                }
+               iscsi_set_param(cls_conn, param, buf, buflen);
                tcp_sw_conn->sendpage = conn->datadgst_en ?
                        sock_no_sendpage : tcp_sw_conn->sock->ops->sendpage;
                mutex_unlock(&tcp_sw_conn->sock_lock);
index 61958a24a43d9f765bef60d9f2af17bc2e20634b..4f7485958c49af72b22c88a4feb4445c1771a954 100644 (file)
@@ -7291,6 +7291,8 @@ lpfc_sli4_cgn_params_read(struct lpfc_hba *phba)
        /* Find out if the FW has a new set of congestion parameters. */
        len = sizeof(struct lpfc_cgn_param);
        pdata = kzalloc(len, GFP_KERNEL);
+       if (!pdata)
+               return -ENOMEM;
        ret = lpfc_read_object(phba, (char *)LPFC_PORT_CFG_NAME,
                               pdata, len);
 
@@ -12563,7 +12565,7 @@ lpfc_cpu_affinity_check(struct lpfc_hba *phba, int vectors)
                                        goto found_same;
                                new_cpu = cpumask_next(
                                        new_cpu, cpu_present_mask);
-                               if (new_cpu == nr_cpumask_bits)
+                               if (new_cpu >= nr_cpu_ids)
                                        new_cpu = first_cpu;
                        }
                        /* At this point, we leave the CPU as unassigned */
@@ -12577,7 +12579,7 @@ found_same:
                         * selecting the same IRQ.
                         */
                        start_cpu = cpumask_next(new_cpu, cpu_present_mask);
-                       if (start_cpu == nr_cpumask_bits)
+                       if (start_cpu >= nr_cpu_ids)
                                start_cpu = first_cpu;
 
                        lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
@@ -12613,7 +12615,7 @@ found_same:
                                        goto found_any;
                                new_cpu = cpumask_next(
                                        new_cpu, cpu_present_mask);
-                               if (new_cpu == nr_cpumask_bits)
+                               if (new_cpu >= nr_cpu_ids)
                                        new_cpu = first_cpu;
                        }
                        /* We should never leave an entry unassigned */
@@ -12631,7 +12633,7 @@ found_any:
                         * selecting the same IRQ.
                         */
                        start_cpu = cpumask_next(new_cpu, cpu_present_mask);
-                       if (start_cpu == nr_cpumask_bits)
+                       if (start_cpu >= nr_cpu_ids)
                                start_cpu = first_cpu;
 
                        lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
@@ -12704,7 +12706,7 @@ found_any:
                                goto found_hdwq;
                        }
                        new_cpu = cpumask_next(new_cpu, cpu_present_mask);
-                       if (new_cpu == nr_cpumask_bits)
+                       if (new_cpu >= nr_cpu_ids)
                                new_cpu = first_cpu;
                }
 
@@ -12719,7 +12721,7 @@ found_any:
                                goto found_hdwq;
 
                        new_cpu = cpumask_next(new_cpu, cpu_present_mask);
-                       if (new_cpu == nr_cpumask_bits)
+                       if (new_cpu >= nr_cpu_ids)
                                new_cpu = first_cpu;
                }
 
@@ -12730,7 +12732,7 @@ found_any:
  found_hdwq:
                /* We found an available entry, copy the IRQ info */
                start_cpu = cpumask_next(new_cpu, cpu_present_mask);
-               if (start_cpu == nr_cpumask_bits)
+               if (start_cpu >= nr_cpu_ids)
                        start_cpu = first_cpu;
                cpup->hdwq = new_cpup->hdwq;
  logit:
index c5b69f313af365694f77f83fb569e427f084acd4..cf630aa6734eb60fb9c9ce9de53bc3fe411e1719 100644 (file)
@@ -21899,20 +21899,20 @@ lpfc_get_io_buf_from_private_pool(struct lpfc_hba *phba,
 static struct lpfc_io_buf *
 lpfc_get_io_buf_from_expedite_pool(struct lpfc_hba *phba)
 {
-       struct lpfc_io_buf *lpfc_ncmd;
+       struct lpfc_io_buf *lpfc_ncmd = NULL, *iter;
        struct lpfc_io_buf *lpfc_ncmd_next;
        unsigned long iflag;
        struct lpfc_epd_pool *epd_pool;
 
        epd_pool = &phba->epd_pool;
-       lpfc_ncmd = NULL;
 
        spin_lock_irqsave(&epd_pool->lock, iflag);
        if (epd_pool->count > 0) {
-               list_for_each_entry_safe(lpfc_ncmd, lpfc_ncmd_next,
+               list_for_each_entry_safe(iter, lpfc_ncmd_next,
                                         &epd_pool->list, list) {
-                       list_del(&lpfc_ncmd->list);
+                       list_del(&iter->list);
                        epd_pool->count--;
+                       lpfc_ncmd = iter;
                        break;
                }
        }
@@ -22109,10 +22109,6 @@ lpfc_read_object(struct lpfc_hba *phba, char *rdobject, uint32_t *datap,
        struct lpfc_dmabuf *pcmd;
        u32 rd_object_name[LPFC_MBX_OBJECT_NAME_LEN_DW] = {0};
 
-       /* sanity check on queue memory */
-       if (!datap)
-               return -ENODEV;
-
        mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
        if (!mbox)
                return -ENOMEM;
index 4919ea54b8277b9c847d40107b501a759fa02037..63bac3684c197ddf7b20a3844d429cb77c838a8c 100644 (file)
@@ -23,8 +23,8 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION                                "07.719.03.00-rc1"
-#define MEGASAS_RELDATE                                "Sep 29, 2021"
+#define MEGASAS_VERSION                                "07.725.01.00-rc1"
+#define MEGASAS_RELDATE                                "Mar 2, 2023"
 
 #define MEGASAS_MSIX_NAME_LEN                  32
 
@@ -1519,6 +1519,8 @@ struct megasas_ctrl_info {
 #define MEGASAS_MAX_LD_IDS                     (MEGASAS_MAX_LD_CHANNELS * \
                                                MEGASAS_MAX_DEV_PER_CHANNEL)
 
+#define MEGASAS_MAX_SUPPORTED_LD_IDS           240
+
 #define MEGASAS_MAX_SECTORS                    (2*1024)
 #define MEGASAS_MAX_SECTORS_IEEE               (2*128)
 #define MEGASAS_DBG_LVL                                1
@@ -1758,7 +1760,8 @@ union megasas_sgl_frame {
 typedef union _MFI_CAPABILITIES {
        struct {
 #if   defined(__BIG_ENDIAN_BITFIELD)
-       u32     reserved:16;
+       u32     reserved:15;
+       u32     support_memdump:1;
        u32     support_fw_exposed_dev_list:1;
        u32     support_nvme_passthru:1;
        u32     support_64bit_mode:1;
@@ -1792,7 +1795,8 @@ typedef union _MFI_CAPABILITIES {
        u32     support_64bit_mode:1;
        u32     support_nvme_passthru:1;
        u32     support_fw_exposed_dev_list:1;
-       u32     reserved:16;
+       u32     support_memdump:1;
+       u32     reserved:15;
 #endif
        } mfi_capabilities;
        __le32          reg;
index 3ceece9883383b78969fac6c87bcca3bbd5a61b1..c895189375e2b6afc5c2616c9934ba9b334bdb59 100644 (file)
@@ -3298,7 +3298,7 @@ fw_crash_buffer_show(struct device *cdev,
 
        spin_lock_irqsave(&instance->crashdump_lock, flags);
        buff_offset = instance->fw_crash_buffer_offset;
-       if (!instance->crash_dump_buf &&
+       if (!instance->crash_dump_buf ||
                !((instance->fw_crash_state == AVAILABLE) ||
                (instance->fw_crash_state == COPYING))) {
                dev_err(&instance->pdev->dev,
index da1cad1ee12389053fec297e2f9da723d2145fb6..4463a538102ad6d7fb1b1d266ae8a3273d38a173 100644 (file)
@@ -358,7 +358,7 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance, u64 map_id)
                ld = MR_TargetIdToLdGet(i, drv_map);
 
                /* For non existing VDs, iterate to next VD*/
-               if (ld >= (MAX_LOGICAL_DRIVES_EXT - 1))
+               if (ld >= MEGASAS_MAX_SUPPORTED_LD_IDS)
                        continue;
 
                raid = MR_LdRaidGet(ld, drv_map);
index 6597e118c805af60de2155266b00391f470e4539..8a83f3fc2b865e7c6a430168c86b2f5fb5c5822e 100644 (file)
@@ -1201,6 +1201,9 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
        drv_ops->mfi_capabilities.support_nvme_passthru = 1;
        drv_ops->mfi_capabilities.support_fw_exposed_dev_list = 1;
 
+       if (reset_devices)
+               drv_ops->mfi_capabilities.support_memdump = 1;
+
        if (instance->consistent_mask_64bit)
                drv_ops->mfi_capabilities.support_64bit_mode = 1;
 
@@ -4768,7 +4771,7 @@ int megasas_task_abort_fusion(struct scsi_cmnd *scmd)
        devhandle = megasas_get_tm_devhandle(scmd->device);
 
        if (devhandle == (u16)ULONG_MAX) {
-               ret = SUCCESS;
+               ret = FAILED;
                sdev_printk(KERN_INFO, scmd->device,
                        "task abort issued for invalid devhandle\n");
                mutex_unlock(&instance->reset_mutex);
@@ -4838,7 +4841,7 @@ int megasas_reset_target_fusion(struct scsi_cmnd *scmd)
        devhandle = megasas_get_tm_devhandle(scmd->device);
 
        if (devhandle == (u16)ULONG_MAX) {
-               ret = SUCCESS;
+               ret = FAILED;
                sdev_printk(KERN_INFO, scmd->device,
                        "target reset issued for invalid devhandle\n");
                mutex_unlock(&instance->reset_mutex);
index 23de2603e71fdd3736ceef7ca1d5fb1b91d35240..364fb1b5e45ace6cd4c5e5aa3ddcc706dee47063 100644 (file)
@@ -902,6 +902,7 @@ struct scmd_priv {
  * @admin_reply_ephase:Admin reply queue expected phase
  * @admin_reply_base: Admin reply queue base virtual address
  * @admin_reply_dma: Admin reply queue base dma address
+ * @admin_reply_q_in_use: Queue is handled by poll/ISR
  * @ready_timeout: Controller ready timeout
  * @intr_info: Interrupt cookie pointer
  * @intr_info_count: Number of interrupt cookies
@@ -1055,6 +1056,7 @@ struct mpi3mr_ioc {
        u8 admin_reply_ephase;
        void *admin_reply_base;
        dma_addr_t admin_reply_dma;
+       atomic_t admin_reply_q_in_use;
 
        u32 ready_timeout;
 
@@ -1390,4 +1392,7 @@ void mpi3mr_add_event_wait_for_device_refresh(struct mpi3mr_ioc *mrioc);
 void mpi3mr_flush_drv_cmds(struct mpi3mr_ioc *mrioc);
 void mpi3mr_flush_cmds_for_unrecovered_controller(struct mpi3mr_ioc *mrioc);
 void mpi3mr_free_enclosure_list(struct mpi3mr_ioc *mrioc);
+int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc);
+void mpi3mr_expander_node_remove(struct mpi3mr_ioc *mrioc,
+       struct mpi3mr_sas_node *sas_expander);
 #endif /*MPI3MR_H_INCLUDED*/
index bff63770239797ce2e9a5e6be4c3d82281d42c14..d10c6afb7f9cdafdd7f2120f552597b88161014f 100644 (file)
@@ -886,7 +886,7 @@ static int mpi3mr_build_nvme_prp(struct mpi3mr_ioc *mrioc,
                         * each time through the loop.
                         */
                        *prp_entry = cpu_to_le64(dma_addr);
-                       if (*prp1_entry & sgemod_mask) {
+                       if (*prp_entry & sgemod_mask) {
                                dprint_bsg_err(mrioc,
                                    "%s: PRP address collides with SGE modifier\n",
                                    __func__);
@@ -895,7 +895,7 @@ static int mpi3mr_build_nvme_prp(struct mpi3mr_ioc *mrioc,
                        *prp_entry &= ~sgemod_mask;
                        *prp_entry |= sgemod_val;
                        prp_entry++;
-                       prp_entry_dma++;
+                       prp_entry_dma += prp_size;
                }
 
                /*
index 758f7ca9e0ee803bad899d35fef7bbd04b222f69..d109a4ceb72b1bef3cd165585dc7863c41d5df69 100644 (file)
@@ -415,7 +415,7 @@ out:
                    le64_to_cpu(scsi_reply->sense_data_buffer_address));
 }
 
-static int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc)
+int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc)
 {
        u32 exp_phase = mrioc->admin_reply_ephase;
        u32 admin_reply_ci = mrioc->admin_reply_ci;
@@ -423,12 +423,17 @@ static int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc)
        u64 reply_dma = 0;
        struct mpi3_default_reply_descriptor *reply_desc;
 
+       if (!atomic_add_unless(&mrioc->admin_reply_q_in_use, 1, 1))
+               return 0;
+
        reply_desc = (struct mpi3_default_reply_descriptor *)mrioc->admin_reply_base +
            admin_reply_ci;
 
        if ((le16_to_cpu(reply_desc->reply_flags) &
-           MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase)
+           MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase) {
+               atomic_dec(&mrioc->admin_reply_q_in_use);
                return 0;
+       }
 
        do {
                if (mrioc->unrecoverable)
@@ -454,6 +459,7 @@ static int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc)
        writel(admin_reply_ci, &mrioc->sysif_regs->admin_reply_queue_ci);
        mrioc->admin_reply_ci = admin_reply_ci;
        mrioc->admin_reply_ephase = exp_phase;
+       atomic_dec(&mrioc->admin_reply_q_in_use);
 
        return num_admin_replies;
 }
@@ -1192,7 +1198,7 @@ mpi3mr_revalidate_factsdata(struct mpi3mr_ioc *mrioc)
  */
 static int mpi3mr_bring_ioc_ready(struct mpi3mr_ioc *mrioc)
 {
-       u32 ioc_config, ioc_status, timeout;
+       u32 ioc_config, ioc_status, timeout, host_diagnostic;
        int retval = 0;
        enum mpi3mr_iocstate ioc_state;
        u64 base_info;
@@ -1246,6 +1252,23 @@ static int mpi3mr_bring_ioc_ready(struct mpi3mr_ioc *mrioc)
                            retval, mpi3mr_iocstate_name(ioc_state));
        }
        if (ioc_state != MRIOC_STATE_RESET) {
+               if (ioc_state == MRIOC_STATE_FAULT) {
+                       timeout = MPI3_SYSIF_DIAG_SAVE_TIMEOUT * 10;
+                       mpi3mr_print_fault_info(mrioc);
+                       do {
+                               host_diagnostic =
+                                       readl(&mrioc->sysif_regs->host_diagnostic);
+                               if (!(host_diagnostic &
+                                     MPI3_SYSIF_HOST_DIAG_SAVE_IN_PROGRESS))
+                                       break;
+                               if (!pci_device_is_present(mrioc->pdev)) {
+                                       mrioc->unrecoverable = 1;
+                                       ioc_err(mrioc, "controller is not present at the bringup\n");
+                                       goto out_device_not_present;
+                               }
+                               msleep(100);
+                       } while (--timeout);
+               }
                mpi3mr_print_fault_info(mrioc);
                ioc_info(mrioc, "issuing soft reset to bring to reset state\n");
                retval = mpi3mr_issue_reset(mrioc,
@@ -2503,7 +2526,7 @@ static void mpi3mr_watchdog_work(struct work_struct *work)
                mrioc->unrecoverable = 1;
                goto schedule_work;
        case MPI3_SYSIF_FAULT_CODE_SOFT_RESET_IN_PROGRESS:
-               return;
+               goto schedule_work;
        case MPI3_SYSIF_FAULT_CODE_CI_ACTIVATION_RESET:
                reset_reason = MPI3MR_RESET_FROM_CIACTIV_FAULT;
                break;
@@ -2605,6 +2628,7 @@ static int mpi3mr_setup_admin_qpair(struct mpi3mr_ioc *mrioc)
        mrioc->admin_reply_ci = 0;
        mrioc->admin_reply_ephase = 1;
        mrioc->admin_reply_base = NULL;
+       atomic_set(&mrioc->admin_reply_q_in_use, 0);
 
        if (!mrioc->admin_req_base) {
                mrioc->admin_req_base = dma_alloc_coherent(&mrioc->pdev->dev,
@@ -3813,27 +3837,34 @@ retry_init:
 
        mpi3mr_print_ioc_info(mrioc);
 
-       dprint_init(mrioc, "allocating config page buffers\n");
-       mrioc->cfg_page = dma_alloc_coherent(&mrioc->pdev->dev,
-           MPI3MR_DEFAULT_CFG_PAGE_SZ, &mrioc->cfg_page_dma, GFP_KERNEL);
-       if (!mrioc->cfg_page)
-               goto out_failed_noretry;
-
-       mrioc->cfg_page_sz = MPI3MR_DEFAULT_CFG_PAGE_SZ;
+       if (!mrioc->cfg_page) {
+               dprint_init(mrioc, "allocating config page buffers\n");
+               mrioc->cfg_page_sz = MPI3MR_DEFAULT_CFG_PAGE_SZ;
+               mrioc->cfg_page = dma_alloc_coherent(&mrioc->pdev->dev,
+                   mrioc->cfg_page_sz, &mrioc->cfg_page_dma, GFP_KERNEL);
+               if (!mrioc->cfg_page) {
+                       retval = -1;
+                       goto out_failed_noretry;
+               }
+       }
 
-       retval = mpi3mr_alloc_reply_sense_bufs(mrioc);
-       if (retval) {
-               ioc_err(mrioc,
-                   "%s :Failed to allocated reply sense buffers %d\n",
-                   __func__, retval);
-               goto out_failed_noretry;
+       if (!mrioc->init_cmds.reply) {
+               retval = mpi3mr_alloc_reply_sense_bufs(mrioc);
+               if (retval) {
+                       ioc_err(mrioc,
+                           "%s :Failed to allocated reply sense buffers %d\n",
+                           __func__, retval);
+                       goto out_failed_noretry;
+               }
        }
 
-       retval = mpi3mr_alloc_chain_bufs(mrioc);
-       if (retval) {
-               ioc_err(mrioc, "Failed to allocated chain buffers %d\n",
-                   retval);
-               goto out_failed_noretry;
+       if (!mrioc->chain_sgl_list) {
+               retval = mpi3mr_alloc_chain_bufs(mrioc);
+               if (retval) {
+                       ioc_err(mrioc, "Failed to allocated chain buffers %d\n",
+                           retval);
+                       goto out_failed_noretry;
+               }
        }
 
        retval = mpi3mr_issue_iocinit(mrioc);
@@ -3879,8 +3910,10 @@ retry_init:
                dprint_init(mrioc, "allocating memory for throttle groups\n");
                sz = sizeof(struct mpi3mr_throttle_group_info);
                mrioc->throttle_groups = kcalloc(mrioc->num_io_throttle_group, sz, GFP_KERNEL);
-               if (!mrioc->throttle_groups)
+               if (!mrioc->throttle_groups) {
+                       retval = -1;
                        goto out_failed_noretry;
+               }
        }
 
        retval = mpi3mr_enable_events(mrioc);
@@ -3900,6 +3933,7 @@ out_failed:
                mpi3mr_memset_buffers(mrioc);
                goto retry_init;
        }
+       retval = -1;
 out_failed_noretry:
        ioc_err(mrioc, "controller initialization failed\n");
        mpi3mr_issue_reset(mrioc, MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT,
@@ -4012,6 +4046,7 @@ retry_init:
                ioc_err(mrioc,
                    "cannot create minimum number of operational queues expected:%d created:%d\n",
                    mrioc->shost->nr_hw_queues, mrioc->num_op_reply_q);
+               retval = -1;
                goto out_failed_noretry;
        }
 
@@ -4078,6 +4113,7 @@ out_failed:
                mpi3mr_memset_buffers(mrioc);
                goto retry_init;
        }
+       retval = -1;
 out_failed_noretry:
        ioc_err(mrioc, "controller %s is failed\n",
            (is_resume)?"resume":"re-initialization");
@@ -4155,6 +4191,7 @@ void mpi3mr_memset_buffers(struct mpi3mr_ioc *mrioc)
                memset(mrioc->admin_req_base, 0, mrioc->admin_req_q_sz);
        if (mrioc->admin_reply_base)
                memset(mrioc->admin_reply_base, 0, mrioc->admin_reply_q_sz);
+       atomic_set(&mrioc->admin_reply_q_in_use, 0);
 
        if (mrioc->init_cmds.reply) {
                memset(mrioc->init_cmds.reply, 0, sizeof(*mrioc->init_cmds.reply));
@@ -4350,13 +4387,20 @@ void mpi3mr_free_mem(struct mpi3mr_ioc *mrioc)
                    mrioc->admin_req_base, mrioc->admin_req_dma);
                mrioc->admin_req_base = NULL;
        }
-
+       if (mrioc->cfg_page) {
+               dma_free_coherent(&mrioc->pdev->dev, mrioc->cfg_page_sz,
+                   mrioc->cfg_page, mrioc->cfg_page_dma);
+               mrioc->cfg_page = NULL;
+       }
        if (mrioc->pel_seqnum_virt) {
                dma_free_coherent(&mrioc->pdev->dev, mrioc->pel_seqnum_sz,
                    mrioc->pel_seqnum_virt, mrioc->pel_seqnum_dma);
                mrioc->pel_seqnum_virt = NULL;
        }
 
+       kfree(mrioc->throttle_groups);
+       mrioc->throttle_groups = NULL;
+
        kfree(mrioc->logdata_buf);
        mrioc->logdata_buf = NULL;
 
index 6eaeba41072cb53e4ff2354fa4241815b2c7a24c..6d55698ea4d16c9ca22c6ca136e18ca7be2977d0 100644 (file)
@@ -3720,6 +3720,7 @@ int mpi3mr_issue_tm(struct mpi3mr_ioc *mrioc, u8 tm_type,
                mpi3mr_poll_pend_io_completions(mrioc);
                mpi3mr_ioc_enable_intr(mrioc);
                mpi3mr_poll_pend_io_completions(mrioc);
+               mpi3mr_process_admin_reply_q(mrioc);
        }
        switch (tm_type) {
        case MPI3_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
@@ -5077,6 +5078,8 @@ static void mpi3mr_remove(struct pci_dev *pdev)
        struct workqueue_struct *wq;
        unsigned long flags;
        struct mpi3mr_tgt_dev *tgtdev, *tgtdev_next;
+       struct mpi3mr_hba_port *port, *hba_port_next;
+       struct mpi3mr_sas_node *sas_expander, *sas_expander_next;
 
        if (!shost)
                return;
@@ -5116,6 +5119,28 @@ static void mpi3mr_remove(struct pci_dev *pdev)
        mpi3mr_free_mem(mrioc);
        mpi3mr_cleanup_resources(mrioc);
 
+       spin_lock_irqsave(&mrioc->sas_node_lock, flags);
+       list_for_each_entry_safe_reverse(sas_expander, sas_expander_next,
+           &mrioc->sas_expander_list, list) {
+               spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);
+               mpi3mr_expander_node_remove(mrioc, sas_expander);
+               spin_lock_irqsave(&mrioc->sas_node_lock, flags);
+       }
+       list_for_each_entry_safe(port, hba_port_next, &mrioc->hba_port_table_list, list) {
+               ioc_info(mrioc,
+                   "removing hba_port entry: %p port: %d from hba_port list\n",
+                   port, port->port_id);
+               list_del(&port->list);
+               kfree(port);
+       }
+       spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);
+
+       if (mrioc->sas_hba.num_phys) {
+               kfree(mrioc->sas_hba.phy);
+               mrioc->sas_hba.phy = NULL;
+               mrioc->sas_hba.num_phys = 0;
+       }
+
        spin_lock(&mrioc_list_lock);
        list_del(&mrioc->list);
        spin_unlock(&mrioc_list_lock);
index 3b61815979dabe5c9a1113a410f34e3333905229..5748bd9369ff78495085f15595b4c580742cdd67 100644 (file)
@@ -9,9 +9,6 @@
 
 #include "mpi3mr.h"
 
-static void mpi3mr_expander_node_remove(struct mpi3mr_ioc *mrioc,
-       struct mpi3mr_sas_node *sas_expander);
-
 /**
  * mpi3mr_post_transport_req - Issue transport requests and wait
  * @mrioc: Adapter instance reference
@@ -1552,7 +1549,8 @@ static void mpi3mr_sas_port_remove(struct mpi3mr_ioc *mrioc, u64 sas_address,
 
        list_for_each_entry_safe(mr_sas_phy, next_phy,
            &mr_sas_port->phy_list, port_siblings) {
-               if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO))
+               if ((!mrioc->stop_drv_processing) &&
+                   (mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO))
                        dev_info(&mr_sas_port->port->dev,
                            "remove: sas_address(0x%016llx), phy(%d)\n",
                            (unsigned long long)
@@ -2163,7 +2161,7 @@ out_fail:
  *
  * Return nothing.
  */
-static void mpi3mr_expander_node_remove(struct mpi3mr_ioc *mrioc,
+void mpi3mr_expander_node_remove(struct mpi3mr_ioc *mrioc,
        struct mpi3mr_sas_node *sas_expander)
 {
        struct mpi3mr_sas_port *mr_sas_port, *next;
@@ -2357,15 +2355,16 @@ int mpi3mr_report_tgtdev_to_sas_transport(struct mpi3mr_ioc *mrioc,
        tgtdev->host_exposed = 1;
        if (!mpi3mr_sas_port_add(mrioc, tgtdev->dev_handle,
            sas_address_parent, hba_port)) {
-               tgtdev->host_exposed = 0;
                retval = -1;
-       } else if ((!tgtdev->starget)) {
-               if (!mrioc->is_driver_loading)
+               } else if ((!tgtdev->starget) && (!mrioc->is_driver_loading)) {
                        mpi3mr_sas_port_remove(mrioc, sas_address,
                            sas_address_parent, hba_port);
-               tgtdev->host_exposed = 0;
                retval = -1;
        }
+       if (retval) {
+               tgtdev->dev_spec.sas_sata_inf.hba_port = NULL;
+               tgtdev->host_exposed = 0;
+       }
        return retval;
 }
 
@@ -2394,6 +2393,7 @@ void mpi3mr_remove_tgtdev_from_sas_transport(struct mpi3mr_ioc *mrioc,
        mpi3mr_sas_port_remove(mrioc, sas_address, sas_address_parent,
            hba_port);
        tgtdev->host_exposed = 0;
+       tgtdev->dev_spec.sas_sata_inf.hba_port = NULL;
 }
 
 /**
@@ -2450,7 +2450,7 @@ static u8 mpi3mr_get_port_id_by_rphy(struct mpi3mr_ioc *mrioc, struct sas_rphy *
 
                tgtdev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc,
                            rphy->identify.sas_address, rphy);
-               if (tgtdev) {
+               if (tgtdev && tgtdev->dev_spec.sas_sata_inf.hba_port) {
                        port_id =
                                tgtdev->dev_spec.sas_sata_inf.hba_port->port_id;
                        mpi3mr_tgtdev_put(tgtdev);
index 2ee9ea57554d70a1b04f65962052d87c9eaf920b..14ae0a9c5d3d84e20ca5a030638937c07789cd51 100644 (file)
@@ -6616,11 +6616,6 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
        else if (rc == -EAGAIN)
                goto try_32bit_dma;
        total_sz += sense_sz;
-       ioc_info(ioc,
-           "sense pool(0x%p)- dma(0x%llx): depth(%d),"
-           "element_size(%d), pool_size(%d kB)\n",
-           ioc->sense, (unsigned long long)ioc->sense_dma, ioc->scsiio_depth,
-           SCSI_SENSE_BUFFERSIZE, sz / 1024);
        /* reply pool, 4 byte align */
        sz = ioc->reply_free_queue_depth * ioc->reply_sz;
        rc = _base_allocate_reply_pool(ioc, sz);
index e5ecd6ada6cdd851e833fce012d1e6f987bc3c3d..e8a4750f6ec473bd6e41385fa2c920179e0c4ba5 100644 (file)
@@ -785,7 +785,7 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
                goto out_fail;
        }
        port = sas_port_alloc_num(sas_node->parent_dev);
-       if ((sas_port_add(port))) {
+       if (!port || (sas_port_add(port))) {
                ioc_err(ioc, "failure at %s:%d/%s()!\n",
                        __FILE__, __LINE__, __func__);
                goto out_fail;
@@ -824,6 +824,12 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
                            mpt3sas_port->remote_identify.sas_address;
        }
 
+       if (!rphy) {
+               ioc_err(ioc, "failure at %s:%d/%s()!\n",
+                       __FILE__, __LINE__, __func__);
+               goto out_delete_port;
+       }
+
        rphy->identify = mpt3sas_port->remote_identify;
 
        if ((sas_rphy_add(rphy))) {
@@ -831,6 +837,7 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
                        __FILE__, __LINE__, __func__);
                sas_rphy_free(rphy);
                rphy = NULL;
+               goto out_delete_port;
        }
 
        if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
@@ -857,7 +864,10 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
                    rphy_to_expander_device(rphy), hba_port->port_id);
        return mpt3sas_port;
 
- out_fail:
+out_delete_port:
+       sas_port_delete(port);
+
+out_fail:
        list_for_each_entry_safe(mpt3sas_phy, next, &mpt3sas_port->phy_list,
            port_siblings)
                list_del(&mpt3sas_phy->port_siblings);
index 9142df876c733451dd62a2d06723f4b8ffc8705a..9aba07c7bde4b142a0ab1f91fa5c9369daec0804 100644 (file)
@@ -192,6 +192,7 @@ extern int ql2xsecenable;
 extern int ql2xenforce_iocb_limit;
 extern int ql2xabts_wait_nvme;
 extern u32 ql2xnvme_queues;
+extern int ql2xfc2target;
 
 extern int qla2x00_loop_reset(scsi_qla_host_t *);
 extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
index 1dbc1496ebeddf9cf1458e5e30b79ba07954b858..ec0423ec66817c1a54ea00d508aeaccc02def258 100644 (file)
@@ -1840,7 +1840,8 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
        case RSCN_PORT_ADDR:
                fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1);
                if (fcport) {
-                       if (fcport->flags & FCF_FCP2_DEVICE &&
+                       if (ql2xfc2target &&
+                           fcport->flags & FCF_FCP2_DEVICE &&
                            atomic_read(&fcport->state) == FCS_ONLINE) {
                                ql_dbg(ql_dbg_disc, vha, 0x2115,
                                       "Delaying session delete for FCP2 portid=%06x %8phC ",
index 030625ebb4e653a0da4df20f62751f4926332354..71feda2cdb63046a713c5018ae64948abed1084f 100644 (file)
@@ -1900,6 +1900,8 @@ qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func,
        }
 
        req->outstanding_cmds[index] = NULL;
+
+       qla_put_fw_resources(sp->qpair, &sp->iores);
        return sp;
 }
 
@@ -3112,7 +3114,6 @@ qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
        }
        bsg_reply->reply_payload_rcv_len = 0;
 
-       qla_put_fw_resources(sp->qpair, &sp->iores);
 done:
        /* Return the vendor specific reply to API */
        bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
index 545167627e48e9fd171adaf54cbbd716fc0e68e3..d0cdbfe771a9cd09bf5c482cb96a35dba10ca366 100644 (file)
@@ -360,6 +360,13 @@ MODULE_PARM_DESC(ql2xnvme_queues,
        "1 - Minimum number of queues supported\n"
        "8 - Default value");
 
+int ql2xfc2target = 1;
+module_param(ql2xfc2target, int, 0444);
+MODULE_PARM_DESC(qla2xfc2target,
+                 "Enables FC2 Target support. "
+                 "0 - FC2 Target support is disabled. "
+                 "1 - FC2 Target support is enabled (default).");
+
 static struct scsi_transport_template *qla2xxx_transport_template = NULL;
 struct scsi_transport_template *qla2xxx_transport_vport_template = NULL;
 
@@ -1858,6 +1865,17 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res)
        for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
                sp = req->outstanding_cmds[cnt];
                if (sp) {
+                       /*
+                        * perform lockless completion during driver unload
+                        */
+                       if (qla2x00_chip_is_down(vha)) {
+                               req->outstanding_cmds[cnt] = NULL;
+                               spin_unlock_irqrestore(qp->qp_lock_ptr, flags);
+                               sp->done(sp, res);
+                               spin_lock_irqsave(qp->qp_lock_ptr, flags);
+                               continue;
+                       }
+
                        switch (sp->cmd_type) {
                        case TYPE_SRB:
                                qla2x00_abort_srb(qp, sp, res, &flags);
@@ -3599,6 +3617,7 @@ skip_dpc:
 probe_failed:
        qla_enode_stop(base_vha);
        qla_edb_stop(base_vha);
+       vfree(base_vha->scan.l);
        if (base_vha->gnl.l) {
                dma_free_coherent(&ha->pdev->dev, base_vha->gnl.size,
                                base_vha->gnl.l, base_vha->gnl.ldma);
@@ -4085,7 +4104,8 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha)
            "Mark all dev lost\n");
 
        list_for_each_entry(fcport, &vha->vp_fcports, list) {
-               if (fcport->loop_id != FC_NO_LOOP_ID &&
+               if (ql2xfc2target &&
+                   fcport->loop_id != FC_NO_LOOP_ID &&
                    (fcport->flags & FCF_FCP2_DEVICE) &&
                    fcport->port_type == FCT_TARGET &&
                    !qla2x00_reset_active(vha)) {
index 7d2210a006f0d44b1c71233e0bc8d684ec4f77ae..09ef0b31dfc09c5d9950bf458c4ae8758862358e 100644 (file)
@@ -314,11 +314,18 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer,
        if (result)
                return -EIO;
 
-       /* Sanity check that we got the page back that we asked for */
+       /*
+        * Sanity check that we got the page back that we asked for and that
+        * the page size is not 0.
+        */
        if (buffer[1] != page)
                return -EIO;
 
-       return get_unaligned_be16(&buffer[2]) + 4;
+       result = get_unaligned_be16(&buffer[2]);
+       if (!result)
+               return -EIO;
+
+       return result + 4;
 }
 
 static int scsi_get_vpd_size(struct scsi_device *sdev, u8 page)
@@ -326,6 +333,9 @@ static int scsi_get_vpd_size(struct scsi_device *sdev, u8 page)
        unsigned char vpd_header[SCSI_VPD_HEADER_SIZE] __aligned(4);
        int result;
 
+       if (sdev->no_vpd_size)
+               return SCSI_DEFAULT_VPD_LEN;
+
        /*
         * Fetch the VPD page header to find out how big the page
         * is. This is done to prevent problems on legacy devices
index c7080454aea997a66202badf18fbfe383c42f32b..3fcaf10a9dfe76daa651db71c9a2f0f6b1bbd1b0 100644 (file)
@@ -134,7 +134,7 @@ static struct {
        {"3PARdata", "VV", NULL, BLIST_REPORTLUN2},
        {"ADAPTEC", "AACRAID", NULL, BLIST_FORCELUN},
        {"ADAPTEC", "Adaptec 5400S", NULL, BLIST_FORCELUN},
-       {"AIX", "VDASD", NULL, BLIST_TRY_VPD_PAGES},
+       {"AIX", "VDASD", NULL, BLIST_TRY_VPD_PAGES | BLIST_NO_VPD_SIZE},
        {"AFT PRO", "-IX CF", "0.0>", BLIST_FORCELUN},
        {"BELKIN", "USB 2 HS-CF", "1.95",  BLIST_FORCELUN | BLIST_INQUIRY_36},
        {"BROWNIE", "1200U3P", NULL, BLIST_NOREPORTLUN},
@@ -188,6 +188,7 @@ static struct {
        {"HPE", "OPEN-", "*", BLIST_REPORTLUN2 | BLIST_TRY_VPD_PAGES},
        {"IBM", "AuSaV1S2", NULL, BLIST_FORCELUN},
        {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+       {"IBM", "2076", NULL, BLIST_NO_VPD_SIZE},
        {"IBM", "2105", NULL, BLIST_RETRY_HWERROR},
        {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN},
        {"IOMEGA", "ZIP", NULL, BLIST_NOTQ | BLIST_NOLUN},
@@ -233,6 +234,7 @@ static struct {
        {"SGI", "RAID5", "*", BLIST_SPARSELUN},
        {"SGI", "TP9100", "*", BLIST_REPORTLUN2},
        {"SGI", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
+       {"SKhynix", "H28U74301AMR", NULL, BLIST_SKIP_VPD_PAGES},
        {"IBM", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
        {"SUN", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
        {"DELL", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
index 4e842d79de317c2e7ed5a54e45f1fd32aa07b908..d217be323cc690f0736df29349d085bd27575170 100644 (file)
@@ -1057,6 +1057,9 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
        else if (*bflags & BLIST_SKIP_VPD_PAGES)
                sdev->skip_vpd_pages = 1;
 
+       if (*bflags & BLIST_NO_VPD_SIZE)
+               sdev->no_vpd_size = 1;
+
        transport_configure_device(&sdev->sdev_gendev);
 
        if (sdev->host->hostt->slave_configure) {
index 4f28dd617ecadaa5636adde4b892834df7cfb1a1..4bb87043e6dba2bd477b34f35a43602c13fe575f 100644 (file)
@@ -2988,8 +2988,13 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp)
        }
 
        if (sdkp->device->type == TYPE_ZBC) {
-               /* Host-managed */
+               /*
+                * Host-managed: Per ZBC and ZAC specifications, writes in
+                * sequential write required zones of host-managed devices must
+                * be aligned to the device physical block size.
+                */
                disk_set_zoned(sdkp->disk, BLK_ZONED_HM);
+               blk_queue_zone_write_granularity(q, sdkp->physical_block_size);
        } else {
                sdkp->zoned = zoned;
                if (sdkp->zoned == 1) {
index 6b3a02d4406c08614ea2fbcbe508a43c4de7ed54..22801c24ea193c795a014a168d0df213a993fdad 100644 (file)
@@ -965,14 +965,6 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE])
        disk_set_max_active_zones(disk, 0);
        nr_zones = round_up(sdkp->capacity, zone_blocks) >> ilog2(zone_blocks);
 
-       /*
-        * Per ZBC and ZAC specifications, writes in sequential write required
-        * zones of host-managed devices must be aligned to the device physical
-        * block size.
-        */
-       if (blk_queue_zoned_model(q) == BLK_ZONED_HM)
-               blk_queue_zone_write_granularity(q, sdkp->physical_block_size);
-
        sdkp->early_zone_info.nr_zones = nr_zones;
        sdkp->early_zone_info.zone_blocks = zone_blocks;
 
index b11a9162e73aaeed994667a3ba04f2fa59cae240..b54f2c6c08c362799e31141b9abbaf3a4667ed71 100644 (file)
@@ -509,9 +509,6 @@ static int ses_enclosure_find_by_addr(struct enclosure_device *edev,
        int i;
        struct ses_component *scomp;
 
-       if (!edev->component[0].scratch)
-               return 0;
-
        for (i = 0; i < edev->components; i++) {
                scomp = edev->component[i].scratch;
                if (scomp->addr != efd->addr)
@@ -602,8 +599,10 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
                                                components++,
                                                type_ptr[0],
                                                name);
-                               else
+                               else if (components < edev->components)
                                        ecomp = &edev->component[components++];
+                               else
+                                       ecomp = ERR_PTR(-EINVAL);
 
                                if (!IS_ERR(ecomp)) {
                                        if (addl_desc_ptr) {
@@ -734,11 +733,6 @@ static int ses_intf_add(struct device *cdev,
                        components += type_ptr[1];
        }
 
-       if (components == 0) {
-               sdev_printk(KERN_WARNING, sdev, "enclosure has no enumerated components\n");
-               goto err_free;
-       }
-
        ses_dev->page1 = buf;
        ses_dev->page1_len = len;
        buf = NULL;
@@ -780,9 +774,11 @@ static int ses_intf_add(struct device *cdev,
                buf = NULL;
        }
 page2_not_supported:
-       scomp = kcalloc(components, sizeof(struct ses_component), GFP_KERNEL);
-       if (!scomp)
-               goto err_free;
+       if (components > 0) {
+               scomp = kcalloc(components, sizeof(struct ses_component), GFP_KERNEL);
+               if (!scomp)
+                       goto err_free;
+       }
 
        edev = enclosure_register(cdev->parent, dev_name(&sdev->sdev_gendev),
                                  components, &ses_enclosure_callbacks);
index 33f568b7f54dee409a06238502e73e77553b034c..d9ce379c4d2e836476a04a724622d80a0a85a36a 100644 (file)
@@ -987,6 +987,22 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
                                goto do_work;
                        }
 
+                       /*
+                        * Check for "Operating parameters have changed"
+                        * due to Hyper-V changing the VHD/VHDX BlockSize
+                        * when adding/removing a differencing disk. This
+                        * causes discard_granularity to change, so do a
+                        * rescan to pick up the new granularity. We don't
+                        * want scsi_report_sense() to output a message
+                        * that a sysadmin wouldn't know what to do with.
+                        */
+                       if ((asc == 0x3f) && (ascq != 0x03) &&
+                                       (ascq != 0x0e)) {
+                               process_err_fn = storvsc_device_scan;
+                               set_host_byte(scmnd, DID_REQUEUE);
+                               goto do_work;
+                       }
+
                        /*
                         * Otherwise, let upper layer deal with the
                         * error when sense message is present
index 23ce2f78c4ed4c5e003e3ffeb022e1a1e20a0f1e..26efe12012a0da443ddd21586c03b56381ed1050 100644 (file)
@@ -191,9 +191,9 @@ static const struct llcc_slice_config sc8280xp_data[] = {
        { LLCC_CVP,      28, 512,  3, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },
        { LLCC_APTCM,    30, 1024, 3, 1, 0x0,   0x1, 1, 0, 0, 1, 0, 0 },
        { LLCC_WRCACHE,  31, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },
-       { LLCC_CVPFW,    32, 512,  1, 0, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },
-       { LLCC_CPUSS1,   33, 2048, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },
-       { LLCC_CPUHWT,   36, 512,  1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },
+       { LLCC_CVPFW,    17, 512,  1, 0, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },
+       { LLCC_CPUSS1,   3, 2048, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },
+       { LLCC_CPUHWT,   5, 512,  1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },
 };
 
 static const struct llcc_slice_config sdm845_data[] =  {
index 2d3ee22b924943c33d41cc6b11f9a79ed0206512..538fa182169a4171752df2f3c41b0b4cf30b1c1d 100644 (file)
@@ -176,7 +176,8 @@ static int qcom_rmtfs_mem_probe(struct platform_device *pdev)
        struct reserved_mem *rmem;
        struct qcom_rmtfs_mem *rmtfs_mem;
        u32 client_id;
-       u32 num_vmids, vmid[NUM_MAX_VMIDS];
+       u32 vmid[NUM_MAX_VMIDS];
+       int num_vmids;
        int ret, i;
 
        rmem = of_reserved_mem_lookup(node);
@@ -228,8 +229,11 @@ static int qcom_rmtfs_mem_probe(struct platform_device *pdev)
        }
 
        num_vmids = of_property_count_u32_elems(node, "qcom,vmid");
-       if (num_vmids < 0) {
-               dev_err(&pdev->dev, "failed to count qcom,vmid elements: %d\n", ret);
+       if (num_vmids == -EINVAL) {
+               /* qcom,vmid is optional */
+               num_vmids = 0;
+       } else if (num_vmids < 0) {
+               dev_err(&pdev->dev, "failed to count qcom,vmid elements: %d\n", num_vmids);
                goto remove_cdev;
        } else if (num_vmids > NUM_MAX_VMIDS) {
                dev_warn(&pdev->dev,
index bd87d3c92dd335f03c49a7f40b234c61f9cff579..69347b6bf60cdbd44a5e5a9bac8efa66cac0c0a3 100644 (file)
@@ -632,7 +632,7 @@ static int rockchip_sfc_probe(struct platform_device *pdev)
        if (ret) {
                dev_err(dev, "Failed to request irq\n");
 
-               return ret;
+               goto err_irq;
        }
 
        ret = rockchip_sfc_init(sfc);
index 44b85a8d47f112f795fb0a8a46397daff7999bcf..7bc14fb309a69970ea92902e4f1ec88b32a41e8c 100644 (file)
@@ -4456,6 +4456,11 @@ static int of_spi_notify(struct notifier_block *nb, unsigned long action,
                        return NOTIFY_OK;
                }
 
+               /*
+                * Clear the flag before adding the device so that fw_devlink
+                * doesn't skip adding consumers to this device.
+                */
+               rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
                spi = of_register_spi_device(ctlr, rd->dn);
                put_device(&ctlr->dev);
 
index 5cfabd5376cc233ab154c43c29a3278d709e4220..f9aef39cac2e93dbb488b62f44236c49eecbf338 100644 (file)
@@ -36,8 +36,6 @@ source "drivers/staging/rtl8723bs/Kconfig"
 
 source "drivers/staging/rtl8712/Kconfig"
 
-source "drivers/staging/r8188eu/Kconfig"
-
 source "drivers/staging/rts5208/Kconfig"
 
 source "drivers/staging/octeon/Kconfig"
index f8c3aa9c241820d0f52f06c1851b042a0db154dc..ffa70dda481d36c526a11275a2b7896957a4edc3 100644 (file)
@@ -8,7 +8,6 @@ obj-$(CONFIG_RTL8192U)          += rtl8192u/
 obj-$(CONFIG_RTL8192E)         += rtl8192e/
 obj-$(CONFIG_RTL8723BS)                += rtl8723bs/
 obj-$(CONFIG_R8712U)           += rtl8712/
-obj-$(CONFIG_R8188EU)          += r8188eu/
 obj-$(CONFIG_RTS5208)          += rts5208/
 obj-$(CONFIG_OCTEON_ETHERNET)  += octeon/
 obj-$(CONFIG_VT6655)           += vt6655/
diff --git a/drivers/staging/r8188eu/Kconfig b/drivers/staging/r8188eu/Kconfig
deleted file mode 100644 (file)
index f5fe423..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-config R8188EU
-       tristate "Realtek RTL8188EU Wireless LAN NIC driver"
-       depends on WLAN && USB && CFG80211
-       depends on m
-       select WIRELESS_EXT
-       select WEXT_PRIV
-       select LIB80211
-       select LIB80211_CRYPT_WEP
-       select LIB80211_CRYPT_CCMP
-       help
-       This option adds support for the Realtek RTL8188EU chipset, used in USB
-       devices such as the ASUS USB-N10 Nano. This newer driver is based on GitHub
-       sources for version v4.1.4_6773.20130222, and contains modifications for
-       newer kernel features. If built as a module, it will be called r8188eu.
-
diff --git a/drivers/staging/r8188eu/Makefile b/drivers/staging/r8188eu/Makefile
deleted file mode 100644 (file)
index fd494c2..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-
-r8188eu-y = \
-               hal/HalHWImg8188E_MAC.o \
-               hal/HalHWImg8188E_BB.o \
-               hal/HalHWImg8188E_RF.o \
-               hal/HalPhyRf_8188e.o \
-               hal/HalPwrSeqCmd.o \
-               hal/Hal8188ERateAdaptive.o \
-               hal/hal_intf.o \
-               hal/hal_com.o \
-               hal/odm.o \
-               hal/odm_HWConfig.o \
-               hal/odm_RTL8188E.o \
-               hal/rtl8188e_cmd.o \
-               hal/rtl8188e_dm.o \
-               hal/rtl8188e_hal_init.o \
-               hal/rtl8188e_phycfg.o \
-               hal/rtl8188e_rf6052.o \
-               hal/rtl8188e_rxdesc.o \
-               hal/rtl8188eu_xmit.o \
-               hal/usb_halinit.o \
-               hal/usb_ops_linux.o \
-               os_dep/ioctl_linux.o \
-               os_dep/os_intfs.o \
-               os_dep/osdep_service.o \
-               os_dep/usb_intf.o \
-               os_dep/usb_ops_linux.o \
-               core/rtw_ap.o \
-               core/rtw_br_ext.o \
-               core/rtw_cmd.o \
-               core/rtw_efuse.o \
-               core/rtw_fw.o \
-               core/rtw_ieee80211.o \
-               core/rtw_ioctl_set.o \
-               core/rtw_iol.o \
-               core/rtw_led.o \
-               core/rtw_mlme.o \
-               core/rtw_mlme_ext.o \
-               core/rtw_pwrctrl.o \
-               core/rtw_p2p.o \
-               core/rtw_recv.o \
-               core/rtw_rf.o \
-               core/rtw_security.o \
-               core/rtw_sta_mgt.o \
-               core/rtw_wlan_util.o \
-               core/rtw_xmit.o
-
-obj-$(CONFIG_R8188EU) := r8188eu.o
diff --git a/drivers/staging/r8188eu/TODO b/drivers/staging/r8188eu/TODO
deleted file mode 100644 (file)
index ab9d5d1..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-To-do list:
-
-* Correct the coding style according to Linux guidelines; please read the document
-  at https://www.kernel.org/doc/html/latest/process/coding-style.html.
-* Remove unnecessary debugging/printing macros; for those that are still needed
-  use the proper kernel API (pr_debug(), dev_dbg(), netdev_dbg()).
-* Remove dead code such as unusued functions, variables, fields, etc..
-* Use in-kernel API and remove unnecessary wrappers where possible.
-* Fix bugs due to code that sleeps in atomic context.
-* Remove the HAL layer and migrate its functionality into the relevant parts of
-  the driver.
-* Switch to use LIB80211.
-* Switch to use MAC80211.
-* Switch to use CFG80211.
-* Improve the error handling of various functions, particularly those that use
-  existing kernel APIs.
diff --git a/drivers/staging/r8188eu/core/rtw_ap.c b/drivers/staging/r8188eu/core/rtw_ap.c
deleted file mode 100644 (file)
index e0ca4b6..0000000
+++ /dev/null
@@ -1,1181 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-#define _RTW_AP_C_
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/wifi.h"
-#include "../include/ieee80211.h"
-#include "../include/rtl8188e_cmd.h"
-
-void init_mlme_ap_info(struct adapter *padapter)
-{
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
-
-       spin_lock_init(&pmlmepriv->bcn_update_lock);
-
-       /* for ACL */
-       rtw_init_queue(&pacl_list->acl_node_q);
-
-       start_ap_mode(padapter);
-}
-
-void free_mlme_ap_info(struct adapter *padapter)
-{
-       struct sta_info *psta = NULL;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       pmlmepriv->update_bcn = false;
-       pmlmeext->bstart_bss = false;
-
-       rtw_sta_flush(padapter);
-
-       pmlmeinfo->state = _HW_STATE_NOLINK_;
-
-       /* free_assoc_sta_resources */
-       rtw_free_all_stainfo(padapter);
-
-       /* free bc/mc sta_info */
-       psta = rtw_get_bcmc_stainfo(padapter);
-       spin_lock_bh(&pstapriv->sta_hash_lock);
-       rtw_free_stainfo(padapter, psta);
-       spin_unlock_bh(&pstapriv->sta_hash_lock);
-}
-
-static void update_BCNTIM(struct adapter *padapter)
-{
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network;
-       unsigned char *pie = pnetwork_mlmeext->IEs;
-       u8 *p, *dst_ie, *premainder_ie = NULL;
-       u8 *pbackup_remainder_ie = NULL;
-       __le16 tim_bitmap_le;
-       uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen;
-
-       /* update TIM IE */
-
-       p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen,
-                      pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_);
-       if (p && tim_ielen > 0) {
-               tim_ielen += 2;
-               premainder_ie = p + tim_ielen;
-               tim_ie_offset = (int)(p - pie);
-               remainder_ielen = pnetwork_mlmeext->IELength - tim_ie_offset - tim_ielen;
-               /* append TIM IE from dst_ie offset */
-               dst_ie = p;
-       } else {
-               tim_ielen = 0;
-
-               /* calculate head_len */
-               offset = _FIXED_IE_LENGTH_;
-               offset += pnetwork_mlmeext->Ssid.SsidLength + 2;
-
-               /*  get supported rates len */
-               p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_,
-                              &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_));
-               if (p)
-                       offset += tmp_len + 2;
-
-               /* DS Parameter Set IE, len = 3 */
-               offset += 3;
-
-               premainder_ie = pie + offset;
-
-               remainder_ielen = pnetwork_mlmeext->IELength - offset - tim_ielen;
-
-               /* append TIM IE from offset */
-               dst_ie = pie + offset;
-       }
-
-       if (remainder_ielen > 0) {
-               pbackup_remainder_ie = kmalloc(remainder_ielen, GFP_ATOMIC);
-               if (pbackup_remainder_ie && premainder_ie)
-                       memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
-       }
-       *dst_ie++ = _TIM_IE_;
-
-       if ((pstapriv->tim_bitmap & 0xff00) && (pstapriv->tim_bitmap & 0x00fc))
-               tim_ielen = 5;
-       else
-               tim_ielen = 4;
-
-       *dst_ie++ = tim_ielen;
-
-       *dst_ie++ = 0;/* DTIM count */
-       *dst_ie++ = 1;/* DTIM period */
-
-       if (pstapriv->tim_bitmap & BIT(0))/* for bc/mc frames */
-               *dst_ie++ = BIT(0);/* bitmap ctrl */
-       else
-               *dst_ie++ = 0;
-
-       tim_bitmap_le = cpu_to_le16(pstapriv->tim_bitmap);
-
-       if (tim_ielen == 4) {
-               *dst_ie++ = *(u8 *)&tim_bitmap_le;
-       } else if (tim_ielen == 5) {
-               memcpy(dst_ie, &tim_bitmap_le, 2);
-               dst_ie += 2;
-       }
-
-       /* copy remainder IE */
-       if (pbackup_remainder_ie) {
-               memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
-
-               kfree(pbackup_remainder_ie);
-       }
-       offset =  (uint)(dst_ie - pie);
-       pnetwork_mlmeext->IELength = offset + remainder_ielen;
-
-       set_tx_beacon_cmd(padapter);
-}
-
-static u8 chk_sta_is_alive(struct sta_info *psta)
-{
-       u8 ret = false;
-
-       if ((psta->sta_stats.last_rx_data_pkts + psta->sta_stats.last_rx_ctrl_pkts) ==
-           (psta->sta_stats.rx_data_pkts + psta->sta_stats.rx_ctrl_pkts))
-               ;
-       else
-               ret = true;
-
-       sta_update_last_rx_pkts(psta);
-
-       return ret;
-}
-
-void   expire_timeout_chk(struct adapter *padapter)
-{
-       struct list_head *phead, *plist;
-       u8 updated = 0;
-       struct sta_info *psta = NULL;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       u8 chk_alive_num = 0;
-       char chk_alive_list[NUM_STA];
-       int i;
-
-       spin_lock_bh(&pstapriv->auth_list_lock);
-
-       phead = &pstapriv->auth_list;
-       plist = phead->next;
-
-       /* check auth_queue */
-       while (phead != plist) {
-               psta = container_of(plist, struct sta_info, auth_list);
-               plist = plist->next;
-
-               if (psta->expire_to > 0) {
-                       psta->expire_to--;
-                       if (psta->expire_to == 0) {
-                               list_del_init(&psta->auth_list);
-                               pstapriv->auth_list_cnt--;
-
-                               spin_unlock_bh(&pstapriv->auth_list_lock);
-
-                               spin_lock_bh(&pstapriv->sta_hash_lock);
-                               rtw_free_stainfo(padapter, psta);
-                               spin_unlock_bh(&pstapriv->sta_hash_lock);
-
-                               spin_lock_bh(&pstapriv->auth_list_lock);
-                       }
-               }
-       }
-       spin_unlock_bh(&pstapriv->auth_list_lock);
-
-       psta = NULL;
-
-       spin_lock_bh(&pstapriv->asoc_list_lock);
-
-       phead = &pstapriv->asoc_list;
-       plist = phead->next;
-
-       /* check asoc_queue */
-       while (phead != plist) {
-               psta = container_of(plist, struct sta_info, asoc_list);
-               plist = plist->next;
-
-               if (chk_sta_is_alive(psta) || !psta->expire_to) {
-                       psta->expire_to = pstapriv->expire_to;
-                       psta->keep_alive_trycnt = 0;
-                       psta->under_exist_checking = 0;
-               } else {
-                       psta->expire_to--;
-               }
-
-               if (psta->expire_to <= 0) {
-                       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
-                       if (padapter->registrypriv.wifi_spec == 1) {
-                               psta->expire_to = pstapriv->expire_to;
-                               continue;
-                       }
-
-                       if (psta->state & WIFI_SLEEP_STATE) {
-                               if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) {
-                                       /* to check if alive by another methods if station is at ps mode. */
-                                       psta->expire_to = pstapriv->expire_to;
-                                       psta->state |= WIFI_STA_ALIVE_CHK_STATE;
-
-                                       /* to update bcn with tim_bitmap for this station */
-                                       pstapriv->tim_bitmap |= BIT(psta->aid);
-                                       update_beacon(padapter, _TIM_IE_, NULL, false);
-
-                                       if (!pmlmeext->active_keep_alive_check)
-                                               continue;
-                               }
-                       }
-                       if (pmlmeext->active_keep_alive_check) {
-                               int stainfo_offset;
-
-                               stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
-                               if (stainfo_offset_valid(stainfo_offset))
-                                       chk_alive_list[chk_alive_num++] = stainfo_offset;
-                               continue;
-                       }
-
-                       list_del_init(&psta->asoc_list);
-                       pstapriv->asoc_list_cnt--;
-
-                       updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
-               } else {
-                       /* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */
-                       if (psta->sleepq_len > (NR_XMITFRAME / pstapriv->asoc_list_cnt) &&
-                           padapter->xmitpriv.free_xmitframe_cnt < (NR_XMITFRAME / pstapriv->asoc_list_cnt / 2)) {
-                               wakeup_sta_to_xmit(padapter, psta);
-                       }
-               }
-       }
-
-       spin_unlock_bh(&pstapriv->asoc_list_lock);
-
-       if (chk_alive_num) {
-               u8 backup_oper_channel = 0;
-               struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-               /* switch to correct channel of current network  before issue keep-alive frames */
-               if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
-                       backup_oper_channel = rtw_get_oper_ch(padapter);
-                       SelectChannel(padapter, pmlmeext->cur_channel);
-               }
-
-               /* issue null data to check sta alive*/
-               for (i = 0; i < chk_alive_num; i++) {
-                       int ret = _FAIL;
-
-                       psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
-
-                       if (psta->state & WIFI_SLEEP_STATE)
-                               ret = issue_nulldata(padapter, psta->hwaddr, 0, 1, 50);
-                       else
-                               ret = issue_nulldata(padapter, psta->hwaddr, 0, 3, 50);
-
-                       psta->keep_alive_trycnt++;
-                       if (ret == _SUCCESS) {
-                               psta->expire_to = pstapriv->expire_to;
-                               psta->keep_alive_trycnt = 0;
-                               continue;
-                       } else if (psta->keep_alive_trycnt <= 3) {
-                               psta->expire_to = 1;
-                               continue;
-                       }
-
-                       psta->keep_alive_trycnt = 0;
-
-                       spin_lock_bh(&pstapriv->asoc_list_lock);
-                       list_del_init(&psta->asoc_list);
-                       pstapriv->asoc_list_cnt--;
-                       updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
-                       spin_unlock_bh(&pstapriv->asoc_list_lock);
-               }
-
-               if (backup_oper_channel > 0) /* back to the original operation channel */
-                       SelectChannel(padapter, backup_oper_channel);
-       }
-
-       associated_clients_update(padapter, updated);
-}
-
-void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level)
-{
-       int i;
-       u32 init_rate = 0;
-       unsigned char sta_band = 0, raid, shortGIrate = false;
-       unsigned char limit;
-       unsigned int tx_ra_bitmap = 0;
-       struct ht_priv  *psta_ht = NULL;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct wlan_bssid_ex *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
-
-       if (psta)
-               psta_ht = &psta->htpriv;
-       else
-               return;
-
-       if (!(psta->state & _FW_LINKED))
-               return;
-
-       /* b/g mode ra_bitmap */
-       for (i = 0; i < sizeof(psta->bssrateset); i++) {
-               if (psta->bssrateset[i])
-                       tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
-       }
-       /* n mode ra_bitmap */
-       if (psta_ht->ht_option) {
-               limit = 8; /* 1R */
-
-               for (i = 0; i < limit; i++) {
-                       if (psta_ht->ht_cap.mcs.rx_mask[i / 8] & BIT(i % 8))
-                               tx_ra_bitmap |= BIT(i + 12);
-               }
-
-               /* max short GI rate */
-               shortGIrate = psta_ht->sgi;
-       }
-
-       if (pcur_network->Configuration.DSConfig > 14) {
-               sta_band |= WIRELESS_INVALID;
-       } else {
-               if (tx_ra_bitmap & 0xffff000)
-                       sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B;
-               else if (tx_ra_bitmap & 0xff0)
-                       sta_band |= WIRELESS_11G | WIRELESS_11B;
-               else
-                       sta_band |= WIRELESS_11B;
-       }
-
-       psta->wireless_mode = sta_band;
-
-       raid = networktype_to_raid(sta_band);
-       init_rate = get_highest_rate_idx(tx_ra_bitmap & 0x0fffffff) & 0x3f;
-
-       if (psta->aid < NUM_STA) {
-               u8 arg = 0;
-
-               arg = psta->mac_id & 0x1f;
-
-               arg |= BIT(7);/* support entry 2~31 */
-
-               if (shortGIrate)
-                       arg |= BIT(5);
-
-               tx_ra_bitmap |= ((raid << 28) & 0xf0000000);
-
-               /* bitmap[0:27] = tx_rate_bitmap */
-               /* bitmap[28:31]= Rate Adaptive id */
-               /* arg[0:4] = macid */
-               /* arg[5] = Short GI */
-               rtl8188e_Add_RateATid(padapter, tx_ra_bitmap, arg, rssi_level);
-
-               if (shortGIrate)
-                       init_rate |= BIT(6);
-
-               /* set ra_id, init_rate */
-               psta->raid = raid;
-               psta->init_rate = init_rate;
-       }
-}
-
-void update_bmc_sta(struct adapter *padapter)
-{
-       u32 init_rate = 0;
-       unsigned char   network_type, raid;
-       int i, supportRateNum = 0;
-       unsigned int tx_ra_bitmap = 0;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct wlan_bssid_ex *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
-       struct sta_info *psta = rtw_get_bcmc_stainfo(padapter);
-
-       if (psta) {
-               psta->aid = 0;/* default set to 0 */
-               psta->mac_id = psta->aid + 1;
-
-               psta->qos_option = 0;
-               psta->htpriv.ht_option = false;
-
-               psta->ieee8021x_blocked = 0;
-
-               memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
-
-               /* prepare for add_RATid */
-               supportRateNum = rtw_get_rateset_len((u8 *)&pcur_network->SupportedRates);
-               network_type = rtw_check_network_type((u8 *)&pcur_network->SupportedRates, supportRateNum, 1);
-
-               memcpy(psta->bssrateset, &pcur_network->SupportedRates, supportRateNum);
-               psta->bssratelen = supportRateNum;
-
-               /* b/g mode ra_bitmap */
-               for (i = 0; i < supportRateNum; i++) {
-                       if (psta->bssrateset[i])
-                               tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
-               }
-
-               if (pcur_network->Configuration.DSConfig > 14) {
-                       network_type = WIRELESS_INVALID;
-               } else {
-                       /* force to b mode */
-                       network_type = WIRELESS_11B;
-                       tx_ra_bitmap = 0xf;
-               }
-
-               raid = networktype_to_raid(network_type);
-               init_rate = get_highest_rate_idx(tx_ra_bitmap & 0x0fffffff) & 0x3f;
-
-               /* ap mode */
-               rtl8188e_SetHalODMVar(padapter, psta, true);
-
-               {
-                       u8 arg = 0;
-
-                       arg = psta->mac_id & 0x1f;
-                       arg |= BIT(7);
-                       tx_ra_bitmap |= ((raid << 28) & 0xf0000000);
-
-                       /* bitmap[0:27] = tx_rate_bitmap */
-                       /* bitmap[28:31]= Rate Adaptive id */
-                       /* arg[0:4] = macid */
-                       /* arg[5] = Short GI */
-                       rtl8188e_Add_RateATid(padapter, tx_ra_bitmap, arg, 0);
-               }
-               /* set ra_id, init_rate */
-               psta->raid = raid;
-               psta->init_rate = init_rate;
-
-               rtw_sta_media_status_rpt(padapter, psta, 1);
-
-               spin_lock_bh(&psta->lock);
-               psta->state = _FW_LINKED;
-               spin_unlock_bh(&psta->lock);
-       }
-}
-
-/* notes: */
-/* AID: 1~MAX for sta and 0 for bc/mc in ap/adhoc mode */
-/* MAC_ID = AID+1 for sta in ap/adhoc mode */
-/* MAC_ID = 1 for bc/mc for sta/ap/adhoc */
-/* MAC_ID = 0 for bssid for sta/ap/adhoc */
-/* CAM_ID = 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */
-
-void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta)
-{
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct security_priv *psecuritypriv = &padapter->securitypriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct ht_priv  *phtpriv_ap = &pmlmepriv->htpriv;
-       struct ht_priv  *phtpriv_sta = &psta->htpriv;
-       u16 sta_cap_info;
-       u16 ap_cap_info;
-
-       psta->mac_id = psta->aid + 1;
-
-       /* ap mode */
-       rtl8188e_SetHalODMVar(padapter, psta, true);
-
-       if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
-               psta->ieee8021x_blocked = true;
-       else
-               psta->ieee8021x_blocked = false;
-
-       /* update sta's cap */
-
-       /* ERP */
-       VCS_update(padapter, psta);
-       /* HT related cap */
-       if (phtpriv_sta->ht_option) {
-               /* check if sta supports rx ampdu */
-               phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable;
-               sta_cap_info = le16_to_cpu(phtpriv_sta->ht_cap.cap_info);
-               ap_cap_info = le16_to_cpu(phtpriv_ap->ht_cap.cap_info);
-
-               /* check if sta support s Short GI */
-               if ((sta_cap_info & ap_cap_info) &
-                   (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40))
-                       phtpriv_sta->sgi = true;
-
-               /*  bwmode */
-               if ((sta_cap_info & ap_cap_info) & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
-                       phtpriv_sta->bwmode = pmlmeext->cur_bwmode;
-                       phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
-               }
-               psta->qos_option = true;
-       } else {
-               phtpriv_sta->ampdu_enable = false;
-               phtpriv_sta->sgi = false;
-               phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20;
-               phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-       }
-
-       /* Rx AMPDU */
-       send_delba(padapter, 0, psta->hwaddr);/*  recipient */
-
-       /* TX AMPDU */
-       send_delba(padapter, 1, psta->hwaddr);/* originator */
-       phtpriv_sta->agg_enable_bitmap = 0x0;/* reset */
-       phtpriv_sta->candidate_tid_bitmap = 0x0;/* reset */
-
-       /* todo: init other variables */
-
-       memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
-
-       spin_lock_bh(&psta->lock);
-       psta->state |= _FW_LINKED;
-       spin_unlock_bh(&psta->lock);
-}
-
-static void update_bcn_erpinfo_ie(struct adapter *padapter)
-{
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
-       unsigned char *p, *ie = pnetwork->IEs;
-       u32 len = 0;
-
-       if (!pmlmeinfo->ERP_enable)
-               return;
-
-       /* parsing ERP_IE */
-       p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &len,
-                      (pnetwork->IELength - _BEACON_IE_OFFSET_));
-       if (p && len > 0) {
-               struct ndis_802_11_var_ie *pIE = (struct ndis_802_11_var_ie *)p;
-
-               if (pmlmepriv->num_sta_non_erp == 1)
-                       pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT | RTW_ERP_INFO_USE_PROTECTION;
-               else
-                       pIE->data[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT | RTW_ERP_INFO_USE_PROTECTION);
-
-               if (pmlmepriv->num_sta_no_short_preamble > 0)
-                       pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE;
-               else
-                       pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE);
-
-               ERP_IE_handler(padapter, pIE);
-       }
-}
-
-static void update_bcn_wps_ie(struct adapter *padapter)
-{
-       u8 *pwps_ie = NULL, *pwps_ie_src;
-       u8 *premainder_ie, *pbackup_remainder_ie = NULL;
-       uint wps_ielen = 0, wps_offset, remainder_ielen;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
-       unsigned char *ie = pnetwork->IEs;
-       u32 ielen = pnetwork->IELength;
-
-       pwps_ie = rtw_get_wps_ie(ie + _FIXED_IE_LENGTH_, ielen - _FIXED_IE_LENGTH_, NULL, &wps_ielen);
-
-       if (!pwps_ie || wps_ielen == 0)
-               return;
-
-       wps_offset = (uint)(pwps_ie - ie);
-
-       premainder_ie = pwps_ie + wps_ielen;
-
-       remainder_ielen = ielen - wps_offset - wps_ielen;
-
-       if (remainder_ielen > 0) {
-               pbackup_remainder_ie = kmalloc(remainder_ielen, GFP_ATOMIC);
-               if (pbackup_remainder_ie)
-                       memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
-       }
-
-       pwps_ie_src = pmlmepriv->wps_beacon_ie;
-       if (!pwps_ie_src)
-               goto exit;
-
-       wps_ielen = (uint)pwps_ie_src[1];/* to get ie data len */
-       if ((wps_offset + wps_ielen + 2 + remainder_ielen) <= MAX_IE_SZ) {
-               memcpy(pwps_ie, pwps_ie_src, wps_ielen + 2);
-               pwps_ie += (wps_ielen + 2);
-
-               if (pbackup_remainder_ie)
-                       memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen);
-
-               /* update IELength */
-               pnetwork->IELength = wps_offset + (wps_ielen + 2) + remainder_ielen;
-       }
-
-exit:
-       kfree(pbackup_remainder_ie);
-}
-
-static void update_bcn_vendor_spec_ie(struct adapter *padapter, u8 *oui)
-{
-       if (!memcmp(WPS_OUI, oui, 4))
-               update_bcn_wps_ie(padapter);
-}
-
-void update_beacon(struct adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
-{
-       struct mlme_priv *pmlmepriv;
-       struct mlme_ext_priv    *pmlmeext;
-
-       if (!padapter)
-               return;
-
-       pmlmepriv = &padapter->mlmepriv;
-       pmlmeext = &padapter->mlmeextpriv;
-
-       if (!pmlmeext->bstart_bss)
-               return;
-
-       spin_lock_bh(&pmlmepriv->bcn_update_lock);
-
-       switch (ie_id) {
-       case _TIM_IE_:
-               update_BCNTIM(padapter);
-               break;
-       case _ERPINFO_IE_:
-               update_bcn_erpinfo_ie(padapter);
-               break;
-       case _VENDOR_SPECIFIC_IE_:
-               update_bcn_vendor_spec_ie(padapter, oui);
-               break;
-       default:
-               break;
-       }
-
-       pmlmepriv->update_bcn = true;
-
-       spin_unlock_bh(&pmlmepriv->bcn_update_lock);
-
-       if (tx)
-               set_tx_beacon_cmd(padapter);
-}
-
-/* op_mode
- * Set to 0 (HT pure) under the following conditions
- *     - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
- *     - all STAs in the BSS are 20 MHz HT in 20 MHz BSS
- * Set to 1 (HT non-member protection) if there may be non-HT STAs
- *     in both the primary and the secondary channel
- * Set to 2 if only HT STAs are associated in BSS,
- *     however and at least one 20 MHz HT STA is associated
- * Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
- *     (currently non-GF HT station is considered as non-HT STA also)
- */
-static int rtw_ht_operation_update(struct adapter *padapter)
-{
-       u16 cur_op_mode, new_op_mode;
-       int op_mode_changes = 0;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct ht_priv  *phtpriv_ap = &pmlmepriv->htpriv;
-
-       if (pmlmepriv->htpriv.ht_option)
-               return 0;
-
-       if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
-           pmlmepriv->num_sta_ht_no_gf) {
-               pmlmepriv->ht_op_mode |=
-                       HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
-               op_mode_changes++;
-       } else if ((pmlmepriv->ht_op_mode &
-                  HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
-                  pmlmepriv->num_sta_ht_no_gf == 0) {
-               pmlmepriv->ht_op_mode &=
-                       ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
-               op_mode_changes++;
-       }
-
-       if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
-           (pmlmepriv->num_sta_no_ht || pmlmepriv->olbc_ht)) {
-               pmlmepriv->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
-               op_mode_changes++;
-       } else if ((pmlmepriv->ht_op_mode &
-                   HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
-                  (pmlmepriv->num_sta_no_ht == 0 && !pmlmepriv->olbc_ht)) {
-               pmlmepriv->ht_op_mode &=
-                       ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
-               op_mode_changes++;
-       }
-
-       /* Note: currently we switch to the MIXED op mode if HT non-greenfield
-        * station is associated. Probably it's a theoretical case, since
-        * it looks like all known HT STAs support greenfield.
-        */
-       new_op_mode = 0;
-       if (pmlmepriv->num_sta_no_ht ||
-           (pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))
-               new_op_mode = OP_MODE_MIXED;
-       else if ((le16_to_cpu(phtpriv_ap->ht_cap.cap_info) &
-                 IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
-                pmlmepriv->num_sta_ht_20mhz)
-               new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
-       else if (pmlmepriv->olbc_ht)
-               new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
-       else
-               new_op_mode = OP_MODE_PURE;
-
-       cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
-       if (cur_op_mode != new_op_mode) {
-               pmlmepriv->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;
-               pmlmepriv->ht_op_mode |= new_op_mode;
-               op_mode_changes++;
-       }
-
-       return op_mode_changes;
-}
-
-void associated_clients_update(struct adapter *padapter, u8 updated)
-{
-       /* update associated stations cap. */
-       if (updated) {
-               struct list_head *phead, *plist;
-               struct sta_info *psta = NULL;
-               struct sta_priv *pstapriv = &padapter->stapriv;
-
-               spin_lock_bh(&pstapriv->asoc_list_lock);
-
-               phead = &pstapriv->asoc_list;
-               plist = phead->next;
-
-               /* check asoc_queue */
-               while (phead != plist) {
-                       psta = container_of(plist, struct sta_info, asoc_list);
-
-                       plist = plist->next;
-
-                       VCS_update(padapter, psta);
-               }
-               spin_unlock_bh(&pstapriv->asoc_list_lock);
-       }
-}
-
-/* called > TSR LEVEL for USB or SDIO Interface*/
-void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta)
-{
-       u8 beacon_updated = false;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
-       if (!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) {
-               if (!psta->no_short_preamble_set) {
-                       psta->no_short_preamble_set = 1;
-
-                       pmlmepriv->num_sta_no_short_preamble++;
-
-                       if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
-                           (pmlmepriv->num_sta_no_short_preamble == 1)) {
-                               beacon_updated = true;
-                               update_beacon(padapter, 0xFF, NULL, true);
-                       }
-               }
-       } else {
-               if (psta->no_short_preamble_set) {
-                       psta->no_short_preamble_set = 0;
-
-                       pmlmepriv->num_sta_no_short_preamble--;
-
-                       if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
-                           (pmlmepriv->num_sta_no_short_preamble == 0)) {
-                               beacon_updated = true;
-                               update_beacon(padapter, 0xFF, NULL, true);
-                       }
-               }
-       }
-
-       if (psta->flags & WLAN_STA_NONERP) {
-               if (!psta->nonerp_set) {
-                       psta->nonerp_set = 1;
-
-                       pmlmepriv->num_sta_non_erp++;
-
-                       if (pmlmepriv->num_sta_non_erp == 1) {
-                               beacon_updated = true;
-                               update_beacon(padapter, _ERPINFO_IE_, NULL, true);
-                       }
-               }
-       } else {
-               if (psta->nonerp_set) {
-                       psta->nonerp_set = 0;
-
-                       pmlmepriv->num_sta_non_erp--;
-
-                       if (pmlmepriv->num_sta_non_erp == 0) {
-                               beacon_updated = true;
-                               update_beacon(padapter, _ERPINFO_IE_, NULL, true);
-                       }
-               }
-       }
-
-       if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT)) {
-               if (!psta->no_short_slot_time_set) {
-                       psta->no_short_slot_time_set = 1;
-
-                       pmlmepriv->num_sta_no_short_slot_time++;
-
-                       if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
-                           (pmlmepriv->num_sta_no_short_slot_time == 1)) {
-                               beacon_updated = true;
-                               update_beacon(padapter, 0xFF, NULL, true);
-                       }
-               }
-       } else {
-               if (psta->no_short_slot_time_set) {
-                       psta->no_short_slot_time_set = 0;
-
-                       pmlmepriv->num_sta_no_short_slot_time--;
-
-                       if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
-                           (pmlmepriv->num_sta_no_short_slot_time == 0)) {
-                               beacon_updated = true;
-                               update_beacon(padapter, 0xFF, NULL, true);
-                       }
-               }
-       }
-
-       if (psta->flags & WLAN_STA_HT) {
-               u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info);
-
-               if (psta->no_ht_set) {
-                       psta->no_ht_set = 0;
-                       pmlmepriv->num_sta_no_ht--;
-               }
-
-               if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) {
-                       if (!psta->no_ht_gf_set) {
-                               psta->no_ht_gf_set = 1;
-                               pmlmepriv->num_sta_ht_no_gf++;
-                       }
-               }
-
-               if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH_20_40) == 0) {
-                       if (!psta->ht_20mhz_set) {
-                               psta->ht_20mhz_set = 1;
-                               pmlmepriv->num_sta_ht_20mhz++;
-                       }
-               }
-       } else {
-               if (!psta->no_ht_set) {
-                       psta->no_ht_set = 1;
-                       pmlmepriv->num_sta_no_ht++;
-               }
-       }
-
-       if (rtw_ht_operation_update(padapter) > 0) {
-               update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, false);
-               update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, true);
-       }
-
-       /* update associated stations cap. */
-       associated_clients_update(padapter,  beacon_updated);
-}
-
-u8 bss_cap_update_on_sta_leave(struct adapter *padapter, struct sta_info *psta)
-{
-       u8 beacon_updated = false;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
-       if (!psta)
-               return beacon_updated;
-
-       if (psta->no_short_preamble_set) {
-               psta->no_short_preamble_set = 0;
-               pmlmepriv->num_sta_no_short_preamble--;
-               if (pmlmeext->cur_wireless_mode > WIRELESS_11B &&
-                   pmlmepriv->num_sta_no_short_preamble == 0) {
-                       beacon_updated = true;
-                       update_beacon(padapter, 0xFF, NULL, true);
-               }
-       }
-
-       if (psta->nonerp_set) {
-               psta->nonerp_set = 0;
-               pmlmepriv->num_sta_non_erp--;
-               if (pmlmepriv->num_sta_non_erp == 0) {
-                       beacon_updated = true;
-                       update_beacon(padapter, _ERPINFO_IE_, NULL, true);
-               }
-       }
-
-       if (psta->no_short_slot_time_set) {
-               psta->no_short_slot_time_set = 0;
-               pmlmepriv->num_sta_no_short_slot_time--;
-               if (pmlmeext->cur_wireless_mode > WIRELESS_11B &&
-                   pmlmepriv->num_sta_no_short_slot_time == 0) {
-                       beacon_updated = true;
-                       update_beacon(padapter, 0xFF, NULL, true);
-               }
-       }
-
-       if (psta->no_ht_gf_set) {
-               psta->no_ht_gf_set = 0;
-               pmlmepriv->num_sta_ht_no_gf--;
-       }
-
-       if (psta->no_ht_set) {
-               psta->no_ht_set = 0;
-               pmlmepriv->num_sta_no_ht--;
-       }
-
-       if (psta->ht_20mhz_set) {
-               psta->ht_20mhz_set = 0;
-               pmlmepriv->num_sta_ht_20mhz--;
-       }
-
-       if (rtw_ht_operation_update(padapter) > 0) {
-               update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, false);
-               update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, true);
-       }
-
-       /* update associated stations cap. */
-
-       return beacon_updated;
-}
-
-void rtw_indicate_sta_assoc_event(struct adapter *padapter, struct sta_info *psta)
-{
-       union iwreq_data wrqu;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-
-       if (!psta)
-               return;
-
-       if (psta->aid > NUM_STA)
-               return;
-
-       if (pstapriv->sta_aid[psta->aid - 1] != psta)
-               return;
-
-       wrqu.addr.sa_family = ARPHRD_ETHER;
-
-       memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN);
-
-       wireless_send_event(padapter->pnetdev, IWEVREGISTERED, &wrqu, NULL);
-}
-
-static void rtw_indicate_sta_disassoc_event(struct adapter *padapter, struct sta_info *psta)
-{
-       union iwreq_data wrqu;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-
-       if (!psta)
-               return;
-
-       if (psta->aid > NUM_STA)
-               return;
-
-       if (pstapriv->sta_aid[psta->aid - 1] != psta)
-               return;
-
-       wrqu.addr.sa_family = ARPHRD_ETHER;
-
-       memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN);
-
-       wireless_send_event(padapter->pnetdev, IWEVEXPIRED, &wrqu, NULL);
-}
-
-u8 ap_free_sta(struct adapter *padapter, struct sta_info *psta,
-              bool active, u16 reason)
-{
-       u8 beacon_updated = false;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-
-       if (!psta)
-               return beacon_updated;
-
-       /* tear down Rx AMPDU */
-       send_delba(padapter, 0, psta->hwaddr);/*  recipient */
-
-       /* tear down TX AMPDU */
-       send_delba(padapter, 1, psta->hwaddr);/*  originator */
-       psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
-       psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
-
-       if (active)
-               issue_deauth(padapter, psta->hwaddr, reason);
-
-       /* clear cam entry / key */
-       rtw_clearstakey_cmd(padapter, (u8 *)psta, (u8)(psta->mac_id + 3), true);
-
-       spin_lock_bh(&psta->lock);
-       psta->state &= ~_FW_LINKED;
-       spin_unlock_bh(&psta->lock);
-
-       rtw_indicate_sta_disassoc_event(padapter, psta);
-
-       report_del_sta_event(padapter, psta->hwaddr, reason);
-
-       beacon_updated = bss_cap_update_on_sta_leave(padapter, psta);
-
-       spin_lock_bh(&pstapriv->sta_hash_lock);
-       rtw_free_stainfo(padapter, psta);
-       spin_unlock_bh(&pstapriv->sta_hash_lock);
-
-       return beacon_updated;
-}
-
-void rtw_sta_flush(struct adapter *padapter)
-{
-       struct list_head *phead, *plist;
-       struct sta_info *psta = NULL;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
-       if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
-               return;
-
-       spin_lock_bh(&pstapriv->asoc_list_lock);
-       phead = &pstapriv->asoc_list;
-       plist = phead->next;
-
-       /* free sta asoc_queue */
-       while (phead != plist) {
-               psta = container_of(plist, struct sta_info, asoc_list);
-
-               plist = plist->next;
-
-               list_del_init(&psta->asoc_list);
-               pstapriv->asoc_list_cnt--;
-
-               ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
-       }
-       spin_unlock_bh(&pstapriv->asoc_list_lock);
-
-       issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING);
-
-       associated_clients_update(padapter, true);
-}
-
-/* called > TSR LEVEL for USB or SDIO Interface*/
-void sta_info_update(struct adapter *padapter, struct sta_info *psta)
-{
-       int flags = psta->flags;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
-       /* update wmm cap. */
-       if (WLAN_STA_WME & flags)
-               psta->qos_option = 1;
-       else
-               psta->qos_option = 0;
-
-       if (pmlmepriv->qospriv.qos_option == 0)
-               psta->qos_option = 0;
-
-       /* update 802.11n ht cap. */
-       if (WLAN_STA_HT & flags) {
-               psta->htpriv.ht_option = true;
-               psta->qos_option = 1;
-       } else {
-               psta->htpriv.ht_option = false;
-       }
-
-       if (!pmlmepriv->htpriv.ht_option)
-               psta->htpriv.ht_option = false;
-
-       update_sta_info_apmode(padapter, psta);
-}
-
-void start_ap_mode(struct adapter *padapter)
-{
-       int i;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-       struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
-
-       pmlmepriv->update_bcn = false;
-
-       pmlmeext->bstart_bss = false;
-
-       pmlmepriv->num_sta_non_erp = 0;
-
-       pmlmepriv->num_sta_no_short_slot_time = 0;
-
-       pmlmepriv->num_sta_no_short_preamble = 0;
-
-       pmlmepriv->num_sta_ht_no_gf = 0;
-       pmlmepriv->num_sta_no_ht = 0;
-       pmlmepriv->num_sta_ht_20mhz = 0;
-
-       pmlmepriv->olbc = false;
-
-       pmlmepriv->olbc_ht = false;
-
-       pmlmepriv->ht_op_mode = 0;
-
-       for (i = 0; i < NUM_STA; i++)
-               pstapriv->sta_aid[i] = NULL;
-
-       pmlmepriv->wps_beacon_ie = NULL;
-       pmlmepriv->wps_probe_resp_ie = NULL;
-       pmlmepriv->wps_assoc_resp_ie = NULL;
-
-       pmlmepriv->p2p_beacon_ie = NULL;
-       pmlmepriv->p2p_probe_resp_ie = NULL;
-
-       /* for ACL */
-       INIT_LIST_HEAD(&pacl_list->acl_node_q.queue);
-       pacl_list->num = 0;
-       pacl_list->mode = 0;
-       for (i = 0; i < NUM_ACL; i++) {
-               INIT_LIST_HEAD(&pacl_list->aclnode[i].list);
-               pacl_list->aclnode[i].valid = false;
-       }
-}
-
-void stop_ap_mode(struct adapter *padapter)
-{
-       struct list_head *phead, *plist;
-       struct rtw_wlan_acl_node *paclnode;
-       struct sta_info *psta = NULL;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-       struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
-       struct __queue *pacl_node_q = &pacl_list->acl_node_q;
-
-       pmlmepriv->update_bcn = false;
-       pmlmeext->bstart_bss = false;
-
-       /* reset and init security priv , this can refine with rtw_reset_securitypriv */
-       memset((unsigned char *)&padapter->securitypriv, 0, sizeof(struct security_priv));
-       padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
-       padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
-
-       /* for ACL */
-       spin_lock_bh(&pacl_node_q->lock);
-       phead = get_list_head(pacl_node_q);
-       plist = phead->next;
-       while (phead != plist) {
-               paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
-               plist = plist->next;
-
-               if (paclnode->valid) {
-                       paclnode->valid = false;
-
-                       list_del_init(&paclnode->list);
-
-                       pacl_list->num--;
-               }
-       }
-       spin_unlock_bh(&pacl_node_q->lock);
-
-       rtw_sta_flush(padapter);
-
-       /* free_assoc_sta_resources */
-       rtw_free_all_stainfo(padapter);
-
-       psta = rtw_get_bcmc_stainfo(padapter);
-       spin_lock_bh(&pstapriv->sta_hash_lock);
-       rtw_free_stainfo(padapter, psta);
-       spin_unlock_bh(&pstapriv->sta_hash_lock);
-
-       rtw_init_bcmc_stainfo(padapter);
-
-       rtw_free_mlme_priv_ie_data(pmlmepriv);
-}
diff --git a/drivers/staging/r8188eu/core/rtw_br_ext.c b/drivers/staging/r8188eu/core/rtw_br_ext.c
deleted file mode 100644 (file)
index a7c6701..0000000
+++ /dev/null
@@ -1,658 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. i*/
-
-#define _RTW_BR_EXT_C_
-
-#include "../include/linux/if_arp.h"
-#include "../include/net/ip.h"
-#include "../include/linux/atalk.h"
-#include "../include/linux/udp.h"
-#include "../include/linux/if_pppox.h"
-
-#include "../include/drv_types.h"
-#include "../include/rtw_br_ext.h"
-#include "../include/usb_osintf.h"
-
-#ifndef csum_ipv6_magic
-#include "../include/net/ip6_checksum.h"
-#endif
-
-#include "../include/linux/ipv6.h"
-#include "../include/linux/icmpv6.h"
-#include "../include/net/ndisc.h"
-#include "../include/net/checksum.h"
-
-#define NAT25_IPV4             01
-#define NAT25_IPV6             02
-#define NAT25_IPX              03
-#define NAT25_APPLE            04
-#define NAT25_PPPOE            05
-
-#define RTL_RELAY_TAG_LEN (ETH_ALEN)
-#define TAG_HDR_LEN            4
-
-#define MAGIC_CODE             0x8186
-#define MAGIC_CODE_LEN 2
-#define WAIT_TIME_PPPOE        5       /*  waiting time for pppoe server in sec */
-
-/*-----------------------------------------------------------------
-  How database records network address:
-          0    1    2    3    4    5    6    7    8    9   10
-       |----|----|----|----|----|----|----|----|----|----|----|
-  IPv4  |type|                             |      IP addr      |
-  IPX   |type|      Net addr     |          Node addr          |
-  IPX   |type|      Net addr     |Sckt addr|
-  Apple |type| Network |node|
-  PPPoE |type|   SID   |           AC MAC            |
------------------------------------------------------------------*/
-
-/* Find a tag in pppoe frame and return the pointer */
-static unsigned char *__nat25_find_pppoe_tag(struct pppoe_hdr *ph, unsigned short type)
-{
-       unsigned char *cur_ptr, *start_ptr;
-       unsigned short tag_len, tag_type;
-
-       start_ptr = (unsigned char *)ph->tag;
-       cur_ptr = (unsigned char *)ph->tag;
-       while ((cur_ptr - start_ptr) < ntohs(ph->length)) {
-               /*  prevent un-alignment access */
-               tag_type = (unsigned short)((cur_ptr[0] << 8) + cur_ptr[1]);
-               tag_len  = (unsigned short)((cur_ptr[2] << 8) + cur_ptr[3]);
-               if (tag_type == type)
-                       return cur_ptr;
-               cur_ptr = cur_ptr + TAG_HDR_LEN + tag_len;
-       }
-       return NULL;
-}
-
-static int __nat25_add_pppoe_tag(struct sk_buff *skb, struct pppoe_tag *tag)
-{
-       struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN);
-       int data_len;
-
-       data_len = be16_to_cpu(tag->tag_len) + TAG_HDR_LEN;
-       if (skb_tailroom(skb) < data_len)
-               return -1;
-
-       skb_put(skb, data_len);
-       /*  have a room for new tag */
-       memmove(((unsigned char *)ph->tag + data_len), (unsigned char *)ph->tag, ntohs(ph->length));
-       ph->length = htons(ntohs(ph->length) + data_len);
-       memcpy((unsigned char *)ph->tag, tag, data_len);
-       return data_len;
-}
-
-static int skb_pull_and_merge(struct sk_buff *skb, unsigned char *src, int len)
-{
-       int tail_len;
-       unsigned long end, tail;
-
-       if ((src + len) > skb_tail_pointer(skb) || skb->len < len)
-               return -1;
-
-       tail = (unsigned long)skb_tail_pointer(skb);
-       end = (unsigned long)src + len;
-       if (tail < end)
-               return -1;
-
-       tail_len = (int)(tail - end);
-       if (tail_len > 0)
-               memmove(src, src + len, tail_len);
-
-       skb_trim(skb, skb->len - len);
-       return 0;
-}
-
-static int  __nat25_has_expired(struct nat25_network_db_entry *fdb)
-{
-       if (time_before_eq(fdb->ageing_timer, jiffies - NAT25_AGEING_TIME * HZ))
-               return 1;
-
-       return 0;
-}
-
-static void __nat25_generate_ipv4_network_addr(unsigned char *addr,
-                               unsigned int *ip_addr)
-{
-       memset(addr, 0, MAX_NETWORK_ADDR_LEN);
-
-       addr[0] = NAT25_IPV4;
-       memcpy(addr + 7, (unsigned char *)ip_addr, 4);
-}
-
-static void __nat25_generate_pppoe_network_addr(unsigned char *addr,
-                               unsigned char *ac_mac, __be16 *sid)
-{
-       memset(addr, 0, MAX_NETWORK_ADDR_LEN);
-
-       addr[0] = NAT25_PPPOE;
-       memcpy(addr + 1, (unsigned char *)sid, 2);
-       memcpy(addr + 3, (unsigned char *)ac_mac, 6);
-}
-
-static  void __nat25_generate_ipv6_network_addr(unsigned char *addr,
-                               unsigned int *ip_addr)
-{
-       memset(addr, 0, MAX_NETWORK_ADDR_LEN);
-
-       addr[0] = NAT25_IPV6;
-       memcpy(addr + 1, (unsigned char *)ip_addr, 16);
-}
-
-static unsigned char *scan_tlv(unsigned char *data, int len, unsigned char tag, unsigned char len8b)
-{
-       while (len > 0) {
-               if (*data == tag && *(data + 1) == len8b && len >= len8b * 8)
-                       return data + 2;
-
-               len -= (*(data + 1)) * 8;
-               data += (*(data + 1)) * 8;
-       }
-       return NULL;
-}
-
-static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char *replace_mac)
-{
-       struct icmp6hdr *icmphdr = (struct icmp6hdr *)data;
-       unsigned char *mac;
-
-       if (icmphdr->icmp6_type == NDISC_ROUTER_SOLICITATION) {
-               if (len >= 8) {
-                       mac = scan_tlv(&data[8], len - 8, 1, 1);
-                       if (mac) {
-                               memcpy(mac, replace_mac, 6);
-                               return 1;
-                       }
-               }
-       } else if (icmphdr->icmp6_type == NDISC_ROUTER_ADVERTISEMENT) {
-               if (len >= 16) {
-                       mac = scan_tlv(&data[16], len - 16, 1, 1);
-                       if (mac) {
-                               memcpy(mac, replace_mac, 6);
-                               return 1;
-                       }
-               }
-       } else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) {
-               if (len >= 24) {
-                       mac = scan_tlv(&data[24], len - 24, 1, 1);
-                       if (mac) {
-                               memcpy(mac, replace_mac, 6);
-                               return 1;
-                       }
-               }
-       } else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT) {
-               if (len >= 24) {
-                       mac = scan_tlv(&data[24], len - 24, 2, 1);
-                       if (mac) {
-                               memcpy(mac, replace_mac, 6);
-                               return 1;
-                       }
-               }
-       } else if (icmphdr->icmp6_type == NDISC_REDIRECT) {
-               if (len >= 40) {
-                       mac = scan_tlv(&data[40], len - 40, 2, 1);
-                       if (mac) {
-                               memcpy(mac, replace_mac, 6);
-                               return 1;
-                       }
-               }
-       }
-       return 0;
-}
-
-static int __nat25_network_hash(unsigned char *addr)
-{
-       if (addr[0] == NAT25_IPV4) {
-               unsigned long x;
-
-               x = addr[7] ^ addr[8] ^ addr[9] ^ addr[10];
-
-               return x & (NAT25_HASH_SIZE - 1);
-       } else if (addr[0] == NAT25_IPX) {
-               unsigned long x;
-
-               x = addr[1] ^ addr[2] ^ addr[3] ^ addr[4] ^ addr[5] ^
-                   addr[6] ^ addr[7] ^ addr[8] ^ addr[9] ^ addr[10];
-
-               return x & (NAT25_HASH_SIZE - 1);
-       } else if (addr[0] == NAT25_APPLE) {
-               unsigned long x;
-
-               x = addr[1] ^ addr[2] ^ addr[3];
-
-               return x & (NAT25_HASH_SIZE - 1);
-       } else if (addr[0] == NAT25_PPPOE) {
-               unsigned long x;
-
-               x = addr[0] ^ addr[1] ^ addr[2] ^ addr[3] ^ addr[4] ^
-                   addr[5] ^ addr[6] ^ addr[7] ^ addr[8];
-
-               return x & (NAT25_HASH_SIZE - 1);
-       } else if (addr[0] == NAT25_IPV6) {
-               unsigned long x;
-
-               x = addr[1] ^ addr[2] ^ addr[3] ^ addr[4] ^ addr[5] ^ addr[6] ^
-                   addr[7] ^ addr[8] ^ addr[9] ^ addr[10] ^ addr[11] ^ addr[12] ^
-                   addr[13] ^ addr[14] ^ addr[15] ^ addr[16];
-
-               return x & (NAT25_HASH_SIZE - 1);
-       } else {
-               unsigned long x = 0;
-               int i;
-
-               for (i = 0; i < MAX_NETWORK_ADDR_LEN; i++)
-                       x ^= addr[i];
-
-               return x & (NAT25_HASH_SIZE - 1);
-       }
-}
-
-static void __network_hash_link(struct adapter *priv,
-                               struct nat25_network_db_entry *ent, int hash)
-{
-       /*  Caller must spin_lock already! */
-       ent->next_hash = priv->nethash[hash];
-       if (ent->next_hash)
-               ent->next_hash->pprev_hash = &ent->next_hash;
-       priv->nethash[hash] = ent;
-       ent->pprev_hash = &priv->nethash[hash];
-}
-
-static void __network_hash_unlink(struct nat25_network_db_entry *ent)
-{
-       /*  Caller must spin_lock already! */
-       *ent->pprev_hash = ent->next_hash;
-       if (ent->next_hash)
-               ent->next_hash->pprev_hash = ent->pprev_hash;
-       ent->next_hash = NULL;
-       ent->pprev_hash = NULL;
-}
-
-static void __nat25_db_network_insert(struct adapter *priv,
-                               unsigned char *mac_addr, unsigned char *addr)
-{
-       struct nat25_network_db_entry *db;
-       int hash;
-
-       spin_lock_bh(&priv->br_ext_lock);
-       hash = __nat25_network_hash(addr);
-       db = priv->nethash[hash];
-       while (db) {
-               if (!memcmp(db->networkAddr, addr, MAX_NETWORK_ADDR_LEN)) {
-                       memcpy(db->macAddr, mac_addr, ETH_ALEN);
-                       db->ageing_timer = jiffies;
-                       spin_unlock_bh(&priv->br_ext_lock);
-                       return;
-               }
-               db = db->next_hash;
-       }
-       db = kmalloc(sizeof(*db), GFP_ATOMIC);
-       if (!db) {
-               spin_unlock_bh(&priv->br_ext_lock);
-               return;
-       }
-       memcpy(db->networkAddr, addr, MAX_NETWORK_ADDR_LEN);
-       memcpy(db->macAddr, mac_addr, ETH_ALEN);
-       atomic_set(&db->use_count, 1);
-       db->ageing_timer = jiffies;
-
-       __network_hash_link(priv, db, hash);
-
-       spin_unlock_bh(&priv->br_ext_lock);
-}
-
-/*
- *     NAT2.5 interface
- */
-
-void nat25_db_cleanup(struct adapter *priv)
-{
-       int i;
-
-       spin_lock_bh(&priv->br_ext_lock);
-
-       for (i = 0; i < NAT25_HASH_SIZE; i++) {
-               struct nat25_network_db_entry *f;
-
-               f = priv->nethash[i];
-               while (f) {
-                       struct nat25_network_db_entry *g;
-
-                       g = f->next_hash;
-                       if (priv->scdb_entry == f) {
-                               memset(priv->scdb_mac, 0, ETH_ALEN);
-                               memset(priv->scdb_ip, 0, 4);
-                               priv->scdb_entry = NULL;
-                       }
-                       __network_hash_unlink(f);
-                       kfree(f);
-                       f = g;
-               }
-       }
-       spin_unlock_bh(&priv->br_ext_lock);
-}
-
-void nat25_db_expire(struct adapter *priv)
-{
-       int i;
-
-       spin_lock_bh(&priv->br_ext_lock);
-
-       for (i = 0; i < NAT25_HASH_SIZE; i++) {
-               struct nat25_network_db_entry *f;
-
-               f = priv->nethash[i];
-               while (f) {
-                       struct nat25_network_db_entry *g;
-
-                       g = f->next_hash;
-                       if (__nat25_has_expired(f)) {
-                               if (atomic_dec_and_test(&f->use_count)) {
-                                       if (priv->scdb_entry == f) {
-                                               memset(priv->scdb_mac, 0, ETH_ALEN);
-                                               memset(priv->scdb_ip, 0, 4);
-                                               priv->scdb_entry = NULL;
-                                       }
-                                       __network_hash_unlink(f);
-                                       kfree(f);
-                               }
-                       }
-                       f = g;
-               }
-       }
-       spin_unlock_bh(&priv->br_ext_lock);
-}
-
-int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
-{
-       unsigned short protocol;
-       unsigned char addr[MAX_NETWORK_ADDR_LEN];
-       unsigned int tmp;
-
-       if (!skb)
-               return -1;
-
-       if ((method <= NAT25_MIN) || (method >= NAT25_MAX))
-               return -1;
-
-       protocol = be16_to_cpu(*((__be16 *)(skb->data + 2 * ETH_ALEN)));
-
-       /*---------------------------------------------------*/
-       /*                 Handle IP frame                   */
-       /*---------------------------------------------------*/
-       if (protocol == ETH_P_IP) {
-               struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN);
-
-               if (((unsigned char *)(iph) + (iph->ihl << 2)) >= (skb->data + ETH_HLEN + skb->len))
-                       return -1;
-
-               switch (method) {
-               case NAT25_CHECK:
-                       return -1;
-               case NAT25_INSERT:
-                       /* some multicast with source IP is all zero, maybe other case is illegal */
-                       /* in class A, B, C, host address is all zero or all one is illegal */
-                       if (iph->saddr == 0)
-                               return 0;
-                       tmp = be32_to_cpu(iph->saddr);
-                       __nat25_generate_ipv4_network_addr(addr, &tmp);
-                       /* record source IP address and , source mac address into db */
-                       __nat25_db_network_insert(priv, skb->data + ETH_ALEN, addr);
-                       return 0;
-               default:
-                       return -1;
-               }
-       } else if (protocol == ETH_P_ARP) {
-               /*---------------------------------------------------*/
-               /*                 Handle ARP frame                  */
-               /*---------------------------------------------------*/
-               struct arphdr *arp = (struct arphdr *)(skb->data + ETH_HLEN);
-               unsigned char *arp_ptr = (unsigned char *)(arp + 1);
-               unsigned int *sender;
-
-               if (arp->ar_pro != htons(ETH_P_IP))
-                       return -1;
-
-               switch (method) {
-               case NAT25_CHECK:
-                       return 0;       /*  skb_copy for all ARP frame */
-               case NAT25_INSERT:
-                       /*  change to ARP sender mac address to wlan STA address */
-                       memcpy(arp_ptr, GET_MY_HWADDR(priv), ETH_ALEN);
-                       arp_ptr += arp->ar_hln;
-                       sender = (unsigned int *)arp_ptr;
-                       __nat25_generate_ipv4_network_addr(addr, sender);
-                       __nat25_db_network_insert(priv, skb->data + ETH_ALEN, addr);
-                       return 0;
-               default:
-                       return -1;
-               }
-       } else if ((protocol == ETH_P_PPP_DISC) ||
-                  (protocol == ETH_P_PPP_SES)) {
-               /*---------------------------------------------------*/
-               /*                Handle PPPoE frame                 */
-               /*---------------------------------------------------*/
-               struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN);
-               __be16 *pMagic;
-
-               switch (method) {
-               case NAT25_CHECK:
-                       if (ph->sid == 0)
-                               return 0;
-                       return 1;
-               case NAT25_INSERT:
-                       if (ph->sid == 0) {     /*  Discovery phase according to tag */
-                               if (ph->code == PADI_CODE || ph->code == PADR_CODE) {
-                                       if (priv->ethBrExtInfo.addPPPoETag) {
-                                               struct pppoe_tag *tag, *pOldTag;
-                                               unsigned char tag_buf[40];
-                                               int old_tag_len = 0;
-
-                                               tag = (struct pppoe_tag *)tag_buf;
-                                               pOldTag = (struct pppoe_tag *)__nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID));
-                                               if (pOldTag) { /*  if SID existed, copy old value and delete it */
-                                                       old_tag_len = ntohs(pOldTag->tag_len);
-                                                       if (old_tag_len +
-                                                           TAG_HDR_LEN +
-                                                           MAGIC_CODE_LEN +
-                                                           RTL_RELAY_TAG_LEN >
-                                                           sizeof(tag_buf))
-                                                               return -1;
-
-                                                       memcpy(tag->tag_data + MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN,
-                                                               pOldTag->tag_data, old_tag_len);
-
-                                                       if (skb_pull_and_merge(skb, (unsigned char *)pOldTag, TAG_HDR_LEN + old_tag_len) < 0)
-                                                               return -1;
-
-                                                       ph->length = htons(ntohs(ph->length) - TAG_HDR_LEN - old_tag_len);
-                                               }
-
-                                               tag->tag_type = PTT_RELAY_SID;
-                                               tag->tag_len = htons(MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN + old_tag_len);
-
-                                               /*  insert the magic_code+client mac in relay tag */
-                                               pMagic = (__be16 *)tag->tag_data;
-                                               *pMagic = htons(MAGIC_CODE);
-                                               memcpy(tag->tag_data + MAGIC_CODE_LEN, skb->data + ETH_ALEN, ETH_ALEN);
-
-                                               /* Add relay tag */
-                                               if (__nat25_add_pppoe_tag(skb, tag) < 0)
-                                                       return -1;
-                                       } else { /*  not add relay tag */
-                                               if (priv->pppoe_connection_in_progress &&
-                                                   memcmp(skb->data + ETH_ALEN,
-                                                          priv->pppoe_addr,
-                                                          ETH_ALEN))
-                                                       return -2;
-
-                                               if (priv->pppoe_connection_in_progress == 0)
-                                                       memcpy(priv->pppoe_addr, skb->data + ETH_ALEN, ETH_ALEN);
-
-                                               priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE;
-                                       }
-                               } else {
-                                       return -1;
-                               }
-                       } else {        /*  session phase */
-                               __nat25_generate_pppoe_network_addr(addr, skb->data, &ph->sid);
-
-                               __nat25_db_network_insert(priv, skb->data + ETH_ALEN, addr);
-
-                               if (!priv->ethBrExtInfo.addPPPoETag &&
-                                   priv->pppoe_connection_in_progress &&
-                                   !memcmp(skb->data + ETH_ALEN, priv->pppoe_addr, ETH_ALEN))
-                                       priv->pppoe_connection_in_progress = 0;
-                       }
-                       return 0;
-               default:
-                       return -1;
-               }
-       } else if (protocol == 0x888e) {
-               /*---------------------------------------------------*/
-               /*                 Handle EAP frame                  */
-               /*---------------------------------------------------*/
-               switch (method) {
-               case NAT25_CHECK:
-                       return -1;
-               case NAT25_INSERT:
-                       return 0;
-               default:
-                       return -1;
-               }
-       } else if ((protocol == 0xe2ae) || (protocol == 0xe2af)) {
-               /*---------------------------------------------------*/
-               /*         Handle C-Media proprietary frame          */
-               /*---------------------------------------------------*/
-               switch (method) {
-               case NAT25_CHECK:
-                       return -1;
-               case NAT25_INSERT:
-                       return 0;
-               default:
-                       return -1;
-               }
-       } else if (protocol == ETH_P_IPV6) {
-               /*------------------------------------------------*/
-               /*         Handle IPV6 frame                      */
-               /*------------------------------------------------*/
-               struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN);
-
-               if (sizeof(*iph) >= (skb->len - ETH_HLEN))
-                       return -1;
-
-               switch (method) {
-               case NAT25_CHECK:
-                       if (skb->data[0] & 1)
-                               return 0;
-                       return -1;
-               case NAT25_INSERT:
-                       if (memcmp(&iph->saddr, "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", 16)) {
-                               __nat25_generate_ipv6_network_addr(addr, (unsigned int *)&iph->saddr);
-                               __nat25_db_network_insert(priv, skb->data + ETH_ALEN, addr);
-
-                               if (iph->nexthdr == IPPROTO_ICMPV6 &&
-                                               skb->len > (ETH_HLEN +  sizeof(*iph) + 4)) {
-                                       if (update_nd_link_layer_addr(skb->data + ETH_HLEN + sizeof(*iph),
-                                                                     skb->len - ETH_HLEN - sizeof(*iph), GET_MY_HWADDR(priv))) {
-                                               struct icmp6hdr  *hdr = (struct icmp6hdr *)(skb->data + ETH_HLEN + sizeof(*iph));
-                                               hdr->icmp6_cksum = 0;
-                                               hdr->icmp6_cksum = csum_ipv6_magic(&iph->saddr, &iph->daddr,
-                                                                               be16_to_cpu(iph->payload_len),
-                                                                               IPPROTO_ICMPV6,
-                                                                               csum_partial((__u8 *)hdr,
-                                                                               be16_to_cpu(iph->payload_len),
-                                                                               0));
-                                       }
-                               }
-                       }
-                       return 0;
-               default:
-                       return -1;
-               }
-       }
-       return -1;
-}
-
-#define SERVER_PORT                    67
-#define CLIENT_PORT                    68
-#define DHCP_MAGIC                     0x63825363
-#define BROADCAST_FLAG         0x8000
-
-struct dhcpMessage {
-       u_int8_t op;
-       u_int8_t htype;
-       u_int8_t hlen;
-       u_int8_t hops;
-       u_int32_t xid;
-       __be16 secs;
-       __be16 flags;
-       __be32 ciaddr;
-       __be32 yiaddr;
-       __be32 siaddr;
-       __be32 giaddr;
-       u_int8_t chaddr[16];
-       u_int8_t sname[64];
-       u_int8_t file[128];
-       __be32 cookie;
-       u_int8_t options[308]; /* 312 - cookie */
-};
-
-void dhcp_flag_bcast(struct adapter *priv, struct sk_buff *skb)
-{
-       if (!skb)
-               return;
-
-       if (!priv->ethBrExtInfo.dhcp_bcst_disable) {
-               __be16 protocol = *((__be16 *)(skb->data + 2 * ETH_ALEN));
-
-               if (protocol == htons(ETH_P_IP)) { /*  IP */
-                       struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN);
-
-                       if (iph->protocol == IPPROTO_UDP) { /*  UDP */
-                               struct udphdr *udph = (void *)iph + (iph->ihl << 2);
-
-                               if ((udph->source == htons(CLIENT_PORT)) &&
-                                   (udph->dest == htons(SERVER_PORT))) { /*  DHCP request */
-                                       struct dhcpMessage *dhcph = (void *)udph + sizeof(struct udphdr);
-                                       u32 cookie = be32_to_cpu(dhcph->cookie);
-
-                                       if (cookie == DHCP_MAGIC) { /*  match magic word */
-                                               if (!(dhcph->flags & htons(BROADCAST_FLAG))) {
-                                                       /*  if not broadcast */
-                                                       register int sum = 0;
-
-                                                       /*  or BROADCAST flag */
-                                                       dhcph->flags |= htons(BROADCAST_FLAG);
-                                                       /*  recalculate checksum */
-                                                       sum = ~(udph->check) & 0xffff;
-                                                       sum += be16_to_cpu(dhcph->flags);
-                                                       while (sum >> 16)
-                                                               sum = (sum & 0xffff) + (sum >> 16);
-                                                       udph->check = ~sum;
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-}
-
-void *scdb_findEntry(struct adapter *priv, unsigned char *ip_addr)
-{
-       unsigned char addr[MAX_NETWORK_ADDR_LEN];
-       struct nat25_network_db_entry *db;
-       int hash;
-
-       __nat25_generate_ipv4_network_addr(addr, (unsigned int *)ip_addr);
-       hash = __nat25_network_hash(addr);
-       db = priv->nethash[hash];
-       while (db) {
-               if (!memcmp(db->networkAddr, addr, MAX_NETWORK_ADDR_LEN))
-                       return (void *)db;
-
-               db = db->next_hash;
-       }
-
-       return NULL;
-}
diff --git a/drivers/staging/r8188eu/core/rtw_cmd.c b/drivers/staging/r8188eu/core/rtw_cmd.c
deleted file mode 100644 (file)
index ca9e3d4..0000000
+++ /dev/null
@@ -1,1529 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-#define _RTW_CMD_C_
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/rtw_br_ext.h"
-#include "../include/rtw_mlme_ext.h"
-#include "../include/rtl8188e_dm.h"
-
-/* Caller and the rtw_cmd_thread can protect cmd_q by spin_lock.
- * No irqsave is necessary.
- */
-
-static void c2h_wk_callback(struct work_struct *work);
-
-void rtw_free_evt_priv(struct  evt_priv *pevtpriv)
-{
-       cancel_work_sync(&pevtpriv->c2h_wk);
-       while (pevtpriv->c2h_wk_alive)
-               msleep(10);
-
-       while (!rtw_cbuf_empty(pevtpriv->c2h_queue)) {
-               void *c2h = rtw_cbuf_pop(pevtpriv->c2h_queue);
-               if (c2h && c2h != (void *)pevtpriv)
-                       kfree(c2h);
-       }
-}
-
-int rtw_init_cmd_priv(struct cmd_priv *pcmdpriv)
-{
-       init_completion(&pcmdpriv->enqueue_cmd);
-       /* sema_init(&(pcmdpriv->cmd_done_sema), 0); */
-       init_completion(&pcmdpriv->start_cmd_thread);
-       init_completion(&pcmdpriv->stop_cmd_thread);
-
-       rtw_init_queue(&pcmdpriv->cmd_queue);
-
-       /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
-
-       pcmdpriv->cmd_allocated_buf = kzalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ,
-                                             GFP_KERNEL);
-
-       if (!pcmdpriv->cmd_allocated_buf)
-               return -ENOMEM;
-
-       pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf  +  CMDBUFF_ALIGN_SZ - ((size_t)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ - 1));
-
-       pcmdpriv->rsp_allocated_buf = kzalloc(MAX_RSPSZ + 4, GFP_KERNEL);
-
-       if (!pcmdpriv->rsp_allocated_buf) {
-               kfree(pcmdpriv->cmd_allocated_buf);
-               return -ENOMEM;
-       }
-
-       pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf  +  4 - ((size_t)(pcmdpriv->rsp_allocated_buf) & 3);
-
-       pcmdpriv->cmd_done_cnt = 0;
-       pcmdpriv->rsp_cnt = 0;
-
-       return 0;
-}
-
-int rtw_init_evt_priv(struct evt_priv *pevtpriv)
-{
-       /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
-       atomic_set(&pevtpriv->event_seq, 0);
-
-       INIT_WORK(&pevtpriv->c2h_wk, c2h_wk_callback);
-       pevtpriv->c2h_wk_alive = false;
-       pevtpriv->c2h_queue = rtw_cbuf_alloc(C2H_QUEUE_MAX_LEN + 1);
-       if (!pevtpriv->c2h_queue)
-               return -ENOMEM;
-
-       return 0;
-}
-
-void rtw_free_cmd_priv(struct  cmd_priv *pcmdpriv)
-{
-       if (pcmdpriv) {
-               kfree(pcmdpriv->cmd_allocated_buf);
-               kfree(pcmdpriv->rsp_allocated_buf);
-       }
-}
-
-static int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
-{
-       u8 bAllow = false; /* set to true to allow enqueuing cmd when hw_init_completed is false */
-
-       if (cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan))
-               bAllow = true;
-
-       if ((!pcmdpriv->padapter->hw_init_completed && !bAllow) ||
-           !pcmdpriv->cmdthd_running)  /* com_thread not running */
-               return _FAIL;
-       return _SUCCESS;
-}
-
-u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
-{
-       unsigned long flags;
-       struct adapter *padapter = pcmdpriv->padapter;
-
-       if (!cmd_obj)
-               return _FAIL;
-
-       cmd_obj->padapter = padapter;
-
-       if (rtw_cmd_filter(pcmdpriv, cmd_obj) == _FAIL) {
-               rtw_free_cmd_obj(cmd_obj);
-               return _FAIL;
-       }
-
-       spin_lock_irqsave(&pcmdpriv->cmd_queue.lock, flags);
-       list_add_tail(&cmd_obj->list, &pcmdpriv->cmd_queue.queue);
-       spin_unlock_irqrestore(&pcmdpriv->cmd_queue.lock, flags);
-
-       complete(&pcmdpriv->enqueue_cmd);
-       return _SUCCESS;
-}
-
-struct cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv)
-{
-       struct cmd_obj *obj;
-       struct __queue *queue = &pcmdpriv->cmd_queue;
-       unsigned long flags;
-
-       spin_lock_irqsave(&queue->lock, flags);
-       if (list_empty(&queue->queue)) {
-               obj = NULL;
-       } else {
-               obj = container_of((&queue->queue)->next, struct cmd_obj, list);
-               list_del_init(&obj->list);
-       }
-
-       spin_unlock_irqrestore(&queue->lock, flags);
-
-       return obj;
-}
-
-void rtw_free_cmd_obj(struct cmd_obj *pcmd)
-{
-
-       if ((pcmd->cmdcode != _JoinBss_CMD_) && (pcmd->cmdcode != _CreateBss_CMD_)) {
-               /* free parmbuf in cmd_obj */
-               kfree(pcmd->parmbuf);
-       }
-
-       if (pcmd->rsp) {
-               if (pcmd->rspsz != 0) {
-                       /* free rsp in cmd_obj */
-                       kfree(pcmd->rsp);
-               }
-       }
-
-       /* free cmd_obj */
-       kfree(pcmd);
-
-}
-
-int rtw_cmd_thread(void *context)
-{
-       u8 ret;
-       struct cmd_obj *pcmd;
-       u8 *pcmdbuf;
-       u8 (*cmd_hdl)(struct adapter *padapter, u8 *pbuf);
-       void (*pcmd_callback)(struct adapter *dev, struct cmd_obj *pcmd);
-       struct adapter *padapter = (struct adapter *)context;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-
-       pcmdbuf = pcmdpriv->cmd_buf;
-
-       pcmdpriv->cmdthd_running = true;
-       complete(&pcmdpriv->start_cmd_thread);
-
-       while (1) {
-               wait_for_completion(&pcmdpriv->enqueue_cmd);
-
-_next:
-               if (padapter->bDriverStopped ||
-                   padapter->bSurpriseRemoved)
-                       break;
-
-               pcmd = rtw_dequeue_cmd(pcmdpriv);
-               if (!pcmd)
-                       continue;
-
-               if (rtw_cmd_filter(pcmdpriv, pcmd) == _FAIL) {
-                       pcmd->res = H2C_DROPPED;
-                       goto post_process;
-               }
-
-               pcmd->cmdsz = round_up(pcmd->cmdsz, 4);
-
-               memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz);
-
-               if (pcmd->cmdcode < ARRAY_SIZE(wlancmds)) {
-                       cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns;
-
-                       if (cmd_hdl) {
-                               ret = cmd_hdl(pcmd->padapter, pcmdbuf);
-                               pcmd->res = ret;
-                       }
-               } else {
-                       pcmd->res = H2C_PARAMETERS_ERROR;
-               }
-
-               cmd_hdl = NULL;
-
-post_process:
-
-               /* call callback function for post-processed */
-               if (pcmd->cmdcode < ARRAY_SIZE(rtw_cmd_callback)) {
-                       pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback;
-                       if (!pcmd_callback)
-                               rtw_free_cmd_obj(pcmd);
-                       else
-                               /* todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!= NULL) */
-                               pcmd_callback(pcmd->padapter, pcmd);/* need consider that free cmd_obj in rtw_cmd_callback */
-               } else {
-                       rtw_free_cmd_obj(pcmd);
-               }
-
-               flush_signals_thread();
-
-               goto _next;
-       }
-       pcmdpriv->cmdthd_running = false;
-
-       /*  free all cmd_obj resources */
-       do {
-               pcmd = rtw_dequeue_cmd(pcmdpriv);
-               if (!pcmd)
-                       break;
-
-               rtw_free_cmd_obj(pcmd);
-       } while (1);
-
-       complete(&pcmdpriv->stop_cmd_thread);
-
-       return 0;
-}
-
-/* rtw_sitesurvey_cmd(~)
- *     ### NOTE:#### (!!!!)
- *     MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock
- */
-u8 rtw_sitesurvey_cmd(struct adapter  *padapter, struct ndis_802_11_ssid *ssid, int ssid_num)
-{
-       u8 res = _FAIL;
-       struct cmd_obj          *ph2c;
-       struct sitesurvey_parm  *psurveyPara;
-       struct cmd_priv         *pcmdpriv = &padapter->cmdpriv;
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-
-       if (check_fwstate(pmlmepriv, _FW_LINKED))
-               rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1);
-
-       if (check_fwstate(pmlmepriv, _FW_LINKED))
-               p2p_ps_wk_cmd(padapter, P2P_PS_SCAN, 1);
-
-       ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
-       if (!ph2c)
-               return _FAIL;
-
-       psurveyPara = kzalloc(sizeof(*psurveyPara), GFP_ATOMIC);
-       if (!psurveyPara) {
-               kfree(ph2c);
-               return _FAIL;
-       }
-
-       rtw_free_network_queue(padapter, false);
-
-       init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
-
-       /* psurveyPara->bsslimit = 48; */
-       psurveyPara->scan_mode = pmlmepriv->scan_mode;
-
-       /* prepare ssid list */
-       if (ssid) {
-               int i;
-               for (i = 0; i < ssid_num && i < RTW_SSID_SCAN_AMOUNT; i++) {
-                       if (ssid[i].SsidLength) {
-                               memcpy(&psurveyPara->ssid[i], &ssid[i], sizeof(struct ndis_802_11_ssid));
-                               psurveyPara->ssid_num++;
-                       }
-               }
-       }
-
-       set_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
-
-       res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-
-       if (res == _SUCCESS) {
-               pmlmepriv->scan_start_time = jiffies;
-
-               _set_timer(&pmlmepriv->scan_to_timer, SCANNING_TIMEOUT);
-
-               rtw_led_control(padapter, LED_CTL_SITE_SURVEY);
-
-               pmlmepriv->scan_interval = SCAN_INTERVAL;/*  30*2 sec = 60sec */
-       } else {
-               _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
-       }
-
-       return res;
-}
-
-int rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset)
-{
-       struct cmd_obj *ph2c;
-       struct setdatarate_parm *pbsetdataratepara;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-
-       ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
-       if (!ph2c)
-               return -ENOMEM;
-
-       pbsetdataratepara = kzalloc(sizeof(*pbsetdataratepara), GFP_ATOMIC);
-       if (!pbsetdataratepara) {
-               kfree(ph2c);
-               return -ENOMEM;
-       }
-
-       init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, GEN_CMD_CODE(_SetDataRate));
-       pbsetdataratepara->mac_id = 5;
-       memcpy(pbsetdataratepara->datarates, rateset, NumRates);
-       if (rtw_enqueue_cmd(pcmdpriv, ph2c) == _FAIL)
-               return -EPERM;
-
-       return 0;
-}
-
-void rtw_getbbrfreg_cmdrsp_callback(struct adapter *padapter,  struct cmd_obj *pcmd)
-{
-
-
-       kfree(pcmd->parmbuf);
-       kfree(pcmd);
-}
-
-u8 rtw_createbss_cmd(struct adapter  *padapter)
-{
-       struct cmd_obj *pcmd;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-       struct wlan_bssid_ex *pdev_network = &padapter->registrypriv.dev_network;
-       u8      res = _SUCCESS;
-
-       rtw_led_control(padapter, LED_CTL_START_TO_LINK);
-
-       pcmd = kzalloc(sizeof(*pcmd), GFP_ATOMIC);
-       if (!pcmd) {
-               res = _FAIL;
-               goto exit;
-       }
-
-       INIT_LIST_HEAD(&pcmd->list);
-       pcmd->cmdcode = _CreateBss_CMD_;
-       pcmd->parmbuf = (unsigned char *)pdev_network;
-       pcmd->cmdsz = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pdev_network);
-       pcmd->rsp = NULL;
-       pcmd->rspsz = 0;
-       pdev_network->Length = pcmd->cmdsz;
-       res = rtw_enqueue_cmd(pcmdpriv, pcmd);
-exit:
-
-       return res;
-}
-
-u8 rtw_joinbss_cmd(struct adapter  *padapter, struct wlan_network *pnetwork)
-{
-       u8      res = _SUCCESS;
-       uint    t_len = 0;
-       struct wlan_bssid_ex            *psecnetwork;
-       struct cmd_obj          *pcmd;
-       struct cmd_priv         *pcmdpriv = &padapter->cmdpriv;
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-       struct qos_priv         *pqospriv = &pmlmepriv->qospriv;
-       struct security_priv    *psecuritypriv = &padapter->securitypriv;
-       struct registry_priv    *pregistrypriv = &padapter->registrypriv;
-       struct ht_priv          *phtpriv = &pmlmepriv->htpriv;
-       enum ndis_802_11_network_infra ndis_network_mode = pnetwork->network.InfrastructureMode;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       rtw_led_control(padapter, LED_CTL_START_TO_LINK);
-
-       pcmd = kzalloc(sizeof(*pcmd), GFP_ATOMIC);
-       if (!pcmd) {
-               res = _FAIL;
-               goto exit;
-       }
-       /* for IEs is fix buf size */
-       t_len = sizeof(struct wlan_bssid_ex);
-
-       /* for hidden ap to set fw_state here */
-       if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE)) {
-               switch (ndis_network_mode) {
-               case Ndis802_11IBSS:
-                       set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
-                       break;
-               case Ndis802_11Infrastructure:
-                       set_fwstate(pmlmepriv, WIFI_STATION_STATE);
-                       break;
-               case Ndis802_11APMode:
-               case Ndis802_11AutoUnknown:
-               case Ndis802_11InfrastructureMax:
-                       break;
-               }
-       }
-
-       psecnetwork = (struct wlan_bssid_ex *)&psecuritypriv->sec_bss;
-       if (!psecnetwork) {
-               kfree(pcmd);
-               res = _FAIL;
-               goto exit;
-       }
-
-       memset(psecnetwork, 0, t_len);
-
-       memcpy(psecnetwork, &pnetwork->network, get_wlan_bssid_ex_sz(&pnetwork->network));
-
-       psecuritypriv->authenticator_ie[0] = (unsigned char)psecnetwork->IELength;
-
-       if (psecnetwork->IELength - 12 < 255)
-               memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], psecnetwork->IELength - 12);
-       else
-               memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], 255);
-
-       psecnetwork->IELength = 0;
-       /*  Added by Albert 2009/02/18 */
-       /*  If the driver wants to use the bssid to create the connection. */
-       /*  If not,  we have to copy the connecting AP's MAC address to it so that */
-       /*  the driver just has the bssid information for PMKIDList searching. */
-
-       if (!pmlmepriv->assoc_by_bssid)
-               memcpy(&pmlmepriv->assoc_bssid[0], &pnetwork->network.MacAddress[0], ETH_ALEN);
-
-       psecnetwork->IELength = rtw_restruct_sec_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength);
-
-       pqospriv->qos_option = 0;
-
-       if (pregistrypriv->wmm_enable) {
-               u32 tmp_len;
-
-               tmp_len = rtw_restruct_wmm_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength, psecnetwork->IELength);
-
-               if (psecnetwork->IELength != tmp_len) {
-                       psecnetwork->IELength = tmp_len;
-                       pqospriv->qos_option = 1; /* There is WMM IE in this corresp. beacon */
-               } else {
-                       pqospriv->qos_option = 0;/* There is no WMM IE in this corresp. beacon */
-               }
-       }
-
-       phtpriv->ht_option = false;
-       if (pregistrypriv->ht_enable) {
-               /*      Added by Albert 2010/06/23 */
-               /*      For the WEP mode, we will use the bg mode to do the connection to avoid some IOT issue. */
-               /*      Especially for Realtek 8192u SoftAP. */
-               if ((padapter->securitypriv.dot11PrivacyAlgrthm != _WEP40_) &&
-                   (padapter->securitypriv.dot11PrivacyAlgrthm != _WEP104_) &&
-                   (padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_)) {
-                       /* rtw_restructure_ht_ie */
-                       rtw_restructure_ht_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0],
-                                                                       pnetwork->network.IELength, &psecnetwork->IELength);
-               }
-       }
-
-       pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->network.IEs, pnetwork->network.IELength);
-
-       if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_TENDA)
-               padapter->pwrctrlpriv.smart_ps = 0;
-       else
-               padapter->pwrctrlpriv.smart_ps = padapter->registrypriv.smart_ps;
-
-       pcmd->cmdsz = get_wlan_bssid_ex_sz(psecnetwork);/* get cmdsz before endian conversion */
-
-       INIT_LIST_HEAD(&pcmd->list);
-       pcmd->cmdcode = _JoinBss_CMD_;/* GEN_CMD_CODE(_JoinBss) */
-       pcmd->parmbuf = (unsigned char *)psecnetwork;
-       pcmd->rsp = NULL;
-       pcmd->rspsz = 0;
-
-       res = rtw_enqueue_cmd(pcmdpriv, pcmd);
-
-exit:
-
-       return res;
-}
-
-u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueue) /* for sta_mode */
-{
-       struct cmd_obj *cmdobj = NULL;
-       struct disconnect_parm *param = NULL;
-       struct cmd_priv *cmdpriv = &padapter->cmdpriv;
-       u8 res = _SUCCESS;
-
-       /* prepare cmd parameter */
-       param = kzalloc(sizeof(*param), GFP_ATOMIC);
-       if (!param) {
-               res = _FAIL;
-               goto exit;
-       }
-       param->deauth_timeout_ms = deauth_timeout_ms;
-
-       if (enqueue) {
-               /* need enqueue, prepare cmd_obj and enqueue */
-               cmdobj = kzalloc(sizeof(*cmdobj), GFP_ATOMIC);
-               if (!cmdobj) {
-                       res = _FAIL;
-                       kfree(param);
-                       goto exit;
-               }
-               init_h2fwcmd_w_parm_no_rsp(cmdobj, param, _DisConnect_CMD_);
-               res = rtw_enqueue_cmd(cmdpriv, cmdobj);
-       } else {
-               /* no need to enqueue, do the cmd hdl directly and free cmd parameter */
-               if (disconnect_hdl(padapter, (u8 *)param) != H2C_SUCCESS)
-                       res = _FAIL;
-               kfree(param);
-       }
-
-exit:
-
-       return res;
-}
-
-u8 rtw_setopmode_cmd(struct adapter  *padapter, enum ndis_802_11_network_infra networktype)
-{
-       struct  cmd_obj *ph2c;
-       struct  setopmode_parm *psetop;
-
-       struct  cmd_priv   *pcmdpriv = &padapter->cmdpriv;
-       u8      res = _SUCCESS;
-
-       ph2c = kzalloc(sizeof(*ph2c), GFP_KERNEL);
-       if (!ph2c) {
-               res = false;
-               goto exit;
-       }
-       psetop = kzalloc(sizeof(*psetop), GFP_KERNEL);
-
-       if (!psetop) {
-               kfree(ph2c);
-               res = false;
-               goto exit;
-       }
-
-       init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_);
-       psetop->mode = (u8)networktype;
-
-       res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-
-exit:
-
-       return res;
-}
-
-u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key)
-{
-       struct cmd_obj *ph2c;
-       struct set_stakey_parm *psetstakey_para;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-       struct set_stakey_rsp *psetstakey_rsp = NULL;
-
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct security_priv *psecuritypriv = &padapter->securitypriv;
-       struct sta_info *sta = (struct sta_info *)psta;
-       u8      res = _SUCCESS;
-
-       ph2c = kzalloc(sizeof(*ph2c), GFP_KERNEL);
-       if (!ph2c) {
-               res = _FAIL;
-               goto exit;
-       }
-
-       psetstakey_para = kzalloc(sizeof(*psetstakey_para), GFP_KERNEL);
-       if (!psetstakey_para) {
-               kfree(ph2c);
-               res = _FAIL;
-               goto exit;
-       }
-
-       psetstakey_rsp = kzalloc(sizeof(*psetstakey_rsp), GFP_KERNEL);
-       if (!psetstakey_rsp) {
-               kfree(ph2c);
-               kfree(psetstakey_para);
-               res = _FAIL;
-               goto exit;
-       }
-
-       init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
-       ph2c->rsp = (u8 *)psetstakey_rsp;
-       ph2c->rspsz = sizeof(struct set_stakey_rsp);
-
-       memcpy(psetstakey_para->addr, sta->hwaddr, ETH_ALEN);
-
-       if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
-               psetstakey_para->algorithm = (unsigned char)psecuritypriv->dot11PrivacyAlgrthm;
-       else
-               GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, false);
-
-       if (unicast_key)
-               memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16);
-       else
-               memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16);
-
-       /* jeff: set this because at least sw key is ready */
-       padapter->securitypriv.busetkipkey = true;
-
-       res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-
-exit:
-
-       return res;
-}
-
-u8 rtw_clearstakey_cmd(struct adapter *padapter, u8 *psta, u8 entry, u8 enqueue)
-{
-       struct cmd_obj *ph2c;
-       struct set_stakey_parm  *psetstakey_para;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-       struct set_stakey_rsp *psetstakey_rsp = NULL;
-       struct sta_info *sta = (struct sta_info *)psta;
-       u8      res = _SUCCESS;
-
-       if (!enqueue) {
-               clear_cam_entry(padapter, entry);
-       } else {
-               ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
-               if (!ph2c) {
-                       res = _FAIL;
-                       goto exit;
-               }
-
-               psetstakey_para = kzalloc(sizeof(*psetstakey_para),
-                                         GFP_ATOMIC);
-               if (!psetstakey_para) {
-                       kfree(ph2c);
-                       res = _FAIL;
-                       goto exit;
-               }
-
-               psetstakey_rsp = kzalloc(sizeof(*psetstakey_rsp),
-                                        GFP_ATOMIC);
-               if (!psetstakey_rsp) {
-                       kfree(ph2c);
-                       kfree(psetstakey_para);
-                       res = _FAIL;
-                       goto exit;
-               }
-
-               init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
-               ph2c->rsp = (u8 *)psetstakey_rsp;
-               ph2c->rspsz = sizeof(struct set_stakey_rsp);
-
-               memcpy(psetstakey_para->addr, sta->hwaddr, ETH_ALEN);
-
-               psetstakey_para->algorithm = _NO_PRIVACY_;
-
-               psetstakey_para->id = entry;
-
-               res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-       }
-exit:
-
-       return res;
-}
-
-u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr)
-{
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-       struct cmd_obj *ph2c;
-       struct addBaReq_parm *paddbareq_parm;
-       u8      res = _SUCCESS;
-
-       ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
-       if (!ph2c) {
-               res = _FAIL;
-               goto exit;
-       }
-
-       paddbareq_parm = kzalloc(sizeof(*paddbareq_parm), GFP_ATOMIC);
-       if (!paddbareq_parm) {
-               kfree(ph2c);
-               res = _FAIL;
-               goto exit;
-       }
-
-       paddbareq_parm->tid = tid;
-       memcpy(paddbareq_parm->addr, addr, ETH_ALEN);
-
-       init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, GEN_CMD_CODE(_AddBAReq));
-
-       /* rtw_enqueue_cmd(pcmdpriv, ph2c); */
-       res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-
-exit:
-
-       return res;
-}
-
-u8 rtw_dynamic_chk_wk_cmd(struct adapter *padapter)
-{
-       struct cmd_obj *ph2c;
-       struct drvextra_cmd_parm *pdrvextra_cmd_parm;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-       u8      res = _SUCCESS;
-
-       ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
-       if (!ph2c) {
-               res = _FAIL;
-               goto exit;
-       }
-
-       pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_cmd_parm), GFP_ATOMIC);
-       if (!pdrvextra_cmd_parm) {
-               kfree(ph2c);
-               res = _FAIL;
-               goto exit;
-       }
-
-       pdrvextra_cmd_parm->ec_id = DYNAMIC_CHK_WK_CID;
-       pdrvextra_cmd_parm->type_size = 0;
-       pdrvextra_cmd_parm->pbuf = (u8 *)padapter;
-
-       init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
-
-       /* rtw_enqueue_cmd(pcmdpriv, ph2c); */
-       res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-exit:
-
-       return res;
-}
-
-u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan)
-{
-       struct  cmd_obj *pcmdobj;
-       struct  SetChannelPlan_param *setChannelPlan_param;
-       struct  cmd_priv   *pcmdpriv = &padapter->cmdpriv;
-
-       u8      res = _SUCCESS;
-
-       /* check input parameter */
-       if (!rtw_is_channel_plan_valid(chplan)) {
-               res = _FAIL;
-               goto exit;
-       }
-
-       /* prepare cmd parameter */
-       setChannelPlan_param = kzalloc(sizeof(*setChannelPlan_param),
-                                      GFP_KERNEL);
-       if (!setChannelPlan_param) {
-               res = _FAIL;
-               goto exit;
-       }
-       setChannelPlan_param->channel_plan = chplan;
-
-       /* need enqueue, prepare cmd_obj and enqueue */
-       pcmdobj = kzalloc(sizeof(*pcmdobj), GFP_KERNEL);
-       if (!pcmdobj) {
-               kfree(setChannelPlan_param);
-               res = _FAIL;
-               goto exit;
-       }
-
-       init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelPlan_param, GEN_CMD_CODE(_SetChannelPlan));
-       res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
-
-       /* do something based on res... */
-       if (res == _SUCCESS)
-               padapter->mlmepriv.ChannelPlan = chplan;
-
-exit:
-
-       return res;
-}
-
-static void traffic_status_watchdog(struct adapter *padapter)
-{
-       u8      bEnterPS;
-       u8      bBusyTraffic = false, bTxBusyTraffic = false, bRxBusyTraffic = false;
-       u8      bHigherBusyTraffic = false, bHigherBusyRxTraffic = false, bHigherBusyTxTraffic = false;
-       struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
-
-       /*  */
-       /*  Determine if our traffic is busy now */
-       /*  */
-       if (check_fwstate(pmlmepriv, _FW_LINKED)) {
-               if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 100 ||
-                   pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 100) {
-                       bBusyTraffic = true;
-
-                       if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod)
-                               bRxBusyTraffic = true;
-                       else
-                               bTxBusyTraffic = true;
-               }
-
-               /*  Higher Tx/Rx data. */
-               if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 4000 ||
-                   pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000) {
-                       bHigherBusyTraffic = true;
-
-                       if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod)
-                               bHigherBusyRxTraffic = true;
-                       else
-                               bHigherBusyTxTraffic = true;
-               }
-
-               /*  check traffic for  powersaving. */
-               if (((pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) > 8) ||
-                   (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 2))
-                       bEnterPS = false;
-               else
-                       bEnterPS = true;
-
-               /*  LeisurePS only work in infra mode. */
-               if (bEnterPS)
-                       LPS_Enter(padapter);
-               else
-                       LPS_Leave(padapter);
-       } else {
-               LPS_Leave(padapter);
-       }
-
-       pmlmepriv->LinkDetectInfo.NumRxOkInPeriod = 0;
-       pmlmepriv->LinkDetectInfo.NumTxOkInPeriod = 0;
-       pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod = 0;
-       pmlmepriv->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
-       pmlmepriv->LinkDetectInfo.bTxBusyTraffic = bTxBusyTraffic;
-       pmlmepriv->LinkDetectInfo.bRxBusyTraffic = bRxBusyTraffic;
-       pmlmepriv->LinkDetectInfo.bHigherBusyTraffic = bHigherBusyTraffic;
-       pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic = bHigherBusyRxTraffic;
-       pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic;
-}
-
-static void rtl8188e_sreset_xmit_status_check(struct adapter *padapter)
-{
-       u32 txdma_status;
-       int res;
-
-       res = rtw_read32(padapter, REG_TXDMA_STATUS, &txdma_status);
-       if (res)
-               return;
-
-       if (txdma_status != 0x00)
-               rtw_write32(padapter, REG_TXDMA_STATUS, txdma_status);
-       /* total xmit irp = 4 */
-}
-
-static void dynamic_chk_wk_hdl(struct adapter *padapter, u8 *pbuf)
-{
-       struct mlme_priv *pmlmepriv;
-
-       padapter = (struct adapter *)pbuf;
-       pmlmepriv = &padapter->mlmepriv;
-
-       if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
-               expire_timeout_chk(padapter);
-
-       rtl8188e_sreset_xmit_status_check(padapter);
-
-       linked_status_chk(padapter);
-       traffic_status_watchdog(padapter);
-
-       rtl8188e_HalDmWatchDog(padapter);
-}
-
-static void lps_ctrl_wk_hdl(struct adapter *padapter, u8 lps_ctrl_type)
-{
-       struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       u8      mstatus;
-
-       if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
-           check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))
-               return;
-
-       switch (lps_ctrl_type) {
-       case LPS_CTRL_SCAN:
-               if (check_fwstate(pmlmepriv, _FW_LINKED)) {
-                       /* connect */
-                       LPS_Leave(padapter);
-               }
-               break;
-       case LPS_CTRL_JOINBSS:
-               LPS_Leave(padapter);
-               break;
-       case LPS_CTRL_CONNECT:
-               mstatus = 1;/* connect */
-               /*  Reset LPS Setting */
-               padapter->pwrctrlpriv.LpsIdleCount = 0;
-               rtl8188e_set_FwJoinBssReport_cmd(padapter, mstatus);
-               break;
-       case LPS_CTRL_DISCONNECT:
-               mstatus = 0;/* disconnect */
-               LPS_Leave(padapter);
-               rtl8188e_set_FwJoinBssReport_cmd(padapter, mstatus);
-               break;
-       case LPS_CTRL_SPECIAL_PACKET:
-               pwrpriv->DelayLPSLastTimeStamp = jiffies;
-               LPS_Leave(padapter);
-               break;
-       case LPS_CTRL_LEAVE:
-               LPS_Leave(padapter);
-               break;
-       default:
-               break;
-       }
-
-}
-
-u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue)
-{
-       struct cmd_obj  *ph2c;
-       struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-       /* struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; */
-       u8      res = _SUCCESS;
-
-       /* if (!pwrctrlpriv->bLeisurePs) */
-       /*      return res; */
-
-       if (enqueue) {
-               ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
-               if (!ph2c) {
-                       res = _FAIL;
-                       goto exit;
-               }
-
-               pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_cmd_parm),
-                                            GFP_ATOMIC);
-               if (!pdrvextra_cmd_parm) {
-                       kfree(ph2c);
-                       res = _FAIL;
-                       goto exit;
-               }
-
-               pdrvextra_cmd_parm->ec_id = LPS_CTRL_WK_CID;
-               pdrvextra_cmd_parm->type_size = lps_ctrl_type;
-               pdrvextra_cmd_parm->pbuf = NULL;
-
-               init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
-
-               res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-       } else {
-               lps_ctrl_wk_hdl(padapter, lps_ctrl_type);
-       }
-
-exit:
-
-       return res;
-}
-
-static void rpt_timer_setting_wk_hdl(struct adapter *padapter, u16 min_time)
-{
-       struct hal_data_8188e *haldata = &padapter->haldata;
-       struct odm_dm_struct *odmpriv = &haldata->odmpriv;
-
-       ODM_RA_Set_TxRPT_Time(odmpriv, min_time);
-}
-
-u8 rtw_rpt_timer_cfg_cmd(struct adapter *padapter, u16 min_time)
-{
-       struct cmd_obj          *ph2c;
-       struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-
-       u8      res = _SUCCESS;
-
-       ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
-       if (!ph2c) {
-               res = _FAIL;
-               goto exit;
-       }
-
-       pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_cmd_parm),
-                                    GFP_ATOMIC);
-       if (!pdrvextra_cmd_parm) {
-               kfree(ph2c);
-               res = _FAIL;
-               goto exit;
-       }
-
-       pdrvextra_cmd_parm->ec_id = RTP_TIMER_CFG_WK_CID;
-       pdrvextra_cmd_parm->type_size = min_time;
-       pdrvextra_cmd_parm->pbuf = NULL;
-       init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
-       res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-exit:
-
-       return res;
-}
-
-static void antenna_select_wk_hdl(struct adapter *padapter, u8 antenna)
-{
-       struct hal_data_8188e *haldata = &padapter->haldata;
-
-       /* switch current antenna to optimum antenna */
-       if (haldata->CurAntenna != antenna) {
-               ODM_UpdateRxIdleAnt_88E(&haldata->odmpriv, antenna == 2 ? MAIN_ANT : AUX_ANT);
-               haldata->CurAntenna = antenna;
-       }
-}
-
-static bool rtw_antenna_diversity(struct adapter *adapter)
-{
-       struct hal_data_8188e *haldata = &adapter->haldata;
-
-       return haldata->AntDivCfg != 0;
-}
-
-u8 rtw_antenna_select_cmd(struct adapter *padapter, u8 antenna, u8 enqueue)
-{
-       struct cmd_obj          *ph2c;
-       struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-       u8      res = _SUCCESS;
-
-       if (!rtw_antenna_diversity(padapter))
-               return res;
-
-       if (enqueue) {
-               ph2c = kzalloc(sizeof(*ph2c), GFP_KERNEL);
-               if (!ph2c) {
-                       res = _FAIL;
-                       goto exit;
-               }
-
-               pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_cmd_parm),
-                                            GFP_KERNEL);
-               if (!pdrvextra_cmd_parm) {
-                       kfree(ph2c);
-                       res = _FAIL;
-                       goto exit;
-               }
-
-               pdrvextra_cmd_parm->ec_id = ANT_SELECT_WK_CID;
-               pdrvextra_cmd_parm->type_size = antenna;
-               pdrvextra_cmd_parm->pbuf = NULL;
-               init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
-
-               res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-       } else {
-               antenna_select_wk_hdl(padapter, antenna);
-       }
-exit:
-
-       return res;
-}
-
-u8 p2p_protocol_wk_cmd(struct adapter *padapter, int intCmdType)
-{
-       struct cmd_obj  *ph2c;
-       struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-       u8      res = _SUCCESS;
-
-       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
-               return res;
-
-       ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
-       if (!ph2c) {
-               res = _FAIL;
-               goto exit;
-       }
-
-       pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_cmd_parm), GFP_ATOMIC);
-       if (!pdrvextra_cmd_parm) {
-               kfree(ph2c);
-               res = _FAIL;
-               goto exit;
-       }
-
-       pdrvextra_cmd_parm->ec_id = P2P_PROTO_WK_CID;
-       pdrvextra_cmd_parm->type_size = intCmdType;     /*      As the command type. */
-       pdrvextra_cmd_parm->pbuf = NULL;                /*      Must be NULL here */
-
-       init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
-
-       res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-
-exit:
-
-       return res;
-}
-
-u8 rtw_ps_cmd(struct adapter *padapter)
-{
-       struct cmd_obj          *ppscmd;
-       struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-
-       u8      res = _SUCCESS;
-
-       ppscmd = kzalloc(sizeof(*ppscmd), GFP_ATOMIC);
-       if (!ppscmd) {
-               res = _FAIL;
-               goto exit;
-       }
-
-       pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_cmd_parm), GFP_ATOMIC);
-       if (!pdrvextra_cmd_parm) {
-               kfree(ppscmd);
-               res = _FAIL;
-               goto exit;
-       }
-
-       pdrvextra_cmd_parm->ec_id = POWER_SAVING_CTRL_WK_CID;
-       pdrvextra_cmd_parm->pbuf = NULL;
-       init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
-
-       res = rtw_enqueue_cmd(pcmdpriv, ppscmd);
-
-exit:
-
-       return res;
-}
-
-static bool rtw_is_hi_queue_empty(struct adapter *adapter)
-{
-       int res;
-       u32 reg;
-
-       res = rtw_read32(adapter, REG_HGQ_INFORMATION, &reg);
-       if (res)
-               return false;
-
-       return (reg & 0x0000ff00) == 0;
-}
-
-static void rtw_chk_hi_queue_hdl(struct adapter *padapter)
-{
-       int cnt = 0;
-       struct sta_info *psta_bmc;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-
-       psta_bmc = rtw_get_bcmc_stainfo(padapter);
-       if (!psta_bmc)
-               return;
-
-       if (psta_bmc->sleepq_len == 0) {
-               bool val = rtw_is_hi_queue_empty(padapter);
-
-               while (!val) {
-                       msleep(100);
-
-                       cnt++;
-
-                       if (cnt > 10)
-                               break;
-
-                       val = rtw_is_hi_queue_empty(padapter);
-               }
-
-               if (cnt <= 10) {
-                       pstapriv->tim_bitmap &= ~BIT(0);
-                       pstapriv->sta_dz_bitmap &= ~BIT(0);
-
-                       update_beacon(padapter, _TIM_IE_, NULL, false);
-               } else { /* re check again */
-                       rtw_chk_hi_queue_cmd(padapter);
-               }
-       }
-}
-
-void rtw_chk_hi_queue_cmd(struct adapter *padapter)
-{
-       struct cmd_obj  *ph2c;
-       struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-
-       ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
-       if (!ph2c)
-               return;
-
-       pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_cmd_parm), GFP_ATOMIC);
-       if (!pdrvextra_cmd_parm) {
-               kfree(ph2c);
-               return;
-       }
-
-       pdrvextra_cmd_parm->ec_id = CHECK_HIQ_WK_CID;
-       pdrvextra_cmd_parm->type_size = 0;
-       pdrvextra_cmd_parm->pbuf = NULL;
-
-       init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
-
-       rtw_enqueue_cmd(pcmdpriv, ph2c);
-}
-
-u8 rtw_c2h_wk_cmd(struct adapter *padapter, u8 *c2h_evt)
-{
-       struct cmd_obj *ph2c;
-       struct drvextra_cmd_parm *pdrvextra_cmd_parm;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-       u8      res = _SUCCESS;
-
-       ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
-       if (!ph2c) {
-               res = _FAIL;
-               goto exit;
-       }
-
-       pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_cmd_parm), GFP_ATOMIC);
-       if (!pdrvextra_cmd_parm) {
-               kfree(ph2c);
-               res = _FAIL;
-               goto exit;
-       }
-
-       pdrvextra_cmd_parm->ec_id = C2H_WK_CID;
-       pdrvextra_cmd_parm->type_size = c2h_evt ? 16 : 0;
-       pdrvextra_cmd_parm->pbuf = c2h_evt;
-
-       init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
-
-       res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-
-exit:
-
-       return res;
-}
-
-/* C2H event format:
- * Field    TRIGGER      CONTENT     CMD_SEQ    CMD_LEN    CMD_ID
- * BITS     [127:120]    [119:16]    [15:8]     [7:4]      [3:0]
- */
-static s32 c2h_evt_read(struct adapter *adapter, u8 *buf)
-{
-       s32 ret = _FAIL;
-       struct c2h_evt_hdr *c2h_evt;
-       int i;
-       u8 trigger;
-
-       if (!buf)
-               goto exit;
-
-       ret = rtw_read8(adapter, REG_C2HEVT_CLEAR, &trigger);
-       if (ret)
-               return _FAIL;
-
-       if (trigger == C2H_EVT_HOST_CLOSE)
-               goto exit; /* Not ready */
-       else if (trigger != C2H_EVT_FW_CLOSE)
-               goto clear_evt; /* Not a valid value */
-
-       c2h_evt = (struct c2h_evt_hdr *)buf;
-
-       memset(c2h_evt, 0, 16);
-
-       ret = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL, buf);
-       if (ret) {
-               ret = _FAIL;
-               goto clear_evt;
-       }
-
-       ret = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1, buf + 1);
-       if (ret) {
-               ret = _FAIL;
-               goto clear_evt;
-       }
-       /* Read the content */
-       for (i = 0; i < c2h_evt->plen; i++) {
-               ret = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL +
-                               sizeof(*c2h_evt) + i, c2h_evt->payload + i);
-               if (ret) {
-                       ret = _FAIL;
-                       goto clear_evt;
-               }
-       }
-
-       ret = _SUCCESS;
-
-clear_evt:
-       /* Clear event to notify FW we have read the command.
-        * If this field isn't clear, the FW won't update the next
-        * command message.
-        */
-       rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
-exit:
-       return ret;
-}
-
-static void c2h_evt_hdl(struct adapter *adapter, struct c2h_evt_hdr *c2h_evt, c2h_id_filter filter)
-{
-       u8 buf[16];
-
-       if (!c2h_evt)
-               c2h_evt_read(adapter, buf);
-}
-
-static void c2h_wk_callback(struct work_struct *work)
-{
-       struct evt_priv *evtpriv = container_of(work, struct evt_priv, c2h_wk);
-       struct adapter *adapter = container_of(evtpriv, struct adapter, evtpriv);
-       struct c2h_evt_hdr *c2h_evt;
-
-       evtpriv->c2h_wk_alive = true;
-
-       while (!rtw_cbuf_empty(evtpriv->c2h_queue)) {
-               c2h_evt = (struct c2h_evt_hdr *)rtw_cbuf_pop(evtpriv->c2h_queue);
-               if (c2h_evt) {
-                       /* This C2H event is read, clear it */
-                       rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
-               } else {
-                       c2h_evt = kmalloc(16, GFP_KERNEL);
-                       if (c2h_evt) {
-                               /* This C2H event is not read, read & clear now */
-                               if (c2h_evt_read(adapter, (u8 *)c2h_evt) != _SUCCESS) {
-                                       kfree(c2h_evt);
-                                       continue;
-                               }
-                       } else {
-                               return;
-                       }
-               }
-
-               /* Special pointer to trigger c2h_evt_clear only */
-               if ((void *)c2h_evt == (void *)evtpriv)
-                       continue;
-
-               if (!c2h_evt_exist(c2h_evt)) {
-                       kfree(c2h_evt);
-                       continue;
-               }
-
-               /* Enqueue into cmd_thread for others */
-               rtw_c2h_wk_cmd(adapter, (u8 *)c2h_evt);
-       }
-
-       evtpriv->c2h_wk_alive = false;
-}
-
-u8 rtw_drvextra_cmd_hdl(struct adapter *padapter, unsigned char *pbuf)
-{
-       struct drvextra_cmd_parm *pdrvextra_cmd;
-
-       if (!pbuf)
-               return H2C_PARAMETERS_ERROR;
-
-       pdrvextra_cmd = (struct drvextra_cmd_parm *)pbuf;
-
-       switch (pdrvextra_cmd->ec_id) {
-       case DYNAMIC_CHK_WK_CID:
-               dynamic_chk_wk_hdl(padapter, pdrvextra_cmd->pbuf);
-               break;
-       case POWER_SAVING_CTRL_WK_CID:
-               rtw_ps_processor(padapter);
-               break;
-       case LPS_CTRL_WK_CID:
-               lps_ctrl_wk_hdl(padapter, (u8)pdrvextra_cmd->type_size);
-               break;
-       case RTP_TIMER_CFG_WK_CID:
-               rpt_timer_setting_wk_hdl(padapter, pdrvextra_cmd->type_size);
-               break;
-       case ANT_SELECT_WK_CID:
-               antenna_select_wk_hdl(padapter, pdrvextra_cmd->type_size);
-               break;
-       case P2P_PS_WK_CID:
-               p2p_ps_wk_hdl(padapter, pdrvextra_cmd->type_size);
-               break;
-       case P2P_PROTO_WK_CID:
-               /*      Commented by Albert 2011/07/01 */
-               /*      I used the type_size as the type command */
-               p2p_protocol_wk_hdl(padapter, pdrvextra_cmd->type_size);
-               break;
-       case CHECK_HIQ_WK_CID:
-               rtw_chk_hi_queue_hdl(padapter);
-               break;
-       case C2H_WK_CID:
-               c2h_evt_hdl(padapter, (struct c2h_evt_hdr *)pdrvextra_cmd->pbuf, NULL);
-               break;
-       default:
-               break;
-       }
-
-       if (pdrvextra_cmd->pbuf && pdrvextra_cmd->type_size > 0)
-               kfree(pdrvextra_cmd->pbuf);
-
-       return H2C_SUCCESS;
-}
-
-void rtw_survey_cmd_callback(struct adapter *padapter,  struct cmd_obj *pcmd)
-{
-       struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
-       if (pcmd->res != H2C_SUCCESS) {
-               /* TODO: cancel timer and do timeout handler directly... */
-               _set_timer(&pmlmepriv->scan_to_timer, 1);
-       }
-
-       /*  free cmd */
-       rtw_free_cmd_obj(pcmd);
-
-}
-
-void rtw_disassoc_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd)
-{
-       struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
-       if (pcmd->res != H2C_SUCCESS) {
-               spin_lock_bh(&pmlmepriv->lock);
-               set_fwstate(pmlmepriv, _FW_LINKED);
-               spin_unlock_bh(&pmlmepriv->lock);
-
-               return;
-       }
-
-       /* clear bridge database */
-       nat25_db_cleanup(padapter);
-
-       /*  free cmd */
-       rtw_free_cmd_obj(pcmd);
-}
-
-void rtw_joinbss_cmd_callback(struct adapter *padapter,  struct cmd_obj *pcmd)
-{
-       struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
-       if (pcmd->res != H2C_SUCCESS) {
-               /* TODO: cancel timer and do timeout handler directly... */
-               _set_timer(&pmlmepriv->assoc_timer, 1);
-       }
-
-       rtw_free_cmd_obj(pcmd);
-}
-
-void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd)
-{
-       struct sta_info *psta = NULL;
-       struct wlan_network *pwlan = NULL;
-       struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)pcmd->parmbuf;
-       struct wlan_network *tgt_network = &pmlmepriv->cur_network;
-
-       if (pcmd->res != H2C_SUCCESS)
-               _set_timer(&pmlmepriv->assoc_timer, 1);
-
-       del_timer_sync(&pmlmepriv->assoc_timer);
-
-       spin_lock_bh(&pmlmepriv->lock);
-
-       if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
-               psta = rtw_get_stainfo(&padapter->stapriv, pnetwork->MacAddress);
-               if (!psta) {
-                       psta = rtw_alloc_stainfo(&padapter->stapriv, pnetwork->MacAddress);
-                       if (!psta)
-                               goto createbss_cmd_fail;
-               }
-
-               rtw_indicate_connect(padapter);
-       } else {
-
-               pwlan = rtw_alloc_network(pmlmepriv);
-               spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-               if (!pwlan) {
-                       pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue);
-                       if (!pwlan) {
-                               spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-                               goto createbss_cmd_fail;
-                       }
-                       pwlan->last_scanned = jiffies;
-               } else {
-                       list_add_tail(&pwlan->list, &pmlmepriv->scanned_queue.queue);
-               }
-
-               pnetwork->Length = get_wlan_bssid_ex_sz(pnetwork);
-               memcpy(&pwlan->network, pnetwork, pnetwork->Length);
-
-               memcpy(&tgt_network->network, pnetwork, (get_wlan_bssid_ex_sz(pnetwork)));
-
-               _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
-
-               spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-               /*  we will set _FW_LINKED when there is one more sat to join us (rtw_stassoc_event_callback) */
-       }
-
-createbss_cmd_fail:
-
-       spin_unlock_bh(&pmlmepriv->lock);
-
-       rtw_free_cmd_obj(pcmd);
-
-}
-
-void rtw_setstaKey_cmdrsp_callback(struct adapter *padapter,  struct cmd_obj *pcmd)
-{
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       struct set_stakey_rsp *psetstakey_rsp = (struct set_stakey_rsp *)(pcmd->rsp);
-       struct sta_info *psta = rtw_get_stainfo(pstapriv, psetstakey_rsp->addr);
-
-       if (!psta)
-               goto exit;
-exit:
-       rtw_free_cmd_obj(pcmd);
-
-}
-
-void rtw_setassocsta_cmdrsp_callback(struct adapter *padapter,  struct cmd_obj *pcmd)
-{
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct set_assocsta_parm *passocsta_parm = (struct set_assocsta_parm *)(pcmd->parmbuf);
-       struct set_assocsta_rsp *passocsta_rsp = (struct set_assocsta_rsp *)(pcmd->rsp);
-       struct sta_info *psta = rtw_get_stainfo(pstapriv, passocsta_parm->addr);
-
-       if (!psta)
-               goto exit;
-
-       psta->aid = passocsta_rsp->cam_id;
-       psta->mac_id = passocsta_rsp->cam_id;
-
-       spin_lock_bh(&pmlmepriv->lock);
-
-       if (check_fwstate(pmlmepriv, WIFI_MP_STATE) && check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
-               _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
-
-       set_fwstate(pmlmepriv, _FW_LINKED);
-       spin_unlock_bh(&pmlmepriv->lock);
-
-exit:
-       rtw_free_cmd_obj(pcmd);
-
-}
diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c
deleted file mode 100644 (file)
index df9534d..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#define _RTW_EFUSE_C_
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/rtw_efuse.h"
-#include "../include/rtl8188e_hal.h"
-
-/*  */
-/*     Description: */
-/*             Execute E-Fuse read byte operation. */
-/*             Referred from SD1 Richard. */
-/*  */
-/*     Assumption: */
-/*             1. Boot from E-Fuse and successfully auto-load. */
-/*             2. PASSIVE_LEVEL (USB interface) */
-/*  */
-/*     Created by Roger, 2008.10.21. */
-/*  */
-void
-ReadEFuseByte(
-               struct adapter *Adapter,
-               u16 _offset,
-               u8 *pbuf)
-{
-       u32 value32;
-       u8 readbyte;
-       u16 retry;
-       int res;
-
-       /* Write Address */
-       rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff));
-       res = rtw_read8(Adapter, EFUSE_CTRL + 2, &readbyte);
-       if (res)
-               return;
-
-       rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
-
-       /* Write bit 32 0 */
-       res = rtw_read8(Adapter, EFUSE_CTRL + 3, &readbyte);
-       if (res)
-               return;
-
-       rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
-
-       /* Check bit 32 read-ready */
-       res = rtw_read32(Adapter, EFUSE_CTRL, &value32);
-       if (res)
-               return;
-
-       for (retry = 0; retry < 10000; retry++) {
-               res = rtw_read32(Adapter, EFUSE_CTRL, &value32);
-               if (res)
-                       continue;
-
-               if (((value32 >> 24) & 0xff) & 0x80)
-                       break;
-       }
-
-       /*  20100205 Joseph: Add delay suggested by SD1 Victor. */
-       /*  This fix the problem that Efuse read error in high temperature condition. */
-       /*  Designer says that there shall be some delay after ready bit is set, or the */
-       /*  result will always stay on last data we read. */
-       udelay(50);
-       res = rtw_read32(Adapter, EFUSE_CTRL, &value32);
-       if (res)
-               return;
-
-       *pbuf = (u8)(value32 & 0xff);
-
-       /* FIXME: return an error to caller */
-}
diff --git a/drivers/staging/r8188eu/core/rtw_fw.c b/drivers/staging/r8188eu/core/rtw_fw.c
deleted file mode 100644 (file)
index 1e4baf7..0000000
+++ /dev/null
@@ -1,335 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#include <linux/firmware.h>
-#include "../include/rtw_fw.h"
-
-#define MAX_REG_BLOCK_SIZE     196
-#define FW_8188E_START_ADDRESS 0x1000
-#define MAX_PAGE_SIZE          4096
-
-#define IS_FW_HEADER_EXIST(_fwhdr)                             \
-       ((le16_to_cpu(_fwhdr->signature) & 0xFFF0) == 0x92C0 || \
-       (le16_to_cpu(_fwhdr->signature) & 0xFFF0) == 0x88C0 ||  \
-       (le16_to_cpu(_fwhdr->signature) & 0xFFF0) == 0x2300 ||  \
-       (le16_to_cpu(_fwhdr->signature) & 0xFFF0) == 0x88E0)
-
-struct rt_firmware_hdr {
-       __le16  signature;      /* 92C0: test chip; 92C,
-                                * 88C0: test chip; 88C1: MP A-cut;
-                                * 92C1: MP A-cut */
-       u8      category;       /* AP/NIC and USB/PCI */
-       u8      function;       /* Reserved for different FW function
-                                * indcation, for further use when
-                                * driver needs to download different
-                                * FW for different conditions */
-       __le16  version;        /* FW Version */
-       u8      subversion;     /* FW Subversion, default 0x00 */
-       u8      rsvd1;
-       u8      month;          /* Release time Month field */
-       u8      date;           /* Release time Date field */
-       u8      hour;           /* Release time Hour field */
-       u8      minute;         /* Release time Minute field */
-       __le16  ramcodesize;    /* The size of RAM code */
-       u8      foundry;
-       u8      rsvd2;
-       __le32  svnidx;         /* The SVN entry index */
-       __le32  rsvd3;
-       __le32  rsvd4;
-       __le32  rsvd5;
-};
-
-static_assert(sizeof(struct rt_firmware_hdr) == 32);
-
-static void fw_download_enable(struct adapter *padapter, bool enable)
-{
-       u8 tmp;
-       int res;
-
-       if (enable) {
-               /*  MCU firmware download enable. */
-               res = rtw_read8(padapter, REG_MCUFWDL, &tmp);
-               if (res)
-                       return;
-
-               rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
-
-               /*  8051 reset */
-               res = rtw_read8(padapter, REG_MCUFWDL + 2, &tmp);
-               if (res)
-                       return;
-
-               rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
-       } else {
-               /*  MCU firmware download disable. */
-               res = rtw_read8(padapter, REG_MCUFWDL, &tmp);
-               if (res)
-                       return;
-
-               rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
-
-               /*  Reserved for fw extension. */
-               rtw_write8(padapter, REG_MCUFWDL + 1, 0x00);
-       }
-}
-
-static int block_write(struct adapter *padapter, u8 *buffer, u32 size)
-{
-       int ret = _SUCCESS;
-       u32 blocks, block_size, remain;
-       u32 i, offset, addr;
-       u8 *data;
-
-       block_size = MAX_REG_BLOCK_SIZE;
-
-       blocks = size / block_size;
-       remain = size % block_size;
-
-       for (i = 0; i < blocks; i++) {
-               addr = FW_8188E_START_ADDRESS + i * block_size;
-               data = buffer + i * block_size;
-
-               if (rtw_writeN(padapter, addr, block_size, data))
-                       return _FAIL;
-       }
-
-       if (remain) {
-               offset = blocks * block_size;
-               block_size = 8;
-
-               blocks = remain / block_size;
-               remain = remain % block_size;
-
-               for (i = 0; i < blocks; i++) {
-                       addr = FW_8188E_START_ADDRESS + offset + i * block_size;
-                       data = buffer + offset + i * block_size;
-
-                       if (rtw_writeN(padapter, addr, block_size, data))
-                               return _FAIL;
-               }
-       }
-
-       if (remain) {
-               offset += blocks * block_size;
-
-               /* block size 1 */
-               blocks = remain;
-
-               for (i = 0; i < blocks; i++) {
-                       addr = FW_8188E_START_ADDRESS + offset + i;
-                       data = buffer + offset + i;
-
-                       ret = rtw_write8(padapter, addr, *data);
-                       if (ret == _FAIL)
-                               goto exit;
-               }
-       }
-
-exit:
-       return ret;
-}
-
-static int page_write(struct adapter *padapter, u32 page, u8 *buffer, u32 size)
-{
-       u8 value8;
-       u8 u8Page = (u8)(page & 0x07);
-       int res;
-
-       res = rtw_read8(padapter, REG_MCUFWDL + 2, &value8);
-       if (res)
-               return _FAIL;
-
-       value8 = (value8 & 0xF8) | u8Page;
-       rtw_write8(padapter, REG_MCUFWDL + 2, value8);
-
-       return block_write(padapter, buffer, size);
-}
-
-static int write_fw(struct adapter *padapter, u8 *buffer, u32 size)
-{
-       /*  Since we need dynamic decide method of dwonload fw, so we call this function to get chip version. */
-       /*  We can remove _ReadChipVersion from ReadpadapterInfo8192C later. */
-       int ret = _SUCCESS;
-       u32     pageNums, remainSize;
-       u32     page, offset;
-
-       pageNums = size / MAX_PAGE_SIZE;
-       remainSize = size % MAX_PAGE_SIZE;
-
-       for (page = 0; page < pageNums; page++) {
-               offset = page * MAX_PAGE_SIZE;
-               ret = page_write(padapter, page, buffer + offset, MAX_PAGE_SIZE);
-
-               if (ret == _FAIL)
-                       goto exit;
-       }
-       if (remainSize) {
-               offset = pageNums * MAX_PAGE_SIZE;
-               page = pageNums;
-               ret = page_write(padapter, page, buffer + offset, remainSize);
-
-               if (ret == _FAIL)
-                       goto exit;
-       }
-exit:
-       return ret;
-}
-
-void rtw_reset_8051(struct adapter *padapter)
-{
-       u8 val8;
-       int res;
-
-       res = rtw_read8(padapter, REG_SYS_FUNC_EN + 1, &val8);
-       if (res)
-               return;
-
-       rtw_write8(padapter, REG_SYS_FUNC_EN + 1, val8 & (~BIT(2)));
-       rtw_write8(padapter, REG_SYS_FUNC_EN + 1, val8 | (BIT(2)));
-}
-
-static int fw_free_to_go(struct adapter *padapter)
-{
-       u32     counter = 0;
-       u32     value32;
-       int res;
-
-       /*  polling CheckSum report */
-       do {
-               res = rtw_read32(padapter, REG_MCUFWDL, &value32);
-               if (res)
-                       continue;
-
-               if (value32 & FWDL_CHKSUM_RPT)
-                       break;
-       } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
-
-       if (counter >= POLLING_READY_TIMEOUT_COUNT)
-               return _FAIL;
-
-       res = rtw_read32(padapter, REG_MCUFWDL, &value32);
-       if (res)
-               return _FAIL;
-
-       value32 |= MCUFWDL_RDY;
-       value32 &= ~WINTINI_RDY;
-       rtw_write32(padapter, REG_MCUFWDL, value32);
-
-       rtw_reset_8051(padapter);
-
-       /*  polling for FW ready */
-       counter = 0;
-       do {
-               res = rtw_read32(padapter, REG_MCUFWDL, &value32);
-               if (!res && value32 & WINTINI_RDY)
-                       return _SUCCESS;
-
-               udelay(5);
-       } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
-
-       return _FAIL;
-}
-
-static int load_firmware(struct rt_firmware *rtfw, struct device *device)
-{
-       int ret = _SUCCESS;
-       const struct firmware *fw;
-       const char *fw_name = FW_RTL8188EU;
-       int err = request_firmware(&fw, fw_name, device);
-
-       if (err) {
-               pr_err("Request firmware failed with error 0x%x\n", err);
-               ret = _FAIL;
-               goto exit;
-       }
-       if (!fw) {
-               pr_err("Firmware %s not available\n", fw_name);
-               ret = _FAIL;
-               goto exit;
-       }
-
-       rtfw->data = kmemdup(fw->data, fw->size, GFP_KERNEL);
-       if (!rtfw->data) {
-               pr_err("Failed to allocate rtfw->data\n");
-               ret = _FAIL;
-               goto exit;
-       }
-       rtfw->size = fw->size;
-
-exit:
-       release_firmware(fw);
-       return ret;
-}
-
-int rtl8188e_firmware_download(struct adapter *padapter)
-{
-       int ret = _SUCCESS;
-       u8 reg;
-       unsigned long fwdl_timeout;
-       struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
-       struct device *device = dvobj_to_dev(dvobj);
-       struct rt_firmware_hdr *fwhdr = NULL;
-       u8 *fw_data;
-       u32 fw_size;
-
-       if (!dvobj->firmware.data)
-               ret = load_firmware(&dvobj->firmware, device);
-       if (ret == _FAIL) {
-               dvobj->firmware.data = NULL;
-               goto exit;
-       }
-       fw_data = dvobj->firmware.data;
-       fw_size = dvobj->firmware.size;
-
-       fwhdr = (struct rt_firmware_hdr *)dvobj->firmware.data;
-
-       if (IS_FW_HEADER_EXIST(fwhdr)) {
-               dev_info_once(device, "Firmware Version %d, SubVersion %d, Signature 0x%x\n",
-                             le16_to_cpu(fwhdr->version), fwhdr->subversion,
-                             le16_to_cpu(fwhdr->signature));
-
-               fw_data = fw_data + sizeof(struct rt_firmware_hdr);
-               fw_size = fw_size - sizeof(struct rt_firmware_hdr);
-       }
-
-       /*  Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, */
-       /*  or it will cause download Fw fail. 2010.02.01. by tynli. */
-       ret = rtw_read8(padapter, REG_MCUFWDL, &reg);
-       if (ret) {
-               ret = _FAIL;
-               goto exit;
-       }
-
-       if (reg & RAM_DL_SEL) { /* 8051 RAM code */
-               rtw_write8(padapter, REG_MCUFWDL, 0x00);
-               rtw_reset_8051(padapter);
-       }
-
-       fw_download_enable(padapter, true);
-       fwdl_timeout = jiffies + msecs_to_jiffies(500);
-       do {
-               /* reset the FWDL chksum */
-               ret = rtw_read8(padapter, REG_MCUFWDL, &reg);
-               if (ret) {
-                       ret = _FAIL;
-                       continue;
-               }
-
-               rtw_write8(padapter, REG_MCUFWDL, reg | FWDL_CHKSUM_RPT);
-
-               ret = write_fw(padapter, fw_data, fw_size);
-               if (ret == _SUCCESS)
-                       break;
-       } while (!time_after(jiffies, fwdl_timeout));
-
-       fw_download_enable(padapter, false);
-       if (ret != _SUCCESS)
-               goto exit;
-
-       ret = fw_free_to_go(padapter);
-       if (ret != _SUCCESS)
-               goto exit;
-
-exit:
-       return ret;
-}
diff --git a/drivers/staging/r8188eu/core/rtw_ieee80211.c b/drivers/staging/r8188eu/core/rtw_ieee80211.c
deleted file mode 100644 (file)
index bc8543e..0000000
+++ /dev/null
@@ -1,1150 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#define _IEEE80211_C
-
-#include "../include/drv_types.h"
-#include "../include/ieee80211.h"
-#include "../include/wifi.h"
-#include "../include/osdep_service.h"
-#include "../include/wlan_bssdef.h"
-#include "../include/usb_osintf.h"
-
-u8 RTW_WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 };
-u16 RTW_WPA_VERSION = 1;
-u8 WPA_AUTH_KEY_MGMT_NONE[] = { 0x00, 0x50, 0xf2, 0 };
-u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x50, 0xf2, 1 };
-u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x50, 0xf2, 2 };
-u8 WPA_CIPHER_SUITE_NONE[] = { 0x00, 0x50, 0xf2, 0 };
-u8 WPA_CIPHER_SUITE_WEP40[] = { 0x00, 0x50, 0xf2, 1 };
-u8 WPA_CIPHER_SUITE_TKIP[] = { 0x00, 0x50, 0xf2, 2 };
-u8 WPA_CIPHER_SUITE_WRAP[] = { 0x00, 0x50, 0xf2, 3 };
-u8 WPA_CIPHER_SUITE_CCMP[] = { 0x00, 0x50, 0xf2, 4 };
-u8 WPA_CIPHER_SUITE_WEP104[] = { 0x00, 0x50, 0xf2, 5 };
-
-u16 RSN_VERSION_BSD = 1;
-u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x0f, 0xac, 1 };
-u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x0f, 0xac, 2 };
-u8 RSN_CIPHER_SUITE_NONE[] = { 0x00, 0x0f, 0xac, 0 };
-u8 RSN_CIPHER_SUITE_WEP40[] = { 0x00, 0x0f, 0xac, 1 };
-u8 RSN_CIPHER_SUITE_TKIP[] = { 0x00, 0x0f, 0xac, 2 };
-u8 RSN_CIPHER_SUITE_WRAP[] = { 0x00, 0x0f, 0xac, 3 };
-u8 RSN_CIPHER_SUITE_CCMP[] = { 0x00, 0x0f, 0xac, 4 };
-u8 RSN_CIPHER_SUITE_WEP104[] = { 0x00, 0x0f, 0xac, 5 };
-/*  */
-/*  for adhoc-master to generate ie and provide supported-rate to fw */
-/*  */
-
-static u8      WIFI_CCKRATES[] = {
-       (IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK),
-       (IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK),
-       (IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK),
-       (IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK)
-       };
-
-static u8      WIFI_OFDMRATES[] = {
-        (IEEE80211_OFDM_RATE_6MB),
-        (IEEE80211_OFDM_RATE_9MB),
-        (IEEE80211_OFDM_RATE_12MB),
-        (IEEE80211_OFDM_RATE_18MB),
-        (IEEE80211_OFDM_RATE_24MB),
-        IEEE80211_OFDM_RATE_36MB,
-        IEEE80211_OFDM_RATE_48MB,
-        IEEE80211_OFDM_RATE_54MB
-       };
-
-int rtw_get_bit_value_from_ieee_value(u8 val)
-{
-       unsigned char dot11_rate_table[] = {
-               2, 4, 11, 22, 12, 18, 24, 36, 48,
-               72, 96, 108, 0}; /*  last element must be zero!! */
-
-       int i = 0;
-       while (dot11_rate_table[i] != 0) {
-               if (dot11_rate_table[i] == val)
-                       return BIT(i);
-               i++;
-       }
-       return 0;
-}
-
-bool   rtw_is_cckrates_included(u8 *rate)
-{
-       u32     i = 0;
-
-       while (rate[i] != 0) {
-               if  ((((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) ||
-                    (((rate[i]) & 0x7f) == 11)  || (((rate[i]) & 0x7f) == 22))
-                       return true;
-               i++;
-       }
-       return false;
-}
-
-bool   rtw_is_cckratesonly_included(u8 *rate)
-{
-       u32 i = 0;
-
-       while (rate[i] != 0) {
-               if  ((((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&
-                    (((rate[i]) & 0x7f) != 11)  && (((rate[i]) & 0x7f) != 22))
-                       return false;
-               i++;
-       }
-
-       return true;
-}
-
-int rtw_check_network_type(unsigned char *rate, int ratelen, int channel)
-{
-       if (channel > 14)
-               return WIRELESS_INVALID;
-       /*  could be pure B, pure G, or B/G */
-       if (rtw_is_cckratesonly_included(rate))
-               return WIRELESS_11B;
-       else if (rtw_is_cckrates_included(rate))
-               return  WIRELESS_11BG;
-       else
-               return WIRELESS_11G;
-}
-
-u8 *rtw_set_fixed_ie(unsigned char *pbuf, unsigned int len, unsigned char *source,
-                               unsigned int *frlen)
-{
-       memcpy((void *)pbuf, (void *)source, len);
-       *frlen = *frlen + len;
-       return pbuf + len;
-}
-
-/*  rtw_set_ie will update frame length */
-u8 *rtw_set_ie
-(
-       u8 *pbuf,
-       int index,
-       uint len,
-       u8 *source,
-       uint *frlen /* frame length */
-)
-{
-
-       *pbuf = (u8)index;
-
-       *(pbuf + 1) = (u8)len;
-
-       if (len > 0)
-               memcpy((void *)(pbuf + 2), (void *)source, len);
-
-       *frlen = *frlen + (len + 2);
-
-       return pbuf + len + 2;
-}
-
-/*----------------------------------------------------------------------------
-index: the information element id index, limit is the limit for search
------------------------------------------------------------------------------*/
-u8 *rtw_get_ie(u8 *pbuf, int index, int *len, int limit)
-{
-       int tmp, i;
-       u8 *p;
-
-       if (limit < 1) {
-
-               return NULL;
-       }
-
-       p = pbuf;
-       i = 0;
-       *len = 0;
-       while (1) {
-               if (*p == index) {
-                       *len = *(p + 1);
-                       return p;
-               }
-               tmp = *(p + 1);
-               p += (tmp + 2);
-               i += (tmp + 2);
-               if (i >= limit)
-                       break;
-       }
-
-       return NULL;
-}
-
-void rtw_set_supported_rate(u8 *SupportedRates, uint mode)
-{
-
-       memset(SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
-
-       switch (mode) {
-       case WIRELESS_11B:
-               memcpy(SupportedRates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN);
-               break;
-       case WIRELESS_11G:
-               memcpy(SupportedRates, WIFI_OFDMRATES, IEEE80211_NUM_OFDM_RATESLEN);
-               break;
-       case WIRELESS_11BG:
-       case WIRELESS_11G_24N:
-       case WIRELESS_11_24N:
-       case WIRELESS_11BG_24N:
-               memcpy(SupportedRates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN);
-               memcpy(SupportedRates + IEEE80211_CCK_RATE_LEN, WIFI_OFDMRATES, IEEE80211_NUM_OFDM_RATESLEN);
-               break;
-       }
-
-}
-
-uint   rtw_get_rateset_len(u8  *rateset)
-{
-       uint i = 0;
-
-       while (1) {
-               if ((rateset[i]) == 0)
-                       break;
-               if (i > 12)
-                       break;
-               i++;
-       }
-
-       return i;
-}
-
-int rtw_generate_ie(struct registry_priv *pregistrypriv)
-{
-       u8      wireless_mode;
-       int     sz = 0, rateLen;
-       struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
-       u8 *ie = pdev_network->IEs;
-
-       /* timestamp will be inserted by hardware */
-       sz += 8;
-       ie += sz;
-
-       /* beacon interval : 2bytes */
-       *(__le16 *)ie = cpu_to_le16((u16)pdev_network->Configuration.BeaconPeriod);/* BCN_INTERVAL; */
-       sz += 2;
-       ie += 2;
-
-       /* capability info */
-       *(u16 *)ie = 0;
-
-       *(__le16 *)ie |= cpu_to_le16(cap_IBSS);
-
-       if (pregistrypriv->preamble == PREAMBLE_SHORT)
-               *(__le16 *)ie |= cpu_to_le16(cap_ShortPremble);
-
-       if (pdev_network->Privacy)
-               *(__le16 *)ie |= cpu_to_le16(cap_Privacy);
-
-       sz += 2;
-       ie += 2;
-
-       /* SSID */
-       ie = rtw_set_ie(ie, _SSID_IE_, pdev_network->Ssid.SsidLength, pdev_network->Ssid.Ssid, &sz);
-
-       /* supported rates */
-       wireless_mode = pregistrypriv->wireless_mode;
-
-       rtw_set_supported_rate(pdev_network->SupportedRates, wireless_mode);
-
-       rateLen = rtw_get_rateset_len(pdev_network->SupportedRates);
-
-       if (rateLen > 8) {
-               ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, pdev_network->SupportedRates, &sz);
-               /* ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (pdev_network->SupportedRates + 8), &sz); */
-       } else {
-               ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, pdev_network->SupportedRates, &sz);
-       }
-
-       /* DS parameter set */
-       ie = rtw_set_ie(ie, _DSSET_IE_, 1, (u8 *)&pdev_network->Configuration.DSConfig, &sz);
-
-       /* IBSS Parameter Set */
-
-       ie = rtw_set_ie(ie, _IBSS_PARA_IE_, 2, (u8 *)&pdev_network->Configuration.ATIMWindow, &sz);
-
-       if (rateLen > 8)
-               ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (pdev_network->SupportedRates + 8), &sz);
-
-       return sz;
-}
-
-unsigned char *rtw_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit)
-{
-       int len;
-       u16 val16;
-       __le16 le_tmp;
-       unsigned char wpa_oui_type[] = {0x00, 0x50, 0xf2, 0x01};
-       u8 *pbuf = pie;
-       int limit_new = limit;
-
-       while (1) {
-               pbuf = rtw_get_ie(pbuf, _WPA_IE_ID_, &len, limit_new);
-
-               if (pbuf) {
-                       /* check if oui matches... */
-                       if (memcmp((pbuf + 2), wpa_oui_type, sizeof(wpa_oui_type)))
-                               goto check_next_ie;
-
-                       /* check version... */
-                       memcpy((u8 *)&le_tmp, (pbuf + 6), sizeof(val16));
-
-                       val16 = le16_to_cpu(le_tmp);
-                       if (val16 != 0x0001)
-                               goto check_next_ie;
-                       *wpa_ie_len = *(pbuf + 1);
-                       return pbuf;
-               }
-               *wpa_ie_len = 0;
-               return NULL;
-
-check_next_ie:
-               limit_new = limit - (pbuf - pie) - 2 - len;
-               if (limit_new <= 0)
-                       break;
-               pbuf += (2 + len);
-       }
-       *wpa_ie_len = 0;
-       return NULL;
-}
-
-unsigned char *rtw_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len, int limit)
-{
-
-       return rtw_get_ie(pie, _WPA2_IE_ID_, rsn_ie_len, limit);
-}
-
-int rtw_get_wpa_cipher_suite(u8 *s)
-{
-       if (!memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN))
-               return WPA_CIPHER_NONE;
-       if (!memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN))
-               return WPA_CIPHER_WEP40;
-       if (!memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN))
-               return WPA_CIPHER_TKIP;
-       if (!memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN))
-               return WPA_CIPHER_CCMP;
-       if (!memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN))
-               return WPA_CIPHER_WEP104;
-
-       return 0;
-}
-
-int rtw_get_wpa2_cipher_suite(u8 *s)
-{
-       if (!memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN))
-               return WPA_CIPHER_NONE;
-       if (!memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN))
-               return WPA_CIPHER_WEP40;
-       if (!memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN))
-               return WPA_CIPHER_TKIP;
-       if (!memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN))
-               return WPA_CIPHER_CCMP;
-       if (!memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN))
-               return WPA_CIPHER_WEP104;
-
-       return 0;
-}
-
-int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x)
-{
-       int i, ret = _SUCCESS;
-       int left, count;
-       u8 *pos;
-       u8 SUITE_1X[4] = {0x00, 0x50, 0xf2, 1};
-
-       if (wpa_ie_len <= 0) {
-               /* No WPA IE - fail silently */
-               return _FAIL;
-       }
-
-       if ((*wpa_ie != _WPA_IE_ID_) || (*(wpa_ie + 1) != (u8)(wpa_ie_len - 2)) ||
-           (memcmp(wpa_ie + 2, RTW_WPA_OUI_TYPE, WPA_SELECTOR_LEN)))
-               return _FAIL;
-
-       pos = wpa_ie;
-
-       pos += 8;
-       left = wpa_ie_len - 8;
-
-       /* group_cipher */
-       if (left >= WPA_SELECTOR_LEN) {
-               *group_cipher = rtw_get_wpa_cipher_suite(pos);
-               pos += WPA_SELECTOR_LEN;
-               left -= WPA_SELECTOR_LEN;
-       } else if (left > 0) {
-               return _FAIL;
-       }
-
-       /* pairwise_cipher */
-       if (left >= 2) {
-               count = get_unaligned_le16(pos);
-               pos += 2;
-               left -= 2;
-
-               if (count == 0 || left < count * WPA_SELECTOR_LEN)
-                       return _FAIL;
-
-               for (i = 0; i < count; i++) {
-                       *pairwise_cipher |= rtw_get_wpa_cipher_suite(pos);
-
-                       pos += WPA_SELECTOR_LEN;
-                       left -= WPA_SELECTOR_LEN;
-               }
-       } else if (left == 1) {
-               return _FAIL;
-       }
-
-       if (is_8021x) {
-               if (left >= 6) {
-                       pos += 2;
-                       if (!memcmp(pos, SUITE_1X, 4))
-                               *is_8021x = 1;
-               }
-       }
-
-       return ret;
-}
-
-int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x)
-{
-       int i, ret = _SUCCESS;
-       int left, count;
-       u8 *pos;
-       u8 SUITE_1X[4] = {0x00, 0x0f, 0xac, 0x01};
-
-       if (rsn_ie_len <= 0) {
-               /* No RSN IE - fail silently */
-               return _FAIL;
-       }
-
-       if ((*rsn_ie != _WPA2_IE_ID_) || (*(rsn_ie + 1) != (u8)(rsn_ie_len - 2)))
-               return _FAIL;
-
-       pos = rsn_ie;
-       pos += 4;
-       left = rsn_ie_len - 4;
-
-       /* group_cipher */
-       if (left >= RSN_SELECTOR_LEN) {
-               *group_cipher = rtw_get_wpa2_cipher_suite(pos);
-
-               pos += RSN_SELECTOR_LEN;
-               left -= RSN_SELECTOR_LEN;
-
-       } else if (left > 0) {
-               return _FAIL;
-       }
-
-       /* pairwise_cipher */
-       if (left >= 2) {
-               count = get_unaligned_le16(pos);
-               pos += 2;
-               left -= 2;
-
-               if (count == 0 || left < count * RSN_SELECTOR_LEN)
-                       return _FAIL;
-
-               for (i = 0; i < count; i++) {
-                       *pairwise_cipher |= rtw_get_wpa2_cipher_suite(pos);
-
-                       pos += RSN_SELECTOR_LEN;
-                       left -= RSN_SELECTOR_LEN;
-               }
-
-       } else if (left == 1) {
-               return _FAIL;
-       }
-
-       if (is_8021x) {
-               if (left >= 6) {
-                       pos += 2;
-                       if (!memcmp(pos, SUITE_1X, 4))
-                               *is_8021x = 1;
-               }
-       }
-       return ret;
-}
-
-int rtw_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie, u16 *wpa_len)
-{
-       u8 authmode;
-       u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01};
-       uint    cnt;
-
-       /* Search required WPA or WPA2 IE and copy to sec_ie[] */
-
-       cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_);
-
-       while (cnt < in_len) {
-               authmode = in_ie[cnt];
-
-               if ((authmode == _WPA_IE_ID_) && (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) {
-                               if (wpa_ie)
-                                       memcpy(wpa_ie, &in_ie[cnt], in_ie[cnt + 1] + 2);
-
-                               *wpa_len = in_ie[cnt + 1] + 2;
-                               cnt += in_ie[cnt + 1] + 2;  /* get next */
-               } else {
-                       if (authmode == _WPA2_IE_ID_) {
-                               if (rsn_ie)
-                                       memcpy(rsn_ie, &in_ie[cnt], in_ie[cnt + 1] + 2);
-
-                               *rsn_len = in_ie[cnt + 1] + 2;
-                               cnt += in_ie[cnt + 1] + 2;  /* get next */
-                       } else {
-                               cnt += in_ie[cnt + 1] + 2;   /* get next */
-                       }
-               }
-       }
-
-       return *rsn_len + *wpa_len;
-}
-
-u8 rtw_is_wps_ie(u8 *ie_ptr, uint *wps_ielen)
-{
-       u8 match = false;
-       u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
-
-       if (!ie_ptr)
-               return match;
-
-       eid = ie_ptr[0];
-
-       if ((eid == _WPA_IE_ID_) && (!memcmp(&ie_ptr[2], wps_oui, 4))) {
-               *wps_ielen = ie_ptr[1] + 2;
-               match = true;
-       }
-       return match;
-}
-
-/**
- * rtw_get_wps_ie - Search WPS IE from a series of IEs
- * @in_ie: Address of IEs to search
- * @in_len: Length limit from in_ie
- * @wps_ie: If not NULL and WPS IE is found, WPS IE will be copied to the buf starting from wps_ie
- * @wps_ielen: If not NULL and WPS IE is found, will set to the length of the entire WPS IE
- *
- * Returns: The address of the WPS IE found, or NULL
- */
-u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen)
-{
-       uint cnt;
-       u8 *wpsie_ptr = NULL;
-       u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
-
-       if (wps_ielen)
-               *wps_ielen = 0;
-
-       if (!in_ie || in_len <= 0)
-               return wpsie_ptr;
-
-       cnt = 0;
-
-       while (cnt < in_len) {
-               eid = in_ie[cnt];
-
-               if ((eid == _WPA_IE_ID_) && (!memcmp(&in_ie[cnt + 2], wps_oui, 4))) {
-                       wpsie_ptr = &in_ie[cnt];
-
-                       if (wps_ie)
-                               memcpy(wps_ie, &in_ie[cnt], in_ie[cnt + 1] + 2);
-
-                       if (wps_ielen)
-                               *wps_ielen = in_ie[cnt + 1] + 2;
-
-                       cnt += in_ie[cnt + 1] + 2;
-
-                       break;
-               }
-               cnt += in_ie[cnt + 1] + 2; /* goto next */
-       }
-       return wpsie_ptr;
-}
-
-/**
- * rtw_get_wps_attr - Search a specific WPS attribute from a given WPS IE
- * @wps_ie: Address of WPS IE to search
- * @wps_ielen: Length limit from wps_ie
- * @target_attr_id: The attribute ID of WPS attribute to search
- * @buf_attr: If not NULL and the WPS attribute is found, WPS attribute will be copied to the buf starting from buf_attr
- * @len_attr: If not NULL and the WPS attribute is found, will set to the length of the entire WPS attribute
- *
- * Returns: the address of the specific WPS attribute found, or NULL
- */
-u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8 *buf_attr, u32 *len_attr)
-{
-       u8 *attr_ptr = NULL;
-       u8 *target_attr_ptr = NULL;
-       u8 wps_oui[4] = {0x00, 0x50, 0xF2, 0x04};
-
-       if (len_attr)
-               *len_attr = 0;
-
-       if ((wps_ie[0] != _VENDOR_SPECIFIC_IE_) ||
-           (memcmp(wps_ie + 2, wps_oui, 4)))
-               return attr_ptr;
-
-       /*  6 = 1(Element ID) + 1(Length) + 4(WPS OUI) */
-       attr_ptr = wps_ie + 6; /* goto first attr */
-
-       while (attr_ptr - wps_ie < wps_ielen) {
-               /*  4 = 2(Attribute ID) + 2(Length) */
-               u16 attr_id = RTW_GET_BE16(attr_ptr);
-               u16 attr_data_len = RTW_GET_BE16(attr_ptr + 2);
-               u16 attr_len = attr_data_len + 4;
-
-               if (attr_id == target_attr_id) {
-                       target_attr_ptr = attr_ptr;
-                       if (buf_attr)
-                               memcpy(buf_attr, attr_ptr, attr_len);
-                       if (len_attr)
-                               *len_attr = attr_len;
-                       break;
-               }
-               attr_ptr += attr_len; /* goto next */
-       }
-       return target_attr_ptr;
-}
-
-/**
- * rtw_get_wps_attr_content - Search a specific WPS attribute content from a given WPS IE
- * @wps_ie: Address of WPS IE to search
- * @wps_ielen: Length limit from wps_ie
- * @target_attr_id: The attribute ID of WPS attribute to search
- * @buf_content: If not NULL and the WPS attribute is found, WPS attribute content will be copied to the buf starting from buf_content
- * @len_content: If not NULL and the WPS attribute is found, will set to the length of the WPS attribute content
- *
- * Returns: the address of the specific WPS attribute content found, or NULL
- */
-u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8 *buf_content, uint *len_content)
-{
-       u8 *attr_ptr;
-       u32 attr_len;
-
-       if (len_content)
-               *len_content = 0;
-
-       attr_ptr = rtw_get_wps_attr(wps_ie, wps_ielen, target_attr_id, NULL, &attr_len);
-
-       if (attr_ptr && attr_len) {
-               if (buf_content)
-                       memcpy(buf_content, attr_ptr + 4, attr_len - 4);
-
-               if (len_content)
-                       *len_content = attr_len - 4;
-
-               return attr_ptr + 4;
-       }
-
-       return NULL;
-}
-
-static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen,
-                                           struct rtw_ieee802_11_elems *elems,
-                                           int show_errors)
-{
-       unsigned int oui;
-
-       /* first 3 bytes in vendor specific information element are the IEEE
-        * OUI of the vendor. The following byte is used a vendor specific
-        * sub-type. */
-       if (elen < 4)
-               return -1;
-
-       oui = RTW_GET_BE24(pos);
-       switch (oui) {
-       case OUI_MICROSOFT:
-               /* Microsoft/Wi-Fi information elements are further typed and
-                * subtyped */
-               switch (pos[3]) {
-               case 1:
-                       /* Microsoft OUI (00:50:F2) with OUI Type 1:
-                        * real WPA information element */
-                       elems->wpa_ie = pos;
-                       elems->wpa_ie_len = elen;
-                       break;
-               case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */
-                       if (elen < 5)
-                               return -1;
-                       switch (pos[4]) {
-                       case WME_OUI_SUBTYPE_INFORMATION_ELEMENT:
-                       case WME_OUI_SUBTYPE_PARAMETER_ELEMENT:
-                               elems->wme = pos;
-                               elems->wme_len = elen;
-                               break;
-                       case WME_OUI_SUBTYPE_TSPEC_ELEMENT:
-                               elems->wme_tspec = pos;
-                               elems->wme_tspec_len = elen;
-                               break;
-                       default:
-                               return -1;
-                       }
-                       break;
-               case 4:
-                       /* Wi-Fi Protected Setup (WPS) IE */
-                       elems->wps_ie = pos;
-                       elems->wps_ie_len = elen;
-                       break;
-               default:
-                       return -1;
-               }
-               break;
-
-       case OUI_BROADCOM:
-               switch (pos[3]) {
-               case VENDOR_HT_CAPAB_OUI_TYPE:
-                       elems->vendor_ht_cap = pos;
-                       elems->vendor_ht_cap_len = elen;
-                       break;
-               default:
-                       return -1;
-               }
-               break;
-       default:
-               return -1;
-       }
-       return 0;
-}
-
-/**
- * ieee802_11_parse_elems - Parse information elements in management frames
- * @start: Pointer to the start of IEs
- * @len: Length of IE buffer in octets
- * @elems: Data structure for parsed elements
- * @show_errors: Whether to show parsing errors in debug log
- * Returns: Parsing result
- */
-enum parse_res rtw_ieee802_11_parse_elems(u8 *start, uint len,
-                               struct rtw_ieee802_11_elems *elems,
-                               int show_errors)
-{
-       uint left = len;
-       u8 *pos = start;
-       int unknown = 0;
-
-       memset(elems, 0, sizeof(*elems));
-
-       while (left >= 2) {
-               u8 id, elen;
-
-               id = *pos++;
-               elen = *pos++;
-               left -= 2;
-
-               if (elen > left)
-                       return ParseFailed;
-
-               switch (id) {
-               case WLAN_EID_SSID:
-                       elems->ssid = pos;
-                       elems->ssid_len = elen;
-                       break;
-               case WLAN_EID_SUPP_RATES:
-                       elems->supp_rates = pos;
-                       elems->supp_rates_len = elen;
-                       break;
-               case WLAN_EID_FH_PARAMS:
-                       elems->fh_params = pos;
-                       elems->fh_params_len = elen;
-                       break;
-               case WLAN_EID_DS_PARAMS:
-                       elems->ds_params = pos;
-                       elems->ds_params_len = elen;
-                       break;
-               case WLAN_EID_CF_PARAMS:
-                       elems->cf_params = pos;
-                       elems->cf_params_len = elen;
-                       break;
-               case WLAN_EID_TIM:
-                       elems->tim = pos;
-                       elems->tim_len = elen;
-                       break;
-               case WLAN_EID_IBSS_PARAMS:
-                       elems->ibss_params = pos;
-                       elems->ibss_params_len = elen;
-                       break;
-               case WLAN_EID_CHALLENGE:
-                       elems->challenge = pos;
-                       elems->challenge_len = elen;
-                       break;
-               case WLAN_EID_ERP_INFO:
-                       elems->erp_info = pos;
-                       elems->erp_info_len = elen;
-                       break;
-               case WLAN_EID_EXT_SUPP_RATES:
-                       elems->ext_supp_rates = pos;
-                       elems->ext_supp_rates_len = elen;
-                       break;
-               case WLAN_EID_VENDOR_SPECIFIC:
-                       if (rtw_ieee802_11_parse_vendor_specific(pos, elen, elems, show_errors))
-                               unknown++;
-                       break;
-               case WLAN_EID_RSN:
-                       elems->rsn_ie = pos;
-                       elems->rsn_ie_len = elen;
-                       break;
-               case WLAN_EID_PWR_CAPABILITY:
-                       elems->power_cap = pos;
-                       elems->power_cap_len = elen;
-                       break;
-               case WLAN_EID_SUPPORTED_CHANNELS:
-                       elems->supp_channels = pos;
-                       elems->supp_channels_len = elen;
-                       break;
-               case WLAN_EID_MOBILITY_DOMAIN:
-                       elems->mdie = pos;
-                       elems->mdie_len = elen;
-                       break;
-               case WLAN_EID_FAST_BSS_TRANSITION:
-                       elems->ftie = pos;
-                       elems->ftie_len = elen;
-                       break;
-               case WLAN_EID_TIMEOUT_INTERVAL:
-                       elems->timeout_int = pos;
-                       elems->timeout_int_len = elen;
-                       break;
-               case WLAN_EID_HT_CAP:
-                       elems->ht_capabilities = pos;
-                       elems->ht_capabilities_len = elen;
-                       break;
-               case WLAN_EID_HT_OPERATION:
-                       elems->ht_operation = pos;
-                       elems->ht_operation_len = elen;
-                       break;
-               default:
-                       unknown++;
-                       break;
-               }
-               left -= elen;
-               pos += elen;
-       }
-       if (left)
-               return ParseFailed;
-       return unknown ? ParseUnknown : ParseOK;
-}
-
-u8 key_char2num(u8 ch)
-{
-       if ((ch >= '0') && (ch <= '9'))
-               return ch - '0';
-       else if ((ch >= 'a') && (ch <= 'f'))
-               return ch - 'a' + 10;
-       else if ((ch >= 'A') && (ch <= 'F'))
-               return ch - 'A' + 10;
-       else
-               return 0xff;
-}
-
-u8 str_2char2num(u8 hch, u8 lch)
-{
-    return (key_char2num(hch) * 10) + key_char2num(lch);
-}
-
-u8 key_2char2num(u8 hch, u8 lch)
-{
-    return (key_char2num(hch) << 4) | key_char2num(lch);
-}
-
-void rtw_macaddr_cfg(u8 *mac_addr)
-{
-       u8 mac[ETH_ALEN];
-
-       if (!mac_addr)
-               return;
-
-       if (rtw_initmac && mac_pton(rtw_initmac, mac)) {
-               /* Users specify the mac address */
-               ether_addr_copy(mac_addr, mac);
-       } else {
-               /* Use the mac address stored in the Efuse */
-               ether_addr_copy(mac, mac_addr);
-       }
-
-       if (is_broadcast_ether_addr(mac) || is_zero_ether_addr(mac))
-               eth_random_addr(mac_addr);
-}
-
-/**
- * rtw_get_p2p_ie - Search P2P IE from a series of IEs
- * @in_ie: Address of IEs to search
- * @in_len: Length limit from in_ie
- * @p2p_ie: If not NULL and P2P IE is found, P2P IE will be copied to the buf starting from p2p_ie
- * @p2p_ielen: If not NULL and P2P IE is found, will set to the length of the entire P2P IE
- *
- * Returns: The address of the P2P IE found, or NULL
- */
-u8 *rtw_get_p2p_ie(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen)
-{
-       uint cnt = 0;
-       u8 *p2p_ie_ptr;
-       u8 eid, p2p_oui[4] = {0x50, 0x6F, 0x9A, 0x09};
-
-       if (p2p_ielen)
-               *p2p_ielen = 0;
-
-       while (cnt < in_len) {
-               eid = in_ie[cnt];
-               if ((in_len < 0) || (cnt > MAX_IE_SZ)) {
-                       dump_stack();
-                       return NULL;
-               }
-               if ((eid == _VENDOR_SPECIFIC_IE_) && !memcmp(&in_ie[cnt + 2], p2p_oui, 4)) {
-                       p2p_ie_ptr = in_ie + cnt;
-
-                       if (p2p_ie)
-                               memcpy(p2p_ie, &in_ie[cnt], in_ie[cnt + 1] + 2);
-                       if (p2p_ielen)
-                               *p2p_ielen = in_ie[cnt + 1] + 2;
-                       return p2p_ie_ptr;
-               }
-               cnt += in_ie[cnt + 1] + 2; /* goto next */
-       }
-       return NULL;
-}
-
-/**
- * rtw_get_p2p_attr - Search a specific P2P attribute from a given P2P IE
- * @p2p_ie: Address of P2P IE to search
- * @p2p_ielen: Length limit from p2p_ie
- * @target_attr_id: The attribute ID of P2P attribute to search
- * @buf_attr: If not NULL and the P2P attribute is found, P2P attribute will be copied to the buf starting from buf_attr
- * @len_attr: If not NULL and the P2P attribute is found, will set to the length of the entire P2P attribute
- *
- * Returns: the address of the specific WPS attribute found, or NULL
- */
-u8 *rtw_get_p2p_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id, u8 *buf_attr, u32 *len_attr)
-{
-       u8 *attr_ptr = NULL;
-       u8 *target_attr_ptr = NULL;
-       u8 p2p_oui[4] = {0x50, 0x6F, 0x9A, 0x09};
-
-       if (len_attr)
-               *len_attr = 0;
-
-       if (!p2p_ie || (p2p_ie[0] != _VENDOR_SPECIFIC_IE_) ||
-           memcmp(p2p_ie + 2, p2p_oui, 4))
-               return attr_ptr;
-
-       /*  6 = 1(Element ID) + 1(Length) + 3 (OUI) + 1(OUI Type) */
-       attr_ptr = p2p_ie + 6; /* goto first attr */
-
-       while (attr_ptr - p2p_ie < p2p_ielen) {
-               /*  3 = 1(Attribute ID) + 2(Length) */
-               u8 attr_id = *attr_ptr;
-               u16 attr_data_len = get_unaligned_le16(attr_ptr + 1);
-               u16 attr_len = attr_data_len + 3;
-
-               if (attr_id == target_attr_id) {
-                       target_attr_ptr = attr_ptr;
-
-                       if (buf_attr)
-                               memcpy(buf_attr, attr_ptr, attr_len);
-                       if (len_attr)
-                               *len_attr = attr_len;
-                       break;
-               }
-               attr_ptr += attr_len; /* goto next */
-       }
-       return target_attr_ptr;
-}
-
-/**
- * rtw_get_p2p_attr_content - Search a specific P2P attribute content from a given P2P IE
- * @p2p_ie: Address of P2P IE to search
- * @p2p_ielen: Length limit from p2p_ie
- * @target_attr_id: The attribute ID of P2P attribute to search
- * @buf_content: If not NULL and the P2P attribute is found, P2P attribute content will be copied to the buf starting from buf_content
- * @len_content: If not NULL and the P2P attribute is found, will set to the length of the P2P attribute content
- *
- * Returns: the address of the specific P2P attribute content found, or NULL
- */
-u8 *rtw_get_p2p_attr_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id, u8 *buf_content, uint *len_content)
-{
-       u8 *attr_ptr;
-       u32 attr_len;
-
-       if (len_content)
-               *len_content = 0;
-
-       attr_ptr = rtw_get_p2p_attr(p2p_ie, p2p_ielen, target_attr_id, NULL, &attr_len);
-
-       if (attr_ptr && attr_len) {
-               if (buf_content)
-                       memcpy(buf_content, attr_ptr + 3, attr_len - 3);
-
-               if (len_content)
-                       *len_content = attr_len - 3;
-
-               return attr_ptr + 3;
-       }
-
-       return NULL;
-}
-
-u32 rtw_set_p2p_attr_content(u8 *pbuf, u8 attr_id, u16 attr_len, u8 *pdata_attr)
-{
-       u32 a_len;
-
-       *pbuf = attr_id;
-
-       /* u16*)(pbuf + 1) = cpu_to_le16(attr_len); */
-       RTW_PUT_LE16(pbuf + 1, attr_len);
-
-       if (pdata_attr)
-               memcpy(pbuf + 3, pdata_attr, attr_len);
-
-       a_len = attr_len + 3;
-
-       return a_len;
-}
-
-static uint rtw_p2p_attr_remove(u8 *ie, uint ielen_ori, u8 attr_id)
-{
-       u8 *target_attr;
-       u32 target_attr_len;
-       uint ielen = ielen_ori;
-
-       while (1) {
-               target_attr = rtw_get_p2p_attr(ie, ielen, attr_id, NULL, &target_attr_len);
-               if (target_attr && target_attr_len) {
-                       u8 *next_attr = target_attr + target_attr_len;
-                       uint remain_len = ielen - (next_attr - ie);
-
-                       memset(target_attr, 0, target_attr_len);
-                       memcpy(target_attr, next_attr, remain_len);
-                       memset(target_attr + remain_len, 0, target_attr_len);
-                       *(ie + 1) -= target_attr_len;
-                       ielen -= target_attr_len;
-               } else {
-                       break;
-               }
-       }
-       return ielen;
-}
-
-void rtw_wlan_bssid_ex_remove_p2p_attr(struct wlan_bssid_ex *bss_ex, u8 attr_id)
-{
-       u8 *p2p_ie;
-       uint p2p_ielen, p2p_ielen_ori;
-
-       p2p_ie = rtw_get_p2p_ie(bss_ex->IEs + _FIXED_IE_LENGTH_, bss_ex->IELength - _FIXED_IE_LENGTH_, NULL, &p2p_ielen_ori);
-       if (p2p_ie) {
-               p2p_ielen = rtw_p2p_attr_remove(p2p_ie, p2p_ielen_ori, attr_id);
-               if (p2p_ielen != p2p_ielen_ori) {
-                       u8 *next_ie_ori = p2p_ie + p2p_ielen_ori;
-                       u8 *next_ie = p2p_ie + p2p_ielen;
-                       uint remain_len = bss_ex->IELength - (next_ie_ori - bss_ex->IEs);
-
-                       memcpy(next_ie, next_ie_ori, remain_len);
-                       memset(next_ie + remain_len, 0, p2p_ielen_ori - p2p_ielen);
-                       bss_ex->IELength -= p2p_ielen_ori - p2p_ielen;
-               }
-       }
-}
-
-static int rtw_get_cipher_info(struct wlan_network *pnetwork)
-{
-       u32 wpa_ielen;
-       unsigned char *pbuf;
-       int group_cipher = 0, pairwise_cipher = 0, is8021x = 0;
-       int ret = _FAIL;
-
-       pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
-
-       if (pbuf && (wpa_ielen > 0)) {
-               if (rtw_parse_wpa_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x) == _SUCCESS) {
-                       pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher;
-                       pnetwork->BcnInfo.group_cipher = group_cipher;
-                       pnetwork->BcnInfo.is_8021x = is8021x;
-                       ret = _SUCCESS;
-               }
-       } else {
-               pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
-
-               if (pbuf && (wpa_ielen > 0)) {
-                       if (rtw_parse_wpa2_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x) == _SUCCESS) {
-                               pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher;
-                               pnetwork->BcnInfo.group_cipher = group_cipher;
-                               pnetwork->BcnInfo.is_8021x = is8021x;
-                               ret = _SUCCESS;
-                       }
-               }
-       }
-
-       return ret;
-}
-
-void rtw_get_bcn_info(struct wlan_network *pnetwork)
-{
-       unsigned short cap = 0;
-       u8 bencrypt = 0;
-       __le16 le_tmp;
-       u16 wpa_len = 0, rsn_len = 0;
-       struct HT_info_element *pht_info = NULL;
-       struct ieee80211_ht_cap *pht_cap = NULL;
-       unsigned int            len;
-       unsigned char           *p;
-
-       memcpy(&le_tmp, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
-       cap = le16_to_cpu(le_tmp);
-       if (cap & WLAN_CAPABILITY_PRIVACY) {
-               bencrypt = 1;
-               pnetwork->network.Privacy = 1;
-       } else {
-               pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_OPENSYS;
-       }
-       rtw_get_sec_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &rsn_len, NULL, &wpa_len);
-
-       if (rsn_len > 0) {
-               pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA2;
-       } else if (wpa_len > 0) {
-               pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA;
-       } else {
-               if (bencrypt)
-                       pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WEP;
-       }
-       rtw_get_cipher_info(pnetwork);
-
-       /* get bwmode and ch_offset */
-       /* parsing HT_CAP_IE */
-       p = rtw_get_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pnetwork->network.IELength - _FIXED_IE_LENGTH_);
-       if (p && len > 0) {
-                       pht_cap = (struct ieee80211_ht_cap *)(p + 2);
-                       pnetwork->BcnInfo.ht_cap_info = le16_to_cpu(pht_cap->cap_info);
-       } else {
-                       pnetwork->BcnInfo.ht_cap_info = 0;
-       }
-       /* parsing HT_INFO_IE */
-       p = rtw_get_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, pnetwork->network.IELength - _FIXED_IE_LENGTH_);
-       if (p && len > 0) {
-                       pht_info = (struct HT_info_element *)(p + 2);
-                       pnetwork->BcnInfo.ht_info_infos_0 = pht_info->infos[0];
-       } else {
-                       pnetwork->BcnInfo.ht_info_infos_0 = 0;
-       }
-}
-
-/* show MCS rate, unit: 100Kbps */
-u16 rtw_mcs_rate(u8 bw_40MHz, u8 short_GI_20, u8 short_GI_40, unsigned char *MCS_rate)
-{
-       u16 max_rate = 0;
-
-       if (MCS_rate[0] & BIT(7))
-               max_rate = (bw_40MHz) ? ((short_GI_40) ? 1500 : 1350) : ((short_GI_20) ? 722 : 650);
-       else if (MCS_rate[0] & BIT(6))
-               max_rate = (bw_40MHz) ? ((short_GI_40) ? 1350 : 1215) : ((short_GI_20) ? 650 : 585);
-       else if (MCS_rate[0] & BIT(5))
-               max_rate = (bw_40MHz) ? ((short_GI_40) ? 1200 : 1080) : ((short_GI_20) ? 578 : 520);
-       else if (MCS_rate[0] & BIT(4))
-               max_rate = (bw_40MHz) ? ((short_GI_40) ? 900 : 810) : ((short_GI_20) ? 433 : 390);
-       else if (MCS_rate[0] & BIT(3))
-               max_rate = (bw_40MHz) ? ((short_GI_40) ? 600 : 540) : ((short_GI_20) ? 289 : 260);
-       else if (MCS_rate[0] & BIT(2))
-               max_rate = (bw_40MHz) ? ((short_GI_40) ? 450 : 405) : ((short_GI_20) ? 217 : 195);
-       else if (MCS_rate[0] & BIT(1))
-               max_rate = (bw_40MHz) ? ((short_GI_40) ? 300 : 270) : ((short_GI_20) ? 144 : 130);
-       else if (MCS_rate[0] & BIT(0))
-               max_rate = (bw_40MHz) ? ((short_GI_40) ? 150 : 135) : ((short_GI_20) ? 72 : 65);
-
-       return max_rate;
-}
diff --git a/drivers/staging/r8188eu/core/rtw_ioctl_set.c b/drivers/staging/r8188eu/core/rtw_ioctl_set.c
deleted file mode 100644 (file)
index 785c0db..0000000
+++ /dev/null
@@ -1,479 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-#define _RTW_IOCTL_SET_C_
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/rtw_ioctl_set.h"
-#include "../include/hal_intf.h"
-
-#include "../include/usb_osintf.h"
-#include "../include/usb_ops.h"
-
-u8 rtw_do_join(struct adapter *padapter)
-{
-       struct list_head *plist, *phead;
-       u8 *pibss = NULL;
-       struct  mlme_priv       *pmlmepriv = &padapter->mlmepriv;
-       struct __queue *queue   = &pmlmepriv->scanned_queue;
-       u8 ret = _SUCCESS;
-
-       spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-       phead = get_list_head(queue);
-       plist = phead->next;
-
-       pmlmepriv->cur_network.join_res = -2;
-
-       set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
-
-       pmlmepriv->pscanned = plist;
-
-       pmlmepriv->to_join = true;
-
-       if (list_empty(&queue->queue)) {
-               spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-               _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
-
-               /* when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty */
-               /* we try to issue sitesurvey firstly */
-
-               if (!pmlmepriv->LinkDetectInfo.bBusyTraffic ||
-                   pmlmepriv->to_roaming > 0) {
-                       /*  submit site_survey_cmd */
-                       ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1);
-                       if (ret != _SUCCESS)
-                               pmlmepriv->to_join = false;
-               } else {
-                       pmlmepriv->to_join = false;
-                       ret = _FAIL;
-               }
-
-               return ret;
-       } else {
-               int select_ret;
-
-               spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-               select_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
-               if (select_ret == _SUCCESS) {
-                       pmlmepriv->to_join = false;
-                       _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
-               } else {
-                       if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
-                               /*  submit createbss_cmd to change to a ADHOC_MASTER */
-
-                               /* pmlmepriv->lock has been acquired by caller... */
-                               struct wlan_bssid_ex    *pdev_network = &padapter->registrypriv.dev_network;
-
-                               pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
-
-                               pibss = padapter->registrypriv.dev_network.MacAddress;
-
-                               memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
-
-                               rtw_update_registrypriv_dev_network(padapter);
-
-                               rtw_generate_random_ibss(pibss);
-
-                               if (rtw_createbss_cmd(padapter) != _SUCCESS)
-                                       return false;
-
-                               pmlmepriv->to_join = false;
-                       } else {
-                               /*  can't associate ; reset under-linking */
-                               _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
-
-                               /* when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue */
-                               /* we try to issue sitesurvey firstly */
-                               if (!pmlmepriv->LinkDetectInfo.bBusyTraffic ||
-                                   pmlmepriv->to_roaming > 0) {
-                                       ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1);
-                                       if (ret != _SUCCESS)
-                                               pmlmepriv->to_join = false;
-                               } else {
-                                       ret = _FAIL;
-                                       pmlmepriv->to_join = false;
-                               }
-                       }
-               }
-       }
-
-       return ret;
-}
-
-u8 rtw_set_802_11_bssid(struct adapter *padapter, u8 *bssid)
-{
-       u8 status = _SUCCESS;
-       u32 cur_time = 0;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
-       if ((bssid[0] == 0x00 && bssid[1] == 0x00 && bssid[2] == 0x00 &&
-            bssid[3] == 0x00 && bssid[4] == 0x00 && bssid[5] == 0x00) ||
-           (bssid[0] == 0xFF && bssid[1] == 0xFF && bssid[2] == 0xFF &&
-            bssid[3] == 0xFF && bssid[4] == 0xFF && bssid[5] == 0xFF)) {
-               status = _FAIL;
-               goto exit;
-       }
-
-       spin_lock_bh(&pmlmepriv->lock);
-
-       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
-               goto handle_tkip_countermeasure;
-       else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
-               goto release_mlme_lock;
-
-       if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
-               if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN)) {
-                       if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE))
-                               goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
-               } else {
-                       rtw_disassoc_cmd(padapter, 0, true);
-
-                       if (check_fwstate(pmlmepriv, _FW_LINKED))
-                               rtw_indicate_disconnect(padapter);
-
-                       rtw_free_assoc_resources(padapter, 1);
-
-                       if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
-                               _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
-                               set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
-                       }
-               }
-       }
-
-handle_tkip_countermeasure:
-       /* should we add something here...? */
-
-       if (padapter->securitypriv.btkip_countermeasure) {
-               cur_time = jiffies;
-
-               if ((cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ) {
-                       padapter->securitypriv.btkip_countermeasure = false;
-                       padapter->securitypriv.btkip_countermeasure_time = 0;
-               } else {
-                       status = _FAIL;
-                       goto release_mlme_lock;
-               }
-       }
-
-       memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
-       pmlmepriv->assoc_by_bssid = true;
-
-       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
-               pmlmepriv->to_join = true;
-       else
-               status = rtw_do_join(padapter);
-
-release_mlme_lock:
-       spin_unlock_bh(&pmlmepriv->lock);
-
-exit:
-       return status;
-}
-
-u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid)
-{
-       u8 status = _SUCCESS;
-       u32 cur_time = 0;
-
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct wlan_network *pnetwork = &pmlmepriv->cur_network;
-
-       if (!padapter->hw_init_completed) {
-               status = _FAIL;
-               goto exit;
-       }
-
-       spin_lock_bh(&pmlmepriv->lock);
-
-       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
-               goto handle_tkip_countermeasure;
-       } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
-               goto release_mlme_lock;
-       }
-
-       if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
-               if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) &&
-                   (!memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength))) {
-                       if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
-                               if (!rtw_is_same_ibss(padapter, pnetwork)) {
-                                       /* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */
-                                       rtw_disassoc_cmd(padapter, 0, true);
-
-                                       if (check_fwstate(pmlmepriv, _FW_LINKED))
-                                               rtw_indicate_disconnect(padapter);
-
-                                       rtw_free_assoc_resources(padapter, 1);
-
-                                       if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
-                                               _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
-                                               set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
-                                       }
-                               } else {
-                                       goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
-                               }
-                       } else {
-                               rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1);
-                       }
-               } else {
-                       rtw_disassoc_cmd(padapter, 0, true);
-
-                       if (check_fwstate(pmlmepriv, _FW_LINKED))
-                               rtw_indicate_disconnect(padapter);
-
-                       rtw_free_assoc_resources(padapter, 1);
-
-                       if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
-                               _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
-                               set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
-                       }
-               }
-       }
-
-handle_tkip_countermeasure:
-
-       if (padapter->securitypriv.btkip_countermeasure) {
-               cur_time = jiffies;
-
-               if ((cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ) {
-                       padapter->securitypriv.btkip_countermeasure = false;
-                       padapter->securitypriv.btkip_countermeasure_time = 0;
-               } else {
-                       status = _FAIL;
-                       goto release_mlme_lock;
-               }
-       }
-
-       memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid));
-       pmlmepriv->assoc_by_bssid = false;
-
-       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
-               pmlmepriv->to_join = true;
-       } else {
-               status = rtw_do_join(padapter);
-       }
-
-release_mlme_lock:
-       spin_unlock_bh(&pmlmepriv->lock);
-
-exit:
-       return status;
-}
-
-u8 rtw_set_802_11_infrastructure_mode(struct adapter *padapter,
-       enum ndis_802_11_network_infra networktype)
-{
-       struct  mlme_priv       *pmlmepriv = &padapter->mlmepriv;
-       struct  wlan_network    *cur_network = &pmlmepriv->cur_network;
-       enum ndis_802_11_network_infra *pold_state = &cur_network->network.InfrastructureMode;
-
-       if (*pold_state != networktype) {
-               spin_lock_bh(&pmlmepriv->lock);
-
-               if (*pold_state == Ndis802_11APMode) {
-                       /* change to other mode from Ndis802_11APMode */
-                       cur_network->join_res = -1;
-
-                       stop_ap_mode(padapter);
-               }
-
-               if ((check_fwstate(pmlmepriv, _FW_LINKED)) ||
-                   (*pold_state == Ndis802_11IBSS))
-                       rtw_disassoc_cmd(padapter, 0, true);
-
-               if ((check_fwstate(pmlmepriv, _FW_LINKED)) ||
-                   (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)))
-                       rtw_free_assoc_resources(padapter, 1);
-
-               if ((*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) {
-                       if (check_fwstate(pmlmepriv, _FW_LINKED))
-                               rtw_indicate_disconnect(padapter); /* will clr Linked_state; before this function, we must have checked whether issue dis-assoc_cmd or not */
-              }
-
-               *pold_state = networktype;
-
-               _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE);
-
-               switch (networktype) {
-               case Ndis802_11IBSS:
-                       set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
-                       break;
-               case Ndis802_11Infrastructure:
-                       set_fwstate(pmlmepriv, WIFI_STATION_STATE);
-                       break;
-               case Ndis802_11APMode:
-                       set_fwstate(pmlmepriv, WIFI_AP_STATE);
-                       break;
-               case Ndis802_11AutoUnknown:
-               case Ndis802_11InfrastructureMax:
-                       break;
-               }
-               spin_unlock_bh(&pmlmepriv->lock);
-       }
-
-       return true;
-}
-
-void rtw_set_802_11_disassociate(struct adapter *padapter)
-{
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
-       spin_lock_bh(&pmlmepriv->lock);
-
-       if (check_fwstate(pmlmepriv, _FW_LINKED)) {
-               rtw_disassoc_cmd(padapter, 0, true);
-               rtw_indicate_disconnect(padapter);
-               rtw_free_assoc_resources(padapter, 1);
-               rtw_pwr_wakeup(padapter);
-       }
-
-       spin_unlock_bh(&pmlmepriv->lock);
-}
-
-u8 rtw_set_802_11_bssid_list_scan(struct adapter *padapter, struct ndis_802_11_ssid *pssid, int ssid_max_num)
-{
-       struct  mlme_priv               *pmlmepriv = &padapter->mlmepriv;
-       u8      res = true;
-
-       if (!padapter) {
-               res = false;
-               goto exit;
-       }
-       if (!padapter->hw_init_completed) {
-               res = false;
-               goto exit;
-       }
-
-       if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) ||
-           (pmlmepriv->LinkDetectInfo.bBusyTraffic)) {
-               /*  Scan or linking is in progress, do nothing. */
-               res = true;
-       } else {
-               spin_lock_bh(&pmlmepriv->lock);
-
-               res = rtw_sitesurvey_cmd(padapter, pssid, ssid_max_num);
-
-               spin_unlock_bh(&pmlmepriv->lock);
-       }
-exit:
-
-       return res;
-}
-
-u8 rtw_set_802_11_authentication_mode(struct adapter *padapter, enum ndis_802_11_auth_mode authmode)
-{
-       struct security_priv *psecuritypriv = &padapter->securitypriv;
-       int res;
-       u8 ret;
-
-       psecuritypriv->ndisauthtype = authmode;
-
-       if (psecuritypriv->ndisauthtype > 3)
-               psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
-
-       res = rtw_set_auth(padapter, psecuritypriv);
-
-       if (res == _SUCCESS)
-               ret = true;
-       else
-               ret = false;
-
-       return ret;
-}
-
-u8 rtw_set_802_11_add_wep(struct adapter *padapter, struct ndis_802_11_wep *wep)
-{
-       int             keyid, res;
-       struct security_priv *psecuritypriv = &padapter->securitypriv;
-       u8              ret = _SUCCESS;
-
-       keyid = wep->KeyIndex & 0x3fffffff;
-
-       if (keyid >= 4) {
-               ret = false;
-               goto exit;
-       }
-
-       switch (wep->KeyLength) {
-       case 5:
-               psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
-               break;
-       case 13:
-               psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
-               break;
-       default:
-               psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
-               break;
-       }
-
-       memcpy(&psecuritypriv->dot11DefKey[keyid].skey[0], &wep->KeyMaterial, wep->KeyLength);
-
-       psecuritypriv->dot11DefKeylen[keyid] = wep->KeyLength;
-
-       psecuritypriv->dot11PrivacyKeyIndex = keyid;
-
-       res = rtw_set_key(padapter, psecuritypriv, keyid, 1);
-
-       if (res == _FAIL)
-               ret = false;
-exit:
-
-       return ret;
-}
-
-/*
-* rtw_get_cur_max_rate -
-* @adapter: pointer to struct adapter structure
-*
-* Return 0 or 100Kbps
-*/
-u16 rtw_get_cur_max_rate(struct adapter *adapter)
-{
-       int     i = 0;
-       u8      *p;
-       u16     rate = 0, max_rate = 0;
-       struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct registry_priv *pregistrypriv = &adapter->registrypriv;
-       struct mlme_priv        *pmlmepriv = &adapter->mlmepriv;
-       struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
-       struct ieee80211_ht_cap *pht_capie;
-       u8      bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0;
-       u16     mcs_rate = 0;
-       u32     ht_ielen = 0;
-
-       if ((!check_fwstate(pmlmepriv, _FW_LINKED)) &&
-           (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)))
-               return 0;
-
-       if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N)) {
-               p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength - 12);
-               if (p && ht_ielen > 0) {
-                       pht_capie = (struct ieee80211_ht_cap *)(p + 2);
-
-                       memcpy(&mcs_rate, pht_capie->mcs.rx_mask, 2);
-
-                       /* cur_bwmod is updated by beacon, pmlmeinfo is updated by association response */
-                       bw_40MHz = (pmlmeext->cur_bwmode && (HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH & pmlmeinfo->HT_info.infos[0])) ? 1 : 0;
-
-                       short_GI_20 = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & IEEE80211_HT_CAP_SGI_20) ? 1 : 0;
-                       short_GI_40 = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & IEEE80211_HT_CAP_SGI_40) ? 1 : 0;
-
-                       max_rate = rtw_mcs_rate(bw_40MHz & (pregistrypriv->cbw40_enable),
-                                               short_GI_20,
-                                               short_GI_40,
-                                               pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate);
-               }
-       } else {
-               while ((pcur_bss->SupportedRates[i] != 0) && (pcur_bss->SupportedRates[i] != 0xFF)) {
-                       rate = pcur_bss->SupportedRates[i] & 0x7F;
-                       if (rate > max_rate)
-                               max_rate = rate;
-                       i++;
-               }
-
-               max_rate *= 5;
-       }
-
-       return max_rate;
-}
diff --git a/drivers/staging/r8188eu/core/rtw_iol.c b/drivers/staging/r8188eu/core/rtw_iol.c
deleted file mode 100644 (file)
index 31e196c..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#include "../include/rtw_iol.h"
-
-struct xmit_frame      *rtw_IOL_accquire_xmit_frame(struct adapter  *adapter)
-{
-       struct xmit_frame       *xmit_frame;
-       struct xmit_buf *xmitbuf;
-       struct pkt_attrib       *pattrib;
-       struct xmit_priv        *pxmitpriv = &adapter->xmitpriv;
-
-       xmit_frame = rtw_alloc_xmitframe(pxmitpriv);
-       if (!xmit_frame)
-               return NULL;
-
-       xmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
-       if (!xmitbuf) {
-               rtw_free_xmitframe(pxmitpriv, xmit_frame);
-               return NULL;
-       }
-
-       xmit_frame->frame_tag = MGNT_FRAMETAG;
-       xmit_frame->pxmitbuf = xmitbuf;
-       xmit_frame->buf_addr = xmitbuf->pbuf;
-       xmitbuf->priv_data = xmit_frame;
-
-       pattrib = &xmit_frame->attrib;
-       update_mgntframe_attrib(adapter, pattrib);
-       pattrib->qsel = 0x10;/* Beacon */
-       pattrib->subtype = WIFI_BEACON;
-       pattrib->pktlen = 0;
-       pattrib->last_txcmdsz = 0;
-
-       return xmit_frame;
-}
-
-int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len)
-{
-       struct pkt_attrib       *pattrib = &xmit_frame->attrib;
-       u16 buf_offset;
-       u32 ori_len;
-
-       buf_offset = TXDESC_OFFSET;
-       ori_len = buf_offset + pattrib->pktlen;
-
-       /* check if the io_buf can accommodate new cmds */
-       if (ori_len + cmd_len + 8 > MAX_XMITBUF_SZ)
-               return _FAIL;
-
-       memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len);
-       pattrib->pktlen += cmd_len;
-       pattrib->last_txcmdsz += cmd_len;
-
-       return _SUCCESS;
-}
-
-bool rtw_IOL_applied(struct adapter  *adapter)
-{
-       if (adapter->registrypriv.fw_iol == 1)
-               return true;
-
-       if ((adapter->registrypriv.fw_iol == 2) &&
-           (adapter_to_dvobj(adapter)->pusbdev->speed != USB_SPEED_HIGH))
-               return true;
-
-       return false;
-}
-
-int rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask)
-{
-       struct ioreg_cfg cmd = {8, IOREG_CMD_WB_REG, 0x0, 0x0, 0x0};
-
-       cmd.address = cpu_to_le16(addr);
-       cmd.data = cpu_to_le32(value);
-
-       if (mask != 0xFF) {
-               cmd.length = 12;
-               cmd.mask = cpu_to_le32(mask);
-       }
-       return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
-}
-
-int rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u16 mask)
-{
-       struct ioreg_cfg cmd = {8, IOREG_CMD_WW_REG, 0x0, 0x0, 0x0};
-
-       cmd.address = cpu_to_le16(addr);
-       cmd.data = cpu_to_le32(value);
-
-       if (mask != 0xFFFF) {
-               cmd.length = 12;
-               cmd.mask =  cpu_to_le32(mask);
-       }
-       return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
-}
-
-int rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask)
-{
-       struct ioreg_cfg cmd = {8, IOREG_CMD_WD_REG, 0x0, 0x0, 0x0};
-
-       cmd.address = cpu_to_le16(addr);
-       cmd.data = cpu_to_le32(value);
-
-       if (mask != 0xFFFFFFFF) {
-               cmd.length = 12;
-               cmd.mask =  cpu_to_le32(mask);
-       }
-       return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
-}
-
-int rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask)
-{
-       struct ioreg_cfg cmd = {8, IOREG_CMD_W_RF, 0x0, 0x0, 0x0};
-
-       cmd.address = cpu_to_le16((rf_path << 8) | ((addr) & 0xFF));
-       cmd.data = cpu_to_le32(value);
-
-       if (mask != 0x000FFFFF) {
-               cmd.length = 12;
-               cmd.mask =  cpu_to_le32(mask);
-       }
-       return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
-}
-
-int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)
-{
-       struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};
-       cmd.address = cpu_to_le16(us);
-
-       return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
-}
-
-int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)
-{
-       struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};
-
-       cmd.address = cpu_to_le16(ms);
-       return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
-}
-
-int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)
-{
-       struct ioreg_cfg cmd = {4, IOREG_CMD_END, cpu_to_le16(0xFFFF), cpu_to_le32(0xFF), 0x0};
-
-       return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
-}
-
-u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame)
-{
-       u8 is_cmd_bndy = false;
-       if (((pxmit_frame->attrib.pktlen + 32) % 256) + 8 >= 256) {
-               rtw_IOL_append_END_cmd(pxmit_frame);
-               pxmit_frame->attrib.pktlen = ((((pxmit_frame->attrib.pktlen + 32) / 256) + 1) * 256);
-
-               pxmit_frame->attrib.last_txcmdsz = pxmit_frame->attrib.pktlen;
-               is_cmd_bndy = true;
-       }
-       return is_cmd_bndy;
-}
diff --git a/drivers/staging/r8188eu/core/rtw_led.c b/drivers/staging/r8188eu/core/rtw_led.c
deleted file mode 100644 (file)
index 48725ce..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-#include "../include/drv_types.h"
-#include "../include/rtw_led.h"
-#include "../include/rtl8188e_spec.h"
-
-#define LED_BLINK_NO_LINK_INTVL                        msecs_to_jiffies(1000)
-#define LED_BLINK_LINK_INTVL                   msecs_to_jiffies(500)
-#define LED_BLINK_SCAN_INTVL                   msecs_to_jiffies(180)
-#define LED_BLINK_FASTER_INTVL                 msecs_to_jiffies(50)
-#define LED_BLINK_WPS_SUCESS_INTVL             msecs_to_jiffies(5000)
-
-#define IS_LED_WPS_BLINKING(l) \
-       ((l)->CurrLedState == LED_BLINK_WPS || \
-       (l)->CurrLedState == LED_BLINK_WPS_STOP || \
-       (l)->bLedWPSBlinkInProgress)
-
-static void ResetLedStatus(struct led_priv *pLed)
-{
-       pLed->CurrLedState = RTW_LED_OFF; /*  Current LED state. */
-       pLed->bLedOn = false; /*  true if LED is ON, false if LED is OFF. */
-
-       pLed->bLedBlinkInProgress = false; /*  true if it is blinking, false o.w.. */
-       pLed->bLedWPSBlinkInProgress = false;
-
-       pLed->BlinkTimes = 0; /*  Number of times to toggle led state for blinking. */
-
-       pLed->bLedScanBlinkInProgress = false;
-}
-
-static void SwLedOn(struct led_priv *pLed)
-{
-       struct adapter *padapter = container_of(pLed, struct adapter, ledpriv);
-
-       if (padapter->bDriverStopped)
-               return;
-
-       if (rtw_write8(padapter, REG_LEDCFG2, BIT(5)) != _SUCCESS)
-               return;
-
-       pLed->bLedOn = true;
-}
-
-static void SwLedOff(struct led_priv *pLed)
-{
-       struct adapter *padapter = container_of(pLed, struct adapter, ledpriv);
-
-       if (padapter->bDriverStopped)
-               return;
-
-       if (rtw_write8(padapter, REG_LEDCFG2, BIT(5) | BIT(3)) != _SUCCESS)
-               return;
-
-       pLed->bLedOn = false;
-}
-
-static void blink_work(struct work_struct *work)
-{
-       struct delayed_work *dwork = to_delayed_work(work);
-       struct led_priv *pLed = container_of(dwork, struct led_priv, blink_work);
-       struct adapter *padapter = container_of(pLed, struct adapter, ledpriv);
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
-       if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) {
-               SwLedOff(pLed);
-               ResetLedStatus(pLed);
-               return;
-       }
-
-       if (pLed->bLedOn)
-               SwLedOff(pLed);
-       else
-               SwLedOn(pLed);
-
-       switch (pLed->CurrLedState) {
-       case LED_BLINK_SLOWLY:
-               schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL);
-               break;
-       case LED_BLINK_NORMAL:
-               schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL);
-               break;
-       case LED_BLINK_SCAN:
-       case LED_BLINK_TXRX:
-               pLed->BlinkTimes--;
-               if (pLed->BlinkTimes == 0) {
-                       if (check_fwstate(pmlmepriv, _FW_LINKED)) {
-                               pLed->CurrLedState = LED_BLINK_NORMAL;
-                               schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL);
-                       } else {
-                               pLed->CurrLedState = LED_BLINK_SLOWLY;
-                               schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL);
-                       }
-                       pLed->bLedBlinkInProgress = false;
-                       pLed->bLedScanBlinkInProgress = false;
-               } else {
-                       schedule_delayed_work(&pLed->blink_work,
-                                             pLed->CurrLedState == LED_BLINK_SCAN ?
-                                             LED_BLINK_SCAN_INTVL : LED_BLINK_FASTER_INTVL);
-               }
-               break;
-       case LED_BLINK_WPS:
-               schedule_delayed_work(&pLed->blink_work, LED_BLINK_SCAN_INTVL);
-               break;
-       case LED_BLINK_WPS_STOP:        /* WPS success */
-               if (!pLed->bLedOn) {
-                       pLed->CurrLedState = LED_BLINK_NORMAL;
-                       schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL);
-
-                       pLed->bLedWPSBlinkInProgress = false;
-               } else {
-                       schedule_delayed_work(&pLed->blink_work, LED_BLINK_WPS_SUCESS_INTVL);
-               }
-               break;
-       default:
-               break;
-       }
-}
-
-void rtl8188eu_InitSwLeds(struct adapter *padapter)
-{
-       struct led_priv *pledpriv = &padapter->ledpriv;
-
-       ResetLedStatus(pledpriv);
-       INIT_DELAYED_WORK(&pledpriv->blink_work, blink_work);
-}
-
-void rtl8188eu_DeInitSwLeds(struct adapter *padapter)
-{
-       struct led_priv *ledpriv = &padapter->ledpriv;
-
-       cancel_delayed_work_sync(&ledpriv->blink_work);
-       ResetLedStatus(ledpriv);
-       SwLedOff(ledpriv);
-}
-
-void rtw_led_control(struct adapter *padapter, enum LED_CTL_MODE LedAction)
-{
-       struct led_priv *pLed = &padapter->ledpriv;
-       struct registry_priv *registry_par;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
-       if (!padapter->hw_init_completed)
-               return;
-
-       if (!pLed->bRegUseLed)
-               return;
-
-       registry_par = &padapter->registrypriv;
-       if (!registry_par->led_enable)
-               return;
-
-       switch (LedAction) {
-       case LED_CTL_START_TO_LINK:
-       case LED_CTL_NO_LINK:
-               if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
-                       return;
-
-               cancel_delayed_work(&pLed->blink_work);
-
-               pLed->bLedBlinkInProgress = false;
-
-               pLed->CurrLedState = LED_BLINK_SLOWLY;
-               schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL);
-               break;
-       case LED_CTL_LINK:
-               if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
-                       return;
-
-               cancel_delayed_work(&pLed->blink_work);
-
-               pLed->bLedBlinkInProgress = false;
-
-               pLed->CurrLedState = LED_BLINK_NORMAL;
-               schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL);
-               break;
-       case LED_CTL_SITE_SURVEY:
-               if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED)))
-                       return;
-
-               if (pLed->bLedScanBlinkInProgress)
-                       return;
-
-               if (IS_LED_WPS_BLINKING(pLed))
-                       return;
-
-               cancel_delayed_work(&pLed->blink_work);
-
-               pLed->bLedBlinkInProgress = false;
-               pLed->bLedScanBlinkInProgress = true;
-
-               pLed->CurrLedState = LED_BLINK_SCAN;
-               pLed->BlinkTimes = 24;
-               schedule_delayed_work(&pLed->blink_work, LED_BLINK_SCAN_INTVL);
-               break;
-       case LED_CTL_TX:
-       case LED_CTL_RX:
-               if (pLed->bLedBlinkInProgress)
-                       return;
-
-               if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
-                       return;
-
-               cancel_delayed_work(&pLed->blink_work);
-
-               pLed->bLedBlinkInProgress = true;
-
-               pLed->CurrLedState = LED_BLINK_TXRX;
-               pLed->BlinkTimes = 2;
-               schedule_delayed_work(&pLed->blink_work, LED_BLINK_FASTER_INTVL);
-               break;
-       case LED_CTL_START_WPS: /* wait until xinpin finish */
-               if (pLed->bLedWPSBlinkInProgress)
-                       return;
-
-               cancel_delayed_work(&pLed->blink_work);
-
-               pLed->bLedBlinkInProgress = false;
-               pLed->bLedScanBlinkInProgress = false;
-               pLed->bLedWPSBlinkInProgress = true;
-               pLed->CurrLedState = LED_BLINK_WPS;
-               schedule_delayed_work(&pLed->blink_work, LED_BLINK_SCAN_INTVL);
-               break;
-       case LED_CTL_STOP_WPS:
-               cancel_delayed_work(&pLed->blink_work);
-
-               pLed->bLedBlinkInProgress = false;
-               pLed->bLedScanBlinkInProgress = false;
-               pLed->bLedWPSBlinkInProgress = true;
-
-               pLed->CurrLedState = LED_BLINK_WPS_STOP;
-               if (pLed->bLedOn) {
-                       schedule_delayed_work(&pLed->blink_work, LED_BLINK_WPS_SUCESS_INTVL);
-               } else {
-                       schedule_delayed_work(&pLed->blink_work, 0);
-               }
-               break;
-       case LED_CTL_STOP_WPS_FAIL:
-               cancel_delayed_work(&pLed->blink_work);
-               pLed->bLedWPSBlinkInProgress = false;
-               pLed->CurrLedState = LED_BLINK_SLOWLY;
-               schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL);
-               break;
-       case LED_CTL_POWER_OFF:
-               pLed->CurrLedState = RTW_LED_OFF;
-               pLed->bLedBlinkInProgress = false;
-               pLed->bLedWPSBlinkInProgress = false;
-               pLed->bLedScanBlinkInProgress = false;
-               cancel_delayed_work(&pLed->blink_work);
-               SwLedOff(pLed);
-               break;
-       default:
-               break;
-       }
-}
diff --git a/drivers/staging/r8188eu/core/rtw_mlme.c b/drivers/staging/r8188eu/core/rtw_mlme.c
deleted file mode 100644 (file)
index fb7d0e1..0000000
+++ /dev/null
@@ -1,2067 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#define _RTW_MLME_C_
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/hal_intf.h"
-#include "../include/sta_info.h"
-#include "../include/wifi.h"
-#include "../include/wlan_bssdef.h"
-#include "../include/rtw_ioctl_set.h"
-#include "../include/usb_osintf.h"
-#include "../include/rtl8188e_dm.h"
-
-extern unsigned char   MCS_rate_1R[16];
-
-void rtw_set_roaming(struct adapter *adapter, u8 to_roaming)
-{
-       if (to_roaming == 0)
-               adapter->mlmepriv.to_join = false;
-       adapter->mlmepriv.to_roaming = to_roaming;
-}
-
-u8 rtw_to_roaming(struct adapter *adapter)
-{
-       return adapter->mlmepriv.to_roaming;
-}
-
-static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen)
-{
-       kfree(*ppie);
-       *plen = 0;
-       *ppie = NULL;
-}
-
-void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
-{
-       kfree(pmlmepriv->assoc_req);
-       rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len);
-       rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len);
-       rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len);
-       rtw_free_mlme_ie_data(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len);
-
-       rtw_free_mlme_ie_data(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len);
-       rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len);
-       rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len);
-       rtw_free_mlme_ie_data(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len);
-       rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len);
-}
-
-void _rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 isfreeall)
-{
-       u32 curr_time, delta_time;
-       u32 lifetime = SCANQUEUE_LIFETIME;
-       struct __queue *free_queue = &pmlmepriv->free_bss_pool;
-
-       if (!pnetwork)
-               return;
-
-       if (pnetwork->fixed)
-               return;
-       curr_time = jiffies;
-       if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) ||
-           (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)))
-               lifetime = 1;
-       if (!isfreeall) {
-               delta_time = (curr_time - pnetwork->last_scanned) / HZ;
-               if (delta_time < lifetime)/*  unit:sec */
-                       return;
-       }
-       spin_lock_bh(&free_queue->lock);
-       list_del_init(&pnetwork->list);
-       list_add_tail(&pnetwork->list, &free_queue->queue);
-       pmlmepriv->num_of_scanned--;
-       spin_unlock_bh(&free_queue->lock);
-}
-
-/*
-       return the wlan_network with the matching addr
-
-       Shall be called under atomic context... to avoid possible racing condition...
-*/
-struct wlan_network *_rtw_find_network(struct __queue *scanned_queue, u8 *addr)
-{
-       struct list_head *phead, *plist;
-       struct  wlan_network *pnetwork = NULL;
-       u8 zero_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
-
-       if (!memcmp(zero_addr, addr, ETH_ALEN)) {
-               pnetwork = NULL;
-               goto exit;
-       }
-       phead = get_list_head(scanned_queue);
-       plist = phead->next;
-
-       while (plist != phead) {
-               pnetwork = container_of(plist, struct wlan_network, list);
-               if (!memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN))
-                       break;
-               plist = plist->next;
-       }
-       if (plist == phead)
-               pnetwork = NULL;
-exit:
-
-       return pnetwork;
-}
-
-void _rtw_free_network_queue(struct adapter *padapter, u8 isfreeall)
-{
-       struct list_head *phead, *plist;
-       struct wlan_network *pnetwork;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct __queue *scanned_queue = &pmlmepriv->scanned_queue;
-
-       spin_lock_bh(&scanned_queue->lock);
-
-       phead = get_list_head(scanned_queue);
-       plist = phead->next;
-
-       while (phead != plist) {
-               pnetwork = container_of(plist, struct wlan_network, list);
-
-               plist = plist->next;
-
-               _rtw_free_network(pmlmepriv, pnetwork, isfreeall);
-       }
-       spin_unlock_bh(&scanned_queue->lock);
-
-}
-
-int rtw_if_up(struct adapter *padapter)
-{
-       int res;
-
-       if (padapter->bDriverStopped || padapter->bSurpriseRemoved ||
-           !check_fwstate(&padapter->mlmepriv, _FW_LINKED))
-               res = false;
-       else
-               res =  true;
-
-       return res;
-}
-
-void rtw_generate_random_ibss(u8 *pibss)
-{
-       u32     curtime = jiffies;
-
-       pibss[0] = 0x02;  /* in ad-hoc mode bit1 must set to 1 */
-       pibss[1] = 0x11;
-       pibss[2] = 0x87;
-       pibss[3] = (u8)(curtime & 0xff);/* p[0]; */
-       pibss[4] = (u8)((curtime >> 8) & 0xff);/* p[1]; */
-       pibss[5] = (u8)((curtime >> 16) & 0xff);/* p[2]; */
-}
-
-u8 *rtw_get_capability_from_ie(u8 *ie)
-{
-       return ie + 8 + 2;
-}
-
-u16 rtw_get_capability(struct wlan_bssid_ex *bss)
-{
-       __le16  val;
-
-       memcpy((u8 *)&val, rtw_get_capability_from_ie(bss->IEs), 2);
-
-       return le16_to_cpu(val);
-}
-
-u8 *rtw_get_beacon_interval_from_ie(u8 *ie)
-{
-       return ie + 8;
-}
-
-static void rtw_join_timeout_handler(struct timer_list *t)
-{
-       struct adapter *adapter = from_timer(adapter, t, mlmepriv.assoc_timer);
-
-       _rtw_join_timeout_handler(adapter);
-}
-
-static void _rtw_scan_timeout_handler(struct timer_list *t)
-{
-       struct adapter *adapter = from_timer(adapter, t, mlmepriv.scan_to_timer);
-
-       rtw_scan_timeout_handler(adapter);
-}
-
-static void _dynamic_check_timer_handlder(struct timer_list *t)
-{
-       struct adapter *adapter = from_timer(adapter, t, mlmepriv.dynamic_chk_timer);
-
-       rtw_dynamic_check_timer_handlder(adapter);
-       _set_timer(&adapter->mlmepriv.dynamic_chk_timer, 2000);
-}
-
-static void rtw_init_mlme_timer(struct adapter *padapter)
-{
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
-       timer_setup(&pmlmepriv->assoc_timer, rtw_join_timeout_handler, 0);
-       timer_setup(&pmlmepriv->scan_to_timer, _rtw_scan_timeout_handler, 0);
-       timer_setup(&pmlmepriv->dynamic_chk_timer, _dynamic_check_timer_handlder, 0);
-}
-
-int rtw_init_mlme_priv(struct adapter *padapter)/* struct      mlme_priv *pmlmepriv) */
-{
-       int     i;
-       u8      *pbuf;
-       struct wlan_network     *pnetwork;
-       struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
-
-       /*  We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */
-
-       pmlmepriv->nic_hdl = (u8 *)padapter;
-
-       pmlmepriv->pscanned = NULL;
-       pmlmepriv->fw_state = 0;
-       pmlmepriv->cur_network.network.InfrastructureMode = Ndis802_11AutoUnknown;
-       pmlmepriv->scan_mode = SCAN_ACTIVE;/*  1: active, 0: pasive. Maybe someday we should rename this varable to "active_mode" (Jeff) */
-
-       spin_lock_init(&pmlmepriv->lock);
-       rtw_init_queue(&pmlmepriv->free_bss_pool);
-       rtw_init_queue(&pmlmepriv->scanned_queue);
-
-       set_scanned_network_val(pmlmepriv, 0);
-
-       memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));
-
-       pbuf = vzalloc(MAX_BSS_CNT * (sizeof(struct wlan_network)));
-
-       if (!pbuf)
-               return -ENOMEM;
-
-       pmlmepriv->free_bss_buf = pbuf;
-
-       pnetwork = (struct wlan_network *)pbuf;
-
-       for (i = 0; i < MAX_BSS_CNT; i++) {
-               INIT_LIST_HEAD(&pnetwork->list);
-
-               list_add_tail(&pnetwork->list, &pmlmepriv->free_bss_pool.queue);
-
-               pnetwork++;
-       }
-
-       /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
-
-       rtw_init_mlme_timer(padapter);
-
-       return 0;
-}
-
-void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv)
-{
-       rtw_free_mlme_priv_ie_data(pmlmepriv);
-       vfree(pmlmepriv->free_bss_buf);
-}
-
-struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv)
-{
-       struct  wlan_network    *pnetwork;
-       struct __queue *free_queue = &pmlmepriv->free_bss_pool;
-       struct list_head *plist = NULL;
-
-       spin_lock_bh(&free_queue->lock);
-
-       if (list_empty(&free_queue->queue)) {
-               pnetwork = NULL;
-               goto exit;
-       }
-       plist = (&free_queue->queue)->next;
-
-       pnetwork = container_of(plist, struct wlan_network, list);
-
-       list_del_init(&pnetwork->list);
-
-       pnetwork->network_type = 0;
-       pnetwork->fixed = false;
-       pnetwork->last_scanned = jiffies;
-       pnetwork->aid = 0;
-       pnetwork->join_res = 0;
-
-       pmlmepriv->num_of_scanned++;
-
-exit:
-       spin_unlock_bh(&free_queue->lock);
-
-       return pnetwork;
-}
-
-static void rtw_free_network_nolock(struct mlme_priv *pmlmepriv,
-                                   struct wlan_network *pnetwork)
-{
-       struct __queue *free_queue = &pmlmepriv->free_bss_pool;
-
-       if (!pnetwork)
-               return;
-       if (pnetwork->fixed)
-               return;
-       list_del_init(&pnetwork->list);
-       list_add_tail(&pnetwork->list, get_list_head(free_queue));
-       pmlmepriv->num_of_scanned--;
-}
-
-void rtw_free_network_queue(struct adapter *dev, u8 isfreeall)
-{
-
-       _rtw_free_network_queue(dev, isfreeall);
-
-}
-
-/*
-       return the wlan_network with the matching addr
-
-       Shall be called under atomic context... to avoid possible racing condition...
-*/
-struct wlan_network *rtw_find_network(struct __queue *scanned_queue, u8 *addr)
-{
-       struct  wlan_network *pnetwork = _rtw_find_network(scanned_queue, addr);
-
-       return pnetwork;
-}
-
-int rtw_is_same_ibss(struct adapter *adapter, struct wlan_network *pnetwork)
-{
-       int ret = true;
-       struct security_priv *psecuritypriv = &adapter->securitypriv;
-
-       if ((psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_) &&
-           (pnetwork->network.Privacy == 0))
-               ret = false;
-       else if ((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_) &&
-                (pnetwork->network.Privacy == 1))
-               ret = false;
-       else
-               ret = true;
-       return ret;
-}
-
-static int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b)
-{
-       return (a->Ssid.SsidLength == b->Ssid.SsidLength) &&
-              !memcmp(a->Ssid.Ssid, b->Ssid.Ssid, a->Ssid.SsidLength);
-}
-
-int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst)
-{
-       u16 s_cap, d_cap;
-       __le16 le_scap, le_dcap;
-
-       memcpy((u8 *)&le_scap, rtw_get_capability_from_ie(src->IEs), 2);
-       memcpy((u8 *)&le_dcap, rtw_get_capability_from_ie(dst->IEs), 2);
-
-       s_cap = le16_to_cpu(le_scap);
-       d_cap = le16_to_cpu(le_dcap);
-
-       return ((src->Ssid.SsidLength == dst->Ssid.SsidLength) &&
-               ((!memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN))) &&
-               ((!memcmp(src->Ssid.Ssid, dst->Ssid.Ssid, src->Ssid.SsidLength))) &&
-               ((s_cap & WLAN_CAPABILITY_IBSS) ==
-               (d_cap & WLAN_CAPABILITY_IBSS)) &&
-               ((s_cap & WLAN_CAPABILITY_BSS) ==
-               (d_cap & WLAN_CAPABILITY_BSS)));
-}
-
-struct wlan_network    *rtw_get_oldest_wlan_network(struct __queue *scanned_queue)
-{
-       struct list_head *plist, *phead;
-       struct  wlan_network    *pwlan = NULL;
-       struct  wlan_network    *oldest = NULL;
-
-       phead = get_list_head(scanned_queue);
-
-       plist = phead->next;
-
-       while (1) {
-               if (phead == plist)
-                       break;
-
-               pwlan = container_of(plist, struct wlan_network, list);
-
-               if (!pwlan->fixed) {
-                       if (!oldest || time_after(oldest->last_scanned, pwlan->last_scanned))
-                               oldest = pwlan;
-               }
-
-               plist = plist->next;
-       }
-
-       return oldest;
-}
-
-void update_network(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src,
-       struct adapter *padapter, bool update_ie)
-{
-       long rssi_ori = dst->Rssi;
-       u8 sq_smp = src->PhyInfo.SignalQuality;
-       u8 ss_final;
-       u8 sq_final;
-       long rssi_final;
-
-       AntDivCompare8188E(padapter, dst, src); /* this will update src.Rssi, need consider again */
-
-       /* The rule below is 1/5 for sample value, 4/5 for history value */
-       if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&padapter->mlmepriv.cur_network.network, src)) {
-               /* Take the recvpriv's value for the connected AP*/
-               ss_final = padapter->recvpriv.signal_strength;
-               sq_final = padapter->recvpriv.signal_qual;
-               /* the rssi value here is undecorated, and will be used for antenna diversity */
-               if (sq_smp != 101) /* from the right channel */
-                       rssi_final = dst->Rssi; //(src->Rssi+dst->Rssi*4)/5;
-               else
-                       rssi_final = rssi_ori;
-       } else {
-//             if (sq_smp != 101) { /* from the right channel */
-                       ss_final = (u32)dst->PhyInfo.SignalStrength; //((u32)(src->PhyInfo.SignalStrength)+(u32)(dst->PhyInfo.SignalStrength)*4)/5;
-                       sq_final = (u32)dst->PhyInfo.SignalQuality; //((u32)(src->PhyInfo.SignalQuality)+(u32)(dst->PhyInfo.SignalQuality)*4)/5;
-                       rssi_final = dst->Rssi; //(src->Rssi+dst->Rssi*4)/5;
-//             } else {
-//                     /* bss info not receiving from the right channel, use the original RX signal infos */
-//                     ss_final = dst->PhyInfo.SignalStrength;
-//                     sq_final = dst->PhyInfo.SignalQuality;
-//                     rssi_final = dst->Rssi;
-//             }
-       }
-       if (update_ie) {
-               dst->Reserved[0] = src->Reserved[0];
-               dst->Reserved[1] = src->Reserved[1];
-               memcpy((u8 *)dst, (u8 *)src, get_wlan_bssid_ex_sz(src));
-       }
-       dst->PhyInfo.SignalStrength = ss_final;
-       dst->PhyInfo.SignalQuality = sq_final;
-       dst->Rssi = rssi_final;
-
-}
-
-static void update_current_network(struct adapter *adapter, struct wlan_bssid_ex *pnetwork)
-{
-       struct  mlme_priv       *pmlmepriv = &adapter->mlmepriv;
-
-       if (check_fwstate(pmlmepriv, _FW_LINKED) &&
-           is_same_network(&pmlmepriv->cur_network.network, pnetwork)) {
-               update_network(&pmlmepriv->cur_network.network, pnetwork, adapter, true);
-       }
-
-}
-
-u8 rtw_current_antenna(struct adapter *adapter)
-{
-       struct hal_data_8188e *haldata = &adapter->haldata;
-
-       return haldata->CurAntenna;
-}
-
-/*
-Caller must hold pmlmepriv->lock first.
-*/
-void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *target)
-{
-       struct list_head *plist, *phead;
-       u32     bssid_ex_sz;
-       struct mlme_priv        *pmlmepriv = &adapter->mlmepriv;
-       struct __queue *queue   = &pmlmepriv->scanned_queue;
-       struct wlan_network     *pnetwork = NULL;
-       struct wlan_network     *oldest = NULL;
-
-       spin_lock_bh(&queue->lock);
-       phead = get_list_head(queue);
-       plist = phead->next;
-
-       while (phead != plist) {
-               pnetwork        = container_of(plist, struct wlan_network, list);
-
-               if (is_same_network(&pnetwork->network, target))
-                       break;
-               if ((oldest == ((struct wlan_network *)0)) ||
-                   time_after(oldest->last_scanned, pnetwork->last_scanned))
-                       oldest = pnetwork;
-               plist = plist->next;
-       }
-       /* If we didn't find a match, then get a new network slot to initialize
-        * with this beacon's information */
-       if (phead == plist) {
-               if (list_empty(&pmlmepriv->free_bss_pool.queue)) {
-                       /* If there are no more slots, expire the oldest */
-                       pnetwork = oldest;
-
-                       target->PhyInfo.Optimum_antenna = rtw_current_antenna(adapter);
-
-                       memcpy(&pnetwork->network, target,  get_wlan_bssid_ex_sz(target));
-                       /*  variable initialize */
-                       pnetwork->fixed = false;
-                       pnetwork->last_scanned = jiffies;
-
-                       pnetwork->network_type = 0;
-                       pnetwork->aid = 0;
-                       pnetwork->join_res = 0;
-
-                       /* bss info not receiving from the right channel */
-                       if (pnetwork->network.PhyInfo.SignalQuality == 101)
-                               pnetwork->network.PhyInfo.SignalQuality = 0;
-               } else {
-                       /* Otherwise just pull from the free list */
-
-                       pnetwork = rtw_alloc_network(pmlmepriv); /*  will update scan_time */
-
-                       if (!pnetwork)
-                               goto exit;
-
-                       bssid_ex_sz = get_wlan_bssid_ex_sz(target);
-                       target->Length = bssid_ex_sz;
-                       target->PhyInfo.Optimum_antenna = rtw_current_antenna(adapter);
-                       memcpy(&pnetwork->network, target, bssid_ex_sz);
-
-                       pnetwork->last_scanned = jiffies;
-
-                       /* bss info not receiving from the right channel */
-                       if (pnetwork->network.PhyInfo.SignalQuality == 101)
-                               pnetwork->network.PhyInfo.SignalQuality = 0;
-                       list_add_tail(&pnetwork->list, &queue->queue);
-               }
-       } else {
-               /* we have an entry and we are going to update it. But this entry may
-                * be already expired. In this case we do the same as we found a new
-                * net and call the new_net handler
-                */
-               bool update_ie = true;
-
-               pnetwork->last_scanned = jiffies;
-
-               /* target.Reserved[0]== 1, means that scanned network is a bcn frame. */
-               /* probe resp(3) > beacon(1) > probe req(2) */
-               if ((target->Reserved[0] != 2) &&
-                   (target->Reserved[0] >= pnetwork->network.Reserved[0]))
-                       update_ie = true;
-               else
-                       update_ie = false;
-               update_network(&pnetwork->network, target, adapter, update_ie);
-       }
-
-exit:
-       spin_unlock_bh(&queue->lock);
-
-}
-
-static void rtw_add_network(struct adapter *adapter,
-                           struct wlan_bssid_ex *pnetwork)
-{
-
-       rtw_wlan_bssid_ex_remove_p2p_attr(pnetwork, P2P_ATTR_GROUP_INFO);
-       update_current_network(adapter, pnetwork);
-       rtw_update_scanned_network(adapter, pnetwork);
-
-}
-
-/* select the desired network based on the capability of the (i)bss. */
-/*  check items:       (1) security */
-/*                     (2) network_type */
-/*                     (3) WMM */
-/*                     (4) HT */
-/*                     (5) others */
-static bool rtw_is_desired_network(struct adapter *adapter, struct wlan_network *pnetwork)
-{
-       struct security_priv *psecuritypriv = &adapter->securitypriv;
-       struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
-       u32 desired_encmode;
-       u32 privacy;
-
-       /* u8 wps_ie[512]; */
-       uint wps_ielen;
-
-       int bselected = true;
-
-       desired_encmode = psecuritypriv->ndisencryptstatus;
-       privacy = pnetwork->network.Privacy;
-
-       if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
-               if (rtw_get_wps_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, pnetwork->network.IELength - _FIXED_IE_LENGTH_, NULL, &wps_ielen))
-                       return true;
-               else
-                       return false;
-       }
-       if (adapter->registrypriv.wifi_spec == 1) { /* for  correct flow of 8021X  to do.... */
-               u8 *p = NULL;
-               uint ie_len = 0;
-
-               if ((desired_encmode == Ndis802_11EncryptionDisabled) && (privacy != 0))
-                       bselected = false;
-               if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
-                       p = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_,
-                                      _RSN_IE_2_, &ie_len,
-                                      (pnetwork->network.IELength -
-                                      _BEACON_IE_OFFSET_));
-                       if (p && ie_len > 0)
-                               bselected = true;
-                       else
-                               bselected = false;
-               }
-       }
-
-       if ((desired_encmode != Ndis802_11EncryptionDisabled) && (privacy == 0))
-               bselected = false;
-
-       if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
-               if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
-                       bselected = false;
-       }
-
-       return bselected;
-}
-
-void rtw_survey_event_callback(struct adapter  *adapter, u8 *pbuf)
-{
-       u32 len;
-       struct wlan_bssid_ex *pnetwork;
-       struct  mlme_priv       *pmlmepriv = &adapter->mlmepriv;
-
-       pnetwork = (struct wlan_bssid_ex *)pbuf;
-
-       len = get_wlan_bssid_ex_sz(pnetwork);
-       if (len > (sizeof(struct wlan_bssid_ex)))
-               return;
-       spin_lock_bh(&pmlmepriv->lock);
-
-       /*  update IBSS_network 's timestamp */
-       if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
-               if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, pnetwork->MacAddress, ETH_ALEN)) {
-                       struct wlan_network *ibss_wlan = NULL;
-
-                       memcpy(pmlmepriv->cur_network.network.IEs, pnetwork->IEs, 8);
-                       spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-                       ibss_wlan = rtw_find_network(&pmlmepriv->scanned_queue,  pnetwork->MacAddress);
-                       if (ibss_wlan) {
-                               memcpy(ibss_wlan->network.IEs, pnetwork->IEs, 8);
-                               spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-                               goto exit;
-                       }
-                       spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-               }
-       }
-
-       /*  lock pmlmepriv->lock when you accessing network_q */
-       if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
-               if (pnetwork->Ssid.Ssid[0] == 0)
-                       pnetwork->Ssid.SsidLength = 0;
-               rtw_add_network(adapter, pnetwork);
-       }
-
-exit:
-
-       spin_unlock_bh(&pmlmepriv->lock);
-}
-
-static void rtw_xmit_schedule(struct adapter *padapter)
-{
-       struct xmit_priv *pxmitpriv;
-
-       if (!padapter)
-               return;
-
-       pxmitpriv = &padapter->xmitpriv;
-
-       spin_lock_bh(&pxmitpriv->lock);
-
-       if (rtw_txframes_pending(padapter))
-               tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
-
-       spin_unlock_bh(&pxmitpriv->lock);
-}
-
-void rtw_surveydone_event_callback(struct adapter      *adapter, u8 *pbuf)
-{
-       struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
-
-       spin_lock_bh(&pmlmepriv->lock);
-
-       if (pmlmepriv->wps_probe_req_ie) {
-               pmlmepriv->wps_probe_req_ie_len = 0;
-               kfree(pmlmepriv->wps_probe_req_ie);
-               pmlmepriv->wps_probe_req_ie = NULL;
-       }
-
-       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
-               _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
-
-       spin_unlock_bh(&pmlmepriv->lock);
-
-       del_timer_sync(&pmlmepriv->scan_to_timer);
-
-       spin_lock_bh(&pmlmepriv->lock);
-       rtw_set_signal_stat_timer(&adapter->recvpriv);
-
-       if (pmlmepriv->to_join) {
-               if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
-                       if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
-                               set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
-
-                               if (rtw_select_and_join_from_scanned_queue(pmlmepriv) == _SUCCESS) {
-                                       _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
-                               } else {
-                                       struct wlan_bssid_ex    *pdev_network = &adapter->registrypriv.dev_network;
-                                       u8 *pibss = adapter->registrypriv.dev_network.MacAddress;
-
-                                       _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
-
-                                       memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
-
-                                       rtw_update_registrypriv_dev_network(adapter);
-                                       rtw_generate_random_ibss(pibss);
-
-                                       pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
-
-                                       rtw_createbss_cmd(adapter);
-                                       pmlmepriv->to_join = false;
-                               }
-                       }
-               } else {
-                       int s_ret;
-                       set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
-                       pmlmepriv->to_join = false;
-                       s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
-                       if (s_ret == _SUCCESS) {
-                               _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
-                       } else {
-                               if (rtw_to_roaming(adapter) != 0) {
-                                       if (--pmlmepriv->to_roaming == 0 ||
-                                           rtw_sitesurvey_cmd(adapter, &pmlmepriv->assoc_ssid, 1) != _SUCCESS) {
-                                               rtw_set_roaming(adapter, 0);
-                                               rtw_free_assoc_resources(adapter, 1);
-                                               rtw_indicate_disconnect(adapter);
-                                       } else {
-                                               pmlmepriv->to_join = true;
-                                       }
-                               } else {
-                                       rtw_indicate_disconnect(adapter);
-                               }
-                               _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
-                       }
-               }
-       }
-
-       indicate_wx_scan_complete_event(adapter);
-
-       spin_unlock_bh(&pmlmepriv->lock);
-
-       if (check_fwstate(pmlmepriv, _FW_LINKED))
-               p2p_ps_wk_cmd(adapter, P2P_PS_SCAN_DONE, 0);
-
-       rtw_xmit_schedule(adapter);
-}
-
-static void free_scanqueue(struct      mlme_priv *pmlmepriv)
-{
-       struct __queue *free_queue = &pmlmepriv->free_bss_pool;
-       struct __queue *scan_queue = &pmlmepriv->scanned_queue;
-       struct list_head *plist, *phead, *ptemp;
-
-       spin_lock_bh(&scan_queue->lock);
-       spin_lock_bh(&free_queue->lock);
-
-       phead = get_list_head(scan_queue);
-       plist = phead->next;
-
-       while (plist != phead) {
-               ptemp = plist->next;
-               list_del_init(plist);
-               list_add_tail(plist, &free_queue->queue);
-               plist = ptemp;
-               pmlmepriv->num_of_scanned--;
-       }
-
-       spin_unlock_bh(&free_queue->lock);
-       spin_unlock_bh(&scan_queue->lock);
-}
-
-/*
-*rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock
-*/
-void rtw_free_assoc_resources(struct adapter *adapter, int lock_scanned_queue)
-{
-       struct wlan_network *pwlan = NULL;
-       struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
-       struct  sta_priv *pstapriv = &adapter->stapriv;
-       struct wlan_network *tgt_network = &pmlmepriv->cur_network;
-
-       if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE)) {
-               struct sta_info *psta;
-
-               psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.MacAddress);
-
-               spin_lock_bh(&pstapriv->sta_hash_lock);
-               rtw_free_stainfo(adapter,  psta);
-               spin_unlock_bh(&pstapriv->sta_hash_lock);
-       }
-
-       if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE)) {
-               struct sta_info *psta;
-
-               rtw_free_all_stainfo(adapter);
-
-               psta = rtw_get_bcmc_stainfo(adapter);
-               spin_lock_bh(&pstapriv->sta_hash_lock);
-               rtw_free_stainfo(adapter, psta);
-               spin_unlock_bh(&pstapriv->sta_hash_lock);
-
-               rtw_init_bcmc_stainfo(adapter);
-       }
-
-       if (lock_scanned_queue)
-               spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-
-       pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
-       if (pwlan)
-               pwlan->fixed = false;
-
-       if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) && (adapter->stapriv.asoc_sta_count == 1)))
-               rtw_free_network_nolock(pmlmepriv, pwlan);
-
-       if (lock_scanned_queue)
-               spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-       pmlmepriv->key_mask = 0;
-
-}
-
-static struct rt_pmkid_list backup_pmkid[NUM_PMKID_CACHE];
-
-static void rtw_reset_securitypriv(struct adapter *adapter)
-{
-       u8 backup_index;
-       u8 backup_counter;
-       u32 backup_time;
-
-       if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
-               /* 802.1x */
-               /*  We have to backup the PMK information for WiFi PMK Caching test item. */
-               /*  Backup the btkip_countermeasure information. */
-               /*  When the countermeasure is trigger, the driver have to disconnect with AP for 60 seconds. */
-               memcpy(&backup_pmkid[0], &adapter->securitypriv.PMKIDList[0], sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
-               backup_index = adapter->securitypriv.PMKIDIndex;
-               backup_counter = adapter->securitypriv.btkip_countermeasure;
-               backup_time = adapter->securitypriv.btkip_countermeasure_time;
-               memset((unsigned char *)&adapter->securitypriv, 0, sizeof(struct security_priv));
-
-               /*  Restore the PMK information to securitypriv structure for the following connection. */
-               memcpy(&adapter->securitypriv.PMKIDList[0],
-                           &backup_pmkid[0],
-                           sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
-               adapter->securitypriv.PMKIDIndex = backup_index;
-               adapter->securitypriv.btkip_countermeasure = backup_counter;
-               adapter->securitypriv.btkip_countermeasure_time = backup_time;
-               adapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
-               adapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
-       } else {
-               /* reset values in securitypriv */
-               struct security_priv *psec_priv = &adapter->securitypriv;
-
-               psec_priv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;  /* open system */
-               psec_priv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
-               psec_priv->dot11PrivacyKeyIndex = 0;
-               psec_priv->dot118021XGrpPrivacy = _NO_PRIVACY_;
-               psec_priv->dot118021XGrpKeyid = 1;
-               psec_priv->ndisauthtype = Ndis802_11AuthModeOpen;
-               psec_priv->ndisencryptstatus = Ndis802_11WEPDisabled;
-       }
-}
-
-/*
-*rtw_indicate_connect: the caller has to lock pmlmepriv->lock
-*/
-void rtw_indicate_connect(struct adapter *padapter)
-{
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-
-       pmlmepriv->to_join = false;
-
-       if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
-               set_fwstate(pmlmepriv, _FW_LINKED);
-
-               rtw_led_control(padapter, LED_CTL_LINK);
-
-               rtw_indicate_wx_assoc_event(padapter);
-               netif_carrier_on(padapter->pnetdev);
-               if (padapter->pid[2] != 0)
-                       rtw_signal_process(padapter->pid[2], SIGALRM);
-       }
-
-       pmlmepriv->to_roaming = 0;
-}
-
-/*
-*rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock
-*/
-void rtw_indicate_disconnect(struct adapter *padapter)
-{
-       struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
-       _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING | WIFI_UNDER_WPS);
-
-       if (pmlmepriv->to_roaming > 0)
-               _clr_fwstate_(pmlmepriv, _FW_LINKED);
-
-       if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) ||
-           (pmlmepriv->to_roaming <= 0)) {
-               /*  Do it first for tx broadcast pkt after disconnection issue! */
-               netif_carrier_off(padapter->pnetdev);
-
-               rtw_indicate_wx_disassoc_event(padapter);
-               rtw_reset_securitypriv(padapter);
-
-               _clr_fwstate_(pmlmepriv, _FW_LINKED);
-               rtw_led_control(padapter, LED_CTL_NO_LINK);
-       }
-       p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1);
-
-       rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 1);
-
-}
-
-inline void rtw_indicate_scan_done(struct adapter *padapter)
-{
-       indicate_wx_scan_complete_event(padapter);
-}
-
-static struct sta_info *rtw_joinbss_update_stainfo(struct adapter *padapter, struct wlan_network *pnetwork)
-{
-       int i;
-       struct sta_info *bmc_sta, *psta = NULL;
-       struct recv_reorder_ctrl *preorder_ctrl;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-
-       psta = rtw_get_stainfo(pstapriv, pnetwork->network.MacAddress);
-       if (!psta)
-               psta = rtw_alloc_stainfo(pstapriv, pnetwork->network.MacAddress);
-
-       if (psta) { /* update ptarget_sta */
-               psta->aid  = pnetwork->join_res;
-               psta->mac_id = 0;
-               /* sta mode */
-               rtl8188e_SetHalODMVar(padapter, psta, true);
-               /* security related */
-               if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
-                       padapter->securitypriv.binstallGrpkey = false;
-                       padapter->securitypriv.busetkipkey = false;
-                       padapter->securitypriv.bgrpkey_handshake = false;
-                       psta->ieee8021x_blocked = true;
-                       psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
-                       memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof(union Keytype));
-                       memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof(union Keytype));
-                       memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof(union Keytype));
-                       memset((u8 *)&psta->dot11txpn, 0, sizeof(union pn48));
-                       memset((u8 *)&psta->dot11rxpn, 0, sizeof(union pn48));
-               }
-               /*      When doing the WPS, the wps_ie_len won't equal to 0 */
-               /*      And the Wi-Fi driver shouldn't allow the data packet to be transmitted. */
-               if (padapter->securitypriv.wps_ie_len != 0) {
-                       psta->ieee8021x_blocked = true;
-                       padapter->securitypriv.wps_ie_len = 0;
-               }
-               /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info */
-               /* if A-MPDU Rx is enabled, resetting  rx_ordering_ctrl wstart_b(indicate_seq) to default value = 0xffff */
-               /* todo: check if AP can send A-MPDU packets */
-               for (i = 0; i < 16; i++) {
-                       /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
-                       preorder_ctrl = &psta->recvreorder_ctrl[i];
-                       preorder_ctrl->enable = false;
-                       preorder_ctrl->indicate_seq = 0xffff;
-                       preorder_ctrl->wend_b = 0xffff;
-                       preorder_ctrl->wsize_b = 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
-               }
-               bmc_sta = rtw_get_bcmc_stainfo(padapter);
-               if (bmc_sta) {
-                       for (i = 0; i < 16; i++) {
-                               /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
-                               preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
-                               preorder_ctrl->enable = false;
-                               preorder_ctrl->indicate_seq = 0xffff;
-                               preorder_ctrl->wend_b = 0xffff;
-                               preorder_ctrl->wsize_b = 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
-                       }
-               }
-               /* misc. */
-               update_sta_info(padapter, psta);
-       }
-       return psta;
-}
-
-/* pnetwork: returns from rtw_joinbss_event_callback */
-/* ptarget_wlan: found from scanned_queue */
-static void rtw_joinbss_update_network(struct adapter *padapter, struct wlan_network *ptarget_wlan, struct wlan_network  *pnetwork)
-{
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-       struct wlan_network  *cur_network = &pmlmepriv->cur_network;
-
-       /*  why not use ptarget_wlan?? */
-       memcpy(&cur_network->network, &pnetwork->network, pnetwork->network.Length);
-       /*  some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs */
-       cur_network->network.IELength = ptarget_wlan->network.IELength;
-       memcpy(&cur_network->network.IEs[0], &ptarget_wlan->network.IEs[0], MAX_IE_SZ);
-
-       cur_network->aid = pnetwork->join_res;
-
-       rtw_set_signal_stat_timer(&padapter->recvpriv);
-       padapter->recvpriv.signal_strength = ptarget_wlan->network.PhyInfo.SignalStrength;
-       padapter->recvpriv.signal_qual = ptarget_wlan->network.PhyInfo.SignalQuality;
-       /* the ptarget_wlan->network.Rssi is raw data, we use ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled) */
-       padapter->recvpriv.rssi = translate_percentage_to_dbm(ptarget_wlan->network.PhyInfo.SignalStrength);
-       rtw_set_signal_stat_timer(&padapter->recvpriv);
-
-       /* update fw_state will clr _FW_UNDER_LINKING here indirectly */
-       switch (pnetwork->network.InfrastructureMode) {
-       case Ndis802_11Infrastructure:
-               if (pmlmepriv->fw_state & WIFI_UNDER_WPS)
-                       pmlmepriv->fw_state = WIFI_STATION_STATE | WIFI_UNDER_WPS;
-               else
-                       pmlmepriv->fw_state = WIFI_STATION_STATE;
-               break;
-       case Ndis802_11IBSS:
-               pmlmepriv->fw_state = WIFI_ADHOC_STATE;
-               break;
-       default:
-               pmlmepriv->fw_state = WIFI_NULL_STATE;
-               break;
-       }
-
-       rtw_update_ht_cap(padapter, cur_network->network.IEs, cur_network->network.IELength);
-}
-
-/* Notes: the function could be > passive_level (the same context as Rx tasklet) */
-/* pnetwork: returns from rtw_joinbss_event_callback */
-/* ptarget_wlan: found from scanned_queue */
-/* if join_res > 0, for (fw_state == WIFI_STATION_STATE), we check if  "ptarget_sta" & "ptarget_wlan" exist. */
-/* if join_res > 0, for (fw_state == WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist. */
-/* if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan != NULL). */
-
-void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf)
-{
-       struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL;
-       struct  sta_priv *pstapriv = &adapter->stapriv;
-       struct  mlme_priv       *pmlmepriv = &adapter->mlmepriv;
-       struct wlan_network     *pnetwork       = (struct wlan_network *)pbuf;
-       struct wlan_network     *cur_network = &pmlmepriv->cur_network;
-       struct wlan_network     *pcur_wlan = NULL, *ptarget_wlan = NULL;
-       unsigned int            the_same_macaddr = false;
-
-       the_same_macaddr = !memcmp(pnetwork->network.MacAddress, cur_network->network.MacAddress, ETH_ALEN);
-
-       pnetwork->network.Length = get_wlan_bssid_ex_sz(&pnetwork->network);
-       if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex))
-               return;
-
-       spin_lock_bh(&pmlmepriv->lock);
-
-       if (pnetwork->join_res > 0) {
-               spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-               if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
-                       /* s1. find ptarget_wlan */
-                       if (check_fwstate(pmlmepriv, _FW_LINKED)) {
-                               if (the_same_macaddr) {
-                                       ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
-                               } else {
-                                       pcur_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
-                                       if (pcur_wlan)
-                                               pcur_wlan->fixed = false;
-
-                                       pcur_sta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
-                                       if (pcur_sta) {
-                                               spin_lock_bh(&pstapriv->sta_hash_lock);
-                                               rtw_free_stainfo(adapter,  pcur_sta);
-                                               spin_unlock_bh(&pstapriv->sta_hash_lock);
-                                       }
-
-                                       ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
-                                       if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
-                                               if (ptarget_wlan)
-                                                       ptarget_wlan->fixed = true;
-                                       }
-                               }
-                       } else {
-                               ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
-                               if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
-                                       if (ptarget_wlan)
-                                               ptarget_wlan->fixed = true;
-                               }
-                       }
-
-                       /* s2. update cur_network */
-                       if (ptarget_wlan) {
-                               rtw_joinbss_update_network(adapter, ptarget_wlan, pnetwork);
-                       } else {
-                               spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-                               goto ignore_joinbss_callback;
-                       }
-
-                       /* s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode */
-                       if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
-                               ptarget_sta = rtw_joinbss_update_stainfo(adapter, pnetwork);
-                               if (!ptarget_sta) {
-                                       spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-                                       goto ignore_joinbss_callback;
-                               }
-                       }
-
-                       /* s4. indicate connect */
-                       if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
-                               pmlmepriv->cur_network_scanned = ptarget_wlan;
-                               rtw_indicate_connect(adapter);
-                       }
-
-                       spin_unlock_bh(&pmlmepriv->lock);
-                       /* s5. Cancel assoc_timer */
-                       del_timer_sync(&pmlmepriv->assoc_timer);
-                       spin_lock_bh(&pmlmepriv->lock);
-               } else {
-                       spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-                       goto ignore_joinbss_callback;
-               }
-
-               spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
-       } else if (pnetwork->join_res == -4) {
-               rtw_reset_securitypriv(adapter);
-               _set_timer(&pmlmepriv->assoc_timer, 1);
-
-               if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
-                       _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
-       } else { /* if join_res < 0 (join fails), then try again */
-               _set_timer(&pmlmepriv->assoc_timer, 1);
-               _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
-       }
-
-ignore_joinbss_callback:
-       spin_unlock_bh(&pmlmepriv->lock);
-}
-
-void rtw_joinbss_event_callback(struct adapter *adapter, u8 *pbuf)
-{
-       struct wlan_network     *pnetwork       = (struct wlan_network *)pbuf;
-
-       mlmeext_joinbss_event_callback(adapter, pnetwork->join_res);
-
-       rtw_xmit_schedule(adapter);
-}
-
-void rtw_set_max_rpt_macid(struct adapter *adapter, u8 macid)
-{
-       rtw_write8(adapter, REG_TX_RPT_CTRL + 1, macid + 1);
-}
-
-static u8 search_max_mac_id(struct adapter *padapter)
-{
-       u8 mac_id;
-       u8 aid;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
-               for (aid = (pstapriv->max_num_sta); aid > 0; aid--) {
-                       if (pstapriv->sta_aid[aid - 1])
-                               break;
-               }
-               mac_id = aid + 1;
-       } else {
-               /* adhoc  id =  31~2 */
-               for (mac_id = (NUM_STA - 1); mac_id >= IBSS_START_MAC_ID; mac_id--) {
-                       if (pmlmeinfo->FW_sta_info[mac_id].status == 1)
-                               break;
-               }
-       }
-       return mac_id;
-}
-
-/* FOR AP , AD-HOC mode */
-void rtw_sta_media_status_rpt(struct adapter *adapter, struct sta_info *psta,
-                             u32 mstatus)
-{
-       u16 media_status_rpt;
-       u8 macid;
-
-       if (!psta)
-               return;
-
-       macid = search_max_mac_id(adapter);
-       rtw_set_max_rpt_macid(adapter, macid);
-
-       /* MACID|OPMODE:1 connect */
-       media_status_rpt = (u16)((psta->mac_id << 8) | mstatus);
-       rtl8188e_set_FwMediaStatus_cmd(adapter, media_status_rpt);
-}
-
-void rtw_stassoc_event_callback(struct adapter *adapter, u8 *pbuf)
-{
-       struct sta_info *psta;
-       struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
-       struct stassoc_event    *pstassoc = (struct stassoc_event *)pbuf;
-       struct wlan_network     *cur_network = &pmlmepriv->cur_network;
-       struct wlan_network     *ptarget_wlan = NULL;
-
-       if (!rtw_access_ctrl(adapter, pstassoc->macaddr))
-               return;
-
-       if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
-               psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
-               if (psta)
-                       rtw_indicate_sta_assoc_event(adapter, psta);
-               return;
-       }
-       /* for AD-HOC mode */
-       psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
-       if (psta)
-               /* the sta have been in sta_info_queue => do nothing */
-               return; /* between drv has received this event before and  fw have not yet to set key to CAM_ENTRY) */
-       psta = rtw_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr);
-       if (!psta)
-               return;
-       /* to do: init sta_info variable */
-       psta->qos_option = 0;
-       psta->mac_id = (uint)pstassoc->cam_id;
-
-       /* for ad-hoc mode */
-       rtl8188e_SetHalODMVar(adapter, psta, true);
-       rtw_sta_media_status_rpt(adapter, psta, 1);
-       if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
-               psta->dot118021XPrivacy = adapter->securitypriv.dot11PrivacyAlgrthm;
-       psta->ieee8021x_blocked = false;
-       spin_lock_bh(&pmlmepriv->lock);
-       if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) ||
-           (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))) {
-               if (adapter->stapriv.asoc_sta_count == 2) {
-                       spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-                       ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
-                       pmlmepriv->cur_network_scanned = ptarget_wlan;
-                       if (ptarget_wlan)
-                               ptarget_wlan->fixed = true;
-                       spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-                       /*  a sta + bc/mc_stainfo (not Ibss_stainfo) */
-                       rtw_indicate_connect(adapter);
-               }
-       }
-       spin_unlock_bh(&pmlmepriv->lock);
-       mlmeext_sta_add_event_callback(adapter, psta);
-}
-
-void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf)
-{
-       int mac_id = -1;
-       struct sta_info *psta;
-       struct wlan_network *pwlan = NULL;
-       struct wlan_bssid_ex *pdev_network = NULL;
-       u8 *pibss = NULL;
-       struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
-       struct  stadel_event *pstadel = (struct stadel_event *)pbuf;
-       struct  sta_priv *pstapriv = &adapter->stapriv;
-       struct wlan_network *tgt_network = &pmlmepriv->cur_network;
-
-       psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr);
-       if (psta)
-               mac_id = psta->mac_id;
-       else
-               mac_id = pstadel->mac_id;
-
-       if (mac_id >= 0) {
-               u16 media_status;
-               media_status = (mac_id << 8) | 0; /*   MACID|OPMODE:0 means disconnect */
-               /* for STA, AP, ADHOC mode, report disconnect stauts to FW */
-               rtl8188e_set_FwMediaStatus_cmd(adapter, media_status);
-       }
-
-       if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
-               return;
-
-       mlmeext_sta_del_event_callback(adapter);
-
-       spin_lock_bh(&pmlmepriv->lock);
-
-       if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
-               if (adapter->registrypriv.wifi_spec == 1)
-                       rtw_set_roaming(adapter, 0); /* don't roam */
-               else if (rtw_to_roaming(adapter) > 0)
-                       pmlmepriv->to_roaming--; /* this stadel_event is caused by roaming, decrease to_roaming */
-               else if (rtw_to_roaming(adapter) == 0)
-                       rtw_set_roaming(adapter,
-                                       adapter->registrypriv.max_roaming_times);
-
-               if (*((unsigned short *)(pstadel->rsvd)) != WLAN_REASON_EXPIRATION_CHK)
-                       rtw_set_roaming(adapter, 0); /* don't roam */
-
-               rtw_free_uc_swdec_pending_queue(adapter);
-
-               rtw_free_assoc_resources(adapter, 1);
-               rtw_indicate_disconnect(adapter);
-               spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-               /*  remove the network entry in scanned_queue */
-               pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
-               if (pwlan) {
-                       pwlan->fixed = false;
-                       rtw_free_network_nolock(pmlmepriv, pwlan);
-               }
-               spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-               _rtw_roaming(adapter, tgt_network);
-       }
-       if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
-           check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
-               spin_lock_bh(&pstapriv->sta_hash_lock);
-               rtw_free_stainfo(adapter,  psta);
-               spin_unlock_bh(&pstapriv->sta_hash_lock);
-
-               if (adapter->stapriv.asoc_sta_count == 1) { /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
-                       spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-                       /* free old ibss network */
-                       pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
-                       if (pwlan) {
-                               pwlan->fixed = false;
-                               rtw_free_network_nolock(pmlmepriv, pwlan);
-                       }
-                       spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-                       /* re-create ibss */
-                       pdev_network = &adapter->registrypriv.dev_network;
-                       pibss = adapter->registrypriv.dev_network.MacAddress;
-
-                       memcpy(pdev_network, &tgt_network->network, get_wlan_bssid_ex_sz(&tgt_network->network));
-
-                       memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
-
-                       rtw_update_registrypriv_dev_network(adapter);
-
-                       rtw_generate_random_ibss(pibss);
-
-                       if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
-                               set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
-                               _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE);
-                       }
-
-                       rtw_createbss_cmd(adapter);
-               }
-       }
-       spin_unlock_bh(&pmlmepriv->lock);
-
-}
-
-/*
-* _rtw_join_timeout_handler - Timeout/failure handler for CMD JoinBss
-* @adapter: pointer to struct adapter structure
-*/
-void _rtw_join_timeout_handler (struct adapter *adapter)
-{
-       struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
-       int do_join_r;
-
-       if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
-               return;
-
-       spin_lock_irq(&pmlmepriv->lock);
-
-       if (rtw_to_roaming(adapter) > 0) { /* join timeout caused by roaming */
-               while (1) {
-                       pmlmepriv->to_roaming--;
-                       if (rtw_to_roaming(adapter) != 0) { /* try another */
-                               do_join_r = rtw_do_join(adapter);
-                               if (do_join_r != _SUCCESS)
-                                       continue;
-                               break;
-                       } else {
-                               rtw_indicate_disconnect(adapter);
-                               break;
-                       }
-               }
-       } else {
-               rtw_indicate_disconnect(adapter);
-               free_scanqueue(pmlmepriv);/*  */
-       }
-       spin_unlock_irq(&pmlmepriv->lock);
-
-}
-
-/*
-* rtw_scan_timeout_handler - Timeout/Failure handler for CMD SiteSurvey
-* @adapter: pointer to struct adapter structure
-*/
-void rtw_scan_timeout_handler (struct adapter *adapter)
-{
-       struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
-
-       spin_lock_bh(&pmlmepriv->lock);
-       _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
-       spin_unlock_bh(&pmlmepriv->lock);
-       rtw_indicate_scan_done(adapter);
-}
-
-static void rtw_auto_scan_handler(struct adapter *padapter)
-{
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
-       /* auto site survey per 60sec */
-       if (pmlmepriv->scan_interval > 0) {
-               pmlmepriv->scan_interval--;
-               if (pmlmepriv->scan_interval == 0) {
-                       rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
-                       pmlmepriv->scan_interval = SCAN_INTERVAL;/*  30*2 sec = 60sec */
-               }
-       }
-}
-
-void rtw_dynamic_check_timer_handlder(struct adapter *adapter)
-{
-       struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
-       struct registry_priv *pregistrypriv = &adapter->registrypriv;
-
-       if (!adapter)
-               return;
-       if (!adapter->hw_init_completed)
-               return;
-       if ((adapter->bDriverStopped) || (adapter->bSurpriseRemoved))
-               return;
-       if (adapter->net_closed)
-               return;
-       rtw_dynamic_chk_wk_cmd(adapter);
-
-       if (pregistrypriv->wifi_spec == 1) {
-               struct wifidirect_info *pwdinfo = &adapter->wdinfo;
-               if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
-                       /* auto site survey */
-                       rtw_auto_scan_handler(adapter);
-               }
-       }
-
-       rcu_read_lock();
-
-       if (rcu_dereference(adapter->pnetdev->rx_handler_data) &&
-           check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE)) {
-               /*  expire NAT2.5 entry */
-               nat25_db_expire(adapter);
-
-               if (adapter->pppoe_connection_in_progress > 0)
-                       adapter->pppoe_connection_in_progress--;
-
-               /*  due to rtw_dynamic_check_timer_handlder() is called every 2 seconds */
-               if (adapter->pppoe_connection_in_progress > 0)
-                       adapter->pppoe_connection_in_progress--;
-       }
-
-       rcu_read_unlock();
-}
-
-#define RTW_SCAN_RESULT_EXPIRE 2000
-
-/*
-* Select a new join candidate from the original @param candidate and @param competitor
-* @return true: candidate is updated
-* @return false: candidate is not updated
-*/
-static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv
-       , struct wlan_network **candidate, struct wlan_network *competitor)
-{
-       int updated = false;
-       struct adapter *adapter = container_of(pmlmepriv, struct adapter, mlmepriv);
-       unsigned long scan_res_expire;
-
-       /* check bssid, if needed */
-       if (pmlmepriv->assoc_by_bssid) {
-               if (memcmp(competitor->network.MacAddress, pmlmepriv->assoc_bssid, ETH_ALEN))
-                       goto exit;
-       }
-
-       /* check ssid, if needed */
-       if (pmlmepriv->assoc_ssid.SsidLength) {
-               if (competitor->network.Ssid.SsidLength != pmlmepriv->assoc_ssid.SsidLength ||
-                   memcmp(competitor->network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength))
-                       goto exit;
-       }
-
-       if (!rtw_is_desired_network(adapter, competitor))
-               goto exit;
-
-       scan_res_expire = competitor->last_scanned + msecs_to_jiffies(RTW_SCAN_RESULT_EXPIRE);
-       if (rtw_to_roaming(adapter) > 0) {
-               if (time_after(jiffies, scan_res_expire) ||
-                   !is_same_ess(&competitor->network, &pmlmepriv->cur_network.network))
-                       goto exit;
-       }
-
-       if (!*candidate || (*candidate)->network.Rssi < competitor->network.Rssi) {
-               *candidate = competitor;
-               updated = true;
-       }
-
-exit:
-       return updated;
-}
-
-/*
-Calling context:
-The caller of the sub-routine will be in critical section...
-The caller must hold the following spinlock
-pmlmepriv->lock
-*/
-
-int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv)
-{
-       int ret;
-       struct list_head *phead;
-       struct adapter *adapter;
-       struct __queue *queue   = &pmlmepriv->scanned_queue;
-       struct  wlan_network    *pnetwork = NULL;
-       struct  wlan_network    *candidate = NULL;
-
-       spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-       phead = get_list_head(queue);
-       adapter = (struct adapter *)pmlmepriv->nic_hdl;
-       pmlmepriv->pscanned = phead->next;
-       while (phead != pmlmepriv->pscanned) {
-               pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
-               pmlmepriv->pscanned = pmlmepriv->pscanned->next;
-               rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork);
-       }
-       if (!candidate) {
-               ret = _FAIL;
-               goto exit;
-       }
-
-       /*  check for situation of  _FW_LINKED */
-       if (check_fwstate(pmlmepriv, _FW_LINKED)) {
-               rtw_disassoc_cmd(adapter, 0, true);
-               rtw_indicate_disconnect(adapter);
-               rtw_free_assoc_resources(adapter, 0);
-       }
-
-       ret = rtw_joinbss_cmd(adapter, candidate);
-
-exit:
-       spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
-       return ret;
-}
-
-int rtw_set_auth(struct adapter *adapter, struct security_priv *psecuritypriv)
-{
-       struct  cmd_obj *pcmd;
-       struct  setauth_parm *psetauthparm;
-       struct  cmd_priv *pcmdpriv = &adapter->cmdpriv;
-       int             res = _SUCCESS;
-
-       pcmd = kzalloc(sizeof(*pcmd), GFP_KERNEL);
-       if (!pcmd) {
-               res = _FAIL;  /* try again */
-               goto exit;
-       }
-
-       psetauthparm = kzalloc(sizeof(*psetauthparm), GFP_KERNEL);
-       if (!psetauthparm) {
-               kfree(pcmd);
-               res = _FAIL;
-               goto exit;
-       }
-       psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm;
-       pcmd->cmdcode = _SetAuth_CMD_;
-       pcmd->parmbuf = (unsigned char *)psetauthparm;
-       pcmd->cmdsz =  (sizeof(struct setauth_parm));
-       pcmd->rsp = NULL;
-       pcmd->rspsz = 0;
-       INIT_LIST_HEAD(&pcmd->list);
-       res = rtw_enqueue_cmd(pcmdpriv, pcmd);
-exit:
-
-       return res;
-}
-
-int rtw_set_key(struct adapter *adapter, struct security_priv *psecuritypriv, int keyid, u8 set_tx)
-{
-       u8      keylen;
-       struct cmd_obj          *pcmd;
-       struct setkey_parm      *psetkeyparm;
-       struct cmd_priv         *pcmdpriv = &adapter->cmdpriv;
-       struct mlme_priv                *pmlmepriv = &adapter->mlmepriv;
-       int     res = _SUCCESS;
-
-       pcmd = kzalloc(sizeof(*pcmd), GFP_KERNEL);
-       if (!pcmd) {
-               res = _FAIL;  /* try again */
-               goto exit;
-       }
-       psetkeyparm = kzalloc(sizeof(*psetkeyparm), GFP_KERNEL);
-       if (!psetkeyparm) {
-               kfree(pcmd);
-               res = _FAIL;
-               goto exit;
-       }
-
-       if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
-               psetkeyparm->algorithm = (unsigned char)psecuritypriv->dot118021XGrpPrivacy;
-       else
-               psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm;
-       psetkeyparm->keyid = (u8)keyid;/* 0~3 */
-       psetkeyparm->set_tx = set_tx;
-       pmlmepriv->key_mask |= BIT(psetkeyparm->keyid);
-
-       switch (psetkeyparm->algorithm) {
-       case _WEP40_:
-               keylen = 5;
-               memcpy(&psetkeyparm->key[0], &psecuritypriv->dot11DefKey[keyid].skey[0], keylen);
-               break;
-       case _WEP104_:
-               keylen = 13;
-               memcpy(&psetkeyparm->key[0], &psecuritypriv->dot11DefKey[keyid].skey[0], keylen);
-               break;
-       case _TKIP_:
-               keylen = 16;
-               memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
-               psetkeyparm->grpkey = 1;
-               break;
-       case _AES_:
-               keylen = 16;
-               memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
-               psetkeyparm->grpkey = 1;
-               break;
-       default:
-               kfree(psetkeyparm);
-               kfree(pcmd);
-               res = _FAIL;
-               goto exit;
-       }
-       pcmd->cmdcode = _SetKey_CMD_;
-       pcmd->parmbuf = (u8 *)psetkeyparm;
-       pcmd->cmdsz =  (sizeof(struct setkey_parm));
-       pcmd->rsp = NULL;
-       pcmd->rspsz = 0;
-       INIT_LIST_HEAD(&pcmd->list);
-       res = rtw_enqueue_cmd(pcmdpriv, pcmd);
-exit:
-       return res;
-}
-
-/* adjust IEs for rtw_joinbss_cmd in WMM */
-int rtw_restruct_wmm_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len)
-{
-       unsigned        int ielength = 0;
-       unsigned int i, j;
-
-       i = 12; /* after the fixed IE */
-       while (i < in_len) {
-               ielength = initial_out_len;
-
-               if (in_ie[i] == 0xDD && in_ie[i + 2] == 0x00 && in_ie[i + 3] == 0x50  && in_ie[i + 4] == 0xF2 && in_ie[i + 5] == 0x02 && i + 5 < in_len) {
-                       /* WMM element ID and OUI */
-                       /* Append WMM IE to the last index of out_ie */
-
-                       for (j = i; j < i + 9; j++) {
-                               out_ie[ielength] = in_ie[j];
-                               ielength++;
-                       }
-                       out_ie[initial_out_len + 1] = 0x07;
-                       out_ie[initial_out_len + 6] = 0x00;
-                       out_ie[initial_out_len + 8] = 0x00;
-                       break;
-               }
-               i += (in_ie[i + 1] + 2); /*  to the next IE element */
-       }
-       return ielength;
-}
-
-/*  */
-/*  Search by BSSID, */
-/*  Return Value: */
-/*             -1              :if there is no pre-auth key in the  table */
-/*             >= 0            :if there is pre-auth key, and   return the entry id */
-/*  */
-/*  */
-
-static int SecIsInPMKIDList(struct adapter *Adapter, u8 *bssid)
-{
-       struct security_priv *p = &Adapter->securitypriv;
-       int i;
-
-       for (i = 0; i < NUM_PMKID_CACHE; i++)
-               if (p->PMKIDList[i].bUsed && !memcmp(p->PMKIDList[i].Bssid, bssid, ETH_ALEN))
-                       return i;
-       return -1;
-}
-
-/*  */
-/*  Check the RSN IE length */
-/*  If the RSN IE length <= 20, the RSN IE didn't include the PMKID information */
-/*  0-11th element in the array are the fixed IE */
-/*  12th element in the array is the IE */
-/*  13th element in the array is the IE length */
-/*  */
-
-static int rtw_append_pmkid(struct adapter *Adapter, int iEntry, u8 *ie, uint ie_len)
-{
-       struct security_priv *psecuritypriv = &Adapter->securitypriv;
-
-       if (ie[13] <= 20) {
-               /*  The RSN IE didn't include the PMK ID, append the PMK information */
-               ie[ie_len] = 1;
-               ie_len++;
-               ie[ie_len] = 0; /* PMKID count = 0x0100 */
-               ie_len++;
-               memcpy(&ie[ie_len], &psecuritypriv->PMKIDList[iEntry].PMKID, 16);
-
-               ie_len += 16;
-               ie[13] += 18;/* PMKID length = 2+16 */
-       }
-       return ie_len;
-}
-
-static void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie)
-{
-       uint len;
-       u8 *buff, *p, i;
-       union iwreq_data wrqu;
-
-       buff = NULL;
-       if (authmode == _WPA_IE_ID_) {
-               buff = kzalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
-               if (!buff)
-                       return;
-               p = buff;
-               p += sprintf(p, "ASSOCINFO(ReqIEs =");
-               len = sec_ie[1] + 2;
-               len =  (len < IW_CUSTOM_MAX) ? len : IW_CUSTOM_MAX;
-               for (i = 0; i < len; i++)
-                       p += sprintf(p, "%02x", sec_ie[i]);
-               p += sprintf(p, ")");
-               memset(&wrqu, 0, sizeof(wrqu));
-               wrqu.data.length = p - buff;
-               wrqu.data.length = (wrqu.data.length < IW_CUSTOM_MAX) ?
-                                  wrqu.data.length : IW_CUSTOM_MAX;
-               wireless_send_event(adapter->pnetdev, IWEVCUSTOM, &wrqu, buff);
-               kfree(buff);
-       }
-}
-
-int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len)
-{
-       u8 authmode = 0;
-       uint    ielength;
-       int iEntry;
-       struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
-       struct security_priv *psecuritypriv = &adapter->securitypriv;
-       uint    ndisauthmode = psecuritypriv->ndisauthtype;
-
-       /* copy fixed ie only */
-       memcpy(out_ie, in_ie, 12);
-       ielength = 12;
-       if ((ndisauthmode == Ndis802_11AuthModeWPA) ||
-           (ndisauthmode == Ndis802_11AuthModeWPAPSK))
-                       authmode = _WPA_IE_ID_;
-       if ((ndisauthmode == Ndis802_11AuthModeWPA2) ||
-           (ndisauthmode == Ndis802_11AuthModeWPA2PSK))
-               authmode = _WPA2_IE_ID_;
-
-       if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
-               memcpy(out_ie + ielength, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len);
-
-               ielength += psecuritypriv->wps_ie_len;
-       } else if ((authmode == _WPA_IE_ID_) || (authmode == _WPA2_IE_ID_)) {
-               /* copy RSN or SSN */
-               memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0], psecuritypriv->supplicant_ie[1] + 2);
-               ielength += psecuritypriv->supplicant_ie[1] + 2;
-               rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie);
-       }
-
-       iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
-       if (iEntry < 0) {
-               return ielength;
-       } else {
-               if (authmode == _WPA2_IE_ID_)
-                       ielength = rtw_append_pmkid(adapter, iEntry, out_ie, ielength);
-       }
-
-       return ielength;
-}
-
-void rtw_init_registrypriv_dev_network(struct adapter *adapter)
-{
-       struct registry_priv *pregistrypriv = &adapter->registrypriv;
-       struct eeprom_priv *peepriv = &adapter->eeprompriv;
-       struct wlan_bssid_ex    *pdev_network = &pregistrypriv->dev_network;
-       u8 *myhwaddr = myid(peepriv);
-
-       memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN);
-
-       memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, sizeof(struct ndis_802_11_ssid));
-
-       pdev_network->Configuration.Length = sizeof(struct ndis_802_11_config);
-       pdev_network->Configuration.BeaconPeriod = 100;
-       pdev_network->Configuration.FHConfig.Length = 0;
-       pdev_network->Configuration.FHConfig.HopPattern = 0;
-       pdev_network->Configuration.FHConfig.HopSet = 0;
-       pdev_network->Configuration.FHConfig.DwellTime = 0;
-
-}
-
-void rtw_update_registrypriv_dev_network(struct adapter *adapter)
-{
-       int sz = 0;
-       struct registry_priv *pregistrypriv = &adapter->registrypriv;
-       struct wlan_bssid_ex    *pdev_network = &pregistrypriv->dev_network;
-       struct  security_priv *psecuritypriv = &adapter->securitypriv;
-       struct  wlan_network    *cur_network = &adapter->mlmepriv.cur_network;
-
-       pdev_network->Privacy = (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0); /*  adhoc no 802.1x */
-
-       pdev_network->Rssi = 0;
-
-       pdev_network->Configuration.DSConfig = (pregistrypriv->channel);
-
-       if (cur_network->network.InfrastructureMode == Ndis802_11IBSS)
-               pdev_network->Configuration.ATIMWindow = (0);
-
-       pdev_network->InfrastructureMode = (cur_network->network.InfrastructureMode);
-
-       /*  1. Supported rates */
-       /*  2. IE */
-
-       sz = rtw_generate_ie(pregistrypriv);
-       pdev_network->IELength = sz;
-       pdev_network->Length = get_wlan_bssid_ex_sz((struct wlan_bssid_ex  *)pdev_network);
-
-       /* notes: translate IELength & Length after assign the Length to cmdsz in createbss_cmd(); */
-       /* pdev_network->IELength = cpu_to_le32(sz); */
-
-}
-
-static void rtw_set_threshold(struct adapter *adapter)
-{
-       struct mlme_priv *mlmepriv = &adapter->mlmepriv;
-       struct ht_priv *htpriv = &mlmepriv->htpriv;
-
-       if (htpriv->ht_option && adapter->registrypriv.wifi_spec != 1) {
-               /* validate usb rx aggregation, use init value. */
-               rtw_write8(adapter, REG_RXDMA_AGG_PG_TH, USB_RXAGG_PAGE_COUNT);
-       } else {
-               /* invalidate usb rx aggregation */
-               rtw_write8(adapter, REG_RXDMA_AGG_PG_TH, 1);
-       }
-}
-
-/* the function is at passive_level */
-void rtw_joinbss_reset(struct adapter *padapter)
-{
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-       struct ht_priv          *phtpriv = &pmlmepriv->htpriv;
-
-       /* todo: if you want to do something io/reg/hw setting before join_bss, please add code here */
-       pmlmepriv->num_FortyMHzIntolerant = 0;
-
-       pmlmepriv->num_sta_no_ht = 0;
-
-       phtpriv->ampdu_enable = false;/* reset to disabled */
-
-       rtw_set_threshold(padapter);
-}
-
-/* the function is >= passive_level */
-unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len)
-{
-       u32 ielen, out_len;
-       unsigned char *p;
-       struct ieee80211_ht_cap ht_capie;
-       unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-       struct qos_priv         *pqospriv = &pmlmepriv->qospriv;
-       struct ht_priv          *phtpriv = &pmlmepriv->htpriv;
-
-       phtpriv->ht_option = false;
-
-       p = rtw_get_ie(in_ie + 12, _HT_CAPABILITY_IE_, &ielen, in_len - 12);
-
-       if (p && ielen > 0) {
-               if (pqospriv->qos_option == 0) {
-                       out_len = *pout_len;
-                       rtw_set_ie(out_ie + out_len, _VENDOR_SPECIFIC_IE_,
-                                  _WMM_IE_Length_, WMM_IE, pout_len);
-
-                       pqospriv->qos_option = 1;
-               }
-
-               out_len = *pout_len;
-
-               memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap));
-
-               ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
-                                               IEEE80211_HT_CAP_SGI_20 |
-                                               IEEE80211_HT_CAP_SGI_40 |
-                                               IEEE80211_HT_CAP_TX_STBC |
-                                               IEEE80211_HT_CAP_DSSSCCK40);
-
-               /*
-               AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
-               AMPDU_para [4:2]:Min MPDU Start Spacing
-               */
-
-               ht_capie.ampdu_params_info = (MAX_AMPDU_FACTOR_64K & 0x03);
-
-               if (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
-                       ht_capie.ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_DENSITY & (0x07 << 2));
-               else
-                       ht_capie.ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00);
-
-               rtw_set_ie(out_ie + out_len, _HT_CAPABILITY_IE_,
-                          sizeof(struct ieee80211_ht_cap), (unsigned char *)&ht_capie, pout_len);
-
-               phtpriv->ht_option = true;
-
-               p = rtw_get_ie(in_ie + 12, _HT_ADD_INFO_IE_, &ielen, in_len - 12);
-               if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) {
-                       out_len = *pout_len;
-                       rtw_set_ie(out_ie + out_len, _HT_ADD_INFO_IE_, ielen, p + 2, pout_len);
-               }
-       }
-       return phtpriv->ht_option;
-}
-
-/* the function is > passive_level (in critical_section) */
-void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len)
-{
-       u8 *p, max_ampdu_sz;
-       int len;
-       struct ieee80211_ht_cap *pht_capie;
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-       struct ht_priv          *phtpriv = &pmlmepriv->htpriv;
-       struct registry_priv *pregistrypriv = &padapter->registrypriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       if (!phtpriv->ht_option)
-               return;
-
-       if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable))
-               return;
-
-       /* maybe needs check if ap supports rx ampdu. */
-       if ((!phtpriv->ampdu_enable) && (pregistrypriv->ampdu_enable == 1)) {
-               if (pregistrypriv->wifi_spec == 1)
-                       phtpriv->ampdu_enable = false;
-               else
-                       phtpriv->ampdu_enable = true;
-       } else if (pregistrypriv->ampdu_enable == 2) {
-               phtpriv->ampdu_enable = true;
-       }
-
-       /* check Max Rx A-MPDU Size */
-       len = 0;
-       p = rtw_get_ie(pie + sizeof(struct ndis_802_11_fixed_ie), _HT_CAPABILITY_IE_, &len, ie_len - sizeof(struct ndis_802_11_fixed_ie));
-       if (p && len > 0) {
-               pht_capie = (struct ieee80211_ht_cap *)(p + 2);
-               max_ampdu_sz = (pht_capie->ampdu_params_info & IEEE80211_HT_AMPDU_PARM_FACTOR);
-               max_ampdu_sz = 1 << (max_ampdu_sz + 3); /*  max_ampdu_sz (kbytes); */
-               phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
-       }
-       len = 0;
-       p = rtw_get_ie(pie + sizeof(struct ndis_802_11_fixed_ie), _HT_ADD_INFO_IE_, &len, ie_len - sizeof(struct ndis_802_11_fixed_ie));
-
-       /* update cur_bwmode & cur_ch_offset */
-       if ((pregistrypriv->cbw40_enable) &&
-           (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & BIT(1)) &&
-           (pmlmeinfo->HT_info.infos[0] & BIT(2))) {
-               int i;
-
-               /* update the MCS rates */
-               for (i = 0; i < 16; i++)
-                       pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
-
-               /* switch to the 40M Hz mode according to the AP */
-               pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
-               switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) {
-               case HT_EXTCHNL_OFFSET_UPPER:
-                       pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
-                       break;
-               case HT_EXTCHNL_OFFSET_LOWER:
-                       pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
-                       break;
-               default:
-                       pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-                       break;
-               }
-       }
-
-       /*  Config SM Power Save setting */
-       pmlmeinfo->SM_PS = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & 0x0C) >> 2;
-
-       /*  Config current HT Protection mode. */
-       pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
-}
-
-void rtw_issue_addbareq_cmd(struct adapter *padapter, struct xmit_frame *pxmitframe)
-{
-       u8 issued;
-       int priority;
-       struct sta_info *psta = NULL;
-       struct ht_priv  *phtpriv;
-       struct pkt_attrib *pattrib = &pxmitframe->attrib;
-
-       if (is_multicast_ether_addr(pattrib->ra) ||
-           padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod < 100)
-               return;
-
-       priority = pattrib->priority;
-
-       if (pattrib->psta)
-               psta = pattrib->psta;
-       else
-               psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
-
-       if (!psta)
-               return;
-
-       phtpriv = &psta->htpriv;
-
-       if ((phtpriv->ht_option) && (phtpriv->ampdu_enable)) {
-               issued = (phtpriv->agg_enable_bitmap >> priority) & 0x1;
-               issued |= (phtpriv->candidate_tid_bitmap >> priority) & 0x1;
-
-               if (issued == 0) {
-                       psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);
-                       rtw_addbareq_cmd(padapter, (u8)priority, pattrib->ra);
-               }
-       }
-}
-
-void rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network)
-{
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-
-       spin_lock_bh(&pmlmepriv->lock);
-       _rtw_roaming(padapter, tgt_network);
-       spin_unlock_bh(&pmlmepriv->lock);
-}
-void _rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network)
-{
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-       int do_join_r;
-
-       struct wlan_network *pnetwork;
-
-       if (tgt_network)
-               pnetwork = tgt_network;
-       else
-               pnetwork = &pmlmepriv->cur_network;
-
-       if (rtw_to_roaming(padapter) > 0) {
-               memcpy(&pmlmepriv->assoc_ssid, &pnetwork->network.Ssid, sizeof(struct ndis_802_11_ssid));
-
-               pmlmepriv->assoc_by_bssid = false;
-
-               while (1) {
-                       do_join_r = rtw_do_join(padapter);
-                       if (do_join_r == _SUCCESS) {
-                               break;
-                       } else {
-                               pmlmepriv->to_roaming--;
-
-                               if (pmlmepriv->to_roaming > 0) {
-                                       continue;
-                               } else {
-                                       rtw_indicate_disconnect(padapter);
-                                       break;
-                               }
-                       }
-               }
-       }
-}
diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c
deleted file mode 100644 (file)
index dc181e4..0000000
+++ /dev/null
@@ -1,7817 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-#define _RTW_MLME_EXT_C_
-
-#include <linux/ieee80211.h>
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/wifi.h"
-#include "../include/rtw_mlme_ext.h"
-#include "../include/wlan_bssdef.h"
-#include "../include/rtl8188e_xmit.h"
-#include "../include/rtl8188e_dm.h"
-
-static u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
-
-/**************************************************
-OUI definitions for the vendor specific IE
-***************************************************/
-unsigned char  RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
-unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
-unsigned char  WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
-unsigned char  P2P_OUI[] = {0x50, 0x6F, 0x9A, 0x09};
-unsigned char  WFD_OUI[] = {0x50, 0x6F, 0x9A, 0x0A};
-
-unsigned char  WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
-unsigned char  WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
-
-unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02};
-unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02};
-
-extern unsigned char REALTEK_96B_IE[];
-
-/********************************************************
-MCS rate definitions
-*********************************************************/
-unsigned char  MCS_rate_1R[16] = {0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
-
-/********************************************************
-ChannelPlan definitions
-*********************************************************/
-static struct rt_channel_plan RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
-       {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},              /*  0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */
-       {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},              /*  0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
-       {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},                      /*  0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
-       {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},  /*  0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
-       {{10, 11, 12, 13}, 4},                                  /*  0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
-       {{}, 0},                                                                        /*  0x05, RT_CHANNEL_DOMAIN_2G_NULL */
-};
-
-static struct rt_channel_plan_map      RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
-       /*  0x00 ~ 0x1F , Old Define ===== */
-       {0x02}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */
-       {0x02}, /* 0x01, RT_CHANNEL_DOMAIN_IC */
-       {0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
-       {0x01}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
-       {0x01}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
-       {0x03}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */
-       {0x03}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
-       {0x01}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
-       {0x03}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
-       {0x03}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
-       {0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
-       {0x02}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
-       {0x01}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
-       {0x02}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
-       {0x02}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
-       {0x02}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
-       {0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
-       {0x02}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
-       {0x01}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
-       {0x00}, /* 0x13 */
-       {0x02}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
-       {0x00}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
-       {0x00}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
-       {0x03}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
-       {0x05}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
-       {0x02}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
-       {0x00}, /* 0x1A, */
-       {0x00}, /* 0x1B, */
-       {0x00}, /* 0x1C, */
-       {0x00}, /* 0x1D, */
-       {0x00}, /* 0x1E, */
-       {0x00}, /* 0x1F, */
-       /*  0x20 ~ 0x7F , New Define ===== */
-       {0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
-       {0x01}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
-       {0x02}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
-       {0x03}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
-       {0x04}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
-       {0x02}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
-       {0x00}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
-       {0x03}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
-       {0x00}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
-       {0x00}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
-       {0x00}, /* 0x2A, */
-       {0x00}, /* 0x2B, */
-       {0x00}, /* 0x2C, */
-       {0x00}, /* 0x2D, */
-       {0x00}, /* 0x2E, */
-       {0x00}, /* 0x2F, */
-       {0x00}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
-       {0x00}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
-       {0x00}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
-       {0x00}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
-       {0x02}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
-       {0x00}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
-       {0x00}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
-       {0x03}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
-       {0x03}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
-       {0x02}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
-       {0x00}, /* 0x3A, */
-       {0x00}, /* 0x3B, */
-       {0x00}, /* 0x3C, */
-       {0x00}, /* 0x3D, */
-       {0x00}, /* 0x3E, */
-       {0x00}, /* 0x3F, */
-       {0x02}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
-       {0x03}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */
-};
-
-static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03}; /* use the combination for max channel numbers */
-
-/*
- * Search the @param channel_num in given @param channel_set
- * @ch_set: the given channel set
- * @ch: the given channel number
- *
- * return the index of channel_num in channel_set, -1 if not found
- */
-int rtw_ch_set_search_ch(struct rt_channel_info *ch_set, const u32 ch)
-{
-       int i;
-       for (i = 0; ch_set[i].ChannelNum != 0; i++) {
-               if (ch == ch_set[i].ChannelNum)
-                       break;
-       }
-
-       if (i >= ch_set[i].ChannelNum)
-               return -1;
-       return i;
-}
-
-/****************************************************************************
-
-Following are the initialization functions for WiFi MLME
-
-*****************************************************************************/
-
-int init_hw_mlme_ext(struct adapter *padapter)
-{
-       struct  mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
-       set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-       return _SUCCESS;
-}
-
-static void init_mlme_ext_priv_value(struct adapter *padapter)
-{
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       unsigned char   mixed_datarate[NumRates] = {
-               _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
-               _9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_,
-                _48M_RATE_, _54M_RATE_, 0xff
-       };
-       unsigned char   mixed_basicrate[NumRates] = {
-               _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
-               _12M_RATE_, _24M_RATE_, 0xff,
-       };
-
-       atomic_set(&pmlmeext->event_seq, 0);
-       pmlmeext->mgnt_seq = 0;/* reset to zero when disconnect at client mode */
-
-       pmlmeext->cur_channel = padapter->registrypriv.channel;
-       pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
-       pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-       pmlmeext->retry = 0;
-
-       pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
-
-       memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
-       memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
-
-       pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
-
-       pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
-       pmlmeext->sitesurvey_res.channel_idx = 0;
-       pmlmeext->sitesurvey_res.bss_cnt = 0;
-       pmlmeext->scan_abort = false;
-
-       pmlmeinfo->state = WIFI_FW_NULL_STATE;
-       pmlmeinfo->reauth_count = 0;
-       pmlmeinfo->reassoc_count = 0;
-       pmlmeinfo->link_count = 0;
-       pmlmeinfo->auth_seq = 0;
-       pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
-       pmlmeinfo->key_index = 0;
-       pmlmeinfo->iv = 0;
-
-       pmlmeinfo->enc_algo = _NO_PRIVACY_;
-       pmlmeinfo->authModeToggle = 0;
-
-       memset(pmlmeinfo->chg_txt, 0, 128);
-
-       pmlmeinfo->slotTime = SHORT_SLOT_TIME;
-       pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
-
-       pmlmeinfo->dialogToken = 0;
-
-       pmlmeext->action_public_rxseq = 0xffff;
-       pmlmeext->action_public_dialog_token = 0xff;
-}
-
-static int has_channel(struct rt_channel_info *channel_set,
-                                          u8 chanset_size,
-                                          u8 chan)
-{
-       int i;
-
-       for (i = 0; i < chanset_size; i++) {
-               if (channel_set[i].ChannelNum == chan)
-                       return 1;
-       }
-       return 0;
-}
-
-static void init_channel_list(struct adapter *padapter, struct rt_channel_info *channel_set,
-                                                         u8 chanset_size,
-                                                         struct p2p_channels *channel_list)
-{
-       struct p2p_oper_class_map op_class[] = {
-               { IEEE80211G,  81,   1,  13,  1, BW20 },
-               { IEEE80211G,  82,  14,  14,  1, BW20 },
-               { -1, 0, 0, 0, 0, BW20 }
-       };
-
-       int cla, op;
-
-       cla = 0;
-
-       for (op = 0; op_class[op].op_class; op++) {
-               u8 ch;
-               struct p2p_oper_class_map *o = &op_class[op];
-               struct p2p_reg_class *reg = NULL;
-
-               for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
-                       if (!has_channel(channel_set, chanset_size, ch)) {
-                               continue;
-                       }
-
-                       if ((padapter->registrypriv.ht_enable == 0) && (o->inc == 8))
-                               continue;
-
-                       if (((padapter->registrypriv.cbw40_enable & BIT(1)) == 0) &&
-                           ((o->bw == BW40MINUS) || (o->bw == BW40PLUS)))
-                               continue;
-
-                       if (!reg) {
-                               reg = &channel_list->reg_class[cla];
-                               cla++;
-                               reg->reg_class = o->op_class;
-                               reg->channels = 0;
-                       }
-                       reg->channel[reg->channels] = ch;
-                       reg->channels++;
-               }
-       }
-       channel_list->reg_classes = cla;
-}
-
-static u8 init_channel_set(struct adapter *padapter, u8 ChannelPlan, struct rt_channel_info *channel_set)
-{
-       u8 index, chanset_size = 0;
-       u8 b2_4GBand = false;
-       u8 Index2G = 0;
-
-       memset(channel_set, 0, sizeof(struct rt_channel_info) * MAX_CHANNEL_NUM);
-
-       if (ChannelPlan >= RT_CHANNEL_DOMAIN_MAX && ChannelPlan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE)
-               return chanset_size;
-
-       if (padapter->registrypriv.wireless_mode & WIRELESS_11G) {
-               b2_4GBand = true;
-               if (ChannelPlan == RT_CHANNEL_DOMAIN_REALTEK_DEFINE)
-                       Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
-               else
-                       Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
-       }
-
-       if (b2_4GBand) {
-               for (index = 0; index < RTW_ChannelPlan2G[Index2G].Len; index++) {
-                       channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index];
-
-                       if ((ChannelPlan == RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN) ||/* Channel 1~11 is active, and 12~14 is passive */
-                           (ChannelPlan == RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G)) {
-                               if (channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11)
-                                       channel_set[chanset_size].ScanType = SCAN_ACTIVE;
-                               else if ((channel_set[chanset_size].ChannelNum  >= 12 && channel_set[chanset_size].ChannelNum  <= 14))
-                                       channel_set[chanset_size].ScanType  = SCAN_PASSIVE;
-                       } else if (ChannelPlan == RT_CHANNEL_DOMAIN_WORLD_WIDE_13 ||
-                                  Index2G == RT_CHANNEL_DOMAIN_2G_WORLD) {/*  channel 12~13, passive scan */
-                               if (channel_set[chanset_size].ChannelNum <= 11)
-                                       channel_set[chanset_size].ScanType = SCAN_ACTIVE;
-                               else
-                                       channel_set[chanset_size].ScanType = SCAN_PASSIVE;
-                       } else {
-                               channel_set[chanset_size].ScanType = SCAN_ACTIVE;
-                       }
-
-                       chanset_size++;
-               }
-       }
-       return chanset_size;
-}
-
-static void _survey_timer_hdl(struct timer_list *t)
-{
-       struct adapter *padapter = from_timer(padapter, t, mlmeextpriv.survey_timer);
-
-       survey_timer_hdl(padapter);
-}
-
-static void _link_timer_hdl(struct timer_list *t)
-{
-       struct adapter *padapter = from_timer(padapter, t, mlmeextpriv.link_timer);
-
-       link_timer_hdl(padapter);
-}
-
-static void init_mlme_ext_timer(struct adapter *padapter)
-{
-       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
-       timer_setup(&pmlmeext->survey_timer, _survey_timer_hdl, 0);
-       timer_setup(&pmlmeext->link_timer, _link_timer_hdl, 0);
-}
-
-void init_mlme_ext_priv(struct adapter *padapter)
-{
-       struct registry_priv *pregistrypriv = &padapter->registrypriv;
-       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       pmlmeext->padapter = padapter;
-
-       init_mlme_ext_priv_value(padapter);
-       pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
-
-       init_mlme_ext_timer(padapter);
-
-       init_mlme_ap_info(padapter);
-
-       pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan, pmlmeext->channel_set);
-       init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
-
-       pmlmeext->chan_scan_time = SURVEY_TO;
-       pmlmeext->mlmeext_init = true;
-
-       pmlmeext->active_keep_alive_check = true;
-}
-
-void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext)
-{
-       struct adapter *padapter = pmlmeext->padapter;
-
-       if (!padapter)
-               return;
-
-       if (padapter->bDriverStopped) {
-               _cancel_timer_ex(&pmlmeext->survey_timer);
-               _cancel_timer_ex(&pmlmeext->link_timer);
-               /* _cancel_timer_ex(&pmlmeext->ADDBA_timer); */
-       }
-}
-
-static u32 p2p_listen_state_process(struct adapter *padapter, unsigned char *da)
-{
-       bool response = true;
-
-       /*      do nothing if the device name is empty */
-       if (!padapter->wdinfo.device_name_len)
-               response = false;
-
-       if (response)
-               issue_probersp_p2p(padapter, da);
-
-       return _SUCCESS;
-}
-
-static void correct_TSF(struct adapter *padapter)
-{
-       u8 reg;
-       int res;
-       u64 tsf;
-       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       tsf = pmlmeext->TSFValue - do_div(pmlmeext->TSFValue,
-                                         pmlmeinfo->bcn_interval * 1024) - 1024; /* us */
-
-       if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
-           ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
-               rtw_stop_tx_beacon(padapter);
-
-       /* disable related TSF function */
-       res = rtw_read8(padapter, REG_BCN_CTRL, &reg);
-       if (res)
-               return;
-
-       rtw_write8(padapter, REG_BCN_CTRL, reg & (~BIT(3)));
-
-       rtw_write32(padapter, REG_TSFTR, tsf);
-       rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
-
-       /* enable related TSF function */
-       res = rtw_read8(padapter, REG_BCN_CTRL, &reg);
-       if (res)
-               return;
-
-       rtw_write8(padapter, REG_BCN_CTRL, reg | BIT(3));
-
-       if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
-           ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
-               rtw_resume_tx_beacon(padapter);
-}
-
-/****************************************************************************
-
-Following are the callback functions for each subtype of the management frames
-
-*****************************************************************************/
-
-static void OnProbeReq(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       unsigned int    ielen;
-       unsigned char   *p;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex *cur = &pmlmeinfo->network;
-       u8 *pframe = precv_frame->rx_data;
-       uint len = precv_frame->len;
-       u8 is_valid_p2p_probereq = false;
-
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-
-       if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
-           !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
-           !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
-           !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
-           !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)) {
-               /*      mcs_rate = 0 -> CCK 1M rate */
-               /*      mcs_rate = 1 -> CCK 2M rate */
-               /*      mcs_rate = 2 -> CCK 5.5M rate */
-               /*      mcs_rate = 3 -> CCK 11M rate */
-               /*      In the P2P mode, the driver should not support the CCK rate */
-
-               /*      Commented by Kurt 2012/10/16 */
-               /*      IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client */
-               is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len);
-               if (is_valid_p2p_probereq) {
-                       if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) {
-                               /*  FIXME */
-                               report_survey_event(padapter, precv_frame);
-                               p2p_listen_state_process(padapter,  get_sa(pframe));
-
-                               return;
-                       }
-               }
-       }
-
-       if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
-               return;
-
-       if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
-           !check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE))
-               return;
-
-       p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
-                       len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
-
-       /* check (wildcard) SSID */
-       if (p) {
-               if (is_valid_p2p_probereq)
-                       goto _issue_probersp;
-
-               if ((ielen != 0 && memcmp((void *)(p + 2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength)) ||
-                   (ielen == 0 && pmlmeinfo->hidden_ssid_mode))
-                       return;
-
-_issue_probersp:
-
-               if (check_fwstate(pmlmepriv, _FW_LINKED) &&
-                   (pmlmepriv->cur_network.join_res ||
-                   check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)))
-                       issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
-       }
-}
-
-static void OnProbeRsp(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-       u8 *pframe = precv_frame->rx_data;
-
-       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) {
-               if (pwdinfo->tx_prov_disc_info.benable) {
-                       if (!memcmp(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr2Ptr(pframe), ETH_ALEN)) {
-                               if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
-                                       pwdinfo->tx_prov_disc_info.benable = false;
-                                       issue_p2p_provision_request(padapter,
-                                                                   pwdinfo->tx_prov_disc_info.ssid.Ssid,
-                                                                   pwdinfo->tx_prov_disc_info.ssid.SsidLength,
-                                                                   pwdinfo->tx_prov_disc_info.peerDevAddr);
-                               } else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
-                                       pwdinfo->tx_prov_disc_info.benable = false;
-                                       issue_p2p_provision_request(padapter, NULL, 0,
-                                                                   pwdinfo->tx_prov_disc_info.peerDevAddr);
-                               }
-                       }
-               }
-               return;
-       } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
-               if (pwdinfo->nego_req_info.benable) {
-                       if (!memcmp(pwdinfo->nego_req_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN)) {
-                               pwdinfo->nego_req_info.benable = false;
-                               issue_p2p_GO_request(padapter, pwdinfo->nego_req_info.peerDevAddr);
-                       }
-               }
-       } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ)) {
-               if (pwdinfo->invitereq_info.benable) {
-                       if (!memcmp(pwdinfo->invitereq_info.peer_macaddr, GetAddr2Ptr(pframe), ETH_ALEN)) {
-                               pwdinfo->invitereq_info.benable = false;
-                               issue_p2p_invitation_request(padapter, pwdinfo->invitereq_info.peer_macaddr);
-                       }
-               }
-       }
-       if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
-               report_survey_event(padapter, precv_frame);
-               return;
-       }
-}
-
-static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data;
-       int cam_idx;
-       struct sta_info *psta;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       u8 *pframe = precv_frame->rx_data;
-       uint len = precv_frame->len;
-       struct wlan_bssid_ex *pbss;
-       u8 *ie_ptr;
-       u32 ie_len;
-
-       ie_ptr = (u8 *)&mgmt->u.beacon.variable;
-       if (precv_frame->len < offsetof(struct ieee80211_mgmt, u.beacon.variable))
-               return;
-       ie_len = precv_frame->len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
-
-       if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
-               report_survey_event(padapter, precv_frame);
-               return;
-       }
-
-       if (memcmp(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
-               return;
-
-       if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
-               /* we should update current network before auth, or some IE is wrong */
-               pbss = kmalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
-               if (!pbss)
-                       return;
-
-               if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
-                       update_network(&pmlmepriv->cur_network.network, pbss, padapter, true);
-                       rtw_get_bcn_info(&pmlmepriv->cur_network);
-               }
-               kfree(pbss);
-
-               /* check the vendor of the assoc AP */
-               pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe + sizeof(struct ieee80211_hdr_3addr), len - sizeof(struct ieee80211_hdr_3addr));
-
-               pmlmeext->TSFValue = le64_to_cpu(mgmt->u.beacon.timestamp);
-
-               /* start auth */
-               start_clnt_auth(padapter);
-
-               return;
-       }
-
-       if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
-               psta = rtw_get_stainfo(pstapriv, mgmt->sa);
-               if (!psta)
-                       return;
-
-               if (rtw_check_bcn_info(padapter, pframe, len) != _SUCCESS) {
-                       receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 0);
-                       return;
-               }
-               /* update WMM, ERP in the beacon */
-               /* todo: the timer is used instead of the number of the beacon received */
-               if ((sta_rx_pkts(psta) & 0xf) == 0)
-                       update_beacon_info(padapter, ie_ptr, ie_len, psta);
-               process_p2p_ps_ie(padapter, ie_ptr, ie_len);
-       } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
-               psta = rtw_get_stainfo(pstapriv, mgmt->sa);
-               if (psta) {
-                       /* update WMM, ERP in the beacon */
-                       /* todo: the timer is used instead of the number of the beacon received */
-                       if ((sta_rx_pkts(psta) & 0xf) == 0)
-                               update_beacon_info(padapter, ie_ptr, ie_len, psta);
-               } else {
-                       /* allocate a new CAM entry for IBSS station */
-                       cam_idx = allocate_fw_sta_entry(padapter);
-                       if (cam_idx == NUM_STA)
-                               return;
-
-                       /* get supported rate */
-                       if (update_sta_support_rate(padapter, ie_ptr, ie_len, cam_idx) == _FAIL) {
-                               pmlmeinfo->FW_sta_info[cam_idx].status = 0;
-                               return;
-                       }
-
-                       pmlmeext->TSFValue = le64_to_cpu(mgmt->u.beacon.timestamp);
-
-                       report_add_sta_event(padapter, mgmt->sa, cam_idx);
-               }
-       }
-}
-
-static void OnAuth(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       unsigned int    auth_mode, ie_len;
-       u16 seq;
-       unsigned char   *sa, *p;
-       u16 algorithm;
-       int     status;
-       static struct sta_info stat;
-       struct  sta_info        *pstat = NULL;
-       struct  sta_priv *pstapriv = &padapter->stapriv;
-       struct security_priv *psecuritypriv = &padapter->securitypriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       u8 *pframe = precv_frame->rx_data;
-       uint len = precv_frame->len;
-
-       if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
-               return;
-
-       sa = GetAddr2Ptr(pframe);
-
-       auth_mode = psecuritypriv->dot11AuthAlgrthm;
-       seq = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN + 2));
-       algorithm = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN));
-
-       if (auth_mode == 2 && psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
-           psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
-               auth_mode = 0;
-
-       if ((algorithm > 0 && auth_mode == 0) ||        /*  rx a shared-key auth but shared not enabled */
-           (algorithm == 0 && auth_mode == 1)) {       /*  rx a open-system auth but shared-key is enabled */
-
-               status = _STATS_NO_SUPP_ALG_;
-
-               goto auth_fail;
-       }
-
-       if (!rtw_access_ctrl(padapter, sa)) {
-               status = _STATS_UNABLE_HANDLE_STA_;
-               goto auth_fail;
-       }
-
-       pstat = rtw_get_stainfo(pstapriv, sa);
-       if (!pstat) {
-               /*  allocate a new one */
-               pstat = rtw_alloc_stainfo(pstapriv, sa);
-               if (!pstat) {
-                       status = _STATS_UNABLE_HANDLE_STA_;
-                       goto auth_fail;
-               }
-
-               pstat->state = WIFI_FW_AUTH_NULL;
-               pstat->auth_seq = 0;
-       } else {
-               spin_lock_bh(&pstapriv->asoc_list_lock);
-               if (!list_empty(&pstat->asoc_list)) {
-                       list_del_init(&pstat->asoc_list);
-                       pstapriv->asoc_list_cnt--;
-               }
-               spin_unlock_bh(&pstapriv->asoc_list_lock);
-
-               if (seq == 1) {
-                       /* TODO: STA re_auth and auth timeout */
-               }
-       }
-
-       spin_lock_bh(&pstapriv->auth_list_lock);
-       if (list_empty(&pstat->auth_list)) {
-               list_add_tail(&pstat->auth_list, &pstapriv->auth_list);
-               pstapriv->auth_list_cnt++;
-       }
-       spin_unlock_bh(&pstapriv->auth_list_lock);
-
-       if (pstat->auth_seq == 0)
-               pstat->expire_to = pstapriv->auth_to;
-
-       if ((pstat->auth_seq + 1) != seq) {
-               status = _STATS_OUT_OF_AUTH_SEQ_;
-               goto auth_fail;
-       }
-
-       if (algorithm == 0 && (auth_mode == 0 || auth_mode == 2)) {
-               if (seq == 1) {
-                       pstat->state &= ~WIFI_FW_AUTH_NULL;
-                       pstat->state |= WIFI_FW_AUTH_SUCCESS;
-                       pstat->expire_to = pstapriv->assoc_to;
-                       pstat->authalg = algorithm;
-               } else {
-                       status = _STATS_OUT_OF_AUTH_SEQ_;
-                       goto auth_fail;
-               }
-       } else { /*  shared system or auto authentication */
-               if (seq == 1) {
-                       /* prepare for the challenging txt... */
-
-                       pstat->state &= ~WIFI_FW_AUTH_NULL;
-                       pstat->state |= WIFI_FW_AUTH_STATE;
-                       pstat->authalg = algorithm;
-                       pstat->auth_seq = 2;
-               } else if (seq == 3) {
-                       /* checking for challenging txt... */
-
-                       p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&ie_len,
-                                       len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
-
-                       if (!p || ie_len <= 0) {
-                               status = _STATS_CHALLENGE_FAIL_;
-                               goto auth_fail;
-                       }
-
-                       if (!memcmp((void *)(p + 2), pstat->chg_txt, 128)) {
-                               pstat->state &= (~WIFI_FW_AUTH_STATE);
-                               pstat->state |= WIFI_FW_AUTH_SUCCESS;
-                               /*  challenging txt is correct... */
-                               pstat->expire_to =  pstapriv->assoc_to;
-                       } else {
-                               status = _STATS_CHALLENGE_FAIL_;
-                               goto auth_fail;
-                       }
-               } else {
-                       status = _STATS_OUT_OF_AUTH_SEQ_;
-                       goto auth_fail;
-               }
-       }
-
-       /*  Now, we are going to issue_auth... */
-       pstat->auth_seq = seq + 1;
-
-       issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
-
-       if (pstat->state & WIFI_FW_AUTH_SUCCESS)
-               pstat->auth_seq = 0;
-
-       return;
-
-auth_fail:
-
-       if (pstat)
-               rtw_free_stainfo(padapter, pstat);
-
-       pstat = &stat;
-       memset((char *)pstat, '\0', sizeof(stat));
-       pstat->auth_seq = 2;
-       memcpy(pstat->hwaddr, sa, 6);
-
-       issue_auth(padapter, pstat, (unsigned short)status);
-}
-
-static void OnAuthClient(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       unsigned int    seq, len, status, offset;
-       unsigned char   *p;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data;
-       u8 *pframe = precv_frame->rx_data;
-       uint pkt_len = precv_frame->len;
-
-       /* check A1 matches or not */
-       if (memcmp(myid(&padapter->eeprompriv), ieee80211_get_DA(hdr), ETH_ALEN))
-               return;
-
-       if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
-               return;
-
-       offset = ieee80211_has_protected(hdr->frame_control) ? 4 : 0;
-
-       seq     = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN + offset + 2));
-       status  = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN + offset + 4));
-
-       if (status != 0) {
-               if (status == 13) { /*  pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
-                       if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
-                               pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
-                       else
-                               pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
-               }
-
-               set_link_timer(pmlmeext, 1);
-               return;
-       }
-
-       if (seq == 2) {
-               if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
-                        /*  legendary shared system */
-                       p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
-                               pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
-
-                       if (!p)
-                               return;
-
-                       memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
-                       pmlmeinfo->auth_seq = 3;
-                       issue_auth(padapter, NULL, 0);
-                       set_link_timer(pmlmeext, REAUTH_TO);
-
-                       return;
-               } else {
-                       /*  open system */
-                       start_clnt_assoc(padapter);
-               }
-       } else if (seq == 4) {
-               if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
-                       start_clnt_assoc(padapter);
-       }
-}
-
-static void UpdateBrateTbl(u8 *mbrate)
-{
-       u8 i;
-       u8 rate;
-
-       /*  1M, 2M, 5.5M, 11M, 6M, 12M, 24M are mandatory. */
-       for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
-               rate = mbrate[i] & 0x7f;
-               switch (rate) {
-               case IEEE80211_CCK_RATE_1MB:
-               case IEEE80211_CCK_RATE_2MB:
-               case IEEE80211_CCK_RATE_5MB:
-               case IEEE80211_CCK_RATE_11MB:
-               case IEEE80211_OFDM_RATE_6MB:
-               case IEEE80211_OFDM_RATE_12MB:
-               case IEEE80211_OFDM_RATE_24MB:
-                       mbrate[i] |= IEEE80211_BASIC_RATE_MASK;
-                       break;
-               }
-       }
-}
-
-static void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen)
-{
-       u8 i;
-       u8 rate;
-
-       for (i = 0; i < bssratelen; i++) {
-               rate = bssrateset[i] & 0x7f;
-               switch (rate) {
-               case IEEE80211_CCK_RATE_1MB:
-               case IEEE80211_CCK_RATE_2MB:
-               case IEEE80211_CCK_RATE_5MB:
-               case IEEE80211_CCK_RATE_11MB:
-                       bssrateset[i] |= IEEE80211_BASIC_RATE_MASK;
-                       break;
-               }
-       }
-}
-
-static void OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       u16 capab_info;
-       struct rtw_ieee802_11_elems elems;
-       struct sta_info *pstat;
-       unsigned char           *p, *pos, *wpa_ie;
-       unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
-       int             i, ie_len, wpa_ie_len, left;
-       unsigned char           supportRate[16];
-       int                                     supportRateNum;
-       unsigned short          status = _STATS_SUCCESSFUL_;
-       unsigned short          frame_type, ie_offset = 0;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct security_priv *psecuritypriv = &padapter->securitypriv;
-       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex *cur = &pmlmeinfo->network;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       u8 *pframe = precv_frame->rx_data;
-       uint pkt_len = precv_frame->len;
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-       u8 p2p_status_code = P2P_STATUS_SUCCESS;
-       u8 *p2pie;
-       u32 p2pielen = 0;
-
-       if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
-               return;
-
-       frame_type = GetFrameSubType(pframe);
-       if (frame_type == WIFI_ASSOCREQ)
-               ie_offset = _ASOCREQ_IE_OFFSET_;
-       else /*  WIFI_REASSOCREQ */
-               ie_offset = _REASOCREQ_IE_OFFSET_;
-
-       if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset)
-               return;
-
-       pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
-       if (pstat == (struct sta_info *)NULL) {
-               status = _RSON_CLS2_;
-               goto asoc_class2_error;
-       }
-
-       capab_info = get_unaligned_le16(pframe + WLAN_HDR_A3_LEN);
-
-       left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
-       pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
-
-       /*  check if this stat has been successfully authenticated/assocated */
-       if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) {
-               if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) {
-                       status = _RSON_CLS2_;
-                       goto asoc_class2_error;
-               } else {
-                       pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
-                       pstat->state |= WIFI_FW_ASSOC_STATE;
-               }
-       } else {
-               pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
-               pstat->state |= WIFI_FW_ASSOC_STATE;
-       }
-       pstat->capability = capab_info;
-       /* now parse all ieee802_11 ie to point to elems */
-       if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
-           !elems.ssid) {
-               status = _STATS_FAILURE_;
-               goto OnAssocReqFail;
-       }
-
-       /*  now we should check all the fields... */
-       /*  checking SSID */
-       p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
-               pkt_len - WLAN_HDR_A3_LEN - ie_offset);
-       if (!p)
-               status = _STATS_FAILURE_;
-
-       if (ie_len == 0) { /*  broadcast ssid, however it is not allowed in assocreq */
-               status = _STATS_FAILURE_;
-       } else {
-               /*  check if ssid match */
-               if (memcmp((void *)(p + 2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
-                       status = _STATS_FAILURE_;
-
-               if (ie_len != cur->Ssid.SsidLength)
-                       status = _STATS_FAILURE_;
-       }
-
-       if (status != _STATS_SUCCESSFUL_)
-               goto OnAssocReqFail;
-
-       /*  check if the supported rate is ok */
-       p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
-       if (!p) {
-               /*  use our own rate set as statoin used */
-               /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
-               /* supportRateNum = AP_BSSRATE_LEN; */
-
-               status = _STATS_FAILURE_;
-               goto OnAssocReqFail;
-       } else {
-               memcpy(supportRate, p + 2, ie_len);
-               supportRateNum = ie_len;
-
-               p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_, &ie_len,
-                               pkt_len - WLAN_HDR_A3_LEN - ie_offset);
-               if (p) {
-                       if (supportRateNum <= sizeof(supportRate)) {
-                               memcpy(supportRate + supportRateNum, p + 2, ie_len);
-                               supportRateNum += ie_len;
-                       }
-               }
-       }
-
-       /* todo: mask supportRate between AP & STA -> move to update raid */
-       /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */
-
-       /* update station supportRate */
-       pstat->bssratelen = supportRateNum;
-       memcpy(pstat->bssrateset, supportRate, supportRateNum);
-       UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
-
-       /* check RSN/WPA/WPS */
-       pstat->dot8021xalg = 0;
-       pstat->wpa_psk = 0;
-       pstat->wpa_group_cipher = 0;
-       pstat->wpa2_group_cipher = 0;
-       pstat->wpa_pairwise_cipher = 0;
-       pstat->wpa2_pairwise_cipher = 0;
-       memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
-       if ((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
-               int group_cipher = 0, pairwise_cipher = 0;
-
-               wpa_ie = elems.rsn_ie;
-               wpa_ie_len = elems.rsn_ie_len;
-
-               if (rtw_parse_wpa2_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
-                       pstat->dot8021xalg = 1;/* psk,  todo:802.1x */
-                       pstat->wpa_psk |= BIT(1);
-
-                       pstat->wpa2_group_cipher = group_cipher & psecuritypriv->wpa2_group_cipher;
-                       pstat->wpa2_pairwise_cipher = pairwise_cipher & psecuritypriv->wpa2_pairwise_cipher;
-
-                       if (!pstat->wpa2_group_cipher)
-                               status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
-
-                       if (!pstat->wpa2_pairwise_cipher)
-                               status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
-               } else {
-                       status = WLAN_STATUS_INVALID_IE;
-               }
-       } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
-               int group_cipher = 0, pairwise_cipher = 0;
-
-               wpa_ie = elems.wpa_ie;
-               wpa_ie_len = elems.wpa_ie_len;
-
-               if (rtw_parse_wpa_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
-                       pstat->dot8021xalg = 1;/* psk,  todo:802.1x */
-                       pstat->wpa_psk |= BIT(0);
-
-                       pstat->wpa_group_cipher = group_cipher & psecuritypriv->wpa_group_cipher;
-                       pstat->wpa_pairwise_cipher = pairwise_cipher & psecuritypriv->wpa_pairwise_cipher;
-
-                       if (!pstat->wpa_group_cipher)
-                               status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
-
-                       if (!pstat->wpa_pairwise_cipher)
-                               status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
-               } else {
-                       status = WLAN_STATUS_INVALID_IE;
-               }
-       } else {
-               wpa_ie = NULL;
-               wpa_ie_len = 0;
-       }
-
-       if (status != _STATS_SUCCESSFUL_)
-               goto OnAssocReqFail;
-
-       pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
-       if (!wpa_ie) {
-               if (elems.wps_ie)
-                       pstat->flags |= WLAN_STA_WPS;
-                       /* wpabuf_free(sta->wps_ie); */
-                       /* sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4, */
-                       /*                              elems.wps_ie_len - 4); */
-               else
-                       pstat->flags |= WLAN_STA_MAYBE_WPS;
-
-               /*  AP support WPA/RSN, and sta is going to do WPS, but AP is not ready */
-               /*  that the selected registrar of AP is _FLASE */
-               if ((psecuritypriv->wpa_psk > 0) && (pstat->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))) {
-                       if (pmlmepriv->wps_beacon_ie) {
-                               u8 selected_registrar = 0;
-
-                               rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR, &selected_registrar, NULL);
-
-                               if (!selected_registrar) {
-
-                                       status = _STATS_UNABLE_HANDLE_STA_;
-
-                                       goto OnAssocReqFail;
-                               }
-                       }
-               }
-       } else {
-               int copy_len;
-
-               if (psecuritypriv->wpa_psk == 0) {
-
-                       status = WLAN_STATUS_INVALID_IE;
-
-                       goto OnAssocReqFail;
-               }
-
-               if (elems.wps_ie) {
-                       pstat->flags |= WLAN_STA_WPS;
-                       copy_len = 0;
-               } else {
-                       copy_len = ((wpa_ie_len + 2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)) : (wpa_ie_len + 2);
-               }
-               if (copy_len > 0)
-                       memcpy(pstat->wpa_ie, wpa_ie - 2, copy_len);
-       }
-       /*  check if there is WMM IE & support WWM-PS */
-       pstat->flags &= ~WLAN_STA_WME;
-       pstat->qos_option = 0;
-       pstat->qos_info = 0;
-       pstat->has_legacy_ac = true;
-       pstat->uapsd_vo = 0;
-       pstat->uapsd_vi = 0;
-       pstat->uapsd_be = 0;
-       pstat->uapsd_bk = 0;
-       if (pmlmepriv->qospriv.qos_option) {
-               p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
-               for (;;) {
-                       p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
-                       if (p) {
-                               if (!memcmp(p + 2, WMM_IE, 6)) {
-                                       pstat->flags |= WLAN_STA_WME;
-
-                                       pstat->qos_option = 1;
-                                       pstat->qos_info = *(p + 8);
-
-                                       pstat->max_sp_len = (pstat->qos_info >> 5) & 0x3;
-
-                                       if ((pstat->qos_info & 0xf) != 0xf)
-                                               pstat->has_legacy_ac = true;
-                                       else
-                                               pstat->has_legacy_ac = false;
-
-                                       if (pstat->qos_info & 0xf) {
-                                               if (pstat->qos_info & BIT(0))
-                                                       pstat->uapsd_vo = BIT(0) | BIT(1);
-                                               else
-                                                       pstat->uapsd_vo = 0;
-
-                                               if (pstat->qos_info & BIT(1))
-                                                       pstat->uapsd_vi = BIT(0) | BIT(1);
-                                               else
-                                                       pstat->uapsd_vi = 0;
-
-                                               if (pstat->qos_info & BIT(2))
-                                                       pstat->uapsd_bk = BIT(0) | BIT(1);
-                                               else
-                                                       pstat->uapsd_bk = 0;
-
-                                               if (pstat->qos_info & BIT(3))
-                                                       pstat->uapsd_be = BIT(0) | BIT(1);
-                                               else
-                                                       pstat->uapsd_be = 0;
-                                       }
-                                       break;
-                               }
-                       } else {
-                               break;
-                       }
-                       p = p + ie_len + 2;
-               }
-       }
-
-       /* save HT capabilities in the sta object */
-       memset(&pstat->htpriv.ht_cap, 0, sizeof(struct ieee80211_ht_cap));
-       if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct ieee80211_ht_cap)) {
-               pstat->flags |= WLAN_STA_HT;
-
-               pstat->flags |= WLAN_STA_WME;
-
-               memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct ieee80211_ht_cap));
-       } else {
-               pstat->flags &= ~WLAN_STA_HT;
-       }
-       if ((!pmlmepriv->htpriv.ht_option) && (pstat->flags & WLAN_STA_HT)) {
-               status = _STATS_FAILURE_;
-               goto OnAssocReqFail;
-       }
-
-       pstat->flags |= WLAN_STA_NONERP;
-       for (i = 0; i < pstat->bssratelen; i++) {
-               if ((pstat->bssrateset[i] & 0x7f) > 22) {
-                       pstat->flags &= ~WLAN_STA_NONERP;
-                       break;
-               }
-       }
-
-       if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
-               pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
-       else
-               pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
-
-       if (status != _STATS_SUCCESSFUL_)
-               goto OnAssocReqFail;
-
-       pstat->is_p2p_device = false;
-       if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
-               p2pie = rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, NULL, &p2pielen);
-               if (p2pie) {
-                       pstat->is_p2p_device = true;
-                       p2p_status_code = (u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat);
-                       if (p2p_status_code > 0) {
-                               pstat->p2p_status_code = p2p_status_code;
-                               status = _STATS_CAP_FAIL_;
-                               goto OnAssocReqFail;
-                       }
-               }
-       }
-       pstat->p2p_status_code = p2p_status_code;
-
-       /* TODO: identify_proprietary_vendor_ie(); */
-       /*  Realtek proprietary IE */
-       /*  identify if this is Broadcom sta */
-       /*  identify if this is ralink sta */
-       /*  Customer proprietary IE */
-
-       /* get a unique AID */
-       if (pstat->aid == 0) {
-               for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
-                       if (!pstapriv->sta_aid[pstat->aid - 1])
-                               break;
-
-               /* if (pstat->aid > NUM_STA) { */
-               if (pstat->aid > pstapriv->max_num_sta) {
-                       pstat->aid = 0;
-
-                       status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
-
-                       goto OnAssocReqFail;
-               } else {
-                       pstapriv->sta_aid[pstat->aid - 1] = pstat;
-               }
-       }
-
-       pstat->state &= (~WIFI_FW_ASSOC_STATE);
-       pstat->state |= WIFI_FW_ASSOC_SUCCESS;
-
-       spin_lock_bh(&pstapriv->auth_list_lock);
-       if (!list_empty(&pstat->auth_list)) {
-               list_del_init(&pstat->auth_list);
-               pstapriv->auth_list_cnt--;
-       }
-       spin_unlock_bh(&pstapriv->auth_list_lock);
-
-       spin_lock_bh(&pstapriv->asoc_list_lock);
-       if (list_empty(&pstat->asoc_list)) {
-               pstat->expire_to = pstapriv->expire_to;
-               list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list);
-               pstapriv->asoc_list_cnt++;
-       }
-       spin_unlock_bh(&pstapriv->asoc_list_lock);
-
-       /*  now the station is qualified to join our BSS... */
-       if (pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (status == _STATS_SUCCESSFUL_)) {
-               /* 1 bss_cap_update & sta_info_update */
-               bss_cap_update_on_sta_join(padapter, pstat);
-               sta_info_update(padapter, pstat);
-
-               /* issue assoc rsp before notify station join event. */
-               if (frame_type == WIFI_ASSOCREQ)
-                       issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
-               else
-                       issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
-
-               /* 2 - report to upper layer */
-               rtw_indicate_sta_assoc_event(padapter, pstat);
-
-               /* 3-(1) report sta add event */
-               report_add_sta_event(padapter, pstat->hwaddr, pstat->aid);
-       }
-
-       return;
-
-asoc_class2_error:
-
-       issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status);
-
-       return;
-
-OnAssocReqFail:
-
-       pstat->aid = 0;
-       if (frame_type == WIFI_ASSOCREQ)
-               issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
-       else
-               issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
-
-       return;
-}
-
-static void OnAssocRsp(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data;
-       uint i;
-       int res;
-       struct ndis_802_11_var_ie *pIE;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       /* struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); */
-       u8 *pframe = precv_frame->rx_data;
-       uint pkt_len = precv_frame->len;
-
-       /* check A1 matches or not */
-       if (memcmp(myid(&padapter->eeprompriv), mgmt->da, ETH_ALEN))
-               return;
-
-       if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
-               return;
-
-       if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
-               return;
-
-       _cancel_timer_ex(&pmlmeext->link_timer);
-
-       if (le16_to_cpu(mgmt->u.assoc_resp.status_code) > 0) {
-               pmlmeinfo->state = WIFI_FW_NULL_STATE;
-               res = -4;
-               goto report_assoc_result;
-       }
-
-       pmlmeinfo->capability = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
-
-       /* set slot time */
-       pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10)) ? 9 : 20;
-
-       pmlmeinfo->aid = le16_to_cpu(mgmt->u.assoc_resp.aid) & 0x3fff;
-       res = pmlmeinfo->aid;
-
-       /* following are moved to join event callback function */
-       /* to handle HT, WMM, rate adaptive, update MAC reg */
-       /* for not to handle the synchronous IO in the tasklet */
-       for (i = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); i < pkt_len;) {
-               pIE = (struct ndis_802_11_var_ie *)(pframe + i);
-
-               switch (pIE->ElementID) {
-               case _VENDOR_SPECIFIC_IE_:
-                       if (!memcmp(pIE->data, WMM_PARA_OUI, 6))        /* WMM */
-                               WMM_param_handler(padapter, pIE);
-                       break;
-               case _HT_CAPABILITY_IE_:        /* HT caps */
-                       HT_caps_handler(padapter, pIE);
-                       break;
-               case _HT_EXTRA_INFO_IE_:        /* HT info */
-                       HT_info_handler(padapter, pIE);
-                       break;
-               case _ERPINFO_IE_:
-                       ERP_IE_handler(padapter, pIE);
-                       break;
-               default:
-                       break;
-               }
-
-               i += (pIE->Length + 2);
-       }
-
-       pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
-       pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
-
-       /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
-       UpdateBrateTbl(pmlmeinfo->network.SupportedRates);
-
-report_assoc_result:
-       report_join_res(padapter, res);
-}
-
-static void OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data;
-       unsigned short  reason;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       if (memcmp(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
-               return;
-
-       if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
-               _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
-               _set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
-       }
-
-       reason = le16_to_cpu(mgmt->u.disassoc.reason_code);
-
-       if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
-               struct sta_info *psta;
-               struct sta_priv *pstapriv = &padapter->stapriv;
-               u8 updated = 0;
-
-               psta = rtw_get_stainfo(pstapriv, mgmt->sa);
-               if (!psta)
-                       return;
-
-               spin_lock_bh(&pstapriv->asoc_list_lock);
-               if (!list_empty(&psta->asoc_list)) {
-                       list_del_init(&psta->asoc_list);
-                       pstapriv->asoc_list_cnt--;
-                       updated = ap_free_sta(padapter, psta, false, reason);
-               }
-               spin_unlock_bh(&pstapriv->asoc_list_lock);
-
-               associated_clients_update(padapter, updated);
-       } else {
-               bool ignore_received_deauth = false;
-
-               /* Before sending the auth frame to start the STA/GC mode connection with AP/GO,
-                *      we will send the deauth first.
-                *      However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth.
-                *      Added the following code to avoid this case.
-                */
-               if (pmlmeinfo->state & (WIFI_FW_AUTH_STATE | WIFI_FW_ASSOC_STATE)) {
-                       if (reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA) {
-                               ignore_received_deauth = true;
-                       } else if (reason == WLAN_REASON_PREV_AUTH_NOT_VALID) {
-                               // TODO: 802.11r
-                               ignore_received_deauth = true;
-                       }
-               }
-
-               if (!ignore_received_deauth)
-                       receive_disconnect(padapter, mgmt->bssid, reason);
-
-               pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
-       }
-}
-
-static void OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data;
-       u16 reason;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-       struct sta_info *psta;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       u8 updated = 0;
-
-       if (memcmp(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
-               return;
-
-       if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
-               _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
-               _set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
-       }
-
-       reason = le16_to_cpu(mgmt->u.disassoc.reason_code);
-
-       if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
-               receive_disconnect(padapter, mgmt->bssid, reason);
-               pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
-               return;
-       }
-
-       psta = rtw_get_stainfo(pstapriv, mgmt->sa);
-       if (!psta)
-               return;
-
-       spin_lock_bh(&pstapriv->asoc_list_lock);
-       if (!list_empty(&psta->asoc_list)) {
-               list_del_init(&psta->asoc_list);
-               pstapriv->asoc_list_cnt--;
-               updated = ap_free_sta(padapter, psta, false, reason);
-       }
-       spin_unlock_bh(&pstapriv->asoc_list_lock);
-
-       associated_clients_update(padapter, updated);
-}
-
-static void OnAction_back(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data;
-       struct sta_info *psta = NULL;
-       struct recv_reorder_ctrl *preorder_ctrl;
-       unsigned short  tid;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-
-       if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
-               if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
-                       return;
-
-       psta = rtw_get_stainfo(pstapriv, mgmt->sa);
-       if (!psta)
-               return;
-
-       if (!pmlmeinfo->HT_enable)
-               return;
-       /* All union members start with an action code, it's ok to use addba_req. */
-       switch (mgmt->u.action.u.addba_req.action_code) {
-       case WLAN_ACTION_ADDBA_REQ:
-               tid = u16_get_bits(le16_to_cpu(mgmt->u.action.u.addba_req.capab),
-                                  IEEE80211_ADDBA_PARAM_TID_MASK);
-               preorder_ctrl = &psta->recvreorder_ctrl[tid];
-               preorder_ctrl->indicate_seq = 0xffff;
-               preorder_ctrl->enable = pmlmeinfo->bAcceptAddbaReq;
-               issue_action_BA(padapter, mgmt->sa, WLAN_ACTION_ADDBA_RESP,
-                               pmlmeinfo->bAcceptAddbaReq ?
-                                       WLAN_STATUS_SUCCESS : WLAN_STATUS_REQUEST_DECLINED, mgmt);
-               break;
-       case WLAN_ACTION_ADDBA_RESP:
-               tid = u16_get_bits(le16_to_cpu(mgmt->u.action.u.addba_resp.capab),
-                                  IEEE80211_ADDBA_PARAM_TID_MASK);
-               if (mgmt->u.action.u.addba_resp.status == 0) {  /* successful */
-                       psta->htpriv.agg_enable_bitmap |= BIT(tid);
-                       psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
-               } else {
-                       psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
-               }
-               break;
-       case WLAN_ACTION_DELBA:
-               tid = u16_get_bits(le16_to_cpu(mgmt->u.action.u.delba.params),
-                                  IEEE80211_DELBA_PARAM_TID_MASK);
-               if (u16_get_bits(le16_to_cpu(mgmt->u.action.u.delba.params),
-                                IEEE80211_DELBA_PARAM_INITIATOR_MASK) == WLAN_BACK_RECIPIENT) {
-                       psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
-                       psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
-               } else {
-                       preorder_ctrl =  &psta->recvreorder_ctrl[tid];
-                       preorder_ctrl->enable = false;
-                       preorder_ctrl->indicate_seq = 0xffff;
-               }
-               /* todo: how to notify the host while receiving DELETE BA */
-               break;
-       default:
-               break;
-       }
-}
-
-static int get_reg_classes_full_count(struct p2p_channels *channel_list)
-{
-       int cnt = 0;
-       int i;
-
-       for (i = 0; i < channel_list->reg_classes; i++) {
-               cnt += channel_list->reg_class[i].channels;
-       }
-
-       return cnt;
-}
-
-void issue_p2p_GO_request(struct adapter *padapter, u8 *raddr)
-{
-       unsigned char category = WLAN_CATEGORY_PUBLIC;
-       u8 action = P2P_PUB_ACTION_ACTION;
-       __be32 p2poui = cpu_to_be32(P2POUI);
-       u8 oui_subtype = P2P_GO_NEGO_REQ;
-       u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
-       u8 wpsielen = 0, p2pielen = 0;
-       u16 len_channellist_attr = 0;
-       struct xmit_frame *pmgntframe;
-       struct pkt_attrib *pattrib;
-       unsigned char *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
-       memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
-       memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(pframe, WIFI_ACTION);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
-       pwdinfo->negotiation_dialog_token = 1;  /*      Initialize the dialog value */
-       pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &pattrib->pktlen);
-
-       /*      WPS Section */
-       wpsielen = 0;
-       /*      WPS OUI */
-       *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI);
-       wpsielen += 4;
-
-       /*      WPS version */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
-       wpsielen += 2;
-
-       /*      Value: */
-       wpsie[wpsielen++] = WPS_VERSION_1;      /*      Version 1.0 */
-
-       /*      Device Password ID */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
-       wpsielen += 2;
-
-       /*      Value: */
-
-       if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN)
-               *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
-       else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN)
-               *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
-       else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC)
-               *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
-
-       wpsielen += 2;
-
-       pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen);
-
-       /*      P2P IE Section. */
-
-       /*      P2P OUI */
-       p2pielen = 0;
-       p2pie[p2pielen++] = 0x50;
-       p2pie[p2pielen++] = 0x6F;
-       p2pie[p2pielen++] = 0x9A;
-       p2pie[p2pielen++] = 0x09;       /*      WFA P2P v1.0 */
-
-       /*      Commented by Albert 20110306 */
-       /*      According to the P2P Specification, the group negotiation request frame should contain 9 P2P attributes */
-       /*      1. P2P Capability */
-       /*      2. Group Owner Intent */
-       /*      3. Configuration Timeout */
-       /*      4. Listen Channel */
-       /*      5. Extended Listen Timing */
-       /*      6. Intended P2P Interface Address */
-       /*      7. Channel List */
-       /*      8. P2P Device Info */
-       /*      9. Operating Channel */
-
-       /*      P2P Capability */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Device Capability Bitmap, 1 byte */
-       p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
-
-       /*      Group Capability Bitmap, 1 byte */
-       if (pwdinfo->persistent_supported)
-               p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
-       else
-               p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
-
-       /*      Group Owner Intent */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Todo the tie breaker bit. */
-       p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
-
-       /*      Configuration Timeout */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
-       p2pielen += 2;
-
-       /*      Value: */
-       p2pie[p2pielen++] = 200;        /*      2 seconds needed to be the P2P GO */
-       p2pie[p2pielen++] = 200;        /*      2 seconds needed to be the P2P Client */
-
-       /*      Listen Channel */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Country String */
-       p2pie[p2pielen++] = 'X';
-       p2pie[p2pielen++] = 'X';
-
-       /*      The third byte should be set to 0x04. */
-       /*      Described in the "Operating Channel Attribute" section. */
-       p2pie[p2pielen++] = 0x04;
-
-       /*      Operating Class */
-       p2pie[p2pielen++] = 0x51;       /*      Copy from SD7 */
-
-       /*      Channel Number */
-       p2pie[p2pielen++] = pwdinfo->listen_channel;    /*      listening channel number */
-
-       /*      Extended Listen Timing ATTR */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Availability Period */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
-       p2pielen += 2;
-
-       /*      Availability Interval */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
-       p2pielen += 2;
-
-       /*      Intended P2P Interface Address */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_INTENTED_IF_ADDR;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
-       p2pielen += 2;
-
-       /*      Value: */
-       memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
-       p2pielen += ETH_ALEN;
-
-       /*      Channel List */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
-
-       /*  Length: */
-       /*  Country String(3) */
-       /*  + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */
-       /*  + number of channels in all classes */
-       len_channellist_attr = 3
-          + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes)
-          + get_reg_classes_full_count(&pmlmeext->channel_list);
-
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Country String */
-       p2pie[p2pielen++] = 'X';
-       p2pie[p2pielen++] = 'X';
-
-       /*      The third byte should be set to 0x04. */
-       /*      Described in the "Operating Channel Attribute" section. */
-       p2pie[p2pielen++] = 0x04;
-
-       /*      Channel Entry List */
-
-       {
-               int i, j;
-               for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
-                       /*      Operating Class */
-                       p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
-
-                       /*      Number of Channels */
-                       p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
-
-                       /*      Channel List */
-                       for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
-                               p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
-                       }
-               }
-       }
-
-       /*      Device Info */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
-
-       /*      Length: */
-       /*      21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
-       /*      + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      P2P Device Address */
-       memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
-       p2pielen += ETH_ALEN;
-
-       /*      Config Method */
-       /*      This field should be big endian. Noted by P2P specification. */
-
-       *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
-
-       p2pielen += 2;
-
-       /*      Primary Device Type */
-       /*      Category ID */
-       *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
-       p2pielen += 2;
-
-       /*      OUI */
-       *(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
-       p2pielen += 4;
-
-       /*      Sub Category ID */
-       *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
-       p2pielen += 2;
-
-       /*      Number of Secondary Device Types */
-       p2pie[p2pielen++] = 0x00;       /*      No Secondary Device Type List */
-
-       /*      Device Name */
-       /*      Type: */
-       *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
-       p2pielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
-       p2pielen += 2;
-
-       /*      Value: */
-       memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
-       p2pielen += pwdinfo->device_name_len;
-
-       /*      Operating Channel */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Country String */
-       p2pie[p2pielen++] = 'X';
-       p2pie[p2pielen++] = 'X';
-
-       /*      The third byte should be set to 0x04. */
-       /*      Described in the "Operating Channel Attribute" section. */
-       p2pie[p2pielen++] = 0x04;
-
-       /*      Operating Class */
-       p2pie[p2pielen++] = 0x51;
-
-       /*      Channel Number */
-       p2pie[p2pielen++] = pwdinfo->operating_channel; /*      operating channel number */
-
-       pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       dump_mgntframe(padapter, pmgntframe);
-}
-
-static void issue_p2p_GO_response(struct adapter *padapter, u8 *raddr, u8 *frame_body, uint len, u8 result)
-{
-       unsigned char category = WLAN_CATEGORY_PUBLIC;
-       u8 action = P2P_PUB_ACTION_ACTION;
-       __be32                  p2poui = cpu_to_be32(P2POUI);
-       u8 oui_subtype = P2P_GO_NEGO_RESP;
-       u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
-       u8 p2pielen = 0;
-       uint                    wpsielen = 0;
-       u16 wps_devicepassword_id = 0x0000;
-       __be16                  be_tmp;
-       uint                    wps_devicepassword_id_len = 0;
-       u16 len_channellist_attr = 0;
-
-       struct xmit_frame                       *pmgntframe;
-       struct pkt_attrib                       *pattrib;
-       unsigned char                                   *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       struct xmit_priv                        *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
-       memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
-       memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(pframe, WIFI_ACTION);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
-       pwdinfo->negotiation_dialog_token = frame_body[7];      /*      The Dialog Token of provisioning discovery request frame. */
-       pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &pattrib->pktlen);
-
-       /*      Commented by Albert 20110328 */
-       /*      Try to get the device password ID from the WPS IE of group negotiation request frame */
-       /*      WiFi Direct test plan 5.1.15 */
-       rtw_get_wps_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
-       rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8 *)&be_tmp, &wps_devicepassword_id_len);
-       wps_devicepassword_id = be16_to_cpu(be_tmp);
-
-       memset(wpsie, 0x00, 255);
-       wpsielen = 0;
-
-       /*      WPS Section */
-       wpsielen = 0;
-       /*      WPS OUI */
-       *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI);
-       wpsielen += 4;
-
-       /*      WPS version */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
-       wpsielen += 2;
-
-       /*      Value: */
-       wpsie[wpsielen++] = WPS_VERSION_1;      /*      Version 1.0 */
-
-       /*      Device Password ID */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
-       wpsielen += 2;
-
-       /*      Value: */
-       if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
-               *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
-       else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
-               *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
-       else
-               *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
-       wpsielen += 2;
-
-       /*      Commented by Kurt 20120113 */
-       /*      If some device wants to do p2p handshake without sending prov_disc_req */
-       /*      We have to get peer_req_cm from here. */
-       if (!memcmp(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3)) {
-               if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
-                       memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3);
-               else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
-                       memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3);
-               else
-                       memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3);
-       }
-
-       pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen);
-
-       /*      P2P IE Section. */
-
-       /*      P2P OUI */
-       p2pielen = 0;
-       p2pie[p2pielen++] = 0x50;
-       p2pie[p2pielen++] = 0x6F;
-       p2pie[p2pielen++] = 0x9A;
-       p2pie[p2pielen++] = 0x09;       /*      WFA P2P v1.0 */
-
-       /*      Commented by Albert 20100908 */
-       /*      According to the P2P Specification, the group negotiation response frame should contain 9 P2P attributes */
-       /*      1. Status */
-       /*      2. P2P Capability */
-       /*      3. Group Owner Intent */
-       /*      4. Configuration Timeout */
-       /*      5. Operating Channel */
-       /*      6. Intended P2P Interface Address */
-       /*      7. Channel List */
-       /*      8. Device Info */
-       /*      9. Group ID     (Only GO) */
-
-       /*      ToDo: */
-
-       /*      P2P Status */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_STATUS;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
-       p2pielen += 2;
-
-       /*      Value: */
-       p2pie[p2pielen++] = result;
-
-       /*      P2P Capability */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Device Capability Bitmap, 1 byte */
-
-       if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
-               /*      Commented by Albert 2011/03/08 */
-               /*      According to the P2P specification */
-               /*      if the sending device will be client, the P2P Capability should be reserved of group negotiation response frame */
-               p2pie[p2pielen++] = 0;
-       } else {
-               /*      Be group owner or meet the error case */
-               p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
-       }
-
-       /*      Group Capability Bitmap, 1 byte */
-       if (pwdinfo->persistent_supported) {
-               p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
-       } else {
-               p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
-       }
-
-       /*      Group Owner Intent */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
-       p2pielen += 2;
-
-       /*      Value: */
-       if (pwdinfo->peer_intent & 0x01) {
-               /*      Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
-               p2pie[p2pielen++] = (pwdinfo->intent << 1);
-       } else {
-               /*      Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
-               p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
-       }
-
-       /*      Configuration Timeout */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
-       p2pielen += 2;
-
-       /*      Value: */
-       p2pie[p2pielen++] = 200;        /*      2 seconds needed to be the P2P GO */
-       p2pie[p2pielen++] = 200;        /*      2 seconds needed to be the P2P Client */
-
-       /*      Operating Channel */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Country String */
-       p2pie[p2pielen++] = 'X';
-       p2pie[p2pielen++] = 'X';
-
-       /*      The third byte should be set to 0x04. */
-       /*      Described in the "Operating Channel Attribute" section. */
-       p2pie[p2pielen++] = 0x04;
-
-       /*      Operating Class */
-       p2pie[p2pielen++] = 0x51;
-
-       /*      Channel Number */
-       p2pie[p2pielen++] = pwdinfo->operating_channel; /*      operating channel number */
-
-       /*      Intended P2P Interface Address */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_INTENTED_IF_ADDR;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
-       p2pielen += 2;
-
-       /*      Value: */
-       memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
-       p2pielen += ETH_ALEN;
-
-       /*      Channel List */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
-
-       /*  Country String(3) */
-       /*  + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */
-       /*  + number of channels in all classes */
-       len_channellist_attr = 3
-          + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
-          + get_reg_classes_full_count(&pmlmeext->channel_list);
-
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
-
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Country String */
-       p2pie[p2pielen++] = 'X';
-       p2pie[p2pielen++] = 'X';
-
-       /*      The third byte should be set to 0x04. */
-       /*      Described in the "Operating Channel Attribute" section. */
-       p2pie[p2pielen++] = 0x04;
-
-       /*      Channel Entry List */
-
-       {
-               int i, j;
-               for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
-                       /*      Operating Class */
-                       p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
-
-                       /*      Number of Channels */
-                       p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
-
-                       /*      Channel List */
-                       for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
-                               p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
-                       }
-               }
-       }
-
-       /*      Device Info */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
-
-       /*      Length: */
-       /*      21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
-       /*      + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      P2P Device Address */
-       memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
-       p2pielen += ETH_ALEN;
-
-       /*      Config Method */
-       /*      This field should be big endian. Noted by P2P specification. */
-
-       *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
-
-       p2pielen += 2;
-
-       /*      Primary Device Type */
-       /*      Category ID */
-       *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
-       p2pielen += 2;
-
-       /*      OUI */
-       *(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
-       p2pielen += 4;
-
-       /*      Sub Category ID */
-       *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
-       p2pielen += 2;
-
-       /*      Number of Secondary Device Types */
-       p2pie[p2pielen++] = 0x00;       /*      No Secondary Device Type List */
-
-       /*      Device Name */
-       /*      Type: */
-       *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
-       p2pielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
-       p2pielen += 2;
-
-       /*      Value: */
-       memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
-       p2pielen += pwdinfo->device_name_len;
-
-       if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
-               /*      Group ID Attribute */
-               /*      Type: */
-               p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
-
-               /*      Length: */
-               *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
-               p2pielen += 2;
-
-               /*      Value: */
-               /*      p2P Device Address */
-               memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);
-               p2pielen += ETH_ALEN;
-
-               /*      SSID */
-               memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
-               p2pielen += pwdinfo->nego_ssidlen;
-       }
-
-       pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       dump_mgntframe(padapter, pmgntframe);
-}
-
-static void issue_p2p_GO_confirm(struct adapter *padapter, u8 *raddr, u8 result)
-{
-       unsigned char category = WLAN_CATEGORY_PUBLIC;
-       u8 action = P2P_PUB_ACTION_ACTION;
-       __be32                  p2poui = cpu_to_be32(P2POUI);
-       u8 oui_subtype = P2P_GO_NEGO_CONF;
-       u8 p2pie[255] = { 0x00 };
-       u8 p2pielen = 0;
-
-       struct xmit_frame                       *pmgntframe;
-       struct pkt_attrib                       *pattrib;
-       unsigned char                                   *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       struct xmit_priv                        *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
-       memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
-       memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(pframe, WIFI_ACTION);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &pattrib->pktlen);
-
-       /*      P2P IE Section. */
-
-       /*      P2P OUI */
-       p2pielen = 0;
-       p2pie[p2pielen++] = 0x50;
-       p2pie[p2pielen++] = 0x6F;
-       p2pie[p2pielen++] = 0x9A;
-       p2pie[p2pielen++] = 0x09;       /*      WFA P2P v1.0 */
-
-       /*      Commented by Albert 20110306 */
-       /*      According to the P2P Specification, the group negotiation request frame should contain 5 P2P attributes */
-       /*      1. Status */
-       /*      2. P2P Capability */
-       /*      3. Operating Channel */
-       /*      4. Channel List */
-       /*      5. Group ID     (if this WiFi is GO) */
-
-       /*      P2P Status */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_STATUS;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
-       p2pielen += 2;
-
-       /*      Value: */
-       p2pie[p2pielen++] = result;
-
-       /*      P2P Capability */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Device Capability Bitmap, 1 byte */
-       p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
-
-       /*      Group Capability Bitmap, 1 byte */
-       if (pwdinfo->persistent_supported)
-               p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
-       else
-               p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
-
-       /*      Operating Channel */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Country String */
-       p2pie[p2pielen++] = 'X';
-       p2pie[p2pielen++] = 'X';
-
-       /*      The third byte should be set to 0x04. */
-       /*      Described in the "Operating Channel Attribute" section. */
-       p2pie[p2pielen++] = 0x04;
-
-       if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
-               /*      Operating Class */
-               p2pie[p2pielen++] = 0x51;
-               p2pie[p2pielen++] = pwdinfo->peer_operating_ch;
-       } else {
-               /*      Operating Class */
-               p2pie[p2pielen++] = 0x51;
-
-               /*      Channel Number */
-               p2pie[p2pielen++] = pwdinfo->operating_channel;         /*      Use the listen channel as the operating channel */
-       }
-
-       /*      Channel List */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(pwdinfo->channel_list_attr_len);
-       p2pielen += 2;
-
-       /*      Value: */
-       memcpy(p2pie + p2pielen, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len);
-       p2pielen += pwdinfo->channel_list_attr_len;
-
-       if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
-               /*      Group ID Attribute */
-               /*      Type: */
-               p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
-
-               /*      Length: */
-               *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
-               p2pielen += 2;
-
-               /*      Value: */
-               /*      p2P Device Address */
-               memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);
-               p2pielen += ETH_ALEN;
-
-               /*      SSID */
-               memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
-               p2pielen += pwdinfo->nego_ssidlen;
-       }
-       pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
-       pattrib->last_txcmdsz = pattrib->pktlen;
-       dump_mgntframe(padapter, pmgntframe);
-}
-
-void issue_p2p_invitation_request(struct adapter *padapter, u8 *raddr)
-{
-       unsigned char category = WLAN_CATEGORY_PUBLIC;
-       u8 action = P2P_PUB_ACTION_ACTION;
-       __be32                  p2poui = cpu_to_be32(P2POUI);
-       u8 oui_subtype = P2P_INVIT_REQ;
-       u8 p2pie[255] = { 0x00 };
-       u8 p2pielen = 0;
-       u8 dialogToken = 3;
-       u16 len_channellist_attr = 0;
-       struct xmit_frame                       *pmgntframe;
-       struct pkt_attrib                       *pattrib;
-       unsigned char                                   *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       struct xmit_priv                        *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
-       memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
-       memcpy(pwlanhdr->addr3, raddr,  ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(pframe, WIFI_ACTION);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen);
-
-       /*      P2P IE Section. */
-
-       /*      P2P OUI */
-       p2pielen = 0;
-       p2pie[p2pielen++] = 0x50;
-       p2pie[p2pielen++] = 0x6F;
-       p2pie[p2pielen++] = 0x9A;
-       p2pie[p2pielen++] = 0x09;       /*      WFA P2P v1.0 */
-
-       /*      Commented by Albert 20101011 */
-       /*      According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes */
-       /*      1. Configuration Timeout */
-       /*      2. Invitation Flags */
-       /*      3. Operating Channel    (Only GO) */
-       /*      4. P2P Group BSSID      (Should be included if I am the GO) */
-       /*      5. Channel List */
-       /*      6. P2P Group ID */
-       /*      7. P2P Device Info */
-
-       /*      Configuration Timeout */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
-       p2pielen += 2;
-
-       /*      Value: */
-       p2pie[p2pielen++] = 200;        /*      2 seconds needed to be the P2P GO */
-       p2pie[p2pielen++] = 200;        /*      2 seconds needed to be the P2P Client */
-
-       /*      Invitation Flags */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_INVITATION_FLAGS;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
-       p2pielen += 2;
-
-       /*      Value: */
-       p2pie[p2pielen++] = P2P_INVITATION_FLAGS_PERSISTENT;
-
-       /*      Operating Channel */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Country String */
-       p2pie[p2pielen++] = 'X';
-       p2pie[p2pielen++] = 'X';
-
-       /*      The third byte should be set to 0x04. */
-       /*      Described in the "Operating Channel Attribute" section. */
-       p2pie[p2pielen++] = 0x04;
-
-       /*      Operating Class */
-       p2pie[p2pielen++] = 0x51;
-
-       /*      Channel Number */
-       p2pie[p2pielen++] = pwdinfo->invitereq_info.operating_ch;       /*      operating channel number */
-
-       if (!memcmp(myid(&padapter->eeprompriv), pwdinfo->invitereq_info.go_bssid, ETH_ALEN)) {
-               /*      P2P Group BSSID */
-               /*      Type: */
-               p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
-
-               /*      Length: */
-               *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
-               p2pielen += 2;
-
-               /*      Value: */
-               /*      P2P Device Address for GO */
-               memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN);
-               p2pielen += ETH_ALEN;
-       }
-
-       /*      Channel List */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
-
-       /*      Length: */
-       /*  Country String(3) */
-       /*  + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */
-       /*  + number of channels in all classes */
-       len_channellist_attr = 3
-          + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
-          + get_reg_classes_full_count(&pmlmeext->channel_list);
-
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
-
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Country String */
-       p2pie[p2pielen++] = 'X';
-       p2pie[p2pielen++] = 'X';
-
-       /*      The third byte should be set to 0x04. */
-       /*      Described in the "Operating Channel Attribute" section. */
-       p2pie[p2pielen++] = 0x04;
-
-       /*      Channel Entry List */
-       {
-               int i, j;
-               for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
-                       /*      Operating Class */
-                       p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
-
-                       /*      Number of Channels */
-                       p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
-
-                       /*      Channel List */
-                       for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
-                               p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
-                       }
-               }
-       }
-
-       /*      P2P Group ID */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(6 + pwdinfo->invitereq_info.ssidlen);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      P2P Device Address for GO */
-       memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN);
-       p2pielen += ETH_ALEN;
-
-       /*      SSID */
-       memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen);
-       p2pielen += pwdinfo->invitereq_info.ssidlen;
-
-       /*      Device Info */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
-
-       /*      Length: */
-       /*      21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
-       /*      + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      P2P Device Address */
-       memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
-       p2pielen += ETH_ALEN;
-
-       /*      Config Method */
-       /*      This field should be big endian. Noted by P2P specification. */
-       *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY);
-       p2pielen += 2;
-
-       /*      Primary Device Type */
-       /*      Category ID */
-       *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
-       p2pielen += 2;
-
-       /*      OUI */
-       *(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
-       p2pielen  += 4;
-
-       /*      Sub Category ID */
-       *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
-       p2pielen += 2;
-
-       /*      Number of Secondary Device Types */
-       p2pie[p2pielen++] = 0x00;       /*      No Secondary Device Type List */
-
-       /*      Device Name */
-       /*      Type: */
-       *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
-       p2pielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
-       p2pielen += 2;
-
-       /*      Value: */
-       memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
-       p2pielen += pwdinfo->device_name_len;
-
-       pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       dump_mgntframe(padapter, pmgntframe);
-}
-
-void issue_p2p_invitation_response(struct adapter *padapter, u8 *raddr, u8 dialogToken, u8 status_code)
-{
-       unsigned char category = WLAN_CATEGORY_PUBLIC;
-       u8 action = P2P_PUB_ACTION_ACTION;
-       __be32                  p2poui = cpu_to_be32(P2POUI);
-       u8 oui_subtype = P2P_INVIT_RESP;
-       u8 p2pie[255] = { 0x00 };
-       u8 p2pielen = 0;
-       u16 len_channellist_attr = 0;
-       struct xmit_frame                       *pmgntframe;
-       struct pkt_attrib                       *pattrib;
-       unsigned char                                   *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       struct xmit_priv                        *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
-       memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
-       memcpy(pwlanhdr->addr3, raddr,  ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(pframe, WIFI_ACTION);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen);
-
-       /*      P2P IE Section. */
-
-       /*      P2P OUI */
-       p2pielen = 0;
-       p2pie[p2pielen++] = 0x50;
-       p2pie[p2pielen++] = 0x6F;
-       p2pie[p2pielen++] = 0x9A;
-       p2pie[p2pielen++] = 0x09;       /*      WFA P2P v1.0 */
-
-       /*      Commented by Albert 20101005 */
-       /*      According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
-       /*      1. Status */
-       /*      2. Configuration Timeout */
-       /*      3. Operating Channel    (Only GO) */
-       /*      4. P2P Group BSSID      (Only GO) */
-       /*      5. Channel List */
-
-       /*      P2P Status */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_STATUS;
-
-       /*      Length: */
-       *(__le16  *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE. */
-       /*      Sent the event receiving the P2P Invitation Req frame to DMP UI. */
-       /*      DMP had to compare the MAC address to find out the profile. */
-       /*      So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB. */
-       /*      If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req */
-       /*      to NB to rebuild the persistent group. */
-       p2pie[p2pielen++] = status_code;
-
-       /*      Configuration Timeout */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
-       p2pielen += 2;
-
-       /*      Value: */
-       p2pie[p2pielen++] = 200;        /*      2 seconds needed to be the P2P GO */
-       p2pie[p2pielen++] = 200;        /*      2 seconds needed to be the P2P Client */
-
-       if (status_code == P2P_STATUS_SUCCESS) {
-               if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
-                       /*      The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
-                       /*      In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
-                       /*      First one is operating channel attribute. */
-                       /*      Second one is P2P Group BSSID attribute. */
-
-                       /*      Operating Channel */
-                       /*      Type: */
-                       p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
-
-                       /*      Length: */
-                       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
-                       p2pielen += 2;
-
-                       /*      Value: */
-                       /*      Country String */
-                       p2pie[p2pielen++] = 'X';
-                       p2pie[p2pielen++] = 'X';
-
-                       /*      The third byte should be set to 0x04. */
-                       /*      Described in the "Operating Channel Attribute" section. */
-                       p2pie[p2pielen++] = 0x04;
-
-                       /*      Operating Class */
-                       p2pie[p2pielen++] = 0x51;       /*      Copy from SD7 */
-
-                       /*      Channel Number */
-                       p2pie[p2pielen++] = pwdinfo->operating_channel; /*      operating channel number */
-
-                       /*      P2P Group BSSID */
-                       /*      Type: */
-                       p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
-
-                       /*      Length: */
-                       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
-                       p2pielen += 2;
-
-                       /*      Value: */
-                       /*      P2P Device Address for GO */
-                       memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
-                       p2pielen += ETH_ALEN;
-               }
-
-               /*      Channel List */
-               /*      Type: */
-               p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
-
-               /*      Length: */
-               /*  Country String(3) */
-               /*  + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */
-               /*  + number of channels in all classes */
-               len_channellist_attr = 3
-                       + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
-                       + get_reg_classes_full_count(&pmlmeext->channel_list);
-
-               *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
-               p2pielen += 2;
-
-               /*      Value: */
-               /*      Country String */
-               p2pie[p2pielen++] = 'X';
-               p2pie[p2pielen++] = 'X';
-
-               /*      The third byte should be set to 0x04. */
-               /*      Described in the "Operating Channel Attribute" section. */
-               p2pie[p2pielen++] = 0x04;
-
-               /*      Channel Entry List */
-               {
-                       int i, j;
-                       for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
-                               /*      Operating Class */
-                               p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
-
-                               /*      Number of Channels */
-                               p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
-
-                               /*      Channel List */
-                               for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
-                                       p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
-                               }
-                       }
-               }
-       }
-
-       pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       dump_mgntframe(padapter, pmgntframe);
-}
-
-void issue_p2p_provision_request(struct adapter *padapter, u8 *pssid, u8 ussidlen, u8 *pdev_raddr)
-{
-       unsigned char category = WLAN_CATEGORY_PUBLIC;
-       u8 action = P2P_PUB_ACTION_ACTION;
-       u8 dialogToken = 1;
-       u8 oui_subtype = P2P_PROVISION_DISC_REQ;
-       u8 wpsie[100] = { 0x00 };
-       u8 wpsielen = 0;
-       __be32 p2poui = cpu_to_be32(P2POUI);
-       u32                     p2pielen = 0;
-       struct xmit_frame                       *pmgntframe;
-       struct pkt_attrib                       *pattrib;
-       unsigned char                                   *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       struct xmit_priv                        *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
-       memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
-       memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(pframe, WIFI_ACTION);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen);
-
-       p2pielen = build_prov_disc_request_p2p_ie(pwdinfo, pframe, pssid, ussidlen, pdev_raddr);
-
-       pframe += p2pielen;
-       pattrib->pktlen += p2pielen;
-
-       wpsielen = 0;
-       /*      WPS OUI */
-       *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI);
-       wpsielen += 4;
-
-       /*      WPS version */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
-       wpsielen += 2;
-
-       /*      Value: */
-       wpsie[wpsielen++] = WPS_VERSION_1;      /*      Version 1.0 */
-
-       /*      Config Method */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
-       wpsielen += 2;
-
-       /*      Value: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->tx_prov_disc_info.wps_config_method_request);
-       wpsielen += 2;
-
-       pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen);
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       dump_mgntframe(padapter, pmgntframe);
-}
-
-static u8 is_matched_in_profilelist(u8 *peermacaddr, struct profile_info *profileinfo)
-{
-       u8 i, match_result = 0;
-
-       for (i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++) {
-               if (!memcmp(peermacaddr, profileinfo->peermac, ETH_ALEN)) {
-                       match_result = 1;
-                       break;
-               }
-       }
-       return match_result;
-}
-
-void issue_probersp_p2p(struct adapter *padapter, unsigned char *da)
-{
-       struct xmit_frame                       *pmgntframe;
-       struct pkt_attrib                       *pattrib;
-       unsigned char                                   *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       unsigned char                                   *mac;
-       struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       u16 beacon_interval = 100;
-       u16 capInfo = 0;
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-       u8 wpsie[255] = { 0x00 };
-       u32                                     wpsielen = 0, p2pielen = 0;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       mac = myid(&padapter->eeprompriv);
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-       memcpy(pwlanhdr->addr1, da, ETH_ALEN);
-       memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
-
-       /*      Use the device address for BSSID field. */
-       memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(fctrl, WIFI_PROBERSP);
-
-       pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = pattrib->hdrlen;
-       pframe += pattrib->hdrlen;
-
-       /* timestamp will be inserted by hardware */
-       pframe += 8;
-       pattrib->pktlen += 8;
-
-       /*  beacon interval: 2 bytes */
-       memcpy(pframe, (unsigned char *)&beacon_interval, 2);
-       pframe += 2;
-       pattrib->pktlen += 2;
-
-       /*      capability info: 2 bytes */
-       /*      ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
-       capInfo |= cap_ShortPremble;
-       capInfo |= cap_ShortSlot;
-
-       memcpy(pframe, (unsigned char *)&capInfo, 2);
-       pframe += 2;
-       pattrib->pktlen += 2;
-
-       /*  SSID */
-       pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
-
-       /*  supported rates... */
-       /*      Use the OFDM rate in the P2P probe response frame. (6(B), 9(B), 12, 18, 24, 36, 48, 54) */
-       pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
-
-       /*  DS parameter set */
-       pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
-
-       /*      Todo: WPS IE */
-       /*      Noted by Albert 20100907 */
-       /*      According to the WPS specification, all the WPS attribute is presented by Big Endian. */
-
-       wpsielen = 0;
-       /*      WPS OUI */
-       *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI);
-       wpsielen += 4;
-
-       /*      WPS version */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
-       wpsielen += 2;
-
-       /*      Value: */
-       wpsie[wpsielen++] = WPS_VERSION_1;      /*      Version 1.0 */
-
-       /*      WiFi Simple Config State */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
-       wpsielen += 2;
-
-       /*      Value: */
-       wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG;   /*      Not Configured. */
-
-       /*      Response Type */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
-       wpsielen += 2;
-
-       /*      Value: */
-       wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
-
-       /*      UUID-E */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
-       wpsielen += 2;
-
-       /*      Value: */
-       memcpy(wpsie + wpsielen, myid(&padapter->eeprompriv), ETH_ALEN);
-       wpsielen += 0x10;
-
-       /*      Manufacturer */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
-       wpsielen += 2;
-
-       /*      Value: */
-       memcpy(wpsie + wpsielen, "Realtek", 7);
-       wpsielen += 7;
-
-       /*      Model Name */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
-       wpsielen += 2;
-
-       /*      Value: */
-       memcpy(wpsie + wpsielen, "8188EU", 6);
-       wpsielen += 6;
-
-       /*      Model Number */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
-       wpsielen += 2;
-
-       /*      Value: */
-       wpsie[wpsielen++] = 0x31;               /*      character 1 */
-
-       /*      Serial Number */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
-       wpsielen += 2;
-
-       /*      Value: */
-       memcpy(wpsie + wpsielen, "123456", ETH_ALEN);
-       wpsielen += ETH_ALEN;
-
-       /*      Primary Device Type */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
-       wpsielen += 2;
-
-       /*      Value: */
-       /*      Category ID */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
-       wpsielen += 2;
-
-       /*      OUI */
-       *(__be32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
-       wpsielen += 4;
-
-       /*      Sub Category ID */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
-       wpsielen += 2;
-
-       /*      Device Name */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
-       wpsielen += 2;
-
-       /*      Value: */
-       if (pwdinfo->device_name_len) {
-               memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
-               wpsielen += pwdinfo->device_name_len;
-       }
-
-       /*      Config Method */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
-       wpsielen += 2;
-
-       /*      Value: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
-       wpsielen += 2;
-
-       pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen);
-
-       p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
-       pframe += p2pielen;
-       pattrib->pktlen += p2pielen;
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       dump_mgntframe(padapter, pmgntframe);
-}
-
-inline void issue_probereq_p2p(struct adapter *padapter)
-{
-       struct xmit_frame               *pmgntframe;
-       struct pkt_attrib               *pattrib;
-       unsigned char                   *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       unsigned char                   *mac;
-       struct xmit_priv                *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-       u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
-       u16 wpsielen = 0, p2pielen = 0;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       mac = myid(&padapter->eeprompriv);
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       if ((pwdinfo->p2p_info.scan_op_ch_only) || (pwdinfo->rx_invitereq_info.scan_op_ch_only)) {
-               /*      This two flags will be set when this is only the P2P client mode. */
-               memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
-               memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
-       } else {
-               /*      broadcast probe request frame */
-               eth_broadcast_addr(pwlanhdr->addr1);
-               eth_broadcast_addr(pwlanhdr->addr3);
-       }
-
-       memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(pframe, WIFI_PROBEREQ);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
-               pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &pattrib->pktlen);
-       else
-               pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
-
-       /*      Use the OFDM rate in the P2P probe request frame. (6(B), 9(B), 12(B), 24(B), 36, 48, 54) */
-       pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
-
-       /*      WPS IE */
-       /*      Noted by Albert 20110221 */
-       /*      According to the WPS specification, all the WPS attribute is presented by Big Endian. */
-
-       wpsielen = 0;
-       /*      WPS OUI */
-       *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI);
-       wpsielen += 4;
-
-       /*      WPS version */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
-       wpsielen += 2;
-
-       /*      Value: */
-       wpsie[wpsielen++] = WPS_VERSION_1;      /*      Version 1.0 */
-
-       if (!pmlmepriv->wps_probe_req_ie) {
-               /*      UUID-E */
-               /*      Type: */
-               *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
-               wpsielen += 2;
-
-               /*      Length: */
-               *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
-               wpsielen += 2;
-
-               /*      Value: */
-               memcpy(wpsie + wpsielen, myid(&padapter->eeprompriv), ETH_ALEN);
-               wpsielen += 0x10;
-
-               /*      Config Method */
-               /*      Type: */
-               *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
-               wpsielen += 2;
-
-               /*      Length: */
-               *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
-               wpsielen += 2;
-
-               /*      Value: */
-               *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
-               wpsielen += 2;
-       }
-
-       /*      Device Name */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
-       wpsielen += 2;
-
-       /*      Value: */
-       memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
-       wpsielen += pwdinfo->device_name_len;
-
-       /*      Primary Device Type */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
-       wpsielen += 2;
-
-       /*      Value: */
-       /*      Category ID */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_RTK_WIDI);
-       wpsielen += 2;
-
-       /*      OUI */
-       *(__be32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
-       wpsielen += 4;
-
-       /*      Sub Category ID */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_RTK_DMP);
-       wpsielen += 2;
-
-       /*      Device Password ID */
-       /*      Type: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
-       wpsielen += 2;
-
-       /*      Length: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
-       wpsielen += 2;
-
-       /*      Value: */
-       *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);   /*      Registrar-specified */
-       wpsielen += 2;
-
-       pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen);
-
-       /*      P2P OUI */
-       p2pielen = 0;
-       p2pie[p2pielen++] = 0x50;
-       p2pie[p2pielen++] = 0x6F;
-       p2pie[p2pielen++] = 0x9A;
-       p2pie[p2pielen++] = 0x09;       /*      WFA P2P v1.0 */
-
-       /*      Commented by Albert 20110221 */
-       /*      According to the P2P Specification, the probe request frame should contain 5 P2P attributes */
-       /*      1. P2P Capability */
-       /*      2. P2P Device ID if this probe request wants to find the specific P2P device */
-       /*      3. Listen Channel */
-       /*      4. Extended Listen Timing */
-       /*      5. Operating Channel if this WiFi is working as the group owner now */
-
-       /*      P2P Capability */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Device Capability Bitmap, 1 byte */
-       p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
-
-       /*      Group Capability Bitmap, 1 byte */
-       if (pwdinfo->persistent_supported)
-               p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
-       else
-               p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
-
-       /*      Listen Channel */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Country String */
-       p2pie[p2pielen++] = 'X';
-       p2pie[p2pielen++] = 'X';
-
-       /*      The third byte should be set to 0x04. */
-       /*      Described in the "Operating Channel Attribute" section. */
-       p2pie[p2pielen++] = 0x04;
-
-       /*      Operating Class */
-       p2pie[p2pielen++] = 0x51;       /*      Copy from SD7 */
-
-       /*      Channel Number */
-       p2pie[p2pielen++] = pwdinfo->listen_channel;    /*      listen channel */
-
-       /*      Extended Listen Timing */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
-
-       /*      Length: */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Availability Period */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
-       p2pielen += 2;
-
-       /*      Availability Interval */
-       *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
-       p2pielen += 2;
-
-       if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
-               /*      Operating Channel (if this WiFi is working as the group owner now) */
-               /*      Type: */
-               p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
-
-               /*      Length: */
-               *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
-               p2pielen += 2;
-
-               /*      Value: */
-               /*      Country String */
-               p2pie[p2pielen++] = 'X';
-               p2pie[p2pielen++] = 'X';
-
-               /*      The third byte should be set to 0x04. */
-               /*      Described in the "Operating Channel Attribute" section. */
-               p2pie[p2pielen++] = 0x04;
-
-               /*      Operating Class */
-               p2pie[p2pielen++] = 0x51;       /*      Copy from SD7 */
-
-               /*      Channel Number */
-               p2pie[p2pielen++] = pwdinfo->operating_channel; /*      operating channel number */
-       }
-
-       pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
-
-       if (pmlmepriv->wps_probe_req_ie) {
-               /* WPS IE */
-               memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
-               pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
-               pframe += pmlmepriv->wps_probe_req_ie_len;
-       }
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       dump_mgntframe(padapter, pmgntframe);
-}
-
-static s32 rtw_action_public_decache(struct recv_frame *recv_frame, u8 token)
-{
-       struct adapter *adapter = recv_frame->adapter;
-       struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
-       u8 *frame = recv_frame->rx_data;
-       u16 seq_ctrl = ((recv_frame->attrib.seq_num & 0xffff) << 4) |
-               (recv_frame->attrib.frag_num & 0xf);
-
-       if (GetRetry(frame)) {
-               if ((seq_ctrl == mlmeext->action_public_rxseq) &&
-                   (token == mlmeext->action_public_dialog_token))
-                       return _FAIL;
-       }
-
-       mlmeext->action_public_rxseq = seq_ctrl;
-       mlmeext->action_public_dialog_token = token;
-       return _SUCCESS;
-}
-
-static unsigned int on_action_public_p2p(struct recv_frame *precv_frame)
-{
-       u8 *pframe = precv_frame->rx_data;
-       u8 *frame_body;
-       u8 dialogToken = 0;
-       struct adapter *padapter = precv_frame->adapter;
-       uint len = precv_frame->len;
-       u8 *p2p_ie;
-       u32     p2p_ielen;
-       struct  wifidirect_info *pwdinfo = &padapter->wdinfo;
-       u8      result = P2P_STATUS_SUCCESS;
-       u8      empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-       frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
-
-       dialogToken = frame_body[7];
-
-       if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
-               return _FAIL;
-
-       _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
-       /*      Do nothing if the driver doesn't enable the P2P function. */
-       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
-               return _SUCCESS;
-
-       len -= sizeof(struct ieee80211_hdr_3addr);
-
-       switch (frame_body[6]) { /* OUI Subtype */
-       case P2P_GO_NEGO_REQ:
-               memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
-
-               if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
-                       rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
-
-               if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) {
-                       /*      Commented by Albert 20110526 */
-                       /*      In this case, this means the previous nego fail doesn't be reset yet. */
-                       _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
-                       /*      Restore the previous p2p state */
-                       rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
-               }
-
-               /*      Commented by Kurt 20110902 */
-               /* Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
-               if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
-                       rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
-
-               /*      Commented by Kurt 20120113 */
-               /*      Get peer_dev_addr here if peer doesn't issue prov_disc frame. */
-               if (!memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN))
-                       memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
-
-               result = process_p2p_group_negotation_req(pwdinfo, frame_body, len);
-               issue_p2p_GO_response(padapter, GetAddr2Ptr(pframe), frame_body, len, result);
-
-               /*      Commented by Albert 20110718 */
-               /*      No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer. */
-               _set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
-               break;
-       case P2P_GO_NEGO_RESP:
-               if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
-                       /*      Commented by Albert 20110425 */
-                       /*      The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function. */
-                       _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
-                       pwdinfo->nego_req_info.benable = false;
-                       result = process_p2p_group_negotation_resp(pwdinfo, frame_body, len);
-                       issue_p2p_GO_confirm(pwdinfo->padapter, GetAddr2Ptr(pframe), result);
-                       if (result == P2P_STATUS_SUCCESS) {
-                               if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT) {
-                                       pwdinfo->p2p_info.operation_ch[0] = pwdinfo->peer_operating_ch;
-                                       pwdinfo->p2p_info.scan_op_ch_only = 1;
-                                       _set_timer(&pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH);
-                               }
-                       }
-                       /*      Reset the dialog token for group negotiation frames. */
-                       pwdinfo->negotiation_dialog_token = 1;
-                       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
-                               _set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
-               }
-               break;
-       case P2P_GO_NEGO_CONF:
-               result = process_p2p_group_negotation_confirm(pwdinfo, frame_body, len);
-               if (result == P2P_STATUS_SUCCESS) {
-                       if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT) {
-                               pwdinfo->p2p_info.operation_ch[0] = pwdinfo->peer_operating_ch;
-                               pwdinfo->p2p_info.scan_op_ch_only = 1;
-                               _set_timer(&pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH);
-                       }
-               }
-               break;
-       case P2P_INVIT_REQ:
-               /*      Added by Albert 2010/10/05 */
-               /*      Received the P2P Invite Request frame. */
-
-               p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen);
-               if (p2p_ie) {
-                       /*      Parse the necessary information from the P2P Invitation Request frame. */
-                       /*      For example: The MAC address of sending this P2P Invitation Request frame. */
-                       u32     attr_contentlen = 0;
-                       u8      status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
-                       struct group_id_info group_id;
-                       u8      invitation_flag = 0;
-
-                       rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
-                       if (attr_contentlen) {
-                               rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
-                               /*      Commented by Albert 20120510 */
-                               /*      Copy to the pwdinfo->p2p_peer_interface_addr. */
-                               /*      So that the WFD UI (or Sigma) can get the peer interface address by using the following command. */
-                               /*      #> iwpriv wlan0 p2p_get peer_ifa */
-                               /*      After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant. */
-
-                               if (invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT) {
-                                       /*      Re-invoke the persistent group. */
-
-                                       memset(&group_id, 0x00, sizeof(struct group_id_info));
-                                       rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, (u8 *)&group_id, &attr_contentlen);
-                                       if (attr_contentlen) {
-                                               if (!memcmp(group_id.go_device_addr, myid(&padapter->eeprompriv), ETH_ALEN)) {
-                                                       /*      The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO. */
-                                                       rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO);
-                                                       rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
-                                                       status_code = P2P_STATUS_SUCCESS;
-                                               } else {
-                                                       /*      The p2p device sending this p2p invitation request wants to be the persistent GO. */
-                                                       if (is_matched_in_profilelist(pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[0])) {
-                                                               u8 operatingch_info[5] = { 0x00 };
-                                                               if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) {
-                                                                       if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4])) {
-                                                                               /*      The operating channel is acceptable for this device. */
-                                                                               pwdinfo->rx_invitereq_info.operation_ch[0] = operatingch_info[4];
-                                                                               pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
-                                                                               _set_timer(&pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH);
-                                                                               rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH);
-                                                                               rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
-                                                                               status_code = P2P_STATUS_SUCCESS;
-                                                                       } else {
-                                                                               /*      The operating channel isn't supported by this device. */
-                                                                               rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
-                                                                               rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
-                                                                               status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
-                                                                               _set_timer(&pwdinfo->restore_p2p_state_timer, 3000);
-                                                                       }
-                                                               } else {
-                                                                       /*      Commented by Albert 20121130 */
-                                                                       /*      Intel will use the different P2P IE to store the operating channel information */
-                                                                       /*      Workaround for Intel WiDi 3.5 */
-                                                                       rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH);
-                                                                       rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
-                                                                       status_code = P2P_STATUS_SUCCESS;
-                                                               }
-                                                       } else {
-                                                               rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
-                                                               status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
-                                                       }
-                                               }
-                                       } else {
-                                               status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
-                                       }
-                               } else {
-                                       /*      Received the invitation to join a P2P group. */
-
-                                       memset(&group_id, 0x00, sizeof(struct group_id_info));
-                                       rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, (u8 *)&group_id, &attr_contentlen);
-                                       if (attr_contentlen) {
-                                               if (!memcmp(group_id.go_device_addr, myid(&padapter->eeprompriv), ETH_ALEN)) {
-                                                       /*      In this case, the GO can't be myself. */
-                                                       rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
-                                                       status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
-                                               } else {
-                                                       /*      The p2p device sending this p2p invitation request wants to join an existing P2P group */
-                                                       /*      Commented by Albert 2012/06/28 */
-                                                       /*      In this case, this Wi-Fi device should use the iwpriv command to get the peer device address. */
-                                                       /*      The peer device address should be the destination address for the provisioning discovery request. */
-                                                       /*      Then, this Wi-Fi device should use the iwpriv command to get the peer interface address. */
-                                                       /*      The peer interface address should be the address for WPS mac address */
-                                                       memcpy(pwdinfo->p2p_peer_device_addr, group_id.go_device_addr, ETH_ALEN);
-                                                       rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
-                                                       rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN);
-                                                       status_code = P2P_STATUS_SUCCESS;
-                                               }
-                                       } else {
-                                               status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
-                                       }
-                               }
-                       } else {
-                               status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
-                       }
-
-                       pwdinfo->inviteresp_info.token = frame_body[7];
-                       issue_p2p_invitation_response(padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code);
-               }
-               break;
-       case P2P_INVIT_RESP: {
-               u8      attr_content = 0x00;
-               u32     attr_contentlen = 0;
-
-               _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
-               p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen);
-               if (p2p_ie) {
-                       rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
-
-                       if (attr_contentlen == 1) {
-                               pwdinfo->invitereq_info.benable = false;
-
-                               if (attr_content == P2P_STATUS_SUCCESS) {
-                                       if (!memcmp(pwdinfo->invitereq_info.go_bssid, myid(&padapter->eeprompriv), ETH_ALEN)) {
-                                               rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
-                                       } else {
-                                               rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
-                                       }
-                                       rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_OK);
-                               } else {
-                                       rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
-                                       rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
-                               }
-                       } else {
-                               rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
-                               rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
-                       }
-               } else {
-                       rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
-                       rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
-               }
-
-               if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL))
-                       _set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
-               break;
-       }
-       case P2P_DEVDISC_REQ:
-               process_p2p_devdisc_req(pwdinfo, pframe, len);
-               break;
-       case P2P_DEVDISC_RESP:
-               process_p2p_devdisc_resp(pwdinfo, pframe, len);
-               break;
-       case P2P_PROVISION_DISC_REQ:
-               process_p2p_provdisc_req(pwdinfo, pframe, len);
-               memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
-
-               /* 20110902 Kurt */
-               /* Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
-               if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
-                       rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
-
-               rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
-               _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
-               break;
-       case P2P_PROVISION_DISC_RESP:
-               /*      Commented by Albert 20110707 */
-               /*      Should we check the pwdinfo->tx_prov_disc_info.bsent flag here?? */
-               /*      Commented by Albert 20110426 */
-               /*      The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function. */
-               _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
-               rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
-               process_p2p_provdisc_resp(pwdinfo, pframe);
-               _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
-               break;
-       }
-
-       return _SUCCESS;
-}
-
-static void on_action_public(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data;
-       u8 *frame_body = (u8 *)&mgmt->u;
-
-       /* All members of the action enum start with action_code. */
-       if (mgmt->u.action.u.s1g.action_code == WLAN_PUB_ACTION_VENDOR_SPECIFIC) {
-               if (!memcmp(frame_body + 2, P2P_OUI, 4))
-                       on_action_public_p2p(precv_frame);
-       } else {
-               rtw_action_public_decache(precv_frame, frame_body[2]);
-       }
-}
-
-static void OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       u8 *frame_body;
-       u8 OUI_Subtype;
-       u8 *pframe = precv_frame->rx_data;
-       uint len = precv_frame->len;
-       struct  wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
-
-       if (be32_to_cpu(*((__be32 *)(frame_body + 1))) != P2POUI)
-               return;
-
-       len -= sizeof(struct ieee80211_hdr_3addr);
-       OUI_Subtype = frame_body[5];
-
-       if (OUI_Subtype == P2P_PRESENCE_REQUEST)
-               process_p2p_presence_req(pwdinfo, pframe, len);
-}
-
-static void OnAction(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data;
-
-       if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da))
-               return;
-
-       switch (mgmt->u.action.category) {
-       case WLAN_CATEGORY_BACK:
-               OnAction_back(padapter, precv_frame);
-               break;
-       case WLAN_CATEGORY_PUBLIC:
-               on_action_public(padapter, precv_frame);
-               break;
-       case RTW_WLAN_CATEGORY_P2P:
-               OnAction_p2p(padapter, precv_frame);
-               break;
-       }
-}
-
-struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
-{
-       struct xmit_frame                       *pmgntframe;
-       struct xmit_buf                         *pxmitbuf;
-
-       pmgntframe = rtw_alloc_xmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return NULL;
-
-       pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv);
-       if (!pxmitbuf) {
-               rtw_free_xmitframe(pxmitpriv, pmgntframe);
-               return NULL;
-       }
-       pmgntframe->frame_tag = MGNT_FRAMETAG;
-       pmgntframe->pxmitbuf = pxmitbuf;
-       pmgntframe->buf_addr = pxmitbuf->pbuf;
-       pxmitbuf->priv_data = pmgntframe;
-       return pmgntframe;
-}
-
-void mgt_dispatcher(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       mlme_handler mlme_sta_tbl[] = {
-               OnAssocReq,
-               OnAssocRsp,
-               OnAssocReq,
-               OnAssocRsp,
-               OnProbeReq,
-               OnProbeRsp,
-               NULL,
-               NULL,
-               OnBeacon,
-               NULL,
-               OnDisassoc,
-               OnAuthClient,
-               OnDeAuth,
-               OnAction,
-       };
-       int index;
-       mlme_handler fct;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data;
-       struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, hdr->addr2);
-
-       if (!ieee80211_is_mgmt(hdr->frame_control))
-               return;
-
-       /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
-       if (memcmp(hdr->addr1, myid(&padapter->eeprompriv), ETH_ALEN) &&
-           !is_broadcast_ether_addr(hdr->addr1))
-               return;
-
-       index = (le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_STYPE) >> 4;
-       if (index >= ARRAY_SIZE(mlme_sta_tbl))
-               return;
-       fct = mlme_sta_tbl[index];
-
-       if (psta) {
-               if (ieee80211_has_retry(hdr->frame_control)) {
-                       if (precv_frame->attrib.seq_num == psta->RxMgmtFrameSeqNum)
-                               /* drop the duplicate management frame */
-                               return;
-               }
-               psta->RxMgmtFrameSeqNum = precv_frame->attrib.seq_num;
-       }
-
-       if (ieee80211_is_auth(hdr->frame_control)) {
-               if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
-                       fct = OnAuth;
-               else
-                       fct = OnAuthClient;
-       }
-
-       if (fct)
-               fct(padapter, precv_frame);
-}
-
-/****************************************************************************
-
-Following are some TX functions for WiFi MLME
-
-*****************************************************************************/
-
-void update_mgnt_tx_rate(struct adapter *padapter, u8 rate)
-{
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-
-       pmlmeext->tx_rate = rate;
-}
-
-void update_mgntframe_attrib(struct adapter *padapter, struct pkt_attrib *pattrib)
-{
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-
-       memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib));
-
-       pattrib->hdrlen = 24;
-       pattrib->nr_frags = 1;
-       pattrib->priority = 7;
-       pattrib->mac_id = 0;
-       pattrib->qsel = 0x12;
-
-       pattrib->pktlen = 0;
-
-       if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
-               pattrib->raid = 6;/* b mode */
-       else
-               pattrib->raid = 5;/* a/g mode */
-
-       pattrib->encrypt = _NO_PRIVACY_;
-       pattrib->bswenc = false;
-
-       pattrib->qos_en = false;
-       pattrib->ht_en = false;
-       pattrib->bwmode = HT_CHANNEL_WIDTH_20;
-       pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-       pattrib->sgi = false;
-
-       pattrib->seqnum = pmlmeext->mgnt_seq;
-
-       pattrib->retry_ctrl = true;
-}
-
-void dump_mgntframe(struct adapter *padapter, struct xmit_frame *pmgntframe)
-{
-       rtl8188eu_mgnt_xmit(padapter, pmgntframe);
-}
-
-s32 dump_mgntframe_and_wait(struct adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
-{
-       s32 ret = _FAIL;
-       struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
-       struct submit_ctx sctx;
-
-       if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
-               return ret;
-
-       rtw_sctx_init(&sctx, timeout_ms);
-       pxmitbuf->sctx = &sctx;
-
-       ret = rtl8188eu_mgnt_xmit(padapter, pmgntframe);
-
-       if (ret == _SUCCESS)
-               ret = rtw_sctx_wait(&sctx);
-
-       return ret;
-}
-
-s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, struct xmit_frame *pmgntframe)
-{
-       s32 ret = _FAIL;
-       u32 timeout_ms = 500;/*   500ms */
-       struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
-
-       mutex_lock(&pxmitpriv->ack_tx_mutex);
-       pxmitpriv->ack_tx = true;
-
-       pmgntframe->ack_report = 1;
-       if (rtl8188eu_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) {
-               ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms);
-       }
-
-       pxmitpriv->ack_tx = false;
-       mutex_unlock(&pxmitpriv->ack_tx_mutex);
-
-       return ret;
-}
-
-static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
-{
-       u8 *ssid_ie;
-       int ssid_len_ori;
-       int len_diff = 0;
-
-       ssid_ie = rtw_get_ie(ies,  WLAN_EID_SSID, &ssid_len_ori, ies_len);
-
-       if (ssid_ie && ssid_len_ori > 0) {
-               switch (hidden_ssid_mode) {
-               case 1: {
-                       u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
-                       u32 remain_len = 0;
-
-                       remain_len = ies_len - (next_ie - ies);
-
-                       ssid_ie[1] = 0;
-                       memcpy(ssid_ie + 2, next_ie, remain_len);
-                       len_diff -= ssid_len_ori;
-
-                       break;
-               }
-               case 2:
-                       memset(&ssid_ie[2], 0, ssid_len_ori);
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       return len_diff;
-}
-
-void issue_beacon(struct adapter *padapter, int timeout_ms)
-{
-       struct xmit_frame       *pmgntframe;
-       struct pkt_attrib       *pattrib;
-       unsigned char   *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       unsigned int    rate_len;
-       struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex            *cur_network = &pmlmeinfo->network;
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return;
-       spin_lock_bh(&pmlmepriv->bcn_update_lock);
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-       pattrib->qsel = 0x10;
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       eth_broadcast_addr(pwlanhdr->addr1);
-       memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
-       memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
-       /* pmlmeext->mgnt_seq++; */
-       SetFrameSubType(pframe, WIFI_BEACON);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
-               /*  for P2P : Primary Device Type & Device Name */
-               u32 wpsielen = 0, insert_len = 0;
-               u8 *wpsie = NULL;
-               wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
-
-               if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
-                       uint wps_offset, remainder_ielen;
-                       u8 *premainder_ie, *pframe_wscie;
-
-                       wps_offset = (uint)(wpsie - cur_network->IEs);
-                       premainder_ie = wpsie + wpsielen;
-                       remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
-                       pframe_wscie = pframe + wps_offset;
-                       memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
-                       pframe += (wps_offset + wpsielen);
-                       pattrib->pktlen += (wps_offset + wpsielen);
-
-                       /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
-                       /*      Primary Device Type */
-                       /*      Type: */
-                       *(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
-                       insert_len += 2;
-
-                       /*      Length: */
-                       *(__be16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
-                       insert_len += 2;
-
-                       /*      Value: */
-                       /*      Category ID */
-                       *(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
-                       insert_len += 2;
-
-                       /*      OUI */
-                       *(__be32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
-                       insert_len += 4;
-
-                       /*      Sub Category ID */
-                       *(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
-                       insert_len += 2;
-
-                       /*      Device Name */
-                       /*      Type: */
-                       *(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
-                       insert_len += 2;
-
-                       /*      Length: */
-                       *(__be16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
-                       insert_len += 2;
-
-                       /*      Value: */
-                       memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
-                       insert_len += pwdinfo->device_name_len;
-
-                       /* update wsc ie length */
-                       *(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
-
-                       /* pframe move to end */
-                       pframe += insert_len;
-                       pattrib->pktlen += insert_len;
-
-                       /* copy remainder_ie to pframe */
-                       memcpy(pframe, premainder_ie, remainder_ielen);
-                       pframe += remainder_ielen;
-                       pattrib->pktlen += remainder_ielen;
-               } else {
-                       int len_diff;
-                       memcpy(pframe, cur_network->IEs, cur_network->IELength);
-                       len_diff = update_hidden_ssid(
-                               pframe + _BEACON_IE_OFFSET_
-                               , cur_network->IELength - _BEACON_IE_OFFSET_
-                               , pmlmeinfo->hidden_ssid_mode
-                       );
-                       pframe += (cur_network->IELength + len_diff);
-                       pattrib->pktlen += (cur_network->IELength + len_diff);
-               }
-
-               {
-                       u8 *wps_ie;
-                       uint wps_ielen;
-                       u8 sr = 0;
-                       wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
-                               pattrib->pktlen - sizeof(struct ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
-                       if (wps_ie && wps_ielen > 0)
-                               rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
-                       if (sr != 0)
-                               set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
-                       else
-                               _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
-               }
-
-               if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
-                       u32 len;
-                       len = build_beacon_p2p_ie(pwdinfo, pframe);
-
-                       pframe += len;
-                       pattrib->pktlen += len;
-               }
-
-               goto _issue_bcn;
-       }
-
-       /* below for ad-hoc mode */
-
-       /* timestamp will be inserted by hardware */
-       pframe += 8;
-       pattrib->pktlen += 8;
-
-       /*  beacon interval: 2 bytes */
-
-       memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
-
-       pframe += 2;
-       pattrib->pktlen += 2;
-
-       /*  capability info: 2 bytes */
-
-       memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
-
-       pframe += 2;
-       pattrib->pktlen += 2;
-
-       /*  SSID */
-       pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
-
-       /*  supported rates... */
-       rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
-       pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen);
-
-       /*  DS parameter set */
-       pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&cur_network->Configuration.DSConfig, &pattrib->pktlen);
-
-       {
-               u8 erpinfo = 0;
-               u32 ATIMWindow;
-               /*  IBSS Parameter Set... */
-               ATIMWindow = 0;
-               pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
-
-               /* ERP IE */
-               pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
-       }
-
-       /*  EXTERNDED SUPPORTED RATE */
-       if (rate_len > 8)
-               pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
-       /* todo:HT for adhoc */
-_issue_bcn:
-
-       pmlmepriv->update_bcn = false;
-
-       spin_unlock_bh(&pmlmepriv->bcn_update_lock);
-
-       if ((pattrib->pktlen + TXDESC_SIZE) > 512)
-               return;
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       if (timeout_ms > 0)
-               dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
-       else
-               dump_mgntframe(padapter, pmgntframe);
-}
-
-void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
-{
-       struct xmit_frame                       *pmgntframe;
-       struct pkt_attrib                       *pattrib;
-       unsigned char                                   *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       unsigned char                                   *mac, *bssid;
-       struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
-       u8 *pwps_ie;
-       uint wps_ielen;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex            *cur_network = &pmlmeinfo->network;
-       unsigned int    rate_len;
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       mac = myid(&padapter->eeprompriv);
-       bssid = cur_network->MacAddress;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-       memcpy(pwlanhdr->addr1, da, ETH_ALEN);
-       memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
-       memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(fctrl, WIFI_PROBERSP);
-
-       pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = pattrib->hdrlen;
-       pframe += pattrib->hdrlen;
-
-       if (cur_network->IELength > MAX_IE_SZ)
-               return;
-
-       if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
-               pwps_ie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wps_ielen);
-
-               /* inerset & update wps_probe_resp_ie */
-               if (pmlmepriv->wps_probe_resp_ie && pwps_ie && wps_ielen > 0) {
-                       uint wps_offset, remainder_ielen;
-                       u8 *premainder_ie;
-
-                       wps_offset = (uint)(pwps_ie - cur_network->IEs);
-
-                       premainder_ie = pwps_ie + wps_ielen;
-
-                       remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
-
-                       memcpy(pframe, cur_network->IEs, wps_offset);
-                       pframe += wps_offset;
-                       pattrib->pktlen += wps_offset;
-
-                       wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];/* to get ie data len */
-                       if ((wps_offset + wps_ielen + 2) <= MAX_IE_SZ) {
-                               memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen + 2);
-                               pframe += wps_ielen + 2;
-                               pattrib->pktlen += wps_ielen + 2;
-                       }
-
-                       if ((wps_offset + wps_ielen + 2 + remainder_ielen) <= MAX_IE_SZ) {
-                               memcpy(pframe, premainder_ie, remainder_ielen);
-                               pframe += remainder_ielen;
-                               pattrib->pktlen += remainder_ielen;
-                       }
-               } else {
-                       memcpy(pframe, cur_network->IEs, cur_network->IELength);
-                       pframe += cur_network->IELength;
-                       pattrib->pktlen += cur_network->IELength;
-               }
-       } else {
-               /* timestamp will be inserted by hardware */
-               pframe += 8;
-               pattrib->pktlen += 8;
-
-               /*  beacon interval: 2 bytes */
-
-               memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
-
-               pframe += 2;
-               pattrib->pktlen += 2;
-
-               /*  capability info: 2 bytes */
-
-               memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
-
-               pframe += 2;
-               pattrib->pktlen += 2;
-
-               /* below for ad-hoc mode */
-
-               /*  SSID */
-               pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
-
-               /*  supported rates... */
-               rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
-               pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen);
-
-               /*  DS parameter set */
-               pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&cur_network->Configuration.DSConfig, &pattrib->pktlen);
-
-               if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
-                       u8 erpinfo = 0;
-                       u32 ATIMWindow;
-                       /*  IBSS Parameter Set... */
-                       /* ATIMWindow = cur->Configuration.ATIMWindow; */
-                       ATIMWindow = 0;
-                       pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
-
-                       /* ERP IE */
-                       pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
-               }
-
-               /*  EXTERNDED SUPPORTED RATE */
-               if (rate_len > 8)
-                       pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
-               /* todo:HT for adhoc */
-       }
-
-       if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && is_valid_p2p_probereq) {
-               u32 len;
-               len = build_probe_resp_p2p_ie(pwdinfo, pframe);
-
-               pframe += len;
-               pattrib->pktlen += len;
-       }
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       dump_mgntframe(padapter, pmgntframe);
-}
-
-static int _issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, int wait_ack)
-{
-       int ret = _FAIL;
-       struct xmit_frame               *pmgntframe;
-       struct pkt_attrib               *pattrib;
-       unsigned char                   *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       unsigned char                   *mac;
-       unsigned char                   bssrate[NumRates];
-       struct xmit_priv                *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       int     bssrate_len = 0;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               goto exit;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       mac = myid(&padapter->eeprompriv);
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       if (da) {
-               /*      unicast probe request frame */
-               memcpy(pwlanhdr->addr1, da, ETH_ALEN);
-               memcpy(pwlanhdr->addr3, da, ETH_ALEN);
-       } else {
-               /*      broadcast probe request frame */
-               eth_broadcast_addr(pwlanhdr->addr1);
-               eth_broadcast_addr(pwlanhdr->addr3);
-       }
-
-       memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(pframe, WIFI_PROBEREQ);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       if (pssid)
-               pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &pattrib->pktlen);
-       else
-               pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pattrib->pktlen);
-
-       get_rate_set(padapter, bssrate, &bssrate_len);
-
-       if (bssrate_len > 8) {
-               pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, bssrate, &pattrib->pktlen);
-               pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, bssrate_len - 8, bssrate + 8, &pattrib->pktlen);
-       } else {
-               pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, bssrate_len, bssrate, &pattrib->pktlen);
-       }
-
-       /* add wps_ie for wps2.0 */
-       if (pmlmepriv->wps_probe_req_ie_len > 0 && pmlmepriv->wps_probe_req_ie) {
-               memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
-               pframe += pmlmepriv->wps_probe_req_ie_len;
-               pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
-       }
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       if (wait_ack) {
-               ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
-       } else {
-               dump_mgntframe(padapter, pmgntframe);
-               ret = _SUCCESS;
-       }
-
-exit:
-       return ret;
-}
-
-inline void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da)
-{
-       _issue_probereq(padapter, pssid, da, false);
-}
-
-void issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da)
-{
-       int i;
-
-       for (i = 0; i < 3; i++) {
-               if (_issue_probereq(padapter, pssid, da, true) == _FAIL)
-                       msleep(1);
-               else
-                       break;
-       }
-}
-
-/*  if psta == NULL, indicate we are station (client) now... */
-void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short status)
-{
-       struct xmit_frame *pmgntframe;
-       struct pkt_attrib *pattrib;
-       unsigned char *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       unsigned int val32;
-       u16 val16;
-       __le16 le_val16;
-       int use_shared_key = 0;
-       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(pframe, WIFI_AUTH);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       if (psta) {/*  for AP mode */
-               memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);
-               memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
-               memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN);
-
-               /*  setting auth algo number */
-               val16 = (u16)psta->authalg;
-
-               if (status != _STATS_SUCCESSFUL_)
-                       val16 = 0;
-
-               if (val16) {
-                       le_val16 = cpu_to_le16(val16);
-                       use_shared_key = 1;
-               } else {
-                       le_val16 = 0;
-               }
-
-               pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&le_val16, &pattrib->pktlen);
-
-               /*  setting auth seq number */
-               val16 = (u16)psta->auth_seq;
-               le_val16 = cpu_to_le16(val16);
-               pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&le_val16, &pattrib->pktlen);
-
-               /*  setting status code... */
-               val16 = status;
-               le_val16 = cpu_to_le16(val16);
-               pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&le_val16, &pattrib->pktlen);
-
-               /*  added challenging text... */
-               if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
-                       pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &pattrib->pktlen);
-       } else {
-               __le32 le_tmp32;
-               __le16 le_tmp16;
-               memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
-               memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
-               memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
-
-               /*  setting auth algo number */
-               val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ? 1 : 0;/*  0:OPEN System, 1:Shared key */
-               if (val16)
-                       use_shared_key = 1;
-
-               /* setting IV for auth seq #3 */
-               if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
-                       val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
-                       le_tmp32 = cpu_to_le32(val32);
-                       pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&le_tmp32, &pattrib->pktlen);
-
-                       pattrib->iv_len = 4;
-               }
-
-               le_tmp16 = cpu_to_le16(val16);
-               pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&le_tmp16, &pattrib->pktlen);
-
-               /*  setting auth seq number */
-               val16 = pmlmeinfo->auth_seq;
-               le_tmp16 = cpu_to_le16(val16);
-               pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&le_tmp16, &pattrib->pktlen);
-
-               /*  setting status code... */
-               le_tmp16 = cpu_to_le16(status);
-               pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&le_tmp16, &pattrib->pktlen);
-
-               /*  then checking to see if sending challenging text... */
-               if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
-                       pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &pattrib->pktlen);
-
-                       SetPrivacy(fctrl);
-
-                       pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
-
-                       pattrib->encrypt = _WEP40_;
-
-                       pattrib->icv_len = 4;
-
-                       pattrib->pktlen += pattrib->icv_len;
-               }
-       }
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       rtw_wep_encrypt(padapter, pmgntframe);
-       dump_mgntframe(padapter, pmgntframe);
-}
-
-void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
-{
-       struct xmit_frame       *pmgntframe;
-       struct ieee80211_hdr *pwlanhdr;
-       struct pkt_attrib *pattrib;
-       unsigned char   *pbuf, *pframe;
-       unsigned short val;
-       __le16 *fctrl;
-       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
-       u8 *ie = pnetwork->IEs;
-       __le16 lestatus, leval;
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
-       memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&padapter->eeprompriv), ETH_ALEN);
-       memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
-               SetFrameSubType(pwlanhdr, pkt_type);
-       else
-               return;
-
-       pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen += pattrib->hdrlen;
-       pframe += pattrib->hdrlen;
-
-       /* capability */
-       val = *(unsigned short *)rtw_get_capability_from_ie(ie);
-
-       pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_, (unsigned char *)&val, &pattrib->pktlen);
-
-       lestatus = cpu_to_le16(status);
-       pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&lestatus, &pattrib->pktlen);
-
-       leval = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
-       pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_, (unsigned char *)&leval, &pattrib->pktlen);
-
-       if (pstat->bssratelen <= 8) {
-               pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &pattrib->pktlen);
-       } else {
-               pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &pattrib->pktlen);
-               pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, pstat->bssratelen - 8, pstat->bssrateset + 8, &pattrib->pktlen);
-       }
-
-       if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option)) {
-               uint ie_len = 0;
-
-               /* FILL HT CAP INFO IE */
-               pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
-               if (pbuf && ie_len > 0) {
-                       memcpy(pframe, pbuf, ie_len + 2);
-                       pframe += (ie_len + 2);
-                       pattrib->pktlen += (ie_len + 2);
-               }
-
-               /* FILL HT ADD INFO IE */
-               pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
-               if (pbuf && ie_len > 0) {
-                       memcpy(pframe, pbuf, ie_len + 2);
-                       pframe += (ie_len + 2);
-                       pattrib->pktlen += (ie_len + 2);
-               }
-       }
-
-       /* FILL WMM IE */
-       if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option)) {
-               uint ie_len = 0;
-               unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
-
-               for (pbuf = ie + _BEACON_IE_OFFSET_;; pbuf += (ie_len + 2)) {
-                       pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
-                       if (pbuf && !memcmp(pbuf + 2, WMM_PARA_IE, 6)) {
-                               memcpy(pframe, pbuf, ie_len + 2);
-                               pframe += (ie_len + 2);
-                               pattrib->pktlen += (ie_len + 2);
-                               break;
-                       }
-
-                       if (!pbuf || ie_len == 0)
-                               break;
-               }
-       }
-
-       if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
-               pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6, REALTEK_96B_IE, &pattrib->pktlen);
-
-       /* add WPS IE ie for wps 2.0 */
-       if (pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len > 0) {
-               memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
-
-               pframe += pmlmepriv->wps_assoc_resp_ie_len;
-               pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
-       }
-
-       if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device)) {
-               u32 len;
-
-               len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
-
-               pframe += len;
-               pattrib->pktlen += len;
-       }
-       pattrib->last_txcmdsz = pattrib->pktlen;
-       dump_mgntframe(padapter, pmgntframe);
-}
-
-void issue_assocreq(struct adapter *padapter)
-{
-       int ret = _FAIL;
-       struct xmit_frame       *pmgntframe;
-       struct pkt_attrib       *pattrib;
-       unsigned char           *pframe, *p;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       __le16          le_tmp;
-       unsigned int    i, j, ie_len, index = 0;
-       unsigned char bssrate[NumRates], sta_bssrate[NumRates];
-       struct ndis_802_11_var_ie *pIE;
-       struct registry_priv    *pregpriv = &padapter->registrypriv;
-       struct xmit_priv                *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       int     bssrate_len = 0, sta_bssrate_len = 0;
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-       u8 p2pie[255] = { 0x00 };
-       u16 p2pielen = 0;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               goto exit;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-       memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
-       memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
-       memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(pframe, WIFI_ASSOCREQ);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       /* caps */
-
-       memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
-
-       pframe += 2;
-       pattrib->pktlen += 2;
-
-       /* listen interval */
-       /* todo: listen interval for power saving */
-       le_tmp = cpu_to_le16(3);
-       memcpy(pframe, (unsigned char *)&le_tmp, 2);
-       pframe += 2;
-       pattrib->pktlen += 2;
-
-       /* SSID */
-       pframe = rtw_set_ie(pframe, _SSID_IE_,  pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &pattrib->pktlen);
-
-       /* supported rate & extended supported rate */
-
-       /*  Check if the AP's supported rates are also supported by STA. */
-       get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
-
-       if (pmlmeext->cur_channel == 14)/*  for JAPAN, channel 14 can only uses B Mode(CCK) */
-               sta_bssrate_len = 4;
-
-       for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
-               if (pmlmeinfo->network.SupportedRates[i] == 0)
-                       break;
-
-               /*  Check if the AP's supported rates are also supported by STA. */
-               for (j = 0; j < sta_bssrate_len; j++) {
-                        /*  Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
-                       if ((pmlmeinfo->network.SupportedRates[i] | IEEE80211_BASIC_RATE_MASK)
-                                       == (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK))
-                               break;
-               }
-
-               if (j != sta_bssrate_len)
-                       /*  the rate is supported by STA */
-                       bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
-       }
-
-       bssrate_len = index;
-
-       if (bssrate_len == 0) {
-               rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
-               rtw_free_xmitframe(pxmitpriv, pmgntframe);
-               goto exit; /* don't connect to AP if no joint supported rate */
-       }
-
-       if (bssrate_len > 8) {
-               pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, bssrate, &pattrib->pktlen);
-               pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, bssrate_len - 8, bssrate + 8, &pattrib->pktlen);
-       } else {
-               pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, bssrate_len, bssrate, &pattrib->pktlen);
-       }
-
-       /* RSN */
-       p = rtw_get_ie((pmlmeinfo->network.IEs + sizeof(struct ndis_802_11_fixed_ie)), _RSN_IE_2_, &ie_len, (pmlmeinfo->network.IELength - sizeof(struct ndis_802_11_fixed_ie)));
-       if (p)
-               pframe = rtw_set_ie(pframe, _RSN_IE_2_, ie_len, p + 2, &pattrib->pktlen);
-
-       /* HT caps */
-       if (padapter->mlmepriv.htpriv.ht_option) {
-               p = rtw_get_ie((pmlmeinfo->network.IEs + sizeof(struct ndis_802_11_fixed_ie)), _HT_CAPABILITY_IE_, &ie_len, (pmlmeinfo->network.IELength - sizeof(struct ndis_802_11_fixed_ie)));
-               if (p && !is_ap_in_tkip(padapter)) {
-                       memcpy(&pmlmeinfo->HT_caps, p + 2, sizeof(struct HT_caps_element));
-
-                       /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
-                       if (pregpriv->cbw40_enable == 0)
-                               pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &= cpu_to_le16(~(BIT(6) | BIT(1)));
-                       else
-                               pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(BIT(1));
-
-                       /* todo: disable SM power save mode */
-                       pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x000c);
-
-                       if (pregpriv->rx_stbc)
-                               pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);/* RX STBC One spatial stream */
-                       memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16);
-
-                       pframe = rtw_set_ie(pframe, _HT_CAPABILITY_IE_, ie_len, (u8 *)(&pmlmeinfo->HT_caps), &pattrib->pktlen);
-               }
-       }
-
-       /* vendor specific IE, such as WPA, WMM, WPS */
-       for (i = sizeof(struct ndis_802_11_fixed_ie); i < pmlmeinfo->network.IELength;) {
-               pIE = (struct ndis_802_11_var_ie *)(pmlmeinfo->network.IEs + i);
-
-               switch (pIE->ElementID) {
-               case _VENDOR_SPECIFIC_IE_:
-                       if ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
-                           (!memcmp(pIE->data, WMM_OUI, 4)) ||
-                           (!memcmp(pIE->data, WPS_OUI, 4))) {
-                               if (!padapter->registrypriv.wifi_spec) {
-                                       /* Commented by Kurt 20110629 */
-                                       /* In some older APs, WPS handshake */
-                                       /* would be fail if we append vendor extension information to AP */
-                                       if (!memcmp(pIE->data, WPS_OUI, 4))
-                                               pIE->Length = 14;
-                               }
-                               pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, pIE->Length, pIE->data, &pattrib->pktlen);
-                       }
-                       break;
-               default:
-                       break;
-               }
-               i += (pIE->Length + 2);
-       }
-
-       if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
-               pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6, REALTEK_96B_IE, &pattrib->pktlen);
-
-       if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
-               /*      Should add the P2P IE in the association request frame. */
-               /*      P2P OUI */
-
-               p2pielen = 0;
-               p2pie[p2pielen++] = 0x50;
-               p2pie[p2pielen++] = 0x6F;
-               p2pie[p2pielen++] = 0x9A;
-               p2pie[p2pielen++] = 0x09;       /*      WFA P2P v1.0 */
-
-               /*      Commented by Albert 20101109 */
-               /*      According to the P2P Specification, the association request frame should contain 3 P2P attributes */
-               /*      1. P2P Capability */
-               /*      2. Extended Listen Timing */
-               /*      3. Device Info */
-               /*      Commented by Albert 20110516 */
-               /*      4. P2P Interface */
-
-               /*      P2P Capability */
-               /*      Type: */
-               p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
-               /*      Length: */
-               *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
-               p2pielen += 2;
-
-               /*      Value: */
-               /*      Device Capability Bitmap, 1 byte */
-               p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
-
-               /*      Group Capability Bitmap, 1 byte */
-               if (pwdinfo->persistent_supported)
-                       p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
-               else
-                       p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
-
-               /*      Extended Listen Timing */
-               /*      Type: */
-               p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
-
-               /*      Length: */
-               *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
-               p2pielen += 2;
-
-               /*      Value: */
-               /*      Availability Period */
-               *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
-               p2pielen += 2;
-
-               /*      Availability Interval */
-               *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
-               p2pielen += 2;
-
-               /*      Device Info */
-               /*      Type: */
-               p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
-
-               /*      Length: */
-               /*      21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
-               /*      + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
-               *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
-               p2pielen += 2;
-
-               /*      Value: */
-               /*      P2P Device Address */
-               memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
-               p2pielen += ETH_ALEN;
-
-               /*      Config Method */
-               /*      This field should be big endian. Noted by P2P specification. */
-               if ((pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN) ||
-                   (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN))
-                       *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY);
-               else
-                       *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_PBC);
-
-               p2pielen += 2;
-
-               /*      Primary Device Type */
-               /*      Category ID */
-               *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
-               p2pielen += 2;
-
-               /*      OUI */
-               *(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
-               p2pielen += 4;
-
-               /*      Sub Category ID */
-               *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
-               p2pielen += 2;
-
-               /*      Number of Secondary Device Types */
-               p2pie[p2pielen++] = 0x00;       /*      No Secondary Device Type List */
-
-               /*      Device Name */
-               /*      Type: */
-               *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
-               p2pielen += 2;
-
-               /*      Length: */
-               *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
-               p2pielen += 2;
-
-               /*      Value: */
-               memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
-               p2pielen += pwdinfo->device_name_len;
-
-               /*      P2P Interface */
-               /*      Type: */
-               p2pie[p2pielen++] = P2P_ATTR_INTERFACE;
-
-               /*      Length: */
-               *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x000D);
-               p2pielen += 2;
-
-               /*      Value: */
-               memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);       /*      P2P Device Address */
-               p2pielen += ETH_ALEN;
-
-               p2pie[p2pielen++] = 1;  /*      P2P Interface Address Count */
-
-               memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);       /*      P2P Interface Address List */
-               p2pielen += ETH_ALEN;
-
-               pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
-       }
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-       dump_mgntframe(padapter, pmgntframe);
-
-       ret = _SUCCESS;
-
-exit:
-       if (ret == _SUCCESS)
-               rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
-       else
-               kfree(pmlmepriv->assoc_req);
-}
-
-/* when wait_ack is true, this function should be called at process context */
-static int _issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
-{
-       int ret = _FAIL;
-       struct xmit_frame                       *pmgntframe;
-       struct pkt_attrib                       *pattrib;
-       unsigned char                                   *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       struct xmit_priv        *pxmitpriv;
-       struct mlme_ext_priv    *pmlmeext;
-       struct mlme_ext_info    *pmlmeinfo;
-
-       if (!padapter)
-               goto exit;
-
-       pxmitpriv = &padapter->xmitpriv;
-       pmlmeext = &padapter->mlmeextpriv;
-       pmlmeinfo = &pmlmeext->mlmext_info;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               goto exit;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-       pattrib->retry_ctrl = false;
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
-               SetFrDs(fctrl);
-       else if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
-               SetToDs(fctrl);
-
-       if (power_mode)
-               SetPwrMgt(fctrl);
-
-       memcpy(pwlanhdr->addr1, da, ETH_ALEN);
-       memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
-       memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(pframe, WIFI_DATA_NULL);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       if (wait_ack) {
-               ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
-       } else {
-               dump_mgntframe(padapter, pmgntframe);
-               ret = _SUCCESS;
-       }
-
-exit:
-       return ret;
-}
-
-/* when wait_ms > 0, this function should be called at process context */
-/* da == NULL for station mode */
-int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
-{
-       int ret;
-       int i = 0;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       /* da == NULL, assume it's null data for sta to ap*/
-       if (!da)
-               da = get_my_bssid(&pmlmeinfo->network);
-
-       do {
-               ret = _issue_nulldata(padapter, da, power_mode, wait_ms > 0);
-
-               i++;
-
-               if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
-                       break;
-
-               if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
-                       msleep(wait_ms);
-       } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
-
-       if (ret != _FAIL) {
-               ret = _SUCCESS;
-               goto exit;
-       }
-exit:
-       return ret;
-}
-
-/* when wait_ack is true, this function should be called at process context */
-static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int wait_ack)
-{
-       int ret = _FAIL;
-       struct xmit_frame                       *pmgntframe;
-       struct pkt_attrib                       *pattrib;
-       unsigned char                                   *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       unsigned short *qc;
-       struct xmit_priv                        *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               goto exit;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       pattrib->hdrlen += 2;
-       pattrib->qos_en = true;
-       pattrib->eosp = 1;
-       pattrib->ack_policy = 0;
-       pattrib->mdata = 0;
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
-               SetFrDs(fctrl);
-       else if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
-               SetToDs(fctrl);
-
-       qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
-
-       SetPriority(qc, tid);
-
-       SetEOSP(qc, pattrib->eosp);
-
-       SetAckpolicy(qc, pattrib->ack_policy);
-
-       memcpy(pwlanhdr->addr1, da, ETH_ALEN);
-       memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
-       memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
-
-       pframe += sizeof(struct ieee80211_qos_hdr);
-       pattrib->pktlen = sizeof(struct ieee80211_qos_hdr);
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       if (wait_ack) {
-               ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
-       } else {
-               dump_mgntframe(padapter, pmgntframe);
-               ret = _SUCCESS;
-       }
-
-exit:
-       return ret;
-}
-
-/* when wait_ms > 0 , this function should be called at process context */
-/* da == NULL for station mode */
-int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
-{
-       int ret;
-       int i = 0;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       /* da == NULL, assume it's null data for sta to ap*/
-       if (!da)
-               da = get_my_bssid(&pmlmeinfo->network);
-
-       do {
-               ret = _issue_qos_nulldata(padapter, da, tid, wait_ms > 0);
-
-               i++;
-
-               if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
-                       break;
-
-               if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
-                       msleep(wait_ms);
-       } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
-
-       if (ret != _FAIL) {
-               ret = _SUCCESS;
-               goto exit;
-       }
-exit:
-       return ret;
-}
-
-static int _issue_deauth(struct adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack)
-{
-       struct xmit_frame                       *pmgntframe;
-       struct pkt_attrib                       *pattrib;
-       unsigned char                                   *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       struct xmit_priv                        *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       int ret = _FAIL;
-       __le16 le_tmp;
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       if (!(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) && (pwdinfo->rx_invitereq_info.scan_op_ch_only)) {
-               _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
-               _set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
-       }
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               goto exit;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-       pattrib->retry_ctrl = false;
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       memcpy(pwlanhdr->addr1, da, ETH_ALEN);
-       memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
-       memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(pframe, WIFI_DEAUTH);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       le_tmp = cpu_to_le16(reason);
-       pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_, (unsigned char *)&le_tmp, &pattrib->pktlen);
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       if (wait_ack) {
-               ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
-       } else {
-               dump_mgntframe(padapter, pmgntframe);
-               ret = _SUCCESS;
-       }
-
-exit:
-       return ret;
-}
-
-int issue_deauth(struct adapter *padapter, unsigned char *da, unsigned short reason)
-{
-       return _issue_deauth(padapter, da, reason, false);
-}
-
-int issue_deauth_ex(struct adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
-       int wait_ms)
-{
-       int ret;
-       int i = 0;
-
-       do {
-               ret = _issue_deauth(padapter, da, reason, wait_ms > 0);
-
-               i++;
-
-               if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
-                       break;
-
-               if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
-                       msleep(wait_ms);
-       } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
-
-       if (ret != _FAIL) {
-               ret = _SUCCESS;
-               goto exit;
-       }
-exit:
-       return ret;
-}
-
-void issue_action_BA(struct adapter *padapter, unsigned char *raddr, u8 action,
-                    u16 status, struct ieee80211_mgmt *mgmt_req)
-{
-       u16 start_seq;
-       u16 BA_starting_seqctrl = 0;
-       struct xmit_frame *pmgntframe;
-       struct pkt_attrib *pattrib;
-       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct sta_info *psta;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       struct registry_priv *pregpriv = &padapter->registrypriv;
-       struct ieee80211_mgmt *mgmt;
-       u16 capab, params;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       mgmt = (struct ieee80211_mgmt *)(pmgntframe->buf_addr + TXDESC_OFFSET);
-
-       mgmt->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION | IEEE80211_FTYPE_MGMT);
-
-       memcpy(mgmt->da, raddr, ETH_ALEN);
-       memcpy(mgmt->sa, myid(&padapter->eeprompriv), ETH_ALEN);
-       memcpy(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
-
-       mgmt->seq_ctrl = cpu_to_le16(pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-
-       mgmt->u.action.category = WLAN_CATEGORY_BACK;
-
-       switch (action) {
-       case WLAN_ACTION_ADDBA_REQ:
-               mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
-               do {
-                       pmlmeinfo->dialogToken++;
-               } while (pmlmeinfo->dialogToken == 0);
-               mgmt->u.action.u.addba_req.dialog_token = pmlmeinfo->dialogToken;
-
-               /* immediate ack & 64 buffer size */
-               capab = u16_encode_bits(64, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK);
-               capab |= u16_encode_bits(1, IEEE80211_ADDBA_PARAM_POLICY_MASK);
-               capab |= u16_encode_bits(status, IEEE80211_ADDBA_PARAM_TID_MASK);
-               mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
-
-               mgmt->u.action.u.addba_req.timeout = cpu_to_le16(5000); /* 5 ms */
-
-               psta = rtw_get_stainfo(pstapriv, raddr);
-               if (psta) {
-                       start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07] & 0xfff) + 1;
-
-                       psta->BA_starting_seqctrl[status & 0x07] = start_seq;
-
-                       BA_starting_seqctrl = start_seq << 4;
-               }
-               mgmt->u.action.u.addba_req.start_seq_num = cpu_to_le16(BA_starting_seqctrl);
-
-               pattrib->pktlen = offsetofend(struct ieee80211_mgmt,
-                                             u.action.u.addba_req.start_seq_num);
-               break;
-       case WLAN_ACTION_ADDBA_RESP:
-               mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP;
-               mgmt->u.action.u.addba_resp.dialog_token = mgmt_req->u.action.u.addba_req.dialog_token;
-               mgmt->u.action.u.addba_resp.status = cpu_to_le16(status);
-               capab = le16_to_cpu(mgmt_req->u.action.u.addba_req.capab) & 0x3f;
-               capab |= u16_encode_bits(64, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK);
-               capab |= u16_encode_bits(pregpriv->ampdu_amsdu, IEEE80211_ADDBA_PARAM_AMSDU_MASK);
-               mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
-               mgmt->u.action.u.addba_resp.timeout = mgmt_req->u.action.u.addba_req.timeout;
-               pattrib->pktlen = offsetofend(struct ieee80211_mgmt, u.action.u.addba_resp.timeout);
-               break;
-       case WLAN_ACTION_DELBA:
-               mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA;
-               mgmt->u.action.u.delba.params = cpu_to_le16((status & 0x1F) << 3);
-               params = u16_encode_bits((status & 0x1), IEEE80211_DELBA_PARAM_INITIATOR_MASK);
-               params |= u16_encode_bits((status >> 1) & 0xF, IEEE80211_DELBA_PARAM_TID_MASK);
-               mgmt->u.action.u.delba.params = cpu_to_le16(params);
-               mgmt->u.action.u.delba.reason_code = cpu_to_le16(WLAN_STATUS_REQUEST_DECLINED);
-               pattrib->pktlen = offsetofend(struct ieee80211_mgmt, u.action.u.delba.reason_code);
-               break;
-       default:
-               break;
-       }
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       dump_mgntframe(padapter, pmgntframe);
-}
-
-static void issue_action_BSSCoexistPacket(struct adapter *padapter)
-{
-       struct list_head *plist, *phead;
-       unsigned char category, action;
-       struct xmit_frame                       *pmgntframe;
-       struct pkt_attrib                       *pattrib;
-       unsigned char                           *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       struct  wlan_network    *pnetwork = NULL;
-       struct xmit_priv                        *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct __queue *queue   = &pmlmepriv->scanned_queue;
-       u8 InfoContent[16] = {0};
-       u8 ICS[8][15];
-       if ((pmlmepriv->num_FortyMHzIntolerant == 0) || (pmlmepriv->num_sta_no_ht == 0))
-               return;
-
-       if (pmlmeinfo->bwmode_updated)
-               return;
-
-       category = WLAN_CATEGORY_PUBLIC;
-       action = ACT_PUBLIC_BSSCOEXIST;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
-       memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
-       memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(pframe, WIFI_ACTION);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
-
-       /*  */
-       if (pmlmepriv->num_FortyMHzIntolerant > 0) {
-               u8 iedata = 0;
-
-               iedata |= BIT(2);/* 20 MHz BSS Width Request */
-
-               pframe = rtw_set_ie(pframe, EID_BSSCoexistence,  1, &iedata, &pattrib->pktlen);
-       }
-
-       /*  */
-       memset(ICS, 0, sizeof(ICS));
-       if (pmlmepriv->num_sta_no_ht > 0) {
-               int i;
-
-               spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-
-               phead = get_list_head(queue);
-               plist = phead->next;
-
-               while (phead != plist) {
-                       int len;
-                       u8 *p;
-                       struct wlan_bssid_ex *pbss_network;
-
-                       pnetwork = container_of(plist, struct wlan_network, list);
-
-                       plist = plist->next;
-
-                       pbss_network = (struct wlan_bssid_ex *)&pnetwork->network;
-
-                       p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
-                       if (!p || len == 0) { /* non-HT */
-                               if ((pbss_network->Configuration.DSConfig <= 0) || (pbss_network->Configuration.DSConfig > 14))
-                                       continue;
-
-                               ICS[0][pbss_network->Configuration.DSConfig] = 1;
-
-                               if (ICS[0][0] == 0)
-                                       ICS[0][0] = 1;
-                       }
-               }
-               spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
-               for (i = 0; i < 8; i++) {
-                       if (ICS[i][0] == 1) {
-                               int j, k = 0;
-
-                               InfoContent[k] = i;
-                               /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */
-                               k++;
-
-                               for (j = 1; j <= 14; j++) {
-                                       if (ICS[i][j] == 1) {
-                                               if (k < 16) {
-                                                       InfoContent[k] = j; /* channel number */
-                                                       /* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */
-                                                       k++;
-                                               }
-                                       }
-                               }
-
-                               pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &pattrib->pktlen);
-                       }
-               }
-       }
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       dump_mgntframe(padapter, pmgntframe);
-}
-
-unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr)
-{
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       struct sta_info *psta = NULL;
-       /* struct recv_reorder_ctrl *preorder_ctrl; */
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       u16 tid;
-
-       if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
-               if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
-                       return _SUCCESS;
-
-       psta = rtw_get_stainfo(pstapriv, addr);
-       if (!psta)
-               return _SUCCESS;
-
-       if (initiator == 0) { /*  recipient */
-               for (tid = 0; tid < MAXTID; tid++) {
-                       if (psta->recvreorder_ctrl[tid].enable) {
-                               issue_action_BA(padapter, addr, WLAN_ACTION_DELBA,
-                                               (((tid << 1) | initiator) & 0x1F), NULL);
-                               psta->recvreorder_ctrl[tid].enable = false;
-                               psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
-                       }
-               }
-       } else if (initiator == 1) { /*  originator */
-               for (tid = 0; tid < MAXTID; tid++) {
-                       if (psta->htpriv.agg_enable_bitmap & BIT(tid)) {
-                               issue_action_BA(padapter, addr, WLAN_ACTION_DELBA,
-                                               (((tid << 1) | initiator) & 0x1F), NULL);
-                               psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
-                               psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
-                       }
-               }
-       }
-
-       return _SUCCESS;
-}
-
-unsigned int send_beacon(struct adapter *padapter)
-{
-       bool bxmitok = false;
-       int     issue = 0;
-       int poll = 0;
-
-       clear_beacon_valid_bit(padapter);
-
-       do {
-               issue_beacon(padapter, 100);
-               issue++;
-               do {
-                       yield();
-                       bxmitok = get_beacon_valid_bit(padapter);
-                       poll++;
-               } while ((poll % 10) != 0 && !bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
-       } while (!bxmitok && issue < 100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
-
-       if (padapter->bSurpriseRemoved || padapter->bDriverStopped || !bxmitok)
-               return _FAIL;
-
-       return _SUCCESS;
-}
-
-bool get_beacon_valid_bit(struct adapter *adapter)
-{
-       int res;
-       u8 reg;
-
-       res = rtw_read8(adapter, REG_TDECTRL + 2, &reg);
-       if (res)
-               return false;
-
-       /* BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2 */
-       return BIT(0) & reg;
-}
-
-void clear_beacon_valid_bit(struct adapter *adapter)
-{
-       int res;
-       u8 reg;
-
-       res = rtw_read8(adapter, REG_TDECTRL + 2, &reg);
-       if (res)
-               return;
-
-       /* BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
-       rtw_write8(adapter, REG_TDECTRL + 2, reg | BIT(0));
-}
-
-void rtw_resume_tx_beacon(struct adapter *adapt)
-{
-       struct hal_data_8188e *haldata = &adapt->haldata;
-
-       /*  2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
-       /*  which should be read from register to a global variable. */
-
-       rtw_write8(adapt, REG_FWHW_TXQ_CTRL + 2, (haldata->RegFwHwTxQCtrl) | BIT(6));
-       haldata->RegFwHwTxQCtrl |= BIT(6);
-       rtw_write8(adapt, REG_TBTT_PROHIBIT + 1, 0xff);
-       haldata->RegReg542 |= BIT(0);
-       rtw_write8(adapt, REG_TBTT_PROHIBIT + 2, haldata->RegReg542);
-}
-
-void rtw_stop_tx_beacon(struct adapter *adapt)
-{
-       struct hal_data_8188e *haldata = &adapt->haldata;
-
-       /*  2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
-       /*  which should be read from register to a global variable. */
-
-       rtw_write8(adapt, REG_FWHW_TXQ_CTRL + 2, (haldata->RegFwHwTxQCtrl) & (~BIT(6)));
-       haldata->RegFwHwTxQCtrl &= (~BIT(6));
-       rtw_write8(adapt, REG_TBTT_PROHIBIT + 1, 0x64);
-       haldata->RegReg542 &= ~(BIT(0));
-       rtw_write8(adapt, REG_TBTT_PROHIBIT + 2, haldata->RegReg542);
-
-        /* todo: CheckFwRsvdPageContent(Adapter);  2010.06.23. Added by tynli. */
-}
-
-static void rtw_set_opmode(struct adapter *adapter, u8 mode)
-{
-       u8 val8;
-       int res;
-
-       /*  disable Port0 TSF update */
-       res = rtw_read8(adapter, REG_BCN_CTRL, &val8);
-       if (res)
-               return;
-
-       rtw_write8(adapter, REG_BCN_CTRL, val8 | BIT(4));
-
-       /*  set net_type */
-       res = rtw_read8(adapter, MSR, &val8);
-       if (res)
-               return;
-
-       val8 &= 0x0c;
-       val8 |= mode;
-       rtw_write8(adapter, MSR, val8);
-
-       if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
-               rtw_stop_tx_beacon(adapter);
-
-               rtw_write8(adapter, REG_BCN_CTRL, 0x19);/* disable atim wnd */
-       } else if (mode == _HW_STATE_ADHOC_) {
-               rtw_resume_tx_beacon(adapter);
-               rtw_write8(adapter, REG_BCN_CTRL, 0x1a);
-       } else if (mode == _HW_STATE_AP_) {
-               rtw_resume_tx_beacon(adapter);
-
-               rtw_write8(adapter, REG_BCN_CTRL, 0x12);
-
-               /* Set RCR */
-               rtw_write32(adapter, REG_RCR, 0x7000208e);/* CBSSID_DATA must set to 0,reject ICV_ERR packet */
-               /* enable to rx data frame */
-               rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
-               /* enable to rx ps-poll */
-               rtw_write16(adapter, REG_RXFLTMAP1, 0x0400);
-
-               /* Beacon Control related register for first time */
-               rtw_write8(adapter, REG_BCNDMATIM, 0x02); /*  2ms */
-
-               rtw_write8(adapter, REG_ATIMWND, 0x0a); /*  10ms */
-               rtw_write16(adapter, REG_BCNTCFG, 0x00);
-               rtw_write16(adapter, REG_TBTT_PROHIBIT, 0xff04);
-               rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/*  +32767 (~32ms) */
-
-               /* reset TSF */
-               rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
-
-               /* BIT(3) - If set 0, hw will clr bcnq when tx becon ok/fail or port 0 */
-               res = rtw_read8(adapter, REG_MBID_NUM, &val8);
-               if (res)
-                       return;
-
-               rtw_write8(adapter, REG_MBID_NUM, val8 | BIT(3) | BIT(4));
-
-               /* enable BCN0 Function for if1 */
-               /* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */
-               rtw_write8(adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP | EN_BCN_FUNCTION | BIT(1)));
-
-               /* dis BCN1 ATIM  WND if if2 is station */
-               res = rtw_read8(adapter, REG_BCN_CTRL_1, &val8);
-               if (res)
-                       return;
-
-               rtw_write8(adapter, REG_BCN_CTRL_1, val8 | BIT(0));
-       }
-}
-
-/****************************************************************************
-
-Following are some utility functions for WiFi MLME
-
-*****************************************************************************/
-
-static void rtw_set_initial_gain(struct adapter *adapter, u8 gain)
-{
-       struct hal_data_8188e *haldata = &adapter->haldata;
-       struct odm_dm_struct *odmpriv = &haldata->odmpriv;
-       struct rtw_dig *digtable = &odmpriv->DM_DigTable;
-
-       if (gain == 0xff) {
-               /* restore rx gain */
-               ODM_Write_DIG(odmpriv, digtable->BackupIGValue);
-       } else {
-               digtable->BackupIGValue = digtable->CurIGValue;
-               ODM_Write_DIG(odmpriv, gain);
-       }
-}
-
-void rtw_mlme_under_site_survey(struct adapter *adapter)
-{
-       /* config RCR to receive different BSSID & not to receive data frame */
-
-       int res;
-       u8 reg;
-       u32 v;
-
-       res = rtw_read32(adapter, REG_RCR, &v);
-       if (res)
-               return;
-
-       v &= ~(RCR_CBSSID_BCN);
-       rtw_write32(adapter, REG_RCR, v);
-       /* reject all data frame */
-       rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
-
-       /* disable update TSF */
-       res = rtw_read8(adapter, REG_BCN_CTRL, &reg);
-       if (res)
-               return;
-
-       rtw_write8(adapter, REG_BCN_CTRL, reg | BIT(4));
-}
-
-void rtw_mlme_site_survey_done(struct adapter *adapter)
-{
-       struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
-       struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-       u32 reg32;
-       int res;
-       u8 reg;
-
-       if ((r8188eu_is_client_associated_to_ap(adapter)) ||
-           ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) {
-               /* enable to rx data frame */
-               rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
-
-               /* enable update TSF */
-               res = rtw_read8(adapter, REG_BCN_CTRL, &reg);
-               if (res)
-                       return;
-
-               rtw_write8(adapter, REG_BCN_CTRL, reg & (~BIT(4)));
-       } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
-               rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
-               /* enable update TSF */
-               res = rtw_read8(adapter, REG_BCN_CTRL, &reg);
-               if (res)
-                       return;
-
-               rtw_write8(adapter, REG_BCN_CTRL, reg & (~BIT(4)));
-       }
-
-       res = rtw_read32(adapter, REG_RCR, &reg32);
-       if (res)
-               return;
-
-       rtw_write32(adapter, REG_RCR, reg32 | RCR_CBSSID_BCN);
-}
-
-void site_survey(struct adapter *padapter)
-{
-       unsigned char survey_channel = 0;
-       enum rt_scan_type ScanType = SCAN_PASSIVE;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       if ((pwdinfo->rx_invitereq_info.scan_op_ch_only) || (pwdinfo->p2p_info.scan_op_ch_only)) {
-               if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
-                       survey_channel = pwdinfo->rx_invitereq_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
-               } else {
-                       survey_channel = pwdinfo->p2p_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
-               }
-               ScanType = SCAN_ACTIVE;
-       } else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) {
-               /*      Commented by Albert 2011/06/03 */
-               /*      The driver is in the find phase, it should go through the social channel. */
-               int ch_set_idx;
-               survey_channel = pwdinfo->social_chan[pmlmeext->sitesurvey_res.channel_idx];
-               ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, survey_channel);
-               if (ch_set_idx >= 0)
-                       ScanType = pmlmeext->channel_set[ch_set_idx].ScanType;
-               else
-                       ScanType = SCAN_ACTIVE;
-       } else {
-               struct rtw_ieee80211_channel *ch;
-               if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) {
-                       ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
-                       survey_channel = ch->hw_value;
-                       ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
-               }
-       }
-
-       if (survey_channel != 0) {
-               if (pmlmeext->sitesurvey_res.channel_idx == 0)
-                       set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
-               else
-                       SelectChannel(padapter, survey_channel);
-
-               if (ScanType == SCAN_ACTIVE) { /* obey the channel plan setting... */
-                       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) ||
-                           rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)) {
-                               issue_probereq_p2p(padapter);
-                               issue_probereq_p2p(padapter);
-                               issue_probereq_p2p(padapter);
-                       } else {
-                               int i;
-                               for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
-                                       if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
-                                               /* todo: to issue two probe req??? */
-                                               issue_probereq(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
-                                               /* msleep(SURVEY_TO>>1); */
-                                               issue_probereq(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
-                                       }
-                               }
-
-                               if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
-                                       /* todo: to issue two probe req??? */
-                                       issue_probereq(padapter, NULL, NULL);
-                                       /* msleep(SURVEY_TO>>1); */
-                                       issue_probereq(padapter, NULL, NULL);
-                               }
-                       }
-               }
-
-               set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
-       } else {
-               /*      channel number is 0 or this channel is not valid. */
-               if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)) {
-                       if ((pwdinfo->rx_invitereq_info.scan_op_ch_only) || (pwdinfo->p2p_info.scan_op_ch_only)) {
-                               /*      Set the find_phase_state_exchange_cnt to P2P_FINDPHASE_EX_CNT. */
-                               /*      This will let the following flow to run the scanning end. */
-                               rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
-                       }
-               }
-
-               if (rtw_p2p_findphase_ex_is_needed(pwdinfo)) {
-                       /*      Set the P2P State to the listen state of find phase and set the current channel to the listen channel */
-                       set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
-                       rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
-                       pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
-
-                       /* restore RX GAIN */
-                       rtw_set_initial_gain(padapter, 0xff);
-                       /* turn on dynamic functions */
-                       Restore_DM_Func_Flag(padapter);
-                       /* Switch_DM_Func(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, true); */
-
-                       _set_timer(&pwdinfo->find_phase_timer, (u32)((u32)(pwdinfo->listen_dwell) * 100));
-               } else {
-                       /*  20100721:Interrupt scan operation here. */
-                       /*  For SW antenna diversity before link, it needs to switch to another antenna and scan again. */
-                       /*  It compares the scan result and selects a better one to do connection. */
-                       if (AntDivBeforeLink8188E(padapter)) {
-                               pmlmeext->sitesurvey_res.bss_cnt = 0;
-                               pmlmeext->sitesurvey_res.channel_idx = -1;
-                               pmlmeext->chan_scan_time = SURVEY_TO / 2;
-                               set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
-                               return;
-                       }
-                       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
-                               rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
-                       rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
-
-                       pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
-
-                       /* switch back to the original channel */
-
-                       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN))
-                               set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
-                       else
-                               set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-
-                       /* config MSR */
-                       Set_MSR(padapter, (pmlmeinfo->state & 0x3));
-
-                       /* restore RX GAIN */
-                       rtw_set_initial_gain(padapter, 0xff);
-                       /* turn on dynamic functions */
-                       Restore_DM_Func_Flag(padapter);
-                       /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); */
-
-                       if (r8188eu_is_client_associated_to_ap(padapter))
-                               issue_nulldata(padapter, NULL, 0, 3, 500);
-
-                       rtw_mlme_site_survey_done(padapter);
-
-                       report_surveydone_event(padapter);
-
-                       pmlmeext->chan_scan_time = SURVEY_TO;
-                       pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
-
-                       issue_action_BSSCoexistPacket(padapter);
-                       issue_action_BSSCoexistPacket(padapter);
-                       issue_action_BSSCoexistPacket(padapter);
-               }
-       }
-}
-
-/* collect bss info from Beacon and Probe request/response frames. */
-u8 collect_bss_info(struct adapter *padapter, struct recv_frame *precv_frame, struct wlan_bssid_ex *bssid)
-{
-       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data;
-       int     i;
-       u32     len;
-       u8 *p;
-       u16 val16;
-       u8 *pframe = precv_frame->rx_data;
-       u32     packet_len = precv_frame->len;
-       u8 ie_offset;
-       struct registry_priv    *pregistrypriv = &padapter->registrypriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       __le32 le32_tmp;
-
-       len = packet_len - sizeof(struct ieee80211_hdr_3addr);
-
-       if (len > MAX_IE_SZ)
-               return _FAIL;
-
-       memset(bssid, 0, sizeof(struct wlan_bssid_ex));
-
-       if (ieee80211_is_beacon(mgmt->frame_control)) {
-               bssid->Reserved[0] = 1;
-               ie_offset = _BEACON_IE_OFFSET_;
-       } else if (ieee80211_is_probe_req(mgmt->frame_control)) {
-               ie_offset = _PROBEREQ_IE_OFFSET_;
-               bssid->Reserved[0] = 2;
-       } else if (ieee80211_is_probe_resp(mgmt->frame_control)) {
-               ie_offset = _PROBERSP_IE_OFFSET_;
-               bssid->Reserved[0] = 3;
-       } else {
-               bssid->Reserved[0] = 0;
-               ie_offset = _FIXED_IE_LENGTH_;
-       }
-
-       bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len;
-
-       /* below is to copy the information element */
-       bssid->IELength = len;
-       memcpy(bssid->IEs, (pframe + sizeof(struct ieee80211_hdr_3addr)), bssid->IELength);
-
-       /* get the signal strength */
-       bssid->Rssi = precv_frame->attrib.phy_info.recvpower; /*  in dBM.raw data */
-       bssid->PhyInfo.SignalQuality = precv_frame->attrib.phy_info.SignalQuality;/* in percentage */
-       bssid->PhyInfo.SignalStrength = precv_frame->attrib.phy_info.SignalStrength;/* in percentage */
-       bssid->PhyInfo.Optimum_antenna = rtw_current_antenna(padapter);
-
-       /*  checking SSID */
-       p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset);
-       if (!p)
-               return _FAIL;
-
-       if (*(p + 1)) {
-               if (len > NDIS_802_11_LENGTH_SSID)
-                       return _FAIL;
-               memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
-               bssid->Ssid.SsidLength = *(p + 1);
-       } else {
-               bssid->Ssid.SsidLength = 0;
-       }
-
-       memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
-
-       /* checking rate info... */
-       i = 0;
-       p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
-       if (p) {
-               if (len > NDIS_802_11_LENGTH_RATES_EX)
-                       return _FAIL;
-               memcpy(bssid->SupportedRates, (p + 2), len);
-               i = len;
-       }
-
-       p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
-       if (p) {
-               if (len > (NDIS_802_11_LENGTH_RATES_EX - i))
-                       return _FAIL;
-               memcpy(bssid->SupportedRates + i, (p + 2), len);
-       }
-
-       if (bssid->IELength < 12)
-               return _FAIL;
-
-       /*  Checking for DSConfig */
-       p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
-
-       bssid->Configuration.DSConfig = 0;
-       bssid->Configuration.Length = 0;
-
-       if (p) {
-               bssid->Configuration.DSConfig = *(p + 2);
-       } else {/*  In 5G, some ap do not have DSSET IE */
-               /*  checking HT info for channel */
-               p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
-               if (p) {
-                       struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
-                       bssid->Configuration.DSConfig = HT_info->primary_channel;
-               } else { /*  use current channel */
-                       bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
-               }
-       }
-
-       memcpy(&le32_tmp, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
-       bssid->Configuration.BeaconPeriod = le32_to_cpu(le32_tmp);
-
-       val16 = rtw_get_capability((struct wlan_bssid_ex *)bssid);
-
-       if (val16 & BIT(0)) {
-               bssid->InfrastructureMode = Ndis802_11Infrastructure;
-               memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
-       } else {
-               bssid->InfrastructureMode = Ndis802_11IBSS;
-               memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
-       }
-
-       if (val16 & BIT(4))
-               bssid->Privacy = 1;
-       else
-               bssid->Privacy = 0;
-
-       bssid->Configuration.ATIMWindow = 0;
-
-       /* 20/40 BSS Coexistence check */
-       if ((pregistrypriv->wifi_spec == 1) && (!pmlmeinfo->bwmode_updated)) {
-               struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-               p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
-               if (p && len > 0) {
-                       struct HT_caps_element  *pHT_caps;
-                       pHT_caps = (struct HT_caps_element *)(p + 2);
-
-                       if (le16_to_cpu(pHT_caps->u.HT_cap_element.HT_caps_info) & BIT(14))
-                               pmlmepriv->num_FortyMHzIntolerant++;
-               } else {
-                       pmlmepriv->num_sta_no_ht++;
-               }
-       }
-
-       /*  mark bss info receiving from nearby channel as SignalQuality 101 */
-       if (bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
-               bssid->PhyInfo.SignalQuality = 101;
-       return _SUCCESS;
-}
-
-static void rtw_set_bssid(struct adapter *adapter, u8 *bssid)
-{
-       int i;
-
-       for (i = 0; i < ETH_ALEN; i++)
-               rtw_write8(adapter, REG_BSSID + i, bssid[i]);
-}
-
-static void mlme_join(struct adapter *adapter, int type)
-{
-       struct mlme_priv *mlmepriv = &adapter->mlmepriv;
-       u8 retry_limit = 0x30, reg;
-       u32 reg32;
-       int res;
-
-       switch (type) {
-       case 0:
-               /* prepare to join */
-               /* enable to rx data frame, accept all data frame */
-               rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
-
-               res = rtw_read32(adapter, REG_RCR, &reg32);
-               if (res)
-                       return;
-
-               rtw_write32(adapter, REG_RCR,
-                           reg32 | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
-
-               if (check_fwstate(mlmepriv, WIFI_STATION_STATE)) {
-                       retry_limit = 48;
-               } else {
-                       /* ad-hoc mode */
-                       retry_limit = 0x7;
-               }
-               break;
-       case 1:
-               /* joinbss_event call back when join res < 0 */
-               rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
-               break;
-       case 2:
-               /* sta add event call back */
-               /* enable update TSF */
-               res = rtw_read8(adapter, REG_BCN_CTRL, &reg);
-               if (res)
-                       return;
-
-               rtw_write8(adapter, REG_BCN_CTRL, reg & (~BIT(4)));
-
-               if (check_fwstate(mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
-                       retry_limit = 0x7;
-               break;
-       default:
-               break;
-       }
-
-       rtw_write16(adapter, REG_RL,
-                   retry_limit << RETRY_LIMIT_SHORT_SHIFT | retry_limit << RETRY_LIMIT_LONG_SHIFT);
-}
-
-void start_create_ibss(struct adapter *padapter)
-{
-       unsigned short  caps;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network);
-       pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
-       pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
-
-       /* update wireless mode */
-       update_wireless_mode(padapter);
-
-       /* update capability */
-       caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork);
-       update_capinfo(padapter, caps);
-       if (caps & cap_IBSS) {/* adhoc master */
-               rtw_write8(padapter, REG_SECCFG, 0xcf);
-
-               /* switch channel */
-               /* SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
-               set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
-
-               beacon_timing_control(padapter);
-
-               /* set msr to WIFI_FW_ADHOC_STATE */
-               pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
-               Set_MSR(padapter, (pmlmeinfo->state & 0x3));
-
-               /* issue beacon */
-               if (send_beacon(padapter) == _FAIL) {
-                       report_join_res(padapter, -1);
-                       pmlmeinfo->state = WIFI_FW_NULL_STATE;
-               } else {
-                       rtw_set_bssid(padapter, padapter->registrypriv.dev_network.MacAddress);
-                       mlme_join(padapter, 0);
-
-                       report_join_res(padapter, 1);
-                       pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
-                       rtw_indicate_connect(padapter);
-               }
-       } else {
-               return;
-       }
-       /* update bc/mc sta_info */
-       update_bmc_sta(padapter);
-}
-
-void start_clnt_join(struct adapter *padapter)
-{
-       unsigned short  caps;
-       u8 val8;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network);
-       int beacon_timeout;
-
-       pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
-       pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
-
-       /* update wireless mode */
-       update_wireless_mode(padapter);
-
-       /* update capability */
-       caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork);
-       update_capinfo(padapter, caps);
-       if (caps & cap_ESS) {
-               Set_MSR(padapter, WIFI_FW_STATION_STATE);
-
-               val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf;
-
-               rtw_write8(padapter, REG_SECCFG, val8);
-
-               /* switch channel */
-               set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-
-               /* here wait for receiving the beacon to start auth */
-               /* and enable a timer */
-               beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
-               set_link_timer(pmlmeext, beacon_timeout);
-               _set_timer(&padapter->mlmepriv.assoc_timer,
-                          (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO * REASSOC_LIMIT) + beacon_timeout);
-
-               pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
-       } else if (caps & cap_IBSS) { /* adhoc client */
-               Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
-
-               rtw_write8(padapter, REG_SECCFG, 0xcf);
-
-               /* switch channel */
-               set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-
-               beacon_timing_control(padapter);
-
-               pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
-
-               report_join_res(padapter, 1);
-       } else {
-               return;
-       }
-}
-
-void start_clnt_auth(struct adapter *padapter)
-{
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       _cancel_timer_ex(&pmlmeext->link_timer);
-
-       pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
-       pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
-
-       pmlmeinfo->auth_seq = 1;
-       pmlmeinfo->reauth_count = 0;
-       pmlmeinfo->reassoc_count = 0;
-       pmlmeinfo->link_count = 0;
-       pmlmeext->retry = 0;
-
-       /*  Because of AP's not receiving deauth before */
-       /*  AP may: 1)not response auth or 2)deauth us after link is complete */
-       /*  issue deauth before issuing auth to deal with the situation */
-       /*      Commented by Albert 2012/07/21 */
-       /*      For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
-       issue_deauth(padapter, (&pmlmeinfo->network)->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
-
-       issue_auth(padapter, NULL, 0);
-
-       set_link_timer(pmlmeext, REAUTH_TO);
-}
-
-void start_clnt_assoc(struct adapter *padapter)
-{
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       _cancel_timer_ex(&pmlmeext->link_timer);
-
-       pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
-       pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
-
-       issue_assocreq(padapter);
-
-       set_link_timer(pmlmeext, REASSOC_TO);
-}
-
-void receive_disconnect(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason)
-{
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       /* check A3 */
-       if (!(!memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
-               return;
-
-       if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
-               if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
-                       pmlmeinfo->state = WIFI_FW_NULL_STATE;
-                       report_del_sta_event(padapter, MacAddr, reason);
-               } else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) {
-                       pmlmeinfo->state = WIFI_FW_NULL_STATE;
-                       report_join_res(padapter, -2);
-               }
-       }
-}
-
-static void process_80211d(struct adapter *padapter, struct wlan_bssid_ex *bssid)
-{
-       struct registry_priv *pregistrypriv;
-       struct mlme_ext_priv *pmlmeext;
-       struct rt_channel_info *chplan_new;
-       u8 channel;
-       u8 i;
-
-       pregistrypriv = &padapter->registrypriv;
-       pmlmeext = &padapter->mlmeextpriv;
-
-       /*  Adjust channel plan by AP Country IE */
-       if (pregistrypriv->enable80211d &&
-           (!pmlmeext->update_channel_plan_by_ap_done)) {
-               u8 *ie, *p;
-               u32 len;
-               struct rt_channel_plan chplan_ap;
-               struct rt_channel_info chplan_sta[MAX_CHANNEL_NUM];
-               u8 country[4];
-               u8 fcn; /*  first channel number */
-               u8 noc; /*  number of channel */
-               u8 j, k;
-
-               ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
-               if (!ie)
-                       return;
-               if (len < 6)
-                       return;
-               ie += 2;
-               p = ie;
-               ie += len;
-
-               memset(country, 0, 4);
-               memcpy(country, p, 3);
-               p += 3;
-
-               i = 0;
-               while ((ie - p) >= 3) {
-                       fcn = *(p++);
-                       noc = *(p++);
-                       p++;
-
-                       for (j = 0; j < noc; j++) {
-                               channel = fcn + j;
-                               chplan_ap.Channel[i++] = channel;
-                       }
-               }
-               chplan_ap.Len = i;
-
-               memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
-
-               memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
-               chplan_new = pmlmeext->channel_set;
-
-               i = 0;
-               j = 0;
-               k = 0;
-               if (pregistrypriv->wireless_mode & WIRELESS_11G) {
-                       do {
-                               if ((i == MAX_CHANNEL_NUM) ||
-                                   (chplan_sta[i].ChannelNum == 0))
-                                       break;
-
-                               if (j == chplan_ap.Len)
-                                       break;
-
-                               if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) {
-                                       chplan_new[k].ChannelNum = chplan_ap.Channel[j];
-                                       chplan_new[k].ScanType = SCAN_ACTIVE;
-                                       i++;
-                                       j++;
-                                       k++;
-                               } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
-                                       chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
-                                       chplan_new[k].ScanType = SCAN_PASSIVE;
-                                       i++;
-                                       k++;
-                               } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) {
-                                       chplan_new[k].ChannelNum = chplan_ap.Channel[j];
-                                       chplan_new[k].ScanType = SCAN_ACTIVE;
-                                       j++;
-                                       k++;
-                               }
-                       } while (1);
-
-                       /*  change AP not support channel to Passive scan */
-                       while ((i < MAX_CHANNEL_NUM) &&
-                              (chplan_sta[i].ChannelNum != 0) &&
-                              (chplan_sta[i].ChannelNum <= 14)) {
-                               chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
-                               chplan_new[k].ScanType = SCAN_PASSIVE;
-                               i++;
-                               k++;
-                       }
-
-                       /*  add channel AP supported */
-                       while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) {
-                               chplan_new[k].ChannelNum = chplan_ap.Channel[j];
-                               chplan_new[k].ScanType = SCAN_ACTIVE;
-                               j++;
-                               k++;
-                       }
-               } else {
-                       /*  keep original STA 2.4G channel plan */
-                       while ((i < MAX_CHANNEL_NUM) &&
-                              (chplan_sta[i].ChannelNum != 0) &&
-                              (chplan_sta[i].ChannelNum <= 14)) {
-                               chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
-                               chplan_new[k].ScanType = chplan_sta[i].ScanType;
-                               i++;
-                               k++;
-                       }
-
-                       /*  skip AP 2.4G channel plan */
-                       while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
-                               j++;
-               }
-
-               /*  keep original STA 5G channel plan */
-               while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
-                       chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
-                       chplan_new[k].ScanType = chplan_sta[i].ScanType;
-                       i++;
-                       k++;
-               }
-
-               pmlmeext->update_channel_plan_by_ap_done = 1;
-       }
-
-       /*  If channel is used by AP, set channel scan type to active */
-       channel = bssid->Configuration.DSConfig;
-       chplan_new = pmlmeext->channel_set;
-       i = 0;
-       while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) {
-               if (chplan_new[i].ChannelNum == channel) {
-                       if (chplan_new[i].ScanType == SCAN_PASSIVE)
-                               chplan_new[i].ScanType = SCAN_ACTIVE;
-                       break;
-               }
-               i++;
-       }
-}
-
-/****************************************************************************
-
-Following are the functions to report events
-
-*****************************************************************************/
-
-void report_survey_event(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       struct cmd_obj *pcmd_obj;
-       u8 *pevtcmd;
-       u32 cmdsz;
-       struct survey_event     *psurvey_evt;
-       struct C2HEvent_Header *pc2h_evt_hdr;
-       struct mlme_ext_priv *pmlmeext;
-       struct cmd_priv *pcmdpriv;
-       /* u8 *pframe = precv_frame->rx_data; */
-       /* uint len = precv_frame->len; */
-
-       if (!padapter)
-               return;
-
-       pmlmeext = &padapter->mlmeextpriv;
-       pcmdpriv = &padapter->cmdpriv;
-
-       pcmd_obj = kzalloc(sizeof(*pcmd_obj), GFP_ATOMIC);
-       if (!pcmd_obj)
-               return;
-
-       cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
-       pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
-       if (!pevtcmd) {
-               kfree(pcmd_obj);
-               return;
-       }
-
-       INIT_LIST_HEAD(&pcmd_obj->list);
-
-       pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
-       pcmd_obj->cmdsz = cmdsz;
-       pcmd_obj->parmbuf = pevtcmd;
-
-       pcmd_obj->rsp = NULL;
-       pcmd_obj->rspsz  = 0;
-
-       pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
-       pc2h_evt_hdr->len = sizeof(struct survey_event);
-       pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
-       pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
-
-       psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
-
-       if (collect_bss_info(padapter, precv_frame, (struct wlan_bssid_ex *)&psurvey_evt->bss) == _FAIL) {
-               kfree(pcmd_obj);
-               kfree(pevtcmd);
-               return;
-       }
-
-       process_80211d(padapter, &psurvey_evt->bss);
-
-       rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
-
-       pmlmeext->sitesurvey_res.bss_cnt++;
-}
-
-void report_surveydone_event(struct adapter *padapter)
-{
-       struct cmd_obj *pcmd_obj;
-       u8 *pevtcmd;
-       u32 cmdsz;
-       struct surveydone_event *psurveydone_evt;
-       struct C2HEvent_Header  *pc2h_evt_hdr;
-       struct mlme_ext_priv            *pmlmeext = &padapter->mlmeextpriv;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-
-       pcmd_obj = kzalloc(sizeof(*pcmd_obj), GFP_KERNEL);
-       if (!pcmd_obj)
-               return;
-
-       cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
-       pevtcmd = kzalloc(cmdsz, GFP_KERNEL);
-       if (!pevtcmd) {
-               kfree(pcmd_obj);
-               return;
-       }
-
-       INIT_LIST_HEAD(&pcmd_obj->list);
-
-       pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
-       pcmd_obj->cmdsz = cmdsz;
-       pcmd_obj->parmbuf = pevtcmd;
-
-       pcmd_obj->rsp = NULL;
-       pcmd_obj->rspsz  = 0;
-
-       pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
-       pc2h_evt_hdr->len = sizeof(struct surveydone_event);
-       pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
-       pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
-
-       psurveydone_evt = (struct surveydone_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
-       psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
-
-       rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
-}
-
-void report_join_res(struct adapter *padapter, int res)
-{
-       struct cmd_obj *pcmd_obj;
-       u8 *pevtcmd;
-       u32 cmdsz;
-       struct joinbss_event            *pjoinbss_evt;
-       struct C2HEvent_Header  *pc2h_evt_hdr;
-       struct mlme_ext_priv            *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-
-       pcmd_obj = kzalloc(sizeof(*pcmd_obj), GFP_ATOMIC);
-       if (!pcmd_obj)
-               return;
-
-       cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
-       pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
-       if (!pevtcmd) {
-               kfree(pcmd_obj);
-               return;
-       }
-
-       INIT_LIST_HEAD(&pcmd_obj->list);
-
-       pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
-       pcmd_obj->cmdsz = cmdsz;
-       pcmd_obj->parmbuf = pevtcmd;
-
-       pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
-       pc2h_evt_hdr->len = sizeof(struct joinbss_event);
-       pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
-       pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
-
-       pjoinbss_evt = (struct joinbss_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
-       memcpy((unsigned char *)(&pjoinbss_evt->network.network), &pmlmeinfo->network, sizeof(struct wlan_bssid_ex));
-       pjoinbss_evt->network.join_res  = res;
-       pjoinbss_evt->network.aid = res;
-
-       rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
-
-       rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
-}
-
-void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason)
-{
-       struct cmd_obj *pcmd_obj;
-       u8 *pevtcmd;
-       u32 cmdsz;
-       struct sta_info *psta;
-       int     mac_id;
-       struct stadel_event                     *pdel_sta_evt;
-       struct C2HEvent_Header  *pc2h_evt_hdr;
-       struct mlme_ext_priv            *pmlmeext = &padapter->mlmeextpriv;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-
-       pcmd_obj = kzalloc(sizeof(*pcmd_obj), GFP_ATOMIC);
-       if (!pcmd_obj)
-               return;
-
-       cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
-       pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
-       if (!pevtcmd) {
-               kfree(pcmd_obj);
-               return;
-       }
-
-       INIT_LIST_HEAD(&pcmd_obj->list);
-
-       pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
-       pcmd_obj->cmdsz = cmdsz;
-       pcmd_obj->parmbuf = pevtcmd;
-
-       pcmd_obj->rsp = NULL;
-       pcmd_obj->rspsz  = 0;
-
-       pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
-       pc2h_evt_hdr->len = sizeof(struct stadel_event);
-       pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
-       pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
-
-       pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
-       memcpy((unsigned char *)(&pdel_sta_evt->macaddr), MacAddr, ETH_ALEN);
-       memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
-
-       psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
-       if (psta)
-               mac_id = (int)psta->mac_id;
-       else
-               mac_id = (-1);
-
-       pdel_sta_evt->mac_id = mac_id;
-
-       rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
-}
-
-void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr, int cam_idx)
-{
-       struct cmd_obj *pcmd_obj;
-       u8 *pevtcmd;
-       u32 cmdsz;
-       struct stassoc_event            *padd_sta_evt;
-       struct C2HEvent_Header  *pc2h_evt_hdr;
-       struct mlme_ext_priv            *pmlmeext = &padapter->mlmeextpriv;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-
-       pcmd_obj = kzalloc(sizeof(*pcmd_obj), GFP_KERNEL);
-       if (!pcmd_obj)
-               return;
-
-       cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
-       pevtcmd = kzalloc(cmdsz, GFP_KERNEL);
-       if (!pevtcmd) {
-               kfree(pcmd_obj);
-               return;
-       }
-
-       INIT_LIST_HEAD(&pcmd_obj->list);
-
-       pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
-       pcmd_obj->cmdsz = cmdsz;
-       pcmd_obj->parmbuf = pevtcmd;
-
-       pcmd_obj->rsp = NULL;
-       pcmd_obj->rspsz  = 0;
-
-       pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
-       pc2h_evt_hdr->len = sizeof(struct stassoc_event);
-       pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
-       pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
-
-       padd_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
-       memcpy((unsigned char *)(&padd_sta_evt->macaddr), MacAddr, ETH_ALEN);
-       padd_sta_evt->cam_id = cam_idx;
-
-       rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
-}
-
-/****************************************************************************
-
-Following are the event callback functions
-
-*****************************************************************************/
-
-/* for sta/adhoc mode */
-void update_sta_info(struct adapter *padapter, struct sta_info *psta)
-{
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       /* ERP */
-       VCS_update(padapter, psta);
-
-       /* HT */
-       if (pmlmepriv->htpriv.ht_option) {
-               psta->htpriv.ht_option = true;
-
-               psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
-
-               if (support_short_GI(padapter, &pmlmeinfo->HT_caps))
-                       psta->htpriv.sgi = true;
-
-               psta->qos_option = true;
-       } else {
-               psta->htpriv.ht_option = false;
-
-               psta->htpriv.ampdu_enable = false;
-
-               psta->htpriv.sgi = false;
-               psta->qos_option = false;
-       }
-       psta->htpriv.bwmode = pmlmeext->cur_bwmode;
-       psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
-
-       psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
-       psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
-
-       /* QoS */
-       if (pmlmepriv->qospriv.qos_option)
-               psta->qos_option = true;
-
-       psta->state = _FW_LINKED;
-}
-
-static void rtw_reset_dm_func_flag(struct adapter *adapter)
-{
-       struct hal_data_8188e *haldata = &adapter->haldata;
-       struct dm_priv *dmpriv = &haldata->dmpriv;
-       struct odm_dm_struct *odmpriv = &haldata->odmpriv;
-
-       odmpriv->SupportAbility = dmpriv->InitODMFlag;
-}
-
-static void rtw_clear_dm_func_flag(struct adapter *adapter)
-{
-       struct hal_data_8188e *haldata = &adapter->haldata;
-       struct odm_dm_struct *odmpriv = &haldata->odmpriv;
-
-       odmpriv->SupportAbility = 0;
-}
-
-void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res)
-{
-       struct sta_info         *psta, *psta_bmc;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
-       struct sta_priv         *pstapriv = &padapter->stapriv;
-       u16 media_status;
-
-       if (join_res < 0) {
-               mlme_join(padapter, 1);
-               rtw_set_bssid(padapter, null_addr);
-
-               /* restore to initial setting. */
-               update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
-
-               return;
-       }
-
-       if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
-               /* for bc/mc */
-               psta_bmc = rtw_get_bcmc_stainfo(padapter);
-               if (psta_bmc) {
-                       pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc;
-                       update_bmc_sta_support_rate(padapter, psta_bmc->mac_id);
-                       Update_RA_Entry(padapter, psta_bmc->mac_id);
-               }
-       }
-
-       /* turn on dynamic functions */
-       rtw_reset_dm_func_flag(padapter);
-
-       /*  update IOT-releated issue */
-       update_IOT_info(padapter);
-
-       rtw_set_basic_rate(padapter, cur_network->SupportedRates);
-
-       /* BCN interval */
-       rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
-
-       /* update capability */
-       update_capinfo(padapter, pmlmeinfo->capability);
-
-       /* WMM, Update EDCA param */
-       WMMOnAssocRsp(padapter);
-
-       /* HT */
-       HTOnAssocRsp(padapter);
-
-       set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-
-       psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
-       if (psta) { /* only for infra. mode */
-               pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
-
-               psta->wireless_mode = pmlmeext->cur_wireless_mode;
-
-               /* set per sta rate after updating HT cap. */
-               set_sta_rate(padapter, psta);
-               rtw_set_max_rpt_macid(padapter, psta->mac_id);
-
-               media_status = (psta->mac_id << 8) | 1; /*   MACID|OPMODE: 1 means connect */
-               rtl8188e_set_FwMediaStatus_cmd(padapter, media_status);
-       }
-
-       mlme_join(padapter, 2);
-
-       if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
-               /*  correcting TSF */
-               correct_TSF(padapter);
-       }
-       rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
-}
-
-void mlmeext_sta_add_event_callback(struct adapter *padapter, struct sta_info *psta)
-{
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
-               if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {/* adhoc master or sta_count>1 */
-                       /* nothing to do */
-               } else { /* adhoc client */
-                       /*  correcting TSF */
-                       correct_TSF(padapter);
-
-                       /* start beacon */
-                       if (send_beacon(padapter) == _FAIL) {
-                               pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
-                               pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
-                               return;
-                       }
-                       pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
-               }
-               mlme_join(padapter, 2);
-       }
-
-       pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
-
-       /* rate radaptive */
-       Update_RA_Entry(padapter, psta->mac_id);
-
-       /* update adhoc sta_info */
-       update_sta_info(padapter, psta);
-}
-
-static void mlme_disconnect(struct adapter *adapter)
-{
-       int res;
-       u8 reg;
-
-       /* Set RCR to not to receive data frame when NO LINK state */
-       /* reject all data frames */
-       rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
-
-       /* reset TSF */
-       rtw_write8(adapter, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
-
-       /* disable update TSF */
-
-       res = rtw_read8(adapter, REG_BCN_CTRL, &reg);
-       if (res)
-               return;
-
-       rtw_write8(adapter, REG_BCN_CTRL, reg | BIT(4));
-}
-
-void mlmeext_sta_del_event_callback(struct adapter *padapter)
-{
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       if (r8188eu_is_client_associated_to_ap(padapter) || r8188eu_is_ibss_empty(padapter)) {
-               mlme_disconnect(padapter);
-               rtw_set_bssid(padapter, null_addr);
-
-               /* restore to initial setting. */
-               update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
-
-               /* switch to the 20M Hz mode after disconnect */
-               pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
-               pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-
-               /* SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */
-               set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-
-               flush_all_cam_entry(padapter);
-
-               pmlmeinfo->state = WIFI_FW_NULL_STATE;
-
-               /* set MSR to no link state -> infra. mode */
-               Set_MSR(padapter, _HW_STATE_STATION_);
-
-               _cancel_timer_ex(&pmlmeext->link_timer);
-       }
-}
-
-/****************************************************************************
-
-Following are the functions for the timer handlers
-
-*****************************************************************************/
-static u8 chk_ap_is_alive(struct sta_info *psta)
-{
-       u8 ret = false;
-
-       if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)) &&
-           sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) &&
-           sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
-               ret = false;
-       else
-               ret = true;
-
-       sta_update_last_rx_pkts(psta);
-
-       return ret;
-}
-
-static int rtl8188e_sreset_linked_status_check(struct adapter *padapter)
-{
-       u32 rx_dma_status;
-       int res;
-       u8 reg;
-
-       res = rtw_read32(padapter, REG_RXDMA_STATUS, &rx_dma_status);
-       if (res)
-               return res;
-
-       if (rx_dma_status != 0x00)
-               rtw_write32(padapter, REG_RXDMA_STATUS, rx_dma_status);
-
-       return rtw_read8(padapter, REG_FMETHR, &reg);
-}
-
-void linked_status_chk(struct adapter *padapter)
-{
-       u32     i;
-       struct sta_info         *psta;
-       struct xmit_priv                *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct sta_priv         *pstapriv = &padapter->stapriv;
-
-       rtl8188e_sreset_linked_status_check(padapter);
-
-       if (r8188eu_is_client_associated_to_ap(padapter)) {
-               /* linked infrastructure client mode */
-
-               int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
-               int rx_chk_limit;
-
-               rx_chk_limit = 4;
-               psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
-               if (psta) {
-                       bool is_p2p_enable = false;
-                       is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
-
-                       if (!chk_ap_is_alive(psta))
-                               rx_chk = _FAIL;
-
-                       if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
-                               tx_chk = _FAIL;
-
-                       if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
-                               u8 backup_oper_channel = 0;
-
-                               /* switch to correct channel of current network  before issue keep-alive frames */
-                               if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
-                                       backup_oper_channel = rtw_get_oper_ch(padapter);
-                                       SelectChannel(padapter, pmlmeext->cur_channel);
-                               }
-
-                               if (rx_chk != _SUCCESS)
-                                       issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr);
-
-                               if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) {
-                                       tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1);
-                                       /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
-                                       if (tx_chk == _SUCCESS && !is_p2p_enable)
-                                               rx_chk = _SUCCESS;
-                               }
-
-                               /* back to the original operation channel */
-                               if (backup_oper_channel > 0)
-                                       SelectChannel(padapter, backup_oper_channel);
-                       } else {
-                               if (rx_chk != _SUCCESS) {
-                                       if (pmlmeext->retry == 0) {
-                                               issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
-                                               issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
-                                               issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
-                                       }
-                               }
-
-                               if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) {
-                                       tx_chk = issue_nulldata(padapter, NULL, 0, 1, 0);
-                               }
-                       }
-
-                       if (rx_chk == _FAIL) {
-                               pmlmeext->retry++;
-                               if (pmlmeext->retry > rx_chk_limit) {
-                                       receive_disconnect(padapter, pmlmeinfo->network.MacAddress,
-                                                          WLAN_REASON_EXPIRATION_CHK);
-                                       return;
-                               }
-                       } else {
-                               pmlmeext->retry = 0;
-                       }
-
-                       if (tx_chk == _FAIL) {
-                               pmlmeinfo->link_count &= 0xf;
-                       } else {
-                               pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
-                               pmlmeinfo->link_count = 0;
-                       }
-               } /* end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) */
-       } else if (r8188eu_is_client_associated_to_ibss(padapter)) {
-               /* linked IBSS mode */
-               /* for each assoc list entry to check the rx pkt counter */
-               for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) {
-                       if (pmlmeinfo->FW_sta_info[i].status == 1) {
-                               psta = pmlmeinfo->FW_sta_info[i].psta;
-
-                               if (psta == NULL)
-                                       continue;
-                               if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta)) {
-                                       if (pmlmeinfo->FW_sta_info[i].retry < 3) {
-                                               pmlmeinfo->FW_sta_info[i].retry++;
-                                       } else {
-                                               pmlmeinfo->FW_sta_info[i].retry = 0;
-                                               pmlmeinfo->FW_sta_info[i].status = 0;
-                                               report_del_sta_event(padapter, psta->hwaddr
-                                                       , 65535/*  indicate disconnect caused by no rx */
-                                       );
-                                       }
-                               } else {
-                                       pmlmeinfo->FW_sta_info[i].retry = 0;
-                                       pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
-                               }
-                       }
-               }
-       }
-}
-
-void survey_timer_hdl(struct adapter *padapter)
-{
-       struct cmd_obj  *ph2c;
-       struct sitesurvey_parm  *psurveyPara;
-       struct cmd_priv                                 *pcmdpriv = &padapter->cmdpriv;
-       struct mlme_ext_priv            *pmlmeext = &padapter->mlmeextpriv;
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       /* issue rtw_sitesurvey_cmd */
-       if (pmlmeext->sitesurvey_res.state > SCAN_START) {
-               if (pmlmeext->sitesurvey_res.state ==  SCAN_PROCESS)
-                       pmlmeext->sitesurvey_res.channel_idx++;
-
-               if (pmlmeext->scan_abort) {
-                       if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) {
-                               rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
-                               pmlmeext->sitesurvey_res.channel_idx = 3;
-                       } else {
-                               pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num;
-                       }
-
-                       pmlmeext->scan_abort = false;/* reset */
-               }
-
-               ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
-               if (!ph2c)
-                       goto exit_survey_timer_hdl;
-
-               psurveyPara = kzalloc(sizeof(*psurveyPara), GFP_ATOMIC);
-               if (!psurveyPara) {
-                       kfree(ph2c);
-                       goto exit_survey_timer_hdl;
-               }
-
-               init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
-               rtw_enqueue_cmd(pcmdpriv, ph2c);
-       }
-
-exit_survey_timer_hdl:
-       return;
-}
-
-void link_timer_hdl(struct adapter *padapter)
-{
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
-               pmlmeinfo->state = WIFI_FW_NULL_STATE;
-               report_join_res(padapter, -3);
-       } else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) {
-               /* re-auth timer */
-               if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) {
-                       pmlmeinfo->state = 0;
-                       report_join_res(padapter, -1);
-                       return;
-               }
-
-               pmlmeinfo->auth_seq = 1;
-               issue_auth(padapter, NULL, 0);
-               set_link_timer(pmlmeext, REAUTH_TO);
-       } else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) {
-               /* re-assoc timer */
-               if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) {
-                       pmlmeinfo->state = WIFI_FW_NULL_STATE;
-                       report_join_res(padapter, -2);
-                       return;
-               }
-
-               issue_assocreq(padapter);
-               set_link_timer(pmlmeext, REASSOC_TO);
-       }
-}
-
-void addba_timer_hdl(struct sta_info *psta)
-{
-       struct ht_priv  *phtpriv;
-
-       if (!psta)
-               return;
-
-       phtpriv = &psta->htpriv;
-
-       if ((phtpriv->ht_option) && (phtpriv->ampdu_enable)) {
-               if (phtpriv->candidate_tid_bitmap)
-                       phtpriv->candidate_tid_bitmap = 0x0;
-       }
-}
-
-u8 NULL_hdl(struct adapter *padapter, u8 *pbuf)
-{
-       return H2C_SUCCESS;
-}
-
-u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf)
-{
-       u8 type;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
-
-       if (psetop->mode == Ndis802_11APMode) {
-               pmlmeinfo->state = WIFI_FW_AP_STATE;
-               type = _HW_STATE_AP_;
-       } else if (psetop->mode == Ndis802_11Infrastructure) {
-               pmlmeinfo->state &= ~(BIT(0) | BIT(1));/*  clear state */
-               pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to     STATION_STATE */
-               type = _HW_STATE_STATION_;
-       } else if (psetop->mode == Ndis802_11IBSS) {
-               type = _HW_STATE_ADHOC_;
-       } else {
-               type = _HW_STATE_NOLINK_;
-       }
-
-       rtw_set_opmode(padapter, type);
-
-       return H2C_SUCCESS;
-}
-
-u8 createbss_hdl(struct adapter *padapter, u8 *pbuf)
-{
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network);
-       struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
-       /* u32  initialgain; */
-
-       if (pparm->network.InfrastructureMode == Ndis802_11APMode) {
-               if (pmlmeinfo->state == WIFI_FW_AP_STATE) {
-                       /* todo: */
-                       return H2C_SUCCESS;
-               }
-       }
-
-       /* below is for ad-hoc master */
-       if (pparm->network.InfrastructureMode == Ndis802_11IBSS) {
-               rtw_joinbss_reset(padapter);
-
-               pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
-               pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-               pmlmeinfo->ERP_enable = 0;
-               pmlmeinfo->WMM_enable = 0;
-               pmlmeinfo->HT_enable = 0;
-               pmlmeinfo->HT_caps_enable = 0;
-               pmlmeinfo->HT_info_enable = 0;
-               pmlmeinfo->agg_enable_bitmap = 0;
-               pmlmeinfo->candidate_tid_bitmap = 0;
-
-               /* disable dynamic functions, such as high power, DIG */
-               Save_DM_Func_Flag(padapter);
-               rtw_clear_dm_func_flag(padapter);
-
-               /* cancel link timer */
-               _cancel_timer_ex(&pmlmeext->link_timer);
-
-               /* clear CAM */
-               flush_all_cam_entry(padapter);
-
-               memcpy(pnetwork, pbuf, offsetof(struct wlan_bssid_ex, IELength));
-               pnetwork->IELength = ((struct wlan_bssid_ex *)pbuf)->IELength;
-
-               if (pnetwork->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
-                       return H2C_PARAMETERS_ERROR;
-
-               memcpy(pnetwork->IEs, ((struct wlan_bssid_ex *)pbuf)->IEs, pnetwork->IELength);
-
-               start_create_ibss(padapter);
-       }
-
-       return H2C_SUCCESS;
-}
-
-u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
-{
-       struct ndis_802_11_var_ie *pIE;
-       struct registry_priv    *pregpriv = &padapter->registrypriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network);
-       struct joinbss_parm     *pparm = (struct joinbss_parm *)pbuf;
-       u32 i;
-
-       /* check already connecting to AP or not */
-       if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
-               if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
-                       issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 5, 100);
-
-               pmlmeinfo->state = WIFI_FW_NULL_STATE;
-
-               /* clear CAM */
-               flush_all_cam_entry(padapter);
-
-               _cancel_timer_ex(&pmlmeext->link_timer);
-
-               /* set MSR to nolink -> infra. mode */
-               Set_MSR(padapter, _HW_STATE_STATION_);
-
-               mlme_disconnect(padapter);
-       }
-
-       rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, false);
-
-       rtw_joinbss_reset(padapter);
-
-       pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
-       pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-       pmlmeinfo->ERP_enable = 0;
-       pmlmeinfo->WMM_enable = 0;
-       pmlmeinfo->HT_enable = 0;
-       pmlmeinfo->HT_caps_enable = 0;
-       pmlmeinfo->HT_info_enable = 0;
-       pmlmeinfo->agg_enable_bitmap = 0;
-       pmlmeinfo->candidate_tid_bitmap = 0;
-       pmlmeinfo->bwmode_updated = false;
-
-       memcpy(pnetwork, pbuf, offsetof(struct wlan_bssid_ex, IELength));
-       pnetwork->IELength = ((struct wlan_bssid_ex *)pbuf)->IELength;
-
-       if (pnetwork->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
-               return H2C_PARAMETERS_ERROR;
-
-       memcpy(pnetwork->IEs, ((struct wlan_bssid_ex *)pbuf)->IEs, pnetwork->IELength);
-
-       /* Check AP vendor to move rtw_joinbss_cmd() */
-
-       for (i = sizeof(struct ndis_802_11_fixed_ie); i < pnetwork->IELength;) {
-               pIE = (struct ndis_802_11_var_ie *)(pnetwork->IEs + i);
-
-               switch (pIE->ElementID) {
-               case _VENDOR_SPECIFIC_IE_:/* Get WMM IE. */
-                       if (!memcmp(pIE->data, WMM_OUI, 4))
-                               pmlmeinfo->WMM_enable = 1;
-                       break;
-               case _HT_CAPABILITY_IE_:        /* Get HT Cap IE. */
-                       pmlmeinfo->HT_caps_enable = 1;
-                       break;
-               case _HT_EXTRA_INFO_IE_:        /* Get HT Info IE. */
-                       pmlmeinfo->HT_info_enable = 1;
-
-                       /* spec case only for cisco's ap because cisco's ap issue assoc rsp using mcs rate @40MHz or @20MHz */
-                       {
-                               struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data);
-
-                               if ((pregpriv->cbw40_enable) &&  (pht_info->infos[0] & BIT(2))) {
-                                       /* switch to the 40M Hz mode according to the AP */
-                                       pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
-                                       switch (pht_info->infos[0] & 0x3) {
-                                       case 1:
-                                               pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
-                                               break;
-                                       case 3:
-                                               pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
-                                               break;
-                                       default:
-                                               pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-                                               break;
-                                       }
-                               }
-                       }
-                       break;
-               default:
-                       break;
-               }
-
-               i += (pIE->Length + 2);
-       }
-       /* disable dynamic functions, such as high power, DIG */
-
-       /* config the initial gain under linking, need to write the BB registers */
-
-       rtw_set_bssid(padapter, pmlmeinfo->network.MacAddress);
-       mlme_join(padapter, 0);
-
-       /* cancel link timer */
-       _cancel_timer_ex(&pmlmeext->link_timer);
-
-       start_clnt_join(padapter);
-
-       return H2C_SUCCESS;
-}
-
-u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf)
-{
-       struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network);
-       u8 val8;
-       int res;
-
-       if (r8188eu_is_client_associated_to_ap(padapter))
-               issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms / 100, 100);
-
-       mlme_disconnect(padapter);
-       rtw_set_bssid(padapter, null_addr);
-
-       /* restore to initial setting. */
-       update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
-
-       if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
-               /* Stop BCN */
-               res = rtw_read8(padapter, REG_BCN_CTRL, &val8);
-               if (res)
-                       return H2C_DROPPED;
-
-               rtw_write8(padapter, REG_BCN_CTRL, val8 & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
-       }
-
-       /* set MSR to no link state -> infra. mode */
-       Set_MSR(padapter, _HW_STATE_STATION_);
-
-       pmlmeinfo->state = WIFI_FW_NULL_STATE;
-
-       /* switch to the 20M Hz mode after disconnect */
-       pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
-       pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-
-       set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-
-       flush_all_cam_entry(padapter);
-
-       _cancel_timer_ex(&pmlmeext->link_timer);
-
-       rtw_free_uc_swdec_pending_queue(padapter);
-
-       return  H2C_SUCCESS;
-}
-
-static int rtw_scan_ch_decision(struct adapter *padapter, struct rtw_ieee80211_channel *out,
-       u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
-{
-       int i, j;
-       int set_idx;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-
-       /* clear out first */
-       memset(out, 0, sizeof(struct rtw_ieee80211_channel) * out_num);
-
-       /* acquire channels from in */
-       j = 0;
-       for (i = 0; i < in_num; i++) {
-               set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value);
-               if (in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED) &&
-                   set_idx >= 0) {
-                       memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
-
-                       if (pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
-                               out[j].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
-
-                       j++;
-               }
-               if (j >= out_num)
-                       break;
-       }
-
-       /* if out is empty, use channel_set as default */
-       if (j == 0) {
-               for (i = 0; i < pmlmeext->max_chan_nums; i++) {
-                       out[i].hw_value = pmlmeext->channel_set[i].ChannelNum;
-
-                       if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
-                               out[i].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
-
-                       j++;
-               }
-       }
-
-       return j;
-}
-
-u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf)
-{
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct sitesurvey_parm  *pparm = (struct sitesurvey_parm *)pbuf;
-       u8 bdelayscan = false;
-       u32     i;
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) {
-               /* for first time sitesurvey_cmd */
-
-               pmlmeext->sitesurvey_res.state = SCAN_START;
-               pmlmeext->sitesurvey_res.bss_cnt = 0;
-               pmlmeext->sitesurvey_res.channel_idx = 0;
-
-               for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
-                       if (pparm->ssid[i].SsidLength) {
-                               memcpy(pmlmeext->sitesurvey_res.ssid[i].Ssid, pparm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
-                               pmlmeext->sitesurvey_res.ssid[i].SsidLength = pparm->ssid[i].SsidLength;
-                       } else {
-                               pmlmeext->sitesurvey_res.ssid[i].SsidLength = 0;
-                       }
-               }
-
-               pmlmeext->sitesurvey_res.ch_num = rtw_scan_ch_decision(padapter
-                       , pmlmeext->sitesurvey_res.ch, RTW_CHANNEL_SCAN_AMOUNT
-                       , pparm->ch, pparm->ch_num
-       );
-
-               pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
-
-               /* issue null data if associating to the AP */
-               if (r8188eu_is_client_associated_to_ap(padapter)) {
-                       pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
-
-                       issue_nulldata(padapter, NULL, 1, 3, 500);
-
-                       bdelayscan = true;
-               }
-               if (bdelayscan) {
-                       /* delay 50ms to protect nulldata(1). */
-                       set_survey_timer(pmlmeext, 50);
-                       return H2C_SUCCESS;
-               }
-       }
-
-       if ((pmlmeext->sitesurvey_res.state == SCAN_START) || (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) {
-               /* disable dynamic functions, such as high power, DIG */
-               Save_DM_Func_Flag(padapter);
-               rtw_clear_dm_func_flag(padapter);
-
-               /* config the initial gain under scanning, need to write the BB registers */
-               if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
-                       rtw_set_initial_gain(padapter, 0x1e);
-               else
-                       rtw_set_initial_gain(padapter, 0x28);
-
-
-               /* set MSR to no link state */
-               Set_MSR(padapter, _HW_STATE_NOLINK_);
-
-               rtw_mlme_under_site_survey(padapter);
-
-               pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
-       }
-
-       site_survey(padapter);
-
-       return H2C_SUCCESS;
-}
-
-u8 setauth_hdl(struct adapter *padapter, unsigned char *pbuf)
-{
-       struct setauth_parm             *pparm = (struct setauth_parm *)pbuf;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       if (pparm->mode < 4)
-               pmlmeinfo->auth_algo = pparm->mode;
-       return  H2C_SUCCESS;
-}
-
-u8 setkey_hdl(struct adapter *padapter, u8 *pbuf)
-{
-       unsigned short                          ctrl;
-       struct setkey_parm              *pparm = (struct setkey_parm *)pbuf;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       unsigned char                                   null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
-       /* main tx key for wep. */
-       if (pparm->set_tx)
-               pmlmeinfo->key_index = pparm->keyid;
-
-       /* write cam */
-       ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
-
-       write_cam(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
-
-       return H2C_SUCCESS;
-}
-
-u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf)
-{
-       u16 ctrl = 0;
-       u8 cam_id;/* cam_entry */
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct set_stakey_parm  *pparm = (struct set_stakey_parm *)pbuf;
-
-       /* cam_entry: */
-       /* 0~3 for default key */
-
-       /* for concurrent mode (ap+sta): */
-       /* default key is disable, using sw encrypt/decrypt */
-       /* cam_entry = 4 for sta mode (macid = 0) */
-       /* cam_entry(macid+3) = 5 ~ N for ap mode (aid = 1~N, macid = 2 ~N) */
-
-       /* for concurrent mode (sta+sta): */
-       /* default key is disable, using sw encrypt/decrypt */
-       /* cam_entry = 4 mapping to macid = 0 */
-       /* cam_entry = 5 mapping to macid = 2 */
-
-       cam_id = 4;
-
-       if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
-               struct sta_info *psta;
-               struct sta_priv *pstapriv = &padapter->stapriv;
-
-               if (pparm->algorithm == _NO_PRIVACY_)   /*  clear cam entry */ {
-                       clear_cam_entry(padapter, pparm->id);
-                       return H2C_SUCCESS_RSP;
-               }
-
-               psta = rtw_get_stainfo(pstapriv, pparm->addr);
-               if (psta) {
-                       ctrl = (BIT(15) | ((pparm->algorithm) << 2));
-
-                       if ((psta->mac_id < 1) || (psta->mac_id > (NUM_STA - 4)))
-                               return H2C_REJECTED;
-
-                       cam_id = (psta->mac_id + 3);/* 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */
-
-                       write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
-
-                       return H2C_SUCCESS_RSP;
-               } else {
-                       return H2C_REJECTED;
-               }
-       }
-
-       /* below for sta mode */
-
-       if (pparm->algorithm == _NO_PRIVACY_) { /*  clear cam entry */
-               clear_cam_entry(padapter, pparm->id);
-               return H2C_SUCCESS;
-       }
-       ctrl = BIT(15) | ((pparm->algorithm) << 2);
-       write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
-       pmlmeinfo->enc_algo = pparm->algorithm;
-       return H2C_SUCCESS;
-}
-
-u8 add_ba_hdl(struct adapter *padapter, unsigned char *pbuf)
-{
-       struct addBaReq_parm    *pparm = (struct addBaReq_parm *)pbuf;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
-
-       if (!psta)
-               return  H2C_SUCCESS;
-
-       if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
-           ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
-               issue_action_BA(padapter, pparm->addr, WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid, NULL);
-               _set_timer(&psta->addba_retry_timer, ADDBA_TO);
-       } else {
-               psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
-       }
-       return  H2C_SUCCESS;
-}
-
-u8 set_tx_beacon_cmd(struct adapter *padapter)
-{
-       struct cmd_obj  *ph2c;
-       struct Tx_Beacon_param  *ptxBeacon_parm;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       u8 res = _SUCCESS;
-       int len_diff = 0;
-
-       ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
-       if (!ph2c) {
-               res = _FAIL;
-               goto exit;
-       }
-
-       ptxBeacon_parm = kzalloc(sizeof(*ptxBeacon_parm), GFP_ATOMIC);
-       if (!ptxBeacon_parm) {
-               kfree(ph2c);
-               res = _FAIL;
-               goto exit;
-       }
-
-       memcpy(&ptxBeacon_parm->network, &pmlmeinfo->network, sizeof(struct wlan_bssid_ex));
-
-       len_diff = update_hidden_ssid(ptxBeacon_parm->network.IEs + _BEACON_IE_OFFSET_,
-                                     ptxBeacon_parm->network.IELength - _BEACON_IE_OFFSET_,
-                                     pmlmeinfo->hidden_ssid_mode);
-       ptxBeacon_parm->network.IELength += len_diff;
-
-       init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
-
-       res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-
-exit:
-
-       return res;
-}
-
-u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf)
-{
-       u8 evt_code;
-       u16 evt_sz;
-       uint    *peventbuf;
-       void (*event_callback)(struct adapter *dev, u8 *pbuf);
-       struct evt_priv *pevt_priv = &padapter->evtpriv;
-
-       peventbuf = (uint *)pbuf;
-       evt_sz = (u16)(*peventbuf & 0xffff);
-       evt_code = (u8)((*peventbuf >> 16) & 0xff);
-
-       /*  checking if event code is valid */
-       if (evt_code >= MAX_C2HEVT)
-               goto _abort_event_;
-
-       /*  checking if event size match the event parm size */
-       if ((wlanevents[evt_code].parmsize != 0) &&
-           (wlanevents[evt_code].parmsize != evt_sz))
-               goto _abort_event_;
-
-       atomic_inc(&pevt_priv->event_seq);
-
-       peventbuf += 2;
-
-       if (peventbuf) {
-               event_callback = wlanevents[evt_code].event_callback;
-               event_callback(padapter, (u8 *)peventbuf);
-       }
-
-_abort_event_:
-       return H2C_SUCCESS;
-}
-
-u8 h2c_msg_hdl(struct adapter *padapter, unsigned char *pbuf)
-{
-       if (!pbuf)
-               return H2C_PARAMETERS_ERROR;
-
-       return H2C_SUCCESS;
-}
-
-u8 tx_beacon_hdl(struct adapter *padapter, unsigned char *pbuf)
-{
-       if (send_beacon(padapter) == _FAIL) {
-               return H2C_PARAMETERS_ERROR;
-       } else {
-               /* tx bc/mc frames after update TIM */
-               struct sta_info *psta_bmc;
-               struct list_head *xmitframe_plist, *xmitframe_phead;
-               struct xmit_frame *pxmitframe = NULL;
-               struct sta_priv  *pstapriv = &padapter->stapriv;
-
-               /* for BC/MC Frames */
-               psta_bmc = rtw_get_bcmc_stainfo(padapter);
-               if (!psta_bmc)
-                       return H2C_SUCCESS;
-
-               if ((pstapriv->tim_bitmap & BIT(0)) && (psta_bmc->sleepq_len > 0)) {
-                       msleep(10);/*  10ms, ATIM(HIQ) Windows */
-                       spin_lock_bh(&psta_bmc->sleep_q.lock);
-
-                       xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
-                       xmitframe_plist = xmitframe_phead->next;
-
-                       while (xmitframe_phead != xmitframe_plist) {
-                               pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
-
-                               xmitframe_plist = xmitframe_plist->next;
-
-                               list_del_init(&pxmitframe->list);
-
-                               psta_bmc->sleepq_len--;
-                               if (psta_bmc->sleepq_len > 0)
-                                       pxmitframe->attrib.mdata = 1;
-                               else
-                                       pxmitframe->attrib.mdata = 0;
-
-                               pxmitframe->attrib.triggered = 1;
-
-                               pxmitframe->attrib.qsel = 0x11;/* HIQ */
-
-                               spin_unlock_bh(&psta_bmc->sleep_q.lock);
-                               if (rtl8188eu_hal_xmit(padapter, pxmitframe))
-                                       rtw_xmit_complete(padapter, pxmitframe);
-                               spin_lock_bh(&psta_bmc->sleep_q.lock);
-                       }
-                       spin_unlock_bh(&psta_bmc->sleep_q.lock);
-               }
-       }
-       return H2C_SUCCESS;
-}
-
-u8 set_ch_hdl(struct adapter *padapter, u8 *pbuf)
-{
-       struct set_ch_parm *set_ch_parm;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-
-       if (!pbuf)
-               return H2C_PARAMETERS_ERROR;
-
-       set_ch_parm = (struct set_ch_parm *)pbuf;
-
-       pmlmeext->cur_channel = set_ch_parm->ch;
-       pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
-       pmlmeext->cur_bwmode = set_ch_parm->bw;
-
-       set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
-
-       return  H2C_SUCCESS;
-}
-
-u8 set_chplan_hdl(struct adapter *padapter, unsigned char *pbuf)
-{
-       struct SetChannelPlan_param *setChannelPlan_param;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-
-       if (!pbuf)
-               return H2C_PARAMETERS_ERROR;
-
-       setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
-
-       pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
-       init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
-
-       return  H2C_SUCCESS;
-}
-
-u8 led_blink_hdl(struct adapter *padapter, unsigned char *pbuf)
-{
-       if (!pbuf)
-               return H2C_PARAMETERS_ERROR;
-       return  H2C_SUCCESS;
-}
-
-u8 set_csa_hdl(struct adapter *padapter, unsigned char *pbuf)
-{
-       return  H2C_REJECTED;
-}
-
-/*  TDLS_WRCR          : write RCR DATA BIT */
-/*  TDLS_SD_PTI                : issue peer traffic indication */
-/*  TDLS_CS_OFF                : go back to the channel linked with AP, terminating channel switch procedure */
-/*  TDLS_INIT_CH_SEN   : init channel sensing, receive all data and mgnt frame */
-/*  TDLS_DONE_CH_SEN: channel sensing and report candidate channel */
-/*  TDLS_OFF_CH                : first time set channel to off channel */
-/*  TDLS_BASE_CH               : go back tp the channel linked with AP when set base channel as target channel */
-/*  TDLS_P_OFF_CH      : periodically go to off channel */
-/*  TDLS_P_BASE_CH     : periodically go back to base channel */
-/*  TDLS_RS_RCR                : restore RCR */
-/*  TDLS_CKALV_PH1     : check alive timer phase1 */
-/*  TDLS_CKALV_PH2     : check alive timer phase2 */
-/*  TDLS_FREE_STA      : free tdls sta */
-u8 tdls_hdl(struct adapter *padapter, unsigned char *pbuf)
-{
-       return H2C_REJECTED;
-}
diff --git a/drivers/staging/r8188eu/core/rtw_p2p.c b/drivers/staging/r8188eu/core/rtw_p2p.c
deleted file mode 100644 (file)
index 93d3c9c..0000000
+++ /dev/null
@@ -1,1918 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#define _RTW_P2P_C_
-
-#include "../include/drv_types.h"
-#include "../include/rtw_p2p.h"
-#include "../include/wifi.h"
-
-static int rtw_p2p_is_channel_list_ok(u8 desired_ch, u8 *ch_list, u8 ch_cnt)
-{
-       int found = 0, i = 0;
-
-       for (i = 0; i < ch_cnt; i++) {
-               if (ch_list[i] == desired_ch) {
-                       found = 1;
-                       break;
-               }
-       }
-       return found;
-}
-
-static u32 go_add_group_info_attr(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
-       struct list_head *phead, *plist;
-       u32 len = 0;
-       u16 attr_len = 0;
-       u8 tmplen, *pdata_attr, *pstart, *pcur;
-       struct sta_info *psta = NULL;
-       struct adapter *padapter = pwdinfo->padapter;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-
-       pdata_attr = kzalloc(MAX_P2P_IE_LEN, GFP_KERNEL);
-
-       pstart = pdata_attr;
-       pcur = pdata_attr;
-
-       spin_lock_bh(&pstapriv->asoc_list_lock);
-       phead = &pstapriv->asoc_list;
-       plist = phead->next;
-
-       /* look up sta asoc_queue */
-       while (phead != plist) {
-               psta = container_of(plist, struct sta_info, asoc_list);
-
-               plist = plist->next;
-
-               if (psta->is_p2p_device) {
-                       tmplen = 0;
-
-                       pcur++;
-
-                       /* P2P device address */
-                       memcpy(pcur, psta->dev_addr, ETH_ALEN);
-                       pcur += ETH_ALEN;
-
-                       /* P2P interface address */
-                       memcpy(pcur, psta->hwaddr, ETH_ALEN);
-                       pcur += ETH_ALEN;
-
-                       *pcur = psta->dev_cap;
-                       pcur++;
-
-                       /* u16*)(pcur) = cpu_to_be16(psta->config_methods); */
-                       RTW_PUT_BE16(pcur, psta->config_methods);
-                       pcur += 2;
-
-                       memcpy(pcur, psta->primary_dev_type, 8);
-                       pcur += 8;
-
-                       *pcur = psta->num_of_secdev_type;
-                       pcur++;
-
-                       memcpy(pcur, psta->secdev_types_list, psta->num_of_secdev_type * 8);
-                       pcur += psta->num_of_secdev_type * 8;
-
-                       if (psta->dev_name_len > 0) {
-                               /* u16*)(pcur) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */
-                               RTW_PUT_BE16(pcur, WPS_ATTR_DEVICE_NAME);
-                               pcur += 2;
-
-                               /* u16*)(pcur) = cpu_to_be16(psta->dev_name_len); */
-                               RTW_PUT_BE16(pcur, psta->dev_name_len);
-                               pcur += 2;
-
-                               memcpy(pcur, psta->dev_name, psta->dev_name_len);
-                               pcur += psta->dev_name_len;
-                       }
-
-                       tmplen = (u8)(pcur - pstart);
-
-                       *pstart = (tmplen - 1);
-
-                       attr_len += tmplen;
-
-                       /* pstart += tmplen; */
-                       pstart = pcur;
-               }
-       }
-       spin_unlock_bh(&pstapriv->asoc_list_lock);
-
-       if (attr_len > 0)
-               len = rtw_set_p2p_attr_content(pbuf, P2P_ATTR_GROUP_INFO, attr_len, pdata_attr);
-
-       kfree(pdata_attr);
-       return len;
-}
-
-static void issue_group_disc_req(struct wifidirect_info *pwdinfo, u8 *da)
-{
-       struct xmit_frame                       *pmgntframe;
-       struct pkt_attrib                       *pattrib;
-       unsigned char                                   *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       struct adapter *padapter = pwdinfo->padapter;
-       struct xmit_priv                        *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       unsigned char category = RTW_WLAN_CATEGORY_P2P;/* P2P action frame */
-       __be32  p2poui = cpu_to_be32(P2POUI);
-       u8      oui_subtype = P2P_GO_DISC_REQUEST;
-       u8      dialogToken = 0;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       memcpy(pwlanhdr->addr1, da, ETH_ALEN);
-       memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN);
-       memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(pframe, WIFI_ACTION);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       /* Build P2P action frame header */
-       pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen);
-
-       /* there is no IE in this P2P action frame */
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       dump_mgntframe(padapter, pmgntframe);
-}
-
-static void issue_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken)
-{
-       struct xmit_frame                       *pmgntframe;
-       struct pkt_attrib                       *pattrib;
-       unsigned char                                   *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       struct adapter *padapter = pwdinfo->padapter;
-       struct xmit_priv                        *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       unsigned char category = WLAN_CATEGORY_PUBLIC;
-       u8                      action = P2P_PUB_ACTION_ACTION;
-       __be32                  p2poui = cpu_to_be32(P2POUI);
-       u8                      oui_subtype = P2P_DEVDISC_RESP;
-       u8 p2pie[8] = { 0x00 };
-       u32 p2pielen = 0;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       memcpy(pwlanhdr->addr1, da, ETH_ALEN);
-       memcpy(pwlanhdr->addr2, pwdinfo->device_addr, ETH_ALEN);
-       memcpy(pwlanhdr->addr3, pwdinfo->device_addr, ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(pframe, WIFI_ACTION);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       /* Build P2P public action frame header */
-       pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen);
-
-       /* Build P2P IE */
-       /*      P2P OUI */
-       p2pielen = 0;
-       p2pie[p2pielen++] = 0x50;
-       p2pie[p2pielen++] = 0x6F;
-       p2pie[p2pielen++] = 0x9A;
-       p2pie[p2pielen++] = 0x09;       /*      WFA P2P v1.0 */
-
-       /*  P2P_ATTR_STATUS */
-       p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status);
-
-       pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &pattrib->pktlen);
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       dump_mgntframe(padapter, pmgntframe);
-}
-
-static void issue_p2p_provision_resp(struct wifidirect_info *pwdinfo, u8 *raddr, u8 *frame_body, u16 config_method)
-{
-       struct adapter *padapter = pwdinfo->padapter;
-       unsigned char category = WLAN_CATEGORY_PUBLIC;
-       u8                      action = P2P_PUB_ACTION_ACTION;
-       u8                      dialogToken = frame_body[7];    /*      The Dialog Token of provisioning discovery request frame. */
-       __be32                  p2poui = cpu_to_be32(P2POUI);
-       u8                      oui_subtype = P2P_PROVISION_DISC_RESP;
-       u8                      wpsie[100] = { 0x00 };
-       u8                      wpsielen = 0;
-       struct xmit_frame                       *pmgntframe;
-       struct pkt_attrib                       *pattrib;
-       unsigned char                                   *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       struct xmit_priv                        *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
-       memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
-       memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(pframe, WIFI_ACTION);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen);
-
-       wpsielen = 0;
-       /*      WPS OUI */
-       RTW_PUT_BE32(wpsie, WPSOUI);
-       wpsielen += 4;
-
-       /*      Config Method */
-       /*      Type: */
-       RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
-       wpsielen += 2;
-
-       /*      Length: */
-       RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
-       wpsielen += 2;
-
-       /*      Value: */
-       RTW_PUT_BE16(wpsie + wpsielen, config_method);
-       wpsielen += 2;
-
-       pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen);
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       dump_mgntframe(padapter, pmgntframe);
-}
-
-static void issue_p2p_presence_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken)
-{
-       struct xmit_frame                       *pmgntframe;
-       struct pkt_attrib                       *pattrib;
-       unsigned char                                   *pframe;
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       struct adapter *padapter = pwdinfo->padapter;
-       struct xmit_priv                        *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       unsigned char category = RTW_WLAN_CATEGORY_P2P;/* P2P action frame */
-       __be32  p2poui = cpu_to_be32(P2POUI);
-       u8      oui_subtype = P2P_PRESENCE_RESPONSE;
-       u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 };
-       u8 noa_attr_content[32] = { 0x00 };
-       u32 p2pielen = 0;
-
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               return;
-
-       /* update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(padapter, pattrib);
-
-       memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
-       pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       memcpy(pwlanhdr->addr1, da, ETH_ALEN);
-       memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN);
-       memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
-       pmlmeext->mgnt_seq++;
-       SetFrameSubType(pframe, WIFI_ACTION);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       /* Build P2P action frame header */
-       pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
-       pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen);
-
-       /* Add P2P IE header */
-       /*      P2P OUI */
-       p2pielen = 0;
-       p2pie[p2pielen++] = 0x50;
-       p2pie[p2pielen++] = 0x6F;
-       p2pie[p2pielen++] = 0x9A;
-       p2pie[p2pielen++] = 0x09;       /*      WFA P2P v1.0 */
-
-       /* Add Status attribute in P2P IE */
-       p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status);
-
-       /* Add NoA attribute in P2P IE */
-       noa_attr_content[0] = 0x1;/* index */
-       noa_attr_content[1] = 0x0;/* CTWindow and OppPS Parameters */
-
-       /* todo: Notice of Absence Descriptor(s) */
-
-       p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_NOA, 2, noa_attr_content);
-
-       pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &pattrib->pktlen);
-
-       pattrib->last_txcmdsz = pattrib->pktlen;
-
-       dump_mgntframe(padapter, pmgntframe);
-}
-
-u32 build_beacon_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
-       u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 };
-       u16 capability = 0;
-       u32 len = 0, p2pielen = 0;
-       __le16 le_tmp;
-
-       /*      P2P OUI */
-       p2pielen = 0;
-       p2pie[p2pielen++] = 0x50;
-       p2pie[p2pielen++] = 0x6F;
-       p2pie[p2pielen++] = 0x9A;
-       p2pie[p2pielen++] = 0x09;       /*      WFA P2P v1.0 */
-
-       /*      According to the P2P Specification, the beacon frame should contain 3 P2P attributes */
-       /*      1. P2P Capability */
-       /*      2. P2P Device ID */
-       /*      3. Notice of Absence (NOA) */
-
-       /*      P2P Capability ATTR */
-       /*      Type: */
-       /*      Length: */
-       /*      Value: */
-       /*      Device Capability Bitmap, 1 byte */
-       /*      Be able to participate in additional P2P Groups and */
-       /*      support the P2P Invitation Procedure */
-       /*      Group Capability Bitmap, 1 byte */
-       capability = P2P_DEVCAP_INVITATION_PROC | P2P_DEVCAP_CLIENT_DISCOVERABILITY;
-       capability |=  ((P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS) << 8);
-       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
-               capability |= (P2P_GRPCAP_GROUP_FORMATION << 8);
-
-       le_tmp = cpu_to_le16(capability);
-       p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_CAPABILITY, 2, (u8 *)&le_tmp);
-
-       /*  P2P Device ID ATTR */
-       p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_DEVICE_ID, ETH_ALEN, pwdinfo->device_addr);
-
-       /*  Notice of Absence ATTR */
-       /*      Type: */
-       /*      Length: */
-       /*      Value: */
-
-       pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len);
-       return len;
-}
-
-u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
-       u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 };
-       u32 len = 0, p2pielen = 0;
-
-       /*      P2P OUI */
-       p2pielen = 0;
-       p2pie[p2pielen++] = 0x50;
-       p2pie[p2pielen++] = 0x6F;
-       p2pie[p2pielen++] = 0x9A;
-       p2pie[p2pielen++] = 0x09;       /*      WFA P2P v1.0 */
-
-       /*      Commented by Albert 20100907 */
-       /*      According to the P2P Specification, the probe response frame should contain 5 P2P attributes */
-       /*      1. P2P Capability */
-       /*      2. Extended Listen Timing */
-       /*      3. Notice of Absence (NOA)      (Only GO needs this) */
-       /*      4. Device Info */
-       /*      5. Group Info   (Only GO need this) */
-
-       /*      P2P Capability ATTR */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
-       /*      Length: */
-       /* u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002); */
-       RTW_PUT_LE16(p2pie + p2pielen, 0x0002);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Device Capability Bitmap, 1 byte */
-       p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
-
-       /*      Group Capability Bitmap, 1 byte */
-       if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
-               p2pie[p2pielen] = (P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS);
-
-               if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
-                       p2pie[p2pielen] |= P2P_GRPCAP_GROUP_FORMATION;
-
-               p2pielen++;
-       } else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) {
-               /*      Group Capability Bitmap, 1 byte */
-               if (pwdinfo->persistent_supported)
-                       p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
-               else
-                       p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
-       }
-
-       /*      Extended Listen Timing ATTR */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
-
-       /*      Length: */
-       /* u16*) (p2pie + p2pielen) = cpu_to_le16(0x0004); */
-       RTW_PUT_LE16(p2pie + p2pielen, 0x0004);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Availability Period */
-       /* u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF); */
-       RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF);
-       p2pielen += 2;
-
-       /*      Availability Interval */
-       /* u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF); */
-       RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF);
-       p2pielen += 2;
-
-       /*  Notice of Absence ATTR */
-       /*      Type: */
-       /*      Length: */
-       /*      Value: */
-
-       /*      Device Info ATTR */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
-
-       /*      Length: */
-       /*      21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
-       /*      + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
-       /* u16*) (p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); */
-       RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      P2P Device Address */
-       memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);
-       p2pielen += ETH_ALEN;
-
-       /*      Config Method */
-       /*      This field should be big endian. Noted by P2P specification. */
-       /* u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm); */
-       RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->supported_wps_cm);
-       p2pielen += 2;
-
-       /*      Primary Device Type */
-       /*      Category ID */
-       /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); */
-       RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA);
-       p2pielen += 2;
-
-       /*      OUI */
-       /* u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI); */
-       RTW_PUT_BE32(p2pie + p2pielen, WPSOUI);
-       p2pielen += 4;
-
-       /*      Sub Category ID */
-       /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); */
-       RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER);
-       p2pielen += 2;
-
-       /*      Number of Secondary Device Types */
-       p2pie[p2pielen++] = 0x00;       /*      No Secondary Device Type List */
-
-       /*      Device Name */
-       /*      Type: */
-       /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */
-       RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME);
-       p2pielen += 2;
-
-       /*      Length: */
-       /* u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); */
-       RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->device_name_len);
-       p2pielen += 2;
-
-       /*      Value: */
-       memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
-       p2pielen += pwdinfo->device_name_len;
-
-       /*  Group Info ATTR */
-       /*      Type: */
-       /*      Length: */
-       /*      Value: */
-       if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
-               p2pielen += go_add_group_info_attr(pwdinfo, p2pie + p2pielen);
-
-       pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len);
-
-       return len;
-}
-
-u32 build_prov_disc_request_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 *pssid, u8 ussidlen, u8 *pdev_raddr)
-{
-       u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 };
-       u32 len = 0, p2pielen = 0;
-
-       /*      P2P OUI */
-       p2pielen = 0;
-       p2pie[p2pielen++] = 0x50;
-       p2pie[p2pielen++] = 0x6F;
-       p2pie[p2pielen++] = 0x9A;
-       p2pie[p2pielen++] = 0x09;       /*      WFA P2P v1.0 */
-
-       /*      Commented by Albert 20110301 */
-       /*      According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes */
-       /*      1. P2P Capability */
-       /*      2. Device Info */
-       /*      3. Group ID (When joining an operating P2P Group) */
-
-       /*      P2P Capability ATTR */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
-       /*      Length: */
-       /* u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002); */
-       RTW_PUT_LE16(p2pie + p2pielen, 0x0002);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      Device Capability Bitmap, 1 byte */
-       p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
-
-       /*      Group Capability Bitmap, 1 byte */
-       if (pwdinfo->persistent_supported)
-               p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
-       else
-               p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
-
-       /*      Device Info ATTR */
-       /*      Type: */
-       p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
-
-       /*      Length: */
-       /*      21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
-       /*      + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
-       /* u16*) (p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); */
-       RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len);
-       p2pielen += 2;
-
-       /*      Value: */
-       /*      P2P Device Address */
-       memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);
-       p2pielen += ETH_ALEN;
-
-       /*      Config Method */
-       /*      This field should be big endian. Noted by P2P specification. */
-       if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC) {
-               /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_PBC); */
-               RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_PBC);
-       } else {
-               /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY); */
-               RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_DISPLAY);
-       }
-
-       p2pielen += 2;
-
-       /*      Primary Device Type */
-       /*      Category ID */
-       /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); */
-       RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA);
-       p2pielen += 2;
-
-       /*      OUI */
-       /* u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI); */
-       RTW_PUT_BE32(p2pie + p2pielen, WPSOUI);
-       p2pielen += 4;
-
-       /*      Sub Category ID */
-       /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); */
-       RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER);
-       p2pielen += 2;
-
-       /*      Number of Secondary Device Types */
-       p2pie[p2pielen++] = 0x00;       /*      No Secondary Device Type List */
-
-       /*      Device Name */
-       /*      Type: */
-       /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */
-       RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME);
-       p2pielen += 2;
-
-       /*      Length: */
-       /* u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); */
-       RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->device_name_len);
-       p2pielen += 2;
-
-       /*      Value: */
-       memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
-       p2pielen += pwdinfo->device_name_len;
-
-       if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
-               /*      Added by Albert 2011/05/19 */
-               /*      In this case, the pdev_raddr is the device address of the group owner. */
-
-               /*      P2P Group ID ATTR */
-               /*      Type: */
-               p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
-
-               /*      Length: */
-               /* u16*) (p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + ussidlen); */
-               RTW_PUT_LE16(p2pie + p2pielen, ETH_ALEN + ussidlen);
-               p2pielen += 2;
-
-               /*      Value: */
-               memcpy(p2pie + p2pielen, pdev_raddr, ETH_ALEN);
-               p2pielen += ETH_ALEN;
-
-               memcpy(p2pie + p2pielen, pssid, ussidlen);
-               p2pielen += ussidlen;
-       }
-
-       pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len);
-
-       return len;
-}
-
-u32 build_assoc_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 status_code)
-{
-       u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 };
-       u32 len = 0, p2pielen = 0;
-
-       /*      P2P OUI */
-       p2pielen = 0;
-       p2pie[p2pielen++] = 0x50;
-       p2pie[p2pielen++] = 0x6F;
-       p2pie[p2pielen++] = 0x9A;
-       p2pie[p2pielen++] = 0x09;       /*      WFA P2P v1.0 */
-
-       /*  According to the P2P Specification, the Association response frame should contain 2 P2P attributes */
-       /*      1. Status */
-       /*      2. Extended Listen Timing (optional) */
-
-       /*      Status ATTR */
-       p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status_code);
-
-       /*  Extended Listen Timing ATTR */
-       /*      Type: */
-       /*      Length: */
-       /*      Value: */
-
-       pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len);
-
-       return len;
-}
-
-u32 process_probe_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
-       u8 *p;
-       u32 ret = false;
-       u8 *p2pie;
-       u32     p2pielen = 0;
-       int ssid_len = 0, rate_cnt = 0;
-
-       p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SUPPORTEDRATES_IE_, (int *)&rate_cnt,
-                       len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
-
-       if (rate_cnt <= 4) {
-               int i, g_rate = 0;
-
-               for (i = 0; i < rate_cnt; i++) {
-                       if (((*(p + 2 + i) & 0xff) != 0x02) &&
-                           ((*(p + 2 + i) & 0xff) != 0x04) &&
-                           ((*(p + 2 + i) & 0xff) != 0x0B) &&
-                           ((*(p + 2 + i) & 0xff) != 0x16))
-                               g_rate = 1;
-               }
-
-               if (g_rate == 0) {
-                       /*      There is no OFDM rate included in SupportedRates IE of this probe request frame */
-                       /*      The driver should response this probe request. */
-                       return ret;
-               }
-       } else {
-               /*      rate_cnt > 4 means the SupportRates IE contains the OFDM rate because the count of CCK rates are 4. */
-               /*      We should proceed the following check for this probe request. */
-       }
-
-       /*      Added comments by Albert 20100906 */
-       /*      There are several items we should check here. */
-       /*      1. This probe request frame must contain the P2P IE. (Done) */
-       /*      2. This probe request frame must contain the wildcard SSID. (Done) */
-       /*      3. Wildcard BSSID. (Todo) */
-       /*      4. Destination Address. (Done in mgt_dispatcher function) */
-       /*      5. Requested Device Type in WSC IE. (Todo) */
-       /*      6. Device ID attribute in P2P IE. (Todo) */
-
-       p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ssid_len,
-                       len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
-
-       ssid_len &= 0xff;       /*      Just last 1 byte is valid for ssid len of the probe request */
-       if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
-               p2pie = rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_, NULL, &p2pielen);
-               if (p2pie) {
-                       if (p && !memcmp((void *)(p + 2), (void *)pwdinfo->p2p_wildcard_ssid, 7)) {
-                               /* todo: */
-                               /* Check Requested Device Type attributes in WSC IE. */
-                               /* Check Device ID attribute in P2P IE */
-
-                               ret = true;
-                       } else if (p && ssid_len == 0) {
-                               ret = true;
-                       }
-               } else {
-                       /* non -p2p device */
-               }
-       }
-
-       return ret;
-}
-
-u32 process_assoc_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len, struct sta_info *psta)
-{
-       u8 status_code = P2P_STATUS_SUCCESS;
-       u8 *pbuf, *pattr_content = NULL;
-       u32 attr_contentlen = 0;
-       u16 cap_attr = 0;
-       unsigned short  frame_type, ie_offset = 0;
-       u8 *ies;
-       u32 ies_len;
-       u8 *p2p_ie;
-       u32     p2p_ielen = 0;
-       __be16 be_tmp;
-       __le16 le_tmp;
-
-       if (!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
-               return P2P_STATUS_FAIL_REQUEST_UNABLE;
-
-       frame_type = GetFrameSubType(pframe);
-       if (frame_type == WIFI_ASSOCREQ)
-               ie_offset = _ASOCREQ_IE_OFFSET_;
-       else /*  WIFI_REASSOCREQ */
-               ie_offset = _REASOCREQ_IE_OFFSET_;
-
-       ies = pframe + WLAN_HDR_A3_LEN + ie_offset;
-       ies_len = len - WLAN_HDR_A3_LEN - ie_offset;
-
-       p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen);
-
-       if (!p2p_ie)
-               status_code =  P2P_STATUS_FAIL_INVALID_PARAM;
-
-       while (p2p_ie) {
-               /* Check P2P Capability ATTR */
-               if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8 *)&le_tmp, (uint *)&attr_contentlen)) {
-                       cap_attr = le16_to_cpu(le_tmp);
-                       psta->dev_cap = cap_attr & 0xff;
-               }
-
-               /* Check Extended Listen Timing ATTR */
-
-               /* Check P2P Device Info ATTR */
-               if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, NULL, (uint *)&attr_contentlen)) {
-                       pattr_content = kzalloc(attr_contentlen, GFP_KERNEL);
-                       pbuf = pattr_content;
-                       if (pattr_content) {
-                               u8 num_of_secdev_type;
-                               u16 dev_name_len;
-
-                               rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, pattr_content, (uint *)&attr_contentlen);
-
-                               memcpy(psta->dev_addr,  pattr_content, ETH_ALEN);/* P2P Device Address */
-
-                               pattr_content += ETH_ALEN;
-
-                               memcpy(&be_tmp, pattr_content, 2);/* Config Methods */
-                               psta->config_methods = be16_to_cpu(be_tmp);
-
-                               pattr_content += 2;
-
-                               memcpy(psta->primary_dev_type, pattr_content, 8);
-
-                               pattr_content += 8;
-
-                               num_of_secdev_type = *pattr_content;
-                               pattr_content += 1;
-
-                               if (num_of_secdev_type == 0) {
-                                       psta->num_of_secdev_type = 0;
-                               } else {
-                                       u32 len;
-
-                                       psta->num_of_secdev_type = num_of_secdev_type;
-
-                                       len = (sizeof(psta->secdev_types_list) < (num_of_secdev_type * 8)) ?
-                                             (sizeof(psta->secdev_types_list)) : (num_of_secdev_type * 8);
-
-                                       memcpy(psta->secdev_types_list, pattr_content, len);
-
-                                       pattr_content += (num_of_secdev_type * 8);
-                               }
-
-                               psta->dev_name_len = 0;
-                               if (be16_to_cpu(*(__be16 *)pattr_content) == WPS_ATTR_DEVICE_NAME) {
-                                       dev_name_len = be16_to_cpu(*(__be16 *)(pattr_content + 2));
-
-                                       psta->dev_name_len = (sizeof(psta->dev_name) < dev_name_len) ? sizeof(psta->dev_name) : dev_name_len;
-
-                                       memcpy(psta->dev_name, pattr_content + 4, psta->dev_name_len);
-                               }
-                               kfree(pbuf);
-                       }
-               }
-
-               /* Get the next P2P IE */
-               p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
-       }
-
-       return status_code;
-}
-
-u32 process_p2p_devdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
-       u8 *frame_body;
-       u8 status, dialogToken;
-       struct sta_info *psta = NULL;
-       struct adapter *padapter = pwdinfo->padapter;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       u8 *p2p_ie;
-       u32     p2p_ielen = 0;
-
-       frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
-
-       dialogToken = frame_body[7];
-       status = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
-
-       p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen);
-       if (p2p_ie) {
-               u8 groupid[38] = { 0x00 };
-               u8 dev_addr[ETH_ALEN] = { 0x00 };
-               u32     attr_contentlen = 0;
-
-               if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) {
-                       if (!memcmp(pwdinfo->device_addr, groupid, ETH_ALEN) &&
-                           !memcmp(pwdinfo->p2p_group_ssid, groupid + ETH_ALEN, pwdinfo->p2p_group_ssid_len)) {
-                               attr_contentlen = 0;
-                               if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_ID, dev_addr, &attr_contentlen)) {
-                                       struct list_head *phead, *plist;
-
-                                       spin_lock_bh(&pstapriv->asoc_list_lock);
-                                       phead = &pstapriv->asoc_list;
-                                       plist = phead->next;
-
-                                       /* look up sta asoc_queue */
-                                       while (phead != plist) {
-                                               psta = container_of(plist, struct sta_info, asoc_list);
-
-                                               plist = plist->next;
-
-                                               if (psta->is_p2p_device && (psta->dev_cap & P2P_DEVCAP_CLIENT_DISCOVERABILITY) &&
-                                                   !memcmp(psta->dev_addr, dev_addr, ETH_ALEN)) {
-                                                       /* issue GO Discoverability Request */
-                                                       issue_group_disc_req(pwdinfo, psta->hwaddr);
-                                                       status = P2P_STATUS_SUCCESS;
-                                                       break;
-                                               } else {
-                                                       status = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
-                                               }
-                                       }
-                                       spin_unlock_bh(&pstapriv->asoc_list_lock);
-                               } else {
-                                       status = P2P_STATUS_FAIL_INVALID_PARAM;
-                               }
-                       } else {
-                               status = P2P_STATUS_FAIL_INVALID_PARAM;
-                       }
-               }
-       }
-
-       /* issue Device Discoverability Response */
-       issue_p2p_devdisc_resp(pwdinfo, GetAddr2Ptr(pframe), status, dialogToken);
-
-       return status == P2P_STATUS_SUCCESS;
-}
-
-u32 process_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
-       return true;
-}
-
-u8 process_p2p_provdisc_req(struct wifidirect_info *pwdinfo,  u8 *pframe, uint len)
-{
-       u8 *frame_body;
-       u8 *wpsie;
-       uint    wps_ielen = 0, attr_contentlen = 0;
-       u16     uconfig_method = 0;
-       __be16 be_tmp;
-
-       frame_body = (pframe + sizeof(struct ieee80211_hdr_3addr));
-
-       wpsie = rtw_get_wps_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen);
-       if (wpsie) {
-               if (rtw_get_wps_attr_content(wpsie, wps_ielen, WPS_ATTR_CONF_METHOD, (u8 *)&be_tmp, &attr_contentlen)) {
-                       uconfig_method = be16_to_cpu(be_tmp);
-                       switch (uconfig_method) {
-                       case WPS_CM_DISPLYA:
-                               memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3);
-                               break;
-                       case WPS_CM_LABEL:
-                               memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "lab", 3);
-                               break;
-                       case WPS_CM_PUSH_BUTTON:
-                               memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3);
-                               break;
-                       case WPS_CM_KEYPAD:
-                               memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3);
-                               break;
-                       }
-                       issue_p2p_provision_resp(pwdinfo, GetAddr2Ptr(pframe), frame_body, uconfig_method);
-               }
-       }
-       return true;
-}
-
-u8 process_p2p_provdisc_resp(struct wifidirect_info *pwdinfo,  u8 *pframe)
-{
-       return true;
-}
-
-static u8 rtw_p2p_get_peer_ch_list(struct wifidirect_info *pwdinfo, u8 *ch_content, u8 ch_cnt, u8 *peer_ch_list)
-{
-       u8 i = 0, j = 0;
-       u8 temp = 0;
-       u8 ch_no = 0;
-       ch_content += 3;
-       ch_cnt -= 3;
-
-       while (ch_cnt > 0) {
-               ch_content += 1;
-               ch_cnt -= 1;
-               temp = *ch_content;
-               for (i = 0 ; i < temp ; i++, j++)
-                       peer_ch_list[j] = *(ch_content + 1 + i);
-               ch_content += (temp + 1);
-               ch_cnt -= (temp + 1);
-               ch_no += temp;
-       }
-
-       return ch_no;
-}
-
-static u8 rtw_p2p_ch_inclusion(struct mlme_ext_priv *pmlmeext, u8 *peer_ch_list, u8 peer_ch_num, u8 *ch_list_inclusioned)
-{
-       int     i = 0, j = 0, temp = 0;
-       u8 ch_no = 0;
-
-       for (i = 0; i < peer_ch_num; i++) {
-               for (j = temp; j < pmlmeext->max_chan_nums; j++) {
-                       if (*(peer_ch_list + i) == pmlmeext->channel_set[j].ChannelNum) {
-                               ch_list_inclusioned[ch_no++] = *(peer_ch_list + i);
-                               temp = j;
-                               break;
-                       }
-               }
-       }
-
-       return ch_no;
-}
-
-u8 process_p2p_group_negotation_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
-       struct adapter *padapter = pwdinfo->padapter;
-       u8      result = P2P_STATUS_SUCCESS;
-       u32     p2p_ielen = 0, wps_ielen = 0;
-       u8 *ies;
-       u32 ies_len;
-       u8 *p2p_ie;
-       u8 *wpsie;
-       u16             wps_devicepassword_id = 0x0000;
-       uint    wps_devicepassword_id_len = 0;
-       __be16 be_tmp;
-
-       wpsie = rtw_get_wps_ie(pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen);
-       if (wpsie) {
-               /*      Commented by Kurt 20120113 */
-               /*      If some device wants to do p2p handshake without sending prov_disc_req */
-               /*      We have to get peer_req_cm from here. */
-               if (!memcmp(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3)) {
-                       rtw_get_wps_attr_content(wpsie, wps_ielen, WPS_ATTR_DEVICE_PWID, (u8 *)&be_tmp, &wps_devicepassword_id_len);
-                       wps_devicepassword_id = be16_to_cpu(be_tmp);
-
-                       if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
-                               memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3);
-                       else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
-                               memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3);
-                       else
-                               memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3);
-               }
-       } else {
-               result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
-               rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
-               return result;
-       }
-
-       if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO) {
-               result = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
-               rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INFOR_NOREADY);
-               return result;
-       }
-
-       ies = pframe + _PUBLIC_ACTION_IE_OFFSET_;
-       ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
-
-       p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen);
-
-       if (!p2p_ie) {
-               result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
-               rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
-       }
-
-       while (p2p_ie) {
-               u8      attr_content = 0x00;
-               u32     attr_contentlen = 0;
-               u8      ch_content[50] = { 0x00 };
-               uint    ch_cnt = 0;
-               u8      peer_ch_list[50] = { 0x00 };
-               u8      peer_ch_num = 0;
-               u8      ch_list_inclusioned[50] = { 0x00 };
-               u8      ch_num_inclusioned = 0;
-
-               rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
-
-               if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, &attr_content, &attr_contentlen)) {
-                       pwdinfo->peer_intent = attr_content;    /*      include both intent and tie breaker values. */
-
-                       if (pwdinfo->intent == (pwdinfo->peer_intent >> 1)) {
-                               /*      Try to match the tie breaker value */
-                               if (pwdinfo->intent == P2P_MAX_INTENT) {
-                                       rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
-                                       result = P2P_STATUS_FAIL_BOTH_GOINTENT_15;
-                               } else {
-                                       if (attr_content & 0x01)
-                                               rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
-                                       else
-                                               rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
-                               }
-                       } else if (pwdinfo->intent > (pwdinfo->peer_intent >> 1)) {
-                               rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
-                       } else {
-                               rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
-                       }
-
-                       if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
-                               /*      Store the group id information. */
-                               memcpy(pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN);
-                               memcpy(pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
-                       }
-               }
-
-               attr_contentlen = 0;
-               if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen)) {
-                       if (attr_contentlen != ETH_ALEN)
-                               memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN);
-               }
-
-               if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, ch_content, &ch_cnt)) {
-                       peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, ch_content, ch_cnt, peer_ch_list);
-                       ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned);
-
-                       if (ch_num_inclusioned == 0) {
-                               result = P2P_STATUS_FAIL_NO_COMMON_CH;
-                               rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
-                               break;
-                       }
-
-                       if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
-                               if (!rtw_p2p_is_channel_list_ok(pwdinfo->operating_channel,
-                                   ch_list_inclusioned, ch_num_inclusioned)) {
-                                       u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0;
-                                       attr_contentlen = 0;
-
-                                       if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen))
-                                               peer_operating_ch = operatingch_info[4];
-
-                                       if (rtw_p2p_is_channel_list_ok(peer_operating_ch,
-                                                                      ch_list_inclusioned,
-                                                                      ch_num_inclusioned))
-                                               /**
-                                                *      Change our operating channel as peer's for compatibility.
-                                                */
-                                               pwdinfo->operating_channel = peer_operating_ch;
-                                       else
-                                               /*  Take first channel of ch_list_inclusioned as operating channel */
-                                               pwdinfo->operating_channel = ch_list_inclusioned[0];
-                               }
-                       }
-               }
-
-               /* Get the next P2P IE */
-               p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
-       }
-       return result;
-}
-
-u8 process_p2p_group_negotation_resp(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
-       struct adapter *padapter = pwdinfo->padapter;
-       u8      result = P2P_STATUS_SUCCESS;
-       u32     p2p_ielen, wps_ielen;
-       u8 *ies;
-       u32 ies_len;
-       u8 *p2p_ie;
-
-       ies = pframe + _PUBLIC_ACTION_IE_OFFSET_;
-       ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
-
-       /*      Be able to know which one is the P2P GO and which one is P2P client. */
-
-       if (!rtw_get_wps_ie(ies, ies_len, NULL, &wps_ielen)) {
-               result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
-               rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
-       }
-
-       p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen);
-       if (!p2p_ie) {
-               rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
-               rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
-               result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
-       } else {
-               u8      attr_content = 0x00;
-               u32     attr_contentlen = 0;
-               u8      operatingch_info[5] = { 0x00 };
-               u8      groupid[38];
-               u8      peer_ch_list[50] = { 0x00 };
-               u8      peer_ch_num = 0;
-               u8      ch_list_inclusioned[50] = { 0x00 };
-               u8      ch_num_inclusioned = 0;
-
-               while (p2p_ie) {        /*      Found the P2P IE. */
-                       rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
-                       if (attr_contentlen == 1) {
-                               if (attr_content == P2P_STATUS_SUCCESS) {
-                                       /*      Do nothing. */
-                               } else {
-                                       if (attr_content == P2P_STATUS_FAIL_INFO_UNAVAILABLE) {
-                                               rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INFOR_NOREADY);
-                                       } else {
-                                               rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
-                                       }
-                                       rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
-                                       result = attr_content;
-                                       break;
-                               }
-                       }
-
-                       /*      Try to get the peer's interface address */
-                       attr_contentlen = 0;
-                       if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen)) {
-                               if (attr_contentlen != ETH_ALEN)
-                                       memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN);
-                       }
-
-                       /*      Try to get the peer's intent and tie breaker value. */
-                       attr_content = 0x00;
-                       attr_contentlen = 0;
-                       if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, &attr_content, &attr_contentlen)) {
-                               pwdinfo->peer_intent = attr_content;    /*      include both intent and tie breaker values. */
-
-                               if (pwdinfo->intent == (pwdinfo->peer_intent >> 1)) {
-                                       /*      Try to match the tie breaker value */
-                                       if (pwdinfo->intent == P2P_MAX_INTENT) {
-                                               rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
-                                               result = P2P_STATUS_FAIL_BOTH_GOINTENT_15;
-                                               rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
-                                       } else {
-                                               rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
-                                               rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
-                                               if (attr_content & 0x01)
-                                                       rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
-                                               else
-                                                       rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
-                                       }
-                               } else if (pwdinfo->intent > (pwdinfo->peer_intent >> 1)) {
-                                       rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
-                                       rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
-                                       rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
-                               } else {
-                                       rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
-                                       rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
-                                       rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
-                               }
-
-                               if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
-                                       /*      Store the group id information. */
-                                       memcpy(pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN);
-                                       memcpy(pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
-                               }
-                       }
-
-                       /*      Try to get the operation channel information */
-
-                       attr_contentlen = 0;
-                       if (rtw_get_p2p_attr_content(p2p_ie,
-                                                    p2p_ielen,
-                                                    P2P_ATTR_OPERATING_CH,
-                                                    operatingch_info,
-                                                    &attr_contentlen))
-                               pwdinfo->peer_operating_ch = operatingch_info[4];
-
-                       /*      Try to get the channel list information */
-                       if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, pwdinfo->channel_list_attr, &pwdinfo->channel_list_attr_len)) {
-
-                               peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len, peer_ch_list);
-                               ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned);
-
-                               if (ch_num_inclusioned == 0) {
-                                       result = P2P_STATUS_FAIL_NO_COMMON_CH;
-                                       rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
-                                       break;
-                               }
-
-                               if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
-                                       if (!rtw_p2p_is_channel_list_ok(pwdinfo->operating_channel,
-                                           ch_list_inclusioned, ch_num_inclusioned)) {
-                                               u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0;
-                                               attr_contentlen = 0;
-
-                                               if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen))
-                                                       peer_operating_ch = operatingch_info[4];
-
-                                               if (rtw_p2p_is_channel_list_ok(peer_operating_ch,
-                                                   ch_list_inclusioned, ch_num_inclusioned))
-                                                       /**
-                                                        *      Change our operating channel as peer's for compatibility.
-                                                        */
-                                                       pwdinfo->operating_channel = peer_operating_ch;
-                                               else
-                                                       /*  Take first channel of ch_list_inclusioned as operating channel */
-                                                       pwdinfo->operating_channel = ch_list_inclusioned[0];
-                                       }
-                               }
-                       }
-
-                       /*      Try to get the group id information if peer is GO */
-                       attr_contentlen = 0;
-                       memset(groupid, 0x00, 38);
-                       if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) {
-                               memcpy(pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN);
-                               memcpy(pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN);
-                       }
-
-                       /* Get the next P2P IE */
-                       p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
-               }
-       }
-       return result;
-}
-
-u8 process_p2p_group_negotation_confirm(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
-       u8 *ies;
-       u32 ies_len;
-       u8 *p2p_ie;
-       u32     p2p_ielen = 0;
-       u8      result = P2P_STATUS_SUCCESS;
-       ies = pframe + _PUBLIC_ACTION_IE_OFFSET_;
-       ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
-
-       p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen);
-       while (p2p_ie) {        /*      Found the P2P IE. */
-               u8      attr_content = 0x00, operatingch_info[5] = { 0x00 };
-               u8      groupid[38] = { 0x00 };
-               u32     attr_contentlen = 0;
-
-               pwdinfo->negotiation_dialog_token = 1;
-               rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
-               if (attr_contentlen == 1) {
-                       result = attr_content;
-
-                       if (attr_content == P2P_STATUS_SUCCESS) {
-                               del_timer_sync(&pwdinfo->restore_p2p_state_timer);
-
-                               /*      Commented by Albert 20100911 */
-                               /*      Todo: Need to handle the case which both Intents are the same. */
-                               rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
-                               rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
-                               if ((pwdinfo->intent) > (pwdinfo->peer_intent >> 1)) {
-                                       rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
-                               } else if ((pwdinfo->intent) < (pwdinfo->peer_intent >> 1)) {
-                                       rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
-                               } else {
-                                       /*      Have to compare the Tie Breaker */
-                                       if (pwdinfo->peer_intent & 0x01)
-                                               rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
-                                       else
-                                               rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
-                               }
-                       } else {
-                               rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
-                               rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
-                               break;
-                       }
-               }
-
-               /*      Try to get the group id information */
-               attr_contentlen = 0;
-               memset(groupid, 0x00, 38);
-               if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) {
-                       memcpy(pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN);
-                       memcpy(pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN);
-               }
-
-               attr_contentlen = 0;
-               if (rtw_get_p2p_attr_content(p2p_ie,
-                                            p2p_ielen,
-                                            P2P_ATTR_OPERATING_CH,
-                                            operatingch_info,
-                                            &attr_contentlen))
-                       pwdinfo->peer_operating_ch = operatingch_info[4];
-
-               /* Get the next P2P IE */
-               p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
-       }
-       return result;
-}
-
-u8 process_p2p_presence_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
-       u8 *frame_body;
-       u8 dialogToken = 0;
-       u8 status = P2P_STATUS_SUCCESS;
-
-       frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
-
-       dialogToken = frame_body[6];
-
-       /* todo: check NoA attribute */
-
-       issue_p2p_presence_resp(pwdinfo, GetAddr2Ptr(pframe), status, dialogToken);
-
-       return true;
-}
-
-static void find_phase_handler(struct adapter *padapter)
-{
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-       struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
-       struct ndis_802_11_ssid ssid;
-
-       memset((unsigned char *)&ssid, 0, sizeof(struct ndis_802_11_ssid));
-       memcpy(ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN);
-       ssid.SsidLength = P2P_WILDCARD_SSID_LEN;
-
-       rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
-
-       spin_lock_bh(&pmlmepriv->lock);
-       spin_unlock_bh(&pmlmepriv->lock);
-
-}
-
-void p2p_concurrent_handler(struct adapter *padapter);
-
-static void restore_p2p_state_handler(struct adapter *padapter)
-{
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-
-       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
-               rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
-       rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
-
-       if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) {
-               /*      In the P2P client mode, the driver should not switch back to its listen channel */
-               /*      because this P2P client should stay at the operating channel of P2P GO. */
-               set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
-       }
-
-}
-
-static void pre_tx_invitereq_handler(struct adapter *padapter)
-{
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-
-       set_channel_bwmode(padapter, pwdinfo->invitereq_info.peer_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
-       rtw_mlme_under_site_survey(padapter);
-       issue_probereq_p2p(padapter);
-       _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
-
-}
-
-static void pre_tx_provdisc_handler(struct adapter *padapter)
-{
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-
-       set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
-       rtw_mlme_under_site_survey(padapter);
-       issue_probereq_p2p(padapter);
-       _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
-
-}
-
-static void pre_tx_negoreq_handler(struct adapter *padapter)
-{
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-
-       set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
-       rtw_mlme_under_site_survey(padapter);
-       issue_probereq_p2p(padapter);
-       _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
-
-}
-
-void p2p_protocol_wk_hdl(struct adapter *padapter, int intCmdType)
-{
-
-       switch (intCmdType) {
-       case P2P_FIND_PHASE_WK:
-               find_phase_handler(padapter);
-               break;
-       case P2P_RESTORE_STATE_WK:
-               restore_p2p_state_handler(padapter);
-               break;
-       case P2P_PRE_TX_PROVDISC_PROCESS_WK:
-               pre_tx_provdisc_handler(padapter);
-               break;
-       case P2P_PRE_TX_INVITEREQ_PROCESS_WK:
-               pre_tx_invitereq_handler(padapter);
-               break;
-       case P2P_PRE_TX_NEGOREQ_PROCESS_WK:
-               pre_tx_negoreq_handler(padapter);
-               break;
-       }
-
-}
-
-void process_p2p_ps_ie(struct adapter *padapter, u8 *IEs, u32 IELength)
-{
-       u8 *p2p_ie;
-       u32     p2p_ielen = 0;
-       u8      noa_attr[MAX_P2P_IE_LEN] = { 0x00 };/*  NoA length should be n*(13) + 2 */
-       u32     attr_contentlen = 0;
-
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-       u8      find_p2p = false, find_p2p_ps = false;
-       u8      noa_offset, noa_num, noa_index;
-
-       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
-               return;
-
-       p2p_ie = rtw_get_p2p_ie(IEs, IELength, NULL, &p2p_ielen);
-
-       while (p2p_ie) {
-               find_p2p = true;
-               /*  Get Notice of Absence IE. */
-               if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_NOA, noa_attr, &attr_contentlen)) {
-                       find_p2p_ps = true;
-                       noa_index = noa_attr[0];
-
-                       if ((pwdinfo->p2p_ps_mode == P2P_PS_NONE) ||
-                           (noa_index != pwdinfo->noa_index)) { /*  if index change, driver should reconfigure related setting. */
-                               pwdinfo->noa_index = noa_index;
-                               pwdinfo->opp_ps = noa_attr[1] >> 7;
-                               pwdinfo->ctwindow = noa_attr[1] & 0x7F;
-
-                               noa_offset = 2;
-                               noa_num = 0;
-                               /*  NoA length should be n*(13) + 2 */
-                               if (attr_contentlen > 2) {
-                                       while (noa_offset < attr_contentlen) {
-                                               /* memcpy(&wifidirect_info->noa_count[noa_num], &noa_attr[noa_offset], 1); */
-                                               pwdinfo->noa_count[noa_num] = noa_attr[noa_offset];
-                                               noa_offset += 1;
-
-                                               memcpy(&pwdinfo->noa_duration[noa_num], &noa_attr[noa_offset], 4);
-                                               noa_offset += 4;
-
-                                               memcpy(&pwdinfo->noa_interval[noa_num], &noa_attr[noa_offset], 4);
-                                               noa_offset += 4;
-
-                                               memcpy(&pwdinfo->noa_start_time[noa_num], &noa_attr[noa_offset], 4);
-                                               noa_offset += 4;
-
-                                               noa_num++;
-                                       }
-                               }
-                               pwdinfo->noa_num = noa_num;
-
-                               if (pwdinfo->opp_ps == 1) {
-                                       pwdinfo->p2p_ps_mode = P2P_PS_CTWINDOW;
-                                       /*  driver should wait LPS for entering CTWindow */
-                                       if (padapter->pwrctrlpriv.bFwCurrentInPSMode)
-                                               p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1);
-                               } else if (pwdinfo->noa_num > 0) {
-                                       pwdinfo->p2p_ps_mode = P2P_PS_NOA;
-                                       p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1);
-                               } else if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
-                                       p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1);
-                               }
-                       }
-
-                       break; /*  find target, just break. */
-               }
-
-               /* Get the next P2P IE */
-               p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, IELength - (p2p_ie - IEs + p2p_ielen), NULL, &p2p_ielen);
-       }
-
-       if (find_p2p) {
-               if ((pwdinfo->p2p_ps_mode > P2P_PS_NONE) && !find_p2p_ps)
-                       p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1);
-       }
-
-}
-
-void p2p_ps_wk_hdl(struct adapter *padapter, u8 p2p_ps_state)
-{
-       struct pwrctrl_priv             *pwrpriv = &padapter->pwrctrlpriv;
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-
-       /*  Pre action for p2p state */
-       switch (p2p_ps_state) {
-       case P2P_PS_DISABLE:
-               pwdinfo->p2p_ps_state = p2p_ps_state;
-
-               rtl8188e_set_p2p_ps_offload_cmd(padapter, p2p_ps_state);
-
-               pwdinfo->noa_index = 0;
-               pwdinfo->ctwindow = 0;
-               pwdinfo->opp_ps = 0;
-               pwdinfo->noa_num = 0;
-               pwdinfo->p2p_ps_mode = P2P_PS_NONE;
-               if (padapter->pwrctrlpriv.bFwCurrentInPSMode) {
-                       if (pwrpriv->smart_ps == 0) {
-                               pwrpriv->smart_ps = 2;
-                               rtw_set_firmware_ps_mode(padapter, pwrpriv->pwr_mode);
-                       }
-               }
-               break;
-       case P2P_PS_ENABLE:
-               if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
-                       pwdinfo->p2p_ps_state = p2p_ps_state;
-
-                       if (pwdinfo->ctwindow > 0) {
-                               if (pwrpriv->smart_ps != 0) {
-                                       pwrpriv->smart_ps = 0;
-                                       rtw_set_firmware_ps_mode(padapter, pwrpriv->pwr_mode);
-                               }
-                       }
-                       rtl8188e_set_p2p_ps_offload_cmd(padapter, p2p_ps_state);
-               }
-               break;
-       case P2P_PS_SCAN:
-       case P2P_PS_SCAN_DONE:
-       case P2P_PS_ALLSTASLEEP:
-               if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
-                       pwdinfo->p2p_ps_state = p2p_ps_state;
-                       rtl8188e_set_p2p_ps_offload_cmd(padapter, p2p_ps_state);
-               }
-               break;
-       default:
-               break;
-       }
-
-}
-
-u8 p2p_ps_wk_cmd(struct adapter *padapter, u8 p2p_ps_state, u8 enqueue)
-{
-       struct cmd_obj  *ph2c;
-       struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-       u8      res = _SUCCESS;
-
-       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
-               return res;
-
-       if (enqueue) {
-               ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
-               if (!ph2c) {
-                       res = _FAIL;
-                       goto exit;
-               }
-
-               pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC);
-               if (!pdrvextra_cmd_parm) {
-                       kfree(ph2c);
-                       res = _FAIL;
-                       goto exit;
-               }
-
-               pdrvextra_cmd_parm->ec_id = P2P_PS_WK_CID;
-               pdrvextra_cmd_parm->type_size = p2p_ps_state;
-               pdrvextra_cmd_parm->pbuf = NULL;
-
-               init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
-
-               res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-       } else {
-               p2p_ps_wk_hdl(padapter, p2p_ps_state);
-       }
-
-exit:
-
-       return res;
-}
-
-static void reset_ch_sitesurvey_timer_process(struct timer_list *t)
-{
-       struct adapter *adapter = from_timer(adapter, t, pwrctrlpriv.pwr_state_check_timer);
-       struct  wifidirect_info         *pwdinfo = &adapter->wdinfo;
-
-       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
-               return;
-
-       /*      Reset the operation channel information */
-       pwdinfo->rx_invitereq_info.operation_ch[0] = 0;
-       pwdinfo->rx_invitereq_info.scan_op_ch_only = 0;
-}
-
-static void reset_ch_sitesurvey_timer_process2(struct timer_list *t)
-{
-       struct adapter *adapter = from_timer(adapter, t, pwrctrlpriv.pwr_state_check_timer);
-       struct  wifidirect_info         *pwdinfo = &adapter->wdinfo;
-
-       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
-               return;
-
-       /*      Reset the operation channel information */
-       pwdinfo->p2p_info.operation_ch[0] = 0;
-       pwdinfo->p2p_info.scan_op_ch_only = 0;
-}
-
-static void restore_p2p_state_timer_process(struct timer_list *t)
-{
-       struct adapter *adapter = from_timer(adapter, t, wdinfo.restore_p2p_state_timer);
-       struct  wifidirect_info         *pwdinfo = &adapter->wdinfo;
-
-       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
-               return;
-
-       p2p_protocol_wk_cmd(adapter, P2P_RESTORE_STATE_WK);
-}
-
-static void pre_tx_scan_timer_process(struct timer_list *t)
-{
-       struct adapter *adapter = from_timer(adapter, t, wdinfo.pre_tx_scan_timer);
-       struct  wifidirect_info *pwdinfo = &adapter->wdinfo;
-       struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
-
-       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
-               return;
-
-       spin_lock_bh(&pmlmepriv->lock);
-
-       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) {
-               if (pwdinfo->tx_prov_disc_info.benable) {       /*      the provision discovery request frame is trigger to send or not */
-                       p2p_protocol_wk_cmd(adapter, P2P_PRE_TX_PROVDISC_PROCESS_WK);
-                       /* issue_probereq_p2p(adapter); */
-                       /* _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); */
-               }
-       } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
-               if (pwdinfo->nego_req_info.benable)
-                       p2p_protocol_wk_cmd(adapter, P2P_PRE_TX_NEGOREQ_PROCESS_WK);
-       } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ)) {
-               if (pwdinfo->invitereq_info.benable)
-                       p2p_protocol_wk_cmd(adapter, P2P_PRE_TX_INVITEREQ_PROCESS_WK);
-       }
-
-       spin_unlock_bh(&pmlmepriv->lock);
-}
-
-static void find_phase_timer_process(struct timer_list *t)
-{
-       struct adapter *adapter = from_timer(adapter, t, wdinfo.find_phase_timer);
-       struct  wifidirect_info         *pwdinfo = &adapter->wdinfo;
-
-       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
-               return;
-
-       adapter->wdinfo.find_phase_state_exchange_cnt++;
-
-       p2p_protocol_wk_cmd(adapter, P2P_FIND_PHASE_WK);
-}
-
-void reset_global_wifidirect_info(struct adapter *padapter)
-{
-       struct wifidirect_info  *pwdinfo;
-
-       pwdinfo = &padapter->wdinfo;
-       pwdinfo->persistent_supported = 0;
-       pwdinfo->session_available = true;
-}
-
-void rtw_init_wifidirect_timers(struct adapter *padapter)
-{
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       timer_setup(&pwdinfo->find_phase_timer, find_phase_timer_process, 0);
-       timer_setup(&pwdinfo->restore_p2p_state_timer, restore_p2p_state_timer_process, 0);
-       timer_setup(&pwdinfo->pre_tx_scan_timer, pre_tx_scan_timer_process, 0);
-       timer_setup(&pwdinfo->reset_ch_sitesurvey, reset_ch_sitesurvey_timer_process, 0);
-       timer_setup(&pwdinfo->reset_ch_sitesurvey2, reset_ch_sitesurvey_timer_process2, 0);
-}
-
-void rtw_init_wifidirect_addrs(struct adapter *padapter, u8 *dev_addr, u8 *iface_addr)
-{
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       /*init device&interface address */
-       if (dev_addr)
-               memcpy(pwdinfo->device_addr, dev_addr, ETH_ALEN);
-       if (iface_addr)
-               memcpy(pwdinfo->interface_addr, iface_addr, ETH_ALEN);
-}
-
-void init_wifidirect_info(struct adapter *padapter, enum P2P_ROLE role)
-{
-       struct wifidirect_info  *pwdinfo;
-
-       pwdinfo = &padapter->wdinfo;
-       pwdinfo->padapter = padapter;
-
-       /*      1, 6, 11 are the social channel defined in the WiFi Direct specification. */
-       pwdinfo->social_chan[0] = 1;
-       pwdinfo->social_chan[1] = 6;
-       pwdinfo->social_chan[2] = 11;
-       pwdinfo->social_chan[3] = 0;    /*      channel 0 for scanning ending in site survey function. */
-
-       /*      Use the channel 11 as the listen channel */
-       pwdinfo->listen_channel = 11;
-
-       if (role == P2P_ROLE_DEVICE) {
-               rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
-               rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
-               pwdinfo->intent = 1;
-               rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_LISTEN);
-       } else if (role == P2P_ROLE_CLIENT) {
-               rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
-               rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
-               pwdinfo->intent = 1;
-               rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
-       } else if (role == P2P_ROLE_GO) {
-               rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
-               rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
-               pwdinfo->intent = 15;
-               rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
-       }
-
-/*     Use the OFDM rate in the P2P probe response frame. (6(B), 9(B), 12, 18, 24, 36, 48, 54) */
-       pwdinfo->support_rate[0] = 0x8c;        /*      6(B) */
-       pwdinfo->support_rate[1] = 0x92;        /*      9(B) */
-       pwdinfo->support_rate[2] = 0x18;        /*      12 */
-       pwdinfo->support_rate[3] = 0x24;        /*      18 */
-       pwdinfo->support_rate[4] = 0x30;        /*      24 */
-       pwdinfo->support_rate[5] = 0x48;        /*      36 */
-       pwdinfo->support_rate[6] = 0x60;        /*      48 */
-       pwdinfo->support_rate[7] = 0x6c;        /*      54 */
-
-       memcpy(pwdinfo->p2p_wildcard_ssid, "DIRECT-", 7);
-
-       memset(pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN);
-       pwdinfo->device_name_len = 0;
-
-       memset(&pwdinfo->invitereq_info, 0x00, sizeof(struct tx_invite_req_info));
-       pwdinfo->invitereq_info.token = 3;      /*      Token used for P2P invitation request frame. */
-
-       memset(&pwdinfo->inviteresp_info, 0x00, sizeof(struct tx_invite_resp_info));
-       pwdinfo->inviteresp_info.token = 0;
-
-       pwdinfo->profileindex = 0;
-       memset(&pwdinfo->profileinfo[0], 0x00, sizeof(struct profile_info) * P2P_MAX_PERSISTENT_GROUP_NUM);
-
-       rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
-
-       pwdinfo->listen_dwell = (u8)((jiffies % 3) + 1);
-
-       memset(&pwdinfo->tx_prov_disc_info, 0x00, sizeof(struct tx_provdisc_req_info));
-       pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_NONE;
-
-       memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info));
-
-       pwdinfo->device_password_id_for_nego = WPS_DPID_PBC;
-       pwdinfo->negotiation_dialog_token = 1;
-
-       memset(pwdinfo->nego_ssid, 0x00, WLAN_SSID_MAXLEN);
-       pwdinfo->nego_ssidlen = 0;
-
-       pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
-       pwdinfo->supported_wps_cm = WPS_CONFIG_METHOD_DISPLAY | WPS_CONFIG_METHOD_PBC | WPS_CONFIG_METHOD_KEYPAD;
-       pwdinfo->channel_list_attr_len = 0;
-       memset(pwdinfo->channel_list_attr, 0x00, 100);
-
-       memset(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, 0x00, 4);
-       memset(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, '0', 3);
-       memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
-       memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN);
-       memset(pwdinfo->p2p_peer_device_addr, 0x00, ETH_ALEN);
-
-       pwdinfo->rx_invitereq_info.operation_ch[0] = 0;
-       pwdinfo->rx_invitereq_info.operation_ch[1] = 0; /*      Used to indicate the scan end in site survey function */
-       pwdinfo->rx_invitereq_info.scan_op_ch_only = 0;
-       pwdinfo->p2p_info.operation_ch[0] = 0;
-       pwdinfo->p2p_info.operation_ch[1] = 0;                  /*      Used to indicate the scan end in site survey function */
-       pwdinfo->p2p_info.scan_op_ch_only = 0;
-}
-
-int rtw_p2p_enable(struct adapter *padapter, enum P2P_ROLE role)
-{
-       int ret;
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       if (role == P2P_ROLE_DEVICE || role == P2P_ROLE_CLIENT || role == P2P_ROLE_GO) {
-               /* leave IPS/Autosuspend */
-               ret = rtw_pwr_wakeup(padapter);
-               if (ret)
-                       return ret;
-
-               /*      Added by Albert 2011/03/22 */
-               /*      In the P2P mode, the driver should not support the b mode. */
-               /*      So, the Tx packet shouldn't use the CCK rate */
-               update_tx_basic_rate(padapter, (WIRELESS_11G | WIRELESS_11_24N));
-
-               /* Enable P2P function */
-               init_wifidirect_info(padapter, role);
-
-       } else if (role == P2P_ROLE_DISABLE) {
-               ret = rtw_pwr_wakeup(padapter);
-               if (ret)
-                       return ret;
-
-               /* Disable P2P function */
-               if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
-                       _cancel_timer_ex(&pwdinfo->find_phase_timer);
-                       _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
-                       _cancel_timer_ex(&pwdinfo->pre_tx_scan_timer);
-                       _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
-                       _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey2);
-                       rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
-                       rtw_p2p_set_role(pwdinfo, P2P_ROLE_DISABLE);
-                       memset(&pwdinfo->rx_prov_disc_info, 0x00, sizeof(struct rx_provdisc_req_info));
-               }
-
-               /* Restore to initial setting. */
-               update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
-       }
-
-       return 0;
-}
diff --git a/drivers/staging/r8188eu/core/rtw_pwrctrl.c b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
deleted file mode 100644 (file)
index 051cdcb..0000000
+++ /dev/null
@@ -1,445 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-#define _RTW_PWRCTRL_C_
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/osdep_intf.h"
-#include "../include/linux/usb.h"
-
-static void ips_enter(struct adapter *padapter)
-{
-       struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
-       struct xmit_priv *pxmit_priv = &padapter->xmitpriv;
-
-       if (pxmit_priv->free_xmitbuf_cnt != NR_XMITBUFF ||
-           pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF)
-               return;
-
-       mutex_lock(&pwrpriv->lock);
-
-       pwrpriv->bips_processing = true;
-
-       /*  syn ips_mode with request */
-       pwrpriv->ips_mode = pwrpriv->ips_mode_req;
-
-       pwrpriv->ips_enter_cnts++;
-       pwrpriv->bpower_saving = true;
-
-       if (pwrpriv->ips_mode == IPS_LEVEL_2)
-               pwrpriv->bkeepfwalive = true;
-
-       rtw_ips_pwr_down(padapter);
-       pwrpriv->rf_pwrstate = rf_off;
-
-       pwrpriv->bips_processing = false;
-
-       mutex_unlock(&pwrpriv->lock);
-}
-
-static int ips_leave(struct adapter *padapter)
-{
-       struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
-       struct security_priv *psecuritypriv = &padapter->securitypriv;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       int result = _SUCCESS;
-       int keyid;
-
-       mutex_lock(&pwrpriv->lock);
-
-       if ((pwrpriv->rf_pwrstate == rf_off) && (!pwrpriv->bips_processing)) {
-               pwrpriv->bips_processing = true;
-               pwrpriv->ips_leave_cnts++;
-
-               result = rtw_ips_pwr_up(padapter);
-               if (result == _SUCCESS) {
-                       pwrpriv->rf_pwrstate = rf_on;
-               }
-
-               if ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_)) {
-                       set_channel_bwmode(padapter, padapter->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
-                       for (keyid = 0; keyid < 4; keyid++) {
-                               if (pmlmepriv->key_mask & BIT(keyid)) {
-                                       if (keyid == psecuritypriv->dot11PrivacyKeyIndex)
-                                               result = rtw_set_key(padapter, psecuritypriv, keyid, 1);
-                                       else
-                                               result = rtw_set_key(padapter, psecuritypriv, keyid, 0);
-                               }
-                       }
-               }
-
-               pwrpriv->bips_processing = false;
-
-               pwrpriv->bkeepfwalive = false;
-               pwrpriv->bpower_saving = false;
-       }
-
-       mutex_unlock(&pwrpriv->lock);
-
-       return result;
-}
-
-static bool rtw_pwr_unassociated_idle(struct adapter *adapter)
-{
-       struct adapter *buddy = adapter->pbuddy_adapter;
-       struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
-       struct wifidirect_info  *pwdinfo = &adapter->wdinfo;
-       bool ret = false;
-
-       if (time_after_eq(adapter->pwrctrlpriv.ips_deny_time, jiffies))
-               goto exit;
-
-       if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE | WIFI_SITE_MONITOR) ||
-           check_fwstate(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS) ||
-           check_fwstate(pmlmepriv, WIFI_UNDER_WPS) ||
-           check_fwstate(pmlmepriv, WIFI_AP_STATE) ||
-           check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE) ||
-           !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
-               goto exit;
-
-       /* consider buddy, if exist */
-       if (buddy) {
-               struct mlme_priv *b_pmlmepriv = &buddy->mlmepriv;
-               struct wifidirect_info *b_pwdinfo = &buddy->wdinfo;
-
-               if (check_fwstate(b_pmlmepriv, WIFI_ASOC_STATE | WIFI_SITE_MONITOR) ||
-                   check_fwstate(b_pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS) ||
-                   check_fwstate(b_pmlmepriv, WIFI_AP_STATE) ||
-                   check_fwstate(b_pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE) ||
-                   !rtw_p2p_chk_state(b_pwdinfo, P2P_STATE_NONE))
-                       goto exit;
-       }
-       ret = true;
-
-exit:
-       return ret;
-}
-
-void rtw_ps_processor(struct adapter *padapter)
-{
-       struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
-
-       pwrpriv->ps_processing = true;
-
-       if (pwrpriv->bips_processing)
-               goto exit;
-
-       if (pwrpriv->ips_mode_req == IPS_NONE)
-               goto exit;
-
-       if (!rtw_pwr_unassociated_idle(padapter))
-               goto exit;
-
-       if (pwrpriv->rf_pwrstate == rf_on)
-               ips_enter(padapter);
-
-exit:
-       rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv);
-       pwrpriv->ps_processing = false;
-}
-
-static void pwr_state_check_handler(struct timer_list *t)
-{
-       struct adapter *padapter =
-               from_timer(padapter, t,
-                          pwrctrlpriv.pwr_state_check_timer);
-       rtw_ps_cmd(padapter);
-}
-
-static bool PS_RDY_CHECK(struct adapter *padapter)
-{
-       u32 curr_time, delta_time;
-       struct pwrctrl_priv     *pwrpriv = &padapter->pwrctrlpriv;
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-
-       curr_time = jiffies;
-       delta_time = curr_time - pwrpriv->DelayLPSLastTimeStamp;
-
-       if (delta_time < LPS_DELAY_TIME)
-               return false;
-
-       if (!check_fwstate(pmlmepriv, _FW_LINKED) ||
-           check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) ||
-           check_fwstate(pmlmepriv, WIFI_AP_STATE) ||
-           check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
-           check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))
-               return false;
-       if (pwrpriv->bInSuspend)
-               return false;
-       if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X &&
-           !padapter->securitypriv.binstallGrpkey)
-               return false;
-       return true;
-}
-
-void rtw_set_firmware_ps_mode(struct adapter *adapter, u8 mode)
-{
-       struct hal_data_8188e *haldata = &adapter->haldata;
-       struct odm_dm_struct *odmpriv = &haldata->odmpriv;
-
-       /* Force leave RF low power mode for 1T1R to prevent
-        * conflicting setting in firmware power saving sequence.
-        */
-       if (mode != PS_MODE_ACTIVE)
-               ODM_RF_Saving(odmpriv, true);
-       rtl8188e_set_FwPwrMode_cmd(adapter, mode);
-}
-
-void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode)
-{
-       struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
-       struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
-
-       if (ps_mode > PM_Card_Disable)
-               return;
-
-       if (pwrpriv->pwr_mode == ps_mode) {
-               if (ps_mode == PS_MODE_ACTIVE)
-                       return;
-
-               if ((pwrpriv->smart_ps == smart_ps) &&
-                   (pwrpriv->bcn_ant_mode == bcn_ant_mode))
-                       return;
-       }
-
-       if (ps_mode == PS_MODE_ACTIVE) {
-               if (pwdinfo->opp_ps == 0) {
-                       pwrpriv->pwr_mode = ps_mode;
-                       rtw_set_firmware_ps_mode(padapter, ps_mode);
-                       pwrpriv->bFwCurrentInPSMode = false;
-               }
-       } else {
-               if (PS_RDY_CHECK(padapter)) {
-                       pwrpriv->bFwCurrentInPSMode = true;
-                       pwrpriv->pwr_mode = ps_mode;
-                       pwrpriv->smart_ps = smart_ps;
-                       pwrpriv->bcn_ant_mode = bcn_ant_mode;
-                       rtw_set_firmware_ps_mode(padapter, ps_mode);
-
-                       /*  Set CTWindow after LPS */
-                       if (pwdinfo->opp_ps == 1)
-                               p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 0);
-               }
-       }
-}
-
-static bool lps_rf_on(struct adapter *adapter)
-{
-       int res;
-       u32 reg;
-
-       /* When we halt NIC, we should check if FW LPS is leave. */
-       if (adapter->pwrctrlpriv.rf_pwrstate == rf_off) {
-               /*  If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave, */
-               /*  because Fw is unload. */
-               return true;
-       }
-
-       res = rtw_read32(adapter, REG_RCR, &reg);
-       if (res)
-               return false;
-
-       if (reg & 0x00070000)
-               return false;
-
-       return true;
-}
-
-/*
- * Return:
- *     0:      Leave OK
- *     -1:     Timeout
- *     -2:     Other error
- */
-static s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms)
-{
-       unsigned long timeout = jiffies + msecs_to_jiffies(delay_ms);
-       s32 err = 0;
-
-       while (1) {
-               if (lps_rf_on(padapter))
-                       break;
-
-               if (padapter->bSurpriseRemoved) {
-                       err = -2;
-                       break;
-               }
-
-               if (time_after(jiffies, timeout)) {
-                       err = -1;
-                       break;
-               }
-               mdelay(1);
-       }
-
-       return err;
-}
-
-/*  */
-/*     Description: */
-/*             Enter the leisure power save mode. */
-/*  */
-void LPS_Enter(struct adapter *padapter)
-{
-       struct pwrctrl_priv     *pwrpriv = &padapter->pwrctrlpriv;
-
-       if (!PS_RDY_CHECK(padapter))
-               return;
-
-       if (pwrpriv->bLeisurePs) {
-               /*  Idle for a while if we connect to AP a while ago. */
-               if (pwrpriv->LpsIdleCount >= 2) { /*   4 Sec */
-                       if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) {
-                               pwrpriv->bpower_saving = true;
-                               /* For Tenda W311R IOT issue */
-                               rtw_set_ps_mode(padapter, pwrpriv->power_mgnt,
-                                               pwrpriv->smart_ps, 0x40);
-                       }
-               } else {
-                       pwrpriv->LpsIdleCount++;
-               }
-       }
-
-}
-
-#define LPS_LEAVE_TIMEOUT_MS 100
-
-/*     Description: */
-/*             Leave the leisure power save mode. */
-void LPS_Leave(struct adapter *padapter)
-{
-       struct pwrctrl_priv     *pwrpriv = &padapter->pwrctrlpriv;
-
-       if (pwrpriv->bLeisurePs) {
-               if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) {
-                       rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0x40);
-
-                       if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
-                               LPS_RF_ON_check(padapter, LPS_LEAVE_TIMEOUT_MS);
-               }
-       }
-
-       pwrpriv->bpower_saving = false;
-
-}
-
-/*  */
-/*  Description: Leave all power save mode: LPS, FwLPS, IPS if needed. */
-/*  Move code to function by tynli. 2010.03.26. */
-/*  */
-void LeaveAllPowerSaveMode(struct adapter *Adapter)
-{
-       struct mlme_priv        *pmlmepriv = &Adapter->mlmepriv;
-       u8      enqueue = 0;
-
-       if (check_fwstate(pmlmepriv, _FW_LINKED)) { /* connect */
-               p2p_ps_wk_cmd(Adapter, P2P_PS_DISABLE, enqueue);
-
-               rtw_lps_ctrl_wk_cmd(Adapter, LPS_CTRL_LEAVE, enqueue);
-       }
-
-}
-
-void rtw_init_pwrctrl_priv(struct adapter *padapter)
-{
-       struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
-
-       mutex_init(&pwrctrlpriv->lock);
-       pwrctrlpriv->rf_pwrstate = rf_on;
-       pwrctrlpriv->ips_enter_cnts = 0;
-       pwrctrlpriv->ips_leave_cnts = 0;
-       pwrctrlpriv->bips_processing = false;
-
-       pwrctrlpriv->ips_mode = padapter->registrypriv.ips_mode;
-       pwrctrlpriv->ips_mode_req = padapter->registrypriv.ips_mode;
-
-       pwrctrlpriv->pwr_state_check_interval = RTW_PWR_STATE_CHK_INTERVAL;
-       pwrctrlpriv->bInSuspend = false;
-       pwrctrlpriv->bkeepfwalive = false;
-
-       pwrctrlpriv->LpsIdleCount = 0;
-       pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt;/*  PS_MODE_MIN; */
-       pwrctrlpriv->bLeisurePs = pwrctrlpriv->power_mgnt != PS_MODE_ACTIVE;
-
-       pwrctrlpriv->bFwCurrentInPSMode = false;
-
-       pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE;
-       pwrctrlpriv->smart_ps = padapter->registrypriv.smart_ps;
-       pwrctrlpriv->bcn_ant_mode = 0;
-
-       timer_setup(&pwrctrlpriv->pwr_state_check_timer, pwr_state_check_handler, 0);
-}
-
-/* Wake the NIC up from: 1)IPS 2)USB autosuspend */
-int rtw_pwr_wakeup(struct adapter *padapter)
-{
-       struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       unsigned long timeout = jiffies + msecs_to_jiffies(3000);
-       unsigned long deny_time;
-       int ret;
-
-       while (pwrpriv->ps_processing && time_before(jiffies, timeout))
-               msleep(10);
-
-       /* I think this should be check in IPS, LPS, autosuspend functions... */
-       /* Below goto is a success path taken for already linked devices */
-       ret = 0;
-       if (check_fwstate(pmlmepriv, _FW_LINKED))
-               goto exit;
-
-       if (pwrpriv->rf_pwrstate == rf_off && ips_leave(padapter) == _FAIL) {
-               ret = -ENOMEM;
-               goto exit;
-       }
-
-       if (padapter->bDriverStopped || !padapter->bup || !padapter->hw_init_completed) {
-               ret = -EBUSY;
-               goto exit;
-       }
-
-exit:
-       deny_time = jiffies + msecs_to_jiffies(RTW_PWR_STATE_CHK_INTERVAL);
-       if (time_before(pwrpriv->ips_deny_time, deny_time))
-               pwrpriv->ips_deny_time = deny_time;
-       return ret;
-}
-
-int rtw_pm_set_lps(struct adapter *padapter, u8 mode)
-{
-       int     ret = 0;
-       struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
-
-       if (mode < PS_MODE_NUM) {
-               if (pwrctrlpriv->power_mgnt != mode) {
-                       if (mode == PS_MODE_ACTIVE)
-                               LeaveAllPowerSaveMode(padapter);
-                       else
-                               pwrctrlpriv->LpsIdleCount = 2;
-                       pwrctrlpriv->power_mgnt = mode;
-                       pwrctrlpriv->bLeisurePs = pwrctrlpriv->power_mgnt != PS_MODE_ACTIVE;
-               }
-       } else {
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-int rtw_pm_set_ips(struct adapter *padapter, u8 mode)
-{
-       struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
-
-       if (mode == IPS_NORMAL || mode == IPS_LEVEL_2) {
-               rtw_ips_mode_req(pwrctrlpriv, mode);
-               return 0;
-       } else if (mode == IPS_NONE) {
-               rtw_ips_mode_req(pwrctrlpriv, mode);
-               if ((padapter->bSurpriseRemoved == 0) && rtw_pwr_wakeup(padapter))
-                       return -EFAULT;
-       } else {
-               return -EINVAL;
-       }
-       return 0;
-}
diff --git a/drivers/staging/r8188eu/core/rtw_recv.c b/drivers/staging/r8188eu/core/rtw_recv.c
deleted file mode 100644 (file)
index fc7568c..0000000
+++ /dev/null
@@ -1,2010 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-#define _RTW_RECV_C_
-
-#include <linux/ieee80211.h>
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/usb_ops.h"
-#include "../include/wifi.h"
-#include "../include/rtl8188e_recv.h"
-
-static u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37};
-static u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3};
-
-/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
-static u8 rtw_bridge_tunnel_header[] = {
-       0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8
-};
-
-static u8 rtw_rfc1042_header[] = {
-       0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00
-};
-
-static void rtw_signal_stat_timer_hdl(struct timer_list *t);
-
-void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv)
-{
-
-       memset((u8 *)psta_recvpriv, 0, sizeof(struct sta_recv_priv));
-
-       spin_lock_init(&psta_recvpriv->lock);
-
-       rtw_init_queue(&psta_recvpriv->defrag_q);
-
-}
-
-static int rtl8188eu_init_recv_priv(struct adapter *padapter)
-{
-       struct recv_priv *precvpriv = &padapter->recvpriv;
-       int i, err = 0;
-       struct recv_buf *precvbuf;
-
-       tasklet_init(&precvpriv->recv_tasklet,
-                    rtl8188eu_recv_tasklet,
-                    (unsigned long)padapter);
-
-       /* init recv_buf */
-       rtw_init_queue(&precvpriv->free_recv_buf_queue);
-
-       precvpriv->pallocated_recv_buf = kzalloc(NR_RECVBUFF * sizeof(struct recv_buf) + 4,
-                                                GFP_KERNEL);
-       if (!precvpriv->pallocated_recv_buf)
-               return -ENOMEM;
-
-       precvpriv->precv_buf = (u8 *)ALIGN((size_t)(precvpriv->pallocated_recv_buf), 4);
-
-       precvbuf = (struct recv_buf *)precvpriv->precv_buf;
-
-       for (i = 0; i < NR_RECVBUFF; i++) {
-               precvbuf->pskb = NULL;
-               precvbuf->reuse = false;
-               precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL);
-               if (!precvbuf->purb) {
-                       err = -ENOMEM;
-                       break;
-               }
-               precvbuf->adapter = padapter;
-               precvbuf++;
-       }
-       precvpriv->free_recv_buf_queue_cnt = NR_RECVBUFF;
-       skb_queue_head_init(&precvpriv->rx_skb_queue);
-       {
-               int i;
-               size_t tmpaddr = 0;
-               size_t alignment = 0;
-               struct sk_buff *pskb = NULL;
-
-               skb_queue_head_init(&precvpriv->free_recv_skb_queue);
-
-               for (i = 0; i < NR_PREALLOC_RECV_SKB; i++) {
-                       pskb = __netdev_alloc_skb(padapter->pnetdev,
-                                                 MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ, GFP_KERNEL);
-                       if (pskb) {
-                               pskb->dev = padapter->pnetdev;
-                               tmpaddr = (size_t)pskb->data;
-                               alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1);
-                               skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment));
-
-                               skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
-                       }
-                       pskb = NULL;
-               }
-       }
-
-       return err;
-}
-
-int _rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter)
-{
-       int i;
-       struct recv_frame *precvframe;
-       int err;
-
-       spin_lock_init(&precvpriv->lock);
-
-       rtw_init_queue(&precvpriv->free_recv_queue);
-       rtw_init_queue(&precvpriv->recv_pending_queue);
-       rtw_init_queue(&precvpriv->uc_swdec_pending_queue);
-
-       precvpriv->adapter = padapter;
-
-       precvpriv->free_recvframe_cnt = NR_RECVFRAME;
-
-       precvpriv->pallocated_frame_buf = vzalloc(NR_RECVFRAME * sizeof(struct recv_frame) + RXFRAME_ALIGN_SZ);
-       if (!precvpriv->pallocated_frame_buf)
-               return -ENOMEM;
-
-       precvpriv->precv_frame_buf = (u8 *)ALIGN((size_t)(precvpriv->pallocated_frame_buf), RXFRAME_ALIGN_SZ);
-
-       precvframe = (struct recv_frame *)precvpriv->precv_frame_buf;
-
-       for (i = 0; i < NR_RECVFRAME; i++) {
-               INIT_LIST_HEAD(&precvframe->list);
-
-               list_add_tail(&precvframe->list, &precvpriv->free_recv_queue.queue);
-
-               precvframe->pkt = NULL;
-
-               precvframe->len = 0;
-
-               precvframe->adapter = padapter;
-               precvframe++;
-       }
-       precvpriv->rx_pending_cnt = 1;
-
-       err = rtl8188eu_init_recv_priv(padapter);
-
-       timer_setup(&precvpriv->signal_stat_timer, rtw_signal_stat_timer_hdl, 0);
-       precvpriv->signal_stat_sampling_interval = 1000; /* ms */
-
-       rtw_set_signal_stat_timer(precvpriv);
-
-       return err;
-}
-
-static void rtl8188eu_free_recv_priv(struct adapter *padapter)
-{
-       int i;
-       struct recv_buf *precvbuf;
-       struct recv_priv *precvpriv = &padapter->recvpriv;
-
-       precvbuf = (struct recv_buf *)precvpriv->precv_buf;
-
-       for (i = 0; i < NR_RECVBUFF; i++) {
-               usb_free_urb(precvbuf->purb);
-               precvbuf++;
-       }
-
-       kfree(precvpriv->pallocated_recv_buf);
-
-       skb_queue_purge(&precvpriv->rx_skb_queue);
-
-       skb_queue_purge(&precvpriv->free_recv_skb_queue);
-}
-
-void _rtw_free_recv_priv(struct recv_priv *precvpriv)
-{
-       struct adapter  *padapter = precvpriv->adapter;
-
-       rtw_free_uc_swdec_pending_queue(padapter);
-
-       vfree(precvpriv->pallocated_frame_buf);
-
-       rtl8188eu_free_recv_priv(padapter);
-       _cancel_timer_ex(&precvpriv->signal_stat_timer);
-}
-
-struct recv_frame *_rtw_alloc_recvframe(struct __queue *pfree_recv_queue)
-{
-       struct recv_frame *hdr;
-       struct list_head *plist, *phead;
-       struct adapter *padapter;
-       struct recv_priv *precvpriv;
-
-       if (list_empty(&pfree_recv_queue->queue)) {
-               hdr = NULL;
-       } else {
-               phead = get_list_head(pfree_recv_queue);
-
-               plist = phead->next;
-
-               hdr = container_of(plist, struct recv_frame, list);
-
-               list_del_init(&hdr->list);
-               padapter = hdr->adapter;
-               if (padapter) {
-                       precvpriv = &padapter->recvpriv;
-                       if (pfree_recv_queue == &precvpriv->free_recv_queue)
-                               precvpriv->free_recvframe_cnt--;
-               }
-       }
-
-       return (struct recv_frame *)hdr;
-}
-
-struct recv_frame *rtw_alloc_recvframe(struct __queue *pfree_recv_queue)
-{
-       struct recv_frame  *precvframe;
-
-       spin_lock_bh(&pfree_recv_queue->lock);
-
-       precvframe = _rtw_alloc_recvframe(pfree_recv_queue);
-
-       spin_unlock_bh(&pfree_recv_queue->lock);
-
-       return precvframe;
-}
-
-int rtw_free_recvframe(struct recv_frame *precvframe, struct __queue *pfree_recv_queue)
-{
-       struct adapter *padapter;
-       struct recv_priv *precvpriv;
-
-       if (!precvframe)
-               return _FAIL;
-       padapter = precvframe->adapter;
-       precvpriv = &padapter->recvpriv;
-       if (precvframe->pkt) {
-               dev_kfree_skb_any(precvframe->pkt);/* free skb by driver */
-               precvframe->pkt = NULL;
-       }
-
-       spin_lock_bh(&pfree_recv_queue->lock);
-
-       list_del_init(&precvframe->list);
-
-       precvframe->len = 0;
-
-       list_add_tail(&precvframe->list, get_list_head(pfree_recv_queue));
-
-       if (padapter && (pfree_recv_queue == &precvpriv->free_recv_queue))
-               precvpriv->free_recvframe_cnt++;
-
-       spin_unlock_bh(&pfree_recv_queue->lock);
-
-       return _SUCCESS;
-}
-
-int _rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue)
-{
-       struct adapter *padapter = precvframe->adapter;
-       struct recv_priv *precvpriv = &padapter->recvpriv;
-
-       list_del_init(&precvframe->list);
-       list_add_tail(&precvframe->list, get_list_head(queue));
-
-       if (padapter) {
-               if (queue == &precvpriv->free_recv_queue)
-                       precvpriv->free_recvframe_cnt++;
-       }
-
-       return _SUCCESS;
-}
-
-int rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue)
-{
-       int ret;
-
-       spin_lock_bh(&queue->lock);
-       ret = _rtw_enqueue_recvframe(precvframe, queue);
-       spin_unlock_bh(&queue->lock);
-
-       return ret;
-}
-
-/*
- * caller : defrag ; recvframe_chk_defrag in recv_thread  (passive)
- * pframequeue: defrag_queue : will be accessed in recv_thread  (passive)
- *
- * using spinlock to protect
- *
- */
-
-void rtw_free_recvframe_queue(struct __queue *pframequeue,  struct __queue *pfree_recv_queue)
-{
-       struct recv_frame *hdr;
-       struct list_head *plist, *phead;
-
-       spin_lock(&pframequeue->lock);
-
-       phead = get_list_head(pframequeue);
-       plist = phead->next;
-
-       while (phead != plist) {
-               hdr = container_of(plist, struct recv_frame, list);
-
-               plist = plist->next;
-
-               rtw_free_recvframe((struct recv_frame *)hdr, pfree_recv_queue);
-       }
-
-       spin_unlock(&pframequeue->lock);
-
-}
-
-u32 rtw_free_uc_swdec_pending_queue(struct adapter *adapter)
-{
-       u32 cnt = 0;
-       struct recv_frame *pending_frame;
-
-       while ((pending_frame = rtw_alloc_recvframe(&adapter->recvpriv.uc_swdec_pending_queue))) {
-               rtw_free_recvframe(pending_frame, &adapter->recvpriv.free_recv_queue);
-               cnt++;
-       }
-
-       return cnt;
-}
-
-static void rtw_handle_tkip_mic_err(struct adapter *padapter, u8 bgroup)
-{
-       union iwreq_data wrqu;
-       struct iw_michaelmicfailure ev;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct security_priv *psecuritypriv = &padapter->securitypriv;
-       u32 cur_time = 0;
-
-       if (psecuritypriv->last_mic_err_time == 0) {
-               psecuritypriv->last_mic_err_time = jiffies;
-       } else {
-               cur_time = jiffies;
-
-               if (cur_time - psecuritypriv->last_mic_err_time < 60 * HZ) {
-                       psecuritypriv->btkip_countermeasure = true;
-                       psecuritypriv->last_mic_err_time = 0;
-                       psecuritypriv->btkip_countermeasure_time = cur_time;
-               } else {
-                       psecuritypriv->last_mic_err_time = jiffies;
-               }
-       }
-
-       memset(&ev, 0x00, sizeof(ev));
-       if (bgroup)
-               ev.flags |= IW_MICFAILURE_GROUP;
-       else
-               ev.flags |= IW_MICFAILURE_PAIRWISE;
-
-       ev.src_addr.sa_family = ARPHRD_ETHER;
-       memcpy(ev.src_addr.sa_data, &pmlmepriv->assoc_bssid[0], ETH_ALEN);
-       memset(&wrqu, 0x00, sizeof(wrqu));
-       wrqu.data.length = sizeof(ev);
-       wireless_send_event(padapter->pnetdev, IWEVMICHAELMICFAILURE,
-                           &wrqu, (char *)&ev);
-}
-
-static int recvframe_chkmic(struct adapter *adapter,  struct recv_frame *precvframe)
-{
-       int     i, res = _SUCCESS;
-       u32     datalen;
-       u8      miccode[8];
-       u8      bmic_err = false, brpt_micerror = true;
-       u8      *pframe, *payload, *pframemic;
-       u8      *mickey;
-       struct  sta_info                *stainfo;
-       struct  rx_pkt_attrib   *prxattrib = &precvframe->attrib;
-       struct  security_priv   *psecuritypriv = &adapter->securitypriv;
-
-       struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       stainfo = rtw_get_stainfo(&adapter->stapriv, &prxattrib->ta[0]);
-
-       if (prxattrib->encrypt == _TKIP_) {
-               /* calculate mic code */
-               if (stainfo) {
-                       if (is_multicast_ether_addr(prxattrib->ra)) {
-                               mickey = &psecuritypriv->dot118021XGrprxmickey[prxattrib->key_index].skey[0];
-
-                               if (!psecuritypriv) {
-                                       res = _FAIL;
-                                       goto exit;
-                               }
-                       } else {
-                               mickey = &stainfo->dot11tkiprxmickey.skey[0];
-                       }
-
-                       datalen = precvframe->len - prxattrib->hdrlen - prxattrib->iv_len - prxattrib->icv_len - 8;/* icv_len included the mic code */
-                       pframe = precvframe->rx_data;
-                       payload = pframe + prxattrib->hdrlen + prxattrib->iv_len;
-
-                       rtw_seccalctkipmic(mickey, pframe, payload, datalen, &miccode[0],
-                                          (unsigned char)prxattrib->priority); /* care the length of the data */
-
-                       pframemic = payload + datalen;
-
-                       bmic_err = false;
-
-                       for (i = 0; i < 8; i++) {
-                               if (miccode[i] != *(pframemic + i))
-                                       bmic_err = true;
-                       }
-
-                       if (bmic_err) {
-                               /*  double check key_index for some timing issue , */
-                               /*  cannot compare with psecuritypriv->dot118021XGrpKeyid also cause timing issue */
-                               if (is_multicast_ether_addr(prxattrib->ra) && prxattrib->key_index != pmlmeinfo->key_index)
-                                       brpt_micerror = false;
-
-                               if ((prxattrib->bdecrypted) && (brpt_micerror))
-                                       rtw_handle_tkip_mic_err(adapter, (u8)is_multicast_ether_addr(prxattrib->ra));
-
-                               res = _FAIL;
-                       } else {
-                               /* mic checked ok */
-                               if (!psecuritypriv->bcheck_grpkey && is_multicast_ether_addr(prxattrib->ra))
-                                       psecuritypriv->bcheck_grpkey = true;
-                       }
-               }
-
-               recvframe_pull_tail(precvframe, 8);
-       }
-
-exit:
-
-       return res;
-}
-
-/* decrypt and set the ivlen, icvlen of the recv_frame */
-static struct recv_frame *decryptor(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       struct rx_pkt_attrib *prxattrib = &precv_frame->attrib;
-       struct security_priv *psecuritypriv = &padapter->securitypriv;
-       struct recv_frame *return_packet = precv_frame;
-       u32      res = _SUCCESS;
-
-       if (prxattrib->encrypt > 0) {
-               u8 *iv = precv_frame->rx_data + prxattrib->hdrlen;
-
-               prxattrib->key_index = (((iv[3]) >> 6) & 0x3);
-
-               if (prxattrib->key_index > WEP_KEYS) {
-                       switch (prxattrib->encrypt) {
-                       case _WEP40_:
-                       case _WEP104_:
-                               prxattrib->key_index = psecuritypriv->dot11PrivacyKeyIndex;
-                               break;
-                       case _TKIP_:
-                       case _AES_:
-                       default:
-                               prxattrib->key_index = psecuritypriv->dot118021XGrpKeyid;
-                               break;
-                       }
-               }
-       }
-
-       if ((prxattrib->encrypt > 0) && ((prxattrib->bdecrypted == 0) || (psecuritypriv->sw_decrypt))) {
-               psecuritypriv->hw_decrypted = false;
-
-               switch (prxattrib->encrypt) {
-               case _WEP40_:
-               case _WEP104_:
-                       rtw_wep_decrypt(padapter, precv_frame);
-                       break;
-               case _TKIP_:
-                       res = rtw_tkip_decrypt(padapter, precv_frame);
-                       break;
-               case _AES_:
-                       res = rtw_aes_decrypt(padapter, precv_frame);
-                       break;
-               default:
-                       break;
-               }
-       } else if (prxattrib->bdecrypted == 1 && prxattrib->encrypt > 0 &&
-                  (psecuritypriv->busetkipkey == 1 || prxattrib->encrypt != _TKIP_))
-                       psecuritypriv->hw_decrypted = true;
-
-       if (res == _FAIL) {
-               rtw_free_recvframe(return_packet, &padapter->recvpriv.free_recv_queue);
-               return_packet = NULL;
-       } else {
-               prxattrib->bdecrypted = true;
-       }
-
-       return return_packet;
-}
-
-/* set the security information in the recv_frame */
-static struct recv_frame *portctrl(struct adapter *adapter, struct recv_frame *precv_frame)
-{
-       u8   *psta_addr, *ptr;
-       uint  auth_alg;
-       struct recv_frame *pfhdr;
-       struct sta_info *psta;
-       struct sta_priv *pstapriv;
-       struct recv_frame *prtnframe;
-       u16 ether_type = 0;
-       u16  eapol_type = 0x888e;/* for Funia BD's WPA issue */
-       struct rx_pkt_attrib *pattrib;
-       __be16 be_tmp;
-
-       pstapriv = &adapter->stapriv;
-
-       auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
-
-       ptr = precv_frame->rx_data;
-       pfhdr = precv_frame;
-       pattrib = &pfhdr->attrib;
-       psta_addr = pattrib->ta;
-
-       prtnframe = NULL;
-
-       psta = rtw_get_stainfo(pstapriv, psta_addr);
-
-       if (auth_alg == 2) {
-               if (psta && psta->ieee8021x_blocked) {
-                       /* blocked */
-                       /* only accept EAPOL frame */
-                       prtnframe = precv_frame;
-
-                       /* get ether_type */
-                       ptr = ptr + pfhdr->attrib.hdrlen + pfhdr->attrib.iv_len + LLC_HEADER_SIZE;
-                       memcpy(&be_tmp, ptr, 2);
-                       ether_type = ntohs(be_tmp);
-
-                       if (ether_type == eapol_type) {
-                               prtnframe = precv_frame;
-                       } else {
-                               /* free this frame */
-                               rtw_free_recvframe(precv_frame, &adapter->recvpriv.free_recv_queue);
-                               prtnframe = NULL;
-                       }
-               } else {
-                       /* allowed */
-                       /* check decryption status, and decrypt the frame if needed */
-                       prtnframe = precv_frame;
-               }
-       } else {
-               prtnframe = precv_frame;
-       }
-
-       return prtnframe;
-}
-
-static int recv_decache(struct recv_frame *precv_frame, u8 bretry, struct stainfo_rxcache *prxcache)
-{
-       int tid = precv_frame->attrib.priority;
-
-       u16 seq_ctrl = ((precv_frame->attrib.seq_num & 0xffff) << 4) |
-               (precv_frame->attrib.frag_num & 0xf);
-
-       if (tid > 15)
-               return _FAIL;
-
-       if (1) {/* if (bretry) */
-               if (seq_ctrl == prxcache->tid_rxseq[tid])
-                       return _FAIL;
-       }
-
-       prxcache->tid_rxseq[tid] = seq_ctrl;
-
-       return _SUCCESS;
-}
-
-static void process_pwrbit_data(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       unsigned char pwrbit;
-       u8 *ptr = precv_frame->rx_data;
-       struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       struct sta_info *psta = NULL;
-
-       psta = rtw_get_stainfo(pstapriv, pattrib->src);
-
-       pwrbit = GetPwrMgt(ptr);
-
-       if (psta) {
-               if (pwrbit) {
-                       if (!(psta->state & WIFI_SLEEP_STATE))
-                               stop_sta_xmit(padapter, psta);
-               } else {
-                       if (psta->state & WIFI_SLEEP_STATE)
-                               wakeup_sta_to_xmit(padapter, psta);
-               }
-       }
-}
-
-static void process_wmmps_data(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       struct sta_info *psta = NULL;
-
-       psta = rtw_get_stainfo(pstapriv, pattrib->src);
-
-       if (!psta)
-               return;
-
-       if (!psta->qos_option)
-               return;
-
-       if (!(psta->qos_info & 0xf))
-               return;
-
-       if (psta->state & WIFI_SLEEP_STATE) {
-               u8 wmmps_ac = 0;
-
-               switch (pattrib->priority) {
-               case 1:
-               case 2:
-                       wmmps_ac = psta->uapsd_bk & BIT(1);
-                       break;
-               case 4:
-               case 5:
-                       wmmps_ac = psta->uapsd_vi & BIT(1);
-                       break;
-               case 6:
-               case 7:
-                       wmmps_ac = psta->uapsd_vo & BIT(1);
-                       break;
-               case 0:
-               case 3:
-               default:
-                       wmmps_ac = psta->uapsd_be & BIT(1);
-                       break;
-               }
-
-               if (wmmps_ac) {
-                       if (psta->sleepq_ac_len > 0) {
-                               /* process received triggered frame */
-                               xmit_delivery_enabled_frames(padapter, psta);
-                       } else {
-                               /* issue one qos null frame with More data bit = 0 and the EOSP bit set (= 1) */
-                               issue_qos_nulldata(padapter, psta->hwaddr, (u16)pattrib->priority, 0, 0);
-                       }
-               }
-       }
-}
-
-static void count_rx_stats(struct adapter *padapter, struct recv_frame *prframe, struct sta_info *sta)
-{
-       int     sz;
-       struct sta_info         *psta = NULL;
-       struct stainfo_stats    *pstats = NULL;
-       struct rx_pkt_attrib    *pattrib = &prframe->attrib;
-       struct recv_priv        *precvpriv = &padapter->recvpriv;
-
-       sz = get_recvframe_len(prframe);
-       precvpriv->rx_bytes += sz;
-
-       padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++;
-
-       if (!is_broadcast_ether_addr(pattrib->dst) && !is_multicast_ether_addr(pattrib->dst))
-               padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod++;
-
-       if (sta)
-               psta = sta;
-       else
-               psta = prframe->psta;
-
-       if (psta) {
-               pstats = &psta->sta_stats;
-
-               pstats->rx_data_pkts++;
-               pstats->rx_bytes += sz;
-       }
-}
-
-static int sta2sta_data_frame(struct adapter *adapter,
-                             struct recv_frame *precv_frame, struct sta_info **psta)
-{
-       int ret = _SUCCESS;
-       struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
-       struct  sta_priv *pstapriv = &adapter->stapriv;
-       struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
-       u8 *mybssid  = get_bssid(pmlmepriv);
-       u8 *myhwaddr = myid(&adapter->eeprompriv);
-       u8 *sta_addr = NULL;
-       bool bmcast = is_multicast_ether_addr(pattrib->dst);
-
-       if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
-           check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
-               /*  filter packets that SA is myself or multicast or broadcast */
-               if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
-                       ret = _FAIL;
-                       goto exit;
-               }
-
-               if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) {
-                       ret = _FAIL;
-                       goto exit;
-               }
-
-               if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
-                   !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
-                   memcmp(pattrib->bssid, mybssid, ETH_ALEN)) {
-                       ret = _FAIL;
-                       goto exit;
-               }
-
-               sta_addr = pattrib->src;
-       } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
-               /*  For Station mode, sa and bssid should always be BSSID, and DA is my mac-address */
-               if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) {
-                       ret = _FAIL;
-                       goto exit;
-               }
-               sta_addr = pattrib->bssid;
-       } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
-               if (bmcast) {
-                       /*  For AP mode, if DA == MCAST, then BSSID should be also MCAST */
-                       if (!is_multicast_ether_addr(pattrib->bssid)) {
-                                       ret = _FAIL;
-                                       goto exit;
-                       }
-               } else { /*  not mc-frame */
-                       /*  For AP mode, if DA is non-MCAST, then it must be BSSID, and bssid == BSSID */
-                       if (memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN)) {
-                               ret = _FAIL;
-                               goto exit;
-                       }
-
-                       sta_addr = pattrib->src;
-               }
-       } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
-               sta_addr = mybssid;
-       } else {
-               ret  = _FAIL;
-       }
-
-       if (bmcast)
-               *psta = rtw_get_bcmc_stainfo(adapter);
-       else
-               *psta = rtw_get_stainfo(pstapriv, sta_addr); /*  get ap_info */
-
-       if (!*psta)
-               goto exit;
-
-exit:
-
-       return ret;
-}
-
-static int ap2sta_data_frame(
-       struct adapter *adapter,
-       struct recv_frame *precv_frame,
-       struct sta_info **psta)
-{
-       u8 *ptr = precv_frame->rx_data;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data;
-       struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
-       int ret = _SUCCESS;
-       struct  sta_priv *pstapriv = &adapter->stapriv;
-       struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
-       u8 *mybssid  = get_bssid(pmlmepriv);
-       u8 *myhwaddr = myid(&adapter->eeprompriv);
-       bool bmcast = is_multicast_ether_addr(pattrib->dst);
-
-       if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
-           (check_fwstate(pmlmepriv, _FW_LINKED) ||
-            check_fwstate(pmlmepriv, _FW_UNDER_LINKING))) {
-               /*  filter packets that SA is myself or multicast or broadcast */
-               if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
-                       ret = _FAIL;
-                       goto exit;
-               }
-
-               /*  da should be for me */
-               if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) {
-                       ret = _FAIL;
-                       goto exit;
-               }
-
-               /*  check BSSID */
-               if (is_zero_ether_addr(pattrib->bssid) || is_zero_ether_addr(mybssid) ||
-                   (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) {
-                       if (!bmcast)
-                               issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
-
-                       ret = _FAIL;
-                       goto exit;
-               }
-
-               if (bmcast)
-                       *psta = rtw_get_bcmc_stainfo(adapter);
-               else
-                       *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /*  get ap_info */
-
-               if (!*psta) {
-                       ret = _FAIL;
-                       goto exit;
-               }
-
-               if (ieee80211_is_nullfunc(hdr->frame_control)) {
-                       /* We count the nullfunc frame, but we'll not pass it on to higher layers. */
-                       count_rx_stats(adapter, precv_frame, *psta);
-                       ret = RTW_RX_HANDLED;
-                       goto exit;
-               }
-       } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) &&
-                  check_fwstate(pmlmepriv, _FW_LINKED)) {
-               memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
-
-               memcpy(pattrib->bssid,  mybssid, ETH_ALEN);
-
-               *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /*  get sta_info */
-               if (!*psta) {
-                       ret = _FAIL;
-                       goto exit;
-               }
-       } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
-               /* Special case */
-               ret = RTW_RX_HANDLED;
-               goto exit;
-       } else {
-               if (!memcmp(myhwaddr, pattrib->dst, ETH_ALEN) && (!bmcast)) {
-                       *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /*  get sta_info */
-                       if (!*psta)
-                               issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
-               }
-
-               ret = _FAIL;
-       }
-
-exit:
-
-       return ret;
-}
-
-static int sta2ap_data_frame(struct adapter *adapter,
-                            struct recv_frame *precv_frame,
-                            struct sta_info **psta)
-{
-       struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
-       struct  sta_priv *pstapriv = &adapter->stapriv;
-       struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
-       u8 *ptr = precv_frame->rx_data;
-       __le16 fc = *(__le16 *)ptr;
-       unsigned char *mybssid  = get_bssid(pmlmepriv);
-       int ret = _SUCCESS;
-
-       if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
-               /* For AP mode, RA = BSSID, TX = STA(SRC_ADDR), A3 = DST_ADDR */
-               if (memcmp(pattrib->bssid, mybssid, ETH_ALEN)) {
-                       ret = _FAIL;
-                       goto exit;
-               }
-
-               *psta = rtw_get_stainfo(pstapriv, pattrib->src);
-               if (!*psta) {
-                       issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
-
-                       ret = RTW_RX_HANDLED;
-                       goto exit;
-               }
-
-               process_pwrbit_data(adapter, precv_frame);
-
-               if (ieee80211_is_data_qos(fc))
-                       process_wmmps_data(adapter, precv_frame);
-
-               if (GetFrameSubType(ptr) & BIT(6)) {
-                       /* No data, will not indicate to upper layer, temporily count it here */
-                       count_rx_stats(adapter, precv_frame, *psta);
-                       ret = RTW_RX_HANDLED;
-                       goto exit;
-               }
-       } else {
-               u8 *myhwaddr = myid(&adapter->eeprompriv);
-
-               if (memcmp(pattrib->ra, myhwaddr, ETH_ALEN)) {
-                       ret = RTW_RX_HANDLED;
-                       goto exit;
-               }
-               issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
-               ret = RTW_RX_HANDLED;
-               goto exit;
-       }
-
-exit:
-
-       return ret;
-}
-
-static void validate_recv_ctrl_frame(struct adapter *padapter,
-                                    struct recv_frame *precv_frame)
-{
-       struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data;
-       struct ieee80211_pspoll *pspoll = (struct ieee80211_pspoll *)hdr;
-       u8 wmmps_ac;
-       struct sta_info *psta;
-
-       /* receive the frames that ra(a1) is my address */
-       if (memcmp(hdr->addr1, myid(&padapter->eeprompriv), ETH_ALEN))
-               return;
-
-       /* only handle ps-poll */
-       if (!ieee80211_is_pspoll(hdr->frame_control))
-               return;
-
-       psta = rtw_get_stainfo(pstapriv, hdr->addr2);
-       if (!psta || psta->aid != (le16_to_cpu(pspoll->aid) & 0x3FFF))
-               return;
-
-       /* for rx pkt statistics */
-       psta->sta_stats.rx_ctrl_pkts++;
-
-       switch (pattrib->priority) {
-       case 1:
-       case 2:
-               wmmps_ac = psta->uapsd_bk & BIT(0);
-               break;
-       case 4:
-       case 5:
-               wmmps_ac = psta->uapsd_vi & BIT(0);
-               break;
-       case 6:
-       case 7:
-               wmmps_ac = psta->uapsd_vo & BIT(0);
-               break;
-       case 0:
-       case 3:
-       default:
-               wmmps_ac = psta->uapsd_be & BIT(0);
-               break;
-       }
-
-       if (wmmps_ac)
-               return;
-
-       if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
-               psta->expire_to = pstapriv->expire_to;
-               psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
-       }
-
-       if ((psta->state & WIFI_SLEEP_STATE) && (pstapriv->sta_dz_bitmap & BIT(psta->aid))) {
-               struct list_head *xmitframe_plist, *xmitframe_phead;
-               struct xmit_frame *pxmitframe = NULL;
-               struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
-               spin_lock_bh(&pxmitpriv->lock);
-
-               xmitframe_phead = get_list_head(&psta->sleep_q);
-               xmitframe_plist = xmitframe_phead->next;
-
-               if (xmitframe_phead != xmitframe_plist) {
-                       pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
-
-                       xmitframe_plist = xmitframe_plist->next;
-
-                       list_del_init(&pxmitframe->list);
-
-                       psta->sleepq_len--;
-
-                       if (psta->sleepq_len > 0)
-                               pxmitframe->attrib.mdata = 1;
-                       else
-                               pxmitframe->attrib.mdata = 0;
-
-                       pxmitframe->attrib.triggered = 1;
-
-                       if (psta->sleepq_len == 0) {
-                               pstapriv->tim_bitmap &= ~BIT(psta->aid);
-
-                               /* update BCN for TIM IE */
-                               /* update_BCNTIM(padapter); */
-                               update_beacon(padapter, _TIM_IE_, NULL, false);
-                       }
-               } else {
-                       if (pstapriv->tim_bitmap & BIT(psta->aid)) {
-                               if (psta->sleepq_len == 0)
-                                       /* issue nulldata with More data bit = 0 to indicate we have no buffered packets */
-                                       issue_nulldata(padapter, psta->hwaddr, 0, 0, 0);
-                               else
-                                       psta->sleepq_len = 0;
-
-                               pstapriv->tim_bitmap &= ~BIT(psta->aid);
-
-                               /* update BCN for TIM IE */
-                               /* update_BCNTIM(padapter); */
-                               update_beacon(padapter, _TIM_IE_, NULL, false);
-                       }
-               }
-               spin_unlock_bh(&pxmitpriv->lock);
-       }
-}
-
-struct recv_frame *recvframe_chk_defrag(struct adapter *padapter, struct recv_frame *precv_frame);
-
-static void validate_recv_mgnt_frame(struct adapter *padapter,
-                                    struct recv_frame *precv_frame)
-{
-       struct sta_info *psta;
-       struct ieee80211_hdr *hdr;
-
-       precv_frame = recvframe_chk_defrag(padapter, precv_frame);
-       if (!precv_frame)
-               return;
-
-       hdr = (struct ieee80211_hdr *)precv_frame->rx_data;
-       psta = rtw_get_stainfo(&padapter->stapriv, hdr->addr2);
-       if (psta) {
-               psta->sta_stats.rx_mgnt_pkts++;
-               if (ieee80211_is_beacon(hdr->frame_control))
-                       psta->sta_stats.rx_beacon_pkts++;
-               else if (ieee80211_is_probe_req(hdr->frame_control))
-                       psta->sta_stats.rx_probereq_pkts++;
-               else if (ieee80211_is_probe_resp(hdr->frame_control)) {
-                       if (!memcmp(padapter->eeprompriv.mac_addr, hdr->addr1, ETH_ALEN))
-                               psta->sta_stats.rx_probersp_pkts++;
-                       else if (is_broadcast_mac_addr(hdr->addr1) || is_multicast_mac_addr(hdr->addr1))
-                               psta->sta_stats.rx_probersp_bm_pkts++;
-                       else
-                               psta->sta_stats.rx_probersp_uo_pkts++;
-               }
-       }
-
-       mgt_dispatcher(padapter, precv_frame);
-}
-
-static int validate_recv_data_frame(struct adapter *adapter,
-                                   struct recv_frame *precv_frame)
-{
-       struct sta_info *psta = NULL;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data;
-       struct rx_pkt_attrib    *pattrib = &precv_frame->attrib;
-       struct security_priv    *psecuritypriv = &adapter->securitypriv;
-       int ret;
-
-       memcpy(pattrib->dst, ieee80211_get_DA(hdr), ETH_ALEN);
-       memcpy(pattrib->src, ieee80211_get_SA(hdr), ETH_ALEN);
-
-       /* address4 is used only if both to_ds and from_ds are set */
-       if (ieee80211_has_a4(hdr->frame_control))
-               return _FAIL;
-
-       memcpy(pattrib->ra, hdr->addr1, ETH_ALEN);
-       memcpy(pattrib->ta, hdr->addr2, ETH_ALEN);
-
-       if (ieee80211_has_fromds(hdr->frame_control)) {
-               memcpy(pattrib->bssid, hdr->addr2, ETH_ALEN);
-               ret = ap2sta_data_frame(adapter, precv_frame, &psta);
-       } else if (ieee80211_has_tods(hdr->frame_control)) {
-               memcpy(pattrib->bssid, hdr->addr1, ETH_ALEN);
-               ret = sta2ap_data_frame(adapter, precv_frame, &psta);
-       } else {
-               memcpy(pattrib->bssid, hdr->addr3, ETH_ALEN);
-               ret = sta2sta_data_frame(adapter, precv_frame, &psta);
-       }
-
-       if (ret == _FAIL || ret == RTW_RX_HANDLED)
-               return ret;
-
-       if (!psta)
-               return _FAIL;
-
-       precv_frame->psta = psta;
-
-       pattrib->amsdu = 0;
-       pattrib->ack_policy = 0;
-       /* parsing QC field */
-       if (pattrib->qos) {
-               struct ieee80211_qos_hdr *qos_hdr = (struct ieee80211_qos_hdr *)hdr;
-
-               pattrib->priority = ieee80211_get_tid(hdr);
-               pattrib->ack_policy = GetAckpolicy(&qos_hdr->qos_ctrl);
-               pattrib->amsdu = GetAMsdu(&qos_hdr->qos_ctrl);
-               pattrib->hdrlen = sizeof(*qos_hdr);
-
-               if (pattrib->priority != 0 && pattrib->priority != 3)
-                       adapter->recvpriv.bIsAnyNonBEPkts = true;
-       } else {
-               pattrib->priority = 0;
-               pattrib->hdrlen = 24;
-       }
-
-       if (pattrib->order)/* HT-CTRL 11n */
-               pattrib->hdrlen += 4;
-
-       precv_frame->preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority];
-
-       /*  decache, drop duplicate recv packets */
-       if (recv_decache(precv_frame, ieee80211_has_retry(hdr->frame_control),
-                        &psta->sta_recvpriv.rxcache) == _FAIL)
-               return _FAIL;
-
-       if (pattrib->privacy) {
-               GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, is_multicast_ether_addr(pattrib->ra));
-
-               SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt);
-       } else {
-               pattrib->encrypt = 0;
-               pattrib->iv_len = 0;
-               pattrib->icv_len = 0;
-       }
-
-       return _SUCCESS;
-}
-
-static int validate_recv_frame(struct adapter *adapter, struct recv_frame *precv_frame)
-{
-       /* shall check frame subtype, to / from ds, da, bssid */
-
-       /* then call check if rx seq/frag. duplicated. */
-
-       int retval = _FAIL;
-       struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data;
-       struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
-
-       if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
-               int ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, rtw_get_oper_ch(adapter));
-
-               if (ch_set_idx >= 0)
-                       pmlmeext->channel_set[ch_set_idx].rx_count++;
-       }
-
-       if ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_VERS)) != 0)
-               return _FAIL;
-
-       pattrib->frag_num = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;
-       pattrib->seq_num = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
-
-       pattrib->pw_save = ieee80211_has_pm(hdr->frame_control);
-       pattrib->mfrag = ieee80211_has_morefrags(hdr->frame_control);
-       pattrib->mdata = ieee80211_has_moredata(hdr->frame_control);
-       pattrib->privacy = ieee80211_has_protected(hdr->frame_control);
-       pattrib->order = ieee80211_has_order(hdr->frame_control);
-
-       /* We return _SUCCESS only for data frames. */
-       if (ieee80211_is_mgmt(hdr->frame_control))
-               validate_recv_mgnt_frame(adapter, precv_frame);
-       else if (ieee80211_is_ctl(hdr->frame_control))
-               validate_recv_ctrl_frame(adapter, precv_frame);
-       else if (ieee80211_is_data(hdr->frame_control)) {
-               rtw_led_control(adapter, LED_CTL_RX);
-               pattrib->qos = ieee80211_is_data_qos(hdr->frame_control);
-               retval = validate_recv_data_frame(adapter, precv_frame);
-               if (retval == _FAIL) {
-                       struct recv_priv *precvpriv = &adapter->recvpriv;
-
-                       precvpriv->rx_drop++;
-               }
-       }
-
-       return retval;
-}
-
-/* remove the wlanhdr and add the eth_hdr */
-
-static int wlanhdr_to_ethhdr(struct recv_frame *precvframe)
-{
-       int     rmv_len;
-       u16     eth_type, len;
-       __be16 be_tmp;
-       u8      bsnaphdr;
-       u8      *psnap_type;
-       struct ieee80211_snap_hdr       *psnap;
-
-       int ret = _SUCCESS;
-       struct adapter                  *adapter = precvframe->adapter;
-       struct mlme_priv        *pmlmepriv = &adapter->mlmepriv;
-
-       u8      *ptr = precvframe->rx_data; /*  point to frame_ctrl field */
-       struct rx_pkt_attrib *pattrib = &precvframe->attrib;
-
-       if (pattrib->encrypt)
-               recvframe_pull_tail(precvframe, pattrib->icv_len);
-
-       psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + pattrib->iv_len);
-       psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE;
-       /* convert hdr + possible LLC headers into Ethernet header */
-       if ((!memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) &&
-            memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) &&
-           memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2)) ||
-           !memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)) {
-               /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
-               bsnaphdr = true;
-       } else {
-               /* Leave Ethernet header part of hdr and full payload */
-               bsnaphdr = false;
-       }
-
-       rmv_len = pattrib->hdrlen + pattrib->iv_len + (bsnaphdr ? SNAP_SIZE : 0);
-       len = precvframe->len - rmv_len;
-
-       memcpy(&be_tmp, ptr + rmv_len, 2);
-       eth_type = ntohs(be_tmp); /* pattrib->ether_type */
-       pattrib->eth_type = eth_type;
-
-       if ((check_fwstate(pmlmepriv, WIFI_MP_STATE))) {
-               ptr += rmv_len;
-               *ptr = 0x87;
-               *(ptr + 1) = 0x12;
-
-               eth_type = 0x8712;
-               /*  append rx status for mp test packets */
-               ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + 2) - 24);
-               if (!ptr)
-                       return _FAIL;
-               memcpy(ptr, get_rxmem(precvframe), 24);
-               ptr += 24;
-       } else {
-               ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
-               if (!ptr)
-                       return _FAIL;
-       }
-
-       memcpy(ptr, pattrib->dst, ETH_ALEN);
-       memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN);
-
-       if (!bsnaphdr) {
-               be_tmp = htons(len);
-               memcpy(ptr + 12, &be_tmp, 2);
-       }
-
-       return ret;
-}
-
-/* perform defrag */
-static struct recv_frame *recvframe_defrag(struct adapter *adapter, struct __queue *defrag_q)
-{
-       struct list_head *plist, *phead;
-       u8 wlanhdr_offset;
-       u8      curfragnum;
-       struct recv_frame *pfhdr, *pnfhdr;
-       struct recv_frame *prframe, *pnextrframe;
-       struct __queue *pfree_recv_queue;
-
-       curfragnum = 0;
-       pfree_recv_queue = &adapter->recvpriv.free_recv_queue;
-
-       phead = get_list_head(defrag_q);
-       plist = phead->next;
-       pfhdr = container_of(plist, struct recv_frame, list);
-       prframe = (struct recv_frame *)pfhdr;
-       list_del_init(&prframe->list);
-
-       if (curfragnum != pfhdr->attrib.frag_num) {
-               /* the first fragment number must be 0 */
-               /* free the whole queue */
-               rtw_free_recvframe(prframe, pfree_recv_queue);
-               rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
-
-               return NULL;
-       }
-
-       curfragnum++;
-
-       plist = get_list_head(defrag_q);
-       plist = phead->next;
-       pfhdr = container_of(plist, struct recv_frame, list);
-       prframe = (struct recv_frame *)pfhdr;
-       list_del_init(&prframe->list);
-
-       plist = plist->next;
-
-       while (phead != plist) {
-               pnfhdr = container_of(plist, struct recv_frame, list);
-               pnextrframe = (struct recv_frame *)pnfhdr;
-
-               /* check the fragment sequence  (2nd ~n fragment frame) */
-
-               if (curfragnum != pnfhdr->attrib.frag_num) {
-                       /* the fragment number must be increasing  (after decache) */
-                       /* release the defrag_q & prframe */
-                       rtw_free_recvframe(prframe, pfree_recv_queue);
-                       rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
-                       return NULL;
-               }
-
-               curfragnum++;
-
-               /* copy the 2nd~n fragment frame's payload to the first fragment */
-               /* get the 2nd~last fragment frame's payload */
-
-               wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len;
-
-               recvframe_pull(pnextrframe, wlanhdr_offset);
-
-               /* append  to first fragment frame's tail (if privacy frame, pull the ICV) */
-               recvframe_pull_tail(prframe, pfhdr->attrib.icv_len);
-
-               /* memcpy */
-               memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len);
-
-               recvframe_put(prframe, pnfhdr->len);
-
-               pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len;
-               plist = plist->next;
-       }
-
-       /* free the defrag_q queue and return the prframe */
-       rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
-
-       return prframe;
-}
-
-/* check if need to defrag, if needed queue the frame to defrag_q */
-struct recv_frame *recvframe_chk_defrag(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       u8      ismfrag;
-       u8      fragnum;
-       u8      *psta_addr;
-       struct recv_frame *pfhdr;
-       struct sta_info *psta;
-       struct sta_priv *pstapriv;
-       struct list_head *phead;
-       struct recv_frame *prtnframe = NULL;
-       struct __queue *pfree_recv_queue, *pdefrag_q;
-
-       pstapriv = &padapter->stapriv;
-
-       pfhdr = precv_frame;
-
-       pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
-
-       /* need to define struct of wlan header frame ctrl */
-       ismfrag = pfhdr->attrib.mfrag;
-       fragnum = pfhdr->attrib.frag_num;
-
-       psta_addr = pfhdr->attrib.ta;
-       psta = rtw_get_stainfo(pstapriv, psta_addr);
-       if (!psta) {
-               __le16 fc = *(__le16 *)pfhdr->rx_data;
-
-               if (ieee80211_is_data(fc)) {
-                       psta = rtw_get_bcmc_stainfo(padapter);
-                       pdefrag_q = &psta->sta_recvpriv.defrag_q;
-               } else {
-                       pdefrag_q = NULL;
-               }
-       } else {
-               pdefrag_q = &psta->sta_recvpriv.defrag_q;
-       }
-
-       if ((ismfrag == 0) && (fragnum == 0))
-               prtnframe = precv_frame;/* isn't a fragment frame */
-
-       if (ismfrag == 1) {
-               /* 0~(n-1) fragment frame */
-               /* enqueue to defraf_g */
-               if (pdefrag_q) {
-                       if (fragnum == 0) {
-                               /* the first fragment */
-                               if (!list_empty(&pdefrag_q->queue)) {
-                                       /* free current defrag_q */
-                                       rtw_free_recvframe_queue(pdefrag_q, pfree_recv_queue);
-                               }
-                       }
-
-                       /* Then enqueue the 0~(n-1) fragment into the defrag_q */
-
-                       phead = get_list_head(pdefrag_q);
-                       list_add_tail(&pfhdr->list, phead);
-
-                       prtnframe = NULL;
-               } else {
-                       /* can't find this ta's defrag_queue, so free this recv_frame */
-                       if (precv_frame && pfree_recv_queue)
-                               rtw_free_recvframe(precv_frame, pfree_recv_queue);
-                       prtnframe = NULL;
-               }
-       }
-
-       if ((ismfrag == 0) && (fragnum != 0)) {
-               /* the last fragment frame */
-               /* enqueue the last fragment */
-               if (pdefrag_q) {
-                       phead = get_list_head(pdefrag_q);
-                       list_add_tail(&pfhdr->list, phead);
-
-                       /* call recvframe_defrag to defrag */
-                       precv_frame = recvframe_defrag(padapter, pdefrag_q);
-                       prtnframe = precv_frame;
-               } else {
-                       /* can't find this ta's defrag_queue, so free this recv_frame */
-                       if (precv_frame && pfree_recv_queue)
-                               rtw_free_recvframe(precv_frame, pfree_recv_queue);
-                       prtnframe = NULL;
-               }
-       }
-
-       if (prtnframe && prtnframe->attrib.privacy) {
-               /* after defrag we must check tkip mic code */
-               if (recvframe_chkmic(padapter,  prtnframe) == _FAIL) {
-                       if (precv_frame && pfree_recv_queue)
-                               rtw_free_recvframe(prtnframe, pfree_recv_queue);
-                       prtnframe = NULL;
-               }
-       }
-
-       return prtnframe;
-}
-
-static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe)
-{
-       int     a_len, padding_len;
-       u16     eth_type, nSubframe_Length;
-       u8      nr_subframes, i;
-       unsigned char *pdata;
-       struct rx_pkt_attrib *pattrib;
-       struct sk_buff *sub_skb, *subframes[MAX_SUBFRAME_COUNT];
-
-       struct recv_priv *precvpriv = &padapter->recvpriv;
-       struct __queue *pfree_recv_queue = &precvpriv->free_recv_queue;
-
-       nr_subframes = 0;
-
-       pattrib = &prframe->attrib;
-
-       recvframe_pull(prframe, prframe->attrib.hdrlen);
-
-       if (prframe->attrib.iv_len > 0)
-               recvframe_pull(prframe, prframe->attrib.iv_len);
-
-       a_len = prframe->len;
-
-       pdata = prframe->rx_data;
-
-       while (a_len > ETH_HLEN) {
-               /* Offset 12 denote 2 mac address */
-               nSubframe_Length = RTW_GET_BE16(pdata + 12);
-
-               if (a_len < ETH_HLEN + nSubframe_Length)
-                       goto exit;
-
-               /* move the data point to data content */
-               pdata += ETH_HLEN;
-               a_len -= ETH_HLEN;
-
-               /* Allocate new skb for releasing to upper layer */
-               sub_skb = dev_alloc_skb(nSubframe_Length + 12);
-               if (sub_skb) {
-                       skb_reserve(sub_skb, 12);
-                       skb_put_data(sub_skb, pdata, nSubframe_Length);
-               } else {
-                       sub_skb = skb_clone(prframe->pkt, GFP_ATOMIC);
-                       if (sub_skb) {
-                               sub_skb->data = pdata;
-                               sub_skb->len = nSubframe_Length;
-                               skb_set_tail_pointer(sub_skb, nSubframe_Length);
-                       } else {
-                               break;
-                       }
-               }
-
-               subframes[nr_subframes++] = sub_skb;
-
-               if (nr_subframes >= MAX_SUBFRAME_COUNT)
-                       break;
-
-               pdata += nSubframe_Length;
-               a_len -= nSubframe_Length;
-               if (a_len != 0) {
-                       padding_len = 4 - ((nSubframe_Length + ETH_HLEN) & (4 - 1));
-                       if (padding_len == 4)
-                               padding_len = 0;
-
-                       if (a_len < padding_len)
-                               goto exit;
-
-                       pdata += padding_len;
-                       a_len -= padding_len;
-               }
-       }
-
-       for (i = 0; i < nr_subframes; i++) {
-               sub_skb = subframes[i];
-               /* convert hdr + possible LLC headers into Ethernet header */
-               eth_type = RTW_GET_BE16(&sub_skb->data[6]);
-               if (sub_skb->len >= 8 &&
-                   ((!memcmp(sub_skb->data, rtw_rfc1042_header, SNAP_SIZE) &&
-                         eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) ||
-                        !memcmp(sub_skb->data, rtw_bridge_tunnel_header, SNAP_SIZE))) {
-                       /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
-                       skb_pull(sub_skb, SNAP_SIZE);
-                       memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN);
-                       memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN);
-               } else {
-                       __be16 len;
-                       /* Leave Ethernet header part of hdr and full payload */
-                       len = htons(sub_skb->len);
-                       memcpy(skb_push(sub_skb, 2), &len, 2);
-                       memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN);
-                       memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN);
-               }
-
-               /* Indicate the packets to upper layer */
-                       /*  Insert NAT2.5 RX here! */
-               sub_skb->protocol = eth_type_trans(sub_skb, padapter->pnetdev);
-               sub_skb->dev = padapter->pnetdev;
-
-               sub_skb->ip_summed = CHECKSUM_NONE;
-
-               netif_rx(sub_skb);
-       }
-
-exit:
-
-       prframe->len = 0;
-       rtw_free_recvframe(prframe, pfree_recv_queue);/* free this recv_frame */
-
-       return _SUCCESS;
-}
-
-static bool check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num)
-{
-       u8      wsize = preorder_ctrl->wsize_b;
-       u16     wend = (preorder_ctrl->indicate_seq + wsize - 1) & 0xFFF;/*  4096; */
-
-       /*  Rx Reorder initialize condition. */
-       if (preorder_ctrl->indicate_seq == 0xFFFF)
-               preorder_ctrl->indicate_seq = seq_num;
-
-       /*  Drop out the packet which SeqNum is smaller than WinStart */
-       if (SN_LESS(seq_num, preorder_ctrl->indicate_seq))
-               return false;
-
-       /*  */
-       /*  Sliding window manipulation. Conditions includes: */
-       /*  1. Incoming SeqNum is equal to WinStart =>Window shift 1 */
-       /*  2. Incoming SeqNum is larger than the WinEnd => Window shift N */
-       /*  */
-       if (SN_EQUAL(seq_num, preorder_ctrl->indicate_seq)) {
-               preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
-       } else if (SN_LESS(wend, seq_num)) {
-               if (seq_num >= (wsize - 1))
-                       preorder_ctrl->indicate_seq = seq_num + 1 - wsize;
-               else
-                       preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1;
-       }
-
-       return true;
-}
-
-static bool enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, struct recv_frame *prframe)
-{
-       struct rx_pkt_attrib *pattrib = &prframe->attrib;
-       struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
-       struct list_head *phead, *plist;
-       struct recv_frame *hdr;
-       struct rx_pkt_attrib *pnextattrib;
-
-       phead = get_list_head(ppending_recvframe_queue);
-       plist = phead->next;
-
-       while (phead != plist) {
-               hdr = container_of(plist, struct recv_frame, list);
-               pnextattrib = &hdr->attrib;
-
-               if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num))
-                       plist = plist->next;
-               else if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num))
-                       return false;
-               else
-                       break;
-       }
-
-       list_del_init(&prframe->list);
-
-       list_add_tail(&prframe->list, plist);
-       return true;
-}
-
-static int rtw_recv_indicatepkt(struct adapter *padapter, struct recv_frame *precv_frame)
-{
-       struct recv_priv *precvpriv;
-       struct __queue *pfree_recv_queue;
-       struct sk_buff *skb;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
-       precvpriv = &padapter->recvpriv;
-       pfree_recv_queue = &precvpriv->free_recv_queue;
-
-       skb = precv_frame->pkt;
-       if (!skb)
-               goto _recv_indicatepkt_drop;
-
-       skb->data = precv_frame->rx_data;
-
-       skb_set_tail_pointer(skb, precv_frame->len);
-
-       skb->len = precv_frame->len;
-
-       if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
-               struct sk_buff *pskb2 = NULL;
-               struct sta_info *psta = NULL;
-               struct sta_priv *pstapriv = &padapter->stapriv;
-               struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
-               bool bmcast = is_multicast_ether_addr(pattrib->dst);
-
-               if (memcmp(pattrib->dst, myid(&padapter->eeprompriv), ETH_ALEN)) {
-                       if (bmcast) {
-                               psta = rtw_get_bcmc_stainfo(padapter);
-                               pskb2 = skb_clone(skb, GFP_ATOMIC);
-                       } else {
-                               psta = rtw_get_stainfo(pstapriv, pattrib->dst);
-                       }
-
-                       if (psta) {
-                               struct net_device *pnetdev;
-
-                               pnetdev = (struct net_device *)padapter->pnetdev;
-                               skb->dev = pnetdev;
-                               skb_set_queue_mapping(skb, rtw_recv_select_queue(skb));
-
-                               rtw_xmit_entry(skb, pnetdev);
-
-                               if (bmcast)
-                                       skb = pskb2;
-                               else
-                                       goto _recv_indicatepkt_end;
-                       }
-               }
-       }
-
-       rcu_read_lock();
-       rcu_dereference(padapter->pnetdev->rx_handler_data);
-       rcu_read_unlock();
-
-       skb->ip_summed = CHECKSUM_NONE;
-       skb->dev = padapter->pnetdev;
-       skb->protocol = eth_type_trans(skb, padapter->pnetdev);
-
-       netif_rx(skb);
-
-_recv_indicatepkt_end:
-
-       /*  pointers to NULL before rtw_free_recvframe() */
-       precv_frame->pkt = NULL;
-
-       rtw_free_recvframe(precv_frame, pfree_recv_queue);
-
-       return _SUCCESS;
-
-_recv_indicatepkt_drop:
-
-       /* enqueue back to free_recv_queue */
-       rtw_free_recvframe(precv_frame, pfree_recv_queue);
-
-       return _FAIL;
-}
-
-static bool recv_indicatepkts_in_order(struct adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced)
-{
-       struct list_head *phead, *plist;
-       struct recv_frame *prframe;
-       struct rx_pkt_attrib *pattrib;
-       int bPktInBuf = false;
-       struct recv_priv *precvpriv = &padapter->recvpriv;
-       struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
-
-       phead =         get_list_head(ppending_recvframe_queue);
-       plist = phead->next;
-
-       /*  Handling some condition for forced indicate case. */
-       if (bforced) {
-               if (list_empty(phead))
-                       return true;
-
-               prframe = container_of(plist, struct recv_frame, list);
-               pattrib = &prframe->attrib;
-               preorder_ctrl->indicate_seq = pattrib->seq_num;
-       }
-
-       /*  Prepare indication list and indication. */
-       /*  Check if there is any packet need indicate. */
-       while (!list_empty(phead)) {
-               prframe = container_of(plist, struct recv_frame, list);
-               pattrib = &prframe->attrib;
-
-               if (!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) {
-                       plist = plist->next;
-                       list_del_init(&prframe->list);
-
-                       if (SN_EQUAL(preorder_ctrl->indicate_seq, pattrib->seq_num))
-                               preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
-
-                       /* Set this as a lock to make sure that only one thread is indicating packet. */
-
-                       /* indicate this recv_frame */
-                       if (!pattrib->amsdu) {
-                               if ((!padapter->bDriverStopped) &&
-                                   (!padapter->bSurpriseRemoved))
-                                       rtw_recv_indicatepkt(padapter, prframe);/* indicate this recv_frame */
-                       } else if (pattrib->amsdu == 1) {
-                               if (amsdu_to_msdu(padapter, prframe) != _SUCCESS)
-                                       rtw_free_recvframe(prframe, &precvpriv->free_recv_queue);
-                       } else {
-                               /* error condition; */
-                       }
-
-                       /* Update local variables. */
-                       bPktInBuf = false;
-               } else {
-                       bPktInBuf = true;
-                       break;
-               }
-       }
-       return bPktInBuf;
-}
-
-static int recv_indicatepkt_reorder(struct adapter *padapter, struct recv_frame *prframe)
-{
-       int retval = _SUCCESS;
-       struct rx_pkt_attrib *pattrib = &prframe->attrib;
-       struct recv_reorder_ctrl *preorder_ctrl = prframe->preorder_ctrl;
-       struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
-
-       if (!pattrib->amsdu) {
-               /* s1. */
-               wlanhdr_to_ethhdr(prframe);
-
-               if (!pattrib->qos) {
-                       if (!padapter->bDriverStopped &&
-                           !padapter->bSurpriseRemoved) {
-                               rtw_recv_indicatepkt(padapter, prframe);
-                               return _SUCCESS;
-                       }
-
-                       return _FAIL;
-               }
-
-               if (!preorder_ctrl->enable) {
-                       /* indicate this recv_frame */
-                       preorder_ctrl->indicate_seq = pattrib->seq_num;
-                       rtw_recv_indicatepkt(padapter, prframe);
-
-                       preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) % 4096;
-                       return _SUCCESS;
-               }
-       } else if (pattrib->amsdu == 1) { /* temp filter -> means didn't support A-MSDUs in a A-MPDU */
-               if (!preorder_ctrl->enable) {
-                       preorder_ctrl->indicate_seq = pattrib->seq_num;
-                       retval = amsdu_to_msdu(padapter, prframe);
-
-                       preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) % 4096;
-                       return retval;
-               }
-       }
-
-       spin_lock_bh(&ppending_recvframe_queue->lock);
-
-       /* s2. check if winstart_b(indicate_seq) needs to been updated */
-       if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num))
-               goto _err_exit;
-
-       /* s3. Insert all packet into Reorder Queue to maintain its ordering. */
-       if (!enqueue_reorder_recvframe(preorder_ctrl, prframe))
-               goto _err_exit;
-
-       /* s4. */
-       /*  Indication process. */
-       /*  After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets */
-       /*  with the SeqNum smaller than latest WinStart and buffer other packets. */
-       /*  */
-       /*  For Rx Reorder condition: */
-       /*  1. All packets with SeqNum smaller than WinStart => Indicate */
-       /*  2. All packets with SeqNum larger than or equal to WinStart => Buffer it. */
-       /*  */
-
-       /* recv_indicatepkts_in_order(padapter, preorder_ctrl, true); */
-       if (recv_indicatepkts_in_order(padapter, preorder_ctrl, false)) {
-               _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
-               spin_unlock_bh(&ppending_recvframe_queue->lock);
-       } else {
-               spin_unlock_bh(&ppending_recvframe_queue->lock);
-               _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);
-       }
-
-       return _SUCCESS;
-
-_err_exit:
-
-       spin_unlock_bh(&ppending_recvframe_queue->lock);
-
-       return _FAIL;
-}
-
-void rtw_reordering_ctrl_timeout_handler(void *pcontext)
-{
-       struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)pcontext;
-       struct adapter *padapter = preorder_ctrl->padapter;
-       struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
-
-       if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
-               return;
-
-       spin_lock_bh(&ppending_recvframe_queue->lock);
-
-       if (recv_indicatepkts_in_order(padapter, preorder_ctrl, true))
-               _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
-
-       spin_unlock_bh(&ppending_recvframe_queue->lock);
-}
-
-static int process_recv_indicatepkts(struct adapter *padapter, struct recv_frame *prframe)
-{
-       int retval = _SUCCESS;
-       /* struct recv_priv *precvpriv = &padapter->recvpriv; */
-       /* struct rx_pkt_attrib *pattrib = &prframe->attrib; */
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-       struct ht_priv  *phtpriv = &pmlmepriv->htpriv;
-
-       if (phtpriv->ht_option) {  /* B/G/N Mode */
-               /* prframe->preorder_ctrl = &precvpriv->recvreorder_ctrl[pattrib->priority]; */
-
-               if (recv_indicatepkt_reorder(padapter, prframe) != _SUCCESS) {
-                       /*  including perform A-MPDU Rx Ordering Buffer Control */
-                       if ((!padapter->bDriverStopped) &&
-                           (!padapter->bSurpriseRemoved)) {
-                               retval = _FAIL;
-                               return retval;
-                       }
-               }
-       } else { /* B/G mode */
-               retval = wlanhdr_to_ethhdr(prframe);
-               if (retval != _SUCCESS)
-                       return retval;
-
-               if ((!padapter->bDriverStopped) &&
-                   (!padapter->bSurpriseRemoved)) {
-                       /* indicate this recv_frame */
-                       rtw_recv_indicatepkt(padapter, prframe);
-               } else {
-                       retval = _FAIL;
-                       return retval;
-               }
-       }
-
-       return retval;
-}
-
-static int recv_func_prehandle(struct adapter *padapter, struct recv_frame *rframe)
-{
-       int ret = _SUCCESS;
-       struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
-
-       /* check the frame crtl field and decache */
-       ret = validate_recv_frame(padapter, rframe);
-       if (ret != _SUCCESS)
-               rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
-
-       return ret;
-}
-
-static int recv_func_posthandle(struct adapter *padapter, struct recv_frame *prframe)
-{
-       int ret = _SUCCESS;
-       struct recv_frame *orig_prframe = prframe;
-       struct recv_priv *precvpriv = &padapter->recvpriv;
-       struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
-
-       /*  DATA FRAME */
-       rtw_led_control(padapter, LED_CTL_RX);
-
-       prframe = decryptor(padapter, prframe);
-       if (!prframe) {
-               ret = _FAIL;
-               goto _recv_data_drop;
-       }
-
-       prframe = recvframe_chk_defrag(padapter, prframe);
-       if (!prframe)
-               goto _recv_data_drop;
-
-       prframe = portctrl(padapter, prframe);
-       if (!prframe) {
-               ret = _FAIL;
-               goto _recv_data_drop;
-       }
-
-       count_rx_stats(padapter, prframe, NULL);
-
-       ret = process_recv_indicatepkts(padapter, prframe);
-       if (ret != _SUCCESS) {
-               rtw_free_recvframe(orig_prframe, pfree_recv_queue);/* free this recv_frame */
-               goto _recv_data_drop;
-       }
-       return ret;
-
-_recv_data_drop:
-       precvpriv->rx_drop++;
-       return ret;
-}
-
-static int recv_func(struct adapter *padapter, struct recv_frame *rframe)
-{
-       int ret;
-       struct rx_pkt_attrib *prxattrib = &rframe->attrib;
-       struct security_priv *psecuritypriv = &padapter->securitypriv;
-       struct mlme_priv *mlmepriv = &padapter->mlmepriv;
-       struct recv_priv *recvpriv = &padapter->recvpriv;
-
-       /* check if need to handle uc_swdec_pending_queue*/
-       if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
-           psecuritypriv->busetkipkey) {
-               struct recv_frame *pending_frame;
-
-               while ((pending_frame = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue)))
-                       recv_func_posthandle(padapter, pending_frame);
-       }
-
-       ret = recv_func_prehandle(padapter, rframe);
-
-       if (ret == _SUCCESS) {
-               /* check if need to enqueue into uc_swdec_pending_queue*/
-               if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
-                   !is_multicast_ether_addr(prxattrib->ra) && prxattrib->encrypt > 0 &&
-                   (prxattrib->bdecrypted == 0 || psecuritypriv->sw_decrypt) &&
-                    psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPAPSK &&
-                    !psecuritypriv->busetkipkey) {
-                       rtw_enqueue_recvframe(rframe, &padapter->recvpriv.uc_swdec_pending_queue);
-                       if (recvpriv->free_recvframe_cnt < NR_RECVFRAME / 4) {
-                               /*
-                                * to prevent from recvframe starvation,
-                                * get recvframe from uc_swdec_pending_queue to
-                                * free_recvframe_cnt
-                                */
-                               rframe = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue);
-                               if (rframe)
-                                       goto do_posthandle;
-                       }
-                       goto exit;
-               }
-do_posthandle:
-               ret = recv_func_posthandle(padapter, rframe);
-       }
-
-exit:
-       return ret;
-}
-
-s32 rtw_recv_entry(struct recv_frame *precvframe)
-{
-       struct adapter *padapter;
-       struct recv_priv *precvpriv;
-       s32 ret = _SUCCESS;
-
-       padapter = precvframe->adapter;
-
-       precvpriv = &padapter->recvpriv;
-
-       ret = recv_func(padapter, precvframe);
-       if (ret == _FAIL)
-               goto _recv_entry_drop;
-
-       precvpriv->rx_pkts++;
-
-       return ret;
-
-_recv_entry_drop:
-
-       return ret;
-}
-
-static void rtw_signal_stat_timer_hdl(struct timer_list *t)
-{
-       struct adapter *adapter = from_timer(adapter, t, recvpriv.signal_stat_timer);
-       struct recv_priv *recvpriv = &adapter->recvpriv;
-
-       u32 tmp_s, tmp_q;
-       u8 avg_signal_strength = 0;
-       u8 avg_signal_qual = 0;
-       u8 _alpha = 3; /*  this value is based on converging_constant = 5000 and sampling_interval = 1000 */
-
-       if (adapter->recvpriv.is_signal_dbg) {
-               /* update the user specific value, signal_strength_dbg, to signal_strength, rssi */
-               adapter->recvpriv.signal_strength = adapter->recvpriv.signal_strength_dbg;
-               adapter->recvpriv.rssi = (s8)translate_percentage_to_dbm((u8)adapter->recvpriv.signal_strength_dbg);
-       } else {
-               if (recvpriv->signal_strength_data.update_req == 0) {/*  update_req is clear, means we got rx */
-                       avg_signal_strength = recvpriv->signal_strength_data.avg_val;
-                       /*  after avg_vals are acquired, we can re-stat the signal values */
-                       recvpriv->signal_strength_data.update_req = 1;
-               }
-
-               if (recvpriv->signal_qual_data.update_req == 0) {/*  update_req is clear, means we got rx */
-                       avg_signal_qual = recvpriv->signal_qual_data.avg_val;
-                       /*  after avg_vals are acquired, we can re-stat the signal values */
-                       recvpriv->signal_qual_data.update_req = 1;
-               }
-
-               /* update value of signal_strength, rssi, signal_qual */
-               if (!check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY)) {
-                       tmp_s = (avg_signal_strength + (_alpha - 1) * recvpriv->signal_strength);
-                       if (tmp_s % _alpha)
-                               tmp_s = tmp_s / _alpha + 1;
-                       else
-                               tmp_s = tmp_s / _alpha;
-                       if (tmp_s > 100)
-                               tmp_s = 100;
-
-                       tmp_q = (avg_signal_qual + (_alpha - 1) * recvpriv->signal_qual);
-                       if (tmp_q % _alpha)
-                               tmp_q = tmp_q / _alpha + 1;
-                       else
-                               tmp_q = tmp_q / _alpha;
-                       if (tmp_q > 100)
-                               tmp_q = 100;
-
-                       recvpriv->signal_strength = tmp_s;
-                       recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s);
-                       recvpriv->signal_qual = tmp_q;
-               }
-       }
-       rtw_set_signal_stat_timer(recvpriv);
-}
diff --git a/drivers/staging/r8188eu/core/rtw_rf.c b/drivers/staging/r8188eu/core/rtw_rf.c
deleted file mode 100644 (file)
index 2d2f0fc..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#include "../include/drv_types.h"
-
-static const u32 ch_freq_map[] = {
-       2412,
-       2417,
-       2422,
-       2427,
-       2432,
-       2437,
-       2442,
-       2447,
-       2452,
-       2457,
-       2462,
-       2467,
-       2472,
-       2484
-};
-
-u32 rtw_ch2freq(u32 channel)
-{
-       if (channel == 0 || channel > ARRAY_SIZE(ch_freq_map))
-               return 2412;
-
-       return ch_freq_map[channel - 1];
-}
diff --git a/drivers/staging/r8188eu/core/rtw_security.c b/drivers/staging/r8188eu/core/rtw_security.c
deleted file mode 100644 (file)
index 780019c..0000000
+++ /dev/null
@@ -1,1374 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#define  _RTW_SECURITY_C_
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/wifi.h"
-#include "../include/osdep_intf.h"
-
-/* WEP related ===== */
-
-/*
-       Need to consider the fragment  situation
-*/
-void rtw_wep_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe)
-{      /*  exclude ICV */
-       union {
-               __le32 f0;
-               u8 f1[4];
-       } crc;
-
-       int     curfragnum, length;
-       u32     keylength;
-
-       u8      *pframe, *payload, *iv;    /* wepkey */
-       u8      wepkey[16];
-       u8   hw_hdr_offset = 0;
-       struct  pkt_attrib       *pattrib = &pxmitframe->attrib;
-       struct  security_priv   *psecuritypriv = &padapter->securitypriv;
-       struct  xmit_priv               *pxmitpriv = &padapter->xmitpriv;
-       struct arc4_ctx *ctx = &psecuritypriv->xmit_arc4_ctx;
-
-       if (!pxmitframe->buf_addr)
-               return;
-
-       hw_hdr_offset = TXDESC_SIZE + pxmitframe->pkt_offset * PACKET_OFFSET_SZ;
-       pframe = pxmitframe->buf_addr + hw_hdr_offset;
-
-       /* start to encrypt each fragment */
-       if ((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) {
-               keylength = psecuritypriv->dot11DefKeylen[psecuritypriv->dot11PrivacyKeyIndex];
-
-               for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
-                       iv = pframe + pattrib->hdrlen;
-                       memcpy(&wepkey[0], iv, 3);
-                       memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength);
-                       payload = pframe + pattrib->iv_len + pattrib->hdrlen;
-
-                       if ((curfragnum + 1) == pattrib->nr_frags) {    /* the last fragment */
-                               length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
-
-                               crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length));
-
-                               arc4_setkey(ctx, wepkey, 3 + keylength);
-                               arc4_crypt(ctx, payload, payload, length);
-                               arc4_crypt(ctx, payload + length, crc.f1, 4);
-                       } else {
-                               length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
-                               crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length));
-                               arc4_setkey(ctx, wepkey, 3 + keylength);
-                               arc4_crypt(ctx, payload, payload, length);
-                               arc4_crypt(ctx, payload + length, crc.f1, 4);
-
-                               pframe += pxmitpriv->frag_len;
-                               pframe = PTR_ALIGN(pframe, 4);
-                       }
-               }
-       }
-
-}
-
-void rtw_wep_decrypt(struct adapter *padapter, struct recv_frame *precvframe)
-{
-       /*  exclude ICV */
-       int     length;
-       u32     keylength;
-       u8      *pframe, *payload, *iv, wepkey[16];
-       u8       keyindex;
-       struct  rx_pkt_attrib    *prxattrib = &precvframe->attrib;
-       struct  security_priv   *psecuritypriv = &padapter->securitypriv;
-       struct arc4_ctx *ctx = &psecuritypriv->recv_arc4_ctx;
-
-       pframe = precvframe->rx_data;
-
-       /* start to decrypt recvframe */
-       if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) {
-               iv = pframe + prxattrib->hdrlen;
-               keyindex = prxattrib->key_index;
-               keylength = psecuritypriv->dot11DefKeylen[keyindex];
-               memcpy(&wepkey[0], iv, 3);
-               memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0], keylength);
-               length = precvframe->len - prxattrib->hdrlen - prxattrib->iv_len;
-
-               payload = pframe + prxattrib->iv_len + prxattrib->hdrlen;
-
-               /* decrypt payload include icv */
-               arc4_setkey(ctx, wepkey, 3 + keylength);
-               arc4_crypt(ctx, payload, payload, length);
-       }
-}
-
-/* 3           ===== TKIP related ===== */
-
-static u32 secmicgetuint32(u8 *p)
-/*  Convert from Byte[] to Us3232 in a portable way */
-{
-       s32 i;
-       u32 res = 0;
-
-       for (i = 0; i < 4; i++)
-               res |= ((u32)(*p++)) << (8 * i);
-
-       return res;
-}
-
-static void secmicputuint32(u8 *p, u32 val)
-/*  Convert from Us3232 to Byte[] in a portable way */
-{
-       long i;
-
-       for (i = 0; i < 4; i++) {
-               *p++ = (u8)(val & 0xff);
-               val >>= 8;
-       }
-
-}
-
-static void secmicclear(struct mic_data *pmicdata)
-{
-/*  Reset the state to the empty message. */
-
-       pmicdata->L = pmicdata->K0;
-       pmicdata->R = pmicdata->K1;
-       pmicdata->nBytesInM = 0;
-       pmicdata->M = 0;
-
-}
-
-void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key)
-{
-       /*  Set the key */
-
-       pmicdata->K0 = secmicgetuint32(key);
-       pmicdata->K1 = secmicgetuint32(key + 4);
-       /*  and reset the message */
-       secmicclear(pmicdata);
-
-}
-
-void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b)
-{
-
-       /*  Append the byte to our word-sized buffer */
-       pmicdata->M |= ((unsigned long)b) << (8 * pmicdata->nBytesInM);
-       pmicdata->nBytesInM++;
-       /*  Process the word if it is full. */
-       if (pmicdata->nBytesInM >= 4) {
-               pmicdata->L ^= pmicdata->M;
-               pmicdata->R ^= ROL32(pmicdata->L, 17);
-               pmicdata->L += pmicdata->R;
-               pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) | ((pmicdata->L & 0x00ff00ff) << 8);
-               pmicdata->L += pmicdata->R;
-               pmicdata->R ^= ROL32(pmicdata->L, 3);
-               pmicdata->L += pmicdata->R;
-               pmicdata->R ^= ROR32(pmicdata->L, 2);
-               pmicdata->L += pmicdata->R;
-               /*  Clear the buffer */
-               pmicdata->M = 0;
-               pmicdata->nBytesInM = 0;
-       }
-
-}
-
-void rtw_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nbytes)
-{
-
-       /*  This is simple */
-       while (nbytes > 0) {
-               rtw_secmicappendbyte(pmicdata, *src++);
-               nbytes--;
-       }
-
-}
-
-void rtw_secgetmic(struct mic_data *pmicdata, u8 *dst)
-{
-
-       /*  Append the minimum padding */
-       rtw_secmicappendbyte(pmicdata, 0x5a);
-       rtw_secmicappendbyte(pmicdata, 0);
-       rtw_secmicappendbyte(pmicdata, 0);
-       rtw_secmicappendbyte(pmicdata, 0);
-       rtw_secmicappendbyte(pmicdata, 0);
-       /*  and then zeroes until the length is a multiple of 4 */
-       while (pmicdata->nBytesInM != 0)
-               rtw_secmicappendbyte(pmicdata, 0);
-       /*  The appendByte function has already computed the result. */
-       secmicputuint32(dst, pmicdata->L);
-       secmicputuint32(dst + 4, pmicdata->R);
-       /*  Reset to the empty message. */
-       secmicclear(pmicdata);
-
-}
-
-void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_code, u8 pri)
-{
-       struct mic_data micdata;
-       u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
-
-       rtw_secmicsetkey(&micdata, key);
-       priority[0] = pri;
-
-       /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
-       if (header[1] & 1) {   /* ToDS == 1 */
-               rtw_secmicappend(&micdata, &header[16], 6);  /* DA */
-               if (header[1] & 2)  /* From Ds == 1 */
-                       rtw_secmicappend(&micdata, &header[24], 6);
-               else
-                       rtw_secmicappend(&micdata, &header[10], 6);
-       } else {        /* ToDS == 0 */
-               rtw_secmicappend(&micdata, &header[4], 6);   /* DA */
-               if (header[1] & 2)  /* From Ds == 1 */
-                       rtw_secmicappend(&micdata, &header[16], 6);
-               else
-                       rtw_secmicappend(&micdata, &header[10], 6);
-       }
-       rtw_secmicappend(&micdata, &priority[0], 4);
-
-       rtw_secmicappend(&micdata, data, data_len);
-
-       rtw_secgetmic(&micdata, mic_code);
-
-}
-
-/* macros for extraction/creation of unsigned char/unsigned short values  */
-#define RotR1(v16)   ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15))
-#define   Lo8(v16)   ((u8)((v16)       & 0x00FF))
-#define   Hi8(v16)   ((u8)(((v16) >> 8) & 0x00FF))
-#define  Lo16(v32)   ((u16)((v32)       & 0xFFFF))
-#define  Hi16(v32)   ((u16)(((v32) >> 16) & 0xFFFF))
-#define  Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8))
-
-/* select the Nth 16-bit word of the temporal key unsigned char array TK[]   */
-#define  TK16(N)     Mk16(tk[2 * (N) + 1], tk[2 * (N)])
-
-/* S-box lookup: 16 bits --> 16 bits */
-#define _S_(v16)     (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)])
-
-/* fixed algorithm "parameters" */
-#define PHASE1_LOOP_CNT   8    /* this needs to be "big enough"     */
-#define TA_SIZE           6    /*  48-bit transmitter address       */
-#define TK_SIZE          16    /* 128-bit temporal key       */
-#define P1K_SIZE        10    /*  80-bit Phase1 key            */
-#define RC4_KEY_SIZE     16    /* 128-bit RC4KEY (104 bits unknown) */
-
-/* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */
-static const unsigned short Sbox1[2][256] = {  /* Sbox for hash (can be in ROM)     */
-{
-   0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
-   0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
-   0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
-   0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
-   0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
-   0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
-   0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
-   0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
-   0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
-   0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
-   0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
-   0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
-   0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
-   0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
-   0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
-   0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
-   0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
-   0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
-   0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
-   0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
-   0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
-   0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
-   0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
-   0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
-   0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
-   0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
-   0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
-   0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
-   0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
-   0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
-   0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
-   0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
-  },
-
-  {  /* second half of table is unsigned char-reversed version of first! */
-   0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
-   0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
-   0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
-   0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
-   0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
-   0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
-   0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
-   0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
-   0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
-   0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
-   0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
-   0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
-   0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
-   0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
-   0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
-   0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
-   0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
-   0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
-   0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
-   0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
-   0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
-   0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
-   0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
-   0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
-   0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
-   0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
-   0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
-   0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
-   0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
-   0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
-   0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
-   0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,
-  }
-};
-
- /*
-**********************************************************************
-* Routine: Phase 1 -- generate P1K, given TA, TK, IV32
-*
-* Inputs:
-*     tk[]      = temporal key                  [128 bits]
-*     ta[]      = transmitter's MAC address        [ 48 bits]
-*     iv32      = upper 32 bits of IV            [ 32 bits]
-* Output:
-*     p1k[]     = Phase 1 key                    [ 80 bits]
-*
-* Note:
-*     This function only needs to be called every 2**16 packets,
-*     although in theory it could be called every packet.
-*
-**********************************************************************
-*/
-static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32)
-{
-       int  i;
-
-       /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5]     */
-       p1k[0]      = Lo16(iv32);
-       p1k[1]      = Hi16(iv32);
-       p1k[2]      = Mk16(ta[1], ta[0]); /* use TA[] as little-endian */
-       p1k[3]      = Mk16(ta[3], ta[2]);
-       p1k[4]      = Mk16(ta[5], ta[4]);
-
-       /* Now compute an unbalanced Feistel cipher with 80-bit block */
-       /* size on the 80-bit block P1K[], using the 128-bit key TK[] */
-       for (i = 0; i < PHASE1_LOOP_CNT; i++) { /* Each add operation here is mod 2**16 */
-               p1k[0] += _S_(p1k[4] ^ TK16((i & 1) + 0));
-               p1k[1] += _S_(p1k[0] ^ TK16((i & 1) + 2));
-               p1k[2] += _S_(p1k[1] ^ TK16((i & 1) + 4));
-               p1k[3] += _S_(p1k[2] ^ TK16((i & 1) + 6));
-               p1k[4] += _S_(p1k[3] ^ TK16((i & 1) + 0));
-               p1k[4] +=  (unsigned short)i;   /* avoid "slide attacks" */
-       }
-
-}
-
-/*
-**********************************************************************
-* Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16
-*
-* Inputs:
-*     tk[]      = Temporal key                  [128 bits]
-*     p1k[]     = Phase 1 output key              [ 80 bits]
-*     iv16      = low 16 bits of IV counter        [ 16 bits]
-* Output:
-*     rc4key[]  = the key used to encrypt the packet   [128 bits]
-*
-* Note:
-*     The value {TA, IV32, IV16} for Phase1/Phase2 must be unique
-*     across all packets using the same key TK value. Then, for a
-*     given value of TK[], this TKIP48 construction guarantees that
-*     the final RC4KEY value is unique across all packets.
-*
-* Suggested implementation optimization: if PPK[] is "overlaid"
-*     appropriately on RC4KEY[], there is no need for the final
-*     for loop below that copies the PPK[] result into RC4KEY[].
-*
-**********************************************************************
-*/
-static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16)
-{
-       int  i;
-       u16 PPK[6];                     /* temporary key for mixing    */
-
-       /* Note: all adds in the PPK[] equations below are mod 2**16     */
-       for (i = 0; i < 5; i++)
-               PPK[i] = p1k[i];        /* first, copy P1K to PPK      */
-       PPK[5]  =  p1k[4] + iv16;       /* next,  add in IV16     */
-
-       /* Bijective non-linear mixing of the 96 bits of PPK[0..5]         */
-       PPK[0] +=    _S_(PPK[5] ^ TK16(0));   /* Mix key in each "round"     */
-       PPK[1] +=    _S_(PPK[0] ^ TK16(1));
-       PPK[2] +=    _S_(PPK[1] ^ TK16(2));
-       PPK[3] +=    _S_(PPK[2] ^ TK16(3));
-       PPK[4] +=    _S_(PPK[3] ^ TK16(4));
-       PPK[5] +=    _S_(PPK[4] ^ TK16(5));   /* Total # S-box lookups == 6  */
-
-       /* Final sweep: bijective, "linear". Rotates kill LSB correlations   */
-       PPK[0] +=  RotR1(PPK[5] ^ TK16(6));
-       PPK[1] +=  RotR1(PPK[0] ^ TK16(7));   /* Use all of TK[] in Phase2   */
-       PPK[2] +=  RotR1(PPK[1]);
-       PPK[3] +=  RotR1(PPK[2]);
-       PPK[4] +=  RotR1(PPK[3]);
-       PPK[5] +=  RotR1(PPK[4]);
-       /* Note: At this point, for a given key TK[0..15], the 96-bit output */
-       /*       value PPK[0..5] is guaranteed to be unique, as a function   */
-       /*       of the 96-bit "input" value   {TA, IV32, IV16}. That is, P1K  */
-       /*       is now a keyed permutation of {TA, IV32, IV16}.               */
-
-       /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key   */
-       rc4key[0] = Hi8(iv16);          /* RC4KEY[0..2] is the WEP IV  */
-       rc4key[1] = (Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys  */
-       rc4key[2] = Lo8(iv16);
-       rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1);
-
-       /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15]  (little-endian)       */
-       for (i = 0; i < 6; i++) {
-               rc4key[4 + 2 * i] = Lo8(PPK[i]);
-               rc4key[5 + 2 * i] = Hi8(PPK[i]);
-       }
-
-}
-
-/* The hlen isn't include the IV */
-u32 rtw_tkip_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe)
-{                                                                                                                                      /*  exclude ICV */
-       u16     pnl;
-       u32     pnh;
-       u8      rc4key[16];
-       u8   ttkey[16];
-       union {
-               __le32 f0;
-               u8 f1[4];
-       } crc;
-       u8   hw_hdr_offset = 0;
-       int                     curfragnum, length;
-
-       u8      *pframe, *payload, *iv, *prwskey;
-       union pn48 dot11txpn;
-       struct  sta_info                *stainfo;
-       struct  pkt_attrib       *pattrib = &pxmitframe->attrib;
-       struct  security_priv   *psecuritypriv = &padapter->securitypriv;
-       struct  xmit_priv               *pxmitpriv = &padapter->xmitpriv;
-       struct arc4_ctx *ctx = &psecuritypriv->xmit_arc4_ctx;
-       u32     res = _SUCCESS;
-
-       if (!pxmitframe->buf_addr)
-               return _FAIL;
-
-       hw_hdr_offset = TXDESC_SIZE + pxmitframe->pkt_offset * PACKET_OFFSET_SZ;
-       pframe = pxmitframe->buf_addr + hw_hdr_offset;
-
-       /* 4 start to encrypt each fragment */
-       if (pattrib->encrypt == _TKIP_) {
-               if (pattrib->psta)
-                       stainfo = pattrib->psta;
-               else
-                       stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]);
-
-               if (stainfo) {
-                       if (is_multicast_ether_addr(pattrib->ra))
-                               prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
-                       else
-                               prwskey = &stainfo->dot118021x_UncstKey.skey[0];
-
-                       for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
-                               iv = pframe + pattrib->hdrlen;
-                               payload = pframe + pattrib->iv_len + pattrib->hdrlen;
-
-                               GET_TKIP_PN(iv, dot11txpn);
-
-                               pnl = (u16)(dot11txpn.val);
-                               pnh = (u32)(dot11txpn.val >> 16);
-                               phase1((u16 *)&ttkey[0], prwskey, &pattrib->ta[0], pnh);
-                               phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0], pnl);
-
-                               if ((curfragnum + 1) == pattrib->nr_frags) {    /* 4 the last fragment */
-                                       length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
-                                       crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length));
-
-                                       arc4_setkey(ctx, rc4key, 16);
-                                       arc4_crypt(ctx, payload, payload, length);
-                                       arc4_crypt(ctx, payload + length, crc.f1, 4);
-                               } else {
-                                       length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
-                                       crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length));
-
-                                       arc4_setkey(ctx, rc4key, 16);
-                                       arc4_crypt(ctx, payload, payload, length);
-                                       arc4_crypt(ctx, payload + length, crc.f1, 4);
-
-                                       pframe += pxmitpriv->frag_len;
-                                       pframe = PTR_ALIGN(pframe, 4);
-                               }
-                       }
-               } else {
-                       res = _FAIL;
-               }
-       }
-
-       return res;
-}
-
-/* The hlen isn't include the IV */
-u32 rtw_tkip_decrypt(struct adapter *padapter, struct recv_frame *precvframe)
-{                                                                                                                                      /*  exclude ICV */
-       u16 pnl;
-       u32 pnh;
-       u8   rc4key[16];
-       u8   ttkey[16];
-       union {
-               __le32 f0;
-               u8 f1[4];
-       } crc;
-       int                     length;
-
-       u8      *pframe, *payload, *iv, *prwskey;
-       union pn48 dot11txpn;
-       struct  sta_info                *stainfo;
-       struct  rx_pkt_attrib    *prxattrib = &precvframe->attrib;
-       struct  security_priv   *psecuritypriv = &padapter->securitypriv;
-       struct arc4_ctx *ctx = &psecuritypriv->recv_arc4_ctx;
-       u32             res = _SUCCESS;
-
-       pframe = precvframe->rx_data;
-
-       /* 4 start to decrypt recvframe */
-       if (prxattrib->encrypt == _TKIP_) {
-               stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
-               if (stainfo) {
-                       if (is_multicast_ether_addr(prxattrib->ra)) {
-                               if (!psecuritypriv->binstallGrpkey) {
-                                       res = _FAIL;
-                                       goto exit;
-                               }
-                               prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
-                       } else {
-                               prwskey = &stainfo->dot118021x_UncstKey.skey[0];
-                       }
-
-                       iv = pframe + prxattrib->hdrlen;
-                       payload = pframe + prxattrib->iv_len + prxattrib->hdrlen;
-                       length = precvframe->len - prxattrib->hdrlen - prxattrib->iv_len;
-
-                       GET_TKIP_PN(iv, dot11txpn);
-
-                       pnl = (u16)(dot11txpn.val);
-                       pnh = (u32)(dot11txpn.val >> 16);
-
-                       phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0], pnh);
-                       phase2(&rc4key[0], prwskey, (unsigned short *)&ttkey[0], pnl);
-
-                       /* 4 decrypt payload include icv */
-
-                       arc4_setkey(ctx, rc4key, 16);
-                       arc4_crypt(ctx, payload, payload, length);
-
-                       crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length));
-
-                       if (crc.f1[3] != payload[length - 1] ||
-                           crc.f1[2] != payload[length - 2] ||
-                           crc.f1[1] != payload[length - 3] ||
-                           crc.f1[0] != payload[length - 4])
-                               res = _FAIL;
-               } else {
-                       res = _FAIL;
-               }
-       }
-
-exit:
-       return res;
-}
-
-/* 3                   ===== AES related ===== */
-
-#define MAX_MSG_SIZE   2048
-/*****************************/
-/******** SBOX Table *********/
-/*****************************/
-
-static  u8 sbox_table[256] = {
-       0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
-       0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
-       0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
-       0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
-       0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
-       0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
-       0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
-       0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
-       0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
-       0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
-       0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
-       0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
-       0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
-       0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
-       0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
-       0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
-       0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
-       0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
-       0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
-       0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
-       0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
-       0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
-       0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
-       0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
-       0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
-       0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
-       0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
-       0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
-       0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
-       0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
-       0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
-       0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-};
-
-/*****************************/
-/**** Function Prototypes ****/
-/*****************************/
-
-static void bitwise_xor(u8 *ina, u8 *inb, u8 *out);
-static void construct_mic_iv(u8 *mic_header1, int qc_exists, int a4_exists, u8 *mpdu, uint payload_length, u8 *pn_vector);
-static void construct_mic_header1(u8 *mic_header1, int header_length, u8 *mpdu);
-static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, int qc_exists);
-static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists, u8 *mpdu, u8 *pn_vector, int c);
-static void xor_128(u8 *a, u8 *b, u8 *out);
-static void xor_32(u8 *a, u8 *b, u8 *out);
-static u8 sbox(u8 a);
-static void next_key(u8 *key, int round);
-static void byte_sub(u8 *in, u8 *out);
-static void shift_row(u8 *in, u8 *out);
-static void mix_column(u8 *in, u8 *out);
-static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext);
-
-/****************************************/
-/* aes128k128d()                       */
-/* Performs a 128 bit AES encrypt with  */
-/* 128 bit data.                       */
-/****************************************/
-static void xor_128(u8 *a, u8 *b, u8 *out)
-{
-       int i;
-
-       for (i = 0; i < 16; i++)
-               out[i] = a[i] ^ b[i];
-
-}
-
-static void xor_32(u8 *a, u8 *b, u8 *out)
-{
-       int i;
-
-       for (i = 0; i < 4; i++)
-               out[i] = a[i] ^ b[i];
-
-}
-
-static u8 sbox(u8 a)
-{
-       return sbox_table[(int)a];
-}
-
-static void next_key(u8 *key, int round)
-{
-       u8 rcon;
-       u8 sbox_key[4];
-       u8 rcon_table[12] = {
-               0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
-               0x1b, 0x36, 0x36, 0x36
-       };
-
-       sbox_key[0] = sbox(key[13]);
-       sbox_key[1] = sbox(key[14]);
-       sbox_key[2] = sbox(key[15]);
-       sbox_key[3] = sbox(key[12]);
-
-       rcon = rcon_table[round];
-
-       xor_32(&key[0], sbox_key, &key[0]);
-       key[0] = key[0] ^ rcon;
-
-       xor_32(&key[4], &key[0], &key[4]);
-       xor_32(&key[8], &key[4], &key[8]);
-       xor_32(&key[12], &key[8], &key[12]);
-
-}
-
-static void byte_sub(u8 *in, u8 *out)
-{
-       int i;
-
-       for (i = 0; i < 16; i++)
-               out[i] = sbox(in[i]);
-
-}
-
-static void shift_row(u8 *in, u8 *out)
-{
-
-       out[0] =  in[0];
-       out[1] =  in[5];
-       out[2] =  in[10];
-       out[3] =  in[15];
-       out[4] =  in[4];
-       out[5] =  in[9];
-       out[6] =  in[14];
-       out[7] =  in[3];
-       out[8] =  in[8];
-       out[9] =  in[13];
-       out[10] = in[2];
-       out[11] = in[7];
-       out[12] = in[12];
-       out[13] = in[1];
-       out[14] = in[6];
-       out[15] = in[11];
-
-}
-
-static void mix_column(u8 *in, u8 *out)
-{
-       int i;
-       u8 add1b[4];
-       u8 add1bf7[4];
-       u8 rotl[4];
-       u8 swap_halfs[4];
-       u8 andf7[4];
-       u8 rotr[4];
-       u8 temp[4];
-       u8 tempb[4];
-
-       for (i = 0 ; i < 4; i++) {
-               if ((in[i] & 0x80) == 0x80)
-                       add1b[i] = 0x1b;
-               else
-                       add1b[i] = 0x00;
-       }
-
-       swap_halfs[0] = in[2];    /* Swap halves */
-       swap_halfs[1] = in[3];
-       swap_halfs[2] = in[0];
-       swap_halfs[3] = in[1];
-
-       rotl[0] = in[3];        /* Rotate left 8 bits */
-       rotl[1] = in[0];
-       rotl[2] = in[1];
-       rotl[3] = in[2];
-
-       andf7[0] = in[0] & 0x7f;
-       andf7[1] = in[1] & 0x7f;
-       andf7[2] = in[2] & 0x7f;
-       andf7[3] = in[3] & 0x7f;
-
-       for (i = 3; i > 0; i--) {    /* logical shift left 1 bit */
-               andf7[i] = andf7[i] << 1;
-               if ((andf7[i - 1] & 0x80) == 0x80)
-                       andf7[i] = (andf7[i] | 0x01);
-       }
-       andf7[0] = andf7[0] << 1;
-       andf7[0] = andf7[0] & 0xfe;
-
-       xor_32(add1b, andf7, add1bf7);
-
-       xor_32(in, add1bf7, rotr);
-
-       temp[0] = rotr[0];       /* Rotate right 8 bits */
-       rotr[0] = rotr[1];
-       rotr[1] = rotr[2];
-       rotr[2] = rotr[3];
-       rotr[3] = temp[0];
-
-       xor_32(add1bf7, rotr, temp);
-       xor_32(swap_halfs, rotl, tempb);
-       xor_32(temp, tempb, out);
-
-}
-
-static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext)
-{
-       int round;
-       int i;
-       u8 intermediatea[16];
-       u8 intermediateb[16];
-       u8 round_key[16];
-
-       for (i = 0; i < 16; i++)
-               round_key[i] = key[i];
-       for (round = 0; round < 11; round++) {
-               if (round == 0) {
-                       xor_128(round_key, data, ciphertext);
-                       next_key(round_key, round);
-               } else if (round == 10) {
-                       byte_sub(ciphertext, intermediatea);
-                       shift_row(intermediatea, intermediateb);
-                       xor_128(intermediateb, round_key, ciphertext);
-               } else {    /* 1 - 9 */
-                       byte_sub(ciphertext, intermediatea);
-                       shift_row(intermediatea, intermediateb);
-                       mix_column(&intermediateb[0], &intermediatea[0]);
-                       mix_column(&intermediateb[4], &intermediatea[4]);
-                       mix_column(&intermediateb[8], &intermediatea[8]);
-                       mix_column(&intermediateb[12], &intermediatea[12]);
-                       xor_128(intermediatea, round_key, ciphertext);
-                       next_key(round_key, round);
-               }
-       }
-
-}
-
-/************************************************/
-/* construct_mic_iv()                     */
-/* Builds the MIC IV from header fields and PN  */
-/************************************************/
-static void construct_mic_iv(u8 *mic_iv, int qc_exists, int a4_exists, u8 *mpdu,
-                            uint payload_length, u8 *pn_vector)
-{
-       int i;
-
-       mic_iv[0] = 0x59;
-       if (qc_exists && a4_exists)
-               mic_iv[1] = mpdu[30] & 0x0f;    /* QoS_TC          */
-       if (qc_exists && !a4_exists)
-               mic_iv[1] = mpdu[24] & 0x0f;    /* mute bits 7-4    */
-       if (!qc_exists)
-               mic_iv[1] = 0x00;
-       for (i = 2; i < 8; i++)
-               mic_iv[i] = mpdu[i + 8];        /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
-       for (i = 8; i < 14; i++)
-               mic_iv[i] = pn_vector[13 - i];  /* mic_iv[8:13] = PN[5:0] */
-       mic_iv[14] = (unsigned char)(payload_length / 256);
-       mic_iv[15] = (unsigned char)(payload_length % 256);
-
-}
-
-/************************************************/
-/* construct_mic_header1()                   */
-/* Builds the first MIC header block from       */
-/* header fields.                             */
-/************************************************/
-static void construct_mic_header1(u8 *mic_header1, int header_length, u8 *mpdu)
-{
-
-       mic_header1[0] = (u8)((header_length - 2) / 256);
-       mic_header1[1] = (u8)((header_length - 2) % 256);
-       mic_header1[2] = mpdu[0] & 0xcf;    /* Mute CF poll & CF ack bits */
-       mic_header1[3] = mpdu[1] & 0xc7;    /* Mute retry, more data and pwr mgt bits */
-       mic_header1[4] = mpdu[4];       /* A1 */
-       mic_header1[5] = mpdu[5];
-       mic_header1[6] = mpdu[6];
-       mic_header1[7] = mpdu[7];
-       mic_header1[8] = mpdu[8];
-       mic_header1[9] = mpdu[9];
-       mic_header1[10] = mpdu[10];     /* A2 */
-       mic_header1[11] = mpdu[11];
-       mic_header1[12] = mpdu[12];
-       mic_header1[13] = mpdu[13];
-       mic_header1[14] = mpdu[14];
-       mic_header1[15] = mpdu[15];
-
-}
-
-/************************************************/
-/* construct_mic_header2()                   */
-/* Builds the last MIC header block from       */
-/* header fields.                             */
-/************************************************/
-static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, int qc_exists)
-{
-       int i;
-
-       for (i = 0; i < 16; i++)
-               mic_header2[i] = 0x00;
-
-       mic_header2[0] = mpdu[16];    /* A3 */
-       mic_header2[1] = mpdu[17];
-       mic_header2[2] = mpdu[18];
-       mic_header2[3] = mpdu[19];
-       mic_header2[4] = mpdu[20];
-       mic_header2[5] = mpdu[21];
-
-       mic_header2[6] = 0x00;
-       mic_header2[7] = 0x00; /* mpdu[23]; */
-
-       if (!qc_exists && a4_exists) {
-               for (i = 0; i < 6; i++)
-                       mic_header2[8 + i] = mpdu[24 + i];   /* A4 */
-       }
-
-       if (qc_exists && !a4_exists) {
-               mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
-               mic_header2[9] = mpdu[25] & 0x00;
-       }
-
-       if (qc_exists && a4_exists) {
-               for (i = 0; i < 6; i++)
-                       mic_header2[8 + i] = mpdu[24 + i];   /* A4 */
-
-               mic_header2[14] = mpdu[30] & 0x0f;
-               mic_header2[15] = mpdu[31] & 0x00;
-       }
-
-}
-
-/************************************************/
-/* construct_mic_header2()                   */
-/* Builds the last MIC header block from       */
-/* header fields.                             */
-/************************************************/
-static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists, u8 *mpdu, u8 *pn_vector, int c)
-{
-       int i;
-
-       for (i = 0; i < 16; i++)
-               ctr_preload[i] = 0x00;
-       i = 0;
-
-       ctr_preload[0] = 0x01;                            /* flag */
-       if (qc_exists && a4_exists)
-               ctr_preload[1] = mpdu[30] & 0x0f;   /* QoC_Control */
-       if (qc_exists && !a4_exists)
-               ctr_preload[1] = mpdu[24] & 0x0f;
-
-       for (i = 2; i < 8; i++)
-               ctr_preload[i] = mpdu[i + 8];                  /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
-       for (i = 8; i < 14; i++)
-               ctr_preload[i] =    pn_vector[13 - i];    /* ctr_preload[8:13] = PN[5:0] */
-       ctr_preload[14] =  (unsigned char)(c / 256); /* Ctr */
-       ctr_preload[15] =  (unsigned char)(c % 256);
-
-}
-
-/************************************/
-/* bitwise_xor()                   */
-/* A 128 bit, bitwise exclusive or  */
-/************************************/
-static void bitwise_xor(u8 *ina, u8 *inb, u8 *out)
-{
-       int i;
-
-       for (i = 0; i < 16; i++)
-               out[i] = ina[i] ^ inb[i];
-
-}
-
-static void aes_cipher(u8 *key, uint hdrlen, u8 *pframe, uint plen)
-{
-       uint    qc_exists, a4_exists, i, j, payload_remainder,
-               num_blocks, payload_index;
-
-       u8 pn_vector[6];
-       u8 mic_iv[16];
-       u8 mic_header1[16];
-       u8 mic_header2[16];
-       u8 ctr_preload[16];
-
-       /* Intermediate Buffers */
-       u8 chain_buffer[16];
-       u8 aes_out[16];
-       u8 padded_buffer[16];
-       u8 mic[8];
-       uint    frtype  = GetFrameType(pframe);
-       uint    frsubtype  = GetFrameSubType(pframe);
-
-       frsubtype = frsubtype >> 4;
-
-       memset((void *)mic_iv, 0, 16);
-       memset((void *)mic_header1, 0, 16);
-       memset((void *)mic_header2, 0, 16);
-       memset((void *)ctr_preload, 0, 16);
-       memset((void *)chain_buffer, 0, 16);
-       memset((void *)aes_out, 0, 16);
-       memset((void *)padded_buffer, 0, 16);
-
-       if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen ==  WLAN_HDR_A3_QOS_LEN))
-               a4_exists = 0;
-       else
-               a4_exists = 1;
-
-       if ((frtype == WIFI_DATA_CFACK) || (frtype == WIFI_DATA_CFPOLL) || (frtype == WIFI_DATA_CFACKPOLL)) {
-               qc_exists = 1;
-               if (hdrlen !=  WLAN_HDR_A3_QOS_LEN)
-                       hdrlen += 2;
-       } else if ((frsubtype == 0x08) || (frsubtype == 0x09) || (frsubtype == 0x0a) || (frsubtype == 0x0b)) {
-               if (hdrlen !=  WLAN_HDR_A3_QOS_LEN)
-                       hdrlen += 2;
-               qc_exists = 1;
-       } else {
-               qc_exists = 0;
-       }
-
-       pn_vector[0] = pframe[hdrlen];
-       pn_vector[1] = pframe[hdrlen + 1];
-       pn_vector[2] = pframe[hdrlen + 4];
-       pn_vector[3] = pframe[hdrlen + 5];
-       pn_vector[4] = pframe[hdrlen + 6];
-       pn_vector[5] = pframe[hdrlen + 7];
-
-       construct_mic_iv(mic_iv, qc_exists, a4_exists, pframe, plen, pn_vector);
-
-       construct_mic_header1(mic_header1, hdrlen, pframe);
-       construct_mic_header2(mic_header2, pframe, a4_exists, qc_exists);
-
-       payload_remainder = plen % 16;
-       num_blocks = plen / 16;
-
-       /* Find start of payload */
-       payload_index = (hdrlen + 8);
-
-       /* Calculate MIC */
-       aes128k128d(key, mic_iv, aes_out);
-       bitwise_xor(aes_out, mic_header1, chain_buffer);
-       aes128k128d(key, chain_buffer, aes_out);
-       bitwise_xor(aes_out, mic_header2, chain_buffer);
-       aes128k128d(key, chain_buffer, aes_out);
-
-       for (i = 0; i < num_blocks; i++) {
-               bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);/* bitwise_xor(aes_out, &message[payload_index], chain_buffer); */
-
-               payload_index += 16;
-               aes128k128d(key, chain_buffer, aes_out);
-       }
-
-       /* Add on the final payload block if it needs padding */
-       if (payload_remainder > 0) {
-               for (j = 0; j < 16; j++)
-                       padded_buffer[j] = 0x00;
-               for (j = 0; j < payload_remainder; j++)
-                       padded_buffer[j] = pframe[payload_index++];/* padded_buffer[j] = message[payload_index++]; */
-               bitwise_xor(aes_out, padded_buffer, chain_buffer);
-               aes128k128d(key, chain_buffer, aes_out);
-       }
-
-       for (j = 0; j < 8; j++)
-               mic[j] = aes_out[j];
-
-       /* Insert MIC into payload */
-       for (j = 0; j < 8; j++)
-               pframe[payload_index + j] = mic[j]; /* message[payload_index+j] = mic[j]; */
-
-       payload_index = hdrlen + 8;
-       for (i = 0; i < num_blocks; i++) {
-               construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, i + 1);
-               aes128k128d(key, ctr_preload, aes_out);
-               bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
-               for (j = 0; j < 16; j++)
-                       pframe[payload_index++] = chain_buffer[j];
-       }
-
-       if (payload_remainder > 0) {    /* If there is a short final block, then pad it,*/
-                                       /* encrypt it and copy the unpadded part back   */
-               construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, num_blocks + 1);
-
-               for (j = 0; j < 16; j++)
-                       padded_buffer[j] = 0x00;
-               for (j = 0; j < payload_remainder; j++)
-                       padded_buffer[j] = pframe[payload_index + j];
-               aes128k128d(key, ctr_preload, aes_out);
-               bitwise_xor(aes_out, padded_buffer, chain_buffer);
-               for (j = 0; j < payload_remainder; j++)
-                       pframe[payload_index++] = chain_buffer[j];
-       }
-       /* Encrypt the MIC */
-       construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, 0);
-
-       for (j = 0; j < 16; j++)
-               padded_buffer[j] = 0x00;
-       for (j = 0; j < 8; j++)
-               padded_buffer[j] = pframe[j + hdrlen + 8 + plen];
-
-       aes128k128d(key, ctr_preload, aes_out);
-       bitwise_xor(aes_out, padded_buffer, chain_buffer);
-       for (j = 0; j < 8; j++)
-               pframe[payload_index++] = chain_buffer[j];
-}
-
-u32 rtw_aes_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe)
-{      /*  exclude ICV */
-
-       /*static*/
-/*     unsigned char   message[MAX_MSG_SIZE]; */
-
-       /* Intermediate Buffers */
-       int     curfragnum, length;
-       u8      *pframe, *prwskey;      /*  *payload,*iv */
-       u8   hw_hdr_offset = 0;
-       struct  sta_info                *stainfo;
-       struct  pkt_attrib       *pattrib = &pxmitframe->attrib;
-       struct  security_priv   *psecuritypriv = &padapter->securitypriv;
-       struct  xmit_priv               *pxmitpriv = &padapter->xmitpriv;
-
-/*     uint    offset = 0; */
-       u32 res = _SUCCESS;
-
-       if (!pxmitframe->buf_addr)
-               return _FAIL;
-
-       hw_hdr_offset = TXDESC_SIZE + pxmitframe->pkt_offset * PACKET_OFFSET_SZ;
-       pframe = pxmitframe->buf_addr + hw_hdr_offset;
-
-       /* 4 start to encrypt each fragment */
-       if (pattrib->encrypt == _AES_) {
-               if (pattrib->psta)
-                       stainfo = pattrib->psta;
-               else
-                       stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]);
-
-               if (stainfo) {
-                       if (is_multicast_ether_addr(pattrib->ra))
-                               prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
-                       else
-                               prwskey = &stainfo->dot118021x_UncstKey.skey[0];
-                       for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
-                               if ((curfragnum + 1) == pattrib->nr_frags) {    /* 4 the last fragment */
-                                       length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
-
-                                       aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
-                               } else {
-                                       length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
-
-                                       aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
-                                       pframe += pxmitpriv->frag_len;
-                                       pframe = PTR_ALIGN(pframe, 4);
-                               }
-                       }
-               } else {
-                       res = _FAIL;
-               }
-       }
-
-       return res;
-}
-
-static int aes_decipher(u8 *key, uint hdrlen,
-                       u8 *pframe, uint plen)
-{
-       static u8       message[MAX_MSG_SIZE];
-       uint    qc_exists, a4_exists, i, j, payload_remainder,
-                       num_blocks, payload_index;
-       int res = _SUCCESS;
-       u8 pn_vector[6];
-       u8 mic_iv[16];
-       u8 mic_header1[16];
-       u8 mic_header2[16];
-       u8 ctr_preload[16];
-
-       /* Intermediate Buffers */
-       u8 chain_buffer[16];
-       u8 aes_out[16];
-       u8 padded_buffer[16];
-       u8 mic[8];
-
-/*     uint    offset = 0; */
-       uint    frtype  = GetFrameType(pframe);
-       uint    frsubtype  = GetFrameSubType(pframe);
-
-       frsubtype = frsubtype >> 4;
-
-       memset((void *)mic_iv, 0, 16);
-       memset((void *)mic_header1, 0, 16);
-       memset((void *)mic_header2, 0, 16);
-       memset((void *)ctr_preload, 0, 16);
-       memset((void *)chain_buffer, 0, 16);
-       memset((void *)aes_out, 0, 16);
-       memset((void *)padded_buffer, 0, 16);
-
-       /* start to decrypt the payload */
-
-       num_blocks = (plen - 8) / 16; /* plen including llc, payload_length and mic) */
-
-       payload_remainder = (plen - 8) % 16;
-
-       pn_vector[0]  = pframe[hdrlen];
-       pn_vector[1]  = pframe[hdrlen + 1];
-       pn_vector[2]  = pframe[hdrlen + 4];
-       pn_vector[3]  = pframe[hdrlen + 5];
-       pn_vector[4]  = pframe[hdrlen + 6];
-       pn_vector[5]  = pframe[hdrlen + 7];
-
-       if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen ==  WLAN_HDR_A3_QOS_LEN))
-               a4_exists = 0;
-       else
-               a4_exists = 1;
-
-       if ((frtype == WIFI_DATA_CFACK) || (frtype == WIFI_DATA_CFPOLL) ||
-           (frtype == WIFI_DATA_CFACKPOLL)) {
-                       qc_exists = 1;
-                       if (hdrlen !=  WLAN_HDR_A3_QOS_LEN)
-                               hdrlen += 2;
-       } else if ((frsubtype == 0x08) || (frsubtype == 0x09) ||
-                  (frsubtype == 0x0a) || (frsubtype == 0x0b)) {
-               if (hdrlen !=  WLAN_HDR_A3_QOS_LEN)
-                       hdrlen += 2;
-               qc_exists = 1;
-       } else {
-               qc_exists = 0;
-       }
-
-       /*  now, decrypt pframe with hdrlen offset and plen long */
-
-       payload_index = hdrlen + 8; /*  8 is for extiv */
-
-       for (i = 0; i < num_blocks; i++) {
-               construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, i + 1);
-
-               aes128k128d(key, ctr_preload, aes_out);
-               bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
-
-               for (j = 0; j < 16; j++)
-                        pframe[payload_index++] = chain_buffer[j];
-       }
-
-       if (payload_remainder > 0) {    /* If there is a short final block, then pad it,*/
-                                       /* encrypt it and copy the unpadded part back   */
-               construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, num_blocks + 1);
-
-               for (j = 0; j < 16; j++)
-                       padded_buffer[j] = 0x00;
-               for (j = 0; j < payload_remainder; j++)
-                       padded_buffer[j] = pframe[payload_index + j];
-               aes128k128d(key, ctr_preload, aes_out);
-               bitwise_xor(aes_out, padded_buffer, chain_buffer);
-               for (j = 0; j < payload_remainder; j++)
-                       pframe[payload_index++] = chain_buffer[j];
-       }
-
-       /* start to calculate the mic */
-       if ((hdrlen + plen + 8) <= MAX_MSG_SIZE)
-               memcpy(message, pframe, (hdrlen + plen + 8)); /* 8 is for ext iv len */
-
-       pn_vector[0] = pframe[hdrlen];
-       pn_vector[1] = pframe[hdrlen + 1];
-       pn_vector[2] = pframe[hdrlen + 4];
-       pn_vector[3] = pframe[hdrlen + 5];
-       pn_vector[4] = pframe[hdrlen + 6];
-       pn_vector[5] = pframe[hdrlen + 7];
-       construct_mic_iv(mic_iv, qc_exists, a4_exists, message, plen - 8, pn_vector);
-
-       construct_mic_header1(mic_header1, hdrlen, message);
-       construct_mic_header2(mic_header2, message, a4_exists, qc_exists);
-
-       payload_remainder = (plen - 8) % 16;
-       num_blocks = (plen - 8) / 16;
-
-       /* Find start of payload */
-       payload_index = (hdrlen + 8);
-
-       /* Calculate MIC */
-       aes128k128d(key, mic_iv, aes_out);
-       bitwise_xor(aes_out, mic_header1, chain_buffer);
-       aes128k128d(key, chain_buffer, aes_out);
-       bitwise_xor(aes_out, mic_header2, chain_buffer);
-       aes128k128d(key, chain_buffer, aes_out);
-
-       for (i = 0; i < num_blocks; i++) {
-               bitwise_xor(aes_out, &message[payload_index], chain_buffer);
-
-               payload_index += 16;
-               aes128k128d(key, chain_buffer, aes_out);
-       }
-
-       /* Add on the final payload block if it needs padding */
-       if (payload_remainder > 0) {
-               for (j = 0; j < 16; j++)
-                       padded_buffer[j] = 0x00;
-               for (j = 0; j < payload_remainder; j++)
-                       padded_buffer[j] = message[payload_index++];
-               bitwise_xor(aes_out, padded_buffer, chain_buffer);
-               aes128k128d(key, chain_buffer, aes_out);
-       }
-
-       for (j = 0 ; j < 8; j++)
-               mic[j] = aes_out[j];
-
-       /* Insert MIC into payload */
-       for (j = 0; j < 8; j++)
-               message[payload_index + j] = mic[j];
-
-       payload_index = hdrlen + 8;
-       for (i = 0; i < num_blocks; i++) {
-               construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, i + 1);
-               aes128k128d(key, ctr_preload, aes_out);
-               bitwise_xor(aes_out, &message[payload_index], chain_buffer);
-               for (j = 0; j < 16; j++)
-                       message[payload_index++] = chain_buffer[j];
-       }
-
-       if (payload_remainder > 0) { /* If there is a short final block, then pad it,*/
-               /* encrypt it and copy the unpadded part back   */
-               construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, num_blocks + 1);
-
-               for (j = 0; j < 16; j++)
-                       padded_buffer[j] = 0x00;
-               for (j = 0; j < payload_remainder; j++)
-                       padded_buffer[j] = message[payload_index + j];
-               aes128k128d(key, ctr_preload, aes_out);
-               bitwise_xor(aes_out, padded_buffer, chain_buffer);
-               for (j = 0; j < payload_remainder; j++)
-                       message[payload_index++] = chain_buffer[j];
-       }
-
-       /* Encrypt the MIC */
-       construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, 0);
-
-       for (j = 0; j < 16; j++)
-               padded_buffer[j] = 0x00;
-       for (j = 0; j < 8; j++)
-               padded_buffer[j] = message[j + hdrlen + 8 + plen - 8];
-
-       aes128k128d(key, ctr_preload, aes_out);
-       bitwise_xor(aes_out, padded_buffer, chain_buffer);
-       for (j = 0; j < 8; j++)
-               message[payload_index++] = chain_buffer[j];
-
-       /* compare the mic */
-       for (i = 0; i < 8; i++) {
-               if (pframe[hdrlen + 8 + plen - 8 + i] != message[hdrlen + 8 + plen - 8 + i])
-                       res = _FAIL;
-       }
-
-       return res;
-}
-
-u32 rtw_aes_decrypt(struct adapter *padapter, struct recv_frame *precvframe)
-{      /*  exclude ICV */
-       /* Intermediate Buffers */
-       int             length;
-       u8      *pframe, *prwskey;      /*  *payload,*iv */
-       struct  sta_info                *stainfo;
-       struct  rx_pkt_attrib    *prxattrib = &precvframe->attrib;
-       struct  security_priv   *psecuritypriv = &padapter->securitypriv;
-       u32     res = _SUCCESS;
-
-       pframe = precvframe->rx_data;
-
-       /* 4 start to encrypt each fragment */
-       if (prxattrib->encrypt == _AES_) {
-               stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
-               if (stainfo) {
-                       if (is_multicast_ether_addr(prxattrib->ra)) {
-                               /* in concurrent we should use sw descrypt in group key, so we remove this message */
-                               if (!psecuritypriv->binstallGrpkey) {
-                                       res = _FAIL;
-                                       goto exit;
-                               }
-                               prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
-                               if (psecuritypriv->dot118021XGrpKeyid != prxattrib->key_index) {
-                                       res = _FAIL;
-                                       goto exit;
-                               }
-                       } else {
-                               prwskey = &stainfo->dot118021x_UncstKey.skey[0];
-                       }
-                       length = precvframe->len - prxattrib->hdrlen - prxattrib->iv_len;
-                       res = aes_decipher(prwskey, prxattrib->hdrlen, pframe, length);
-               } else {
-                       res = _FAIL;
-               }
-       }
-
-exit:
-       return res;
-}
diff --git a/drivers/staging/r8188eu/core/rtw_sta_mgt.c b/drivers/staging/r8188eu/core/rtw_sta_mgt.c
deleted file mode 100644 (file)
index e1ae185..0000000
+++ /dev/null
@@ -1,490 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#define _RTW_STA_MGT_C_
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/sta_info.h"
-
-static void _rtw_init_stainfo(struct sta_info *psta)
-{
-
-       memset((u8 *)psta, 0, sizeof(struct sta_info));
-
-       spin_lock_init(&psta->lock);
-       INIT_LIST_HEAD(&psta->list);
-       INIT_LIST_HEAD(&psta->hash_list);
-       rtw_init_queue(&psta->sleep_q);
-       psta->sleepq_len = 0;
-
-       _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv);
-       _rtw_init_sta_recv_priv(&psta->sta_recvpriv);
-
-       INIT_LIST_HEAD(&psta->asoc_list);
-
-       INIT_LIST_HEAD(&psta->auth_list);
-
-       psta->expire_to = 0;
-
-       psta->flags = 0;
-
-       psta->capability = 0;
-
-       psta->bpairwise_key_installed = false;
-
-       psta->nonerp_set = 0;
-       psta->no_short_slot_time_set = 0;
-       psta->no_short_preamble_set = 0;
-       psta->no_ht_gf_set = 0;
-       psta->no_ht_set = 0;
-       psta->ht_20mhz_set = 0;
-
-       psta->under_exist_checking = 0;
-
-       psta->keep_alive_trycnt = 0;
-}
-
-int _rtw_init_sta_priv(struct sta_priv *pstapriv)
-{
-       struct sta_info *psta;
-       s32 i;
-
-       pstapriv->pallocated_stainfo_buf = vzalloc(sizeof(struct sta_info) * NUM_STA + 4);
-
-       if (!pstapriv->pallocated_stainfo_buf)
-               return -ENOMEM;
-
-       pstapriv->pstainfo_buf = pstapriv->pallocated_stainfo_buf + 4 -
-               ((size_t)(pstapriv->pallocated_stainfo_buf) & 3);
-
-       rtw_init_queue(&pstapriv->free_sta_queue);
-
-       spin_lock_init(&pstapriv->sta_hash_lock);
-
-       pstapriv->asoc_sta_count = 0;
-       rtw_init_queue(&pstapriv->sleep_q);
-       rtw_init_queue(&pstapriv->wakeup_q);
-
-       psta = (struct sta_info *)(pstapriv->pstainfo_buf);
-
-       for (i = 0; i < NUM_STA; i++) {
-               _rtw_init_stainfo(psta);
-
-               INIT_LIST_HEAD(&pstapriv->sta_hash[i]);
-
-               list_add_tail(&psta->list, get_list_head(&pstapriv->free_sta_queue));
-
-               psta++;
-       }
-
-       pstapriv->sta_dz_bitmap = 0;
-       pstapriv->tim_bitmap = 0;
-
-       INIT_LIST_HEAD(&pstapriv->asoc_list);
-       INIT_LIST_HEAD(&pstapriv->auth_list);
-       spin_lock_init(&pstapriv->asoc_list_lock);
-       spin_lock_init(&pstapriv->auth_list_lock);
-       pstapriv->asoc_list_cnt = 0;
-       pstapriv->auth_list_cnt = 0;
-
-       pstapriv->auth_to = 3; /*  3*2 = 6 sec */
-       pstapriv->assoc_to = 3;
-       pstapriv->expire_to = 3; /*  3*2 = 6 sec */
-       pstapriv->max_num_sta = NUM_STA;
-
-       return 0;
-}
-
-inline int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta)
-{
-       return (((u8 *)sta) - stapriv->pstainfo_buf) / sizeof(struct sta_info);
-}
-
-inline struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int offset)
-{
-       return (struct sta_info *)(stapriv->pstainfo_buf + offset * sizeof(struct sta_info));
-}
-
-void _rtw_free_sta_priv(struct sta_priv *pstapriv)
-{
-       struct list_head *phead, *plist;
-       struct sta_info *psta = NULL;
-       struct recv_reorder_ctrl *preorder_ctrl;
-       int     index;
-
-       if (pstapriv) {
-               /*      delete all reordering_ctrl_timer                */
-               spin_lock_bh(&pstapriv->sta_hash_lock);
-               for (index = 0; index < NUM_STA; index++) {
-                       phead = &pstapriv->sta_hash[index];
-                       plist = phead->next;
-
-                       while (phead != plist) {
-                               int i;
-                               psta = container_of(plist, struct sta_info, hash_list);
-                               plist = plist->next;
-
-                               for (i = 0; i < 16; i++) {
-                                       preorder_ctrl = &psta->recvreorder_ctrl[i];
-                                       _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);
-                               }
-                       }
-               }
-               spin_unlock_bh(&pstapriv->sta_hash_lock);
-               /*===============================*/
-
-               vfree(pstapriv->pallocated_stainfo_buf);
-       }
-}
-
-static void _rtw_reordering_ctrl_timeout_handler(struct timer_list *t)
-{
-       struct recv_reorder_ctrl *preorder_ctrl;
-
-       preorder_ctrl = from_timer(preorder_ctrl, t, reordering_ctrl_timer);
-       rtw_reordering_ctrl_timeout_handler(preorder_ctrl);
-}
-
-static void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl)
-{
-       timer_setup(&preorder_ctrl->reordering_ctrl_timer, _rtw_reordering_ctrl_timeout_handler, 0);
-}
-
-static void _addba_timer_hdl(struct timer_list *t)
-{
-       struct sta_info *psta = from_timer(psta, t, addba_retry_timer);
-
-       addba_timer_hdl(psta);
-}
-
-static void init_addba_retry_timer(struct adapter *padapter, struct sta_info *psta)
-{
-       timer_setup(&psta->addba_retry_timer, _addba_timer_hdl, 0);
-}
-
-struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
-{
-       s32     index;
-       struct list_head *phash_list;
-       struct sta_info *psta;
-       struct __queue *pfree_sta_queue;
-       struct recv_reorder_ctrl *preorder_ctrl;
-       int i = 0;
-       u16  wRxSeqInitialValue = 0xffff;
-
-       pfree_sta_queue = &pstapriv->free_sta_queue;
-
-       spin_lock_bh(&pfree_sta_queue->lock);
-
-       if (list_empty(&pfree_sta_queue->queue)) {
-               spin_unlock_bh(&pfree_sta_queue->lock);
-               psta = NULL;
-       } else {
-               psta = container_of((&pfree_sta_queue->queue)->next, struct sta_info, list);
-               list_del_init(&psta->list);
-               spin_unlock_bh(&pfree_sta_queue->lock);
-               _rtw_init_stainfo(psta);
-               memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
-               index = wifi_mac_hash(hwaddr);
-               if (index >= NUM_STA) {
-                       psta = NULL;
-                       goto exit;
-               }
-               phash_list = &pstapriv->sta_hash[index];
-
-               spin_lock_bh(&pstapriv->sta_hash_lock);
-
-               list_add_tail(&psta->hash_list, phash_list);
-
-               pstapriv->asoc_sta_count++;
-
-               spin_unlock_bh(&pstapriv->sta_hash_lock);
-
-/*  Commented by Albert 2009/08/13 */
-/*  For the SMC router, the sequence number of first packet of WPS handshake will be 0. */
-/*  In this case, this packet will be dropped by recv_decache function if we use the 0x00 as the default value for tid_rxseq variable. */
-/*  So, we initialize the tid_rxseq variable as the 0xffff. */
-
-               for (i = 0; i < 16; i++)
-                       memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i], &wRxSeqInitialValue, 2);
-
-               init_addba_retry_timer(pstapriv->padapter, psta);
-
-               /* for A-MPDU Rx reordering buffer control */
-               for (i = 0; i < 16; i++) {
-                       preorder_ctrl = &psta->recvreorder_ctrl[i];
-
-                       preorder_ctrl->padapter = pstapriv->padapter;
-
-                       preorder_ctrl->enable = false;
-
-                       preorder_ctrl->indicate_seq = 0xffff;
-                       preorder_ctrl->wend_b = 0xffff;
-                       preorder_ctrl->wsize_b = 64;/* 64; */
-
-                       rtw_init_queue(&preorder_ctrl->pending_recvframe_queue);
-
-                       rtw_init_recv_timer(preorder_ctrl);
-               }
-
-               /* init for DM */
-               psta->rssi_stat.UndecoratedSmoothedPWDB = (-1);
-               psta->rssi_stat.UndecoratedSmoothedCCK = (-1);
-
-               /* init for the sequence number of received management frame */
-               psta->RxMgmtFrameSeqNum = 0xffff;
-       }
-
-exit:
-
-       return psta;
-}
-
-/*  using pstapriv->sta_hash_lock to protect */
-void rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta)
-{
-       int i;
-       struct __queue *pfree_sta_queue;
-       struct recv_reorder_ctrl *preorder_ctrl;
-       struct  sta_xmit_priv   *pstaxmitpriv;
-       struct  xmit_priv       *pxmitpriv = &padapter->xmitpriv;
-       struct  sta_priv *pstapriv = &padapter->stapriv;
-
-       if (!psta)
-               return;
-
-       pfree_sta_queue = &pstapriv->free_sta_queue;
-
-       pstaxmitpriv = &psta->sta_xmitpriv;
-
-       spin_lock_bh(&pxmitpriv->lock);
-
-       rtw_free_xmitframe_list(pxmitpriv, get_list_head(&psta->sleep_q));
-       psta->sleepq_len = 0;
-
-       rtw_free_xmitframe_list(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);
-
-       list_del_init(&pstaxmitpriv->vo_q.tx_pending);
-
-       rtw_free_xmitframe_list(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);
-
-       list_del_init(&pstaxmitpriv->vi_q.tx_pending);
-
-       rtw_free_xmitframe_list(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);
-
-       list_del_init(&pstaxmitpriv->bk_q.tx_pending);
-
-       rtw_free_xmitframe_list(pxmitpriv, &pstaxmitpriv->be_q.sta_pending);
-
-       list_del_init(&pstaxmitpriv->be_q.tx_pending);
-
-       spin_unlock_bh(&pxmitpriv->lock);
-
-       list_del_init(&psta->hash_list);
-       pstapriv->asoc_sta_count--;
-
-       /*  re-init sta_info; 20061114 */
-       _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv);
-       _rtw_init_sta_recv_priv(&psta->sta_recvpriv);
-
-       _cancel_timer_ex(&psta->addba_retry_timer);
-
-       /* for A-MPDU Rx reordering buffer control, cancel reordering_ctrl_timer */
-       for (i = 0; i < 16 ; i++) {
-               struct list_head *phead, *plist;
-               struct recv_frame *prframe;
-               struct __queue *ppending_recvframe_queue;
-               struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
-
-               preorder_ctrl = &psta->recvreorder_ctrl[i];
-
-               _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);
-
-               ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
-
-               spin_lock_bh(&ppending_recvframe_queue->lock);
-
-               phead =         get_list_head(ppending_recvframe_queue);
-               plist = phead->next;
-
-               while (!list_empty(phead)) {
-                       prframe = container_of(plist, struct recv_frame, list);
-
-                       plist = plist->next;
-
-                       list_del_init(&prframe->list);
-
-                       rtw_free_recvframe(prframe, pfree_recv_queue);
-               }
-
-               spin_unlock_bh(&ppending_recvframe_queue->lock);
-       }
-
-       if (!(psta->state & WIFI_AP_STATE))
-               rtl8188e_SetHalODMVar(padapter, psta, false);
-
-       spin_lock_bh(&pstapriv->auth_list_lock);
-       if (!list_empty(&psta->auth_list)) {
-               list_del_init(&psta->auth_list);
-               pstapriv->auth_list_cnt--;
-       }
-       spin_unlock_bh(&pstapriv->auth_list_lock);
-
-       psta->expire_to = 0;
-
-       psta->sleepq_ac_len = 0;
-       psta->qos_info = 0;
-
-       psta->max_sp_len = 0;
-       psta->uapsd_bk = 0;
-       psta->uapsd_be = 0;
-       psta->uapsd_vi = 0;
-       psta->uapsd_vo = 0;
-       psta->has_legacy_ac = 0;
-
-       pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
-       pstapriv->tim_bitmap &= ~BIT(psta->aid);
-
-       if ((psta->aid > 0) && (pstapriv->sta_aid[psta->aid - 1] == psta)) {
-               pstapriv->sta_aid[psta->aid - 1] = NULL;
-               psta->aid = 0;
-       }
-
-       psta->under_exist_checking = 0;
-
-       spin_lock_bh(&pfree_sta_queue->lock);
-       list_add_tail(&psta->list, get_list_head(pfree_sta_queue));
-       spin_unlock_bh(&pfree_sta_queue->lock);
-}
-
-/*  free all stainfo which in sta_hash[all] */
-void rtw_free_all_stainfo(struct adapter *padapter)
-{
-       struct list_head *plist, *phead;
-       s32     index;
-       struct sta_info *psta = NULL;
-       struct  sta_priv *pstapriv = &padapter->stapriv;
-       struct sta_info *pbcmc_stainfo = rtw_get_bcmc_stainfo(padapter);
-
-       if (pstapriv->asoc_sta_count == 1)
-               return;
-
-       spin_lock_bh(&pstapriv->sta_hash_lock);
-
-       for (index = 0; index < NUM_STA; index++) {
-               phead = &pstapriv->sta_hash[index];
-               plist = phead->next;
-
-               while (phead != plist) {
-                       psta = container_of(plist, struct sta_info, hash_list);
-
-                       plist = plist->next;
-
-                       if (pbcmc_stainfo != psta)
-                               rtw_free_stainfo(padapter, psta);
-               }
-       }
-       spin_unlock_bh(&pstapriv->sta_hash_lock);
-}
-
-/* any station allocated can be searched by hash list */
-struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
-{
-       struct sta_info *ploop, *psta = NULL;
-       u32     index;
-       u8 *addr;
-       u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
-       if (!hwaddr)
-               return NULL;
-
-       if (is_multicast_ether_addr(hwaddr))
-               addr = bc_addr;
-       else
-               addr = hwaddr;
-
-       index = wifi_mac_hash(addr);
-
-       spin_lock_bh(&pstapriv->sta_hash_lock);
-
-       list_for_each_entry(ploop, &pstapriv->sta_hash[index], hash_list) {
-               if (!memcmp(ploop->hwaddr, addr, ETH_ALEN)) {
-                       psta = ploop;
-                       break;
-               }
-       }
-
-       spin_unlock_bh(&pstapriv->sta_hash_lock);
-
-       return psta;
-}
-
-u32 rtw_init_bcmc_stainfo(struct adapter *padapter)
-{
-       struct sta_info         *psta;
-       u32 res = _SUCCESS;
-       unsigned char bcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-       struct  sta_priv *pstapriv = &padapter->stapriv;
-
-       psta = rtw_alloc_stainfo(pstapriv, bcast_addr);
-
-       if (!psta) {
-               res = _FAIL;
-               goto exit;
-       }
-
-       /*  default broadcast & multicast use macid 1 */
-       psta->mac_id = 1;
-
-exit:
-
-       return res;
-}
-
-struct sta_info *rtw_get_bcmc_stainfo(struct adapter *padapter)
-{
-       struct sta_info         *psta;
-       struct sta_priv         *pstapriv = &padapter->stapriv;
-       u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
-       psta = rtw_get_stainfo(pstapriv, bc_addr);
-
-       return psta;
-}
-
-u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr)
-{
-       u8 res = true;
-       struct list_head *plist, *phead;
-       struct rtw_wlan_acl_node *paclnode;
-       u8 match = false;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
-       struct __queue *pacl_node_q = &pacl_list->acl_node_q;
-
-       spin_lock_bh(&pacl_node_q->lock);
-       phead = get_list_head(pacl_node_q);
-       plist = phead->next;
-       while (phead != plist) {
-               paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
-               plist = plist->next;
-
-               if (!memcmp(paclnode->addr, mac_addr, ETH_ALEN)) {
-                       if (paclnode->valid) {
-                               match = true;
-                               break;
-                       }
-               }
-       }
-       spin_unlock_bh(&pacl_node_q->lock);
-
-       if (pacl_list->mode == 1)/* accept unless in deny list */
-               res = !match;
-       else if (pacl_list->mode == 2)/* deny unless in accept list */
-               res = match;
-       else
-               res = true;
-
-       return res;
-}
diff --git a/drivers/staging/r8188eu/core/rtw_wlan_util.c b/drivers/staging/r8188eu/core/rtw_wlan_util.c
deleted file mode 100644 (file)
index f1ebb53..0000000
+++ /dev/null
@@ -1,1551 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-#define _RTW_WLAN_UTIL_C_
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/wifi.h"
-
-static unsigned char ARTHEROS_OUI1[] = {0x00, 0x03, 0x7f};
-static unsigned char ARTHEROS_OUI2[] = {0x00, 0x13, 0x74};
-
-static unsigned char BROADCOM_OUI1[] = {0x00, 0x10, 0x18};
-static unsigned char BROADCOM_OUI2[] = {0x00, 0x0a, 0xf7};
-
-static unsigned char CISCO_OUI[] = {0x00, 0x40, 0x96};
-static unsigned char MARVELL_OUI[] = {0x00, 0x50, 0x43};
-static unsigned char RALINK_OUI[] = {0x00, 0x0c, 0x43};
-static unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
-static unsigned char AIRGOCAP_OUI[] = {0x00, 0x0a, 0xf5};
-static unsigned char EPIGRAM_OUI[] = {0x00, 0x90, 0x4c};
-
-unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
-
-#define R2T_PHY_DELAY  (0)
-
-/* define WAIT_FOR_BCN_TO_M    (3000) */
-#define WAIT_FOR_BCN_TO_MIN    (6000)
-#define WAIT_FOR_BCN_TO_MAX    (20000)
-
-static u8 rtw_basic_rate_cck[4] = {
-       IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK,
-       IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK
-};
-
-static u8 rtw_basic_rate_ofdm[3] = {
-       IEEE80211_OFDM_RATE_6MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_OFDM_RATE_12MB | IEEE80211_BASIC_RATE_MASK,
-       IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK
-};
-
-static u8 rtw_basic_rate_mix[7] = {
-       IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK,
-       IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK,
-       IEEE80211_OFDM_RATE_6MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_OFDM_RATE_12MB | IEEE80211_BASIC_RATE_MASK,
-       IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK
-};
-
-bool cckrates_included(unsigned char *rate, int ratelen)
-{
-       int     i;
-
-       for (i = 0; i < ratelen; i++) {
-               if  ((((rate[i]) & 0x7f) == 2)  || (((rate[i]) & 0x7f) == 4) ||
-                    (((rate[i]) & 0x7f) == 11)  || (((rate[i]) & 0x7f) == 22))
-                       return true;
-       }
-       return false;
-}
-
-bool cckratesonly_included(unsigned char *rate, int ratelen)
-{
-       int     i;
-
-       for (i = 0; i < ratelen; i++) {
-               if ((((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&
-                   (((rate[i]) & 0x7f) != 11)  && (((rate[i]) & 0x7f) != 22))
-                       return false;
-       }
-
-       return true;
-}
-
-unsigned char networktype_to_raid(unsigned char network_type)
-{
-       unsigned char raid;
-
-       switch (network_type) {
-       case WIRELESS_11B:
-               raid = RATR_INX_WIRELESS_B;
-               break;
-       case WIRELESS_11G:
-               raid = RATR_INX_WIRELESS_G;
-               break;
-       case WIRELESS_11BG:
-               raid = RATR_INX_WIRELESS_GB;
-               break;
-       case WIRELESS_11_24N:
-               raid = RATR_INX_WIRELESS_N;
-               break;
-       case WIRELESS_11G_24N:
-               raid = RATR_INX_WIRELESS_NG;
-               break;
-       case WIRELESS_11BG_24N:
-               raid = RATR_INX_WIRELESS_NGB;
-               break;
-       default:
-               raid = RATR_INX_WIRELESS_GB;
-               break;
-       }
-       return raid;
-}
-
-u8 judge_network_type(struct adapter *padapter, unsigned char *rate, int ratelen)
-{
-       u8 network_type = 0;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       if (pmlmeext->cur_channel > 14) {
-               network_type |= WIRELESS_INVALID;
-       } else {
-               if (pmlmeinfo->HT_enable)
-                       network_type = WIRELESS_11_24N;
-
-               if (cckratesonly_included(rate, ratelen))
-                       network_type |= WIRELESS_11B;
-               else if (cckrates_included(rate, ratelen))
-                       network_type |= WIRELESS_11BG;
-               else
-                       network_type |= WIRELESS_11G;
-       }
-       return  network_type;
-}
-
-static unsigned char ratetbl_val_2wifirate(unsigned char rate)
-{
-       unsigned char val = 0;
-
-       switch (rate & 0x7f) {
-       case 0:
-               val = IEEE80211_CCK_RATE_1MB;
-               break;
-       case 1:
-               val = IEEE80211_CCK_RATE_2MB;
-               break;
-       case 2:
-               val = IEEE80211_CCK_RATE_5MB;
-               break;
-       case 3:
-               val = IEEE80211_CCK_RATE_11MB;
-               break;
-       case 4:
-               val = IEEE80211_OFDM_RATE_6MB;
-               break;
-       case 5:
-               val = IEEE80211_OFDM_RATE_9MB;
-               break;
-       case 6:
-               val = IEEE80211_OFDM_RATE_12MB;
-               break;
-       case 7:
-               val = IEEE80211_OFDM_RATE_18MB;
-               break;
-       case 8:
-               val = IEEE80211_OFDM_RATE_24MB;
-               break;
-       case 9:
-               val = IEEE80211_OFDM_RATE_36MB;
-               break;
-       case 10:
-               val = IEEE80211_OFDM_RATE_48MB;
-               break;
-       case 11:
-               val = IEEE80211_OFDM_RATE_54MB;
-               break;
-       }
-       return val;
-}
-
-static bool is_basicrate(struct adapter *padapter, unsigned char rate)
-{
-       int i;
-       unsigned char val;
-       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
-       for (i = 0; i < NumRates; i++) {
-               val = pmlmeext->basicrate[i];
-
-               if ((val != 0xff) && (val != 0xfe)) {
-                       if (rate == ratetbl_val_2wifirate(val))
-                               return true;
-               }
-       }
-       return false;
-}
-
-static unsigned int ratetbl2rateset(struct adapter *padapter, unsigned char *rateset)
-{
-       int i;
-       unsigned char rate;
-       unsigned int    len = 0;
-       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
-       for (i = 0; i < NumRates; i++) {
-               rate = pmlmeext->datarate[i];
-
-               switch (rate) {
-               case 0xff:
-                       return len;
-               case 0xfe:
-                       continue;
-               default:
-                       rate = ratetbl_val_2wifirate(rate);
-
-                       if (is_basicrate(padapter, rate))
-                               rate |= IEEE80211_BASIC_RATE_MASK;
-
-                       rateset[len] = rate;
-                       len++;
-                       break;
-               }
-       }
-       return len;
-}
-
-void get_rate_set(struct adapter *padapter, unsigned char *pbssrate, int *bssrate_len)
-{
-       unsigned char supportedrates[NumRates];
-
-       memset(supportedrates, 0, NumRates);
-       *bssrate_len = ratetbl2rateset(padapter, supportedrates);
-       memcpy(pbssrate, supportedrates, *bssrate_len);
-}
-
-void Save_DM_Func_Flag(struct adapter *padapter)
-{
-       struct hal_data_8188e *haldata = &padapter->haldata;
-       struct odm_dm_struct *odmpriv = &haldata->odmpriv;
-
-       odmpriv->BK_SupportAbility = odmpriv->SupportAbility;
-}
-
-void Restore_DM_Func_Flag(struct adapter *padapter)
-{
-       struct hal_data_8188e *haldata = &padapter->haldata;
-       struct odm_dm_struct *odmpriv = &haldata->odmpriv;
-
-       odmpriv->SupportAbility = odmpriv->BK_SupportAbility;
-}
-
-void Set_MSR(struct adapter *padapter, u8 type)
-{
-       u8 val8;
-       int res;
-
-       res = rtw_read8(padapter, MSR, &val8);
-       if (res)
-               return;
-
-       val8 &= 0x0c;
-       val8 |= type;
-       rtw_write8(padapter, MSR, val8);
-}
-
-inline u8 rtw_get_oper_ch(struct adapter *adapter)
-{
-       return adapter->mlmeextpriv.oper_channel;
-}
-
-inline void rtw_set_oper_ch(struct adapter *adapter, u8 ch)
-{
-       adapter->mlmeextpriv.oper_channel = ch;
-}
-
-inline void rtw_set_oper_bw(struct adapter *adapter, u8 bw)
-{
-       adapter->mlmeextpriv.oper_bwmode = bw;
-}
-
-inline void rtw_set_oper_choffset(struct adapter *adapter, u8 offset)
-{
-       adapter->mlmeextpriv.oper_ch_offset = offset;
-}
-
-void SelectChannel(struct adapter *padapter, unsigned char channel)
-{
-       /* saved channel info */
-       rtw_set_oper_ch(padapter, channel);
-       PHY_SwChnl8188E(padapter, channel);
-}
-
-void SetBWMode(struct adapter *padapter, unsigned short bwmode,
-              unsigned char channel_offset)
-{
-       /* saved bw info */
-       rtw_set_oper_bw(padapter, bwmode);
-       rtw_set_oper_choffset(padapter, channel_offset);
-
-       PHY_SetBWMode8188E(padapter, (enum ht_channel_width)bwmode, channel_offset);
-}
-
-void set_channel_bwmode(struct adapter *padapter, unsigned char channel, unsigned char channel_offset, unsigned short bwmode)
-{
-       u8 center_ch;
-
-       if ((bwmode == HT_CHANNEL_WIDTH_20) ||
-           (channel_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)) {
-               /* SelectChannel(padapter, channel); */
-               center_ch = channel;
-       } else {
-               /* switch to the proper channel */
-               if (channel_offset == HAL_PRIME_CHNL_OFFSET_LOWER) {
-                       /* SelectChannel(padapter, channel + 2); */
-                       center_ch = channel + 2;
-               } else {
-                       /* SelectChannel(padapter, channel - 2); */
-                       center_ch = channel - 2;
-               }
-       }
-
-       /* set Channel */
-       /* saved channel/bw info */
-       rtw_set_oper_ch(padapter, channel);
-       rtw_set_oper_bw(padapter, bwmode);
-       rtw_set_oper_choffset(padapter, channel_offset);
-
-       PHY_SwChnl8188E(padapter, center_ch); /*  set center channel */
-       SetBWMode(padapter, bwmode, channel_offset);
-}
-
-__inline u8 *get_my_bssid(struct wlan_bssid_ex *pnetwork)
-{
-       return pnetwork->MacAddress;
-}
-
-u16 get_beacon_interval(struct wlan_bssid_ex *bss)
-{
-       __le16 val;
-       memcpy((unsigned char *)&val, rtw_get_beacon_interval_from_ie(bss->IEs), 2);
-
-       return le16_to_cpu(val);
-}
-
-bool r8188eu_is_client_associated_to_ap(struct adapter *padapter)
-{
-       struct mlme_ext_priv    *pmlmeext;
-       struct mlme_ext_info    *pmlmeinfo;
-
-       if (!padapter)
-               return false;
-
-       pmlmeext = &padapter->mlmeextpriv;
-       pmlmeinfo = &pmlmeext->mlmext_info;
-
-       if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE))
-               return true;
-
-       return false;
-}
-
-bool r8188eu_is_client_associated_to_ibss(struct adapter *padapter)
-{
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE))
-               return true;
-
-       return false;
-}
-
-bool r8188eu_is_ibss_empty(struct adapter *padapter)
-{
-       unsigned int i;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) {
-               if (pmlmeinfo->FW_sta_info[i].status == 1)
-                       return false;
-       }
-       return true;
-}
-
-unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval)
-{
-       if ((bcn_interval << 2) < WAIT_FOR_BCN_TO_MIN)
-               return WAIT_FOR_BCN_TO_MIN;
-       else if ((bcn_interval << 2) > WAIT_FOR_BCN_TO_MAX)
-               return WAIT_FOR_BCN_TO_MAX;
-       else
-               return bcn_interval << 2;
-}
-
-void invalidate_cam_all(struct adapter *padapter)
-{
-       rtw_write32(padapter, RWCAM, BIT(31) | BIT(30));
-}
-
-void write_cam(struct adapter *padapter, u8 entry, u16 ctrl, u8 *mac, u8 *key)
-{
-       unsigned int    i, val, addr;
-       int j;
-       u32     cam_val[2];
-
-       addr = entry << 3;
-
-       for (j = 5; j >= 0; j--) {
-               switch (j) {
-               case 0:
-                       val = (ctrl | (mac[0] << 16) | (mac[1] << 24));
-                       break;
-               case 1:
-                       val = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
-                       break;
-               default:
-                       i = (j - 2) << 2;
-                       val = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
-                       break;
-               }
-
-               cam_val[0] = val;
-               cam_val[1] = addr + (unsigned int)j;
-
-               rtw_write32(padapter, WCAMI, cam_val[0]);
-               rtw_write32(padapter, RWCAM, CAM_POLLINIG | CAM_WRITE | cam_val[1]);
-       }
-}
-
-void clear_cam_entry(struct adapter *padapter, u8 entry)
-{
-       unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-       unsigned char null_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
-       write_cam(padapter, entry, 0, null_sta, null_key);
-}
-
-int allocate_fw_sta_entry(struct adapter *padapter)
-{
-       unsigned int mac_id;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       for (mac_id = IBSS_START_MAC_ID; mac_id < NUM_STA; mac_id++) {
-               if (pmlmeinfo->FW_sta_info[mac_id].status == 0) {
-                       pmlmeinfo->FW_sta_info[mac_id].status = 1;
-                       pmlmeinfo->FW_sta_info[mac_id].retry = 0;
-                       break;
-               }
-       }
-
-       return mac_id;
-}
-
-void flush_all_cam_entry(struct adapter *padapter)
-{
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       rtw_write32(padapter, RWCAM, BIT(31) | BIT(30));
-
-       memset((u8 *)(pmlmeinfo->FW_sta_info), 0, sizeof(pmlmeinfo->FW_sta_info));
-}
-
-int WMM_param_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
-{
-       /* struct registry_priv *pregpriv = &padapter->registrypriv; */
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       if (pmlmepriv->qospriv.qos_option == 0) {
-               pmlmeinfo->WMM_enable = 0;
-               return _FAIL;
-       }
-
-       pmlmeinfo->WMM_enable = 1;
-       memcpy(&pmlmeinfo->WMM_param, pIE->data + 6, sizeof(struct WMM_para_element));
-       return true;
-}
-
-static void set_acm_ctrl(struct adapter *adapter, u8 acm_mask)
-{
-       u8 acmctrl;
-       int res = rtw_read8(adapter, REG_ACMHWCTRL, &acmctrl);
-
-       if (res)
-               return;
-
-       if (acm_mask > 1)
-               acmctrl = acmctrl | 0x1;
-
-       if (acm_mask & BIT(3))
-               acmctrl |= ACMHW_VOQEN;
-       else
-               acmctrl &= (~ACMHW_VOQEN);
-
-       if (acm_mask & BIT(2))
-               acmctrl |= ACMHW_VIQEN;
-       else
-               acmctrl &= (~ACMHW_VIQEN);
-
-       if (acm_mask & BIT(1))
-               acmctrl |= ACMHW_BEQEN;
-       else
-               acmctrl &= (~ACMHW_BEQEN);
-
-       rtw_write8(adapter, REG_ACMHWCTRL, acmctrl);
-}
-
-void WMMOnAssocRsp(struct adapter *padapter)
-{
-       u8      ACI, ACM, AIFS, ECWMin, ECWMax, aSifsTime;
-       u8      acm_mask;
-       u16     TXOP;
-       u32     acParm, i;
-       u32     edca[4], inx[4];
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct xmit_priv                *pxmitpriv = &padapter->xmitpriv;
-       struct registry_priv    *pregpriv = &padapter->registrypriv;
-       struct hal_data_8188e *haldata = &padapter->haldata;
-
-       if (pmlmeinfo->WMM_enable == 0) {
-               padapter->mlmepriv.acm_mask = 0;
-               return;
-       }
-
-       acm_mask = 0;
-
-       if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
-               aSifsTime = 10;
-       else
-               aSifsTime = 16;
-
-       for (i = 0; i < 4; i++) {
-               ACI = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 5) & 0x03;
-               ACM = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 4) & 0x01;
-
-               /* AIFS = AIFSN * slot time + SIFS - r2t phy delay */
-               AIFS = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN & 0x0f) * pmlmeinfo->slotTime + aSifsTime;
-
-               ECWMin = (pmlmeinfo->WMM_param.ac_param[i].CW & 0x0f);
-               ECWMax = (pmlmeinfo->WMM_param.ac_param[i].CW & 0xf0) >> 4;
-               TXOP = le16_to_cpu(pmlmeinfo->WMM_param.ac_param[i].TXOP_limit);
-
-               acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
-
-               switch (ACI) {
-               case 0x0:
-                       haldata->AcParam_BE = acParm;
-                       rtw_write32(padapter, REG_EDCA_BE_PARAM, acParm);
-                       acm_mask |= (ACM ? BIT(1) : 0);
-                       edca[XMIT_BE_QUEUE] = acParm;
-                       break;
-               case 0x1:
-                       rtw_write32(padapter, REG_EDCA_BK_PARAM, acParm);
-                       edca[XMIT_BK_QUEUE] = acParm;
-                       break;
-               case 0x2:
-                       rtw_write32(padapter, REG_EDCA_VI_PARAM, acParm);
-                       acm_mask |= (ACM ? BIT(2) : 0);
-                       edca[XMIT_VI_QUEUE] = acParm;
-                       break;
-               case 0x3:
-                       rtw_write32(padapter, REG_EDCA_VO_PARAM, acParm);
-                       acm_mask |= (ACM ? BIT(3) : 0);
-                       edca[XMIT_VO_QUEUE] = acParm;
-                       break;
-               }
-       }
-
-       if (padapter->registrypriv.acm_method == 1)
-               set_acm_ctrl(padapter, acm_mask);
-       else
-               padapter->mlmepriv.acm_mask = acm_mask;
-
-       inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3;
-
-       if (pregpriv->wifi_spec == 1) {
-               u32 j, change_inx = false;
-
-               /* entry indx: 0->vo, 1->vi, 2->be, 3->bk. */
-               for (i = 0; i < 4; i++) {
-                       for (j = i + 1; j < 4; j++) {
-                               /* compare CW and AIFS */
-                               if ((edca[j] & 0xFFFF) < (edca[i] & 0xFFFF)) {
-                                       change_inx = true;
-                               } else if ((edca[j] & 0xFFFF) == (edca[i] & 0xFFFF)) {
-                                       /* compare TXOP */
-                                       if ((edca[j] >> 16) > (edca[i] >> 16))
-                                               change_inx = true;
-                               }
-
-                               if (change_inx) {
-                                       swap(edca[i], edca[j]);
-                                       swap(inx[i], inx[j]);
-
-                                       change_inx = false;
-                               }
-                       }
-               }
-       }
-
-       for (i = 0; i < 4; i++)
-               pxmitpriv->wmm_para_seq[i] = inx[i];
-}
-
-static void bwmode_update_check(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
-{
-       unsigned char    new_bwmode;
-       unsigned char  new_ch_offset;
-       struct HT_info_element   *pHT_info;
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct registry_priv *pregistrypriv = &padapter->registrypriv;
-       struct ht_priv                  *phtpriv = &pmlmepriv->htpriv;
-
-       if (!pIE)
-               return;
-
-       if (!phtpriv)
-               return;
-
-       if (pIE->Length > sizeof(struct HT_info_element))
-               return;
-
-       pHT_info = (struct HT_info_element *)pIE->data;
-
-       if ((pHT_info->infos[0] & BIT(2)) && pregistrypriv->cbw40_enable) {
-               new_bwmode = HT_CHANNEL_WIDTH_40;
-
-               switch (pHT_info->infos[0] & 0x3) {
-               case 1:
-                       new_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
-                       break;
-               case 3:
-                       new_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
-                       break;
-               default:
-                       new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-                       break;
-               }
-       } else {
-               new_bwmode = HT_CHANNEL_WIDTH_20;
-               new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-       }
-
-       if ((new_bwmode != pmlmeext->cur_bwmode) ||
-           (new_ch_offset != pmlmeext->cur_ch_offset)) {
-               pmlmeinfo->bwmode_updated = true;
-
-               pmlmeext->cur_bwmode = new_bwmode;
-               pmlmeext->cur_ch_offset = new_ch_offset;
-
-               /* update HT info also */
-               HT_info_handler(padapter, pIE);
-       } else {
-               pmlmeinfo->bwmode_updated = false;
-       }
-
-       if (pmlmeinfo->bwmode_updated) {
-               struct sta_info *psta;
-               struct wlan_bssid_ex    *cur_network = &pmlmeinfo->network;
-               struct sta_priv *pstapriv = &padapter->stapriv;
-
-               /* set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
-
-               /* update ap's stainfo */
-               psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
-               if (psta) {
-                       struct ht_priv  *phtpriv_sta = &psta->htpriv;
-
-                       if (phtpriv_sta->ht_option) {
-                               /*  bwmode */
-                               phtpriv_sta->bwmode = pmlmeext->cur_bwmode;
-                               phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
-                       } else {
-                               phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20;
-                               phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-                       }
-               }
-       }
-}
-
-void HT_caps_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
-{
-       unsigned int    i;
-       u8      max_AMPDU_len, min_MPDU_spacing;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
-       struct ht_priv                  *phtpriv = &pmlmepriv->htpriv;
-
-       if (!pIE)
-               return;
-
-       if (!phtpriv->ht_option)
-               return;
-
-       pmlmeinfo->HT_caps_enable = 1;
-
-       for (i = 0; i < (pIE->Length); i++) {
-               if (i != 2) {
-                       /*      Got the endian issue here. */
-                       pmlmeinfo->HT_caps.u.HT_cap[i] &= (pIE->data[i]);
-               } else {
-                       /* modify from  fw by Thomas 2010/11/17 */
-                       max_AMPDU_len = min(pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3,
-                                           pIE->data[i] & 0x3);
-
-                       min_MPDU_spacing = max(pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c,
-                                              pIE->data[i] & 0x1c);
-
-                       pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para = max_AMPDU_len | min_MPDU_spacing;
-               }
-       }
-
-       /* update the MCS rates */
-       for (i = 0; i < 16; i++)
-               pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
-}
-
-void HT_info_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
-{
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
-       struct ht_priv                  *phtpriv = &pmlmepriv->htpriv;
-
-       if (!pIE)
-               return;
-
-       if (!phtpriv->ht_option)
-               return;
-
-       if (pIE->Length > sizeof(struct HT_info_element))
-               return;
-
-       pmlmeinfo->HT_info_enable = 1;
-       memcpy(&pmlmeinfo->HT_info, pIE->data, pIE->Length);
-}
-
-static void set_min_ampdu_spacing(struct adapter *adapter, u8 spacing)
-{
-       u8 sec_spacing;
-       int res;
-
-       if (spacing <= 7) {
-               switch (adapter->securitypriv.dot11PrivacyAlgrthm) {
-               case _NO_PRIVACY_:
-               case _AES_:
-                       sec_spacing = 0;
-                       break;
-               case _WEP40_:
-               case _WEP104_:
-               case _TKIP_:
-               case _TKIP_WTMIC_:
-                       sec_spacing = 6;
-                       break;
-               default:
-                       sec_spacing = 7;
-                       break;
-               }
-
-               if (spacing < sec_spacing)
-                       spacing = sec_spacing;
-
-               res = rtw_read8(adapter, REG_AMPDU_MIN_SPACE, &sec_spacing);
-               if (res)
-                       return;
-
-               rtw_write8(adapter, REG_AMPDU_MIN_SPACE,
-                          (sec_spacing & 0xf8) | spacing);
-       }
-}
-
-static void set_ampdu_factor(struct adapter *adapter, u8 factor)
-{
-       u8 RegToSet_Normal[4] = {0x41, 0xa8, 0x72, 0xb9};
-       u8 FactorToSet;
-       u8 *pRegToSet;
-       u8 index = 0;
-
-       pRegToSet = RegToSet_Normal; /*  0xb972a841; */
-       FactorToSet = factor;
-       if (FactorToSet <= 3) {
-               FactorToSet = (1 << (FactorToSet + 2));
-               if (FactorToSet > 0xf)
-                       FactorToSet = 0xf;
-
-               for (index = 0; index < 4; index++) {
-                       if ((pRegToSet[index] & 0xf0) > (FactorToSet << 4))
-                               pRegToSet[index] = (pRegToSet[index] & 0x0f) | (FactorToSet << 4);
-
-                       if ((pRegToSet[index] & 0x0f) > FactorToSet)
-                               pRegToSet[index] = (pRegToSet[index] & 0xf0) | (FactorToSet);
-
-                       rtw_write8(adapter, (REG_AGGLEN_LMT + index), pRegToSet[index]);
-               }
-       }
-}
-
-void HTOnAssocRsp(struct adapter *padapter)
-{
-       unsigned char           max_AMPDU_len;
-       unsigned char           min_MPDU_spacing;
-       /* struct registry_priv  *pregpriv = &padapter->registrypriv; */
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable)) {
-               pmlmeinfo->HT_enable = 1;
-       } else {
-               pmlmeinfo->HT_enable = 0;
-               return;
-       }
-
-       /* handle A-MPDU parameter field */
-       /*
-               AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
-               AMPDU_para [4:2]:Min MPDU Start Spacing
-       */
-       max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
-
-       min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;
-
-       set_min_ampdu_spacing(padapter, min_MPDU_spacing);
-
-       set_ampdu_factor(padapter, max_AMPDU_len);
-}
-
-void ERP_IE_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
-{
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       if (pIE->Length > 1)
-               return;
-
-       pmlmeinfo->ERP_enable = 1;
-       memcpy(&pmlmeinfo->ERP_IE, pIE->data, pIE->Length);
-}
-
-void VCS_update(struct adapter *padapter, struct sta_info *psta)
-{
-       struct registry_priv     *pregpriv = &padapter->registrypriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       switch (pregpriv->vrtl_carrier_sense) { /* 0:off 1:on 2:auto */
-       case 0: /* off */
-               psta->rtsen = 0;
-               psta->cts2self = 0;
-               break;
-       case 1: /* on */
-               if (pregpriv->vcs_type == 1) { /* 1:RTS/CTS 2:CTS to self */
-                       psta->rtsen = 1;
-                       psta->cts2self = 0;
-               } else {
-                       psta->rtsen = 0;
-                       psta->cts2self = 1;
-               }
-               break;
-       case 2: /* auto */
-       default:
-               if ((pmlmeinfo->ERP_enable) && (pmlmeinfo->ERP_IE & BIT(1))) {
-                       if (pregpriv->vcs_type == 1) {
-                               psta->rtsen = 1;
-                               psta->cts2self = 0;
-                       } else {
-                               psta->rtsen = 0;
-                               psta->cts2self = 1;
-                       }
-               } else {
-                       psta->rtsen = 0;
-                       psta->cts2self = 0;
-               }
-               break;
-       }
-}
-
-int rtw_check_bcn_info(struct adapter  *Adapter, u8 *pframe, u32 packet_len)
-{
-       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)pframe;
-       unsigned int            len;
-       unsigned char           *p;
-       unsigned short  val16;
-       struct wlan_network *cur_network = &Adapter->mlmepriv.cur_network;
-       /* u8 wpa_ie[255], rsn_ie[255]; */
-       u16 wpa_len = 0, rsn_len = 0;
-       u8 encryp_protocol = 0;
-       struct wlan_bssid_ex *bssid;
-       int group_cipher = 0, pairwise_cipher = 0, is_8021x = 0;
-       unsigned char *pbuf;
-       u32 wpa_ielen = 0;
-       u8 *pbssid = GetAddr3Ptr(pframe);
-       u32 hidden_ssid = 0;
-       struct HT_info_element *pht_info = NULL;
-       struct ieee80211_ht_cap *pht_cap = NULL;
-       u32 bcn_channel;
-       unsigned short  ht_cap_info;
-       unsigned char   ht_info_infos_0;
-
-       if (!r8188eu_is_client_associated_to_ap(Adapter))
-               return true;
-
-       len = packet_len - sizeof(struct ieee80211_hdr_3addr);
-
-       if (len > MAX_IE_SZ)
-               return _FAIL;
-
-       if (memcmp(cur_network->network.MacAddress, pbssid, 6))
-               return true;
-
-       bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
-       if (!bssid)
-               return _FAIL;
-
-       if (ieee80211_is_beacon(mgmt->frame_control))
-               bssid->Reserved[0] = 1;
-
-       bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len;
-
-       /* below is to copy the information element */
-       bssid->IELength = len;
-       memcpy(bssid->IEs, (pframe + sizeof(struct ieee80211_hdr_3addr)), bssid->IELength);
-
-       /* check bw and channel offset */
-       /* parsing HT_CAP_IE */
-       p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
-       if (p && len > 0) {
-               pht_cap = (struct ieee80211_ht_cap *)(p + 2);
-               ht_cap_info = le16_to_cpu(pht_cap->cap_info);
-       } else {
-               ht_cap_info = 0;
-       }
-       /* parsing HT_INFO_IE */
-       p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
-       if (p && len > 0) {
-                       pht_info = (struct HT_info_element *)(p + 2);
-                       ht_info_infos_0 = pht_info->infos[0];
-       } else {
-                       ht_info_infos_0 = 0;
-       }
-       if (ht_cap_info != cur_network->BcnInfo.ht_cap_info ||
-           ((ht_info_infos_0 & 0x03) != (cur_network->BcnInfo.ht_info_infos_0 & 0x03))) {
-                       /* bcn_info_update */
-                       cur_network->BcnInfo.ht_cap_info = ht_cap_info;
-                       cur_network->BcnInfo.ht_info_infos_0 = ht_info_infos_0;
-                       /* to do : need to check that whether modify related register of BB or not */
-                       /* goto _mismatch; */
-       }
-
-       /* Checking for channel */
-       p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _DSSET_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
-       if (p) {
-                       bcn_channel = *(p + 2);
-       } else {/* In 5G, some ap do not have DSSET IE checking HT info for channel */
-                       p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
-                       if (pht_info)
-                               bcn_channel = pht_info->primary_channel;
-                       else /* we don't find channel IE, so don't check it */
-                               bcn_channel = Adapter->mlmeextpriv.cur_channel;
-       }
-       if (bcn_channel != Adapter->mlmeextpriv.cur_channel)
-               goto _mismatch;
-
-       /* checking SSID */
-       p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _SSID_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
-       if (!p)
-               hidden_ssid = true;
-       else
-               hidden_ssid = false;
-
-       if (p && (!hidden_ssid && (*(p + 1)))) {
-               memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
-               bssid->Ssid.SsidLength = *(p + 1);
-       } else {
-               bssid->Ssid.SsidLength = 0;
-               bssid->Ssid.Ssid[0] = '\0';
-       }
-
-       if (memcmp(bssid->Ssid.Ssid, cur_network->network.Ssid.Ssid, 32) ||
-           bssid->Ssid.SsidLength != cur_network->network.Ssid.SsidLength) {
-               /* not hidden ssid */
-               if (bssid->Ssid.Ssid[0] != '\0' && bssid->Ssid.SsidLength != 0)
-                       goto _mismatch;
-       }
-
-       /* check encryption info */
-       val16 = rtw_get_capability((struct wlan_bssid_ex *)bssid);
-
-       if (val16 & BIT(4))
-               bssid->Privacy = 1;
-       else
-               bssid->Privacy = 0;
-
-       if (cur_network->network.Privacy != bssid->Privacy)
-               goto _mismatch;
-
-       rtw_get_sec_ie(bssid->IEs, bssid->IELength, NULL, &rsn_len, NULL, &wpa_len);
-
-       if (rsn_len > 0) {
-               encryp_protocol = ENCRYP_PROTOCOL_WPA2;
-       } else if (wpa_len > 0) {
-               encryp_protocol = ENCRYP_PROTOCOL_WPA;
-       } else {
-               if (bssid->Privacy)
-                       encryp_protocol = ENCRYP_PROTOCOL_WEP;
-       }
-
-       if (cur_network->BcnInfo.encryp_protocol != encryp_protocol)
-               goto _mismatch;
-
-       if (encryp_protocol == ENCRYP_PROTOCOL_WPA || encryp_protocol == ENCRYP_PROTOCOL_WPA2) {
-               pbuf = rtw_get_wpa_ie(&bssid->IEs[12], &wpa_ielen, bssid->IELength - 12);
-               if (pbuf && (wpa_ielen > 0)) {
-                       rtw_parse_wpa_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is_8021x);
-               } else {
-                       pbuf = rtw_get_wpa2_ie(&bssid->IEs[12], &wpa_ielen, bssid->IELength - 12);
-
-                       if (pbuf && (wpa_ielen > 0))
-                               rtw_parse_wpa2_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is_8021x);
-               }
-
-               if (pairwise_cipher != cur_network->BcnInfo.pairwise_cipher ||
-                   group_cipher != cur_network->BcnInfo.group_cipher)
-                       goto _mismatch;
-
-               if (is_8021x != cur_network->BcnInfo.is_8021x)
-                       goto _mismatch;
-       }
-
-       kfree(bssid);
-
-       return _SUCCESS;
-
-_mismatch:
-       kfree(bssid);
-
-       return _FAIL;
-}
-
-void update_beacon_info(struct adapter *padapter, u8 *ie_ptr, uint ie_len, struct sta_info *psta)
-{
-       unsigned int i;
-       struct ndis_802_11_var_ie *pIE;
-
-       for (i = 0; i < ie_len;) {
-               pIE = (struct ndis_802_11_var_ie *)(ie_ptr + i);
-
-               switch (pIE->ElementID) {
-               case _HT_EXTRA_INFO_IE_:        /* HT info */
-                       /* HT_info_handler(padapter, pIE); */
-                       bwmode_update_check(padapter, pIE);
-                       break;
-               case _ERPINFO_IE_:
-                       ERP_IE_handler(padapter, pIE);
-                       VCS_update(padapter, psta);
-                       break;
-               default:
-                       break;
-               }
-
-               i += (pIE->Length + 2);
-       }
-}
-
-bool is_ap_in_tkip(struct adapter *padapter)
-{
-       u32 i;
-       struct ndis_802_11_var_ie *pIE;
-       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex            *cur_network = &pmlmeinfo->network;
-
-       if (rtw_get_capability((struct wlan_bssid_ex *)cur_network) & WLAN_CAPABILITY_PRIVACY) {
-               for (i = sizeof(struct ndis_802_11_fixed_ie); i < pmlmeinfo->network.IELength;) {
-                       pIE = (struct ndis_802_11_var_ie *)(pmlmeinfo->network.IEs + i);
-
-                       switch (pIE->ElementID) {
-                       case _VENDOR_SPECIFIC_IE_:
-                               if ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) && (!memcmp((pIE->data + 12), WPA_TKIP_CIPHER, 4)))
-                                       return true;
-                               break;
-                       case _RSN_IE_2_:
-                               if (!memcmp((pIE->data + 8), RSN_TKIP_CIPHER, 4))
-                                       return true;
-                               break;
-                       default:
-                               break;
-                       }
-
-                       i += (pIE->Length + 2);
-               }
-               return false;
-       } else {
-               return false;
-       }
-}
-
-int wifirate2_ratetbl_inx(unsigned char rate)
-{
-       int     inx = 0;
-       rate = rate & 0x7f;
-
-       switch (rate) {
-       case 54 * 2:
-               inx = 11;
-               break;
-       case 48 * 2:
-               inx = 10;
-               break;
-       case 36 * 2:
-               inx = 9;
-               break;
-       case 24 * 2:
-               inx = 8;
-               break;
-       case 18 * 2:
-               inx = 7;
-               break;
-       case 12 * 2:
-               inx = 6;
-               break;
-       case 9 * 2:
-               inx = 5;
-               break;
-       case 6 * 2:
-               inx = 4;
-               break;
-       case 11 * 2:
-               inx = 3;
-               break;
-       case 11:
-               inx = 2;
-               break;
-       case 2 * 2:
-               inx = 1;
-               break;
-       case 1 * 2:
-               inx = 0;
-               break;
-       }
-       return inx;
-}
-
-unsigned int update_basic_rate(unsigned char *ptn, unsigned int ptn_sz)
-{
-       unsigned int i, num_of_rate;
-       unsigned int mask = 0;
-
-       num_of_rate = (ptn_sz > NumRates) ? NumRates : ptn_sz;
-
-       for (i = 0; i < num_of_rate; i++) {
-               if ((*(ptn + i)) & 0x80)
-                       mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i));
-       }
-       return mask;
-}
-
-unsigned int update_supported_rate(unsigned char *ptn, unsigned int ptn_sz)
-{
-       unsigned int i, num_of_rate;
-       unsigned int mask = 0;
-
-       num_of_rate = (ptn_sz > NumRates) ? NumRates : ptn_sz;
-
-       for (i = 0; i < num_of_rate; i++)
-               mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i));
-       return mask;
-}
-
-unsigned int update_MSC_rate(struct HT_caps_element *pHT_caps)
-{
-       unsigned int mask = 0;
-
-       mask = ((pHT_caps->u.HT_cap_element.MCS_rate[0] << 12) | (pHT_caps->u.HT_cap_element.MCS_rate[1] << 20));
-
-       return mask;
-}
-
-int support_short_GI(struct adapter *padapter, struct HT_caps_element *pHT_caps)
-{
-       unsigned char                                   bit_offset;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       if (!(pmlmeinfo->HT_enable))
-               return _FAIL;
-
-       if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_RALINK)
-               return _FAIL;
-
-       bit_offset = (pmlmeext->cur_bwmode & HT_CHANNEL_WIDTH_40) ? 6 : 5;
-
-       if (__le16_to_cpu(pHT_caps->u.HT_cap_element.HT_caps_info) & (0x1 << bit_offset))
-               return _SUCCESS;
-       else
-               return _FAIL;
-}
-
-unsigned char get_highest_rate_idx(u32 mask)
-{
-       int i;
-       unsigned char rate_idx = 0;
-
-       for (i = 27; i >= 0; i--) {
-               if (mask & BIT(i)) {
-                       rate_idx = i;
-                       break;
-               }
-       }
-       return rate_idx;
-}
-
-void Update_RA_Entry(struct adapter *padapter, u32 mac_id)
-{
-       rtw_hal_update_ra_mask(padapter, mac_id, 0);
-}
-
-static void enable_rate_adaptive(struct adapter *padapter, u32 mac_id)
-{
-       Update_RA_Entry(padapter, mac_id);
-}
-
-void set_sta_rate(struct adapter *padapter, struct sta_info *psta)
-{
-       /* rate adaptive */
-       enable_rate_adaptive(padapter, psta->mac_id);
-}
-
-void rtw_set_basic_rate(struct adapter *adapter, u8 *rates)
-{
-       u16 BrateCfg = 0;
-       u8 RateIndex = 0;
-       int res;
-       u8 reg;
-
-       /*  2007.01.16, by Emily */
-       /*  Select RRSR (in Legacy-OFDM and CCK) */
-       /*  For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate. */
-       /*  We do not use other rates. */
-       HalSetBrateCfg(adapter, rates, &BrateCfg);
-
-       /* 2011.03.30 add by Luke Lee */
-       /* CCK 2M ACK should be disabled for some BCM and Atheros AP IOT */
-       /* because CCK 2M has poor TXEVM */
-       /* CCK 5.5M & 11M ACK should be enabled for better performance */
-
-       BrateCfg = (BrateCfg | 0xd) & 0x15d;
-
-       BrateCfg |= 0x01; /*  default enable 1M ACK rate */
-       /*  Set RRSR rate table. */
-       rtw_write8(adapter, REG_RRSR, BrateCfg & 0xff);
-       rtw_write8(adapter, REG_RRSR + 1, (BrateCfg >> 8) & 0xff);
-       res = rtw_read8(adapter, REG_RRSR + 2, &reg);
-       if (res)
-               return;
-
-       rtw_write8(adapter, REG_RRSR + 2, reg & 0xf0);
-
-       /*  Set RTS initial rate */
-       while (BrateCfg > 0x1) {
-               BrateCfg = (BrateCfg >> 1);
-               RateIndex++;
-       }
-       /*  Ziv - Check */
-       rtw_write8(adapter, REG_INIRTS_RATE_SEL, RateIndex);
-}
-
-/*  Update RRSR and Rate for USERATE */
-void update_tx_basic_rate(struct adapter *padapter, u8 wirelessmode)
-{
-       unsigned char supported_rates[NDIS_802_11_LENGTH_RATES_EX];
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       /*      Added by Albert 2011/03/22 */
-       /*      In the P2P mode, the driver should not support the b mode. */
-       /*      So, the Tx packet shouldn't use the CCK rate */
-       if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
-               return;
-       memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX);
-
-       if ((wirelessmode & WIRELESS_11B) && (wirelessmode == WIRELESS_11B))
-               memcpy(supported_rates, rtw_basic_rate_cck, 4);
-       else if (wirelessmode & WIRELESS_11B)
-               memcpy(supported_rates, rtw_basic_rate_mix, 7);
-       else
-               memcpy(supported_rates, rtw_basic_rate_ofdm, 3);
-
-       if (wirelessmode & WIRELESS_11B)
-               update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB);
-       else
-               update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB);
-
-       rtw_set_basic_rate(padapter, supported_rates);
-}
-
-unsigned char check_assoc_AP(u8 *pframe, uint len)
-{
-       unsigned int i;
-       struct ndis_802_11_var_ie *pIE;
-       u8      epigram_vendor_flag;
-       u8      ralink_vendor_flag;
-       epigram_vendor_flag = 0;
-       ralink_vendor_flag = 0;
-
-       for (i = sizeof(struct ndis_802_11_fixed_ie); i < len;) {
-               pIE = (struct ndis_802_11_var_ie *)(pframe + i);
-
-               switch (pIE->ElementID) {
-               case _VENDOR_SPECIFIC_IE_:
-                       if ((!memcmp(pIE->data, ARTHEROS_OUI1, 3)) ||
-                           (!memcmp(pIE->data, ARTHEROS_OUI2, 3))) {
-                               return HT_IOT_PEER_ATHEROS;
-                       } else if ((!memcmp(pIE->data, BROADCOM_OUI1, 3)) ||
-                                  (!memcmp(pIE->data, BROADCOM_OUI2, 3))) {
-                               return HT_IOT_PEER_BROADCOM;
-                       } else if (!memcmp(pIE->data, MARVELL_OUI, 3)) {
-                               return HT_IOT_PEER_MARVELL;
-                       } else if (!memcmp(pIE->data, RALINK_OUI, 3)) {
-                               if (!ralink_vendor_flag) {
-                                       ralink_vendor_flag = 1;
-                               } else {
-                                       return HT_IOT_PEER_RALINK;
-                               }
-                       } else if (!memcmp(pIE->data, CISCO_OUI, 3)) {
-                               return HT_IOT_PEER_CISCO;
-                       } else if (!memcmp(pIE->data, REALTEK_OUI, 3)) {
-                               return HT_IOT_PEER_REALTEK;
-                       } else if (!memcmp(pIE->data, AIRGOCAP_OUI, 3)) {
-                               return HT_IOT_PEER_AIRGO;
-                       } else if (!memcmp(pIE->data, EPIGRAM_OUI, 3)) {
-                               epigram_vendor_flag = 1;
-                               if (ralink_vendor_flag)
-                                       return HT_IOT_PEER_TENDA;
-                       } else {
-                               break;
-                       }
-                       break;
-
-               default:
-                       break;
-               }
-               i += (pIE->Length + 2);
-       }
-
-       if (ralink_vendor_flag && !epigram_vendor_flag)
-               return HT_IOT_PEER_RALINK;
-       else if (ralink_vendor_flag && epigram_vendor_flag)
-               return HT_IOT_PEER_TENDA;
-       else
-               return HT_IOT_PEER_UNKNOWN;
-}
-
-void update_IOT_info(struct adapter *padapter)
-{
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       switch (pmlmeinfo->assoc_AP_vendor) {
-       case HT_IOT_PEER_MARVELL:
-               pmlmeinfo->turboMode_cts2self = 1;
-               pmlmeinfo->turboMode_rtsen = 0;
-               break;
-       case HT_IOT_PEER_RALINK:
-               pmlmeinfo->turboMode_cts2self = 0;
-               pmlmeinfo->turboMode_rtsen = 1;
-               break;
-       case HT_IOT_PEER_REALTEK:
-               /* rtw_write16(padapter, 0x4cc, 0xffff); */
-               /* rtw_write16(padapter, 0x546, 0x01c0); */
-               break;
-       default:
-               pmlmeinfo->turboMode_cts2self = 0;
-               pmlmeinfo->turboMode_rtsen = 1;
-               break;
-       }
-}
-
-static void set_ack_preamble(struct adapter *adapter, bool short_preamble)
-{
-       struct hal_data_8188e *haldata = &adapter->haldata;
-       u8 val8;
-
-       /*  Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) */
-       val8 = haldata->nCur40MhzPrimeSC << 5;
-       if (short_preamble)
-               val8 |= 0x80;
-
-       rtw_write8(adapter, REG_RRSR + 2, val8);
-};
-
-static void set_slot_time(struct adapter *adapter, u8 slot_time)
-{
-       u8 u1bAIFS, aSifsTime;
-       struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
-       struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       rtw_write8(adapter, REG_SLOT, slot_time);
-
-       if (pmlmeinfo->WMM_enable == 0) {
-               if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
-                       aSifsTime = 10;
-               else
-                       aSifsTime = 16;
-
-               u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
-
-               /*  <Roger_EXP> Temporary removed, 2008.06.20. */
-               rtw_write8(adapter, REG_EDCA_VO_PARAM, u1bAIFS);
-               rtw_write8(adapter, REG_EDCA_VI_PARAM, u1bAIFS);
-               rtw_write8(adapter, REG_EDCA_BE_PARAM, u1bAIFS);
-               rtw_write8(adapter, REG_EDCA_BK_PARAM, u1bAIFS);
-       }
-}
-
-void update_capinfo(struct adapter *Adapter, u16 updateCap)
-{
-       struct mlme_ext_priv    *pmlmeext = &Adapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       /*  Check preamble mode, 2005.01.06, by rcnjko. */
-       /*  Mark to update preamble value forever, 2008.03.18 by lanhsin */
-
-       if (updateCap & cShortPreamble) { /*  Short Preamble */
-               if (pmlmeinfo->preamble_mode != PREAMBLE_SHORT) { /*  PREAMBLE_LONG or PREAMBLE_AUTO */
-                       pmlmeinfo->preamble_mode = PREAMBLE_SHORT;
-                       set_ack_preamble(Adapter, true);
-               }
-       } else { /*  Long Preamble */
-               if (pmlmeinfo->preamble_mode != PREAMBLE_LONG) {  /*  PREAMBLE_SHORT or PREAMBLE_AUTO */
-                       pmlmeinfo->preamble_mode = PREAMBLE_LONG;
-                       set_ack_preamble(Adapter, false);
-               }
-       }
-
-       if (updateCap & cIBSS) {
-               /* Filen: See 802.11-2007 p.91 */
-               pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
-       } else { /* Filen: See 802.11-2007 p.90 */
-               if (pmlmeext->cur_wireless_mode & (WIRELESS_11G | WIRELESS_11_24N)) {
-                       if (updateCap & cShortSlotTime) { /*  Short Slot Time */
-                               if (pmlmeinfo->slotTime != SHORT_SLOT_TIME)
-                                       pmlmeinfo->slotTime = SHORT_SLOT_TIME;
-                       } else { /*  Long Slot Time */
-                               if (pmlmeinfo->slotTime != NON_SHORT_SLOT_TIME)
-                                       pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
-                       }
-               } else {
-                       /* B Mode */
-                       pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
-               }
-       }
-
-       set_slot_time(Adapter, pmlmeinfo->slotTime);
-}
-
-void update_wireless_mode(struct adapter *padapter)
-{
-       int ratelen, network_type = 0;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex    *cur_network = &pmlmeinfo->network;
-       unsigned char           *rate = cur_network->SupportedRates;
-
-       ratelen = rtw_get_rateset_len(cur_network->SupportedRates);
-
-       if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable))
-               pmlmeinfo->HT_enable = 1;
-
-       if (pmlmeext->cur_channel > 14) {
-               network_type |= WIRELESS_INVALID;
-       } else {
-               if (pmlmeinfo->HT_enable)
-                       network_type = WIRELESS_11_24N;
-
-               if (cckratesonly_included(rate, ratelen))
-                       network_type |= WIRELESS_11B;
-               else if (cckrates_included(rate, ratelen))
-                       network_type |= WIRELESS_11BG;
-               else
-                       network_type |= WIRELESS_11G;
-       }
-
-       pmlmeext->cur_wireless_mode = network_type & padapter->registrypriv.wireless_mode;
-
-       /* RESP_SIFS for CCK */
-       rtw_write8(padapter, REG_R2T_SIFS, 0x08);
-       rtw_write8(padapter, REG_R2T_SIFS + 1, 0x08);
-       /* RESP_SIFS for OFDM */
-       rtw_write8(padapter, REG_T2T_SIFS, 0x0a);
-       rtw_write8(padapter, REG_T2T_SIFS + 1, 0x0a);
-
-       if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
-               update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB);
-        else
-               update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB);
-}
-
-void update_bmc_sta_support_rate(struct adapter *padapter, u32 mac_id)
-{
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       if (pmlmeext->cur_wireless_mode & WIRELESS_11B) {
-               /*  Only B, B/G, and B/G/N AP could use CCK rate */
-               memcpy((pmlmeinfo->FW_sta_info[mac_id].SupportedRates), rtw_basic_rate_cck, 4);
-       } else {
-               memcpy((pmlmeinfo->FW_sta_info[mac_id].SupportedRates), rtw_basic_rate_ofdm, 3);
-       }
-}
-
-int update_sta_support_rate(struct adapter *padapter, u8 *pvar_ie, uint var_ie_len, int cam_idx)
-{
-       unsigned int    ie_len;
-       struct ndis_802_11_var_ie *pIE;
-       int     supportRateNum = 0;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       pIE = (struct ndis_802_11_var_ie *)rtw_get_ie(pvar_ie, _SUPPORTEDRATES_IE_, &ie_len, var_ie_len);
-       if (!pIE)
-               return _FAIL;
-
-       memcpy(pmlmeinfo->FW_sta_info[cam_idx].SupportedRates, pIE->data, ie_len);
-       supportRateNum = ie_len;
-
-       pIE = (struct ndis_802_11_var_ie *)rtw_get_ie(pvar_ie, _EXT_SUPPORTEDRATES_IE_, &ie_len, var_ie_len);
-       if (pIE)
-               memcpy((pmlmeinfo->FW_sta_info[cam_idx].SupportedRates + supportRateNum), pIE->data, ie_len);
-
-       return _SUCCESS;
-}
-
-void beacon_timing_control(struct adapter *padapter)
-{
-       SetBeaconRelatedRegisters8188EUsb(padapter);
-}
-
-static struct adapter *pbuddy_padapter;
-
-void rtw_handle_dualmac(struct adapter *adapter, bool init)
-{
-       if (init) {
-               if (!pbuddy_padapter) {
-                       pbuddy_padapter = adapter;
-               } else {
-                       adapter->pbuddy_adapter = pbuddy_padapter;
-                       pbuddy_padapter->pbuddy_adapter = adapter;
-                       /*  clear global value */
-                       pbuddy_padapter = NULL;
-               }
-       } else {
-               pbuddy_padapter = NULL;
-       }
-}
diff --git a/drivers/staging/r8188eu/core/rtw_xmit.c b/drivers/staging/r8188eu/core/rtw_xmit.c
deleted file mode 100644 (file)
index df88b3e..0000000
+++ /dev/null
@@ -1,2179 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-#define _RTW_XMIT_C_
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/wifi.h"
-#include "../include/osdep_intf.h"
-#include "../include/usb_ops.h"
-#include "../include/usb_osintf.h"
-#include "../include/rtl8188e_xmit.h"
-
-static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
-static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
-
-static void _init_txservq(struct tx_servq *ptxservq)
-{
-       INIT_LIST_HEAD(&ptxservq->tx_pending);
-       INIT_LIST_HEAD(&ptxservq->sta_pending);
-       ptxservq->qcnt = 0;
-}
-
-void   _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
-{
-       memset((unsigned char *)psta_xmitpriv, 0, sizeof(struct sta_xmit_priv));
-       spin_lock_init(&psta_xmitpriv->lock);
-       _init_txservq(&psta_xmitpriv->be_q);
-       _init_txservq(&psta_xmitpriv->bk_q);
-       _init_txservq(&psta_xmitpriv->vi_q);
-       _init_txservq(&psta_xmitpriv->vo_q);
-}
-
-static int rtw_xmit_resource_alloc(struct adapter *padapter, struct xmit_buf *pxmitbuf,
-                                  u32 alloc_sz)
-{
-       pxmitbuf->pallocated_buf = kzalloc(alloc_sz, GFP_KERNEL);
-       if (!pxmitbuf->pallocated_buf)
-               return -ENOMEM;
-
-       pxmitbuf->pbuf = (u8 *)ALIGN((size_t)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ);
-
-       pxmitbuf->pxmit_urb = usb_alloc_urb(0, GFP_KERNEL);
-       if (!pxmitbuf->pxmit_urb) {
-               kfree(pxmitbuf->pallocated_buf);
-               return -ENOMEM;
-       }
-
-       return 0;
-}
-
-static void rtw_xmit_resource_free(struct adapter *padapter, struct xmit_buf *pxmitbuf,
-                                  u32 free_sz)
-{
-       usb_free_urb(pxmitbuf->pxmit_urb);
-       kfree(pxmitbuf->pallocated_buf);
-}
-
-int _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
-{
-       int i;
-       struct xmit_buf *pxmitbuf;
-       struct xmit_frame *pxframe;
-       u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
-       u32 num_xmit_extbuf = NR_XMIT_EXTBUFF;
-
-       /*  We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */
-
-       spin_lock_init(&pxmitpriv->lock);
-
-       /*
-        * Please insert all the queue initializaiton using rtw_init_queue below
-        */
-
-       pxmitpriv->adapter = padapter;
-
-       INIT_LIST_HEAD(&pxmitpriv->be_pending);
-       INIT_LIST_HEAD(&pxmitpriv->bk_pending);
-       INIT_LIST_HEAD(&pxmitpriv->vi_pending);
-       INIT_LIST_HEAD(&pxmitpriv->vo_pending);
-
-       rtw_init_queue(&pxmitpriv->free_xmit_queue);
-
-       /*
-        * Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME,
-        * and initialize free_xmit_frame below.
-        * Please also apply  free_txobj to link_up all the xmit_frames...
-        */
-
-       pxmitpriv->pallocated_frame_buf = vzalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4);
-
-       if (!pxmitpriv->pallocated_frame_buf) {
-               pxmitpriv->pxmit_frame_buf = NULL;
-               goto exit;
-       }
-       pxmitpriv->pxmit_frame_buf = (u8 *)ALIGN((size_t)(pxmitpriv->pallocated_frame_buf), 4);
-       /* pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 - */
-       /*                                              ((size_t) (pxmitpriv->pallocated_frame_buf) &3); */
-
-       pxframe = (struct xmit_frame *)pxmitpriv->pxmit_frame_buf;
-
-       for (i = 0; i < NR_XMITFRAME; i++) {
-               INIT_LIST_HEAD(&pxframe->list);
-
-               pxframe->padapter = padapter;
-               pxframe->frame_tag = NULL_FRAMETAG;
-
-               pxframe->pkt = NULL;
-
-               pxframe->buf_addr = NULL;
-               pxframe->pxmitbuf = NULL;
-
-               list_add_tail(&pxframe->list, &pxmitpriv->free_xmit_queue.queue);
-
-               pxframe++;
-       }
-
-       pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
-
-       pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
-
-       /* init xmit_buf */
-       rtw_init_queue(&pxmitpriv->free_xmitbuf_queue);
-       rtw_init_queue(&pxmitpriv->pending_xmitbuf_queue);
-
-       pxmitpriv->pallocated_xmitbuf = vzalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4);
-
-       if (!pxmitpriv->pallocated_xmitbuf)
-               goto free_frame_buf;
-
-       pxmitpriv->pxmitbuf = (u8 *)ALIGN((size_t)(pxmitpriv->pallocated_xmitbuf), 4);
-       /* pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 - */
-       /*                                              ((size_t) (pxmitpriv->pallocated_xmitbuf) &3); */
-
-       pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
-
-       for (i = 0; i < NR_XMITBUFF; i++) {
-               INIT_LIST_HEAD(&pxmitbuf->list);
-
-               pxmitbuf->priv_data = NULL;
-               pxmitbuf->padapter = padapter;
-               pxmitbuf->ext_tag = false;
-
-               /* Tx buf allocation may fail sometimes, so sleep and retry. */
-               if (rtw_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ))) {
-                       msleep(10);
-                       if (rtw_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ)))
-                               goto free_xmitbuf;
-               }
-
-               pxmitbuf->high_queue = false;
-
-               list_add_tail(&pxmitbuf->list, &pxmitpriv->free_xmitbuf_queue.queue);
-               pxmitbuf++;
-       }
-
-       pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
-
-       /*  Init xmit extension buff */
-       rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue);
-
-       pxmitpriv->pallocated_xmit_extbuf = vzalloc(num_xmit_extbuf * sizeof(struct xmit_buf) + 4);
-
-       if (!pxmitpriv->pallocated_xmit_extbuf)
-               goto free_xmitbuf;
-
-       pxmitpriv->pxmit_extbuf = (u8 *)ALIGN((size_t)(pxmitpriv->pallocated_xmit_extbuf), 4);
-
-       pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
-
-       for (i = 0; i < num_xmit_extbuf; i++) {
-               INIT_LIST_HEAD(&pxmitbuf->list);
-
-               pxmitbuf->priv_data = NULL;
-               pxmitbuf->padapter = padapter;
-               pxmitbuf->ext_tag = true;
-
-               if (rtw_xmit_resource_alloc(padapter, pxmitbuf, max_xmit_extbuf_size + XMITBUF_ALIGN_SZ))
-                       goto free_xmit_extbuf;
-
-               list_add_tail(&pxmitbuf->list, &pxmitpriv->free_xmit_extbuf_queue.queue);
-               pxmitbuf++;
-       }
-
-       pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf;
-
-       if (rtw_alloc_hwxmits(padapter))
-               goto free_xmit_extbuf;
-
-       for (i = 0; i < 4; i++)
-               pxmitpriv->wmm_para_seq[i] = i;
-
-       pxmitpriv->ack_tx = false;
-       mutex_init(&pxmitpriv->ack_tx_mutex);
-       rtw_sctx_init(&pxmitpriv->ack_tx_ops, 0);
-
-       tasklet_init(&pxmitpriv->xmit_tasklet, rtl8188eu_xmit_tasklet, (unsigned long)padapter);
-
-       return 0;
-
-free_xmit_extbuf:
-       pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
-       while (i--) {
-               rtw_xmit_resource_free(padapter, pxmitbuf, (max_xmit_extbuf_size + XMITBUF_ALIGN_SZ));
-               pxmitbuf++;
-       }
-       vfree(pxmitpriv->pallocated_xmit_extbuf);
-       i = NR_XMITBUFF;
-free_xmitbuf:
-       pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
-       while (i--) {
-               rtw_xmit_resource_free(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ));
-               pxmitbuf++;
-       }
-       vfree(pxmitpriv->pallocated_xmitbuf);
-free_frame_buf:
-       vfree(pxmitpriv->pallocated_frame_buf);
-exit:
-       return -ENOMEM;
-}
-
-static void rtw_pkt_complete(struct adapter *padapter, struct sk_buff *pkt)
-{
-       u16 queue;
-       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
-       queue = skb_get_queue_mapping(pkt);
-       if (padapter->registrypriv.wifi_spec) {
-               if (__netif_subqueue_stopped(padapter->pnetdev, queue) &&
-                   (pxmitpriv->hwxmits[queue].accnt < WMM_XMIT_THRESHOLD))
-                       netif_wake_subqueue(padapter->pnetdev, queue);
-       } else {
-               if (__netif_subqueue_stopped(padapter->pnetdev, queue))
-                       netif_wake_subqueue(padapter->pnetdev, queue);
-       }
-
-       dev_kfree_skb_any(pkt);
-}
-
-void rtw_xmit_complete(struct adapter *padapter, struct xmit_frame *pxframe)
-{
-       if (pxframe->pkt)
-               rtw_pkt_complete(padapter, pxframe->pkt);
-       pxframe->pkt = NULL;
-}
-
-void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv)
-{
-       int i;
-       struct adapter *padapter = pxmitpriv->adapter;
-       struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitpriv->pxmit_frame_buf;
-       struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
-       u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
-       u32 num_xmit_extbuf = NR_XMIT_EXTBUFF;
-
-       if (!pxmitpriv->pxmit_frame_buf)
-               return;
-
-       for (i = 0; i < NR_XMITFRAME; i++) {
-               rtw_xmit_complete(padapter, pxmitframe);
-
-               pxmitframe++;
-       }
-
-       for (i = 0; i < NR_XMITBUFF; i++) {
-               rtw_xmit_resource_free(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ));
-               pxmitbuf++;
-       }
-
-       vfree(pxmitpriv->pallocated_frame_buf);
-
-       vfree(pxmitpriv->pallocated_xmitbuf);
-
-       pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
-       for (i = 0; i < num_xmit_extbuf; i++) {
-               rtw_xmit_resource_free(padapter, pxmitbuf, (max_xmit_extbuf_size + XMITBUF_ALIGN_SZ));
-               pxmitbuf++;
-       }
-
-       vfree(pxmitpriv->pallocated_xmit_extbuf);
-
-       kfree(pxmitpriv->hwxmits);
-
-       mutex_destroy(&pxmitpriv->ack_tx_mutex);
-}
-
-static void update_attrib_vcs_info(struct adapter *padapter, struct xmit_frame *pxmitframe)
-{
-       u32     sz;
-       struct pkt_attrib       *pattrib = &pxmitframe->attrib;
-       struct sta_info *psta = pattrib->psta;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       if (pattrib->nr_frags != 1)
-               sz = padapter->xmitpriv.frag_len;
-       else /* no frag */
-               sz = pattrib->last_txcmdsz;
-
-       /*  (1) RTS_Threshold is compared to the MPDU, not MSDU. */
-       /*  (2) If there are more than one frag in  this MSDU, only the first frag uses protection frame. */
-       /*              Other fragments are protected by previous fragment. */
-       /*              So we only need to check the length of first fragment. */
-       if (pmlmeext->cur_wireless_mode < WIRELESS_11_24N  || padapter->registrypriv.wifi_spec) {
-               if (sz > padapter->registrypriv.rts_thresh) {
-                       pattrib->vcs_mode = RTS_CTS;
-               } else {
-                       if (psta->rtsen)
-                               pattrib->vcs_mode = RTS_CTS;
-                       else if (psta->cts2self)
-                               pattrib->vcs_mode = CTS_TO_SELF;
-                       else
-                               pattrib->vcs_mode = NONE_VCS;
-               }
-       } else {
-               while (true) {
-                       /* IOT action */
-                       if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS) && pattrib->ampdu_en &&
-                           (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) {
-                               pattrib->vcs_mode = CTS_TO_SELF;
-                               break;
-                       }
-
-                       /* check ERP protection */
-                       if (psta->rtsen || psta->cts2self) {
-                               if (psta->rtsen)
-                                       pattrib->vcs_mode = RTS_CTS;
-                               else if (psta->cts2self)
-                                       pattrib->vcs_mode = CTS_TO_SELF;
-
-                               break;
-                       }
-
-                       /* check HT op mode */
-                       if (pattrib->ht_en) {
-                               u8 htopmode = pmlmeinfo->HT_protection;
-
-                               if ((pmlmeext->cur_bwmode && (htopmode == 2 || htopmode == 3)) ||
-                                   (!pmlmeext->cur_bwmode && htopmode == 3)) {
-                                       pattrib->vcs_mode = RTS_CTS;
-                                       break;
-                               }
-                       }
-
-                       /* check rts */
-                       if (sz > padapter->registrypriv.rts_thresh) {
-                               pattrib->vcs_mode = RTS_CTS;
-                               break;
-                       }
-
-                       /* to do list: check MIMO power save condition. */
-
-                       /* check AMPDU aggregation for TXOP */
-                       if (pattrib->ampdu_en) {
-                               pattrib->vcs_mode = RTS_CTS;
-                               break;
-                       }
-
-                       pattrib->vcs_mode = NONE_VCS;
-                       break;
-               }
-       }
-}
-
-static void update_attrib_phy_info(struct pkt_attrib *pattrib, struct sta_info *psta)
-{
-       /*if (psta->rtsen)
-               pattrib->vcs_mode = RTS_CTS;
-       else if (psta->cts2self)
-               pattrib->vcs_mode = CTS_TO_SELF;
-       else
-               pattrib->vcs_mode = NONE_VCS;*/
-
-       pattrib->mdata = 0;
-       pattrib->eosp = 0;
-       pattrib->triggered = 0;
-
-       /* qos_en, ht_en, init rate, , bw, ch_offset, sgi */
-       pattrib->qos_en = psta->qos_option;
-
-       pattrib->raid = psta->raid;
-       pattrib->ht_en = psta->htpriv.ht_option;
-       pattrib->bwmode = psta->htpriv.bwmode;
-       pattrib->ch_offset = psta->htpriv.ch_offset;
-       pattrib->sgi = psta->htpriv.sgi;
-       pattrib->ampdu_en = false;
-       pattrib->retry_ctrl = false;
-}
-
-u8     qos_acm(u8 acm_mask, u8 priority)
-{
-       u8      change_priority = priority;
-
-       switch (priority) {
-       case 0:
-       case 3:
-               if (acm_mask & BIT(1))
-                       change_priority = 1;
-               break;
-       case 1:
-       case 2:
-               break;
-       case 4:
-       case 5:
-               if (acm_mask & BIT(2))
-                       change_priority = 0;
-               break;
-       case 6:
-       case 7:
-               if (acm_mask & BIT(3))
-                       change_priority = 5;
-               break;
-       default:
-               break;
-       }
-
-       return change_priority;
-}
-
-static void rtw_open_pktfile(struct sk_buff *pktptr, struct pkt_file *pfile)
-{
-       if (!pktptr) {
-               pr_err("8188eu: pktptr is NULL\n");
-               return;
-       }
-       if (!pfile) {
-               pr_err("8188eu: pfile is NULL\n");
-               return;
-       }
-       pfile->pkt = pktptr;
-       pfile->cur_addr = pktptr->data;
-       pfile->buf_start = pktptr->data;
-       pfile->pkt_len = pktptr->len;
-       pfile->buf_len = pktptr->len;
-
-       pfile->cur_buffer = pfile->buf_start;
-}
-
-static uint rtw_remainder_len(struct pkt_file *pfile)
-{
-       return pfile->buf_len - ((size_t)(pfile->cur_addr) -
-              (size_t)(pfile->buf_start));
-}
-
-static uint rtw_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen)
-{
-       uint len;
-
-       len = min(rtw_remainder_len(pfile), rlen);
-
-       if (rmem)
-               skb_copy_bits(pfile->pkt, pfile->buf_len - pfile->pkt_len, rmem, len);
-
-       pfile->cur_addr += len;
-       pfile->pkt_len -= len;
-
-       return len;
-}
-
-static void set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib)
-{
-       struct ethhdr etherhdr;
-       struct iphdr ip_hdr;
-       s32 user_prio = 0;
-
-       rtw_open_pktfile(ppktfile->pkt, ppktfile);
-       rtw_pktfile_read(ppktfile, (unsigned char *)&etherhdr, ETH_HLEN);
-
-       /*  get user_prio from IP hdr */
-       if (pattrib->ether_type == 0x0800) {
-               rtw_pktfile_read(ppktfile, (u8 *)&ip_hdr, sizeof(ip_hdr));
-/*             user_prio = (ntohs(ip_hdr.tos) >> 5) & 0x3; */
-               user_prio = ip_hdr.tos >> 5;
-       } else if (pattrib->ether_type == 0x888e) {
-               /*  "When priority processing of data frames is supported, */
-               /*  a STA's SME should send EAPOL-Key frames at the highest priority." */
-               user_prio = 7;
-       }
-
-       pattrib->priority = user_prio;
-       pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
-       pattrib->subtype = IEEE80211_STYPE_QOS_DATA | IEEE80211_FTYPE_DATA;
-}
-
-static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct pkt_attrib *pattrib)
-{
-       struct pkt_file pktfile;
-       struct sta_info *psta = NULL;
-       struct ethhdr etherhdr;
-
-       bool bmcast;
-       struct sta_priv         *pstapriv = &padapter->stapriv;
-       struct security_priv    *psecuritypriv = &padapter->securitypriv;
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-       struct qos_priv         *pqospriv = &pmlmepriv->qospriv;
-       int res = _SUCCESS;
-
-
-
-       rtw_open_pktfile(pkt, &pktfile);
-       rtw_pktfile_read(&pktfile, (u8 *)&etherhdr, ETH_HLEN);
-
-       pattrib->ether_type = ntohs(etherhdr.h_proto);
-
-       memcpy(pattrib->dst, &etherhdr.h_dest, ETH_ALEN);
-       memcpy(pattrib->src, &etherhdr.h_source, ETH_ALEN);
-
-       pattrib->pctrl = 0;
-
-       if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
-           check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
-               memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
-               memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
-       } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
-               memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
-               memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
-       } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
-               memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
-               memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
-       }
-
-       pattrib->pktlen = pktfile.pkt_len;
-
-       if (pattrib->ether_type == ETH_P_IP) {
-               /*  The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time */
-               /*  to prevent DHCP protocol fail */
-               u8 tmp[24];
-
-               rtw_pktfile_read(&pktfile, &tmp[0], 24);
-               pattrib->dhcp_pkt = 0;
-               if (pktfile.pkt_len > 282) {/* MINIMUM_DHCP_PACKET_SIZE) { */
-                       if (((tmp[21] == 68) && (tmp[23] == 67)) ||
-                           ((tmp[21] == 67) && (tmp[23] == 68))) {
-                               /*  68 : UDP BOOTP client */
-                               /*  67 : UDP BOOTP server */
-                               /*  Use low rate to send DHCP packet. */
-                               pattrib->dhcp_pkt = 1;
-                       }
-               }
-       }
-
-       /*  If EAPOL , ARP , OR DHCP packet, driver must be in active mode. */
-       if ((pattrib->ether_type == 0x0806) || (pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1))
-               rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SPECIAL_PACKET, 1);
-
-       bmcast = is_multicast_ether_addr(pattrib->ra);
-
-       /*  get sta_info */
-       if (bmcast) {
-               psta = rtw_get_bcmc_stainfo(padapter);
-       } else {
-               psta = rtw_get_stainfo(pstapriv, pattrib->ra);
-               if (!psta) { /*  if we cannot get psta => drrp the pkt */
-                       res = _FAIL;
-                       goto exit;
-               } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) && !(psta->state & _FW_LINKED)) {
-                       res = _FAIL;
-                       goto exit;
-               }
-       }
-
-       if (psta) {
-               pattrib->mac_id = psta->mac_id;
-               pattrib->psta = psta;
-       } else {
-               /*  if we cannot get psta => drop the pkt */
-               res = _FAIL;
-               goto exit;
-       }
-
-       pattrib->ack_policy = 0;
-       /*  get ether_hdr_len */
-       pattrib->pkt_hdrlen = ETH_HLEN;/* pattrib->ether_type == 0x8100) ? (14 + 4): 14; vlan tag */
-
-       pattrib->hdrlen = WLAN_HDR_A3_LEN;
-       pattrib->subtype = IEEE80211_FTYPE_DATA;
-       pattrib->priority = 0;
-
-       if (check_fwstate(pmlmepriv, WIFI_AP_STATE | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
-               if (psta->qos_option)
-                       set_qos(&pktfile, pattrib);
-       } else {
-               if (pqospriv->qos_option) {
-                       set_qos(&pktfile, pattrib);
-
-                       if (pmlmepriv->acm_mask != 0)
-                               pattrib->priority = qos_acm(pmlmepriv->acm_mask, pattrib->priority);
-               }
-       }
-
-       if (psta->ieee8021x_blocked) {
-               pattrib->encrypt = 0;
-
-               if ((pattrib->ether_type != 0x888e) && !check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
-                       res = _FAIL;
-                       goto exit;
-               }
-       } else {
-               GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
-
-               switch (psecuritypriv->dot11AuthAlgrthm) {
-               case dot11AuthAlgrthm_Open:
-               case dot11AuthAlgrthm_Shared:
-               case dot11AuthAlgrthm_Auto:
-                       pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex;
-                       break;
-               case dot11AuthAlgrthm_8021X:
-                       if (bmcast)
-                               pattrib->key_idx = (u8)psecuritypriv->dot118021XGrpKeyid;
-                       else
-                               pattrib->key_idx = 0;
-                       break;
-               default:
-                       pattrib->key_idx = 0;
-                       break;
-               }
-       }
-
-       switch (pattrib->encrypt) {
-       case _WEP40_:
-       case _WEP104_:
-               pattrib->iv_len = 4;
-               pattrib->icv_len = 4;
-               break;
-       case _TKIP_:
-               pattrib->iv_len = 8;
-               pattrib->icv_len = 4;
-
-               if (padapter->securitypriv.busetkipkey == _FAIL) {
-                       res = _FAIL;
-                       goto exit;
-               }
-               break;
-       case _AES_:
-               pattrib->iv_len = 8;
-               pattrib->icv_len = 8;
-               break;
-       default:
-               pattrib->iv_len = 0;
-               pattrib->icv_len = 0;
-               break;
-       }
-
-       if (pattrib->encrypt &&
-           (padapter->securitypriv.sw_encrypt || !psecuritypriv->hw_decrypted))
-               pattrib->bswenc = true;
-       else
-               pattrib->bswenc = false;
-
-       update_attrib_phy_info(pattrib, psta);
-
-exit:
-
-       return res;
-}
-
-static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitframe)
-{
-       int curfragnum, length;
-       u8      *pframe, *payload, mic[8];
-       struct  mic_data micdata;
-       struct  sta_info *stainfo;
-       struct  pkt_attrib *pattrib = &pxmitframe->attrib;
-       struct  security_priv   *psecuritypriv = &padapter->securitypriv;
-       struct  xmit_priv *pxmitpriv = &padapter->xmitpriv;
-       u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
-       u8 hw_hdr_offset = 0;
-
-       if (pattrib->psta)
-               stainfo = pattrib->psta;
-       else
-               stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]);
-
-       hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
-
-       if (pattrib->encrypt == _TKIP_) {/* if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_PRIVACY_) */
-               /* encode mic code */
-               if (stainfo) {
-                       u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-                                          0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-                                          0x0, 0x0};
-
-                       pframe = pxmitframe->buf_addr + hw_hdr_offset;
-
-                       if (is_multicast_ether_addr(pattrib->ra)) {
-                               if (!memcmp(psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey, null_key, 16))
-                                       return _FAIL;
-                               /* start to calculate the mic code */
-                               rtw_secmicsetkey(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey);
-                       } else {
-                               if (!memcmp(&stainfo->dot11tkiptxmickey.skey[0], null_key, 16)) {
-                                       /* msleep(10); */
-                                       return _FAIL;
-                               }
-                               /* start to calculate the mic code */
-                               rtw_secmicsetkey(&micdata, &stainfo->dot11tkiptxmickey.skey[0]);
-                       }
-
-                       if (pframe[1] & 1) {   /* ToDS == 1 */
-                               rtw_secmicappend(&micdata, &pframe[16], 6);  /* DA */
-                               if (pframe[1] & 2)  /* From Ds == 1 */
-                                       rtw_secmicappend(&micdata, &pframe[24], 6);
-                               else
-                                       rtw_secmicappend(&micdata, &pframe[10], 6);
-                       } else {        /* ToDS == 0 */
-                               rtw_secmicappend(&micdata, &pframe[4], 6);   /* DA */
-                               if (pframe[1] & 2)  /* From Ds == 1 */
-                                       rtw_secmicappend(&micdata, &pframe[16], 6);
-                               else
-                                       rtw_secmicappend(&micdata, &pframe[10], 6);
-                       }
-
-                       if (pattrib->qos_en)
-                               priority[0] = (u8)pxmitframe->attrib.priority;
-
-                       rtw_secmicappend(&micdata, &priority[0], 4);
-
-                       payload = pframe;
-
-                       for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
-                               payload = PTR_ALIGN(payload, 4);
-
-                               payload = payload + pattrib->hdrlen + pattrib->iv_len;
-                               if ((curfragnum + 1) == pattrib->nr_frags) {
-                                       length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - ((pattrib->bswenc) ? pattrib->icv_len : 0);
-                                       rtw_secmicappend(&micdata, payload, length);
-                                       payload = payload + length;
-                               } else {
-                                       length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - ((pattrib->bswenc) ? pattrib->icv_len : 0);
-                                       rtw_secmicappend(&micdata, payload, length);
-                                       payload = payload + length + pattrib->icv_len;
-                               }
-                       }
-                       rtw_secgetmic(&micdata, &mic[0]);
-                       /* add mic code  and add the mic code length in last_txcmdsz */
-
-                       memcpy(payload, &mic[0], 8);
-                       pattrib->last_txcmdsz += 8;
-
-                       payload = payload - pattrib->last_txcmdsz + 8;
-               }
-       }
-
-       return _SUCCESS;
-}
-
-static void xmitframe_swencrypt(struct adapter *padapter, struct xmit_frame *pxmitframe)
-{
-       struct  pkt_attrib       *pattrib = &pxmitframe->attrib;
-
-       if (!pattrib->bswenc)
-               return;
-
-       switch (pattrib->encrypt) {
-       case _WEP40_:
-       case _WEP104_:
-               rtw_wep_encrypt(padapter, pxmitframe);
-               break;
-       case _TKIP_:
-               rtw_tkip_encrypt(padapter, pxmitframe);
-               break;
-       case _AES_:
-               rtw_aes_encrypt(padapter, pxmitframe);
-               break;
-       default:
-               break;
-       }
-}
-
-s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, struct pkt_attrib *pattrib)
-{
-       u16 *qc;
-
-       struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct qos_priv *pqospriv = &pmlmepriv->qospriv;
-       bool qos_option;
-       __le16 *fctrl = &pwlanhdr->frame_control;
-
-       struct sta_info *psta;
-
-       if (pattrib->psta)
-               psta = pattrib->psta;
-       else if (is_multicast_ether_addr(pattrib->ra))
-               psta = rtw_get_bcmc_stainfo(padapter);
-       else
-               psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
-
-       memset(hdr, 0, WLANHDR_OFFSET);
-
-       SetFrameSubType(fctrl, pattrib->subtype);
-
-       if (!(pattrib->subtype & IEEE80211_FTYPE_DATA))
-               return _SUCCESS;
-
-       if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
-               /* to_ds = 1, fr_ds = 0; */
-               /* Data transfer to AP */
-               SetToDs(fctrl);
-               memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
-               memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
-               memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
-               qos_option = pqospriv->qos_option;
-       } else if (check_fwstate(pmlmepriv,  WIFI_AP_STATE)) {
-               /* to_ds = 0, fr_ds = 1; */
-               SetFrDs(fctrl);
-               memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
-               memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN);
-               memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN);
-               qos_option = psta->qos_option;
-       } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
-                  check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
-               memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
-               memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
-               memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
-               qos_option = psta->qos_option;
-       } else {
-               return _FAIL;
-       }
-
-       if (pattrib->mdata)
-               SetMData(fctrl);
-
-       if (pattrib->encrypt)
-               SetPrivacy(fctrl);
-
-       if (qos_option) {
-               qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
-
-               if (pattrib->priority)
-                       SetPriority(qc, pattrib->priority);
-
-               SetEOSP(qc, pattrib->eosp);
-
-               SetAckpolicy(qc, pattrib->ack_policy);
-       }
-
-       /* TODO: fill HT Control Field */
-
-       /* Update Seq Num will be handled by f/w */
-       if (psta) {
-               psta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
-               psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
-
-               pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority];
-
-               SetSeqNum(hdr, pattrib->seqnum);
-
-               /* check if enable ampdu */
-               if (pattrib->ht_en && psta->htpriv.ampdu_enable) {
-                       if (psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority))
-                               pattrib->ampdu_en = true;
-               }
-
-               /* re-check if enable ampdu by BA_starting_seqctrl */
-               if (pattrib->ampdu_en) {
-                       u16 tx_seq;
-
-                       tx_seq = psta->BA_starting_seqctrl[pattrib->priority & 0x0f];
-
-                       /* check BA_starting_seqctrl */
-                       if (SN_LESS(pattrib->seqnum, tx_seq)) {
-                               pattrib->ampdu_en = false;/* AGG BK */
-                       } else if (SN_EQUAL(pattrib->seqnum, tx_seq)) {
-                               psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq + 1) & 0xfff;
-
-                               pattrib->ampdu_en = true;/* AGG EN */
-                       } else {
-                               psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum + 1) & 0xfff;
-                               pattrib->ampdu_en = true;/* AGG EN */
-                       }
-               }
-       }
-
-       return _SUCCESS;
-}
-
-s32 rtw_txframes_pending(struct adapter *padapter)
-{
-       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
-       return (!list_empty(&pxmitpriv->be_pending) ||
-               !list_empty(&pxmitpriv->bk_pending) ||
-               !list_empty(&pxmitpriv->vi_pending) ||
-               !list_empty(&pxmitpriv->vo_pending));
-}
-
-s32 rtw_txframes_sta_ac_pending(struct adapter *padapter, struct pkt_attrib *pattrib)
-{
-       struct sta_info *psta;
-       struct tx_servq *ptxservq;
-       int priority = pattrib->priority;
-
-       psta = pattrib->psta;
-
-       switch (priority) {
-       case 1:
-       case 2:
-               ptxservq = &psta->sta_xmitpriv.bk_q;
-               break;
-       case 4:
-       case 5:
-               ptxservq = &psta->sta_xmitpriv.vi_q;
-               break;
-       case 6:
-       case 7:
-               ptxservq = &psta->sta_xmitpriv.vo_q;
-               break;
-       case 0:
-       case 3:
-       default:
-               ptxservq = &psta->sta_xmitpriv.be_q;
-               break;
-       }
-
-       if (ptxservq)
-               return ptxservq->qcnt;
-       return 0;
-}
-
-/*
- * This sub-routine will perform all the following:
- *
- * 1. remove 802.3 header.
- * 2. create wlan_header, based on the info in pxmitframe
- * 3. append sta's iv/ext-iv
- * 4. append LLC
- * 5. move frag chunk from pframe to pxmitframe->mem
- * 6. apply sw-encrypt, if necessary.
- */
-s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct xmit_frame *pxmitframe)
-{
-       struct pkt_file pktfile;
-       s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
-       u8 *pframe, *mem_start;
-       u8 hw_hdr_offset;
-       struct sta_info         *psta;
-       struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
-       struct pkt_attrib       *pattrib = &pxmitframe->attrib;
-       u8 *pbuf_start;
-       bool bmcst = is_multicast_ether_addr(pattrib->ra);
-       s32 res = _SUCCESS;
-
-       if (!pkt)
-               return _FAIL;
-
-       psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
-
-       if (!psta)
-               return _FAIL;
-
-       if (!pxmitframe->buf_addr)
-               return _FAIL;
-
-       pbuf_start = pxmitframe->buf_addr;
-
-       hw_hdr_offset =  TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
-
-       mem_start = pbuf_start +        hw_hdr_offset;
-
-       if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) {
-               res = _FAIL;
-               goto exit;
-       }
-
-       rtw_open_pktfile(pkt, &pktfile);
-       rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen);
-
-       frg_inx = 0;
-       frg_len = pxmitpriv->frag_len - 4;/* 2346-4 = 2342 */
-
-       while (1) {
-               llc_sz = 0;
-
-               mpdu_len = frg_len;
-
-               pframe = mem_start;
-
-               SetMFrag(mem_start);
-
-               pframe += pattrib->hdrlen;
-               mpdu_len -= pattrib->hdrlen;
-
-               /* adding icv, if necessary... */
-               if (pattrib->iv_len) {
-                       switch (pattrib->encrypt) {
-                       case _WEP40_:
-                       case _WEP104_:
-                               WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
-                               break;
-                       case _TKIP_:
-                               if (bmcst)
-                                       TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
-                               else
-                                       TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
-                               break;
-                       case _AES_:
-                               if (bmcst)
-                                       AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
-                               else
-                                       AES_IV(pattrib->iv, psta->dot11txpn, 0);
-                               break;
-                       }
-
-                       memcpy(pframe, pattrib->iv, pattrib->iv_len);
-
-                       pframe += pattrib->iv_len;
-
-                       mpdu_len -= pattrib->iv_len;
-               }
-
-               if (frg_inx == 0) {
-                       llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
-                       pframe += llc_sz;
-                       mpdu_len -= llc_sz;
-               }
-
-               if ((pattrib->icv_len > 0) && (pattrib->bswenc))
-                       mpdu_len -= pattrib->icv_len;
-
-               if (bmcst) {
-                       /*  don't do fragment to broadcast/multicast packets */
-                       mem_sz = rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen);
-               } else {
-                       mem_sz = rtw_pktfile_read(&pktfile, pframe, mpdu_len);
-               }
-
-               pframe += mem_sz;
-
-               if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
-                       memcpy(pframe, pattrib->icv, pattrib->icv_len);
-                       pframe += pattrib->icv_len;
-               }
-
-               frg_inx++;
-
-               if (bmcst || pktfile.pkt_len == 0) {
-                       pattrib->nr_frags = frg_inx;
-
-                       pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + ((pattrib->nr_frags == 1) ? llc_sz : 0) +
-                                               ((pattrib->bswenc) ? pattrib->icv_len : 0) + mem_sz;
-
-                       ClearMFrag(mem_start);
-
-                       break;
-               }
-
-               mem_start = PTR_ALIGN(pframe, 4) + hw_hdr_offset;
-               memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen);
-       }
-
-       if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) {
-               res = _FAIL;
-               goto exit;
-       }
-
-       xmitframe_swencrypt(padapter, pxmitframe);
-
-       if (!bmcst)
-               update_attrib_vcs_info(padapter, pxmitframe);
-       else
-               pattrib->vcs_mode = NONE_VCS;
-
-exit:
-
-       return res;
-}
-
-/* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header
- * IEEE LLC/SNAP header contains 8 octets
- * First 3 octets comprise the LLC portion
- * SNAP portion, 5 octets, is divided into two fields:
- *     Organizationally Unique Identifier(OUI), 3 octets,
- *     type, defined by that organization, 2 octets.
- */
-s32 rtw_put_snap(u8 *data, u16 h_proto)
-{
-       struct ieee80211_snap_hdr *snap;
-       u8 *oui;
-
-       snap = (struct ieee80211_snap_hdr *)data;
-       snap->dsap = 0xaa;
-       snap->ssap = 0xaa;
-       snap->ctrl = 0x03;
-
-       if (h_proto == 0x8137 || h_proto == 0x80f3)
-               oui = P802_1H_OUI;
-       else
-               oui = RFC1042_OUI;
-
-       snap->oui[0] = oui[0];
-       snap->oui[1] = oui[1];
-       snap->oui[2] = oui[2];
-
-       *(__be16 *)(data + SNAP_SIZE) = htons(h_proto);
-
-       return SNAP_SIZE + sizeof(u16);
-}
-
-void rtw_count_tx_stats(struct adapter *padapter, struct xmit_frame *pxmitframe, int sz)
-{
-       struct sta_info *psta = NULL;
-       struct stainfo_stats *pstats = NULL;
-       struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-
-       if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) {
-               pxmitpriv->tx_bytes += sz;
-               pmlmepriv->LinkDetectInfo.NumTxOkInPeriod += pxmitframe->agg_num;
-
-               psta = pxmitframe->attrib.psta;
-               if (psta) {
-                       pstats = &psta->sta_stats;
-                       pstats->tx_pkts += pxmitframe->agg_num;
-                       pstats->tx_bytes += sz;
-               }
-       }
-}
-
-struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv)
-{
-       struct xmit_buf *pxmitbuf =  NULL;
-       struct list_head *plist, *phead;
-       struct __queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
-       unsigned long flags;
-
-       spin_lock_irqsave(&pfree_queue->lock, flags);
-
-       if (list_empty(&pfree_queue->queue)) {
-               pxmitbuf = NULL;
-       } else {
-               phead = get_list_head(pfree_queue);
-
-               plist = phead->next;
-
-               pxmitbuf = container_of(plist, struct xmit_buf, list);
-
-               list_del_init(&pxmitbuf->list);
-       }
-
-       if (pxmitbuf) {
-               pxmitpriv->free_xmit_extbuf_cnt--;
-
-               pxmitbuf->priv_data = NULL;
-               /* pxmitbuf->ext_tag = true; */
-
-               if (pxmitbuf->sctx)
-                       rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
-       }
-
-       spin_unlock_irqrestore(&pfree_queue->lock, flags);
-
-       return pxmitbuf;
-}
-
-s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
-{
-       struct __queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
-       unsigned long flags;
-
-       if (!pxmitbuf)
-               return _FAIL;
-
-       spin_lock_irqsave(&pfree_queue->lock, flags);
-
-       list_del_init(&pxmitbuf->list);
-
-       list_add_tail(&pxmitbuf->list, get_list_head(pfree_queue));
-       pxmitpriv->free_xmit_extbuf_cnt++;
-
-       spin_unlock_irqrestore(&pfree_queue->lock, flags);
-
-       return _SUCCESS;
-}
-
-struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
-{
-       struct xmit_buf *pxmitbuf =  NULL;
-       struct list_head *plist, *phead;
-       struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
-       unsigned long flags;
-
-       spin_lock_irqsave(&pfree_xmitbuf_queue->lock, flags);
-
-       if (list_empty(&pfree_xmitbuf_queue->queue)) {
-               pxmitbuf = NULL;
-       } else {
-               phead = get_list_head(pfree_xmitbuf_queue);
-
-               plist = phead->next;
-
-               pxmitbuf = container_of(plist, struct xmit_buf, list);
-
-               list_del_init(&pxmitbuf->list);
-       }
-
-       if (pxmitbuf) {
-               pxmitpriv->free_xmitbuf_cnt--;
-               pxmitbuf->priv_data = NULL;
-               if (pxmitbuf->sctx)
-                       rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
-       }
-       spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, flags);
-
-       return pxmitbuf;
-}
-
-s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
-{
-       struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
-       unsigned long flags;
-
-       if (!pxmitbuf)
-               return _FAIL;
-
-       if (pxmitbuf->sctx)
-               rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_FREE);
-
-       if (pxmitbuf->ext_tag) {
-               rtw_free_xmitbuf_ext(pxmitpriv, pxmitbuf);
-       } else {
-               spin_lock_irqsave(&pfree_xmitbuf_queue->lock, flags);
-
-               list_del_init(&pxmitbuf->list);
-
-               list_add_tail(&pxmitbuf->list, get_list_head(pfree_xmitbuf_queue));
-
-               pxmitpriv->free_xmitbuf_cnt++;
-               spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, flags);
-       }
-
-       return _SUCCESS;
-}
-
-/*
- * Calling context:
- * 1. OS_TXENTRY
- * 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
- *
- * If we turn on USE_RXTHREAD, then, no need for critical section.
- * Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
- *
- * Must be very very cautious...
- */
-struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)/* _queue *pfree_xmit_queue) */
-{
-       /*
-        * Please remember to use all the osdep_service api,
-        * and lock/unlock or _enter/_exit critical to protect
-        * pfree_xmit_queue
-        */
-
-       struct xmit_frame *pxframe = NULL;
-       struct list_head *plist, *phead;
-       struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
-
-       spin_lock_bh(&pfree_xmit_queue->lock);
-
-       if (list_empty(&pfree_xmit_queue->queue))
-               goto out;
-
-       phead = get_list_head(pfree_xmit_queue);
-       plist = phead->next;
-       pxframe = container_of(plist, struct xmit_frame, list);
-       list_del_init(&pxframe->list);
-
-       pxmitpriv->free_xmitframe_cnt--;
-
-       pxframe->buf_addr = NULL;
-       pxframe->pxmitbuf = NULL;
-
-       memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib));
-       /* pxframe->attrib.psta = NULL; */
-
-       pxframe->frame_tag = DATA_FRAMETAG;
-
-       pxframe->pkt = NULL;
-       pxframe->pkt_offset = 1;/* default use pkt_offset to fill tx desc */
-
-       pxframe->agg_num = 1;
-       pxframe->ack_report = 0;
-
-out:
-       spin_unlock_bh(&pfree_xmit_queue->lock);
-       return pxframe;
-}
-
-s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe)
-{
-       struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
-       struct adapter *padapter = pxmitpriv->adapter;
-       struct sk_buff *pndis_pkt = NULL;
-
-       if (!pxmitframe)
-               goto exit;
-
-       spin_lock_bh(&pfree_xmit_queue->lock);
-
-       list_del_init(&pxmitframe->list);
-
-       if (pxmitframe->pkt) {
-               pndis_pkt = pxmitframe->pkt;
-               pxmitframe->pkt = NULL;
-       }
-
-       list_add_tail(&pxmitframe->list, get_list_head(pfree_xmit_queue));
-
-       pxmitpriv->free_xmitframe_cnt++;
-
-       spin_unlock_bh(&pfree_xmit_queue->lock);
-
-       if (pndis_pkt)
-               rtw_pkt_complete(padapter, pndis_pkt);
-
-exit:
-
-       return _SUCCESS;
-}
-
-void rtw_free_xmitframe_list(struct xmit_priv *pxmitpriv, struct list_head *xframe_list)
-{
-       struct  xmit_frame *pxmitframe, *tmp_xmitframe;
-
-       list_for_each_entry_safe(pxmitframe, tmp_xmitframe, xframe_list, list)
-               rtw_free_xmitframe(pxmitpriv, pxmitframe);
-}
-
-struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i)
-{
-       struct hw_xmit *phwxmit;
-       struct tx_servq *ptxservq, *tmp_txservq;
-       struct list_head *xframe_list;
-       struct xmit_frame *pxmitframe = NULL;
-       struct adapter *padapter = pxmitpriv->adapter;
-       struct registry_priv    *pregpriv = &padapter->registrypriv;
-       int i, inx[] = { 0, 1, 2, 3 };
-
-       if (pregpriv->wifi_spec == 1) {
-               for (i = 0; i < ARRAY_SIZE(inx); i++)
-                       inx[i] = pxmitpriv->wmm_para_seq[i];
-       }
-
-       spin_lock_bh(&pxmitpriv->lock);
-
-       for (i = 0; i < HWXMIT_ENTRY; i++) {
-               phwxmit = phwxmit_i + inx[i];
-               list_for_each_entry_safe(ptxservq, tmp_txservq, phwxmit->sta_list, tx_pending) {
-                       xframe_list = &ptxservq->sta_pending;
-                       if (list_empty(xframe_list))
-                               continue;
-
-                       pxmitframe = container_of(xframe_list->next, struct xmit_frame, list);
-                       list_del_init(&pxmitframe->list);
-
-                       phwxmit->accnt--;
-                       ptxservq->qcnt--;
-
-                       /* Remove sta node when there are no pending packets. */
-                       if (list_empty(xframe_list))
-                               list_del_init(&ptxservq->tx_pending);
-
-                       goto exit;
-               }
-       }
-exit:
-       spin_unlock_bh(&pxmitpriv->lock);
-
-       return pxmitframe;
-}
-
-struct tx_servq *rtw_get_sta_pending(struct adapter *padapter, struct sta_info *psta, int up, u8 *ac)
-{
-       struct tx_servq *ptxservq;
-
-       switch (up) {
-       case 1:
-       case 2:
-               ptxservq = &psta->sta_xmitpriv.bk_q;
-               *(ac) = 3;
-               break;
-       case 4:
-       case 5:
-               ptxservq = &psta->sta_xmitpriv.vi_q;
-               *(ac) = 1;
-               break;
-       case 6:
-       case 7:
-               ptxservq = &psta->sta_xmitpriv.vo_q;
-               *(ac) = 0;
-               break;
-       case 0:
-       case 3:
-       default:
-               ptxservq = &psta->sta_xmitpriv.be_q;
-               *(ac) = 2;
-       break;
-       }
-
-       return ptxservq;
-}
-
-/*
- * Will enqueue pxmitframe to the proper queue,
- * and indicate it to xx_pending list.....
- */
-s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe)
-{
-       u8      ac_index;
-       struct sta_info *psta;
-       struct tx_servq *ptxservq;
-       struct pkt_attrib       *pattrib = &pxmitframe->attrib;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       struct hw_xmit  *phwxmits =  padapter->xmitpriv.hwxmits;
-       int res = _SUCCESS;
-
-       if (pattrib->psta)
-               psta = pattrib->psta;
-       else
-               psta = rtw_get_stainfo(pstapriv, pattrib->ra);
-
-       if (!psta) {
-               res = _FAIL;
-               goto exit;
-       }
-
-       ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
-
-       if (list_empty(&ptxservq->tx_pending))
-               list_add_tail(&ptxservq->tx_pending, phwxmits[ac_index].sta_list);
-
-       list_add_tail(&pxmitframe->list, &ptxservq->sta_pending);
-       ptxservq->qcnt++;
-       phwxmits[ac_index].accnt++;
-exit:
-
-       return res;
-}
-
-int rtw_alloc_hwxmits(struct adapter *padapter)
-{
-       struct hw_xmit *hwxmits;
-       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
-       pxmitpriv->hwxmits = kcalloc(HWXMIT_ENTRY, sizeof(struct hw_xmit), GFP_KERNEL);
-       if (!pxmitpriv->hwxmits)
-               return -ENOMEM;
-
-       hwxmits = pxmitpriv->hwxmits;
-
-       hwxmits[0].sta_list = &pxmitpriv->vo_pending;
-       hwxmits[1].sta_list = &pxmitpriv->vi_pending;
-       hwxmits[2].sta_list = &pxmitpriv->be_pending;
-       hwxmits[3].sta_list = &pxmitpriv->bk_pending;
-
-       return 0;
-}
-
-static int rtw_br_client_tx(struct adapter *padapter, struct sk_buff **pskb)
-{
-       struct sk_buff *skb = *pskb;
-       int res, is_vlan_tag = 0, i, do_nat25 = 1;
-       unsigned short vlan_hdr = 0;
-       void *br_port = NULL;
-
-       rcu_read_lock();
-       br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
-       rcu_read_unlock();
-       spin_lock_bh(&padapter->br_ext_lock);
-       if (!(skb->data[0] & 1) && br_port &&
-           memcmp(skb->data + ETH_ALEN, padapter->br_mac, ETH_ALEN) &&
-           *((__be16 *)(skb->data + ETH_ALEN * 2)) != htons(ETH_P_8021Q) &&
-           *((__be16 *)(skb->data + ETH_ALEN * 2)) == htons(ETH_P_IP) &&
-           !memcmp(padapter->scdb_mac, skb->data + ETH_ALEN, ETH_ALEN) && padapter->scdb_entry) {
-               memcpy(skb->data + ETH_ALEN, GET_MY_HWADDR(padapter), ETH_ALEN);
-               padapter->scdb_entry->ageing_timer = jiffies;
-               spin_unlock_bh(&padapter->br_ext_lock);
-       } else {
-               if (*((__be16 *)(skb->data + ETH_ALEN * 2)) == htons(ETH_P_8021Q)) {
-                       is_vlan_tag = 1;
-                       vlan_hdr = *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2));
-                       for (i = 0; i < 6; i++)
-                               *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2 - i * 2)) = *((unsigned short *)(skb->data + ETH_ALEN * 2 - 2 - i * 2));
-                       skb_pull(skb, 4);
-               }
-               if (!memcmp(skb->data + ETH_ALEN, padapter->br_mac, ETH_ALEN) &&
-                   (*((__be16 *)(skb->data + ETH_ALEN * 2)) == htons(ETH_P_IP)))
-                       memcpy(padapter->br_ip, skb->data + WLAN_ETHHDR_LEN + 12, 4);
-
-               if (*((__be16 *)(skb->data + ETH_ALEN * 2)) == htons(ETH_P_IP)) {
-                       if (memcmp(padapter->scdb_mac, skb->data + ETH_ALEN, ETH_ALEN)) {
-                               padapter->scdb_entry = (struct nat25_network_db_entry *)scdb_findEntry(padapter,
-                                                       skb->data + WLAN_ETHHDR_LEN + 12);
-                               if (padapter->scdb_entry) {
-                                       memcpy(padapter->scdb_mac, skb->data + ETH_ALEN, ETH_ALEN);
-                                       memcpy(padapter->scdb_ip, skb->data + WLAN_ETHHDR_LEN + 12, 4);
-                                       padapter->scdb_entry->ageing_timer = jiffies;
-                                       do_nat25 = 0;
-                               }
-                       } else {
-                               if (padapter->scdb_entry) {
-                                       padapter->scdb_entry->ageing_timer = jiffies;
-                                       do_nat25 = 0;
-                               } else {
-                                       memset(padapter->scdb_mac, 0, ETH_ALEN);
-                                       memset(padapter->scdb_ip, 0, 4);
-                               }
-                       }
-               }
-               spin_unlock_bh(&padapter->br_ext_lock);
-               if (do_nat25) {
-                       if (nat25_db_handle(padapter, skb, NAT25_CHECK) == 0) {
-                               struct sk_buff *newskb;
-
-                               if (is_vlan_tag) {
-                                       skb_push(skb, 4);
-                                       for (i = 0; i < 6; i++)
-                                               *((unsigned short *)(skb->data + i * 2)) = *((unsigned short *)(skb->data + 4 + i * 2));
-                                       *((__be16 *)(skb->data + ETH_ALEN * 2)) = htons(ETH_P_8021Q);
-                                       *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2)) = vlan_hdr;
-                               }
-
-                               newskb = skb_copy(skb, GFP_ATOMIC);
-                               if (!newskb)
-                                       return -1;
-                               dev_kfree_skb_any(skb);
-
-                               *pskb = skb = newskb;
-                               if (is_vlan_tag) {
-                                       vlan_hdr = *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2));
-                                       for (i = 0; i < 6; i++)
-                                               *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2 - i * 2)) = *((unsigned short *)(skb->data + ETH_ALEN * 2 - 2 - i * 2));
-                                       skb_pull(skb, 4);
-                               }
-                       }
-
-                       res = skb_linearize(skb);
-                       if (res < 0)
-                               return -1;
-
-                       res = nat25_db_handle(padapter, skb, NAT25_INSERT);
-                       if (res < 0) {
-                               if (res == -2)
-                                       return -1;
-
-                               return 0;
-                       }
-               }
-
-               memcpy(skb->data + ETH_ALEN, GET_MY_HWADDR(padapter), ETH_ALEN);
-
-               dhcp_flag_bcast(padapter, skb);
-
-               if (is_vlan_tag) {
-                       skb_push(skb, 4);
-                       for (i = 0; i < 6; i++)
-                               *((unsigned short *)(skb->data + i * 2)) = *((unsigned short *)(skb->data + 4 + i * 2));
-                       *((__be16 *)(skb->data + ETH_ALEN * 2)) = htons(ETH_P_8021Q);
-                       *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2)) = vlan_hdr;
-               }
-       }
-
-       /*  check if SA is equal to our MAC */
-       if (memcmp(skb->data + ETH_ALEN, GET_MY_HWADDR(padapter), ETH_ALEN))
-               return -1;
-
-       return 0;
-}
-
-u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe)
-{
-       u32 addr;
-       struct pkt_attrib *pattrib = &pxmitframe->attrib;
-
-       switch (pattrib->qsel) {
-       case 0:
-       case 3:
-               addr = BE_QUEUE_INX;
-               break;
-       case 1:
-       case 2:
-               addr = BK_QUEUE_INX;
-               break;
-       case 4:
-       case 5:
-               addr = VI_QUEUE_INX;
-               break;
-       case 6:
-       case 7:
-               addr = VO_QUEUE_INX;
-               break;
-       case 0x10:
-               addr = BCN_QUEUE_INX;
-               break;
-       case 0x11:/* BC/MC in PS (HIQ) */
-               addr = HIGH_QUEUE_INX;
-               break;
-       case 0x12:
-       default:
-               addr = MGT_QUEUE_INX;
-               break;
-       }
-
-       return addr;
-}
-
-/*
- * The main transmit(tx) entry
- *
- * Return
- *     1       enqueue
- *     0       success, hardware will handle this xmit frame(packet)
- *     <0      fail
- */
-s32 rtw_xmit(struct adapter *padapter, struct sk_buff **ppkt)
-{
-       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-       struct xmit_frame *pxmitframe = NULL;
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-       s32 res;
-
-       pxmitframe = rtw_alloc_xmitframe(pxmitpriv);
-       if (!pxmitframe)
-               return -1;
-
-       if (rcu_access_pointer(padapter->pnetdev->rx_handler_data) &&
-           check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE)) {
-               res = rtw_br_client_tx(padapter, ppkt);
-               if (res == -1) {
-                       rtw_free_xmitframe(pxmitpriv, pxmitframe);
-                       return -1;
-               }
-       }
-
-       res = update_attrib(padapter, *ppkt, &pxmitframe->attrib);
-
-       if (res == _FAIL) {
-               rtw_free_xmitframe(pxmitpriv, pxmitframe);
-               return -1;
-       }
-       pxmitframe->pkt = *ppkt;
-
-       rtw_led_control(padapter, LED_CTL_TX);
-
-       pxmitframe->attrib.qsel = pxmitframe->attrib.priority;
-
-       spin_lock_bh(&pxmitpriv->lock);
-       if (xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe)) {
-               spin_unlock_bh(&pxmitpriv->lock);
-               return 1;
-       }
-       spin_unlock_bh(&pxmitpriv->lock);
-
-       if (!rtl8188eu_hal_xmit(padapter, pxmitframe))
-               return 1;
-
-       return 0;
-}
-
-int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_frame *pxmitframe)
-{
-       int ret = false;
-       struct sta_info *psta = NULL;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       struct pkt_attrib *pattrib = &pxmitframe->attrib;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       bool bmcst = is_multicast_ether_addr(pattrib->ra);
-
-       if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
-               return ret;
-
-       if (pattrib->psta)
-               psta = pattrib->psta;
-       else
-               psta = rtw_get_stainfo(pstapriv, pattrib->ra);
-
-       if (!psta)
-               return ret;
-
-       if (pattrib->triggered == 1) {
-               if (bmcst)
-                       pattrib->qsel = 0x11;/* HIQ */
-               return ret;
-       }
-
-       if (bmcst) {
-               spin_lock_bh(&psta->sleep_q.lock);
-
-               if (pstapriv->sta_dz_bitmap) {/* if any one sta is in ps mode */
-                       list_del_init(&pxmitframe->list);
-
-                       list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
-
-                       psta->sleepq_len++;
-
-                       pstapriv->tim_bitmap |= BIT(0);/*  */
-                       pstapriv->sta_dz_bitmap |= BIT(0);
-                       /* tx bc/mc packets after update bcn */
-                       update_beacon(padapter, _TIM_IE_, NULL, false);
-
-                       ret = true;
-               }
-
-               spin_unlock_bh(&psta->sleep_q.lock);
-
-               return ret;
-       }
-
-       spin_lock_bh(&psta->sleep_q.lock);
-
-       if (psta->state & WIFI_SLEEP_STATE) {
-               u8 wmmps_ac = 0;
-
-               if (pstapriv->sta_dz_bitmap & BIT(psta->aid)) {
-                       list_del_init(&pxmitframe->list);
-
-                       list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
-
-                       psta->sleepq_len++;
-
-                       switch (pattrib->priority) {
-                       case 1:
-                       case 2:
-                               wmmps_ac = psta->uapsd_bk & BIT(0);
-                               break;
-                       case 4:
-                       case 5:
-                               wmmps_ac = psta->uapsd_vi & BIT(0);
-                               break;
-                       case 6:
-                       case 7:
-                               wmmps_ac = psta->uapsd_vo & BIT(0);
-                               break;
-                       case 0:
-                       case 3:
-                       default:
-                               wmmps_ac = psta->uapsd_be & BIT(0);
-                               break;
-                       }
-
-                       if (wmmps_ac)
-                               psta->sleepq_ac_len++;
-
-                       if (((psta->has_legacy_ac) && (!wmmps_ac)) ||
-                           ((!psta->has_legacy_ac) && (wmmps_ac))) {
-                               pstapriv->tim_bitmap |= BIT(psta->aid);
-
-                               if (psta->sleepq_len == 1) {
-                                       /* update BCN for TIM IE */
-                                       update_beacon(padapter, _TIM_IE_, NULL, false);
-                               }
-                       }
-                       ret = true;
-               }
-       }
-
-       spin_unlock_bh(&psta->sleep_q.lock);
-
-       return ret;
-}
-
-static void dequeue_xmitframes_to_sleeping_queue(struct adapter *padapter, struct sta_info *psta, struct list_head *phead)
-{
-       struct list_head *plist;
-       u8      ac_index;
-       struct tx_servq *ptxservq;
-       struct pkt_attrib       *pattrib;
-       struct xmit_frame       *pxmitframe;
-       struct hw_xmit *phwxmits =  padapter->xmitpriv.hwxmits;
-
-       plist = phead->next;
-
-       while (phead != plist) {
-               pxmitframe = container_of(plist, struct xmit_frame, list);
-
-               plist = plist->next;
-
-               xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe);
-
-               pattrib = &pxmitframe->attrib;
-
-               ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
-
-               ptxservq->qcnt--;
-               phwxmits[ac_index].accnt--;
-       }
-}
-
-void stop_sta_xmit(struct adapter *padapter, struct sta_info *psta)
-{
-       struct sta_info *psta_bmc;
-       struct sta_xmit_priv *pstaxmitpriv;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
-       pstaxmitpriv = &psta->sta_xmitpriv;
-
-       /* for BC/MC Frames */
-       psta_bmc = rtw_get_bcmc_stainfo(padapter);
-
-       spin_lock_bh(&pxmitpriv->lock);
-
-       psta->state |= WIFI_SLEEP_STATE;
-
-       pstapriv->sta_dz_bitmap |= BIT(psta->aid);
-
-       dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending);
-       list_del_init(&pstaxmitpriv->vo_q.tx_pending);
-
-       dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending);
-       list_del_init(&pstaxmitpriv->vi_q.tx_pending);
-
-       dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->be_q.sta_pending);
-       list_del_init(&pstaxmitpriv->be_q.tx_pending);
-
-       dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->bk_q.sta_pending);
-       list_del_init(&pstaxmitpriv->bk_q.tx_pending);
-
-       /* for BC/MC Frames */
-       pstaxmitpriv = &psta_bmc->sta_xmitpriv;
-       dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->be_q.sta_pending);
-       list_del_init(&pstaxmitpriv->be_q.tx_pending);
-
-       spin_unlock_bh(&pxmitpriv->lock);
-}
-
-void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta)
-{
-       u8 update_mask = 0, wmmps_ac = 0;
-       struct sta_info *psta_bmc;
-       struct list_head *xmitframe_plist, *xmitframe_phead;
-       struct xmit_frame *pxmitframe = NULL;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-
-       spin_lock_bh(&psta->sleep_q.lock);
-
-       xmitframe_phead = get_list_head(&psta->sleep_q);
-       xmitframe_plist = xmitframe_phead->next;
-
-       while (xmitframe_phead != xmitframe_plist) {
-               pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
-
-               xmitframe_plist = xmitframe_plist->next;
-
-               list_del_init(&pxmitframe->list);
-
-               switch (pxmitframe->attrib.priority) {
-               case 1:
-               case 2:
-                       wmmps_ac = psta->uapsd_bk & BIT(1);
-                       break;
-               case 4:
-               case 5:
-                       wmmps_ac = psta->uapsd_vi & BIT(1);
-                       break;
-               case 6:
-               case 7:
-                       wmmps_ac = psta->uapsd_vo & BIT(1);
-                       break;
-               case 0:
-               case 3:
-               default:
-                       wmmps_ac = psta->uapsd_be & BIT(1);
-                       break;
-               }
-
-               psta->sleepq_len--;
-               if (psta->sleepq_len > 0)
-                       pxmitframe->attrib.mdata = 1;
-               else
-                       pxmitframe->attrib.mdata = 0;
-
-               if (wmmps_ac) {
-                       psta->sleepq_ac_len--;
-                       if (psta->sleepq_ac_len > 0) {
-                               pxmitframe->attrib.mdata = 1;
-                               pxmitframe->attrib.eosp = 0;
-                       } else {
-                               pxmitframe->attrib.mdata = 0;
-                               pxmitframe->attrib.eosp = 1;
-                       }
-               }
-
-               pxmitframe->attrib.triggered = 1;
-
-               spin_unlock_bh(&psta->sleep_q.lock);
-               if (rtl8188eu_hal_xmit(padapter, pxmitframe))
-                       rtw_xmit_complete(padapter, pxmitframe);
-               spin_lock_bh(&psta->sleep_q.lock);
-       }
-
-       if (psta->sleepq_len == 0) {
-               pstapriv->tim_bitmap &= ~BIT(psta->aid);
-
-               update_mask = BIT(0);
-
-               if (psta->state & WIFI_SLEEP_STATE)
-                       psta->state ^= WIFI_SLEEP_STATE;
-
-               if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
-                       psta->expire_to = pstapriv->expire_to;
-                       psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
-               }
-
-               pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
-       }
-
-       spin_unlock_bh(&psta->sleep_q.lock);
-
-       /* for BC/MC Frames */
-       psta_bmc = rtw_get_bcmc_stainfo(padapter);
-       if (!psta_bmc)
-               return;
-
-       if ((pstapriv->sta_dz_bitmap & 0xfffe) == 0x0) { /* no any sta in ps mode */
-               spin_lock_bh(&psta_bmc->sleep_q.lock);
-
-               xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
-               xmitframe_plist = xmitframe_phead->next;
-
-               while (xmitframe_phead != xmitframe_plist) {
-                       pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
-
-                       xmitframe_plist = xmitframe_plist->next;
-
-                       list_del_init(&pxmitframe->list);
-
-                       psta_bmc->sleepq_len--;
-                       if (psta_bmc->sleepq_len > 0)
-                               pxmitframe->attrib.mdata = 1;
-                       else
-                               pxmitframe->attrib.mdata = 0;
-
-                       pxmitframe->attrib.triggered = 1;
-
-                       spin_unlock_bh(&psta_bmc->sleep_q.lock);
-                       if (rtl8188eu_hal_xmit(padapter, pxmitframe))
-                               rtw_xmit_complete(padapter, pxmitframe);
-                       spin_lock_bh(&psta_bmc->sleep_q.lock);
-               }
-
-               if (psta_bmc->sleepq_len == 0) {
-                       pstapriv->tim_bitmap &= ~BIT(0);
-                       pstapriv->sta_dz_bitmap &= ~BIT(0);
-
-                       update_mask |= BIT(1);
-               }
-
-               spin_unlock_bh(&psta_bmc->sleep_q.lock);
-       }
-
-       if (update_mask)
-               update_beacon(padapter, _TIM_IE_, NULL, false);
-}
-
-void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *psta)
-{
-       u8 wmmps_ac = 0;
-       struct list_head *xmitframe_plist, *xmitframe_phead;
-       struct xmit_frame *pxmitframe = NULL;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-
-       spin_lock_bh(&psta->sleep_q.lock);
-
-       xmitframe_phead = get_list_head(&psta->sleep_q);
-       xmitframe_plist = xmitframe_phead->next;
-
-       while (xmitframe_phead != xmitframe_plist) {
-               pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
-
-               xmitframe_plist = xmitframe_plist->next;
-
-               switch (pxmitframe->attrib.priority) {
-               case 1:
-               case 2:
-                       wmmps_ac = psta->uapsd_bk & BIT(1);
-                       break;
-               case 4:
-               case 5:
-                       wmmps_ac = psta->uapsd_vi & BIT(1);
-                       break;
-               case 6:
-               case 7:
-                       wmmps_ac = psta->uapsd_vo & BIT(1);
-                       break;
-               case 0:
-               case 3:
-               default:
-                       wmmps_ac = psta->uapsd_be & BIT(1);
-                       break;
-               }
-
-               if (!wmmps_ac)
-                       continue;
-
-               list_del_init(&pxmitframe->list);
-
-               psta->sleepq_len--;
-               psta->sleepq_ac_len--;
-
-               if (psta->sleepq_ac_len > 0) {
-                       pxmitframe->attrib.mdata = 1;
-                       pxmitframe->attrib.eosp = 0;
-               } else {
-                       pxmitframe->attrib.mdata = 0;
-                       pxmitframe->attrib.eosp = 1;
-               }
-
-               pxmitframe->attrib.triggered = 1;
-
-               if (rtl8188eu_hal_xmit(padapter, pxmitframe))
-                       rtw_xmit_complete(padapter, pxmitframe);
-
-               if ((psta->sleepq_ac_len == 0) && (!psta->has_legacy_ac) && (wmmps_ac)) {
-                       pstapriv->tim_bitmap &= ~BIT(psta->aid);
-
-                       /* update BCN for TIM IE */
-                       update_beacon(padapter, _TIM_IE_, NULL, false);
-               }
-       }
-
-       spin_unlock_bh(&psta->sleep_q.lock);
-}
-
-void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms)
-{
-       sctx->timeout_ms = timeout_ms;
-       sctx->submit_time = jiffies;
-       init_completion(&sctx->done);
-       sctx->status = RTW_SCTX_SUBMITTED;
-}
-
-int rtw_sctx_wait(struct submit_ctx *sctx)
-{
-       int ret = _FAIL;
-       unsigned long expire;
-       int status = 0;
-
-       expire = sctx->timeout_ms ? msecs_to_jiffies(sctx->timeout_ms) : MAX_SCHEDULE_TIMEOUT;
-       if (!wait_for_completion_timeout(&sctx->done, expire))
-               /* timeout, do something?? */
-               status = RTW_SCTX_DONE_TIMEOUT;
-       else
-               status = sctx->status;
-
-       if (status == RTW_SCTX_DONE_SUCCESS)
-               ret = _SUCCESS;
-
-       return ret;
-}
-
-void rtw_sctx_done_err(struct submit_ctx **sctx, int status)
-{
-       if (*sctx) {
-               (*sctx)->status = status;
-               complete(&((*sctx)->done));
-               *sctx = NULL;
-       }
-}
-
-int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms)
-{
-       struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
-
-       pack_tx_ops->submit_time = jiffies;
-       pack_tx_ops->timeout_ms = timeout_ms;
-       pack_tx_ops->status = RTW_SCTX_SUBMITTED;
-
-       return rtw_sctx_wait(pack_tx_ops);
-}
-
-void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status)
-{
-       struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
-
-       if (pxmitpriv->ack_tx)
-               rtw_sctx_done_err(&pack_tx_ops, status);
-}
-
-static void rtw_check_xmit_resource(struct adapter *padapter, struct sk_buff *pkt)
-{
-       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-       u16 queue;
-
-       queue = skb_get_queue_mapping(pkt);
-       if (padapter->registrypriv.wifi_spec) {
-               /* No free space for Tx, tx_worker is too slow */
-               if (pxmitpriv->hwxmits[queue].accnt > WMM_XMIT_THRESHOLD)
-                       netif_stop_subqueue(padapter->pnetdev, queue);
-       } else {
-               if (pxmitpriv->free_xmitframe_cnt <= 4) {
-                       if (!netif_tx_queue_stopped(netdev_get_tx_queue(padapter->pnetdev, queue)))
-                               netif_stop_subqueue(padapter->pnetdev, queue);
-               }
-       }
-}
-
-static int rtw_mlcst2unicst(struct adapter *padapter, struct sk_buff *skb)
-{
-       struct  sta_priv *pstapriv = &padapter->stapriv;
-       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-       struct list_head *phead, *plist;
-       struct sk_buff *newskb;
-       struct sta_info *psta = NULL;
-       s32 res;
-
-       spin_lock_bh(&pstapriv->asoc_list_lock);
-       phead = &pstapriv->asoc_list;
-       plist = phead->next;
-
-       /* free sta asoc_queue */
-       while (phead != plist) {
-               psta = container_of(plist, struct sta_info, asoc_list);
-
-               plist = plist->next;
-
-               /* avoid   come from STA1 and send back STA1 */
-               if (!memcmp(psta->hwaddr, &skb->data[6], 6))
-                       continue;
-
-               newskb = skb_copy(skb, GFP_ATOMIC);
-
-               if (newskb) {
-                       memcpy(newskb->data, psta->hwaddr, 6);
-                       res = rtw_xmit(padapter, &newskb);
-                       if (res < 0) {
-                               pxmitpriv->tx_drop++;
-                               dev_kfree_skb_any(newskb);
-                       } else {
-                               pxmitpriv->tx_pkts++;
-                       }
-               } else {
-                       pxmitpriv->tx_drop++;
-
-                       spin_unlock_bh(&pstapriv->asoc_list_lock);
-                       return false;   /*  Caller shall tx this multicast frame via normal way. */
-               }
-       }
-
-       spin_unlock_bh(&pstapriv->asoc_list_lock);
-       dev_kfree_skb_any(skb);
-       return true;
-}
-
-netdev_tx_t rtw_xmit_entry(struct sk_buff *pkt, struct net_device *pnetdev)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev);
-       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       s32 res = 0;
-
-       if (!rtw_if_up(padapter))
-               goto drop_packet;
-
-       rtw_check_xmit_resource(padapter, pkt);
-
-       if (!rtw_mc2u_disable && check_fwstate(pmlmepriv, WIFI_AP_STATE) &&
-           (IP_MCAST_MAC(pkt->data) || ICMPV6_MCAST_MAC(pkt->data)) &&
-           (padapter->registrypriv.wifi_spec == 0)) {
-               if (pxmitpriv->free_xmitframe_cnt > (NR_XMITFRAME / 4)) {
-                       res = rtw_mlcst2unicst(padapter, pkt);
-                       if (res)
-                               goto exit;
-               }
-       }
-
-       res = rtw_xmit(padapter, &pkt);
-       if (res < 0)
-               goto drop_packet;
-
-       pxmitpriv->tx_pkts++;
-       goto exit;
-
-drop_packet:
-       pxmitpriv->tx_drop++;
-       dev_kfree_skb_any(pkt);
-
-exit:
-       return NETDEV_TX_OK;
-}
diff --git a/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c b/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c
deleted file mode 100644 (file)
index 1e04de3..0000000
+++ /dev/null
@@ -1,654 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright (c) Realtek Semiconductor Corp. */
-
-#include "../include/drv_types.h"
-
-static u8 RETRY_PENALTY[PERENTRY][RETRYSIZE + 1] = {
-               {5, 4, 3, 2, 0, 3},      /* 92 , idx = 0 */
-               {6, 5, 4, 3, 0, 4},      /* 86 , idx = 1 */
-               {6, 5, 4, 2, 0, 4},      /* 81 , idx = 2 */
-               {8, 7, 6, 4, 0, 6},      /* 75 , idx = 3 */
-               {10, 9, 8, 6, 0, 8},     /* 71  , idx = 4 */
-               {10, 9, 8, 4, 0, 8},     /* 66  , idx = 5 */
-               {10, 9, 8, 2, 0, 8},     /* 62  , idx = 6 */
-               {10, 9, 8, 0, 0, 8},     /* 59  , idx = 7 */
-               {18, 17, 16, 8, 0, 16},  /* 53 , idx = 8 */
-               {26, 25, 24, 16, 0, 24}, /* 50  , idx = 9 */
-               {34, 33, 32, 24, 0, 32}, /* 47  , idx = 0x0a */
-               {34, 31, 28, 20, 0, 32}, /* 43  , idx = 0x0b */
-               {34, 31, 27, 18, 0, 32}, /* 40 , idx = 0x0c */
-               {34, 31, 26, 16, 0, 32}, /* 37 , idx = 0x0d */
-               {34, 30, 22, 16, 0, 32}, /* 32 , idx = 0x0e */
-               {34, 30, 24, 16, 0, 32}, /* 26 , idx = 0x0f */
-               {49, 46, 40, 16, 0, 48}, /* 20  , idx = 0x10 */
-               {49, 45, 32, 0, 0, 48},  /* 17 , idx = 0x11 */
-               {49, 45, 22, 18, 0, 48}, /* 15  , idx = 0x12 */
-               {49, 40, 24, 16, 0, 48}, /* 12  , idx = 0x13 */
-               {49, 32, 18, 12, 0, 48}, /* 9 , idx = 0x14 */
-               {49, 22, 18, 14, 0, 48}, /* 6 , idx = 0x15 */
-               {49, 16, 16, 0, 0, 48}
-       }; /* 3, idx = 0x16 */
-
-static u8 PT_PENALTY[RETRYSIZE + 1] = {34, 31, 30, 24, 0, 32};
-
-/*  wilson modify */
-static u8 RETRY_PENALTY_IDX[2][RATESIZE] = {
-               {4, 4, 4, 5, 4, 4, 5, 7, 7, 7, 8, 0x0a,        /*  SS>TH */
-               4, 4, 4, 4, 6, 0x0a, 0x0b, 0x0d,
-               5, 5, 7, 7, 8, 0x0b, 0x0d, 0x0f},                          /*  0329 R01 */
-               {0x0a, 0x0a, 0x0b, 0x0c, 0x0a,
-               0x0a, 0x0b, 0x0c, 0x0d, 0x10, 0x13, 0x14,          /*  SS<TH */
-               0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11, 0x13, 0x15,
-               9, 9, 9, 9, 0x0c, 0x0e, 0x11, 0x13}
-       };
-
-static u8 RETRY_PENALTY_UP_IDX[RATESIZE] = {
-               0x0c, 0x0d, 0x0d, 0x0f, 0x0d, 0x0e,
-               0x0f, 0x0f, 0x10, 0x12, 0x13, 0x14,            /*  SS>TH */
-               0x0f, 0x10, 0x10, 0x12, 0x12, 0x13, 0x14, 0x15,
-               0x11, 0x11, 0x12, 0x13, 0x13, 0x13, 0x14, 0x15};
-
-static u8 RSSI_THRESHOLD[RATESIZE] = {
-               0, 0, 0, 0,
-               0, 0, 0, 0, 0, 0x24, 0x26, 0x2a,
-               0x18, 0x1a, 0x1d, 0x1f, 0x21, 0x27, 0x29, 0x2a,
-               0, 0, 0, 0x1f, 0x23, 0x28, 0x2a, 0x2c};
-
-static u16 N_THRESHOLD_HIGH[RATESIZE] = {
-               4, 4, 8, 16,
-               24, 36, 48, 72, 96, 144, 192, 216,
-               60, 80, 100, 160, 240, 400, 560, 640,
-               300, 320, 480, 720, 1000, 1200, 1600, 2000};
-static u16 N_THRESHOLD_LOW[RATESIZE] = {
-               2, 2, 4, 8,
-               12, 18, 24, 36, 48, 72, 96, 108,
-               30, 40, 50, 80, 120, 200, 280, 320,
-               150, 160, 240, 360, 500, 600, 800, 1000};
-
-static u8 DROPING_NECESSARY[RATESIZE] = {
-               1, 1, 1, 1,
-               1, 2, 3, 4, 5, 6, 7, 8,
-               1, 2, 3, 4, 5, 6, 7, 8,
-               5, 6, 7, 8, 9, 10, 11, 12};
-
-static u8 PendingForRateUpFail[5] = {2, 10, 24, 40, 60};
-static u16 DynamicTxRPTTiming[6] = {
-       0x186a, 0x30d4, 0x493e, 0x61a8, 0x7a12, 0x927c}; /*  200ms-1200ms */
-
-/*  End Rate adaptive parameters */
-
-static void odm_SetTxRPTTiming_8188E(
-               struct odm_dm_struct *dm_odm,
-               struct odm_ra_info *pRaInfo,
-               u8 extend
-       )
-{
-       u8 idx = 0;
-
-       for (idx = 0; idx < 5; idx++)
-               if (DynamicTxRPTTiming[idx] == pRaInfo->RptTime)
-                       break;
-
-       if (extend == 0) { /*  back to default timing */
-               idx = 0;  /* 200ms */
-       } else if (extend == 1) {/*  increase the timing */
-               idx += 1;
-               if (idx > 5)
-                       idx = 5;
-       } else if (extend == 2) {/*  decrease the timing */
-               if (idx != 0)
-                       idx -= 1;
-       }
-       pRaInfo->RptTime = DynamicTxRPTTiming[idx];
-}
-
-static int odm_RateDown_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_info *pRaInfo)
-{
-       u8 RateID, LowestRate, HighestRate;
-       u8 i;
-
-       if (NULL == pRaInfo)
-               return -1;
-       RateID = pRaInfo->PreRate;
-       LowestRate = pRaInfo->LowestRate;
-       HighestRate = pRaInfo->HighestRate;
-
-       if (RateID > HighestRate) {
-               RateID = HighestRate;
-       } else if (pRaInfo->RateSGI) {
-               pRaInfo->RateSGI = 0;
-       } else if (RateID > LowestRate) {
-               if (RateID > 0) {
-                       for (i = RateID - 1; i > LowestRate; i--) {
-                               if (pRaInfo->RAUseRate & BIT(i)) {
-                                       RateID = i;
-                                       goto RateDownFinish;
-                               }
-                       }
-               }
-       } else if (RateID <= LowestRate) {
-               RateID = LowestRate;
-       }
-RateDownFinish:
-       if (pRaInfo->RAWaitingCounter == 1) {
-               pRaInfo->RAWaitingCounter += 1;
-               pRaInfo->RAPendingCounter += 1;
-       } else if (pRaInfo->RAWaitingCounter == 0) {
-               ;
-       } else {
-               pRaInfo->RAWaitingCounter = 0;
-               pRaInfo->RAPendingCounter = 0;
-       }
-
-       if (pRaInfo->RAPendingCounter >= 4)
-               pRaInfo->RAPendingCounter = 4;
-
-       pRaInfo->DecisionRate = RateID;
-       odm_SetTxRPTTiming_8188E(dm_odm, pRaInfo, 2);
-       return 0;
-}
-
-static int odm_RateUp_8188E(
-               struct odm_dm_struct *dm_odm,
-               struct odm_ra_info *pRaInfo
-       )
-{
-       u8 RateID, HighestRate;
-       u8 i;
-
-       if (NULL == pRaInfo)
-               return -1;
-       RateID = pRaInfo->PreRate;
-       HighestRate = pRaInfo->HighestRate;
-       if (pRaInfo->RAWaitingCounter == 1) {
-               pRaInfo->RAWaitingCounter = 0;
-               pRaInfo->RAPendingCounter = 0;
-       } else if (pRaInfo->RAWaitingCounter > 1) {
-               pRaInfo->PreRssiStaRA = pRaInfo->RssiStaRA;
-               goto RateUpfinish;
-       }
-       odm_SetTxRPTTiming_8188E(dm_odm, pRaInfo, 0);
-
-       if (RateID < HighestRate) {
-               for (i = RateID + 1; i <= HighestRate; i++) {
-                       if (pRaInfo->RAUseRate & BIT(i)) {
-                               RateID = i;
-                               goto RateUpfinish;
-                       }
-               }
-       } else if (RateID == HighestRate) {
-               if (pRaInfo->SGIEnable && (pRaInfo->RateSGI != 1))
-                       pRaInfo->RateSGI = 1;
-               else if ((pRaInfo->SGIEnable) != 1)
-                       pRaInfo->RateSGI = 0;
-       } else {
-               RateID = HighestRate;
-       }
-RateUpfinish:
-       if (pRaInfo->RAWaitingCounter == (4 + PendingForRateUpFail[pRaInfo->RAPendingCounter]))
-               pRaInfo->RAWaitingCounter = 0;
-       else
-               pRaInfo->RAWaitingCounter++;
-
-       pRaInfo->DecisionRate = RateID;
-       return 0;
-}
-
-static void odm_ResetRaCounter_8188E(struct odm_ra_info *pRaInfo)
-{
-       u8 RateID;
-
-       RateID = pRaInfo->DecisionRate;
-       pRaInfo->NscUp = (N_THRESHOLD_HIGH[RateID] + N_THRESHOLD_LOW[RateID]) >> 1;
-       pRaInfo->NscDown = (N_THRESHOLD_HIGH[RateID] + N_THRESHOLD_LOW[RateID]) >> 1;
-}
-
-static void odm_RateDecision_8188E(struct odm_dm_struct *dm_odm,
-               struct odm_ra_info *pRaInfo
-       )
-{
-       u8 RateID = 0, RtyPtID = 0, PenaltyID1 = 0, PenaltyID2 = 0;
-       /* u32 pool_retry; */
-       static u8 DynamicTxRPTTimingCounter;
-
-       if (pRaInfo->Active && (pRaInfo->TOTAL > 0)) { /*  STA used and data packet exits */
-               if ((pRaInfo->RssiStaRA < (pRaInfo->PreRssiStaRA - 3)) ||
-                   (pRaInfo->RssiStaRA > (pRaInfo->PreRssiStaRA + 3))) {
-                       pRaInfo->RAWaitingCounter = 0;
-                       pRaInfo->RAPendingCounter = 0;
-               }
-               /*  Start RA decision */
-               if (pRaInfo->PreRate > pRaInfo->HighestRate)
-                       RateID = pRaInfo->HighestRate;
-               else
-                       RateID = pRaInfo->PreRate;
-               if (pRaInfo->RssiStaRA > RSSI_THRESHOLD[RateID])
-                       RtyPtID = 0;
-               else
-                       RtyPtID = 1;
-               PenaltyID1 = RETRY_PENALTY_IDX[RtyPtID][RateID]; /* TODO by page */
-
-               pRaInfo->NscDown += pRaInfo->RTY[0] * RETRY_PENALTY[PenaltyID1][0];
-               pRaInfo->NscDown += pRaInfo->RTY[1] * RETRY_PENALTY[PenaltyID1][1];
-               pRaInfo->NscDown += pRaInfo->RTY[2] * RETRY_PENALTY[PenaltyID1][2];
-               pRaInfo->NscDown += pRaInfo->RTY[3] * RETRY_PENALTY[PenaltyID1][3];
-               pRaInfo->NscDown += pRaInfo->RTY[4] * RETRY_PENALTY[PenaltyID1][4];
-               if (pRaInfo->NscDown > (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID1][5]))
-                       pRaInfo->NscDown -= pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID1][5];
-               else
-                       pRaInfo->NscDown = 0;
-
-               /*  rate up */
-               PenaltyID2 = RETRY_PENALTY_UP_IDX[RateID];
-               pRaInfo->NscUp += pRaInfo->RTY[0] * RETRY_PENALTY[PenaltyID2][0];
-               pRaInfo->NscUp += pRaInfo->RTY[1] * RETRY_PENALTY[PenaltyID2][1];
-               pRaInfo->NscUp += pRaInfo->RTY[2] * RETRY_PENALTY[PenaltyID2][2];
-               pRaInfo->NscUp += pRaInfo->RTY[3] * RETRY_PENALTY[PenaltyID2][3];
-               pRaInfo->NscUp += pRaInfo->RTY[4] * RETRY_PENALTY[PenaltyID2][4];
-               if (pRaInfo->NscUp > (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID2][5]))
-                       pRaInfo->NscUp -= pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID2][5];
-               else
-                       pRaInfo->NscUp = 0;
-
-               if ((pRaInfo->NscDown < N_THRESHOLD_LOW[RateID]) ||
-                   (pRaInfo->DROP > DROPING_NECESSARY[RateID]))
-                       odm_RateDown_8188E(dm_odm, pRaInfo);
-               else if (pRaInfo->NscUp > N_THRESHOLD_HIGH[RateID])
-                       odm_RateUp_8188E(dm_odm, pRaInfo);
-
-               if (pRaInfo->DecisionRate > pRaInfo->HighestRate)
-                       pRaInfo->DecisionRate = pRaInfo->HighestRate;
-
-               if ((pRaInfo->DecisionRate) == (pRaInfo->PreRate))
-                       DynamicTxRPTTimingCounter += 1;
-               else
-                       DynamicTxRPTTimingCounter = 0;
-
-               if (DynamicTxRPTTimingCounter >= 4) {
-                       odm_SetTxRPTTiming_8188E(dm_odm, pRaInfo, 1);
-                       DynamicTxRPTTimingCounter = 0;
-               }
-
-               pRaInfo->PreRate = pRaInfo->DecisionRate;  /* YJ, add, 120120 */
-
-               odm_ResetRaCounter_8188E(pRaInfo);
-       }
-}
-
-static int odm_ARFBRefresh_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_info *pRaInfo)
-{  /*  Wilson 2011/10/26 */
-       u32 MaskFromReg;
-       s8 i;
-       int res;
-
-       switch (pRaInfo->RateID) {
-       case RATR_INX_WIRELESS_NGB:
-               pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0f8ff015;
-               break;
-       case RATR_INX_WIRELESS_NG:
-               pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0f8ff010;
-               break;
-       case RATR_INX_WIRELESS_NB:
-               pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0f8ff005;
-               break;
-       case RATR_INX_WIRELESS_N:
-               pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0f8ff000;
-               break;
-       case RATR_INX_WIRELESS_GB:
-               pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x00000ff5;
-               break;
-       case RATR_INX_WIRELESS_G:
-               pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x00000ff0;
-               break;
-       case RATR_INX_WIRELESS_B:
-               pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0000000d;
-               break;
-       case 12:
-               res = rtw_read32(dm_odm->Adapter, REG_ARFR0, &MaskFromReg);
-               if (res)
-                       return res;
-
-               pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
-               break;
-       case 13:
-               res = rtw_read32(dm_odm->Adapter, REG_ARFR1, &MaskFromReg);
-               if (res)
-                       return res;
-
-               pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
-               break;
-       case 14:
-               res = rtw_read32(dm_odm->Adapter, REG_ARFR2, &MaskFromReg);
-               if (res)
-                       return res;
-
-               pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
-               break;
-       case 15:
-               res = rtw_read32(dm_odm->Adapter, REG_ARFR3, &MaskFromReg);
-               if (res)
-                       return res;
-
-               pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
-               break;
-       default:
-               pRaInfo->RAUseRate = (pRaInfo->RateMask);
-               break;
-       }
-       /*  Highest rate */
-       if (pRaInfo->RAUseRate) {
-               for (i = RATESIZE; i >= 0; i--) {
-                       if ((pRaInfo->RAUseRate) & BIT(i)) {
-                               pRaInfo->HighestRate = i;
-                               break;
-                       }
-               }
-       } else {
-               pRaInfo->HighestRate = 0;
-       }
-       /*  Lowest rate */
-       if (pRaInfo->RAUseRate) {
-               for (i = 0; i < RATESIZE; i++) {
-                       if ((pRaInfo->RAUseRate) & BIT(i)) {
-                               pRaInfo->LowestRate = i;
-                               break;
-                       }
-               }
-       } else {
-               pRaInfo->LowestRate = 0;
-       }
-       if (pRaInfo->HighestRate > 0x13)
-               pRaInfo->PTModeSS = 3;
-       else if (pRaInfo->HighestRate > 0x0b)
-               pRaInfo->PTModeSS = 2;
-       else if (pRaInfo->HighestRate > 0x03)
-               pRaInfo->PTModeSS = 1;
-       else
-               pRaInfo->PTModeSS = 0;
-
-       if (pRaInfo->DecisionRate > pRaInfo->HighestRate)
-               pRaInfo->DecisionRate = pRaInfo->HighestRate;
-
-       return 0;
-}
-
-static void odm_PTTryState_8188E(struct odm_ra_info *pRaInfo)
-{
-       pRaInfo->PTTryState = 0;
-       switch (pRaInfo->PTModeSS) {
-       case 3:
-               if (pRaInfo->DecisionRate >= 0x19)
-                       pRaInfo->PTTryState = 1;
-               break;
-       case 2:
-               if (pRaInfo->DecisionRate >= 0x11)
-                       pRaInfo->PTTryState = 1;
-               break;
-       case 1:
-               if (pRaInfo->DecisionRate >= 0x0a)
-                       pRaInfo->PTTryState = 1;
-               break;
-       case 0:
-               if (pRaInfo->DecisionRate >= 0x03)
-                       pRaInfo->PTTryState = 1;
-               break;
-       default:
-               pRaInfo->PTTryState = 0;
-               break;
-       }
-
-       if (pRaInfo->RssiStaRA < 48) {
-               pRaInfo->PTStage = 0;
-       } else if (pRaInfo->PTTryState == 1) {
-               if ((pRaInfo->PTStopCount >= 10) ||
-                   (pRaInfo->PTPreRssi > pRaInfo->RssiStaRA + 5) ||
-                   (pRaInfo->PTPreRssi < pRaInfo->RssiStaRA - 5) ||
-                   (pRaInfo->DecisionRate != pRaInfo->PTPreRate)) {
-                       if (pRaInfo->PTStage == 0)
-                               pRaInfo->PTStage = 1;
-                       else if (pRaInfo->PTStage == 1)
-                               pRaInfo->PTStage = 3;
-                       else
-                               pRaInfo->PTStage = 5;
-
-                       pRaInfo->PTPreRssi = pRaInfo->RssiStaRA;
-                       pRaInfo->PTStopCount = 0;
-               } else {
-                       pRaInfo->RAstage = 0;
-                       pRaInfo->PTStopCount++;
-               }
-       } else {
-               pRaInfo->PTStage = 0;
-               pRaInfo->RAstage = 0;
-       }
-       pRaInfo->PTPreRate = pRaInfo->DecisionRate;
-}
-
-static void odm_PTDecision_8188E(struct odm_ra_info *pRaInfo)
-{
-       u8 j;
-       u8 temp_stage;
-       u32 numsc;
-       u32 num_total;
-       u8 stage_id;
-
-       numsc  = 0;
-       num_total = pRaInfo->TOTAL * PT_PENALTY[5];
-       for (j = 0; j <= 4; j++) {
-               numsc += pRaInfo->RTY[j] * PT_PENALTY[j];
-               if (numsc > num_total)
-                       break;
-       }
-
-       j = j >> 1;
-       temp_stage = (pRaInfo->PTStage + 1) >> 1;
-       if (temp_stage > j)
-               stage_id = temp_stage - j;
-       else
-               stage_id = 0;
-
-       pRaInfo->PTSmoothFactor = (pRaInfo->PTSmoothFactor >> 1) + (pRaInfo->PTSmoothFactor >> 2) + stage_id * 16 + 2;
-       if (pRaInfo->PTSmoothFactor > 192)
-               pRaInfo->PTSmoothFactor = 192;
-       stage_id = pRaInfo->PTSmoothFactor >> 6;
-       temp_stage = stage_id * 2;
-       if (temp_stage != 0)
-               temp_stage -= 1;
-       if (pRaInfo->DROP > 3)
-               temp_stage = 0;
-       pRaInfo->PTStage = temp_stage;
-}
-
-static void
-odm_RATxRPTTimerSetting(
-               struct odm_dm_struct *dm_odm,
-               u16 minRptTime
-)
-{
-       if (dm_odm->CurrminRptTime != minRptTime) {
-               rtw_rpt_timer_cfg_cmd(dm_odm->Adapter, minRptTime);
-               dm_odm->CurrminRptTime = minRptTime;
-       }
-}
-
-int ODM_RAInfo_Init(struct odm_dm_struct *dm_odm, u8 macid)
-{
-       struct odm_ra_info *pRaInfo = &dm_odm->RAInfo[macid];
-       u8 WirelessMode = 0xFF; /* invalid value */
-       u8 max_rate_idx = 0x13; /* MCS7 */
-       if (dm_odm->pWirelessMode)
-               WirelessMode = *dm_odm->pWirelessMode;
-
-       if (WirelessMode != 0xFF) {
-               if (WirelessMode & ODM_WM_N24G)
-                       max_rate_idx = 0x13;
-               else if (WirelessMode & ODM_WM_G)
-                       max_rate_idx = 0x0b;
-               else if (WirelessMode & ODM_WM_B)
-                       max_rate_idx = 0x03;
-       }
-
-       pRaInfo->DecisionRate = max_rate_idx;
-       pRaInfo->PreRate = max_rate_idx;
-       pRaInfo->HighestRate = max_rate_idx;
-       pRaInfo->LowestRate = 0;
-       pRaInfo->RateID = 0;
-       pRaInfo->RateMask = 0xffffffff;
-       pRaInfo->RssiStaRA = 0;
-       pRaInfo->PreRssiStaRA = 0;
-       pRaInfo->SGIEnable = 0;
-       pRaInfo->RAUseRate = 0xffffffff;
-       pRaInfo->NscDown = (N_THRESHOLD_HIGH[0x13] + N_THRESHOLD_LOW[0x13]) / 2;
-       pRaInfo->NscUp = (N_THRESHOLD_HIGH[0x13] + N_THRESHOLD_LOW[0x13]) / 2;
-       pRaInfo->RateSGI = 0;
-       pRaInfo->Active = 1;    /* Active is not used at present. by page, 110819 */
-       pRaInfo->RptTime = 0x927c;
-       pRaInfo->DROP = 0;
-       pRaInfo->RTY[0] = 0;
-       pRaInfo->RTY[1] = 0;
-       pRaInfo->RTY[2] = 0;
-       pRaInfo->RTY[3] = 0;
-       pRaInfo->RTY[4] = 0;
-       pRaInfo->TOTAL = 0;
-       pRaInfo->RAWaitingCounter = 0;
-       pRaInfo->RAPendingCounter = 0;
-       pRaInfo->PTActive = 1;   /*  Active when this STA is use */
-       pRaInfo->PTTryState = 0;
-       pRaInfo->PTStage = 5; /*  Need to fill into HW_PWR_STATUS */
-       pRaInfo->PTSmoothFactor = 192;
-       pRaInfo->PTStopCount = 0;
-       pRaInfo->PTPreRate = 0;
-       pRaInfo->PTPreRssi = 0;
-       pRaInfo->PTModeSS = 0;
-       pRaInfo->RAstage = 0;
-       return 0;
-}
-
-int ODM_RAInfo_Init_all(struct odm_dm_struct *dm_odm)
-{
-       u8 macid = 0;
-
-       dm_odm->CurrminRptTime = 0;
-
-       for (macid = 0; macid < ODM_ASSOCIATE_ENTRY_NUM; macid++)
-               ODM_RAInfo_Init(dm_odm, macid);
-
-       return 0;
-}
-
-u8 ODM_RA_GetShortGI_8188E(struct odm_dm_struct *dm_odm, u8 macid)
-{
-       if ((NULL == dm_odm) || (macid >= ODM_ASSOCIATE_ENTRY_NUM))
-               return 0;
-       return dm_odm->RAInfo[macid].RateSGI;
-}
-
-u8 ODM_RA_GetDecisionRate_8188E(struct odm_dm_struct *dm_odm, u8 macid)
-{
-       u8 DecisionRate = 0;
-
-       if ((NULL == dm_odm) || (macid >= ODM_ASSOCIATE_ENTRY_NUM))
-               return 0;
-       DecisionRate = (dm_odm->RAInfo[macid].DecisionRate);
-       return DecisionRate;
-}
-
-u8 ODM_RA_GetHwPwrStatus_8188E(struct odm_dm_struct *dm_odm, u8 macid)
-{
-       u8 PTStage = 5;
-
-       if ((NULL == dm_odm) || (macid >= ODM_ASSOCIATE_ENTRY_NUM))
-               return 0;
-       PTStage = (dm_odm->RAInfo[macid].PTStage);
-       return PTStage;
-}
-
-void ODM_RA_UpdateRateInfo_8188E(struct odm_dm_struct *dm_odm, u8 macid, u8 RateID, u32 RateMask, u8 SGIEnable)
-{
-       struct odm_ra_info *pRaInfo = NULL;
-
-       if ((NULL == dm_odm) || (macid >= ODM_ASSOCIATE_ENTRY_NUM))
-               return;
-
-       pRaInfo = &dm_odm->RAInfo[macid];
-       pRaInfo->RateID = RateID;
-       pRaInfo->RateMask = RateMask;
-       pRaInfo->SGIEnable = SGIEnable;
-       odm_ARFBRefresh_8188E(dm_odm, pRaInfo);
-}
-
-void ODM_RA_SetRSSI_8188E(struct odm_dm_struct *dm_odm, u8 macid, u8 Rssi)
-{
-       struct odm_ra_info *pRaInfo = NULL;
-
-       if ((NULL == dm_odm) || (macid >= ODM_ASSOCIATE_ENTRY_NUM))
-               return;
-
-       pRaInfo = &dm_odm->RAInfo[macid];
-       pRaInfo->RssiStaRA = Rssi;
-}
-
-void ODM_RA_Set_TxRPT_Time(struct odm_dm_struct *dm_odm, u16 minRptTime)
-{
-       rtw_write16(dm_odm->Adapter, REG_TX_RPT_TIME, minRptTime);
-}
-
-void ODM_RA_TxRPT2Handle_8188E(struct odm_dm_struct *dm_odm, u8 *TxRPT_Buf, u16 TxRPT_Len, u32 macid_entry0, u32 macid_entry1)
-{
-       struct odm_ra_info *pRAInfo = NULL;
-       u8 MacId = 0;
-       u8 *pBuffer = NULL;
-       u32 valid = 0, ItemNum = 0;
-       u16 minRptTime = 0x927c;
-
-       ItemNum = TxRPT_Len >> 3;
-       pBuffer = TxRPT_Buf;
-
-       do {
-               if (MacId >= ODM_ASSOCIATE_ENTRY_NUM)
-                       valid = 0;
-               else if (MacId >= 32)
-                       valid = (1 << (MacId - 32)) & macid_entry1;
-               else
-                       valid = (1 << MacId) & macid_entry0;
-
-               pRAInfo = &dm_odm->RAInfo[MacId];
-               if (valid) {
-                       pRAInfo->RTY[0] = le16_to_cpup((__le16 *)pBuffer);
-                       pRAInfo->RTY[1] = pBuffer[2];
-                       pRAInfo->RTY[2] = pBuffer[3];
-                       pRAInfo->RTY[3] = pBuffer[4];
-                       pRAInfo->RTY[4] = pBuffer[5];
-                       pRAInfo->DROP = pBuffer[6];
-                       pRAInfo->TOTAL = pRAInfo->RTY[0] + pRAInfo->RTY[1] +
-                                        pRAInfo->RTY[2] + pRAInfo->RTY[3] +
-                                        pRAInfo->RTY[4] + pRAInfo->DROP;
-                       if (pRAInfo->TOTAL != 0) {
-                               if (pRAInfo->PTActive) {
-                                       if (pRAInfo->RAstage < 5)
-                                               odm_RateDecision_8188E(dm_odm, pRAInfo);
-                                       else if (pRAInfo->RAstage == 5) /*  Power training try state */
-                                               odm_PTTryState_8188E(pRAInfo);
-                                       else /*  RAstage == 6 */
-                                               odm_PTDecision_8188E(pRAInfo);
-
-                                       /*  Stage_RA counter */
-                                       if (pRAInfo->RAstage <= 5)
-                                               pRAInfo->RAstage++;
-                                       else
-                                               pRAInfo->RAstage = 0;
-                               } else {
-                                       odm_RateDecision_8188E(dm_odm, pRAInfo);
-                               }
-                       }
-               }
-
-               if (minRptTime > pRAInfo->RptTime)
-                       minRptTime = pRAInfo->RptTime;
-
-               pBuffer += TX_RPT2_ITEM_SIZE;
-               MacId++;
-       } while (MacId < ItemNum);
-
-       odm_RATxRPTTimerSetting(dm_odm, minRptTime);
-}
diff --git a/drivers/staging/r8188eu/hal/HalHWImg8188E_BB.c b/drivers/staging/r8188eu/hal/HalHWImg8188E_BB.c
deleted file mode 100644 (file)
index 23b7205..0000000
+++ /dev/null
@@ -1,733 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#include "../include/rtw_iol.h"
-
-#define read_next_pair(array, v1, v2, i)               \
-        do {                                           \
-                i += 2;                                \
-                v1 = array[i];                         \
-                v2 = array[i + 1];                     \
-        } while (0)
-
-static bool CheckCondition(const u32  condition, const u32  hex)
-{
-       u32 _interface = (hex & 0x0000FF00) >> 8;
-       u32 _platform  = (hex & 0x00FF0000) >> 16;
-       u32 cond = condition;
-
-       if (condition == 0xCDCDCDCD)
-               return true;
-
-       cond = condition & 0x0000FF00;
-       cond = cond >> 8;
-       if ((_interface & cond) == 0 && cond != 0x07)
-               return false;
-
-       cond = condition & 0x00FF0000;
-       cond = cond >> 16;
-       if ((_platform & cond) == 0 && cond != 0x0F)
-               return false;
-       return true;
-}
-
-/******************************************************************************
-*                           AGC_TAB_1T.TXT
-******************************************************************************/
-
-static u32 array_agc_tab_1t_8188e[] = {
-               0xC78, 0xFB000001,
-               0xC78, 0xFB010001,
-               0xC78, 0xFB020001,
-               0xC78, 0xFB030001,
-               0xC78, 0xFB040001,
-               0xC78, 0xFB050001,
-               0xC78, 0xFA060001,
-               0xC78, 0xF9070001,
-               0xC78, 0xF8080001,
-               0xC78, 0xF7090001,
-               0xC78, 0xF60A0001,
-               0xC78, 0xF50B0001,
-               0xC78, 0xF40C0001,
-               0xC78, 0xF30D0001,
-               0xC78, 0xF20E0001,
-               0xC78, 0xF10F0001,
-               0xC78, 0xF0100001,
-               0xC78, 0xEF110001,
-               0xC78, 0xEE120001,
-               0xC78, 0xED130001,
-               0xC78, 0xEC140001,
-               0xC78, 0xEB150001,
-               0xC78, 0xEA160001,
-               0xC78, 0xE9170001,
-               0xC78, 0xE8180001,
-               0xC78, 0xE7190001,
-               0xC78, 0xE61A0001,
-               0xC78, 0xE51B0001,
-               0xC78, 0xE41C0001,
-               0xC78, 0xE31D0001,
-               0xC78, 0xE21E0001,
-               0xC78, 0xE11F0001,
-               0xC78, 0x8A200001,
-               0xC78, 0x89210001,
-               0xC78, 0x88220001,
-               0xC78, 0x87230001,
-               0xC78, 0x86240001,
-               0xC78, 0x85250001,
-               0xC78, 0x84260001,
-               0xC78, 0x83270001,
-               0xC78, 0x82280001,
-               0xC78, 0x6B290001,
-               0xC78, 0x6A2A0001,
-               0xC78, 0x692B0001,
-               0xC78, 0x682C0001,
-               0xC78, 0x672D0001,
-               0xC78, 0x662E0001,
-               0xC78, 0x652F0001,
-               0xC78, 0x64300001,
-               0xC78, 0x63310001,
-               0xC78, 0x62320001,
-               0xC78, 0x61330001,
-               0xC78, 0x46340001,
-               0xC78, 0x45350001,
-               0xC78, 0x44360001,
-               0xC78, 0x43370001,
-               0xC78, 0x42380001,
-               0xC78, 0x41390001,
-               0xC78, 0x403A0001,
-               0xC78, 0x403B0001,
-               0xC78, 0x403C0001,
-               0xC78, 0x403D0001,
-               0xC78, 0x403E0001,
-               0xC78, 0x403F0001,
-               0xC78, 0xFB400001,
-               0xC78, 0xFB410001,
-               0xC78, 0xFB420001,
-               0xC78, 0xFB430001,
-               0xC78, 0xFB440001,
-               0xC78, 0xFB450001,
-               0xC78, 0xFB460001,
-               0xC78, 0xFB470001,
-               0xC78, 0xFB480001,
-               0xC78, 0xFA490001,
-               0xC78, 0xF94A0001,
-               0xC78, 0xF84B0001,
-               0xC78, 0xF74C0001,
-               0xC78, 0xF64D0001,
-               0xC78, 0xF54E0001,
-               0xC78, 0xF44F0001,
-               0xC78, 0xF3500001,
-               0xC78, 0xF2510001,
-               0xC78, 0xF1520001,
-               0xC78, 0xF0530001,
-               0xC78, 0xEF540001,
-               0xC78, 0xEE550001,
-               0xC78, 0xED560001,
-               0xC78, 0xEC570001,
-               0xC78, 0xEB580001,
-               0xC78, 0xEA590001,
-               0xC78, 0xE95A0001,
-               0xC78, 0xE85B0001,
-               0xC78, 0xE75C0001,
-               0xC78, 0xE65D0001,
-               0xC78, 0xE55E0001,
-               0xC78, 0xE45F0001,
-               0xC78, 0xE3600001,
-               0xC78, 0xE2610001,
-               0xC78, 0xC3620001,
-               0xC78, 0xC2630001,
-               0xC78, 0xC1640001,
-               0xC78, 0x8B650001,
-               0xC78, 0x8A660001,
-               0xC78, 0x89670001,
-               0xC78, 0x88680001,
-               0xC78, 0x87690001,
-               0xC78, 0x866A0001,
-               0xC78, 0x856B0001,
-               0xC78, 0x846C0001,
-               0xC78, 0x676D0001,
-               0xC78, 0x666E0001,
-               0xC78, 0x656F0001,
-               0xC78, 0x64700001,
-               0xC78, 0x63710001,
-               0xC78, 0x62720001,
-               0xC78, 0x61730001,
-               0xC78, 0x60740001,
-               0xC78, 0x46750001,
-               0xC78, 0x45760001,
-               0xC78, 0x44770001,
-               0xC78, 0x43780001,
-               0xC78, 0x42790001,
-               0xC78, 0x417A0001,
-               0xC78, 0x407B0001,
-               0xC78, 0x407C0001,
-               0xC78, 0x407D0001,
-               0xC78, 0x407E0001,
-               0xC78, 0x407F0001,
-};
-
-static void odm_ConfigBB_AGC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Bitmask, u32 Data)
-{
-       rtl8188e_PHY_SetBBReg(pDM_Odm->Adapter, Addr, Bitmask, Data);
-       /*  Add 1us delay between BB/RF register setting. */
-       udelay(1);
-}
-
-int ODM_ReadAndConfig_AGC_TAB_1T_8188E(struct odm_dm_struct *dm_odm)
-{
-       u32     hex         = 0;
-       u32     i           = 0;
-       u32     arraylen    = ARRAY_SIZE(array_agc_tab_1t_8188e);
-       u32    *array       = array_agc_tab_1t_8188e;
-       bool            biol = false;
-       struct adapter *adapter =  dm_odm->Adapter;
-       struct xmit_frame *pxmit_frame = NULL;
-       u8 bndy_cnt = 1;
-
-       hex += ODM_ITRF_USB << 8;
-       hex += ODM_CE << 16;
-       hex += 0xFF000000;
-       biol = rtw_IOL_applied(adapter);
-
-       if (biol) {
-               pxmit_frame = rtw_IOL_accquire_xmit_frame(adapter);
-               if (!pxmit_frame) {
-                       pr_info("rtw_IOL_accquire_xmit_frame failed\n");
-                       return -ENOMEM;
-               }
-       }
-
-       for (i = 0; i < arraylen; i += 2) {
-               u32 v1 = array[i];
-               u32 v2 = array[i + 1];
-
-               /*  This (offset, data) pair meets the condition. */
-               if (v1 < 0xCDCDCDCD) {
-                       if (biol) {
-                               if (rtw_IOL_cmd_boundary_handle(pxmit_frame))
-                                       bndy_cnt++;
-                               rtw_IOL_append_WD_cmd(pxmit_frame, (u16)v1, v2, bMaskDWord);
-                       } else {
-                               odm_ConfigBB_AGC_8188E(dm_odm, v1, bMaskDWord, v2);
-                       }
-                       continue;
-               } else {
-                       /*  This line is the start line of branch. */
-                       if (!CheckCondition(array[i], hex)) {
-                               /*  Discard the following (offset, data) pairs. */
-                               read_next_pair(array, v1, v2, i);
-                               while (v2 != 0xDEAD &&
-                                      v2 != 0xCDEF &&
-                                      v2 != 0xCDCD && i < arraylen - 2)
-                                       read_next_pair(array, v1, v2, i);
-                               i -= 2; /*  prevent from for-loop += 2 */
-                       } else { /*  Configure matched pairs and skip to end of if-else. */
-                               read_next_pair(array, v1, v2, i);
-                               while (v2 != 0xDEAD &&
-                                      v2 != 0xCDEF &&
-                                      v2 != 0xCDCD && i < arraylen - 2) {
-                                       if (biol) {
-                                               if (rtw_IOL_cmd_boundary_handle(pxmit_frame))
-                                                       bndy_cnt++;
-                                               rtw_IOL_append_WD_cmd(pxmit_frame, (u16)v1, v2, bMaskDWord);
-                                       } else {
-                                               odm_ConfigBB_AGC_8188E(dm_odm, v1, bMaskDWord, v2);
-                                       }
-                                       read_next_pair(array, v1, v2, i);
-                               }
-
-                               while (v2 != 0xDEAD && i < arraylen - 2)
-                                       read_next_pair(array, v1, v2, i);
-                       }
-               }
-       }
-       if (biol) {
-               if (!rtl8188e_IOL_exec_cmds_sync(dm_odm->Adapter, pxmit_frame, 1000, bndy_cnt)) {
-                       printk("~~~ %s IOL_exec_cmds Failed !!!\n", __func__);
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-/******************************************************************************
-*                           PHY_REG_1T.TXT
-******************************************************************************/
-
-static u32 array_phy_reg_1t_8188e[] = {
-               0x800, 0x80040000,
-               0x804, 0x00000003,
-               0x808, 0x0000FC00,
-               0x80C, 0x0000000A,
-               0x810, 0x10001331,
-               0x814, 0x020C3D10,
-               0x818, 0x02200385,
-               0x81C, 0x00000000,
-               0x820, 0x01000100,
-               0x824, 0x00390204,
-               0x828, 0x00000000,
-               0x82C, 0x00000000,
-               0x830, 0x00000000,
-               0x834, 0x00000000,
-               0x838, 0x00000000,
-               0x83C, 0x00000000,
-               0x840, 0x00010000,
-               0x844, 0x00000000,
-               0x848, 0x00000000,
-               0x84C, 0x00000000,
-               0x850, 0x00000000,
-               0x854, 0x00000000,
-               0x858, 0x569A11A9,
-               0x85C, 0x01000014,
-               0x860, 0x66F60110,
-               0x864, 0x061F0649,
-               0x868, 0x00000000,
-               0x86C, 0x27272700,
-               0x870, 0x07000760,
-               0x874, 0x25004000,
-               0x878, 0x00000808,
-               0x87C, 0x00000000,
-               0x880, 0xB0000C1C,
-               0x884, 0x00000001,
-               0x888, 0x00000000,
-               0x88C, 0xCCC000C0,
-               0x890, 0x00000800,
-               0x894, 0xFFFFFFFE,
-               0x898, 0x40302010,
-               0x89C, 0x00706050,
-               0x900, 0x00000000,
-               0x904, 0x00000023,
-               0x908, 0x00000000,
-               0x90C, 0x81121111,
-               0x910, 0x00000002,
-               0x914, 0x00000201,
-               0xA00, 0x00D047C8,
-               0xA04, 0x80FF000C,
-               0xA08, 0x8C838300,
-               0xA0C, 0x2E7F120F,
-               0xA10, 0x9500BB78,
-               0xA14, 0x1114D028,
-               0xA18, 0x00881117,
-               0xA1C, 0x89140F00,
-               0xA20, 0x1A1B0000,
-               0xA24, 0x090E1317,
-               0xA28, 0x00000204,
-               0xA2C, 0x00D30000,
-               0xA70, 0x101FBF00,
-               0xA74, 0x00000007,
-               0xA78, 0x00000900,
-               0xA7C, 0x225B0606,
-               0xA80, 0x218075B1,
-               0xB2C, 0x80000000,
-               0xC00, 0x48071D40,
-               0xC04, 0x03A05611,
-               0xC08, 0x000000E4,
-               0xC0C, 0x6C6C6C6C,
-               0xC10, 0x08800000,
-               0xC14, 0x40000100,
-               0xC18, 0x08800000,
-               0xC1C, 0x40000100,
-               0xC20, 0x00000000,
-               0xC24, 0x00000000,
-               0xC28, 0x00000000,
-               0xC2C, 0x00000000,
-               0xC30, 0x69E9AC47,
-               0xC34, 0x469652AF,
-               0xC38, 0x49795994,
-               0xC3C, 0x0A97971C,
-               0xC40, 0x1F7C403F,
-               0xC44, 0x000100B7,
-               0xC48, 0xEC020107,
-               0xC4C, 0x007F037F,
-               0xC50, 0x69553420,
-               0xC54, 0x43BC0094,
-               0xC58, 0x00013169,
-               0xC5C, 0x00250492,
-               0xC60, 0x00000000,
-               0xC64, 0x7112848B,
-               0xC68, 0x47C00BFF,
-               0xC6C, 0x00000036,
-               0xC70, 0x2C7F000D,
-               0xC74, 0x020610DB,
-               0xC78, 0x0000001F,
-               0xC7C, 0x00B91612,
-               0xC80, 0x390000E4,
-               0xC84, 0x20F60000,
-               0xC88, 0x40000100,
-               0xC8C, 0x20200000,
-               0xC90, 0x00091521,
-               0xC94, 0x00000000,
-               0xC98, 0x00121820,
-               0xC9C, 0x00007F7F,
-               0xCA0, 0x00000000,
-               0xCA4, 0x000300A0,
-               0xCA8, 0x00000000,
-               0xCAC, 0x00000000,
-               0xCB0, 0x00000000,
-               0xCB4, 0x00000000,
-               0xCB8, 0x00000000,
-               0xCBC, 0x28000000,
-               0xCC0, 0x00000000,
-               0xCC4, 0x00000000,
-               0xCC8, 0x00000000,
-               0xCCC, 0x00000000,
-               0xCD0, 0x00000000,
-               0xCD4, 0x00000000,
-               0xCD8, 0x64B22427,
-               0xCDC, 0x00766932,
-               0xCE0, 0x00222222,
-               0xCE4, 0x00000000,
-               0xCE8, 0x37644302,
-               0xCEC, 0x2F97D40C,
-               0xD00, 0x00000740,
-               0xD04, 0x00020401,
-               0xD08, 0x0000907F,
-               0xD0C, 0x20010201,
-               0xD10, 0xA0633333,
-               0xD14, 0x3333BC43,
-               0xD18, 0x7A8F5B6F,
-               0xD2C, 0xCC979975,
-               0xD30, 0x00000000,
-               0xD34, 0x80608000,
-               0xD38, 0x00000000,
-               0xD3C, 0x00127353,
-               0xD40, 0x00000000,
-               0xD44, 0x00000000,
-               0xD48, 0x00000000,
-               0xD4C, 0x00000000,
-               0xD50, 0x6437140A,
-               0xD54, 0x00000000,
-               0xD58, 0x00000282,
-               0xD5C, 0x30032064,
-               0xD60, 0x4653DE68,
-               0xD64, 0x04518A3C,
-               0xD68, 0x00002101,
-               0xD6C, 0x2A201C16,
-               0xD70, 0x1812362E,
-               0xD74, 0x322C2220,
-               0xD78, 0x000E3C24,
-               0xE00, 0x2D2D2D2D,
-               0xE04, 0x2D2D2D2D,
-               0xE08, 0x0390272D,
-               0xE10, 0x2D2D2D2D,
-               0xE14, 0x2D2D2D2D,
-               0xE18, 0x2D2D2D2D,
-               0xE1C, 0x2D2D2D2D,
-               0xE28, 0x00000000,
-               0xE30, 0x1000DC1F,
-               0xE34, 0x10008C1F,
-               0xE38, 0x02140102,
-               0xE3C, 0x681604C2,
-               0xE40, 0x01007C00,
-               0xE44, 0x01004800,
-               0xE48, 0xFB000000,
-               0xE4C, 0x000028D1,
-               0xE50, 0x1000DC1F,
-               0xE54, 0x10008C1F,
-               0xE58, 0x02140102,
-               0xE5C, 0x28160D05,
-               0xE60, 0x00000008,
-               0xE68, 0x001B25A4,
-               0xE6C, 0x00C00014,
-               0xE70, 0x00C00014,
-               0xE74, 0x01000014,
-               0xE78, 0x01000014,
-               0xE7C, 0x01000014,
-               0xE80, 0x01000014,
-               0xE84, 0x00C00014,
-               0xE88, 0x01000014,
-               0xE8C, 0x00C00014,
-               0xED0, 0x00C00014,
-               0xED4, 0x00C00014,
-               0xED8, 0x00C00014,
-               0xEDC, 0x00000014,
-               0xEE0, 0x00000014,
-               0xEEC, 0x01C00014,
-               0xF14, 0x00000003,
-               0xF4C, 0x00000000,
-               0xF00, 0x00000300,
-};
-
-static void odm_ConfigBB_PHY_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Bitmask, u32 Data)
-{
-       if (Addr == 0xfe) {
-               msleep(50);
-       } else if (Addr == 0xfd) {
-               mdelay(5);
-       } else if (Addr == 0xfc) {
-               mdelay(1);
-       } else if (Addr == 0xfb) {
-               udelay(50);
-       } else if (Addr == 0xfa) {
-               udelay(5);
-       } else if (Addr == 0xf9) {
-               udelay(1);
-       } else {
-               if (Addr == 0xa24)
-                       pDM_Odm->RFCalibrateInfo.RegA24 = Data;
-               rtl8188e_PHY_SetBBReg(pDM_Odm->Adapter, Addr, Bitmask, Data);
-
-               /*  Add 1us delay between BB/RF register setting. */
-               udelay(1);
-       }
-}
-
-int ODM_ReadAndConfig_PHY_REG_1T_8188E(struct odm_dm_struct *dm_odm)
-{
-       u32     hex         = 0;
-       u32     i           = 0;
-       u32     arraylen    = ARRAY_SIZE(array_phy_reg_1t_8188e);
-       u32    *array       = array_phy_reg_1t_8188e;
-       bool    biol = false;
-       struct adapter *adapter =  dm_odm->Adapter;
-       struct xmit_frame *pxmit_frame = NULL;
-       u8 bndy_cnt = 1;
-       hex += ODM_ITRF_USB << 8;
-       hex += ODM_CE << 16;
-       hex += 0xFF000000;
-       biol = rtw_IOL_applied(adapter);
-
-       if (biol) {
-               pxmit_frame = rtw_IOL_accquire_xmit_frame(adapter);
-               if (!pxmit_frame) {
-                       pr_info("rtw_IOL_accquire_xmit_frame failed\n");
-                       return -ENOMEM;
-               }
-       }
-
-       for (i = 0; i < arraylen; i += 2) {
-               u32 v1 = array[i];
-               u32 v2 = array[i + 1];
-
-               /*  This (offset, data) pair meets the condition. */
-               if (v1 < 0xCDCDCDCD) {
-                       if (biol) {
-                               if (rtw_IOL_cmd_boundary_handle(pxmit_frame))
-                                       bndy_cnt++;
-                               if (v1 == 0xfe) {
-                                       rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 50);
-                               } else if (v1 == 0xfd) {
-                                       rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 5);
-                               } else if (v1 == 0xfc) {
-                                       rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 1);
-                               } else if (v1 == 0xfb) {
-                                       rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 50);
-                               } else if (v1 == 0xfa) {
-                                       rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 5);
-                               } else if (v1 == 0xf9) {
-                                       rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 1);
-                               } else {
-                                       if (v1 == 0xa24)
-                                               dm_odm->RFCalibrateInfo.RegA24 = v2;
-                                       rtw_IOL_append_WD_cmd(pxmit_frame, (u16)v1, v2, bMaskDWord);
-                               }
-                       } else {
-                               odm_ConfigBB_PHY_8188E(dm_odm, v1, bMaskDWord, v2);
-                       }
-                       continue;
-               } else { /*  This line is the start line of branch. */
-                       if (!CheckCondition(array[i], hex)) {
-                               /*  Discard the following (offset, data) pairs. */
-                               read_next_pair(array, v1, v2, i);
-                               while (v2 != 0xDEAD &&
-                                      v2 != 0xCDEF &&
-                                      v2 != 0xCDCD && i < arraylen - 2)
-                                       read_next_pair(array, v1, v2, i);
-                               i -= 2; /*  prevent from for-loop += 2 */
-                       } else { /*  Configure matched pairs and skip to end of if-else. */
-                               read_next_pair(array, v1, v2, i);
-                               while (v2 != 0xDEAD &&
-                                      v2 != 0xCDEF &&
-                                      v2 != 0xCDCD && i < arraylen - 2) {
-                                       if (biol) {
-                                               if (rtw_IOL_cmd_boundary_handle(pxmit_frame))
-                                                       bndy_cnt++;
-                                               if (v1 == 0xfe) {
-                                                       rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 50);
-                                               } else if (v1 == 0xfd) {
-                                                       rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 5);
-                                               } else if (v1 == 0xfc) {
-                                                       rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 1);
-                                               } else if (v1 == 0xfb) {
-                                                       rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 50);
-                                               } else if (v1 == 0xfa) {
-                                                       rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 5);
-                                               } else if (v1 == 0xf9) {
-                                                       rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 1);
-                                               } else {
-                                                       if (v1 == 0xa24)
-                                                               dm_odm->RFCalibrateInfo.RegA24 = v2;
-
-                                                       rtw_IOL_append_WD_cmd(pxmit_frame, (u16)v1, v2, bMaskDWord);
-                                               }
-                                       } else {
-                                               odm_ConfigBB_PHY_8188E(dm_odm, v1, bMaskDWord, v2);
-                                       }
-                                       read_next_pair(array, v1, v2, i);
-                               }
-
-                               while (v2 != 0xDEAD && i < arraylen - 2)
-                                       read_next_pair(array, v1, v2, i);
-                       }
-               }
-       }
-       if (biol) {
-               if (!rtl8188e_IOL_exec_cmds_sync(dm_odm->Adapter, pxmit_frame, 1000, bndy_cnt)) {
-                       pr_info("~~~ IOL Config %s Failed !!!\n", __func__);
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-/******************************************************************************
-*                           PHY_REG_PG.TXT
-******************************************************************************/
-
-static u32 array_phy_reg_pg_8188e[] = {
-               0xE00, 0xFFFFFFFF, 0x06070809,
-               0xE04, 0xFFFFFFFF, 0x02020405,
-               0xE08, 0x0000FF00, 0x00000006,
-               0x86C, 0xFFFFFF00, 0x00020400,
-               0xE10, 0xFFFFFFFF, 0x08090A0B,
-               0xE14, 0xFFFFFFFF, 0x01030607,
-               0xE18, 0xFFFFFFFF, 0x08090A0B,
-               0xE1C, 0xFFFFFFFF, 0x01030607,
-               0xE00, 0xFFFFFFFF, 0x00000000,
-               0xE04, 0xFFFFFFFF, 0x00000000,
-               0xE08, 0x0000FF00, 0x00000000,
-               0x86C, 0xFFFFFF00, 0x00000000,
-               0xE10, 0xFFFFFFFF, 0x00000000,
-               0xE14, 0xFFFFFFFF, 0x00000000,
-               0xE18, 0xFFFFFFFF, 0x00000000,
-               0xE1C, 0xFFFFFFFF, 0x00000000,
-               0xE00, 0xFFFFFFFF, 0x02020202,
-               0xE04, 0xFFFFFFFF, 0x00020202,
-               0xE08, 0x0000FF00, 0x00000000,
-               0x86C, 0xFFFFFF00, 0x00000000,
-               0xE10, 0xFFFFFFFF, 0x04040404,
-               0xE14, 0xFFFFFFFF, 0x00020404,
-               0xE18, 0xFFFFFFFF, 0x00000000,
-               0xE1C, 0xFFFFFFFF, 0x00000000,
-               0xE00, 0xFFFFFFFF, 0x02020202,
-               0xE04, 0xFFFFFFFF, 0x00020202,
-               0xE08, 0x0000FF00, 0x00000000,
-               0x86C, 0xFFFFFF00, 0x00000000,
-               0xE10, 0xFFFFFFFF, 0x04040404,
-               0xE14, 0xFFFFFFFF, 0x00020404,
-               0xE18, 0xFFFFFFFF, 0x00000000,
-               0xE1C, 0xFFFFFFFF, 0x00000000,
-               0xE00, 0xFFFFFFFF, 0x00000000,
-               0xE04, 0xFFFFFFFF, 0x00000000,
-               0xE08, 0x0000FF00, 0x00000000,
-               0x86C, 0xFFFFFF00, 0x00000000,
-               0xE10, 0xFFFFFFFF, 0x00000000,
-               0xE14, 0xFFFFFFFF, 0x00000000,
-               0xE18, 0xFFFFFFFF, 0x00000000,
-               0xE1C, 0xFFFFFFFF, 0x00000000,
-               0xE00, 0xFFFFFFFF, 0x02020202,
-               0xE04, 0xFFFFFFFF, 0x00020202,
-               0xE08, 0x0000FF00, 0x00000000,
-               0x86C, 0xFFFFFF00, 0x00000000,
-               0xE10, 0xFFFFFFFF, 0x04040404,
-               0xE14, 0xFFFFFFFF, 0x00020404,
-               0xE18, 0xFFFFFFFF, 0x00000000,
-               0xE1C, 0xFFFFFFFF, 0x00000000,
-               0xE00, 0xFFFFFFFF, 0x00000000,
-               0xE04, 0xFFFFFFFF, 0x00000000,
-               0xE08, 0x0000FF00, 0x00000000,
-               0x86C, 0xFFFFFF00, 0x00000000,
-               0xE10, 0xFFFFFFFF, 0x00000000,
-               0xE14, 0xFFFFFFFF, 0x00000000,
-               0xE18, 0xFFFFFFFF, 0x00000000,
-               0xE1C, 0xFFFFFFFF, 0x00000000,
-               0xE00, 0xFFFFFFFF, 0x00000000,
-               0xE04, 0xFFFFFFFF, 0x00000000,
-               0xE08, 0x0000FF00, 0x00000000,
-               0x86C, 0xFFFFFF00, 0x00000000,
-               0xE10, 0xFFFFFFFF, 0x00000000,
-               0xE14, 0xFFFFFFFF, 0x00000000,
-               0xE18, 0xFFFFFFFF, 0x00000000,
-               0xE1C, 0xFFFFFFFF, 0x00000000,
-               0xE00, 0xFFFFFFFF, 0x00000000,
-               0xE04, 0xFFFFFFFF, 0x00000000,
-               0xE08, 0x0000FF00, 0x00000000,
-               0x86C, 0xFFFFFF00, 0x00000000,
-               0xE10, 0xFFFFFFFF, 0x00000000,
-               0xE14, 0xFFFFFFFF, 0x00000000,
-               0xE18, 0xFFFFFFFF, 0x00000000,
-               0xE1C, 0xFFFFFFFF, 0x00000000,
-               0xE00, 0xFFFFFFFF, 0x00000000,
-               0xE04, 0xFFFFFFFF, 0x00000000,
-               0xE08, 0x0000FF00, 0x00000000,
-               0x86C, 0xFFFFFF00, 0x00000000,
-               0xE10, 0xFFFFFFFF, 0x00000000,
-               0xE14, 0xFFFFFFFF, 0x00000000,
-               0xE18, 0xFFFFFFFF, 0x00000000,
-               0xE1C, 0xFFFFFFFF, 0x00000000,
-               0xE00, 0xFFFFFFFF, 0x00000000,
-               0xE04, 0xFFFFFFFF, 0x00000000,
-               0xE08, 0x0000FF00, 0x00000000,
-               0x86C, 0xFFFFFF00, 0x00000000,
-               0xE10, 0xFFFFFFFF, 0x00000000,
-               0xE14, 0xFFFFFFFF, 0x00000000,
-               0xE18, 0xFFFFFFFF, 0x00000000,
-               0xE1C, 0xFFFFFFFF, 0x00000000,
-
-};
-
-static void odm_ConfigBB_PHY_REG_PG_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Bitmask,
-                                         u32 Data)
-{
-       if (Addr == 0xfe)
-               msleep(50);
-       else if (Addr == 0xfd)
-               mdelay(5);
-       else if (Addr == 0xfc)
-               mdelay(1);
-       else if (Addr == 0xfb)
-               udelay(50);
-       else if (Addr == 0xfa)
-               udelay(5);
-       else if (Addr == 0xf9)
-               udelay(1);
-       else
-               storePwrIndexDiffRateOffset(pDM_Odm->Adapter, Addr, Bitmask, Data);
-}
-
-void ODM_ReadAndConfig_PHY_REG_PG_8188E(struct odm_dm_struct *dm_odm)
-{
-       u32  hex;
-       u32  i           = 0;
-       u32  arraylen    = ARRAY_SIZE(array_phy_reg_pg_8188e);
-       u32 *array       = array_phy_reg_pg_8188e;
-
-       hex = ODM_ITRF_USB << 8;
-       hex += (ODM_CE << 16) + 0xFF000000;
-
-       for (i = 0; i < arraylen; i += 3) {
-               u32 v1 = array[i];
-               u32 v2 = array[i + 1];
-               u32 v3 = array[i + 2];
-
-               /*  this line is a line of pure_body */
-               if (v1 < 0xCDCDCDCD) {
-                       odm_ConfigBB_PHY_REG_PG_8188E(dm_odm, v1, v2, v3);
-                       continue;
-               } else { /*  this line is the start of branch */
-                       if (!CheckCondition(array[i], hex)) {
-                               /*  don't need the hw_body */
-                               i += 2; /*  skip the pair of expression */
-                               v1 = array[i];
-                               v2 = array[i + 1];
-                               v3 = array[i + 2];
-                               while (v2 != 0xDEAD) {
-                                       i += 3;
-                                       v1 = array[i];
-                                       v2 = array[i + 1];
-                                       v3 = array[i + 1];
-                               }
-                       }
-               }
-       }
-}
diff --git a/drivers/staging/r8188eu/hal/HalHWImg8188E_MAC.c b/drivers/staging/r8188eu/hal/HalHWImg8188E_MAC.c
deleted file mode 100644 (file)
index da71867..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#include "../include/rtw_iol.h"
-
-static bool Checkcondition(const u32  condition, const u32  hex)
-{
-       u32 _board     = (hex & 0x000000FF);
-       u32 _interface = (hex & 0x0000FF00) >> 8;
-       u32 _platform  = (hex & 0x00FF0000) >> 16;
-       u32 cond = condition;
-
-       if (condition == 0xCDCDCDCD)
-               return true;
-
-       cond = condition & 0x000000FF;
-       if ((_board == cond) && cond != 0x00)
-               return false;
-
-       cond = condition & 0x0000FF00;
-       cond = cond >> 8;
-       if ((_interface & cond) == 0 && cond != 0x07)
-               return false;
-
-       cond = condition & 0x00FF0000;
-       cond = cond >> 16;
-       if ((_platform & cond) == 0 && cond != 0x0F)
-               return false;
-       return true;
-}
-
-/******************************************************************************
-*                           MAC_REG.TXT
-******************************************************************************/
-
-static u32 array_MAC_REG_8188E[] = {
-               0x026, 0x00000041,
-               0x027, 0x00000035,
-               0x428, 0x0000000A,
-               0x429, 0x00000010,
-               0x430, 0x00000000,
-               0x431, 0x00000001,
-               0x432, 0x00000002,
-               0x433, 0x00000004,
-               0x434, 0x00000005,
-               0x435, 0x00000006,
-               0x436, 0x00000007,
-               0x437, 0x00000008,
-               0x438, 0x00000000,
-               0x439, 0x00000000,
-               0x43A, 0x00000001,
-               0x43B, 0x00000002,
-               0x43C, 0x00000004,
-               0x43D, 0x00000005,
-               0x43E, 0x00000006,
-               0x43F, 0x00000007,
-               0x440, 0x0000005D,
-               0x441, 0x00000001,
-               0x442, 0x00000000,
-               0x444, 0x00000015,
-               0x445, 0x000000F0,
-               0x446, 0x0000000F,
-               0x447, 0x00000000,
-               0x458, 0x00000041,
-               0x459, 0x000000A8,
-               0x45A, 0x00000072,
-               0x45B, 0x000000B9,
-               0x460, 0x00000066,
-               0x461, 0x00000066,
-               0x480, 0x00000008,
-               0x4C8, 0x000000FF,
-               0x4C9, 0x00000008,
-               0x4CC, 0x000000FF,
-               0x4CD, 0x000000FF,
-               0x4CE, 0x00000001,
-               0x4D3, 0x00000001,
-               0x500, 0x00000026,
-               0x501, 0x000000A2,
-               0x502, 0x0000002F,
-               0x503, 0x00000000,
-               0x504, 0x00000028,
-               0x505, 0x000000A3,
-               0x506, 0x0000005E,
-               0x507, 0x00000000,
-               0x508, 0x0000002B,
-               0x509, 0x000000A4,
-               0x50A, 0x0000005E,
-               0x50B, 0x00000000,
-               0x50C, 0x0000004F,
-               0x50D, 0x000000A4,
-               0x50E, 0x00000000,
-               0x50F, 0x00000000,
-               0x512, 0x0000001C,
-               0x514, 0x0000000A,
-               0x516, 0x0000000A,
-               0x525, 0x0000004F,
-               0x550, 0x00000010,
-               0x551, 0x00000010,
-               0x559, 0x00000002,
-               0x55D, 0x000000FF,
-               0x605, 0x00000030,
-               0x608, 0x0000000E,
-               0x609, 0x0000002A,
-               0x620, 0x000000FF,
-               0x621, 0x000000FF,
-               0x622, 0x000000FF,
-               0x623, 0x000000FF,
-               0x624, 0x000000FF,
-               0x625, 0x000000FF,
-               0x626, 0x000000FF,
-               0x627, 0x000000FF,
-               0x652, 0x00000020,
-               0x63C, 0x0000000A,
-               0x63D, 0x0000000A,
-               0x63E, 0x0000000E,
-               0x63F, 0x0000000E,
-               0x640, 0x00000040,
-               0x66E, 0x00000005,
-               0x700, 0x00000021,
-               0x701, 0x00000043,
-               0x702, 0x00000065,
-               0x703, 0x00000087,
-               0x708, 0x00000021,
-               0x709, 0x00000043,
-               0x70A, 0x00000065,
-               0x70B, 0x00000087,
-};
-
-static void odm_ConfigMAC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u8 Data)
-{
-       rtw_write8(pDM_Odm->Adapter, Addr, Data);
-}
-
-int ODM_ReadAndConfig_MAC_REG_8188E(struct odm_dm_struct *dm_odm)
-{
-       #define READ_NEXT_PAIR(v1, v2, i) do { i += 2; v1 = array[i]; v2 = array[i + 1]; } while (0)
-
-       u32     hex         = 0;
-       u32     i;
-       u32     array_len    = ARRAY_SIZE(array_MAC_REG_8188E);
-       u32    *array       = array_MAC_REG_8188E;
-       bool    biol = false;
-
-       struct adapter *adapt =  dm_odm->Adapter;
-       struct xmit_frame       *pxmit_frame = NULL;
-       u8 bndy_cnt = 1;
-       hex += ODM_ITRF_USB << 8;
-       hex += ODM_CE << 16;
-       hex += 0xFF000000;
-
-       biol = rtw_IOL_applied(adapt);
-
-       if (biol) {
-               pxmit_frame = rtw_IOL_accquire_xmit_frame(adapt);
-               if (!pxmit_frame) {
-                       pr_info("rtw_IOL_accquire_xmit_frame failed\n");
-                       return -ENOMEM;
-               }
-       }
-
-       for (i = 0; i < array_len; i += 2) {
-               u32 v1 = array[i];
-               u32 v2 = array[i + 1];
-
-               /*  This (offset, data) pair meets the condition. */
-               if (v1 < 0xCDCDCDCD) {
-                               if (biol) {
-                                       if (rtw_IOL_cmd_boundary_handle(pxmit_frame))
-                                               bndy_cnt++;
-                                       rtw_IOL_append_WB_cmd(pxmit_frame, (u16)v1, (u8)v2, 0xFF);
-                               } else {
-                                       odm_ConfigMAC_8188E(dm_odm, v1, (u8)v2);
-                               }
-                               continue;
-               } else { /*  This line is the start line of branch. */
-                       if (!Checkcondition(array[i], hex)) {
-                               /*  Discard the following (offset, data) pairs. */
-                               READ_NEXT_PAIR(v1, v2, i);
-                               while (v2 != 0xDEAD &&
-                                      v2 != 0xCDEF &&
-                                      v2 != 0xCDCD && i < array_len - 2) {
-                                       READ_NEXT_PAIR(v1, v2, i);
-                               }
-                               i -= 2; /*  prevent from for-loop += 2 */
-                       } else { /*  Configure matched pairs and skip to end of if-else. */
-                               READ_NEXT_PAIR(v1, v2, i);
-                               while (v2 != 0xDEAD &&
-                                      v2 != 0xCDEF &&
-                                      v2 != 0xCDCD && i < array_len - 2) {
-                                       if (biol) {
-                                               if (rtw_IOL_cmd_boundary_handle(pxmit_frame))
-                                                       bndy_cnt++;
-                                               rtw_IOL_append_WB_cmd(pxmit_frame, (u16)v1, (u8)v2, 0xFF);
-                                       } else {
-                                               odm_ConfigMAC_8188E(dm_odm, v1, (u8)v2);
-                                       }
-
-                                       READ_NEXT_PAIR(v1, v2, i);
-                               }
-                               while (v2 != 0xDEAD && i < array_len - 2)
-                                       READ_NEXT_PAIR(v1, v2, i);
-                       }
-               }
-       }
-       if (biol) {
-               if (!rtl8188e_IOL_exec_cmds_sync(dm_odm->Adapter, pxmit_frame, 1000, bndy_cnt)) {
-                       pr_info("~~~ MAC IOL_exec_cmds Failed !!!\n");
-                       return -1;
-               }
-       }
-       return 0;
-}
diff --git a/drivers/staging/r8188eu/hal/HalHWImg8188E_RF.c b/drivers/staging/r8188eu/hal/HalHWImg8188E_RF.c
deleted file mode 100644 (file)
index a4c3d3d..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#include "../include/rtw_iol.h"
-
-static bool CheckCondition(const u32  Condition, const u32  Hex)
-{
-       u32 _interface = (Hex & 0x0000FF00) >> 8;
-       u32 _platform  = (Hex & 0x00FF0000) >> 16;
-       u32 cond = Condition;
-
-       if (Condition == 0xCDCDCDCD)
-               return true;
-
-       cond = Condition & 0x0000FF00;
-       cond = cond >> 8;
-       if ((_interface & cond) == 0 && cond != 0x07)
-               return false;
-
-       cond = Condition & 0x00FF0000;
-       cond = cond >> 16;
-       if ((_platform & cond) == 0 && cond != 0x0F)
-               return false;
-       return true;
-}
-
-/******************************************************************************
-*                           RadioA_1T.TXT
-******************************************************************************/
-
-static u32 Array_RadioA_1T_8188E[] = {
-               0x000, 0x00030000,
-               0x008, 0x00084000,
-               0x018, 0x00000407,
-               0x019, 0x00000012,
-               0x01E, 0x00080009,
-               0x01F, 0x00000880,
-               0x02F, 0x0001A060,
-               0x03F, 0x00000000,
-               0x042, 0x000060C0,
-               0x057, 0x000D0000,
-               0x058, 0x000BE180,
-               0x067, 0x00001552,
-               0x083, 0x00000000,
-               0x0B0, 0x000FF8FC,
-               0x0B1, 0x00054400,
-               0x0B2, 0x000CCC19,
-               0x0B4, 0x00043003,
-               0x0B6, 0x0004953E,
-               0x0B7, 0x0001C718,
-               0x0B8, 0x000060FF,
-               0x0B9, 0x00080001,
-               0x0BA, 0x00040000,
-               0x0BB, 0x00000400,
-               0x0BF, 0x000C0000,
-               0x0C2, 0x00002400,
-               0x0C3, 0x00000009,
-               0x0C4, 0x00040C91,
-               0x0C5, 0x00099999,
-               0x0C6, 0x000000A3,
-               0x0C7, 0x00088820,
-               0x0C8, 0x00076C06,
-               0x0C9, 0x00000000,
-               0x0CA, 0x00080000,
-               0x0DF, 0x00000180,
-               0x0EF, 0x000001A0,
-               0x051, 0x0006B27D,
-               0xFF0F041F, 0xABCD,
-               0x052, 0x0007E4DD,
-               0xCDCDCDCD, 0xCDCD,
-               0x052, 0x0007E49D,
-               0xFF0F041F, 0xDEAD,
-               0x053, 0x00000073,
-               0x056, 0x00051FF3,
-               0x035, 0x00000086,
-               0x035, 0x00000186,
-               0x035, 0x00000286,
-               0x036, 0x00001C25,
-               0x036, 0x00009C25,
-               0x036, 0x00011C25,
-               0x036, 0x00019C25,
-               0x0B6, 0x00048538,
-               0x018, 0x00000C07,
-               0x05A, 0x0004BD00,
-               0x019, 0x000739D0,
-               0x034, 0x0000ADF3,
-               0x034, 0x00009DF0,
-               0x034, 0x00008DED,
-               0x034, 0x00007DEA,
-               0x034, 0x00006DE7,
-               0x034, 0x000054EE,
-               0x034, 0x000044EB,
-               0x034, 0x000034E8,
-               0x034, 0x0000246B,
-               0x034, 0x00001468,
-               0x034, 0x0000006D,
-               0x000, 0x00030159,
-               0x084, 0x00068200,
-               0x086, 0x000000CE,
-               0x087, 0x00048A00,
-               0x08E, 0x00065540,
-               0x08F, 0x00088000,
-               0x0EF, 0x000020A0,
-               0x03B, 0x000F02B0,
-               0x03B, 0x000EF7B0,
-               0x03B, 0x000D4FB0,
-               0x03B, 0x000CF060,
-               0x03B, 0x000B0090,
-               0x03B, 0x000A0080,
-               0x03B, 0x00090080,
-               0x03B, 0x0008F780,
-               0x03B, 0x000722B0,
-               0x03B, 0x0006F7B0,
-               0x03B, 0x00054FB0,
-               0x03B, 0x0004F060,
-               0x03B, 0x00030090,
-               0x03B, 0x00020080,
-               0x03B, 0x00010080,
-               0x03B, 0x0000F780,
-               0x0EF, 0x000000A0,
-               0x000, 0x00010159,
-               0x018, 0x0000F407,
-               0xFFE, 0x00000000,
-               0xFFE, 0x00000000,
-               0x01F, 0x00080003,
-               0xFFE, 0x00000000,
-               0xFFE, 0x00000000,
-               0x01E, 0x00000001,
-               0x01F, 0x00080000,
-               0x000, 0x00033E60,
-};
-
-static void odm_ConfigRFReg_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr,
-                                 u32 Data, u32 RegAddr)
-{
-       if (Addr == 0xffe) {
-               msleep(50);
-       } else if (Addr == 0xfd) {
-               mdelay(5);
-       } else if (Addr == 0xfc) {
-               mdelay(1);
-       } else if (Addr == 0xfb) {
-               udelay(50);
-       } else if (Addr == 0xfa) {
-               udelay(5);
-       } else if (Addr == 0xf9) {
-               udelay(1);
-       } else {
-               rtl8188e_PHY_SetRFReg(pDM_Odm->Adapter, RegAddr, bRFRegOffsetMask, Data);
-               /*  Add 1us delay between BB/RF register setting. */
-               udelay(1);
-       }
-}
-
-static void odm_ConfigRF_RadioA_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Data)
-{
-       u32  content = 0x1000; /*  RF_Content: radioa_txt */
-       u32 maskforPhySet = (u32)(content & 0xE000);
-
-       odm_ConfigRFReg_8188E(pDM_Odm, Addr, Data, Addr | maskforPhySet);
-}
-
-int ODM_ReadAndConfig_RadioA_1T_8188E(struct odm_dm_struct *pDM_Odm)
-{
-       #define READ_NEXT_PAIR(v1, v2, i) do    \
-                { i += 2; v1 = Array[i];       \
-                v2 = Array[i + 1]; } while (0)
-
-       u32     hex         = 0;
-       u32     i           = 0;
-       u32     ArrayLen    = ARRAY_SIZE(Array_RadioA_1T_8188E);
-       u32    *Array       = Array_RadioA_1T_8188E;
-       bool            biol = false;
-       struct adapter *Adapter =  pDM_Odm->Adapter;
-       struct xmit_frame *pxmit_frame = NULL;
-       u8 bndy_cnt = 1;
-
-       hex += ODM_ITRF_USB << 8;
-       hex += ODM_CE << 16;
-       hex += 0xFF000000;
-       biol = rtw_IOL_applied(Adapter);
-
-       if (biol) {
-               pxmit_frame = rtw_IOL_accquire_xmit_frame(Adapter);
-               if (!pxmit_frame) {
-                       pr_info("rtw_IOL_accquire_xmit_frame failed\n");
-                       return -ENOMEM;
-               }
-       }
-
-       for (i = 0; i < ArrayLen; i += 2) {
-               u32 v1 = Array[i];
-               u32 v2 = Array[i + 1];
-
-               /*  This (offset, data) pair meets the condition. */
-               if (v1 < 0xCDCDCDCD) {
-                       if (biol) {
-                               if (rtw_IOL_cmd_boundary_handle(pxmit_frame))
-                                       bndy_cnt++;
-
-                               if (v1 == 0xffe)
-                                       rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 50);
-                               else if (v1 == 0xfd)
-                                       rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 5);
-                               else if (v1 == 0xfc)
-                                       rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 1);
-                               else if (v1 == 0xfb)
-                                       rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 50);
-                               else if (v1 == 0xfa)
-                                       rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 5);
-                               else if (v1 == 0xf9)
-                                       rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 1);
-                               else
-                                       rtw_IOL_append_WRF_cmd(pxmit_frame, RF_PATH_A, (u16)v1, v2, bRFRegOffsetMask);
-                       } else {
-                               odm_ConfigRF_RadioA_8188E(pDM_Odm, v1, v2);
-                       }
-                       continue;
-               } else { /*  This line is the start line of branch. */
-                       if (!CheckCondition(Array[i], hex)) {
-                               /*  Discard the following (offset, data) pairs. */
-                               READ_NEXT_PAIR(v1, v2, i);
-                               while (v2 != 0xDEAD &&
-                                      v2 != 0xCDEF &&
-                                      v2 != 0xCDCD && i < ArrayLen - 2)
-                                       READ_NEXT_PAIR(v1, v2, i);
-                               i -= 2; /*  prevent from for-loop += 2 */
-                       } else { /*  Configure matched pairs and skip to end of if-else. */
-                       READ_NEXT_PAIR(v1, v2, i);
-                               while (v2 != 0xDEAD &&
-                                      v2 != 0xCDEF &&
-                                      v2 != 0xCDCD && i < ArrayLen - 2) {
-                                       if (biol) {
-                                               if (rtw_IOL_cmd_boundary_handle(pxmit_frame))
-                                                       bndy_cnt++;
-
-                                               if (v1 == 0xffe)
-                                                       rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 50);
-                                               else if (v1 == 0xfd)
-                                                       rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 5);
-                                               else if (v1 == 0xfc)
-                                                       rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 1);
-                                               else if (v1 == 0xfb)
-                                                       rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 50);
-                                               else if (v1 == 0xfa)
-                                                       rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 5);
-                                               else if (v1 == 0xf9)
-                                                       rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 1);
-                                               else
-                                                       rtw_IOL_append_WRF_cmd(pxmit_frame, RF_PATH_A, (u16)v1, v2, bRFRegOffsetMask);
-                                       } else {
-                                               odm_ConfigRF_RadioA_8188E(pDM_Odm, v1, v2);
-                                       }
-                                       READ_NEXT_PAIR(v1, v2, i);
-                               }
-
-                               while (v2 != 0xDEAD && i < ArrayLen - 2)
-                                       READ_NEXT_PAIR(v1, v2, i);
-                       }
-               }
-       }
-       if (biol) {
-               if (!rtl8188e_IOL_exec_cmds_sync(pDM_Odm->Adapter, pxmit_frame, 1000, bndy_cnt)) {
-                       pr_info("~~~ IOL Config %s Failed !!!\n", __func__);
-                       return -1;
-               }
-       }
-       return 0;
-}
diff --git a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
deleted file mode 100644 (file)
index 26e710e..0000000
+++ /dev/null
@@ -1,900 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#include "../include/drv_types.h"
-
-/*---------------------------Define Local Constant---------------------------*/
-/*  2010/04/25 MH Define the max tx power tracking tx agc power. */
-#define                ODM_TXPWRTRACK_MAX_IDX_88E              6
-
-/*---------------------------Define Local Constant---------------------------*/
-
-/* 3============================================================ */
-/* 3 Tx Power Tracking */
-/* 3============================================================ */
-/*-----------------------------------------------------------------------------
- * Function:   ODM_TxPwrTrackAdjust88E()
- *
- * Overview:   88E we can not write 0xc80/c94/c4c/ 0xa2x. Instead of write TX agc.
- *                             No matter OFDM & CCK use the same method.
- *
- * Input:              NONE
- *
- * Output:             NONE
- *
- * Return:             NONE
- *
- * Revised History:
- *     When            Who             Remark
- *     04/23/2012      MHC             Create Version 0.
- *     04/23/2012      MHC             Adjust TX agc directly not throughput BB digital.
- *
- *---------------------------------------------------------------------------*/
-void ODM_TxPwrTrackAdjust88E(struct odm_dm_struct *dm_odm, u8 Type,/*  0 = OFDM, 1 = CCK */
-       u8 *pDirection,                 /*  1 = +(increase) 2 = -(decrease) */
-       u32 *pOutWriteVal               /*  Tx tracking CCK/OFDM BB swing index adjust */
-       )
-{
-       u8 pwr_value = 0;
-       /*  Tx power tracking BB swing table. */
-       /*  The base index = 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB */
-       if (Type == 0) {                /*  For OFDM afjust */
-               if (dm_odm->BbSwingIdxOfdm <= dm_odm->BbSwingIdxOfdmBase) {
-                       *pDirection     = 1;
-                       pwr_value               = (dm_odm->BbSwingIdxOfdmBase - dm_odm->BbSwingIdxOfdm);
-               } else {
-                       *pDirection     = 2;
-                       pwr_value               = (dm_odm->BbSwingIdxOfdm - dm_odm->BbSwingIdxOfdmBase);
-               }
-       } else if (Type == 1) { /*  For CCK adjust. */
-               if (dm_odm->BbSwingIdxCck <= dm_odm->BbSwingIdxCckBase) {
-                       *pDirection     = 1;
-                       pwr_value               = (dm_odm->BbSwingIdxCckBase - dm_odm->BbSwingIdxCck);
-               } else {
-                       *pDirection     = 2;
-                       pwr_value               = (dm_odm->BbSwingIdxCck - dm_odm->BbSwingIdxCckBase);
-               }
-       }
-
-       /*  */
-       /*  2012/04/25 MH According to Ed/Luke.Lees estimate for EVM the max tx power tracking */
-       /*  need to be less than 6 power index for 88E. */
-       /*  */
-       if (pwr_value >= ODM_TXPWRTRACK_MAX_IDX_88E && *pDirection == 1)
-               pwr_value = ODM_TXPWRTRACK_MAX_IDX_88E;
-
-       *pOutWriteVal = pwr_value | (pwr_value << 8) | (pwr_value << 16) | (pwr_value << 24);
-}      /*  ODM_TxPwrTrackAdjust88E */
-
-/*-----------------------------------------------------------------------------
- * Function:   odm_TxPwrTrackSetPwr88E()
- *
- * Overview:   88E change all channel tx power according to flag.
- *                             OFDM & CCK are all different.
- *
- * Input:              NONE
- *
- * Output:             NONE
- *
- * Return:             NONE
- *
- * Revised History:
- *     When            Who             Remark
- *     04/23/2012      MHC             Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-static void odm_TxPwrTrackSetPwr88E(struct odm_dm_struct *dm_odm)
-{
-       if (dm_odm->BbSwingFlagOfdm || dm_odm->BbSwingFlagCck) {
-               PHY_SetTxPowerLevel8188E(dm_odm->Adapter, *dm_odm->pChannel);
-               dm_odm->BbSwingFlagOfdm = false;
-               dm_odm->BbSwingFlagCck  = false;
-       }
-}      /*  odm_TxPwrTrackSetPwr88E */
-
-/* 091212 chiyokolin */
-void
-odm_TXPowerTrackingCallback_ThermalMeter_8188E(
-       struct adapter *Adapter
-       )
-{
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-       u8 ThermalValue = 0, delta, delta_LCK, delta_IQK, offset;
-       u8 ThermalValue_AVG_count = 0;
-       u32 ThermalValue_AVG = 0;
-       s32 ele_D, TempCCk;
-       s8 OFDM_index, CCK_index = 0;
-       s8 OFDM_index_old = 0, CCK_index_old = 0;
-       u32 i = 0, j = 0;
-
-       u8 OFDM_min_index = 6; /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */
-       s8 OFDM_index_mapping[2][index_mapping_NUM_88E] = {
-               {0, 0, 2, 3, 4, 4,              /* 2.4G, decrease power */
-               5, 6, 7, 7, 8, 9,
-               10, 10, 11}, /*  For lower temperature, 20120220 updated on 20120220. */
-               {0, 0, -1, -2, -3, -4,          /* 2.4G, increase power */
-               -4, -4, -4, -5, -7, -8,
-               -9, -9, -10},
-       };
-       u8 Thermal_mapping[2][index_mapping_NUM_88E] = {
-               {0, 2, 4, 6, 8, 10,             /* 2.4G, decrease power */
-               12, 14, 16, 18, 20, 22,
-               24, 26, 27},
-               {0, 2, 4, 6, 8, 10,             /* 2.4G,, increase power */
-               12, 14, 16, 18, 20, 22,
-               25, 25, 25},
-       };
-       struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
-
-       /*  2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */
-       odm_TxPwrTrackSetPwr88E(dm_odm);
-
-       /*  <Kordan> RFCalibrateInfo.RegA24 will be initialized when ODM HW configuring, but MP configures with para files. */
-       dm_odm->RFCalibrateInfo.RegA24 = 0x090e1317;
-
-       ThermalValue = (u8)rtl8188e_PHY_QueryRFReg(Adapter, RF_T_METER_88E, 0xfc00); /* 0x42: RF Reg[15:10] 88E */
-
-       if (ThermalValue) {
-               /* Query OFDM path A default setting */
-               ele_D = rtl8188e_PHY_QueryBBReg(Adapter, rOFDM0_XATxIQImbalance, bMaskDWord) & bMaskOFDM_D;
-               for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {     /* find the index */
-                       if (ele_D == (OFDMSwingTable[i] & bMaskOFDM_D)) {
-                               OFDM_index_old = (u8)i;
-                               dm_odm->BbSwingIdxOfdmBase = (u8)i;
-                               break;
-                       }
-               }
-
-               /* Query CCK default setting From 0xa24 */
-               TempCCk = dm_odm->RFCalibrateInfo.RegA24;
-
-               for (i = 0; i < CCK_TABLE_SIZE; i++) {
-                       if (memcmp((void *)&TempCCk, (void *)&cck_swing_table[i][2], 4)) {
-                               CCK_index_old = (u8)i;
-                               dm_odm->BbSwingIdxCckBase = (u8)i;
-                               break;
-                       }
-               }
-
-               if (!dm_odm->RFCalibrateInfo.ThermalValue) {
-                       dm_odm->RFCalibrateInfo.ThermalValue = pHalData->EEPROMThermalMeter;
-                       dm_odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue;
-                       dm_odm->RFCalibrateInfo.ThermalValue_IQK = ThermalValue;
-
-                       dm_odm->RFCalibrateInfo.OFDM_index = OFDM_index_old;
-                       dm_odm->RFCalibrateInfo.CCK_index = CCK_index_old;
-               }
-
-               /* calculate average thermal meter */
-               dm_odm->RFCalibrateInfo.ThermalValue_AVG[dm_odm->RFCalibrateInfo.ThermalValue_AVG_index] = ThermalValue;
-               dm_odm->RFCalibrateInfo.ThermalValue_AVG_index++;
-               if (dm_odm->RFCalibrateInfo.ThermalValue_AVG_index == AVG_THERMAL_NUM_88E)
-                       dm_odm->RFCalibrateInfo.ThermalValue_AVG_index = 0;
-
-               for (i = 0; i < AVG_THERMAL_NUM_88E; i++) {
-                       if (dm_odm->RFCalibrateInfo.ThermalValue_AVG[i]) {
-                               ThermalValue_AVG += dm_odm->RFCalibrateInfo.ThermalValue_AVG[i];
-                               ThermalValue_AVG_count++;
-                       }
-               }
-
-               if (ThermalValue_AVG_count)
-                       ThermalValue = (u8)(ThermalValue_AVG / ThermalValue_AVG_count);
-
-               if (dm_odm->RFCalibrateInfo.bReloadtxpowerindex) {
-                       delta = ThermalValue > pHalData->EEPROMThermalMeter ?
-                               (ThermalValue - pHalData->EEPROMThermalMeter) :
-                               (pHalData->EEPROMThermalMeter - ThermalValue);
-                       dm_odm->RFCalibrateInfo.bReloadtxpowerindex = false;
-                       dm_odm->RFCalibrateInfo.bDoneTxpower = false;
-               } else if (dm_odm->RFCalibrateInfo.bDoneTxpower) {
-                       delta = (ThermalValue > dm_odm->RFCalibrateInfo.ThermalValue) ?
-                               (ThermalValue - dm_odm->RFCalibrateInfo.ThermalValue) :
-                               (dm_odm->RFCalibrateInfo.ThermalValue - ThermalValue);
-               } else {
-                       delta = ThermalValue > pHalData->EEPROMThermalMeter ?
-                               (ThermalValue - pHalData->EEPROMThermalMeter) :
-                               (pHalData->EEPROMThermalMeter - ThermalValue);
-               }
-               delta_LCK = (ThermalValue > dm_odm->RFCalibrateInfo.ThermalValue_LCK) ?
-                           (ThermalValue - dm_odm->RFCalibrateInfo.ThermalValue_LCK) :
-                           (dm_odm->RFCalibrateInfo.ThermalValue_LCK - ThermalValue);
-               delta_IQK = (ThermalValue > dm_odm->RFCalibrateInfo.ThermalValue_IQK) ?
-                           (ThermalValue - dm_odm->RFCalibrateInfo.ThermalValue_IQK) :
-                           (dm_odm->RFCalibrateInfo.ThermalValue_IQK - ThermalValue);
-
-               if ((delta_LCK >= 8)) { /*  Delta temperature is equal to or larger than 20 centigrade. */
-                       dm_odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue;
-                       PHY_LCCalibrate_8188E(Adapter);
-               }
-
-               if (delta > 0 && dm_odm->RFCalibrateInfo.TxPowerTrackControl) {
-                       delta = ThermalValue > pHalData->EEPROMThermalMeter ?
-                               (ThermalValue - pHalData->EEPROMThermalMeter) :
-                               (pHalData->EEPROMThermalMeter - ThermalValue);
-                       /* calculate new OFDM / CCK offset */
-                       if (ThermalValue > pHalData->EEPROMThermalMeter)
-                               j = 1;
-                       else
-                               j = 0;
-                       for (offset = 0; offset < index_mapping_NUM_88E; offset++) {
-                               if (delta < Thermal_mapping[j][offset]) {
-                                       if (offset != 0)
-                                               offset--;
-                                       break;
-                               }
-                       }
-                       if (offset >= index_mapping_NUM_88E)
-                               offset = index_mapping_NUM_88E - 1;
-                       OFDM_index = dm_odm->RFCalibrateInfo.OFDM_index + OFDM_index_mapping[j][offset];
-                       CCK_index = dm_odm->RFCalibrateInfo.CCK_index + OFDM_index_mapping[j][offset];
-
-                       if (OFDM_index > OFDM_TABLE_SIZE_92D - 1)
-                               OFDM_index = OFDM_TABLE_SIZE_92D - 1;
-                       else if (OFDM_index < OFDM_min_index)
-                               OFDM_index = OFDM_min_index;
-
-                       if (CCK_index > CCK_TABLE_SIZE - 1)
-                               CCK_index = CCK_TABLE_SIZE - 1;
-                       else if (CCK_index < 0)
-                               CCK_index = 0;
-
-                       /* 2 temporarily remove bNOPG */
-                       /* Config by SwingTable */
-                       if (dm_odm->RFCalibrateInfo.TxPowerTrackControl) {
-                               dm_odm->RFCalibrateInfo.bDoneTxpower = true;
-
-                               /*  Revse TX power table. */
-                               dm_odm->BbSwingIdxOfdm          = (u8)OFDM_index;
-                               dm_odm->BbSwingIdxCck           = (u8)CCK_index;
-
-                               if (dm_odm->BbSwingIdxOfdmCurrent != dm_odm->BbSwingIdxOfdm) {
-                                       dm_odm->BbSwingIdxOfdmCurrent = dm_odm->BbSwingIdxOfdm;
-                                       dm_odm->BbSwingFlagOfdm = true;
-                               }
-
-                               if (dm_odm->BbSwingIdxCckCurrent != dm_odm->BbSwingIdxCck) {
-                                       dm_odm->BbSwingIdxCckCurrent = dm_odm->BbSwingIdxCck;
-                                       dm_odm->BbSwingFlagCck = true;
-                               }
-                       }
-               }
-
-               if (delta_IQK >= 8) { /*  Delta temperature is equal to or larger than 20 centigrade. */
-                       dm_odm->RFCalibrateInfo.ThermalValue_IQK = ThermalValue;
-                       PHY_IQCalibrate_8188E(Adapter, false);
-               }
-               /* update thermal meter value */
-               if (dm_odm->RFCalibrateInfo.TxPowerTrackControl)
-                       dm_odm->RFCalibrateInfo.ThermalValue = ThermalValue;
-       }
-}
-
-/* 1 7.        IQK */
-#define MAX_TOLERANCE          5
-#define IQK_DELAY_TIME         1               /* ms */
-
-static u8 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
-phy_PathA_IQK_8188E(struct adapter *adapt)
-{
-       u32 regeac, regE94, regE9C;
-       u8 result = 0x00;
-
-       /* 1 Tx IQK */
-       /* path-A IQK setting */
-       rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c);
-       rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c);
-       rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x8214032a);
-       rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160000);
-
-       /* LO calibration setting */
-       rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x00462911);
-
-       /* One shot, path A LOK & IQK */
-       rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
-       rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
-
-       /*  delay x ms */
-       /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */
-       mdelay(IQK_DELAY_TIME_88E);
-
-       /*  Check failed */
-       regeac = rtl8188e_PHY_QueryBBReg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
-       regE94 = rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
-       regE9C = rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
-
-       if (!(regeac & BIT(28)) &&
-           (((regE94 & 0x03FF0000) >> 16) != 0x142) &&
-           (((regE9C & 0x03FF0000) >> 16) != 0x42))
-               result |= 0x01;
-       return result;
-}
-
-static u8 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
-phy_PathA_RxIQK(struct adapter *adapt)
-{
-       u32 regeac, regE94, regE9C, regEA4, u4tmp;
-       u8 result = 0x00;
-
-       /* 1 Get TXIMR setting */
-       /* modify RXIQK mode table */
-       rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
-       rtl8188e_PHY_SetRFReg(adapt, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
-       rtl8188e_PHY_SetRFReg(adapt, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
-       rtl8188e_PHY_SetRFReg(adapt, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
-       rtl8188e_PHY_SetRFReg(adapt, RF_TXPA_G2, bRFRegOffsetMask, 0xf117B);
-
-       /* PA,PAD off */
-       rtl8188e_PHY_SetRFReg(adapt, 0xdf, bRFRegOffsetMask, 0x980);
-       rtl8188e_PHY_SetRFReg(adapt, 0x56, bRFRegOffsetMask, 0x51000);
-
-       rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
-
-       /* IQK setting */
-       rtl8188e_PHY_SetBBReg(adapt, rTx_IQK, bMaskDWord, 0x01007c00);
-       rtl8188e_PHY_SetBBReg(adapt, rRx_IQK, bMaskDWord, 0x81004800);
-
-       /* path-A IQK setting */
-       rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c);
-       rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c);
-       rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f);
-       rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160000);
-
-       /* LO calibration setting */
-       rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
-
-       /* One shot, path A LOK & IQK */
-       rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
-       rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
-
-       /*  delay x ms */
-       mdelay(IQK_DELAY_TIME_88E);
-
-       /*  Check failed */
-       regeac = rtl8188e_PHY_QueryBBReg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
-       regE94 = rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
-       regE9C = rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
-
-       if (!(regeac & BIT(28)) &&
-           (((regE94 & 0x03FF0000) >> 16) != 0x142) &&
-           (((regE9C & 0x03FF0000) >> 16) != 0x42))
-               result |= 0x01;
-       else                                                    /* if Tx not OK, ignore Rx */
-               return result;
-
-       u4tmp = 0x80007C00 | (regE94 & 0x3FF0000)  | ((regE9C & 0x3FF0000) >> 16);
-       rtl8188e_PHY_SetBBReg(adapt, rTx_IQK, bMaskDWord, u4tmp);
-
-       /* 1 RX IQK */
-       /* modify RXIQK mode table */
-       rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
-       rtl8188e_PHY_SetRFReg(adapt, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
-       rtl8188e_PHY_SetRFReg(adapt, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
-       rtl8188e_PHY_SetRFReg(adapt, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
-       rtl8188e_PHY_SetRFReg(adapt, RF_TXPA_G2, bRFRegOffsetMask, 0xf7ffa);
-       rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
-
-       /* IQK setting */
-       rtl8188e_PHY_SetBBReg(adapt, rRx_IQK, bMaskDWord, 0x01004800);
-
-       /* path-A IQK setting */
-       rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
-       rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
-       rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c05);
-       rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160c1f);
-
-       /* LO calibration setting */
-       rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
-
-       /* One shot, path A LOK & IQK */
-       rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
-       rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
-
-       /*  delay x ms */
-       /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */
-       mdelay(IQK_DELAY_TIME_88E);
-
-       /*  Check failed */
-       regeac = rtl8188e_PHY_QueryBBReg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
-       regE94 = rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
-       regE9C = rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
-       regEA4 = rtl8188e_PHY_QueryBBReg(adapt, rRx_Power_Before_IQK_A_2, bMaskDWord);
-
-       /* reload RF 0xdf */
-       rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
-       rtl8188e_PHY_SetRFReg(adapt, 0xdf, bRFRegOffsetMask, 0x180);
-
-       if (!(regeac & BIT(27)) &&              /* if Tx is OK, check whether Rx is OK */
-           (((regEA4 & 0x03FF0000) >> 16) != 0x132) &&
-           (((regeac & 0x03FF0000) >> 16) != 0x36))
-               result |= 0x02;
-
-       return result;
-}
-
-static void patha_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8], u8 final_candidate, bool txonly)
-{
-       u32 Oldval_0, X, TX0_A, reg;
-       s32 Y, TX0_C;
-
-       if (final_candidate == 0xFF) {
-               return;
-       } else if (iqkok) {
-               Oldval_0 = (rtl8188e_PHY_QueryBBReg(adapt, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
-
-               X = result[final_candidate][0];
-               if ((X & 0x00000200) != 0)
-                       X = X | 0xFFFFFC00;
-               TX0_A = (X * Oldval_0) >> 8;
-               rtl8188e_PHY_SetBBReg(adapt, rOFDM0_XATxIQImbalance, 0x3FF, TX0_A);
-
-               rtl8188e_PHY_SetBBReg(adapt, rOFDM0_ECCAThreshold, BIT(31), ((X * Oldval_0 >> 7) & 0x1));
-
-               Y = result[final_candidate][1];
-               if ((Y & 0x00000200) != 0)
-                       Y = Y | 0xFFFFFC00;
-
-               TX0_C = (Y * Oldval_0) >> 8;
-               rtl8188e_PHY_SetBBReg(adapt, rOFDM0_XCTxAFE, 0xF0000000, ((TX0_C & 0x3C0) >> 6));
-               rtl8188e_PHY_SetBBReg(adapt, rOFDM0_XATxIQImbalance, 0x003F0000, (TX0_C & 0x3F));
-
-               rtl8188e_PHY_SetBBReg(adapt, rOFDM0_ECCAThreshold, BIT(29), ((Y * Oldval_0 >> 7) & 0x1));
-
-               if (txonly)
-                       return;
-
-               reg = result[final_candidate][2];
-               rtl8188e_PHY_SetBBReg(adapt, rOFDM0_XARxIQImbalance, 0x3FF, reg);
-
-               reg = result[final_candidate][3] & 0x3F;
-               rtl8188e_PHY_SetBBReg(adapt, rOFDM0_XARxIQImbalance, 0xFC00, reg);
-
-               reg = (result[final_candidate][3] >> 6) & 0xF;
-               rtl8188e_PHY_SetBBReg(adapt, rOFDM0_RxIQExtAnta, 0xF0000000, reg);
-       }
-}
-
-void _PHY_SaveADDARegisters(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegisterNum)
-{
-       u32 i;
-
-       for (i = 0; i < RegisterNum; i++) {
-               ADDABackup[i] = rtl8188e_PHY_QueryBBReg(adapt, ADDAReg[i], bMaskDWord);
-       }
-}
-
-/* FIXME: return an error to caller */
-static void _PHY_SaveMACRegisters(
-               struct adapter *adapt,
-               u32 *MACReg,
-               u32 *MACBackup
-       )
-{
-       u32 i;
-       int res;
-
-       for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
-               u8 reg;
-
-               res = rtw_read8(adapt, MACReg[i], &reg);
-               if (res)
-                       return;
-
-               MACBackup[i] = reg;
-       }
-
-       res = rtw_read32(adapt, MACReg[i], MACBackup + i);
-       (void)res;
-}
-
-static void reload_adda_reg(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegiesterNum)
-{
-       u32 i;
-
-       for (i = 0; i < RegiesterNum; i++)
-               rtl8188e_PHY_SetBBReg(adapt, ADDAReg[i], bMaskDWord, ADDABackup[i]);
-}
-
-static void
-_PHY_ReloadMACRegisters(
-               struct adapter *adapt,
-               u32 *MACReg,
-               u32 *MACBackup
-       )
-{
-       u32 i;
-
-       for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
-               rtw_write8(adapt, MACReg[i], (u8)MACBackup[i]);
-
-       rtw_write32(adapt, MACReg[i], MACBackup[i]);
-}
-
-static void
-_PHY_PathADDAOn(
-               struct adapter *adapt,
-               u32 *ADDAReg)
-{
-       u32 i;
-
-       rtl8188e_PHY_SetBBReg(adapt, ADDAReg[0], bMaskDWord, 0x0b1b25a0);
-
-       for (i = 1; i < IQK_ADDA_REG_NUM; i++)
-               rtl8188e_PHY_SetBBReg(adapt, ADDAReg[i], bMaskDWord, 0x0bdb25a0);
-}
-
-void
-_PHY_MACSettingCalibration(
-               struct adapter *adapt,
-               u32 *MACReg,
-               u32 *MACBackup
-       )
-{
-       u32 i = 0;
-
-       rtw_write8(adapt, MACReg[i], 0x3F);
-
-       for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
-               rtw_write8(adapt, MACReg[i], (u8)(MACBackup[i] & (~BIT(3))));
-
-       rtw_write8(adapt, MACReg[i], (u8)(MACBackup[i] & (~BIT(5))));
-}
-
-static void _PHY_PIModeSwitch(
-               struct adapter *adapt,
-               bool PIMode
-       )
-{
-       u32 mode;
-
-       mode = PIMode ? 0x01000100 : 0x01000000;
-       rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XA_HSSIParameter1, bMaskDWord, mode);
-       rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XB_HSSIParameter1, bMaskDWord, mode);
-}
-
-static bool phy_SimularityCompare_8188E(
-               struct adapter *adapt,
-               s32 resulta[][8],
-               u8  c1,
-               u8  c2
-       )
-{
-       u32 i, j, diff, sim_bitmap, bound = 0;
-       u8 final_candidate[2] = {0xFF, 0xFF};   /* for path A and path B */
-       bool result = true;
-       s32 tmp1 = 0, tmp2 = 0;
-
-       bound = 4;
-       sim_bitmap = 0;
-
-       for (i = 0; i < bound; i++) {
-               if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
-                       if ((resulta[c1][i] & 0x00000200) != 0)
-                               tmp1 = resulta[c1][i] | 0xFFFFFC00;
-                       else
-                               tmp1 = resulta[c1][i];
-
-                       if ((resulta[c2][i] & 0x00000200) != 0)
-                               tmp2 = resulta[c2][i] | 0xFFFFFC00;
-                       else
-                               tmp2 = resulta[c2][i];
-               } else {
-                       tmp1 = resulta[c1][i];
-                       tmp2 = resulta[c2][i];
-               }
-
-               diff = abs(tmp1 - tmp2);
-
-               if (diff > MAX_TOLERANCE) {
-                       if ((i == 2 || i == 6) && !sim_bitmap) {
-                               if (resulta[c1][i] + resulta[c1][i + 1] == 0)
-                                       final_candidate[(i / 4)] = c2;
-                               else if (resulta[c2][i] + resulta[c2][i + 1] == 0)
-                                       final_candidate[(i / 4)] = c1;
-                               else
-                                       sim_bitmap = sim_bitmap | (1 << i);
-                       } else {
-                               sim_bitmap = sim_bitmap | (1 << i);
-                       }
-               }
-       }
-
-       if (sim_bitmap == 0) {
-               for (i = 0; i < (bound / 4); i++) {
-                       if (final_candidate[i] != 0xFF) {
-                               for (j = i * 4; j < (i + 1) * 4 - 2; j++)
-                                       resulta[3][j] = resulta[final_candidate[i]][j];
-                               result = false;
-                       }
-               }
-               return result;
-       } else {
-               if (!(sim_bitmap & 0x03)) {                /* path A TX OK */
-                       for (i = 0; i < 2; i++)
-                               resulta[3][i] = resulta[c1][i];
-               }
-               if (!(sim_bitmap & 0x0c)) {                /* path A RX OK */
-                       for (i = 2; i < 4; i++)
-                               resulta[3][i] = resulta[c1][i];
-               }
-
-               if (!(sim_bitmap & 0x30)) { /* path B TX OK */
-                       for (i = 4; i < 6; i++)
-                               resulta[3][i] = resulta[c1][i];
-               }
-
-               if (!(sim_bitmap & 0xc0)) { /* path B RX OK */
-                       for (i = 6; i < 8; i++)
-                               resulta[3][i] = resulta[c1][i];
-               }
-               return false;
-       }
-}
-
-static void phy_IQCalibrate_8188E(struct adapter *adapt, s32 result[][8], u8 t)
-{
-       struct hal_data_8188e *pHalData = &adapt->haldata;
-       struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
-       u32 i;
-       u8 PathAOK;
-       u32 ADDA_REG[IQK_ADDA_REG_NUM] = {
-                                               rFPGA0_XCD_SwitchControl, rBlue_Tooth,
-                                               rRx_Wait_CCA,   rTx_CCK_RFON,
-                                               rTx_CCK_BBON, rTx_OFDM_RFON,
-                                               rTx_OFDM_BBON, rTx_To_Rx,
-                                               rTx_To_Tx,      rRx_CCK,
-                                               rRx_OFDM,       rRx_Wait_RIFS,
-                                               rRx_TO_Rx,      rStandby,
-                                               rSleep,                         rPMPD_ANAEN };
-       u32 IQK_MAC_REG[IQK_MAC_REG_NUM] = {
-                                               REG_TXPAUSE,    REG_BCN_CTRL,
-                                               REG_BCN_CTRL_1, REG_GPIO_MUXCFG};
-
-       /* since 92C & 92D have the different define in IQK_BB_REG */
-       u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
-                                                       rOFDM0_TRxPathEnable,   rOFDM0_TRMuxPar,
-                                                       rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB,
-                                                       rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE,
-                                                       rFPGA0_XB_RFInterfaceOE, rFPGA0_RFMOD
-                                                       };
-       u32 retryCount = 2;
-       /*  Note: IQ calibration must be performed after loading */
-       /*              PHY_REG.txt , and radio_a, radio_b.txt */
-
-       if (t == 0) {
-               /*  Save ADDA parameters, turn Path A ADDA on */
-               _PHY_SaveADDARegisters(adapt, ADDA_REG, dm_odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM);
-               _PHY_SaveMACRegisters(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup);
-               _PHY_SaveADDARegisters(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
-       }
-
-       _PHY_PathADDAOn(adapt, ADDA_REG);
-       if (t == 0)
-               dm_odm->RFCalibrateInfo.bRfPiEnable = (u8)rtl8188e_PHY_QueryBBReg(adapt, rFPGA0_XA_HSSIParameter1, BIT(8));
-
-       if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
-               /*  Switch BB to PI mode to do IQ Calibration. */
-               _PHY_PIModeSwitch(adapt, true);
-       }
-
-       /* BB setting */
-       rtl8188e_PHY_SetBBReg(adapt, rFPGA0_RFMOD, BIT(24), 0x00);
-       rtl8188e_PHY_SetBBReg(adapt, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600);
-       rtl8188e_PHY_SetBBReg(adapt, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4);
-       rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000);
-
-       rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT(10), 0x01);
-       rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT(26), 0x01);
-       rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XA_RFInterfaceOE, BIT(10), 0x00);
-       rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XB_RFInterfaceOE, BIT(10), 0x00);
-
-       /* MAC settings */
-       _PHY_MACSettingCalibration(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup);
-
-       /* Page B init */
-       /* AP or IQK */
-       rtl8188e_PHY_SetBBReg(adapt, rConfig_AntA, bMaskDWord, 0x0f600000);
-
-
-       /*  IQ calibration setting */
-       rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
-       rtl8188e_PHY_SetBBReg(adapt, rTx_IQK, bMaskDWord, 0x01007c00);
-       rtl8188e_PHY_SetBBReg(adapt, rRx_IQK, bMaskDWord, 0x81004800);
-
-       for (i = 0; i < retryCount; i++) {
-               PathAOK = phy_PathA_IQK_8188E(adapt);
-               if (PathAOK == 0x01) {
-                       result[t][0] = (rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_Before_IQK_A, bMaskDWord) & 0x3FF0000) >> 16;
-                       result[t][1] = (rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_After_IQK_A, bMaskDWord) & 0x3FF0000) >> 16;
-                       break;
-               }
-       }
-
-       for (i = 0; i < retryCount; i++) {
-               PathAOK = phy_PathA_RxIQK(adapt);
-               if (PathAOK == 0x03) {
-                       result[t][2] = (rtl8188e_PHY_QueryBBReg(adapt, rRx_Power_Before_IQK_A_2, bMaskDWord) & 0x3FF0000) >> 16;
-                       result[t][3] = (rtl8188e_PHY_QueryBBReg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord) & 0x3FF0000) >> 16;
-                       break;
-               }
-       }
-
-       /* Back to BB mode, load original value */
-       rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0);
-
-       if (t != 0) {
-               if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
-                       /*  Switch back BB to SI mode after finish IQ Calibration. */
-                       _PHY_PIModeSwitch(adapt, false);
-               }
-
-               /*  Reload ADDA power saving parameters */
-               reload_adda_reg(adapt, ADDA_REG, dm_odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM);
-
-               /*  Reload MAC parameters */
-               _PHY_ReloadMACRegisters(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup);
-
-               reload_adda_reg(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
-
-               /*  Restore RX initial gain */
-               rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00032ed3);
-
-               /* load 0xe30 IQC default value */
-               rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00);
-               rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00);
-       }
-}
-
-static void phy_LCCalibrate_8188E(struct adapter *adapt)
-{
-       u8 tmpreg;
-       u32 RF_Amode = 0, LC_Cal;
-       int res;
-
-       /* Check continuous TX and Packet TX */
-       res = rtw_read8(adapt, 0xd03, &tmpreg);
-       if (res)
-               return;
-
-       if ((tmpreg & 0x70) != 0)                       /* Deal with contisuous TX case */
-               rtw_write8(adapt, 0xd03, tmpreg & 0x8F);        /* disable all continuous TX */
-       else                                                    /*  Deal with Packet TX case */
-               rtw_write8(adapt, REG_TXPAUSE, 0xFF);           /*  block all queues */
-
-       if ((tmpreg & 0x70) != 0) {
-               /* 1. Read original RF mode */
-               /* Path-A */
-               RF_Amode = rtl8188e_PHY_QueryRFReg(adapt, RF_AC, bMask12Bits);
-
-               /* 2. Set RF mode = standby mode */
-               /* Path-A */
-               rtl8188e_PHY_SetRFReg(adapt, RF_AC, bMask12Bits, (RF_Amode & 0x8FFFF) | 0x10000);
-       }
-
-       /* 3. Read RF reg18 */
-       LC_Cal = rtl8188e_PHY_QueryRFReg(adapt, RF_CHNLBW, bMask12Bits);
-
-       /* 4. Set LC calibration begin  bit15 */
-       rtl8188e_PHY_SetRFReg(adapt, RF_CHNLBW, bMask12Bits, LC_Cal | 0x08000);
-
-       msleep(100);
-
-       /* Restore original situation */
-       if ((tmpreg & 0x70) != 0) {
-               /* Deal with continuous TX case */
-               /* Path-A */
-               rtw_write8(adapt, 0xd03, tmpreg);
-               rtl8188e_PHY_SetRFReg(adapt, RF_AC, bMask12Bits, RF_Amode);
-       } else {
-               /*  Deal with Packet TX case */
-               rtw_write8(adapt, REG_TXPAUSE, 0x00);
-       }
-}
-
-void PHY_IQCalibrate_8188E(struct adapter *adapt, bool recovery)
-{
-       struct hal_data_8188e *pHalData = &adapt->haldata;
-       struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
-       s32 result[4][8];       /* last is final result */
-       u8 i, final_candidate;
-       bool pathaok;
-       s32 RegE94, RegE9C, RegEA4, RegEB4, RegEBC;
-       bool is12simular, is13simular, is23simular;
-       u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
-               rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance,
-               rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable,
-               rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance,
-               rOFDM0_XCTxAFE, rOFDM0_XDTxAFE,
-               rOFDM0_RxIQExtAnta};
-
-       if (recovery) {
-               reload_adda_reg(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
-               return;
-       }
-
-       for (i = 0; i < 8; i++) {
-               result[0][i] = 0;
-               result[1][i] = 0;
-               result[2][i] = 0;
-               if ((i == 0) || (i == 2) || (i == 4)  || (i == 6))
-                       result[3][i] = 0x100;
-               else
-                       result[3][i] = 0;
-       }
-       final_candidate = 0xff;
-       pathaok = false;
-       is12simular = false;
-       is23simular = false;
-       is13simular = false;
-
-       for (i = 0; i < 3; i++) {
-               phy_IQCalibrate_8188E(adapt, result, i);
-
-               if (i == 1) {
-                       is12simular = phy_SimularityCompare_8188E(adapt, result, 0, 1);
-                       if (is12simular) {
-                               final_candidate = 0;
-                               break;
-                       }
-               }
-
-               if (i == 2) {
-                       is13simular = phy_SimularityCompare_8188E(adapt, result, 0, 2);
-                       if (is13simular) {
-                               final_candidate = 0;
-
-                               break;
-                       }
-                       is23simular = phy_SimularityCompare_8188E(adapt, result, 1, 2);
-                       if (is23simular) {
-                               final_candidate = 1;
-                       } else {
-                               final_candidate = 3;
-                       }
-               }
-       }
-
-       for (i = 0; i < 4; i++) {
-               RegE94 = result[i][0];
-               RegE9C = result[i][1];
-               RegEA4 = result[i][2];
-               RegEB4 = result[i][4];
-               RegEBC = result[i][5];
-       }
-
-       if (final_candidate != 0xff) {
-               RegE94 = result[final_candidate][0];
-               RegE9C = result[final_candidate][1];
-               RegEA4 = result[final_candidate][2];
-               RegEB4 = result[final_candidate][4];
-               RegEBC = result[final_candidate][5];
-               dm_odm->RFCalibrateInfo.RegE94 = RegE94;
-               dm_odm->RFCalibrateInfo.RegE9C = RegE9C;
-               dm_odm->RFCalibrateInfo.RegEB4 = RegEB4;
-               dm_odm->RFCalibrateInfo.RegEBC = RegEBC;
-               pathaok = true;
-       } else {
-               dm_odm->RFCalibrateInfo.RegE94 = 0x100;
-               dm_odm->RFCalibrateInfo.RegEB4 = 0x100; /* X default value */
-               dm_odm->RFCalibrateInfo.RegE9C = 0x0;
-               dm_odm->RFCalibrateInfo.RegEBC = 0x0;   /* Y default value */
-       }
-       if (RegE94 != 0)
-               patha_fill_iqk(adapt, pathaok, result, final_candidate, (RegEA4 == 0));
-
-       _PHY_SaveADDARegisters(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
-}
-
-void PHY_LCCalibrate_8188E(struct adapter *adapt)
-{
-       u32 timeout = 2000, timecount = 0;
-       struct hal_data_8188e *pHalData = &adapt->haldata;
-       struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
-
-       while (*dm_odm->pbScanInProcess && timecount < timeout) {
-               mdelay(50);
-               timecount += 50;
-       }
-
-       phy_LCCalibrate_8188E(adapt);
-}
diff --git a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
deleted file mode 100644 (file)
index 6c0b136..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#include "../include/HalPwrSeqCmd.h"
-
-#define PWR_CMD_WRITE                  0x01
-     /*  offset: the read register offset */
-     /*  msk: the mask of the write bits */
-     /*  value: write value */
-     /*  note: driver shall implement this cmd by read & msk after write */
-
-#define PWR_CMD_POLLING                        0x02
-     /*  offset: the read register offset */
-     /*  msk: the mask of the polled value */
-     /*  value: the value to be polled, masked by the msd field. */
-     /*  note: driver shall implement this cmd by */
-     /*  do{ */
-     /*  if ( (Read(offset) & msk) == (value & msk) ) */
-     /*  break; */
-     /*  } while (not timeout); */
-
-#define PWR_CMD_DELAY                  0x03
-     /*  offset: the value to delay (in us) */
-     /*  msk: N/A */
-     /*  value: N/A */
-
-struct wl_pwr_cfg {
-       u16 offset;
-       u8 cmd:4;
-       u8 msk;
-       u8 value;
-};
-
-#define GET_PWR_CFG_OFFSET(__PWR_CMD)          __PWR_CMD.offset
-#define GET_PWR_CFG_CMD(__PWR_CMD)             __PWR_CMD.cmd
-#define GET_PWR_CFG_MASK(__PWR_CMD)            __PWR_CMD.msk
-#define GET_PWR_CFG_VALUE(__PWR_CMD)           __PWR_CMD.value
-
-static struct wl_pwr_cfg rtl8188E_power_on_flow[] = {
-       { 0x0006, PWR_CMD_POLLING, BIT(1), BIT(1) },
-       { 0x0002, PWR_CMD_WRITE, BIT(0) | BIT(1), 0 }, /* reset BB */
-       { 0x0026, PWR_CMD_WRITE, BIT(7), BIT(7) }, /* schmitt trigger */
-       { 0x0005, PWR_CMD_WRITE, BIT(7), 0 }, /* disable HWPDN (control by DRV)*/
-       { 0x0005, PWR_CMD_WRITE, BIT(4) | BIT(3), 0 }, /* disable WL suspend*/
-       { 0x0005, PWR_CMD_WRITE, BIT(0), BIT(0) },
-       { 0x0005, PWR_CMD_POLLING, BIT(0), 0 },
-       { 0x0023, PWR_CMD_WRITE, BIT(4), 0 },
-};
-
-static struct wl_pwr_cfg rtl8188E_card_disable_flow[] = {
-       { 0x001F, PWR_CMD_WRITE, 0xFF, 0 }, /* turn off RF */
-       { 0x0023, PWR_CMD_WRITE, BIT(4), BIT(4) }, /* LDO Sleep mode */
-       { 0x0005, PWR_CMD_WRITE, BIT(1), BIT(1) }, /* turn off MAC by HW state machine */
-       { 0x0005, PWR_CMD_POLLING, BIT(1), 0 },
-       { 0x0026, PWR_CMD_WRITE, BIT(7), BIT(7) }, /* schmitt trigger */
-       { 0x0005, PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3) }, /* enable WL suspend */
-       { 0x0007, PWR_CMD_WRITE, 0xFF, 0 }, /* enable bandgap mbias in suspend */
-       { 0x0041, PWR_CMD_WRITE, BIT(4), 0 }, /* Clear SIC_EN register */
-       { 0xfe10, PWR_CMD_WRITE, BIT(4), BIT(4) }, /* Set USB suspend enable local register */
-};
-
-/* This is used by driver for LPSRadioOff Procedure, not for FW LPS Step */
-static struct wl_pwr_cfg rtl8188E_enter_lps_flow[] = {
-       { 0x0522, PWR_CMD_WRITE, 0xFF, 0x7F },/* Tx Pause */
-       { 0x05F8, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
-       { 0x05F9, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
-       { 0x05FA, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
-       { 0x05FB, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
-       { 0x0002, PWR_CMD_WRITE, BIT(0), 0 }, /* CCK and OFDM are disabled, clocks are gated */
-       { 0x0002, PWR_CMD_DELAY, 0, 0 },
-       { 0x0100, PWR_CMD_WRITE, 0xFF, 0x3F }, /* Reset MAC TRX */
-       { 0x0101, PWR_CMD_WRITE, BIT(1), 0 }, /* check if removed later */
-       { 0x0553, PWR_CMD_WRITE, BIT(5), BIT(5) }, /* Respond TxOK to scheduler */
-};
-
-u8 HalPwrSeqCmdParsing(struct adapter *padapter, enum r8188eu_pwr_seq seq)
-{
-       struct wl_pwr_cfg pwrcfgcmd = {0};
-       struct wl_pwr_cfg *pwrseqcmd;
-       u8 poll_bit = false;
-       u8 idx, num_steps;
-       u8 value = 0;
-       u32 offset = 0;
-       u32 poll_count = 0; /*  polling autoload done. */
-       u32 max_poll_count = 5000;
-       int res;
-
-       switch (seq) {
-       case PWR_ON_FLOW:
-               pwrseqcmd = rtl8188E_power_on_flow;
-               num_steps = ARRAY_SIZE(rtl8188E_power_on_flow);
-               break;
-       case DISABLE_FLOW:
-               pwrseqcmd = rtl8188E_card_disable_flow;
-               num_steps = ARRAY_SIZE(rtl8188E_card_disable_flow);
-               break;
-       case LPS_ENTER_FLOW:
-               pwrseqcmd = rtl8188E_enter_lps_flow;
-               num_steps = ARRAY_SIZE(rtl8188E_enter_lps_flow);
-               break;
-       default:
-               return false;
-       }
-
-       for (idx = 0; idx < num_steps; idx++) {
-               pwrcfgcmd = pwrseqcmd[idx];
-
-               switch (GET_PWR_CFG_CMD(pwrcfgcmd)) {
-               case PWR_CMD_WRITE:
-                       offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
-
-                       /*  Read the value from system register */
-                       res = rtw_read8(padapter, offset, &value);
-                       if (res)
-                               return false;
-
-                       value &= ~(GET_PWR_CFG_MASK(pwrcfgcmd));
-                       value |= (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd));
-
-                       /*  Write the value back to system register */
-                       rtw_write8(padapter, offset, value);
-                       break;
-               case PWR_CMD_POLLING:
-                       poll_bit = false;
-                       offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
-                       do {
-                               res = rtw_read8(padapter, offset, &value);
-                               if (res)
-                                       return false;
-
-                               value &= GET_PWR_CFG_MASK(pwrcfgcmd);
-                               if (value == (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd)))
-                                       poll_bit = true;
-                               else
-                                       udelay(10);
-
-                               if (poll_count++ > max_poll_count)
-                                       return false;
-                       } while (!poll_bit);
-                       break;
-               case PWR_CMD_DELAY:
-                       udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd));
-                       break;
-               default:
-                       break;
-               }
-       }
-       return true;
-}
diff --git a/drivers/staging/r8188eu/hal/hal_com.c b/drivers/staging/r8188eu/hal/hal_com.c
deleted file mode 100644 (file)
index 33967eb..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-
-#include "../include/hal_intf.h"
-#include "../include/hal_com.h"
-#include "../include/rtl8188e_hal.h"
-
-#define _HAL_INIT_C_
-
-#define        CHAN_PLAN_HW    0x80
-
-u8 /* return the final channel plan decision */
-hal_com_get_channel_plan(struct adapter *padapter, u8 hw_channel_plan,
-                        u8 sw_channel_plan, u8 def_channel_plan,
-                        bool load_fail)
-{
-       u8 sw_cfg;
-       u8 chnlplan;
-
-       sw_cfg = true;
-       if (!load_fail) {
-               if (!rtw_is_channel_plan_valid(sw_channel_plan))
-                       sw_cfg = false;
-               if (hw_channel_plan & CHAN_PLAN_HW)
-                       sw_cfg = false;
-       }
-
-       if (sw_cfg)
-               chnlplan = sw_channel_plan;
-       else
-               chnlplan = hw_channel_plan & (~CHAN_PLAN_HW);
-
-       if (!rtw_is_channel_plan_valid(chnlplan))
-               chnlplan = def_channel_plan;
-
-       return chnlplan;
-}
-
-u8 MRateToHwRate(u8 rate)
-{
-       u8 ret = DESC_RATE1M;
-
-       switch (rate) {
-               /*  CCK and OFDM non-HT rates */
-       case IEEE80211_CCK_RATE_1MB:
-               ret = DESC_RATE1M;
-               break;
-       case IEEE80211_CCK_RATE_2MB:
-               ret = DESC_RATE2M;
-               break;
-       case IEEE80211_CCK_RATE_5MB:
-               ret = DESC_RATE5_5M;
-               break;
-       case IEEE80211_CCK_RATE_11MB:
-               ret = DESC_RATE11M;
-               break;
-       case IEEE80211_OFDM_RATE_6MB:
-               ret = DESC_RATE6M;
-               break;
-       case IEEE80211_OFDM_RATE_9MB:
-               ret = DESC_RATE9M;
-               break;
-       case IEEE80211_OFDM_RATE_12MB:
-               ret = DESC_RATE12M;
-               break;
-       case IEEE80211_OFDM_RATE_18MB:
-               ret = DESC_RATE18M;
-               break;
-       case IEEE80211_OFDM_RATE_24MB:
-               ret = DESC_RATE24M;
-               break;
-       case IEEE80211_OFDM_RATE_36MB:
-               ret = DESC_RATE36M;
-               break;
-       case IEEE80211_OFDM_RATE_48MB:
-               ret = DESC_RATE48M;
-               break;
-       case IEEE80211_OFDM_RATE_54MB:
-               ret = DESC_RATE54M;
-               break;
-       default:
-               break;
-       }
-       return ret;
-}
-
-void HalSetBrateCfg(struct adapter *adapt, u8 *brates, u16 *rate_cfg)
-{
-       u8 i, is_brate, brate;
-
-       for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
-               is_brate = brates[i] & IEEE80211_BASIC_RATE_MASK;
-               brate = brates[i] & 0x7f;
-
-               if (is_brate) {
-                       switch (brate) {
-                       case IEEE80211_CCK_RATE_1MB:
-                               *rate_cfg |= RATE_1M;
-                               break;
-                       case IEEE80211_CCK_RATE_2MB:
-                               *rate_cfg |= RATE_2M;
-                               break;
-                       case IEEE80211_CCK_RATE_5MB:
-                               *rate_cfg |= RATE_5_5M;
-                               break;
-                       case IEEE80211_CCK_RATE_11MB:
-                               *rate_cfg |= RATE_11M;
-                               break;
-                       case IEEE80211_OFDM_RATE_6MB:
-                               *rate_cfg |= RATE_6M;
-                               break;
-                       case IEEE80211_OFDM_RATE_9MB:
-                               *rate_cfg |= RATE_9M;
-                               break;
-                       case IEEE80211_OFDM_RATE_12MB:
-                               *rate_cfg |= RATE_12M;
-                               break;
-                       case IEEE80211_OFDM_RATE_18MB:
-                               *rate_cfg |= RATE_18M;
-                               break;
-                       case IEEE80211_OFDM_RATE_24MB:
-                               *rate_cfg |= RATE_24M;
-                               break;
-                       case IEEE80211_OFDM_RATE_36MB:
-                               *rate_cfg |= RATE_36M;
-                               break;
-                       case IEEE80211_OFDM_RATE_48MB:
-                               *rate_cfg |= RATE_48M;
-                               break;
-                       case IEEE80211_OFDM_RATE_54MB:
-                               *rate_cfg |= RATE_54M;
-                               break;
-                       }
-               }
-       }
-}
diff --git a/drivers/staging/r8188eu/hal/hal_intf.c b/drivers/staging/r8188eu/hal/hal_intf.c
deleted file mode 100644 (file)
index 13790e3..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-#define _HAL_INTF_C_
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/hal_intf.h"
-
-uint rtw_hal_init(struct adapter *adapt)
-{
-       adapt->hw_init_completed = false;
-
-       if (rtl8188eu_hal_init(adapt) != _SUCCESS)
-               return _FAIL;
-
-       adapt->hw_init_completed = true;
-
-       if (adapt->registrypriv.notch_filter == 1)
-               hal_notch_filter_8188e(adapt, 1);
-
-       return _SUCCESS;
-}
-
-uint rtw_hal_deinit(struct adapter *adapt)
-{
-       uint    status = _SUCCESS;
-
-       status = rtl8188eu_hal_deinit(adapt);
-
-       if (status == _SUCCESS)
-               adapt->hw_init_completed = false;
-
-       return status;
-}
-
-void rtw_hal_update_ra_mask(struct adapter *adapt, u32 mac_id, u8 rssi_level)
-{
-       struct mlme_priv *pmlmepriv = &adapt->mlmepriv;
-
-       if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
-               struct sta_info *psta = NULL;
-               struct sta_priv *pstapriv = &adapt->stapriv;
-               if (mac_id >= 2)
-                       psta = pstapriv->sta_aid[(mac_id - 1) - 1];
-               if (psta)
-                       add_RATid(adapt, psta, 0);/* todo: based on rssi_level*/
-       } else {
-               UpdateHalRAMask8188EUsb(adapt, mac_id, rssi_level);
-       }
-}
diff --git a/drivers/staging/r8188eu/hal/odm.c b/drivers/staging/r8188eu/hal/odm.c
deleted file mode 100644 (file)
index 94f9b12..0000000
+++ /dev/null
@@ -1,821 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#include "../include/drv_types.h"
-
-/* avoid to warn in FreeBSD ==> To DO modify */
-static u32 EDCAParam[HT_IOT_PEER_MAX][3] = {
-       /*  UL                  DL */
-       {0x5ea42b, 0x5ea42b, 0x5ea42b}, /* 0:unknown AP */
-       {0xa44f, 0x5ea44f, 0x5e431c}, /*  1:realtek AP */
-       {0x5ea42b, 0x5ea42b, 0x5ea42b}, /*  2:unknown AP => realtek_92SE */
-       {0x5ea32b, 0x5ea42b, 0x5e4322}, /*  3:broadcom AP */
-       {0x5ea422, 0x00a44f, 0x00a44f}, /*  4:ralink AP */
-       {0x5ea322, 0x00a630, 0x00a44f}, /*  5:atheros AP */
-       {0x5e4322, 0x5e4322, 0x5e4322},/*  6:cisco AP */
-       {0x5ea44f, 0x00a44f, 0x5ea42b}, /*  8:marvell AP */
-       {0x5ea42b, 0x5ea42b, 0x5ea42b}, /*  10:unknown AP=> 92U AP */
-       {0x5ea42b, 0xa630, 0x5e431c}, /*  11:airgocap AP */
-};
-
-/*  Global var */
-u32 OFDMSwingTable[OFDM_TABLE_SIZE_92D] = {
-       0x7f8001fe, /*  0, +6.0dB */
-       0x788001e2, /*  1, +5.5dB */
-       0x71c001c7, /*  2, +5.0dB */
-       0x6b8001ae, /*  3, +4.5dB */
-       0x65400195, /*  4, +4.0dB */
-       0x5fc0017f, /*  5, +3.5dB */
-       0x5a400169, /*  6, +3.0dB */
-       0x55400155, /*  7, +2.5dB */
-       0x50800142, /*  8, +2.0dB */
-       0x4c000130, /*  9, +1.5dB */
-       0x47c0011f, /*  10, +1.0dB */
-       0x43c0010f, /*  11, +0.5dB */
-       0x40000100, /*  12, +0dB */
-       0x3c8000f2, /*  13, -0.5dB */
-       0x390000e4, /*  14, -1.0dB */
-       0x35c000d7, /*  15, -1.5dB */
-       0x32c000cb, /*  16, -2.0dB */
-       0x300000c0, /*  17, -2.5dB */
-       0x2d4000b5, /*  18, -3.0dB */
-       0x2ac000ab, /*  19, -3.5dB */
-       0x288000a2, /*  20, -4.0dB */
-       0x26000098, /*  21, -4.5dB */
-       0x24000090, /*  22, -5.0dB */
-       0x22000088, /*  23, -5.5dB */
-       0x20000080, /*  24, -6.0dB */
-       0x1e400079, /*  25, -6.5dB */
-       0x1c800072, /*  26, -7.0dB */
-       0x1b00006c, /*  27. -7.5dB */
-       0x19800066, /*  28, -8.0dB */
-       0x18000060, /*  29, -8.5dB */
-       0x16c0005b, /*  30, -9.0dB */
-       0x15800056, /*  31, -9.5dB */
-       0x14400051, /*  32, -10.0dB */
-       0x1300004c, /*  33, -10.5dB */
-       0x12000048, /*  34, -11.0dB */
-       0x11000044, /*  35, -11.5dB */
-       0x10000040, /*  36, -12.0dB */
-       0x0f00003c,/*  37, -12.5dB */
-       0x0e400039,/*  38, -13.0dB */
-       0x0d800036,/*  39, -13.5dB */
-       0x0cc00033,/*  40, -14.0dB */
-       0x0c000030,/*  41, -14.5dB */
-       0x0b40002d,/*  42, -15.0dB */
-};
-
-u8 cck_swing_table[CCK_TABLE_SIZE][8] = {
-       {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /*  0, +0dB */
-       {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /*  1, -0.5dB */
-       {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /*  2, -1.0dB */
-       {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /*  3, -1.5dB */
-       {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /*  4, -2.0dB */
-       {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /*  5, -2.5dB */
-       {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /*  6, -3.0dB */
-       {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /*  7, -3.5dB */
-       {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /*  8, -4.0dB */
-       {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /*  9, -4.5dB */
-       {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /*  10, -5.0dB */
-       {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /*  11, -5.5dB */
-       {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /*  12, -6.0dB */
-       {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /*  13, -6.5dB */
-       {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /*  14, -7.0dB */
-       {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /*  15, -7.5dB */
-       {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /*  16, -8.0dB */
-       {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /*  17, -8.5dB */
-       {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /*  18, -9.0dB */
-       {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /*  19, -9.5dB */
-       {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /*  20, -10.0dB */
-       {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /*  21, -10.5dB */
-       {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /*  22, -11.0dB */
-       {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /*  23, -11.5dB */
-       {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /*  24, -12.0dB */
-       {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /*  25, -12.5dB */
-       {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /*  26, -13.0dB */
-       {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /*  27, -13.5dB */
-       {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /*  28, -14.0dB */
-       {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /*  29, -14.5dB */
-       {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /*  30, -15.0dB */
-       {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /*  31, -15.5dB */
-       {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}        /*  32, -16.0dB */
-};
-
-#define                RxDefaultAnt1           0x65a9
-#define        RxDefaultAnt2           0x569a
-
-static void odm_DIGInit(struct odm_dm_struct *pDM_Odm)
-{
-       struct rtw_dig *pDM_DigTable = &pDM_Odm->DM_DigTable;
-       struct adapter *adapter = pDM_Odm->Adapter;
-
-       pDM_DigTable->CurIGValue = (u8)rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_IGI_A_11N, ODM_BIT_IGI_11N);
-       pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
-       pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
-       pDM_DigTable->CurCCK_CCAThres = 0x83;
-       pDM_DigTable->ForbiddenIGI = DM_DIG_MIN_NIC;
-       pDM_DigTable->LargeFAHit = 0;
-       pDM_DigTable->Recover_cnt = 0;
-       pDM_DigTable->DIG_Dynamic_MIN_0 = DM_DIG_MIN_NIC;
-       pDM_DigTable->bMediaConnect_0 = false;
-
-       /* To Initialize pDM_Odm->bDMInitialGainEnable == false to avoid DIG error */
-       pDM_Odm->bDMInitialGainEnable = true;
-}
-
-static void odm_DIG(struct odm_dm_struct *pDM_Odm)
-{
-       struct rtw_dig *pDM_DigTable = &pDM_Odm->DM_DigTable;
-       struct false_alarm_stats *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
-       u8 DIG_Dynamic_MIN;
-       u8 DIG_MaxOfMin;
-       bool FirstConnect, FirstDisConnect;
-       u8 dm_dig_max, dm_dig_min;
-       u8 CurrentIGI = pDM_DigTable->CurIGValue;
-
-       if (*pDM_Odm->pbScanInProcess)
-               return;
-
-       /* add by Neil Chen to avoid PSD is processing */
-       if (!pDM_Odm->bDMInitialGainEnable)
-               return;
-
-       DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0;
-       FirstConnect = (pDM_Odm->bLinked) && (!pDM_DigTable->bMediaConnect_0);
-       FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0);
-
-       /* 1 Boundary Decision */
-       dm_dig_max = DM_DIG_MAX_NIC;
-       dm_dig_min = DM_DIG_MIN_NIC;
-       DIG_MaxOfMin = DM_DIG_MAX_AP;
-
-       if (pDM_Odm->bLinked) {
-               /* 2 8723A Series, offset need to be 10 */
-               /* 2 Modify DIG upper bound */
-               if ((pDM_Odm->RSSI_Min + 20) > dm_dig_max)
-                       pDM_DigTable->rx_gain_range_max = dm_dig_max;
-               else if ((pDM_Odm->RSSI_Min + 20) < dm_dig_min)
-                       pDM_DigTable->rx_gain_range_max = dm_dig_min;
-               else
-                       pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + 20;
-               /* 2 Modify DIG lower bound */
-               if (pDM_Odm->bOneEntryOnly) {
-                       if (pDM_Odm->RSSI_Min < dm_dig_min)
-                               DIG_Dynamic_MIN = dm_dig_min;
-                       else if (pDM_Odm->RSSI_Min > DIG_MaxOfMin)
-                               DIG_Dynamic_MIN = DIG_MaxOfMin;
-                       else
-                               DIG_Dynamic_MIN = pDM_Odm->RSSI_Min;
-               } else if (pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) {
-                       /* 1 Lower Bound for 88E AntDiv */
-                       if (pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV)
-                               DIG_Dynamic_MIN = (u8)pDM_DigTable->AntDiv_RSSI_max;
-               } else {
-                       DIG_Dynamic_MIN = dm_dig_min;
-               }
-       } else {
-               pDM_DigTable->rx_gain_range_max = dm_dig_max;
-               DIG_Dynamic_MIN = dm_dig_min;
-       }
-
-       /* 1 Modify DIG lower bound, deal with abnormally large false alarm */
-       if (pFalseAlmCnt->Cnt_all > 10000) {
-               if (pDM_DigTable->LargeFAHit != 3)
-                       pDM_DigTable->LargeFAHit++;
-               if (pDM_DigTable->ForbiddenIGI < CurrentIGI) {
-                       pDM_DigTable->ForbiddenIGI = CurrentIGI;
-                       pDM_DigTable->LargeFAHit = 1;
-               }
-
-               if (pDM_DigTable->LargeFAHit >= 3) {
-                       if ((pDM_DigTable->ForbiddenIGI + 1) > pDM_DigTable->rx_gain_range_max)
-                               pDM_DigTable->rx_gain_range_min = pDM_DigTable->rx_gain_range_max;
-                       else
-                               pDM_DigTable->rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 1);
-                       pDM_DigTable->Recover_cnt = 3600; /* 3600=2hr */
-               }
-
-       } else {
-               /* Recovery mechanism for IGI lower bound */
-               if (pDM_DigTable->Recover_cnt != 0) {
-                       pDM_DigTable->Recover_cnt--;
-               } else {
-                       if (pDM_DigTable->LargeFAHit < 3) {
-                               if ((pDM_DigTable->ForbiddenIGI - 1) < DIG_Dynamic_MIN) { /* DM_DIG_MIN) */
-                                       pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; /* DM_DIG_MIN; */
-                                       pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN; /* DM_DIG_MIN; */
-                               } else {
-                                       pDM_DigTable->ForbiddenIGI--;
-                                       pDM_DigTable->rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 1);
-                               }
-                       } else {
-                               pDM_DigTable->LargeFAHit = 0;
-                       }
-               }
-       }
-
-       /* 1 Adjust initial gain by false alarm */
-       if (pDM_Odm->bLinked) {
-               if (FirstConnect) {
-                       CurrentIGI = pDM_Odm->RSSI_Min;
-               } else {
-                       if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2)
-                               CurrentIGI = CurrentIGI + 4;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+2; */
-                       else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1)
-                               CurrentIGI = CurrentIGI + 2;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+1; */
-                       else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0)
-                               CurrentIGI = CurrentIGI - 2;/* pDM_DigTable->CurIGValue =pDM_DigTable->PreIGValue-1; */
-               }
-       } else {
-               if (FirstDisConnect) {
-                       CurrentIGI = pDM_DigTable->rx_gain_range_min;
-               } else {
-                       /* 2012.03.30 LukeLee: enable DIG before link but with very high thresholds */
-                       if (pFalseAlmCnt->Cnt_all > 10000)
-                               CurrentIGI = CurrentIGI + 2;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+2; */
-                       else if (pFalseAlmCnt->Cnt_all > 8000)
-                               CurrentIGI = CurrentIGI + 1;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+1; */
-                       else if (pFalseAlmCnt->Cnt_all < 500)
-                               CurrentIGI = CurrentIGI - 1;/* pDM_DigTable->CurIGValue =pDM_DigTable->PreIGValue-1; */
-               }
-       }
-       /* 1 Check initial gain by upper/lower bound */
-       if (CurrentIGI > pDM_DigTable->rx_gain_range_max)
-               CurrentIGI = pDM_DigTable->rx_gain_range_max;
-       if (CurrentIGI < pDM_DigTable->rx_gain_range_min)
-               CurrentIGI = pDM_DigTable->rx_gain_range_min;
-
-       /* 2 High power RSSI threshold */
-
-       ODM_Write_DIG(pDM_Odm, CurrentIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
-       pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked;
-       pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN;
-}
-
-static void odm_CommonInfoSelfInit(struct odm_dm_struct *pDM_Odm)
-{
-       struct adapter *adapter = pDM_Odm->Adapter;
-
-       pDM_Odm->bCckHighPower = (bool)rtl8188e_PHY_QueryBBReg(adapter, 0x824, BIT(9));
-       pDM_Odm->RFPathRxEnable = (u8)rtl8188e_PHY_QueryBBReg(adapter, 0xc04, 0x0F);
-}
-
-static void odm_CommonInfoSelfUpdate(struct odm_dm_struct *pDM_Odm)
-{
-       u8 EntryCnt = 0;
-       u8 i;
-       struct sta_info *pEntry;
-
-       if (*pDM_Odm->pBandWidth == HT_CHANNEL_WIDTH_40) {
-               if (*pDM_Odm->pSecChOffset == 1)
-                       pDM_Odm->ControlChannel = *pDM_Odm->pChannel - 2;
-               else if (*pDM_Odm->pSecChOffset == 2)
-                       pDM_Odm->ControlChannel = *pDM_Odm->pChannel + 2;
-       } else {
-               pDM_Odm->ControlChannel = *pDM_Odm->pChannel;
-       }
-
-       for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
-               pEntry = pDM_Odm->pODM_StaInfo[i];
-               if (IS_STA_VALID(pEntry))
-                       EntryCnt++;
-       }
-       if (EntryCnt == 1)
-               pDM_Odm->bOneEntryOnly = true;
-       else
-               pDM_Odm->bOneEntryOnly = false;
-}
-
-static void odm_RateAdaptiveMaskInit(struct odm_dm_struct *pDM_Odm)
-{
-       struct odm_rate_adapt *pOdmRA = &pDM_Odm->RateAdaptive;
-
-       pOdmRA->RATRState = DM_RATR_STA_INIT;
-       pOdmRA->HighRSSIThresh = 50;
-       pOdmRA->LowRSSIThresh = 20;
-}
-
-static void odm_RefreshRateAdaptiveMask(struct odm_dm_struct *pDM_Odm)
-{
-       u8 i;
-       struct adapter *pAdapter = pDM_Odm->Adapter;
-
-       if (pAdapter->bDriverStopped)
-               return;
-
-       for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
-               struct sta_info *pstat = pDM_Odm->pODM_StaInfo[i];
-
-               if (IS_STA_VALID(pstat)) {
-                       if (ODM_RAStateCheck(pDM_Odm, pstat->rssi_stat.UndecoratedSmoothedPWDB, false, &pstat->rssi_level))
-                               rtw_hal_update_ra_mask(pAdapter, i, pstat->rssi_level);
-               }
-       }
-}
-
-static void odm_DynamicBBPowerSavingInit(struct odm_dm_struct *pDM_Odm)
-{
-       struct rtl_ps *pDM_PSTable = &pDM_Odm->DM_PSTable;
-
-       pDM_PSTable->pre_rf_state = RF_MAX;
-       pDM_PSTable->cur_rf_state = RF_MAX;
-       pDM_PSTable->initialize = 0;
-}
-
-static void odm_FalseAlarmCounterStatistics(struct odm_dm_struct *pDM_Odm)
-{
-       u32 ret_value;
-       struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt;
-       struct adapter *adapter = pDM_Odm->Adapter;
-
-       /* hold ofdm counter */
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1); /* hold page C counter */
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), 1); /* hold page D counter */
-
-       ret_value = rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord);
-       FalseAlmCnt->Cnt_Fast_Fsync = (ret_value & 0xffff);
-       FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value & 0xffff0000) >> 16);
-       ret_value = rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord);
-       FalseAlmCnt->Cnt_OFDM_CCA = (ret_value & 0xffff);
-       FalseAlmCnt->Cnt_Parity_Fail = ((ret_value & 0xffff0000) >> 16);
-       ret_value = rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord);
-       FalseAlmCnt->Cnt_Rate_Illegal = (ret_value & 0xffff);
-       FalseAlmCnt->Cnt_Crc8_fail = ((ret_value & 0xffff0000) >> 16);
-       ret_value = rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord);
-       FalseAlmCnt->Cnt_Mcs_fail = (ret_value & 0xffff);
-
-       FalseAlmCnt->Cnt_Ofdm_fail = FalseAlmCnt->Cnt_Parity_Fail + FalseAlmCnt->Cnt_Rate_Illegal +
-                                    FalseAlmCnt->Cnt_Crc8_fail + FalseAlmCnt->Cnt_Mcs_fail +
-                                    FalseAlmCnt->Cnt_Fast_Fsync + FalseAlmCnt->Cnt_SB_Search_fail;
-
-       ret_value = rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_SC_CNT_11N, bMaskDWord);
-       FalseAlmCnt->Cnt_BW_LSC = (ret_value & 0xffff);
-       FalseAlmCnt->Cnt_BW_USC = ((ret_value & 0xffff0000) >> 16);
-
-       /* hold cck counter */
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_CCK_FA_RST_11N, BIT(12), 1);
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_CCK_FA_RST_11N, BIT(14), 1);
-
-       ret_value = rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_CCK_FA_LSB_11N, bMaskByte0);
-       FalseAlmCnt->Cnt_Cck_fail = ret_value;
-       ret_value = rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_CCK_FA_MSB_11N, bMaskByte3);
-       FalseAlmCnt->Cnt_Cck_fail +=  (ret_value & 0xff) << 8;
-
-       ret_value = rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_CCK_CCA_CNT_11N, bMaskDWord);
-       FalseAlmCnt->Cnt_CCK_CCA = ((ret_value & 0xFF) << 8) | ((ret_value & 0xFF00) >> 8);
-
-       FalseAlmCnt->Cnt_all = (FalseAlmCnt->Cnt_Fast_Fsync +
-                               FalseAlmCnt->Cnt_SB_Search_fail +
-                               FalseAlmCnt->Cnt_Parity_Fail +
-                               FalseAlmCnt->Cnt_Rate_Illegal +
-                               FalseAlmCnt->Cnt_Crc8_fail +
-                               FalseAlmCnt->Cnt_Mcs_fail +
-                               FalseAlmCnt->Cnt_Cck_fail);
-
-       FalseAlmCnt->Cnt_CCA_all = FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA;
-}
-
-static void odm_CCKPacketDetectionThresh(struct odm_dm_struct *pDM_Odm)
-{
-       u8 CurCCK_CCAThres;
-       struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt;
-
-       if (pDM_Odm->bLinked) {
-               if (pDM_Odm->RSSI_Min > 25) {
-                       CurCCK_CCAThres = 0xcd;
-               } else if ((pDM_Odm->RSSI_Min <= 25) && (pDM_Odm->RSSI_Min > 10)) {
-                       CurCCK_CCAThres = 0x83;
-               } else {
-                       if (FalseAlmCnt->Cnt_Cck_fail > 1000)
-                               CurCCK_CCAThres = 0x83;
-                       else
-                               CurCCK_CCAThres = 0x40;
-               }
-       } else {
-               if (FalseAlmCnt->Cnt_Cck_fail > 1000)
-                       CurCCK_CCAThres = 0x83;
-               else
-                       CurCCK_CCAThres = 0x40;
-       }
-       ODM_Write_CCK_CCA_Thres(pDM_Odm, CurCCK_CCAThres);
-}
-
-static void FindMinimumRSSI(struct adapter *pAdapter)
-{
-       struct hal_data_8188e *pHalData = &pAdapter->haldata;
-       struct dm_priv  *pdmpriv = &pHalData->dmpriv;
-       struct mlme_priv        *pmlmepriv = &pAdapter->mlmepriv;
-
-       /* 1 1.Determine the minimum RSSI */
-       if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
-           pdmpriv->EntryMinUndecoratedSmoothedPWDB == 0)
-               pdmpriv->MinUndecoratedPWDBForDM = 0;
-
-       pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB;
-}
-
-static void odm_RSSIMonitorCheck(struct odm_dm_struct *pDM_Odm)
-{
-       struct adapter *Adapter = pDM_Odm->Adapter;
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-       struct dm_priv  *pdmpriv = &pHalData->dmpriv;
-       int     i;
-       int     tmpEntryMaxPWDB = 0, tmpEntryMinPWDB = 0xff;
-       u8      sta_cnt = 0;
-       u32 PWDB_rssi[NUM_STA] = {0};/* 0~15]:MACID, [16~31]:PWDB_rssi */
-       struct sta_info *psta;
-
-       if (!(pDM_Odm->SupportAbility & ODM_BB_RSSI_MONITOR))
-               return;
-
-       if (!check_fwstate(&Adapter->mlmepriv, _FW_LINKED))
-               return;
-
-       for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
-               psta = pDM_Odm->pODM_StaInfo[i];
-               if (IS_STA_VALID(psta) &&
-                   (psta->state & WIFI_ASOC_STATE) &&
-                   !is_broadcast_ether_addr(psta->hwaddr) &&
-                   memcmp(psta->hwaddr, myid(&Adapter->eeprompriv), ETH_ALEN)) {
-                       if (psta->rssi_stat.UndecoratedSmoothedPWDB < tmpEntryMinPWDB)
-                               tmpEntryMinPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB;
-
-                       if (psta->rssi_stat.UndecoratedSmoothedPWDB > tmpEntryMaxPWDB)
-                               tmpEntryMaxPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB;
-                       if (psta->rssi_stat.UndecoratedSmoothedPWDB != (-1))
-                               PWDB_rssi[sta_cnt++] = (psta->mac_id | (psta->rssi_stat.UndecoratedSmoothedPWDB << 16));
-               }
-       }
-
-       for (i = 0; i < sta_cnt; i++) {
-               if (PWDB_rssi[i] != (0)) {
-                       if (pHalData->fw_ractrl) {
-                               /*  Report every sta's RSSI to FW */
-                       } else {
-                               ODM_RA_SetRSSI_8188E(
-                               &pHalData->odmpriv, (PWDB_rssi[i] & 0xFF), (u8)((PWDB_rssi[i] >> 16) & 0xFF));
-                       }
-               }
-       }
-
-       if (tmpEntryMinPWDB != 0xff) /*  If associated entry is found */
-               pdmpriv->EntryMinUndecoratedSmoothedPWDB = tmpEntryMinPWDB;
-       else
-               pdmpriv->EntryMinUndecoratedSmoothedPWDB = 0;
-
-       FindMinimumRSSI(Adapter);
-       pHalData->odmpriv.RSSI_Min = pdmpriv->MinUndecoratedPWDBForDM;
-}
-
-static void odm_TXPowerTrackingThermalMeterInit(struct odm_dm_struct *pDM_Odm)
-{
-       pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = true;
-}
-
-static void odm_InitHybridAntDiv(struct odm_dm_struct *pDM_Odm)
-{
-       if (!(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV))
-               return;
-
-       ODM_AntennaDiversityInit_88E(pDM_Odm);
-}
-
-static void odm_HwAntDiv(struct odm_dm_struct *pDM_Odm)
-{
-       if (!(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV))
-               return;
-
-       ODM_AntennaDiversity_88E(pDM_Odm);
-}
-
-static void ODM_EdcaTurboInit(struct odm_dm_struct *pDM_Odm)
-{
-       struct adapter *Adapter = pDM_Odm->Adapter;
-       pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false;
-       pDM_Odm->DM_EDCA_Table.bIsCurRDLState = false;
-       Adapter->recvpriv.bIsAnyNonBEPkts = false;
-}
-
-static void odm_EdcaTurboCheck(struct odm_dm_struct *pDM_Odm)
-{
-       struct adapter *Adapter = pDM_Odm->Adapter;
-       u32     trafficIndex;
-       u32     edca_param;
-       u64     cur_tx_bytes = 0;
-       u64     cur_rx_bytes = 0;
-       u8      bbtchange = false;
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-       struct xmit_priv                *pxmitpriv = &Adapter->xmitpriv;
-       struct recv_priv                *precvpriv = &Adapter->recvpriv;
-       struct registry_priv    *pregpriv = &Adapter->registrypriv;
-       struct mlme_ext_priv    *pmlmeext = &Adapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       if (pregpriv->wifi_spec == 1)
-               goto dm_CheckEdcaTurbo_EXIT;
-
-       if (pmlmeinfo->assoc_AP_vendor >=  HT_IOT_PEER_MAX)
-               goto dm_CheckEdcaTurbo_EXIT;
-
-       /*  Check if the status needs to be changed. */
-       if ((bbtchange) || (!precvpriv->bIsAnyNonBEPkts)) {
-               cur_tx_bytes = pxmitpriv->tx_bytes - pxmitpriv->last_tx_bytes;
-               cur_rx_bytes = precvpriv->rx_bytes - precvpriv->last_rx_bytes;
-
-               /* traffic, TX or RX */
-               if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_RALINK) ||
-                   (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS)) {
-                       if (cur_tx_bytes > (cur_rx_bytes << 2)) {
-                               /*  Uplink TP is present. */
-                               trafficIndex = UP_LINK;
-                       } else {
-                               /*  Balance TP is present. */
-                               trafficIndex = DOWN_LINK;
-                       }
-               } else {
-                       if (cur_rx_bytes > (cur_tx_bytes << 2)) {
-                               /*  Downlink TP is present. */
-                               trafficIndex = DOWN_LINK;
-                       } else {
-                               /*  Balance TP is present. */
-                               trafficIndex = UP_LINK;
-                       }
-               }
-
-               if ((pDM_Odm->DM_EDCA_Table.prv_traffic_idx != trafficIndex) || (!pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA)) {
-                       if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_CISCO) && (pmlmeext->cur_wireless_mode & WIRELESS_11_24N))
-                               edca_param = EDCAParam[pmlmeinfo->assoc_AP_vendor][trafficIndex];
-                       else
-                               edca_param = EDCAParam[HT_IOT_PEER_UNKNOWN][trafficIndex];
-
-                       rtw_write32(Adapter, REG_EDCA_BE_PARAM, edca_param);
-
-                       pDM_Odm->DM_EDCA_Table.prv_traffic_idx = trafficIndex;
-               }
-
-               pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = true;
-       } else {
-               /*  Turn Off EDCA turbo here. */
-               /*  Restore original EDCA according to the declaration of AP. */
-               if (pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA) {
-                       rtw_write32(Adapter, REG_EDCA_BE_PARAM, pHalData->AcParam_BE);
-                       pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false;
-               }
-       }
-
-dm_CheckEdcaTurbo_EXIT:
-       /*  Set variables for next time. */
-       precvpriv->bIsAnyNonBEPkts = false;
-       pxmitpriv->last_tx_bytes = pxmitpriv->tx_bytes;
-       precvpriv->last_rx_bytes = precvpriv->rx_bytes;
-}
-
-/*  2011/09/21 MH Add to describe different team necessary resource allocate?? */
-void ODM_DMInit(struct odm_dm_struct *pDM_Odm)
-{
-       /* 2012.05.03 Luke: For all IC series */
-       odm_CommonInfoSelfInit(pDM_Odm);
-       odm_DIGInit(pDM_Odm);
-       odm_RateAdaptiveMaskInit(pDM_Odm);
-
-       odm_DynamicBBPowerSavingInit(pDM_Odm);
-       odm_TXPowerTrackingThermalMeterInit(pDM_Odm);
-       ODM_EdcaTurboInit(pDM_Odm);
-       ODM_RAInfo_Init_all(pDM_Odm);
-       if ((pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV)   ||
-           (pDM_Odm->AntDivType == CGCS_RX_HW_ANTDIV) ||
-           (pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV))
-               odm_InitHybridAntDiv(pDM_Odm);
-}
-
-/*  2011/09/20 MH This is the entry pointer for all team to execute HW out source DM. */
-/*  You can not add any dummy function here, be care, you can only use DM structure */
-/*  to perform any new ODM_DM. */
-void ODM_DMWatchdog(struct odm_dm_struct *pDM_Odm)
-{
-       /* 2012.05.03 Luke: For all IC series */
-       odm_CommonInfoSelfUpdate(pDM_Odm);
-       odm_FalseAlarmCounterStatistics(pDM_Odm);
-       odm_RSSIMonitorCheck(pDM_Odm);
-
-       odm_DIG(pDM_Odm);
-       odm_CCKPacketDetectionThresh(pDM_Odm);
-
-       if (*pDM_Odm->pbPowerSaving)
-               return;
-
-       odm_RefreshRateAdaptiveMask(pDM_Odm);
-
-       if ((pDM_Odm->AntDivType ==  CG_TRX_HW_ANTDIV)  ||
-           (pDM_Odm->AntDivType == CGCS_RX_HW_ANTDIV)  ||
-           (pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV))
-               odm_HwAntDiv(pDM_Odm);
-
-       ODM_TXPowerTrackingCheck(pDM_Odm);
-       odm_EdcaTurboCheck(pDM_Odm);
-}
-
-/*  Init /.. Fixed HW value. Only init time. */
-void ODM_CmnInfoInit(struct odm_dm_struct *pDM_Odm, enum odm_common_info_def CmnInfo, u32 Value)
-{
-       /*  This section is used for init value */
-       switch  (CmnInfo) {
-       /*  Fixed ODM value. */
-       case    ODM_CMNINFO_MP_TEST_CHIP:
-               pDM_Odm->bIsMPChip = (u8)Value;
-               break;
-       case    ODM_CMNINFO_RF_ANTENNA_TYPE:
-               pDM_Odm->AntDivType = (u8)Value;
-               break;
-       default:
-               /* do nothing */
-               break;
-       }
-
-       /*  Tx power tracking BB swing table. */
-       /*  The base index = 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB */
-       pDM_Odm->BbSwingIdxOfdm                 = 12; /*  Set defalut value as index 12. */
-       pDM_Odm->BbSwingIdxOfdmCurrent  = 12;
-       pDM_Odm->BbSwingFlagOfdm                = false;
-}
-
-void ODM_Write_DIG(struct odm_dm_struct *pDM_Odm, u8 CurrentIGI)
-{
-       struct rtw_dig *pDM_DigTable = &pDM_Odm->DM_DigTable;
-       struct adapter *adapter = pDM_Odm->Adapter;
-
-       if (pDM_DigTable->CurIGValue != CurrentIGI) {
-               rtl8188e_PHY_SetBBReg(adapter, ODM_REG_IGI_A_11N, ODM_BIT_IGI_11N, CurrentIGI);
-               pDM_DigTable->CurIGValue = CurrentIGI;
-       }
-}
-
-void ODM_Write_CCK_CCA_Thres(struct odm_dm_struct *pDM_Odm, u8 CurCCK_CCAThres)
-{
-       struct rtw_dig *pDM_DigTable = &pDM_Odm->DM_DigTable;
-
-       if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres)           /* modify by Guo.Mingzhi 2012-01-03 */
-               rtw_write8(pDM_Odm->Adapter, ODM_REG_CCK_CCA_11N, CurCCK_CCAThres);
-       pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres;
-}
-
-void ODM_RF_Saving(struct odm_dm_struct *pDM_Odm, u8 bForceInNormal)
-{
-       struct rtl_ps *pDM_PSTable = &pDM_Odm->DM_PSTable;
-       struct adapter *adapter = pDM_Odm->Adapter;
-       u8 Rssi_Up_bound = 30;
-       u8 Rssi_Low_bound = 25;
-
-       if (pDM_PSTable->initialize == 0) {
-               pDM_PSTable->reg_874 = (rtl8188e_PHY_QueryBBReg(adapter, 0x874, bMaskDWord) & 0x1CC000) >> 14;
-               pDM_PSTable->reg_c70 = (rtl8188e_PHY_QueryBBReg(adapter, 0xc70, bMaskDWord) & BIT(3)) >> 3;
-               pDM_PSTable->reg_85c = (rtl8188e_PHY_QueryBBReg(adapter, 0x85c, bMaskDWord) & 0xFF000000) >> 24;
-               pDM_PSTable->reg_a74 = (rtl8188e_PHY_QueryBBReg(adapter, 0xa74, bMaskDWord) & 0xF000) >> 12;
-               pDM_PSTable->initialize = 1;
-       }
-
-       if (!bForceInNormal) {
-               if (pDM_Odm->RSSI_Min != 0xFF) {
-                       if (pDM_PSTable->pre_rf_state == RF_Normal) {
-                               if (pDM_Odm->RSSI_Min >= Rssi_Up_bound)
-                                       pDM_PSTable->cur_rf_state = RF_Save;
-                               else
-                                       pDM_PSTable->cur_rf_state = RF_Normal;
-                       } else {
-                               if (pDM_Odm->RSSI_Min <= Rssi_Low_bound)
-                                       pDM_PSTable->cur_rf_state = RF_Normal;
-                               else
-                                       pDM_PSTable->cur_rf_state = RF_Save;
-                       }
-               } else {
-                       pDM_PSTable->cur_rf_state = RF_MAX;
-               }
-       } else {
-               pDM_PSTable->cur_rf_state = RF_Normal;
-       }
-
-       if (pDM_PSTable->pre_rf_state != pDM_PSTable->cur_rf_state) {
-               if (pDM_PSTable->cur_rf_state == RF_Save) {
-                       rtl8188e_PHY_SetBBReg(adapter, 0x874, 0x1C0000, 0x2); /* Reg874[20:18]=3'b010 */
-                       rtl8188e_PHY_SetBBReg(adapter, 0xc70, BIT(3), 0); /* RegC70[3]=1'b0 */
-                       rtl8188e_PHY_SetBBReg(adapter, 0x85c, 0xFF000000, 0x63); /* Reg85C[31:24]=0x63 */
-                       rtl8188e_PHY_SetBBReg(adapter, 0x874, 0xC000, 0x2); /* Reg874[15:14]=2'b10 */
-                       rtl8188e_PHY_SetBBReg(adapter, 0xa74, 0xF000, 0x3); /* RegA75[7:4]=0x3 */
-                       rtl8188e_PHY_SetBBReg(adapter, 0x818, BIT(28), 0x0); /* Reg818[28]=1'b0 */
-                       rtl8188e_PHY_SetBBReg(adapter, 0x818, BIT(28), 0x1); /* Reg818[28]=1'b1 */
-               } else {
-                       rtl8188e_PHY_SetBBReg(adapter, 0x874, 0x1CC000, pDM_PSTable->reg_874);
-                       rtl8188e_PHY_SetBBReg(adapter, 0xc70, BIT(3), pDM_PSTable->reg_c70);
-                       rtl8188e_PHY_SetBBReg(adapter, 0x85c, 0xFF000000, pDM_PSTable->reg_85c);
-                       rtl8188e_PHY_SetBBReg(adapter, 0xa74, 0xF000, pDM_PSTable->reg_a74);
-                       rtl8188e_PHY_SetBBReg(adapter, 0x818, BIT(28), 0x0);
-               }
-               pDM_PSTable->pre_rf_state = pDM_PSTable->cur_rf_state;
-       }
-}
-
-u32 ODM_Get_Rate_Bitmap(struct odm_dm_struct *pDM_Odm, u32 macid, u32 ra_mask, u8 rssi_level)
-{
-       struct sta_info *pEntry;
-       u32 rate_bitmap = 0x0fffffff;
-       u8 WirelessMode;
-
-       pEntry = pDM_Odm->pODM_StaInfo[macid];
-       if (!IS_STA_VALID(pEntry))
-               return ra_mask;
-
-       WirelessMode = pEntry->wireless_mode;
-
-       switch (WirelessMode) {
-       case ODM_WM_B:
-               if (ra_mask & 0x0000000c)               /* 11M or 5.5M enable */
-                       rate_bitmap = 0x0000000d;
-               else
-                       rate_bitmap = 0x0000000f;
-               break;
-       case (ODM_WM_B | ODM_WM_G):
-               if (rssi_level == DM_RATR_STA_HIGH)
-                       rate_bitmap = 0x00000f00;
-               else if (rssi_level == DM_RATR_STA_MIDDLE)
-                       rate_bitmap = 0x00000ff0;
-               else
-                       rate_bitmap = 0x00000ff5;
-               break;
-       case (ODM_WM_B | ODM_WM_G | ODM_WM_N24G):
-               if (rssi_level == DM_RATR_STA_HIGH) {
-                       rate_bitmap = 0x000f0000;
-               } else if (rssi_level == DM_RATR_STA_MIDDLE) {
-                       rate_bitmap = 0x000ff000;
-               } else {
-                       if (*pDM_Odm->pBandWidth == HT_CHANNEL_WIDTH_40)
-                               rate_bitmap = 0x000ff015;
-                       else
-                               rate_bitmap = 0x000ff005;
-               }
-               break;
-       default:
-               /* case WIRELESS_11_24N: */
-               rate_bitmap = 0x0fffffff;
-               break;
-       }
-
-       return rate_bitmap;
-}
-
-/*  Return Value: bool */
-/*  - true: RATRState is changed. */
-bool ODM_RAStateCheck(struct odm_dm_struct *pDM_Odm, s32 RSSI, bool bForceUpdate, u8 *pRATRState)
-{
-       struct odm_rate_adapt *pRA = &pDM_Odm->RateAdaptive;
-       const u8 GoUpGap = 5;
-       u8 HighRSSIThreshForRA = pRA->HighRSSIThresh;
-       u8 LowRSSIThreshForRA = pRA->LowRSSIThresh;
-       u8 RATRState;
-
-       /*  Threshold Adjustment: */
-       /*  when RSSI state trends to go up one or two levels, make sure RSSI is high enough. */
-       /*  Here GoUpGap is added to solve the boundary's level alternation issue. */
-       switch (*pRATRState) {
-       case DM_RATR_STA_INIT:
-       case DM_RATR_STA_HIGH:
-               break;
-       case DM_RATR_STA_MIDDLE:
-               HighRSSIThreshForRA += GoUpGap;
-               break;
-       case DM_RATR_STA_LOW:
-               HighRSSIThreshForRA += GoUpGap;
-               LowRSSIThreshForRA += GoUpGap;
-               break;
-       default:
-               break;
-       }
-
-       /*  Decide RATRState by RSSI. */
-       if (RSSI > HighRSSIThreshForRA)
-               RATRState = DM_RATR_STA_HIGH;
-       else if (RSSI > LowRSSIThreshForRA)
-               RATRState = DM_RATR_STA_MIDDLE;
-       else
-               RATRState = DM_RATR_STA_LOW;
-
-       if (*pRATRState != RATRState || bForceUpdate) {
-               *pRATRState = RATRState;
-               return true;
-       }
-       return false;
-}
-
-void ODM_TXPowerTrackingCheck(struct odm_dm_struct *pDM_Odm)
-{
-       struct adapter *Adapter = pDM_Odm->Adapter;
-
-       if (!pDM_Odm->RFCalibrateInfo.TM_Trigger) {             /* at least delay 1 sec */
-               rtl8188e_PHY_SetRFReg(Adapter, RF_T_METER_88E, BIT(17) | BIT(16), 0x03);
-
-               pDM_Odm->RFCalibrateInfo.TM_Trigger = 1;
-               return;
-       } else {
-               odm_TXPowerTrackingCallback_ThermalMeter_8188E(Adapter);
-               pDM_Odm->RFCalibrateInfo.TM_Trigger = 0;
-       }
-}
diff --git a/drivers/staging/r8188eu/hal/odm_HWConfig.c b/drivers/staging/r8188eu/hal/odm_HWConfig.c
deleted file mode 100644 (file)
index 38f357e..0000000
+++ /dev/null
@@ -1,349 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#include "../include/drv_types.h"
-
-static u8 odm_query_rxpwrpercentage(s8 antpower)
-{
-       if ((antpower <= -100) || (antpower >= 20))
-               return 0;
-       else if (antpower >= 0)
-               return 100;
-       else
-               return 100 + antpower;
-}
-
-static s32 odm_signal_scale_mapping(struct odm_dm_struct *dm_odm, s32 currsig)
-{
-       s32 retsig;
-
-       if (currsig >= 51 && currsig <= 100)
-               retsig = 100;
-       else if (currsig >= 41 && currsig <= 50)
-               retsig = 80 + ((currsig - 40) * 2);
-       else if (currsig >= 31 && currsig <= 40)
-               retsig = 66 + (currsig - 30);
-       else if (currsig >= 21 && currsig <= 30)
-               retsig = 54 + (currsig - 20);
-       else if (currsig >= 10 && currsig <= 20)
-               retsig = 42 + (((currsig - 10) * 2) / 3);
-       else if (currsig >= 5 && currsig <= 9)
-               retsig = 22 + (((currsig - 5) * 3) / 2);
-       else if (currsig >= 1 && currsig <= 4)
-               retsig = 6 + (((currsig - 1) * 3) / 2);
-       else
-               retsig = currsig;
-
-       return retsig;
-}
-
-static u8 odm_evm_db_to_percentage(s8 value)
-{
-       /*  -33dB~0dB to 0%~99% */
-       s8 ret_val = clamp(-value, 0, 33) * 3;
-
-       if (ret_val == 99)
-               ret_val = 100;
-
-       return ret_val;
-}
-
-static void odm_RxPhyStatus92CSeries_Parsing(struct odm_dm_struct *dm_odm,
-                       struct phy_info *pPhyInfo,
-                       u8 *pPhyStatus,
-                       struct odm_per_pkt_info *pPktinfo,
-                       struct adapter *adapt)
-{
-       u8 i, Max_spatial_stream;
-       s8 rx_pwr[4], rx_pwr_all = 0;
-       u8 EVM, PWDB_ALL = 0;
-       u8 RSSI, total_rssi = 0;
-       u8 isCCKrate = 0;
-       u8 rf_rx_num = 0;
-       u8 cck_highpwr = 0;
-       u8 LNA_idx, VGA_idx;
-
-       struct phy_status_rpt *pPhyStaRpt = (struct phy_status_rpt *)pPhyStatus;
-
-       isCCKrate = pPktinfo->Rate >= DESC92C_RATE1M && pPktinfo->Rate <= DESC92C_RATE11M;
-
-       if (isCCKrate) {
-               u8 cck_agc_rpt;
-
-               /*  (1)Hardware does not provide RSSI for CCK */
-               /*  (2)PWDB, Average PWDB calculated by hardware (for rate adaptive) */
-
-               cck_highpwr = dm_odm->bCckHighPower;
-
-               cck_agc_rpt =  pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a;
-
-               /* 2011.11.28 LukeLee: 88E use different LNA & VGA gain table */
-               /* The RSSI formula should be modified according to the gain table */
-               /* In 88E, cck_highpwr is always set to 1 */
-               LNA_idx = ((cck_agc_rpt & 0xE0) >> 5);
-               VGA_idx = (cck_agc_rpt & 0x1F);
-               switch (LNA_idx) {
-               case 7:
-                       if (VGA_idx <= 27)
-                               rx_pwr_all = -100 + 2 * (27 - VGA_idx); /* VGA_idx = 27~2 */
-                       else
-                               rx_pwr_all = -100;
-                       break;
-               case 6:
-                       rx_pwr_all = -48 + 2 * (2 - VGA_idx); /* VGA_idx = 2~0 */
-                       break;
-               case 5:
-                       rx_pwr_all = -42 + 2 * (7 - VGA_idx); /* VGA_idx = 7~5 */
-                       break;
-               case 4:
-                       rx_pwr_all = -36 + 2 * (7 - VGA_idx); /* VGA_idx = 7~4 */
-                       break;
-               case 3:
-                       rx_pwr_all = -24 + 2 * (7 - VGA_idx); /* VGA_idx = 7~0 */
-                       break;
-               case 2:
-                       if (cck_highpwr)
-                               rx_pwr_all = -12 + 2 * (5 - VGA_idx); /* VGA_idx = 5~0 */
-                       else
-                               rx_pwr_all = -6 + 2 * (5 - VGA_idx);
-                       break;
-               case 1:
-                               rx_pwr_all = 8 - 2 * VGA_idx;
-                       break;
-               case 0:
-                               rx_pwr_all = 14 - 2 * VGA_idx;
-                       break;
-               default:
-                       break;
-               }
-               rx_pwr_all += 6;
-               PWDB_ALL = odm_query_rxpwrpercentage(rx_pwr_all);
-               if (!cck_highpwr) {
-                       if (PWDB_ALL >= 80)
-                               PWDB_ALL = ((PWDB_ALL - 80) << 1) + ((PWDB_ALL - 80) >> 1) + 80;
-                       else if ((PWDB_ALL <= 78) && (PWDB_ALL >= 20))
-                               PWDB_ALL += 3;
-                       if (PWDB_ALL > 100)
-                               PWDB_ALL = 100;
-               }
-
-               pPhyInfo->RxPWDBAll = PWDB_ALL;
-               pPhyInfo->recvpower = rx_pwr_all;
-               /*  (3) Get Signal Quality (EVM) */
-               if (pPktinfo->bPacketMatchBSSID) {
-                       u8 SQ, SQ_rpt;
-
-                       if (pPhyInfo->RxPWDBAll > 40) {
-                               SQ = 100;
-                       } else {
-                               SQ_rpt = pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all;
-
-                               if (SQ_rpt > 64)
-                                       SQ = 0;
-                               else if (SQ_rpt < 20)
-                                       SQ = 100;
-                               else
-                                       SQ = ((64 - SQ_rpt) * 100) / 44;
-                       }
-                       pPhyInfo->SignalQuality = SQ;
-               }
-       } else { /* is OFDM rate */
-               /*  (1)Get RSSI for HT rate */
-
-               for (i = RF_PATH_A; i < RF_PATH_MAX; i++) {
-                       /*  2008/01/30 MH we will judge RF RX path now. */
-                       if (dm_odm->RFPathRxEnable & BIT(i))
-                               rf_rx_num++;
-
-                       rx_pwr[i] = ((pPhyStaRpt->path_agc[i].gain & 0x3F) * 2) - 110;
-                       if (i == RF_PATH_A)
-                               adapt->signal_strength = rx_pwr[i];
-
-                       pPhyInfo->RxPwr[i] = rx_pwr[i];
-
-                       /* Translate DBM to percentage. */
-                       RSSI = odm_query_rxpwrpercentage(rx_pwr[i]);
-                       total_rssi += RSSI;
-
-                       pPhyInfo->RxMIMOSignalStrength[i] = (u8)RSSI;
-
-                       /* Get Rx snr value in DB */
-                       dm_odm->PhyDbgInfo.RxSNRdB[i] = (s32)(pPhyStaRpt->path_rxsnr[i] / 2);
-               }
-               /*  (2)PWDB, Average PWDB calculated by hardware (for rate adaptive) */
-               rx_pwr_all = (((pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all) >> 1) & 0x7f) - 110;
-
-               PWDB_ALL = odm_query_rxpwrpercentage(rx_pwr_all);
-
-               pPhyInfo->RxPWDBAll = PWDB_ALL;
-               pPhyInfo->RxPower = rx_pwr_all;
-               pPhyInfo->recvpower = rx_pwr_all;
-
-               /*  (3)EVM of HT rate */
-               if (pPktinfo->Rate >= DESC92C_RATEMCS8 && pPktinfo->Rate <= DESC92C_RATEMCS15)
-                       Max_spatial_stream = 2; /* both spatial stream make sense */
-               else
-                       Max_spatial_stream = 1; /* only spatial stream 1 makes sense */
-
-               for (i = 0; i < Max_spatial_stream; i++) {
-                       /*  Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment */
-                       /*  fill most significant bit to "zero" when doing shifting operation which may change a negative */
-                       /*  value to positive one, then the dbm value (which is supposed to be negative)  is not correct anymore. */
-                       EVM = odm_evm_db_to_percentage((pPhyStaRpt->stream_rxevm[i]));  /* dbm */
-
-                       if (pPktinfo->bPacketMatchBSSID) {
-                               if (i == RF_PATH_A) /*  Fill value in RFD, Get the first spatial stream only */
-                                       pPhyInfo->SignalQuality = (u8)(EVM & 0xff);
-                       }
-               }
-       }
-       /* UI BSS List signal strength(in percentage), make it good looking, from 0~100. */
-       /* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */
-       if (isCCKrate) {
-               pPhyInfo->SignalStrength = (u8)(odm_signal_scale_mapping(dm_odm, PWDB_ALL));/* PWDB_ALL; */
-       } else {
-               if (rf_rx_num != 0)
-                       pPhyInfo->SignalStrength = (u8)(odm_signal_scale_mapping(dm_odm, total_rssi /= rf_rx_num));
-       }
-
-       /* For 88E HW Antenna Diversity */
-       dm_odm->DM_FatTable.antsel_rx_keep_0 = pPhyStaRpt->ant_sel;
-       dm_odm->DM_FatTable.antsel_rx_keep_1 = pPhyStaRpt->ant_sel_b;
-       dm_odm->DM_FatTable.antsel_rx_keep_2 = pPhyStaRpt->antsel_rx_keep_2;
-}
-
-static void odm_Process_RSSIForDM(struct odm_dm_struct *dm_odm,
-                                 struct phy_info *pPhyInfo,
-                                 struct odm_per_pkt_info *pPktinfo)
-{
-       s32 UndecoratedSmoothedPWDB, UndecoratedSmoothedCCK;
-       s32 UndecoratedSmoothedOFDM, RSSI_Ave;
-       u8 isCCKrate = 0;
-       u8 RSSI_max, RSSI_min, i;
-       u32 OFDM_pkt = 0;
-       u32 Weighting = 0;
-       struct sta_info *pEntry;
-       u8 antsel_tr_mux;
-       struct fast_ant_train *pDM_FatTable = &dm_odm->DM_FatTable;
-
-       if (pPktinfo->StationID == 0xFF)
-               return;
-       pEntry = dm_odm->pODM_StaInfo[pPktinfo->StationID];
-       if (!IS_STA_VALID(pEntry))
-               return;
-       if ((!pPktinfo->bPacketMatchBSSID))
-               return;
-
-       isCCKrate = pPktinfo->Rate >= DESC92C_RATE1M && pPktinfo->Rate <= DESC92C_RATE11M;
-
-       /* Smart Antenna Debug Message------------------  */
-       if ((dm_odm->AntDivType == CG_TRX_HW_ANTDIV) || (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV)) {
-               if (pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) {
-                       antsel_tr_mux = (pDM_FatTable->antsel_rx_keep_2 << 2) |
-                                       (pDM_FatTable->antsel_rx_keep_1 << 1) | pDM_FatTable->antsel_rx_keep_0;
-                       ODM_AntselStatistics_88E(dm_odm, antsel_tr_mux, pPktinfo->StationID, pPhyInfo->RxPWDBAll);
-               }
-       }
-
-       /* Smart Antenna Debug Message------------------ */
-
-       UndecoratedSmoothedCCK =  pEntry->rssi_stat.UndecoratedSmoothedCCK;
-       UndecoratedSmoothedOFDM = pEntry->rssi_stat.UndecoratedSmoothedOFDM;
-       UndecoratedSmoothedPWDB = pEntry->rssi_stat.UndecoratedSmoothedPWDB;
-
-       if (pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) {
-               if (!isCCKrate) { /* ofdm rate */
-                       if (pPhyInfo->RxMIMOSignalStrength[RF_PATH_B] == 0) {
-                               RSSI_Ave = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A];
-                       } else {
-                               if (pPhyInfo->RxMIMOSignalStrength[RF_PATH_A] > pPhyInfo->RxMIMOSignalStrength[RF_PATH_B]) {
-                                       RSSI_max = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A];
-                                       RSSI_min = pPhyInfo->RxMIMOSignalStrength[RF_PATH_B];
-                               } else {
-                                       RSSI_max = pPhyInfo->RxMIMOSignalStrength[RF_PATH_B];
-                                       RSSI_min = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A];
-                               }
-                               if ((RSSI_max - RSSI_min) < 3)
-                                       RSSI_Ave = RSSI_max;
-                               else if ((RSSI_max - RSSI_min) < 6)
-                                       RSSI_Ave = RSSI_max - 1;
-                               else if ((RSSI_max - RSSI_min) < 10)
-                                       RSSI_Ave = RSSI_max - 2;
-                               else
-                                       RSSI_Ave = RSSI_max - 3;
-                       }
-
-                       /* 1 Process OFDM RSSI */
-                       if (UndecoratedSmoothedOFDM <= 0) {     /*  initialize */
-                               UndecoratedSmoothedOFDM = pPhyInfo->RxPWDBAll;
-                       } else {
-                               if (pPhyInfo->RxPWDBAll > (u32)UndecoratedSmoothedOFDM) {
-                                       UndecoratedSmoothedOFDM =
-                                                       (((UndecoratedSmoothedOFDM) * (Rx_Smooth_Factor - 1)) +
-                                                       (RSSI_Ave)) / (Rx_Smooth_Factor);
-                                       UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM + 1;
-                               } else {
-                                       UndecoratedSmoothedOFDM =
-                                                       (((UndecoratedSmoothedOFDM) * (Rx_Smooth_Factor - 1)) +
-                                                       (RSSI_Ave)) / (Rx_Smooth_Factor);
-                               }
-                       }
-
-                       pEntry->rssi_stat.PacketMap = (pEntry->rssi_stat.PacketMap << 1) | BIT(0);
-
-               } else {
-                       RSSI_Ave = pPhyInfo->RxPWDBAll;
-
-                       /* 1 Process CCK RSSI */
-                       if (UndecoratedSmoothedCCK <= 0) {      /*  initialize */
-                               UndecoratedSmoothedCCK = pPhyInfo->RxPWDBAll;
-                       } else {
-                               if (pPhyInfo->RxPWDBAll > (u32)UndecoratedSmoothedCCK) {
-                                       UndecoratedSmoothedCCK =
-                                                       ((UndecoratedSmoothedCCK * (Rx_Smooth_Factor - 1)) +
-                                                       pPhyInfo->RxPWDBAll) / Rx_Smooth_Factor;
-                                       UndecoratedSmoothedCCK = UndecoratedSmoothedCCK + 1;
-                               } else {
-                                       UndecoratedSmoothedCCK =
-                                                       ((UndecoratedSmoothedCCK * (Rx_Smooth_Factor - 1)) +
-                                                       pPhyInfo->RxPWDBAll) / Rx_Smooth_Factor;
-                               }
-                       }
-                       pEntry->rssi_stat.PacketMap = pEntry->rssi_stat.PacketMap << 1;
-               }
-               /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */
-               if (pEntry->rssi_stat.ValidBit >= 64)
-                       pEntry->rssi_stat.ValidBit = 64;
-               else
-                       pEntry->rssi_stat.ValidBit++;
-
-               for (i = 0; i < pEntry->rssi_stat.ValidBit; i++)
-                       OFDM_pkt += (u8)(pEntry->rssi_stat.PacketMap >> i) & BIT(0);
-
-               if (pEntry->rssi_stat.ValidBit == 64) {
-                       Weighting = ((OFDM_pkt << 4) > 64) ? 64 : (OFDM_pkt << 4);
-                       UndecoratedSmoothedPWDB = (Weighting * UndecoratedSmoothedOFDM + (64 - Weighting) * UndecoratedSmoothedCCK) >> 6;
-               } else {
-                       if (pEntry->rssi_stat.ValidBit != 0)
-                               UndecoratedSmoothedPWDB = (OFDM_pkt * UndecoratedSmoothedOFDM +
-                                                         (pEntry->rssi_stat.ValidBit - OFDM_pkt) *
-                                                         UndecoratedSmoothedCCK) / pEntry->rssi_stat.ValidBit;
-                       else
-                               UndecoratedSmoothedPWDB = 0;
-               }
-               pEntry->rssi_stat.UndecoratedSmoothedCCK = UndecoratedSmoothedCCK;
-               pEntry->rssi_stat.UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM;
-               pEntry->rssi_stat.UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB;
-       }
-}
-
-/*  Endianness before calling this API */
-void ODM_PhyStatusQuery(struct odm_dm_struct *dm_odm,
-                       struct phy_info *pPhyInfo,
-                       u8 *pPhyStatus,
-                       struct odm_per_pkt_info *pPktinfo,
-                       struct adapter *adapt)
-{
-       odm_RxPhyStatus92CSeries_Parsing(dm_odm, pPhyInfo, pPhyStatus, pPktinfo, adapt);
-       odm_Process_RSSIForDM(dm_odm, pPhyInfo, pPktinfo);
-}
diff --git a/drivers/staging/r8188eu/hal/odm_RTL8188E.c b/drivers/staging/r8188eu/hal/odm_RTL8188E.c
deleted file mode 100644 (file)
index f3f4074..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#include "../include/drv_types.h"
-
-static void odm_RX_HWAntDivInit(struct odm_dm_struct *dm_odm)
-{
-       struct adapter *adapter = dm_odm->Adapter;
-       u32     value32;
-
-       /* MAC Setting */
-       value32 = rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_ANTSEL_PIN_11N, bMaskDWord);
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_ANTSEL_PIN_11N, bMaskDWord, value32 | (BIT(23) | BIT(25))); /* Reg4C[25]=1, Reg4C[23]=1 for pin output */
-       /* Pin Settings */
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);/* Reg870[8]=1'b0, Reg870[9]=1'b0      antsel antselb by HW */
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_RX_ANT_CTRL_11N, BIT(10), 0);    /* Reg864[10]=1'b0      antsel2 by HW */
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_LNA_SWITCH_11N, BIT(22), 1);     /* Regb2c[22]=1'b0      disable CS/CG switch */
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_LNA_SWITCH_11N, BIT(31), 1);     /* Regb2c[31]=1'b1      output at CG only */
-       /* OFDM Settings */
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_ANTDIV_PARA1_11N, bMaskDWord, 0x000000a0);
-       /* CCK Settings */
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_BB_PWR_SAV4_11N, BIT(7), 1); /* Fix CCK PHY status report issue */
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1); /* CCK complete HW AntDiv within 64 samples */
-       ODM_UpdateRxIdleAnt_88E(dm_odm, MAIN_ANT);
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_ANT_MAPPING1_11N, 0xFFFF, 0x0201);       /* antenna mapping table */
-}
-
-static void odm_TRX_HWAntDivInit(struct odm_dm_struct *dm_odm)
-{
-       struct adapter *adapter = dm_odm->Adapter;
-       u32     value32;
-
-       /* MAC Setting */
-       value32 = rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_ANTSEL_PIN_11N, bMaskDWord);
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_ANTSEL_PIN_11N, bMaskDWord, value32 | (BIT(23) | BIT(25))); /* Reg4C[25]=1, Reg4C[23]=1 for pin output */
-       /* Pin Settings */
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);/* Reg870[8]=1'b0, Reg870[9]=1'b0              antsel antselb by HW */
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_RX_ANT_CTRL_11N, BIT(10), 0);    /* Reg864[10]=1'b0      antsel2 by HW */
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_LNA_SWITCH_11N, BIT(22), 0);     /* Regb2c[22]=1'b0      disable CS/CG switch */
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_LNA_SWITCH_11N, BIT(31), 1);     /* Regb2c[31]=1'b1      output at CG only */
-       /* OFDM Settings */
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_ANTDIV_PARA1_11N, bMaskDWord, 0x000000a0);
-       /* CCK Settings */
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_BB_PWR_SAV4_11N, BIT(7), 1); /* Fix CCK PHY status report issue */
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1); /* CCK complete HW AntDiv within 64 samples */
-       /* Tx Settings */
-       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_TX_ANT_CTRL_11N, BIT(21), 0); /* Reg80c[21]=1'b0         from TX Reg */
-       ODM_UpdateRxIdleAnt_88E(dm_odm, MAIN_ANT);
-
-       /* antenna mapping table */
-       if (!dm_odm->bIsMPChip) { /* testchip */
-               rtl8188e_PHY_SetBBReg(adapter, ODM_REG_RX_DEFUALT_A_11N, BIT(10) | BIT(9) | BIT(8), 1); /* Reg858[10:8]=3'b001 */
-               rtl8188e_PHY_SetBBReg(adapter, ODM_REG_RX_DEFUALT_A_11N, BIT(13) | BIT(12) | BIT(11), 2);       /* Reg858[13:11]=3'b010 */
-       } else { /* MPchip */
-               rtl8188e_PHY_SetBBReg(adapter, ODM_REG_ANT_MAPPING1_11N, bMaskDWord, 0x0201);   /* Reg914=3'b010, Reg915=3'b001 */
-       }
-}
-
-static void odm_FastAntTrainingInit(struct odm_dm_struct *dm_odm)
-{
-       struct adapter *adapter = dm_odm->Adapter;
-       u32     value32;
-
-       /* MAC Setting */
-       value32 = rtl8188e_PHY_QueryBBReg(adapter, 0x4c, bMaskDWord);
-       rtl8188e_PHY_SetBBReg(adapter, 0x4c, bMaskDWord, value32 | (BIT(23) | BIT(25))); /* Reg4C[25]=1, Reg4C[23]=1 for pin output */
-       value32 = rtl8188e_PHY_QueryBBReg(adapter,  0x7B4, bMaskDWord);
-       rtl8188e_PHY_SetBBReg(adapter, 0x7b4, bMaskDWord, value32 | (BIT(16) | BIT(17))); /* Reg7B4[16]=1 enable antenna training, Reg7B4[17]=1 enable A2 match */
-
-       /* Match MAC ADDR */
-       rtl8188e_PHY_SetBBReg(adapter, 0x7b4, 0xFFFF, 0);
-       rtl8188e_PHY_SetBBReg(adapter, 0x7b0, bMaskDWord, 0);
-
-       rtl8188e_PHY_SetBBReg(adapter, 0x870, BIT(9) | BIT(8), 0);/* Reg870[8]=1'b0, Reg870[9]=1'b0             antsel antselb by HW */
-       rtl8188e_PHY_SetBBReg(adapter, 0x864, BIT(10), 0);      /* Reg864[10]=1'b0      antsel2 by HW */
-       rtl8188e_PHY_SetBBReg(adapter, 0xb2c, BIT(22), 0);      /* Regb2c[22]=1'b0      disable CS/CG switch */
-       rtl8188e_PHY_SetBBReg(adapter, 0xb2c, BIT(31), 1);      /* Regb2c[31]=1'b1      output at CG only */
-       rtl8188e_PHY_SetBBReg(adapter, 0xca4, bMaskDWord, 0x000000a0);
-
-       if (!dm_odm->bIsMPChip) { /* testchip */
-               rtl8188e_PHY_SetBBReg(adapter, 0x858, BIT(10) | BIT(9) | BIT(8), 1);    /* Reg858[10:8]=3'b001 */
-               rtl8188e_PHY_SetBBReg(adapter, 0x858, BIT(13) | BIT(12) | BIT(11), 2);  /* Reg858[13:11]=3'b010 */
-       } else { /* MPchip */
-               rtl8188e_PHY_SetBBReg(adapter, 0x914, bMaskByte0, 1);
-               rtl8188e_PHY_SetBBReg(adapter, 0x914, bMaskByte1, 2);
-       }
-
-       /* Default Ant Setting when no fast training */
-       rtl8188e_PHY_SetBBReg(adapter, 0x80c, BIT(21), 1); /* Reg80c[21]=1'b1           from TX Info */
-       rtl8188e_PHY_SetBBReg(adapter, 0x864, BIT(5) | BIT(4) | BIT(3), 0);     /* Default RX */
-       rtl8188e_PHY_SetBBReg(adapter, 0x864, BIT(8) | BIT(7) | BIT(6), 1);     /* Optional RX */
-
-       /* Enter Training state */
-       rtl8188e_PHY_SetBBReg(adapter, 0x864, BIT(2) | BIT(1) | BIT(0), 1);
-       rtl8188e_PHY_SetBBReg(adapter, 0xc50, BIT(7), 1);       /* RegC50[7]=1'b1               enable HW AntDiv */
-}
-
-void ODM_AntennaDiversityInit_88E(struct odm_dm_struct *dm_odm)
-{
-       if (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV)
-               odm_RX_HWAntDivInit(dm_odm);
-       else if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV)
-               odm_TRX_HWAntDivInit(dm_odm);
-       else if (dm_odm->AntDivType == CG_TRX_SMART_ANTDIV)
-               odm_FastAntTrainingInit(dm_odm);
-}
-
-void ODM_UpdateRxIdleAnt_88E(struct odm_dm_struct *dm_odm, u8 Ant)
-{
-       struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable;
-       struct adapter *adapter = dm_odm->Adapter;
-       u32     DefaultAnt, OptionalAnt;
-
-       if (dm_fat_tbl->RxIdleAnt != Ant) {
-               if (Ant == MAIN_ANT) {
-                       DefaultAnt = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ? MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX;
-                       OptionalAnt = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ? AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX;
-               } else {
-                       DefaultAnt = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ? AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX;
-                       OptionalAnt = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ? MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX;
-               }
-
-               if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) {
-                       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_RX_ANT_CTRL_11N, BIT(5) | BIT(4) | BIT(3), DefaultAnt);  /* Default RX */
-                       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_RX_ANT_CTRL_11N, BIT(8) | BIT(7) | BIT(6), OptionalAnt);         /* Optional RX */
-                       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_ANTSEL_CTRL_11N, BIT(14) | BIT(13) | BIT(12), DefaultAnt);       /* Default TX */
-                       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_RESP_TX_11N, BIT(6) | BIT(7), DefaultAnt);       /* Resp Tx */
-               } else if (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV) {
-                       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_RX_ANT_CTRL_11N, BIT(5) | BIT(4) | BIT(3), DefaultAnt);  /* Default RX */
-                       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_RX_ANT_CTRL_11N, BIT(8) | BIT(7) | BIT(6), OptionalAnt);         /* Optional RX */
-               }
-       }
-       dm_fat_tbl->RxIdleAnt = Ant;
-       if (Ant != MAIN_ANT)
-               pr_info("RxIdleAnt=AUX_ANT\n");
-}
-
-static void odm_UpdateTxAnt_88E(struct odm_dm_struct *dm_odm, u8 Ant, u32 MacId)
-{
-       struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable;
-       u8      TargetAnt;
-
-       if (Ant == MAIN_ANT)
-               TargetAnt = MAIN_ANT_CG_TRX;
-       else
-               TargetAnt = AUX_ANT_CG_TRX;
-       dm_fat_tbl->antsel_a[MacId] = TargetAnt & BIT(0);
-       dm_fat_tbl->antsel_b[MacId] = (TargetAnt & BIT(1)) >> 1;
-       dm_fat_tbl->antsel_c[MacId] = (TargetAnt & BIT(2)) >> 2;
-}
-
-void ODM_SetTxAntByTxInfo_88E(struct odm_dm_struct *dm_odm, u8 *pDesc, u8 macId)
-{
-       struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable;
-
-       if ((dm_odm->AntDivType == CG_TRX_HW_ANTDIV) || (dm_odm->AntDivType == CG_TRX_SMART_ANTDIV)) {
-               SET_TX_DESC_ANTSEL_A_88E(pDesc, dm_fat_tbl->antsel_a[macId]);
-               SET_TX_DESC_ANTSEL_B_88E(pDesc, dm_fat_tbl->antsel_b[macId]);
-               SET_TX_DESC_ANTSEL_C_88E(pDesc, dm_fat_tbl->antsel_c[macId]);
-       }
-}
-
-void ODM_AntselStatistics_88E(struct odm_dm_struct *dm_odm, u8 antsel_tr_mux, u32 MacId, u8 RxPWDBAll)
-{
-       struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable;
-       if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) {
-               if (antsel_tr_mux == MAIN_ANT_CG_TRX) {
-                       dm_fat_tbl->MainAnt_Sum[MacId] += RxPWDBAll;
-                       dm_fat_tbl->MainAnt_Cnt[MacId]++;
-               } else {
-                       dm_fat_tbl->AuxAnt_Sum[MacId] += RxPWDBAll;
-                       dm_fat_tbl->AuxAnt_Cnt[MacId]++;
-               }
-       } else if (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV) {
-               if (antsel_tr_mux == MAIN_ANT_CGCS_RX) {
-                       dm_fat_tbl->MainAnt_Sum[MacId] += RxPWDBAll;
-                       dm_fat_tbl->MainAnt_Cnt[MacId]++;
-               } else {
-                       dm_fat_tbl->AuxAnt_Sum[MacId] += RxPWDBAll;
-                       dm_fat_tbl->AuxAnt_Cnt[MacId]++;
-               }
-       }
-}
-
-static void odm_HWAntDiv(struct odm_dm_struct *dm_odm)
-{
-       u32     i, MinRSSI = 0xFF, AntDivMaxRSSI = 0, MaxRSSI = 0, LocalMinRSSI, LocalMaxRSSI;
-       u32     Main_RSSI, Aux_RSSI;
-       u8      RxIdleAnt = 0, TargetAnt = 7;
-       struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable;
-       struct rtw_dig *pDM_DigTable = &dm_odm->DM_DigTable;
-       struct sta_info *pEntry;
-
-       for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
-               pEntry = dm_odm->pODM_StaInfo[i];
-               if (IS_STA_VALID(pEntry)) {
-                       /* 2 Calculate RSSI per Antenna */
-                       Main_RSSI = (dm_fat_tbl->MainAnt_Cnt[i] != 0) ? (dm_fat_tbl->MainAnt_Sum[i] / dm_fat_tbl->MainAnt_Cnt[i]) : 0;
-                       Aux_RSSI = (dm_fat_tbl->AuxAnt_Cnt[i] != 0) ? (dm_fat_tbl->AuxAnt_Sum[i] / dm_fat_tbl->AuxAnt_Cnt[i]) : 0;
-                       TargetAnt = (Main_RSSI >= Aux_RSSI) ? MAIN_ANT : AUX_ANT;
-                       /* 2 Select MaxRSSI for DIG */
-                       LocalMaxRSSI = max(Main_RSSI, Aux_RSSI);
-                       if ((LocalMaxRSSI > AntDivMaxRSSI) && (LocalMaxRSSI < 40))
-                               AntDivMaxRSSI = LocalMaxRSSI;
-                       if (LocalMaxRSSI > MaxRSSI)
-                               MaxRSSI = LocalMaxRSSI;
-
-                       /* 2 Select RX Idle Antenna */
-                       if ((dm_fat_tbl->RxIdleAnt == MAIN_ANT) && (Main_RSSI == 0))
-                               Main_RSSI = Aux_RSSI;
-                       else if ((dm_fat_tbl->RxIdleAnt == AUX_ANT) && (Aux_RSSI == 0))
-                               Aux_RSSI = Main_RSSI;
-
-                       LocalMinRSSI = min(Main_RSSI, Aux_RSSI);
-                       if (LocalMinRSSI < MinRSSI) {
-                               MinRSSI = LocalMinRSSI;
-                               RxIdleAnt = TargetAnt;
-                       }
-                       /* 2 Select TRX Antenna */
-                       if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV)
-                               odm_UpdateTxAnt_88E(dm_odm, TargetAnt, i);
-               }
-               dm_fat_tbl->MainAnt_Sum[i] = 0;
-               dm_fat_tbl->AuxAnt_Sum[i] = 0;
-               dm_fat_tbl->MainAnt_Cnt[i] = 0;
-               dm_fat_tbl->AuxAnt_Cnt[i] = 0;
-       }
-
-       /* 2 Set RX Idle Antenna */
-       ODM_UpdateRxIdleAnt_88E(dm_odm, RxIdleAnt);
-
-       pDM_DigTable->AntDiv_RSSI_max = AntDivMaxRSSI;
-       pDM_DigTable->RSSI_max = MaxRSSI;
-}
-
-void ODM_AntennaDiversity_88E(struct odm_dm_struct *dm_odm)
-{
-       struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable;
-       struct adapter *adapter = dm_odm->Adapter;
-
-       if (!(dm_odm->SupportAbility & ODM_BB_ANT_DIV))
-               return;
-       if (!dm_odm->bLinked) {
-               if (dm_fat_tbl->bBecomeLinked) {
-                       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_IGI_A_11N, BIT(7), 0);   /* RegC50[7]=1'b1               enable HW AntDiv */
-                       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_CCK_ANTDIV_PARA1_11N, BIT(15), 0); /* Enable CCK AntDiv */
-                       if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV)
-                               rtl8188e_PHY_SetBBReg(adapter, ODM_REG_TX_ANT_CTRL_11N, BIT(21), 0); /* Reg80c[21]=1'b0         from TX Reg */
-                       dm_fat_tbl->bBecomeLinked = dm_odm->bLinked;
-               }
-               return;
-       } else {
-               if (!dm_fat_tbl->bBecomeLinked) {
-                       /* Because HW AntDiv is disabled before Link, we enable HW AntDiv after link */
-                       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_IGI_A_11N, BIT(7), 1);   /* RegC50[7]=1'b1               enable HW AntDiv */
-                       rtl8188e_PHY_SetBBReg(adapter, ODM_REG_CCK_ANTDIV_PARA1_11N, BIT(15), 1); /* Enable CCK AntDiv */
-                       if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV)
-                               rtl8188e_PHY_SetBBReg(adapter, ODM_REG_TX_ANT_CTRL_11N, BIT(21), 1); /* Reg80c[21]=1'b1         from TX Info */
-                       dm_fat_tbl->bBecomeLinked = dm_odm->bLinked;
-               }
-       }
-       if ((dm_odm->AntDivType == CG_TRX_HW_ANTDIV) || (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV))
-               odm_HWAntDiv(dm_odm);
-}
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
deleted file mode 100644 (file)
index 788904d..0000000
+++ /dev/null
@@ -1,694 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#define _RTL8188E_CMD_C_
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/rtw_ioctl_set.h"
-
-#include "../include/rtl8188e_hal.h"
-
-#define RTL88E_MAX_H2C_BOX_NUMS                4
-#define RTL88E_MAX_CMD_LEN             7
-#define RTL88E_MESSAGE_BOX_SIZE                4
-#define RTL88E_EX_MESSAGE_BOX_SIZE     4
-
-static u8 _is_fw_read_cmd_down(struct adapter *adapt, u8 msgbox_num)
-{
-       u8 read_down = false, reg;
-       int     retry_cnts = 100;
-       int res;
-
-       u8 valid;
-
-       do {
-               res = rtw_read8(adapt, REG_HMETFR, &reg);
-               if (res)
-                       continue;
-
-               valid = reg & BIT(msgbox_num);
-               if (0 == valid)
-                       read_down = true;
-       } while ((!read_down) && (retry_cnts--));
-
-       return read_down;
-}
-
-/*****************************************
-* H2C Msg format :
-* 0x1DF - 0x1D0
-*| 31 - 8      | 7-5    4 - 0  |
-*| h2c_msg     |Class_ID CMD_ID        |
-*
-* Extend 0x1FF - 0x1F0
-*|31 - 0         |
-*|ext_msg|
-******************************************/
-static s32 FillH2CCmd_88E(struct adapter *adapt, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer)
-{
-       u8 bcmd_down = false;
-       s32 retry_cnts = 100;
-       u8 h2c_box_num;
-       u32 msgbox_addr;
-       u32 msgbox_ex_addr;
-       struct hal_data_8188e *haldata = &adapt->haldata;
-       u8 cmd_idx, ext_cmd_len;
-       u32 h2c_cmd = 0;
-       u32 h2c_cmd_ex = 0;
-
-       if (!adapt->bFWReady)
-               return _FAIL;
-
-       if (!pCmdBuffer || CmdLen > RTL88E_MAX_CMD_LEN || adapt->bSurpriseRemoved)
-               return _FAIL;
-
-       /* pay attention to if  race condition happened in  H2C cmd setting. */
-       do {
-               h2c_box_num = haldata->LastHMEBoxNum;
-
-               if (!_is_fw_read_cmd_down(adapt, h2c_box_num))
-                       return _FAIL;
-
-               *(u8 *)(&h2c_cmd) = ElementID;
-
-               if (CmdLen <= 3) {
-                       memcpy((u8 *)(&h2c_cmd) + 1, pCmdBuffer, CmdLen);
-               } else {
-                       memcpy((u8 *)(&h2c_cmd) + 1, pCmdBuffer, 3);
-                       ext_cmd_len = CmdLen - 3;
-                       memcpy((u8 *)(&h2c_cmd_ex), pCmdBuffer + 3, ext_cmd_len);
-
-                       /* Write Ext command */
-                       msgbox_ex_addr = REG_HMEBOX_EXT_0 + (h2c_box_num * RTL88E_EX_MESSAGE_BOX_SIZE);
-                       for (cmd_idx = 0; cmd_idx < ext_cmd_len; cmd_idx++) {
-                               rtw_write8(adapt, msgbox_ex_addr + cmd_idx, *((u8 *)(&h2c_cmd_ex) + cmd_idx));
-                       }
-               }
-               /*  Write command */
-               msgbox_addr = REG_HMEBOX_0 + (h2c_box_num * RTL88E_MESSAGE_BOX_SIZE);
-               for (cmd_idx = 0; cmd_idx < RTL88E_MESSAGE_BOX_SIZE; cmd_idx++) {
-                       rtw_write8(adapt, msgbox_addr + cmd_idx, *((u8 *)(&h2c_cmd) + cmd_idx));
-               }
-               bcmd_down = true;
-
-               haldata->LastHMEBoxNum = (h2c_box_num + 1) % RTL88E_MAX_H2C_BOX_NUMS;
-
-       } while ((!bcmd_down) && (retry_cnts--));
-
-       return _SUCCESS;
-}
-
-u8 rtl8188e_set_raid_cmd(struct adapter *adapt, u32 mask)
-{
-       u8 buf[3];
-       u8 res = _SUCCESS;
-       struct hal_data_8188e *haldata = &adapt->haldata;
-
-       if (haldata->fw_ractrl) {
-               __le32 lmask;
-
-               memset(buf, 0, 3);
-               lmask = cpu_to_le32(mask);
-               memcpy(buf, &lmask, 3);
-
-               FillH2CCmd_88E(adapt, H2C_DM_MACID_CFG, 3, buf);
-       } else {
-               res = _FAIL;
-       }
-
-       return res;
-}
-
-/* bitmap[0:27] = tx_rate_bitmap */
-/* bitmap[28:31]= Rate Adaptive id */
-/* arg[0:4] = macid */
-/* arg[5] = Short GI */
-void rtl8188e_Add_RateATid(struct adapter *pAdapter, u32 bitmap, u8 arg, u8 rssi_level)
-{
-       struct hal_data_8188e *haldata = &pAdapter->haldata;
-
-       u8 macid, raid, short_gi_rate = false;
-
-       macid = arg & 0x1f;
-
-       raid = (bitmap >> 28) & 0x0f;
-       bitmap &= 0x0fffffff;
-
-       if (rssi_level != DM_RATR_STA_INIT)
-               bitmap = ODM_Get_Rate_Bitmap(&haldata->odmpriv, macid, bitmap, rssi_level);
-
-       bitmap |= ((raid << 28) & 0xf0000000);
-
-       short_gi_rate = (arg & BIT(5)) ? true : false;
-
-       raid = (bitmap >> 28) & 0x0f;
-
-       bitmap &= 0x0fffffff;
-
-       ODM_RA_UpdateRateInfo_8188E(&haldata->odmpriv, macid, raid, bitmap, short_gi_rate);
-}
-
-void rtl8188e_set_FwPwrMode_cmd(struct adapter *adapt, u8 Mode)
-{
-       struct setpwrmode_parm H2CSetPwrMode;
-       struct pwrctrl_priv *pwrpriv = &adapt->pwrctrlpriv;
-       u8 RLBM = 0; /*  0:Min, 1:Max, 2:User define */
-
-       switch (Mode) {
-       case PS_MODE_ACTIVE:
-               H2CSetPwrMode.Mode = 0;
-               break;
-       case PS_MODE_MIN:
-               H2CSetPwrMode.Mode = 1;
-               break;
-       case PS_MODE_MAX:
-               RLBM = 1;
-               H2CSetPwrMode.Mode = 1;
-               break;
-       case PS_MODE_DTIM:
-               RLBM = 2;
-               H2CSetPwrMode.Mode = 1;
-               break;
-       case PS_MODE_UAPSD_WMM:
-               H2CSetPwrMode.Mode = 2;
-               break;
-       default:
-               H2CSetPwrMode.Mode = 0;
-               break;
-       }
-
-       H2CSetPwrMode.SmartPS_RLBM = (((pwrpriv->smart_ps << 4) & 0xf0) | (RLBM & 0x0f));
-
-       H2CSetPwrMode.AwakeInterval = 1;
-
-       H2CSetPwrMode.bAllQueueUAPSD = adapt->registrypriv.uapsd_enable;
-
-       if (Mode > 0)
-               H2CSetPwrMode.PwrState = 0x00;/*  AllON(0x0C), RFON(0x04), RFOFF(0x00) */
-       else
-               H2CSetPwrMode.PwrState = 0x0C;/*  AllON(0x0C), RFON(0x04), RFOFF(0x00) */
-
-       FillH2CCmd_88E(adapt, H2C_PS_PWR_MODE, sizeof(H2CSetPwrMode), (u8 *)&H2CSetPwrMode);
-
-}
-
-void rtl8188e_set_FwMediaStatus_cmd(struct adapter *adapt, u16 mstatus_rpt)
-{
-       __le16 mst_rpt = cpu_to_le16(mstatus_rpt);
-
-       FillH2CCmd_88E(adapt, H2C_COM_MEDIA_STATUS_RPT, sizeof(mst_rpt), (u8 *)&mst_rpt);
-}
-
-static void ConstructBeacon(struct adapter *adapt, u8 *pframe, u32 *pLength)
-{
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       u32 rate_len, pktlen;
-       struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex            *cur_network = &pmlmeinfo->network;
-
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-
-       eth_broadcast_addr(pwlanhdr->addr1);
-       memcpy(pwlanhdr->addr2, myid(&adapt->eeprompriv), ETH_ALEN);
-       memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
-       SetFrameSubType(pframe, WIFI_BEACON);
-
-       pframe += sizeof(struct ieee80211_hdr_3addr);
-       pktlen = sizeof(struct ieee80211_hdr_3addr);
-
-       /* timestamp will be inserted by hardware */
-       pframe += 8;
-       pktlen += 8;
-
-       /*  beacon interval: 2 bytes */
-       memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
-
-       pframe += 2;
-       pktlen += 2;
-
-       /*  capability info: 2 bytes */
-       memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
-
-       pframe += 2;
-       pktlen += 2;
-
-       if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
-               pktlen += cur_network->IELength - sizeof(struct ndis_802_11_fixed_ie);
-               memcpy(pframe, cur_network->IEs + sizeof(struct ndis_802_11_fixed_ie), pktlen);
-
-               goto _ConstructBeacon;
-       }
-
-       /* below for ad-hoc mode */
-
-       /*  SSID */
-       pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
-
-       /*  supported rates... */
-       rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
-       pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
-
-       /*  DS parameter set */
-       pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&cur_network->Configuration.DSConfig, &pktlen);
-
-       if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
-               u32 ATIMWindow;
-               /*  IBSS Parameter Set... */
-               ATIMWindow = 0;
-               pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
-       }
-
-       /* todo: ERP IE */
-
-       /*  EXTERNDED SUPPORTED RATE */
-       if (rate_len > 8)
-               pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
-
-       /* todo:HT for adhoc */
-
-_ConstructBeacon:
-
-       if ((pktlen + TXDESC_SIZE) > 512)
-               return;
-
-       *pLength = pktlen;
-}
-
-static void ConstructPSPoll(struct adapter *adapt, u8 *pframe, u32 *pLength)
-{
-       struct ieee80211_hdr *pwlanhdr;
-       struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       __le16 *fctrl;
-
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       /*  Frame control. */
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-       SetPwrMgt(fctrl);
-       SetFrameSubType(pframe, WIFI_PSPOLL);
-
-       /*  AID. */
-       SetDuration(pframe, (pmlmeinfo->aid | 0xc000));
-
-       /*  BSSID. */
-       memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
-
-       /*  TA. */
-       memcpy(pwlanhdr->addr2, myid(&adapt->eeprompriv), ETH_ALEN);
-
-       *pLength = 16;
-}
-
-static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe,
-       u32 *pLength,
-       u8 *StaAddr,
-       u8 bQoS,
-       u8 AC,
-       u8 bEosp,
-       u8 bForcePowerSave)
-{
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       u32 pktlen;
-       struct mlme_priv *pmlmepriv = &adapt->mlmepriv;
-       struct wlan_network             *cur_network = &pmlmepriv->cur_network;
-       struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-       if (bForcePowerSave)
-               SetPwrMgt(fctrl);
-
-       switch (cur_network->network.InfrastructureMode) {
-       case Ndis802_11Infrastructure:
-               SetToDs(fctrl);
-               memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
-               memcpy(pwlanhdr->addr2, myid(&adapt->eeprompriv), ETH_ALEN);
-               memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
-               break;
-       case Ndis802_11APMode:
-               SetFrDs(fctrl);
-               memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
-               memcpy(pwlanhdr->addr2, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
-               memcpy(pwlanhdr->addr3, myid(&adapt->eeprompriv), ETH_ALEN);
-               break;
-       case Ndis802_11IBSS:
-       default:
-               memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
-               memcpy(pwlanhdr->addr2, myid(&adapt->eeprompriv), ETH_ALEN);
-               memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
-               break;
-       }
-
-       SetSeqNum(pwlanhdr, 0);
-
-       if (bQoS) {
-               struct ieee80211_qos_hdr *pwlanqoshdr;
-
-               SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
-
-               pwlanqoshdr = (struct ieee80211_qos_hdr *)pframe;
-               SetPriority(&pwlanqoshdr->qos_ctrl, AC);
-               SetEOSP(&pwlanqoshdr->qos_ctrl, bEosp);
-
-               pktlen = sizeof(struct ieee80211_qos_hdr);
-       } else {
-               SetFrameSubType(pframe, WIFI_DATA_NULL);
-
-               pktlen = sizeof(struct ieee80211_qos_hdr);
-       }
-
-       *pLength = pktlen;
-}
-
-static void ConstructProbeRsp(struct adapter *adapt, u8 *pframe, u32 *pLength, u8 *StaAddr, bool bHideSSID)
-{
-       struct ieee80211_hdr *pwlanhdr;
-       __le16 *fctrl;
-       u8 *mac, *bssid;
-       u32 pktlen;
-       struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex    *cur_network = &pmlmeinfo->network;
-
-       pwlanhdr = (struct ieee80211_hdr *)pframe;
-
-       mac = myid(&adapt->eeprompriv);
-       bssid = cur_network->MacAddress;
-
-       fctrl = &pwlanhdr->frame_control;
-       *(fctrl) = 0;
-       memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
-       memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
-       memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
-
-       SetSeqNum(pwlanhdr, 0);
-       SetFrameSubType(fctrl, WIFI_PROBERSP);
-
-       pktlen = sizeof(struct ieee80211_hdr_3addr);
-       pframe += pktlen;
-
-       if (cur_network->IELength > MAX_IE_SZ)
-               return;
-
-       memcpy(pframe, cur_network->IEs, cur_network->IELength);
-       pframe += cur_network->IELength;
-       pktlen += cur_network->IELength;
-
-       *pLength = pktlen;
-}
-
-/*  To check if reserved page content is destroyed by beacon because beacon is too large. */
-/*  2010.06.23. Added by tynli. */
-void CheckFwRsvdPageContent(struct adapter *Adapter)
-{
-}
-
-/*  */
-/*  Description: Fill the reserved packets that FW will use to RSVD page. */
-/*                     Now we just send 4 types packet to rsvd page. */
-/*                     (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp. */
-/*     Input: */
-/*         bDLFinished - false: At the first time we will send all the packets as a large packet to Hw, */
-/*                                             so we need to set the packet length to total length. */
-/*                           true: At the second time, we should send the first packet (default:beacon) */
-/*                                             to Hw again and set the length in descriptor to the real beacon length. */
-/*  2009.10.15 by tynli. */
-static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
-{
-       struct xmit_frame       *pmgntframe;
-       struct pkt_attrib       *pattrib;
-       struct xmit_priv *pxmitpriv;
-       struct mlme_ext_priv *pmlmeext;
-       struct mlme_ext_info    *pmlmeinfo;
-       u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength;
-       u32 NullDataLength, QosNullLength;
-       u8 *ReservedPagePacket;
-       u8 PageNum, PageNeed, TxDescLen;
-       u16 BufIndex;
-       u32 TotalPacketLen;
-       struct rsvdpage_loc RsvdPageLoc;
-
-       ReservedPagePacket = kzalloc(1000, GFP_KERNEL);
-       if (!ReservedPagePacket)
-               return;
-
-       pxmitpriv = &adapt->xmitpriv;
-       pmlmeext = &adapt->mlmeextpriv;
-       pmlmeinfo = &pmlmeext->mlmext_info;
-
-       TxDescLen = TXDESC_SIZE;
-       PageNum = 0;
-
-       /* 3 (1) beacon * 2 pages */
-       BufIndex = TXDESC_OFFSET;
-       ConstructBeacon(adapt, &ReservedPagePacket[BufIndex], &BeaconLength);
-
-       /*  When we count the first page size, we need to reserve description size for the RSVD */
-       /*  packet, it will be filled in front of the packet in TXPKTBUF. */
-       PageNeed = (u8)PageNum_128(TxDescLen + BeaconLength);
-       /*  To reserved 2 pages for beacon buffer. 2010.06.24. */
-       if (PageNeed == 1)
-               PageNeed += 1;
-       PageNum += PageNeed;
-
-       BufIndex += PageNeed * 128;
-
-       /* 3 (2) ps-poll *1 page */
-       RsvdPageLoc.LocPsPoll = PageNum;
-       ConstructPSPoll(adapt, &ReservedPagePacket[BufIndex], &PSPollLength);
-       rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex - TxDescLen], PSPollLength, true, false);
-
-       PageNeed = (u8)PageNum_128(TxDescLen + PSPollLength);
-       PageNum += PageNeed;
-
-       BufIndex += PageNeed * 128;
-
-       /* 3 (3) null data * 1 page */
-       RsvdPageLoc.LocNullData = PageNum;
-       ConstructNullFunctionData(adapt, &ReservedPagePacket[BufIndex], &NullDataLength, get_my_bssid(&pmlmeinfo->network), false, 0, 0, false);
-       rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex - TxDescLen], NullDataLength, false, false);
-
-       PageNeed = (u8)PageNum_128(TxDescLen + NullDataLength);
-       PageNum += PageNeed;
-
-       BufIndex += PageNeed * 128;
-
-       /* 3 (4) probe response * 1page */
-       RsvdPageLoc.LocProbeRsp = PageNum;
-       ConstructProbeRsp(adapt, &ReservedPagePacket[BufIndex], &ProbeRspLength, get_my_bssid(&pmlmeinfo->network), false);
-       rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex - TxDescLen], ProbeRspLength, false, false);
-
-       PageNeed = (u8)PageNum_128(TxDescLen + ProbeRspLength);
-       PageNum += PageNeed;
-
-       BufIndex += PageNeed * 128;
-
-       /* 3 (5) Qos null data */
-       RsvdPageLoc.LocQosNull = PageNum;
-       ConstructNullFunctionData(adapt, &ReservedPagePacket[BufIndex],
-                                 &QosNullLength, get_my_bssid(&pmlmeinfo->network), true, 0, 0, false);
-       rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex - TxDescLen], QosNullLength, false, false);
-
-       PageNeed = (u8)PageNum_128(TxDescLen + QosNullLength);
-       PageNum += PageNeed;
-
-       TotalPacketLen = BufIndex + QosNullLength;
-       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-       if (!pmgntframe)
-               goto exit;
-
-       /*  update attribute */
-       pattrib = &pmgntframe->attrib;
-       update_mgntframe_attrib(adapt, pattrib);
-       pattrib->qsel = 0x10;
-       pattrib->last_txcmdsz = TotalPacketLen - TXDESC_OFFSET;
-       pattrib->pktlen = pattrib->last_txcmdsz;
-       memcpy(pmgntframe->buf_addr, ReservedPagePacket, TotalPacketLen);
-
-       rtl8188eu_mgnt_xmit(adapt, pmgntframe);
-
-       FillH2CCmd_88E(adapt, H2C_COM_RSVD_PAGE, sizeof(RsvdPageLoc), (u8 *)&RsvdPageLoc);
-
-exit:
-       kfree(ReservedPagePacket);
-}
-
-void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
-{
-       struct hal_data_8188e *haldata = &adapt->haldata;
-       struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       bool    bSendBeacon = false;
-       bool    bcn_valid = false;
-       u8 DLBcnCount = 0;
-       u32 poll = 0;
-       u8 reg;
-       int res;
-
-       if (mstatus == 1) {
-               /*  We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C. */
-               /*  Suggested by filen. Added by tynli. */
-               rtw_write16(adapt, REG_BCN_PSR_RPT, (0xC000 | pmlmeinfo->aid));
-               /*  Do not set TSF again here or vWiFi beacon DMA INT will not work. */
-
-               /* Set REG_CR bit 8. DMA beacon by SW. */
-               haldata->RegCR_1 |= BIT(0);
-               rtw_write8(adapt,  REG_CR + 1, haldata->RegCR_1);
-
-               /*  Disable Hw protection for a time which revserd for Hw sending beacon. */
-               /*  Fix download reserved page packet fail that access collision with the protection time. */
-               /*  2010.05.11. Added by tynli. */
-               res = rtw_read8(adapt, REG_BCN_CTRL, &reg);
-               if (res)
-                       return;
-
-               rtw_write8(adapt, REG_BCN_CTRL, reg & (~BIT(3)));
-
-               res = rtw_read8(adapt, REG_BCN_CTRL, &reg);
-               if (res)
-                       return;
-
-               rtw_write8(adapt, REG_BCN_CTRL, reg | BIT(4));
-
-               if (haldata->RegFwHwTxQCtrl & BIT(6))
-                       bSendBeacon = true;
-
-               /*  Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame. */
-               rtw_write8(adapt, REG_FWHW_TXQ_CTRL + 2, (haldata->RegFwHwTxQCtrl & (~BIT(6))));
-               haldata->RegFwHwTxQCtrl &= (~BIT(6));
-
-               clear_beacon_valid_bit(adapt);
-               DLBcnCount = 0;
-               poll = 0;
-               do {
-                       /*  download rsvd page. */
-                       SetFwRsvdPagePkt(adapt, false);
-                       DLBcnCount++;
-                       do {
-                               yield();
-                               /* mdelay(10); */
-                               /*  check rsvd page download OK. */
-                               bcn_valid = get_beacon_valid_bit(adapt);
-                               poll++;
-                       } while (!bcn_valid && (poll % 10) != 0 && !adapt->bSurpriseRemoved && !adapt->bDriverStopped);
-               } while (!bcn_valid && DLBcnCount <= 100 && !adapt->bSurpriseRemoved && !adapt->bDriverStopped);
-
-               /*  */
-               /*  We just can send the reserved page twice during the time that Tx thread is stopped (e.g. pnpsetpower) */
-               /*  because we need to free the Tx BCN Desc which is used by the first reserved page packet. */
-               /*  At run time, we cannot get the Tx Desc until it is released in TxHandleInterrupt() so we will return */
-               /*  the beacon TCB in the following code. 2011.11.23. by tynli. */
-               /*  */
-
-               /*  Enable Bcn */
-               res = rtw_read8(adapt, REG_BCN_CTRL, &reg);
-               if (res)
-                       return;
-
-               rtw_write8(adapt, REG_BCN_CTRL, reg | BIT(3));
-
-               res = rtw_read8(adapt, REG_BCN_CTRL, &reg);
-               if (res)
-                       return;
-
-               rtw_write8(adapt, REG_BCN_CTRL, reg & (~BIT(4)));
-
-               /*  To make sure that if there exists an adapter which would like to send beacon. */
-               /*  If exists, the origianl value of 0x422[6] will be 1, we should check this to */
-               /*  prevent from setting 0x422[6] to 0 after download reserved page, or it will cause */
-               /*  the beacon cannot be sent by HW. */
-               /*  2010.06.23. Added by tynli. */
-               if (bSendBeacon) {
-                       rtw_write8(adapt, REG_FWHW_TXQ_CTRL + 2, (haldata->RegFwHwTxQCtrl | BIT(6)));
-                       haldata->RegFwHwTxQCtrl |= BIT(6);
-               }
-
-               /*  Update RSVD page location H2C to Fw. */
-               if (bcn_valid)
-                       clear_beacon_valid_bit(adapt);
-
-               /*  Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli. */
-               /*  Clear CR[8] or beacon packet will not be send to TxBuf anymore. */
-               haldata->RegCR_1 &= (~BIT(0));
-               rtw_write8(adapt,  REG_CR + 1, haldata->RegCR_1);
-       }
-
-}
-
-void rtl8188e_set_p2p_ps_offload_cmd(struct adapter *adapt, u8 p2p_ps_state)
-{
-       struct hal_data_8188e *haldata = &adapt->haldata;
-       struct wifidirect_info  *pwdinfo = &adapt->wdinfo;
-       struct P2P_PS_Offload_t *p2p_ps_offload = &haldata->p2p_ps_offload;
-       u8 i;
-
-       switch (p2p_ps_state) {
-       case P2P_PS_DISABLE:
-               memset(p2p_ps_offload, 0, 1);
-               break;
-       case P2P_PS_ENABLE:
-               /*  update CTWindow value. */
-               if (pwdinfo->ctwindow > 0) {
-                       p2p_ps_offload->CTWindow_En = 1;
-                       rtw_write8(adapt, REG_P2P_CTWIN, pwdinfo->ctwindow);
-               }
-
-               /*  hw only support 2 set of NoA */
-               for (i = 0; i < pwdinfo->noa_num; i++) {
-                       /*  To control the register setting for which NOA */
-                       rtw_write8(adapt, REG_NOA_DESC_SEL, (i << 4));
-                       if (i == 0)
-                               p2p_ps_offload->NoA0_En = 1;
-                       else
-                               p2p_ps_offload->NoA1_En = 1;
-
-                       /*  config P2P NoA Descriptor Register */
-                       rtw_write32(adapt, REG_NOA_DESC_DURATION, pwdinfo->noa_duration[i]);
-                       rtw_write32(adapt, REG_NOA_DESC_INTERVAL, pwdinfo->noa_interval[i]);
-                       rtw_write32(adapt, REG_NOA_DESC_START, pwdinfo->noa_start_time[i]);
-                       rtw_write8(adapt, REG_NOA_DESC_COUNT, pwdinfo->noa_count[i]);
-               }
-
-               if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
-                       /*  rst p2p circuit */
-                       rtw_write8(adapt, REG_DUAL_TSF_RST, BIT(4));
-
-                       p2p_ps_offload->Offload_En = 1;
-
-                       if (pwdinfo->role == P2P_ROLE_GO) {
-                               p2p_ps_offload->role = 1;
-                               p2p_ps_offload->AllStaSleep = 0;
-                       } else {
-                               p2p_ps_offload->role = 0;
-                       }
-
-                       p2p_ps_offload->discovery = 0;
-               }
-               break;
-       case P2P_PS_SCAN:
-               p2p_ps_offload->discovery = 1;
-               break;
-       case P2P_PS_SCAN_DONE:
-               p2p_ps_offload->discovery = 0;
-               pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
-               break;
-       default:
-               break;
-       }
-
-       FillH2CCmd_88E(adapt, H2C_PS_P2P_OFFLOAD, 1, (u8 *)p2p_ps_offload);
-}
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_dm.c b/drivers/staging/r8188eu/hal/rtl8188e_dm.c
deleted file mode 100644 (file)
index 0399872..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-/*  This file is for 92CE/92CU dynamic mechanism only */
-#define _RTL8188E_DM_C_
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/rtl8188e_hal.h"
-
-/*  Initialize GPIO setting registers */
-static void dm_InitGPIOSetting(struct adapter *Adapter)
-{
-       u8      tmp1byte;
-       int res;
-
-       res = rtw_read8(Adapter, REG_GPIO_MUXCFG, &tmp1byte);
-       if (res)
-               return;
-
-       tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT);
-
-       rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte);
-}
-
-/*  */
-/*  functions */
-/*  */
-static void Update_ODM_ComInfo_88E(struct adapter *Adapter)
-{
-       struct mlme_ext_priv    *pmlmeext = &Adapter->mlmeextpriv;
-       struct mlme_priv        *pmlmepriv = &Adapter->mlmepriv;
-       struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
-       struct hal_data_8188e *hal_data = &Adapter->haldata;
-       struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
-       struct dm_priv  *pdmpriv = &hal_data->dmpriv;
-       int i;
-
-       pdmpriv->InitODMFlag = ODM_BB_RSSI_MONITOR;
-       if (hal_data->AntDivCfg)
-               pdmpriv->InitODMFlag |= ODM_BB_ANT_DIV;
-
-       dm_odm->SupportAbility = pdmpriv->InitODMFlag;
-
-       dm_odm->pWirelessMode = &pmlmeext->cur_wireless_mode;
-       dm_odm->pSecChOffset = &hal_data->nCur40MhzPrimeSC;
-       dm_odm->pBandWidth = &hal_data->CurrentChannelBW;
-       dm_odm->pChannel = &hal_data->CurrentChannel;
-       dm_odm->pbScanInProcess = &pmlmepriv->bScanInProcess;
-       dm_odm->pbPowerSaving = &pwrctrlpriv->bpower_saving;
-
-       ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_RF_ANTENNA_TYPE, hal_data->TRxAntDivType);
-
-       for (i = 0; i < NUM_STA; i++)
-               dm_odm->pODM_StaInfo[i] = NULL;
-}
-
-void rtl8188e_InitHalDm(struct adapter *Adapter)
-{
-       struct hal_data_8188e *hal_data = &Adapter->haldata;
-       struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
-
-       dm_InitGPIOSetting(Adapter);
-       Update_ODM_ComInfo_88E(Adapter);
-       ODM_DMInit(dm_odm);
-}
-
-void rtl8188e_HalDmWatchDog(struct adapter *Adapter)
-{
-       u8 hw_init_completed = Adapter->hw_init_completed;
-       struct hal_data_8188e *hal_data = &Adapter->haldata;
-       struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
-       u8 bLinked = false;
-
-       if (!hw_init_completed)
-               return;
-
-       if ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) ||
-           (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))) {
-               if (Adapter->stapriv.asoc_sta_count > 2)
-                       bLinked = true;
-       } else {/* Station mode */
-               if (check_fwstate(pmlmepriv, _FW_LINKED))
-                       bLinked = true;
-       }
-
-       hal_data->odmpriv.bLinked = bLinked;
-       ODM_DMWatchdog(&hal_data->odmpriv);
-}
-
-void rtl8188e_init_dm_priv(struct adapter *Adapter)
-{
-       struct hal_data_8188e *hal_data = &Adapter->haldata;
-       struct dm_priv  *pdmpriv = &hal_data->dmpriv;
-       struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
-
-       memset(pdmpriv, 0, sizeof(struct dm_priv));
-       memset(dm_odm, 0, sizeof(*dm_odm));
-
-       dm_odm->Adapter = Adapter;
-       ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_MP_TEST_CHIP, IS_NORMAL_CHIP(hal_data->VersionID));
-       ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_RF_ANTENNA_TYPE, hal_data->TRxAntDivType);
-}
-
-/*  Add new function to reset the state of antenna diversity before link. */
-/*  Compare RSSI for deciding antenna */
-void AntDivCompare8188E(struct adapter *Adapter, struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src)
-{
-       struct hal_data_8188e *hal_data = &Adapter->haldata;
-
-       if (0 != hal_data->AntDivCfg) {
-               /* select optimum_antenna for before linked =>For antenna diversity */
-               if (dst->Rssi >=  src->Rssi) {/* keep org parameter */
-                       src->Rssi = dst->Rssi;
-                       src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
-               }
-       }
-}
-
-/*  Add new function to reset the state of antenna diversity before link. */
-u8 AntDivBeforeLink8188E(struct adapter *Adapter)
-{
-       struct hal_data_8188e *hal_data = &Adapter->haldata;
-       struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
-       struct sw_ant_switch *dm_swat_tbl = &dm_odm->DM_SWAT_Table;
-       struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
-
-       /*  Condition that does not need to use antenna diversity. */
-       if (hal_data->AntDivCfg == 0)
-               return false;
-
-       if (check_fwstate(pmlmepriv, _FW_LINKED))
-               return false;
-
-       if (dm_swat_tbl->SWAS_NoLink_State == 0) {
-               /* switch channel */
-               dm_swat_tbl->SWAS_NoLink_State = 1;
-               dm_swat_tbl->CurAntenna = (dm_swat_tbl->CurAntenna == Antenna_A) ? Antenna_B : Antenna_A;
-
-               rtw_antenna_select_cmd(Adapter, dm_swat_tbl->CurAntenna, false);
-               return true;
-       } else {
-               dm_swat_tbl->SWAS_NoLink_State = 0;
-               return false;
-       }
-}
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
deleted file mode 100644 (file)
index 73855bc..0000000
+++ /dev/null
@@ -1,922 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#define _HAL_INIT_C_
-
-#include "../include/drv_types.h"
-#include "../include/rtw_efuse.h"
-#include "../include/rtl8188e_hal.h"
-#include "../include/rtw_iol.h"
-#include "../include/usb_ops.h"
-#include "../include/rtw_fw.h"
-
-static void iol_mode_enable(struct adapter *padapter, u8 enable)
-{
-       u8 reg_0xf0 = 0;
-       int res;
-
-       if (enable) {
-               /* Enable initial offload */
-               res = rtw_read8(padapter, REG_SYS_CFG, &reg_0xf0);
-               if (res)
-                       return;
-
-               rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 | SW_OFFLOAD_EN);
-
-               if (!padapter->bFWReady)
-                       rtw_reset_8051(padapter);
-
-       } else {
-               /* disable initial offload */
-               res = rtw_read8(padapter, REG_SYS_CFG, &reg_0xf0);
-               if (res)
-                       return;
-
-               rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN);
-       }
-}
-
-static s32 iol_execute(struct adapter *padapter, u8 control)
-{
-       s32 status = _FAIL;
-       u8 reg_0x88 = 0;
-       unsigned long timeout;
-       int res;
-
-       control = control & 0x0f;
-       res = rtw_read8(padapter, REG_HMEBOX_E0, &reg_0x88);
-       if (res)
-               return _FAIL;
-
-       rtw_write8(padapter, REG_HMEBOX_E0,  reg_0x88 | control);
-
-       timeout = jiffies + msecs_to_jiffies(1000);
-
-       do {
-               res = rtw_read8(padapter, REG_HMEBOX_E0, &reg_0x88);
-               if (res)
-                       continue;
-
-               if (!(reg_0x88 & control))
-                       break;
-
-       } while (time_before(jiffies, timeout));
-
-       res = rtw_read8(padapter, REG_HMEBOX_E0, &reg_0x88);
-       if (res)
-               return _FAIL;
-
-       status = (reg_0x88 & control) ? _FAIL : _SUCCESS;
-       if (reg_0x88 & control << 4)
-               status = _FAIL;
-       return status;
-}
-
-static s32 iol_InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
-{
-       s32 rst = _SUCCESS;
-       iol_mode_enable(padapter, 1);
-       rtw_write8(padapter, REG_TDECTRL + 1, txpktbuf_bndy);
-       rst = iol_execute(padapter, CMD_INIT_LLT);
-       iol_mode_enable(padapter, 0);
-       return rst;
-}
-
-static void
-efuse_phymap_to_logical(u8 *phymap, u16 _size_byte, u8  *pbuf)
-{
-       u8 *efuseTbl = NULL;
-       u8 rtemp8;
-       u16     eFuse_Addr = 0;
-       u8 offset, wren;
-       u16     i, j;
-       u16     **eFuseWord = NULL;
-       u8 u1temp = 0;
-
-       efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL);
-       if (!efuseTbl)
-               goto exit;
-
-       eFuseWord = rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
-       if (!eFuseWord)
-               goto exit;
-
-       /*  0. Refresh efuse init map as all oxFF. */
-       for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
-               for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
-                       eFuseWord[i][j] = 0xFFFF;
-
-       /*  */
-       /*  1. Read the first byte to check if efuse is empty!!! */
-       /*  */
-       /*  */
-       rtemp8 = *(phymap + eFuse_Addr);
-       if (rtemp8 != 0xFF) {
-               eFuse_Addr++;
-       } else {
-               goto exit;
-       }
-
-       /*  */
-       /*  2. Read real efuse content. Filter PG header and every section data. */
-       /*  */
-       while ((rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
-               /*  Check PG header for section num. */
-               if ((rtemp8 & 0x1F) == 0x0F) {          /* extended header */
-                       u1temp = ((rtemp8 & 0xE0) >> 5);
-                       rtemp8 = *(phymap + eFuse_Addr);
-                       if ((rtemp8 & 0x0F) == 0x0F) {
-                               eFuse_Addr++;
-                               rtemp8 = *(phymap + eFuse_Addr);
-
-                               if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
-                                       eFuse_Addr++;
-                               continue;
-                       } else {
-                               offset = ((rtemp8 & 0xF0) >> 1) | u1temp;
-                               wren = (rtemp8 & 0x0F);
-                               eFuse_Addr++;
-                       }
-               } else {
-                       offset = ((rtemp8 >> 4) & 0x0f);
-                       wren = (rtemp8 & 0x0f);
-               }
-
-               if (offset < EFUSE_MAX_SECTION_88E) {
-                       /*  Get word enable value from PG header */
-                       for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
-                               /*  Check word enable condition in the section */
-                               if (!(wren & 0x01)) {
-                                       rtemp8 = *(phymap + eFuse_Addr);
-                                       eFuse_Addr++;
-                                       eFuseWord[offset][i] = (rtemp8 & 0xff);
-                                       if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
-                                               break;
-                                       rtemp8 = *(phymap + eFuse_Addr);
-                                       eFuse_Addr++;
-                                       eFuseWord[offset][i] |= (((u16)rtemp8 << 8) & 0xff00);
-
-                                       if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
-                                               break;
-                               }
-                               wren >>= 1;
-                       }
-               }
-               /*  Read next PG header */
-               rtemp8 = *(phymap + eFuse_Addr);
-
-               if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
-                       eFuse_Addr++;
-               }
-       }
-
-       /*  */
-       /*  3. Collect 16 sections and 4 word unit into Efuse map. */
-       /*  */
-       for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) {
-               for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
-                       efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff);
-                       efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff);
-               }
-       }
-
-       /*  */
-       /*  4. Copy from Efuse map to output pointer memory!!! */
-       /*  */
-       memcpy(pbuf, efuseTbl, _size_byte);
-
-exit:
-       kfree(efuseTbl);
-       kfree(eFuseWord);
-}
-
-/* FIXME: add error handling in callers */
-static int efuse_read_phymap_from_txpktbuf(
-       struct adapter  *adapter,
-       u8 *content,    /* buffer to store efuse physical map */
-       u16 *size       /* for efuse content: the max byte to read. will update to byte read */
-       )
-{
-       unsigned long timeout;
-       __le32 lo32 = 0, hi32 = 0;
-       u16 len = 0, count = 0;
-       int i = 0, res;
-       u16 limit = *size;
-       u8 reg;
-       u8 *pos = content;
-       u32 reg32;
-
-       rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
-
-       while (1) {
-               rtw_write16(adapter, REG_PKTBUF_DBG_ADDR, i);
-
-               rtw_write8(adapter, REG_TXPKTBUF_DBG, 0);
-               timeout = jiffies + msecs_to_jiffies(1000);
-               do {
-                       res = rtw_read8(adapter, REG_TXPKTBUF_DBG, &reg);
-                       if (res)
-                               continue;
-
-                       if (reg)
-                               break;
-
-                       msleep(1);
-               } while (time_before(jiffies, timeout));
-
-               /* data from EEPROM needs to be in LE */
-               res = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L, &reg32);
-               if (res)
-                       return res;
-
-               lo32 = cpu_to_le32(reg32);
-
-               res = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H, &reg32);
-               if (res)
-                       return res;
-
-               hi32 = cpu_to_le32(reg32);
-
-               if (i == 0) {
-                       u16 reg;
-
-                       /* Although lenc is only used in a debug statement,
-                        * do not remove it as the rtw_read16() call consumes
-                        * 2 bytes from the EEPROM source.
-                        */
-                       res = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L, &reg);
-                       if (res)
-                               return res;
-
-                       len = le32_to_cpu(lo32) & 0x0000ffff;
-
-                       limit = (len - 2 < limit) ? len - 2 : limit;
-
-                       memcpy(pos, ((u8 *)&lo32) + 2, (limit >= count + 2) ? 2 : limit - count);
-                       count += (limit >= count + 2) ? 2 : limit - count;
-                       pos = content + count;
-               } else {
-                       memcpy(pos, ((u8 *)&lo32), (limit >= count + 4) ? 4 : limit - count);
-                       count += (limit >= count + 4) ? 4 : limit - count;
-                       pos = content + count;
-               }
-
-               if (limit > count && len - 2 > count) {
-                       memcpy(pos, (u8 *)&hi32, (limit >= count + 4) ? 4 : limit - count);
-                       count += (limit >= count + 4) ? 4 : limit - count;
-                       pos = content + count;
-               }
-
-               if (limit <= count || len - 2 <= count)
-                       break;
-               i++;
-       }
-       rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
-       *size = count;
-
-       return 0;
-}
-
-static s32 iol_read_efuse(struct adapter *padapter, u16 size_byte, u8 *logical_map)
-{
-       s32 status = _FAIL;
-       u8 physical_map[512];
-       u16 size = 512;
-
-       rtw_write8(padapter, REG_TDECTRL + 1, 0);
-       memset(physical_map, 0xFF, 512);
-       rtw_write8(padapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
-       status = iol_execute(padapter, CMD_READ_EFUSE_MAP);
-       if (status == _SUCCESS)
-               efuse_read_phymap_from_txpktbuf(padapter, physical_map, &size);
-       efuse_phymap_to_logical(physical_map, size_byte, logical_map);
-       return status;
-}
-
-s32 rtl8188e_iol_efuse_patch(struct adapter *padapter)
-{
-       s32     result = _SUCCESS;
-
-       if (rtw_IOL_applied(padapter)) {
-               iol_mode_enable(padapter, 1);
-               result = iol_execute(padapter, CMD_READ_EFUSE_MAP);
-               if (result == _SUCCESS)
-                       result = iol_execute(padapter, CMD_EFUSE_PATCH);
-
-               iol_mode_enable(padapter, 0);
-       }
-       return result;
-}
-
-static s32 iol_ioconfig(struct adapter *padapter, u8 iocfg_bndy)
-{
-       s32 rst = _SUCCESS;
-
-       rtw_write8(padapter, REG_TDECTRL + 1, iocfg_bndy);
-       rst = iol_execute(padapter, CMD_IOCONFIG);
-       return rst;
-}
-
-int rtl8188e_IOL_exec_cmds_sync(struct adapter *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt)
-{
-       struct pkt_attrib *pattrib = &xmit_frame->attrib;
-       u8 i;
-       int ret = _FAIL;
-
-       if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS)
-               goto exit;
-       if (rtw_usb_bulk_size_boundary(adapter, TXDESC_SIZE + pattrib->last_txcmdsz)) {
-               if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS)
-                       goto exit;
-       }
-
-       dump_mgntframe_and_wait(adapter, xmit_frame, max_wating_ms);
-
-       iol_mode_enable(adapter, 1);
-       for (i = 0; i < bndy_cnt; i++) {
-               u8 page_no = 0;
-               page_no = i * 2;
-               ret = iol_ioconfig(adapter, page_no);
-               if (ret != _SUCCESS)
-                       break;
-       }
-       iol_mode_enable(adapter, 0);
-exit:
-       /* restore BCN_HEAD */
-       rtw_write8(adapter, REG_TDECTRL + 1, 0);
-       return ret;
-}
-
-void rtl8188e_EfusePowerSwitch(struct adapter *pAdapter, u8 PwrState)
-{
-       u16     tmpV16;
-       int res;
-
-       if (PwrState) {
-               rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
-
-               /*  1.2V Power: From VDDON with Power Cut(0x0000h[15]), default valid */
-               res = rtw_read16(pAdapter, REG_SYS_ISO_CTRL, &tmpV16);
-               if (res)
-                       return;
-
-               if (!(tmpV16 & PWC_EV12V)) {
-                       tmpV16 |= PWC_EV12V;
-                       rtw_write16(pAdapter, REG_SYS_ISO_CTRL, tmpV16);
-               }
-               /*  Reset: 0x0000h[28], default valid */
-               res = rtw_read16(pAdapter, REG_SYS_FUNC_EN, &tmpV16);
-               if (res)
-                       return;
-
-               if (!(tmpV16 & FEN_ELDR)) {
-                       tmpV16 |= FEN_ELDR;
-                       rtw_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16);
-               }
-
-               /*  Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
-               res = rtw_read16(pAdapter, REG_SYS_CLKR, &tmpV16);
-               if (res)
-                       return;
-
-               if ((!(tmpV16 & LOADER_CLK_EN))  || (!(tmpV16 & ANA8M))) {
-                       tmpV16 |= (LOADER_CLK_EN | ANA8M);
-                       rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16);
-               }
-       } else {
-               rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
-       }
-}
-
-static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
-       u16                     _offset,
-       u16                     _size_byte,
-       u8 *pbuf)
-{
-       u8 *efuseTbl = NULL;
-       u8 rtemp8[1];
-       u16     eFuse_Addr = 0;
-       u8 offset, wren;
-       u16     i, j;
-       u16     **eFuseWord = NULL;
-       u16     efuse_utilized = 0;
-       u8 u1temp = 0;
-
-       /*  */
-       /*  Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
-       /*  */
-       if ((_offset + _size_byte) > EFUSE_MAP_LEN_88E) /*  total E-Fuse table is 512bytes */
-               goto exit;
-
-       efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL);
-       if (!efuseTbl)
-               goto exit;
-
-       eFuseWord = rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
-       if (!eFuseWord)
-               goto exit;
-
-       /*  0. Refresh efuse init map as all oxFF. */
-       for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
-               for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
-                       eFuseWord[i][j] = 0xFFFF;
-
-       /*  */
-       /*  1. Read the first byte to check if efuse is empty!!! */
-       /*  */
-       /*  */
-       ReadEFuseByte(Adapter, eFuse_Addr, rtemp8);
-       if (*rtemp8 != 0xFF) {
-               efuse_utilized++;
-               eFuse_Addr++;
-       } else {
-               goto exit;
-       }
-
-       /*  */
-       /*  2. Read real efuse content. Filter PG header and every section data. */
-       /*  */
-       while ((*rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
-               /*  Check PG header for section num. */
-               if ((*rtemp8 & 0x1F) == 0x0F) {         /* extended header */
-                       u1temp = ((*rtemp8 & 0xE0) >> 5);
-
-                       ReadEFuseByte(Adapter, eFuse_Addr, rtemp8);
-
-                       if ((*rtemp8 & 0x0F) == 0x0F) {
-                               eFuse_Addr++;
-                               ReadEFuseByte(Adapter, eFuse_Addr, rtemp8);
-
-                               if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
-                                       eFuse_Addr++;
-                               continue;
-                       } else {
-                               offset = ((*rtemp8 & 0xF0) >> 1) | u1temp;
-                               wren = (*rtemp8 & 0x0F);
-                               eFuse_Addr++;
-                       }
-               } else {
-                       offset = ((*rtemp8 >> 4) & 0x0f);
-                       wren = (*rtemp8 & 0x0f);
-               }
-
-               if (offset < EFUSE_MAX_SECTION_88E) {
-                       /*  Get word enable value from PG header */
-
-                       for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
-                               /*  Check word enable condition in the section */
-                               if (!(wren & 0x01)) {
-                                       ReadEFuseByte(Adapter, eFuse_Addr, rtemp8);
-                                       eFuse_Addr++;
-                                       efuse_utilized++;
-                                       eFuseWord[offset][i] = (*rtemp8 & 0xff);
-                                       if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
-                                               break;
-                                       ReadEFuseByte(Adapter, eFuse_Addr, rtemp8);
-                                       eFuse_Addr++;
-                                       efuse_utilized++;
-                                       eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
-                                       if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
-                                               break;
-                               }
-                               wren >>= 1;
-                       }
-               }
-
-               /*  Read next PG header */
-               ReadEFuseByte(Adapter, eFuse_Addr, rtemp8);
-
-               if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
-                       efuse_utilized++;
-                       eFuse_Addr++;
-               }
-       }
-
-       /*  3. Collect 16 sections and 4 word unit into Efuse map. */
-       for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) {
-               for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
-                       efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff);
-                       efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff);
-               }
-       }
-
-       /*  4. Copy from Efuse map to output pointer memory!!! */
-       for (i = 0; i < _size_byte; i++)
-               pbuf[i] = efuseTbl[_offset + i];
-
-exit:
-       kfree(efuseTbl);
-       kfree(eFuseWord);
-}
-
-void rtl8188e_ReadEFuse(struct adapter *Adapter, u16 _size_byte, u8 *pbuf)
-{
-       int ret = _FAIL;
-       if (rtw_IOL_applied(Adapter)) {
-               rtl8188eu_InitPowerOn(Adapter);
-
-               iol_mode_enable(Adapter, 1);
-               ret = iol_read_efuse(Adapter, _size_byte, pbuf);
-               iol_mode_enable(Adapter, 0);
-
-               if (_SUCCESS == ret)
-                       return;
-       }
-
-       Hal_EfuseReadEFuse88E(Adapter, 0, _size_byte, pbuf);
-}
-
-static void dump_chip_info(struct adapter *adapter, struct HAL_VERSION chip_vers)
-{
-       struct net_device *netdev = adapter->pnetdev;
-       char *cut = NULL;
-       char buf[25];
-
-       switch (chip_vers.CUTVersion) {
-       case A_CUT_VERSION:
-               cut = "A_CUT";
-               break;
-       case B_CUT_VERSION:
-               cut = "B_CUT";
-               break;
-       case C_CUT_VERSION:
-               cut = "C_CUT";
-               break;
-       case D_CUT_VERSION:
-               cut = "D_CUT";
-               break;
-       case E_CUT_VERSION:
-               cut = "E_CUT";
-               break;
-       default:
-               snprintf(buf, sizeof(buf), "UNKNOWN_CUT(%d)", chip_vers.CUTVersion);
-               cut = buf;
-               break;
-       }
-
-       netdev_dbg(netdev, "Chip Version Info: CHIP_8188E_%s_%s_%s_1T1R_RomVer(%d)\n",
-                  IS_NORMAL_CHIP(chip_vers) ? "Normal_Chip" : "Test_Chip",
-                  IS_CHIP_VENDOR_TSMC(chip_vers) ? "TSMC" : "UMC",
-                  cut, 0);
-}
-
-void rtl8188e_read_chip_version(struct adapter *padapter)
-{
-       u32                             value32;
-       struct HAL_VERSION              ChipVersion;
-       struct hal_data_8188e *pHalData = &padapter->haldata;
-       int res;
-
-       res = rtw_read32(padapter, REG_SYS_CFG, &value32);
-       if (res)
-               return;
-
-       ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
-
-       ChipVersion.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
-       ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK) >> CHIP_VER_RTL_SHIFT; /*  IC version (CUT) */
-
-       dump_chip_info(padapter, ChipVersion);
-
-       pHalData->VersionID = ChipVersion;
-}
-
-void rtl8188e_SetHalODMVar(struct adapter *Adapter, void *pValue1, bool bSet)
-{
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-       struct odm_dm_struct *podmpriv = &pHalData->odmpriv;
-       struct sta_info *psta = (struct sta_info *)pValue1;
-
-       if (bSet) {
-               podmpriv->pODM_StaInfo[psta->mac_id] = psta;
-               ODM_RAInfo_Init(podmpriv, psta->mac_id);
-       } else {
-               podmpriv->pODM_StaInfo[psta->mac_id] = NULL;
-       }
-}
-
-void hal_notch_filter_8188e(struct adapter *adapter, bool enable)
-{
-       int res;
-       u8 reg;
-
-       res = rtw_read8(adapter, rOFDM0_RxDSP + 1, &reg);
-       if (res)
-               return;
-
-       if (enable)
-               rtw_write8(adapter, rOFDM0_RxDSP + 1, reg | BIT(1));
-       else
-               rtw_write8(adapter, rOFDM0_RxDSP + 1, reg & ~BIT(1));
-}
-
-/*  */
-/*  */
-/*  LLT R/W/Init function */
-/*  */
-/*  */
-static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data)
-{
-       s32     count;
-       u32     value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
-       u16     LLTReg = REG_LLT_INIT;
-       int res;
-
-       rtw_write32(padapter, LLTReg, value);
-
-       /* polling */
-       for (count = 0; count <= POLLING_LLT_THRESHOLD; count++) {
-               res = rtw_read32(padapter, LLTReg, &value);
-               if (res)
-                       continue;
-
-               if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
-                       break;
-       }
-
-       return count > POLLING_LLT_THRESHOLD ? _FAIL : _SUCCESS;
-}
-
-s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
-{
-       s32     status = _FAIL;
-       u32     i;
-       u32     Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER;/*  176, 22k */
-
-       if (rtw_IOL_applied(padapter)) {
-               status = iol_InitLLTTable(padapter, txpktbuf_bndy);
-       } else {
-               for (i = 0; i < (txpktbuf_bndy - 1); i++) {
-                       status = _LLTWrite(padapter, i, i + 1);
-                       if (_SUCCESS != status)
-                               return status;
-               }
-
-               /*  end of list */
-               status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF);
-               if (_SUCCESS != status)
-                       return status;
-
-               /*  Make the other pages as ring buffer */
-               /*  This ring buffer is used as beacon buffer if we config this MAC as two MAC transfer. */
-               /*  Otherwise used as local loopback buffer. */
-               for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) {
-                       status = _LLTWrite(padapter, i, (i + 1));
-                       if (_SUCCESS != status)
-                               return status;
-               }
-
-               /*  Let last entry point to the start entry of ring buffer */
-               status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy);
-               if (_SUCCESS != status) {
-                       return status;
-               }
-       }
-
-       return status;
-}
-
-void Hal_EfuseParseIDCode88E(struct adapter *padapter, u8 *hwinfo)
-{
-       struct eeprom_priv *pEEPROM = &padapter->eeprompriv;
-       struct net_device *netdev = padapter->pnetdev;
-       u16                     EEPROMId;
-
-       /*  Check 0x8129 again for making sure autoload status!! */
-       EEPROMId = le16_to_cpu(*((__le16 *)hwinfo));
-       if (EEPROMId != RTL_EEPROM_ID) {
-               pr_err("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
-               pEEPROM->bautoload_fail_flag = true;
-       } else {
-               pEEPROM->bautoload_fail_flag = false;
-       }
-
-       netdev_dbg(netdev, "EEPROM ID = 0x%04x\n", EEPROMId);
-}
-
-static void Hal_ReadPowerValueFromPROM_8188E(struct txpowerinfo24g *pwrInfo24G, u8 *PROMContent, bool AutoLoadFail)
-{
-       u32 rfPath, eeAddr = EEPROM_TX_PWR_INX_88E, group, TxCount = 0;
-
-       memset(pwrInfo24G, 0, sizeof(struct txpowerinfo24g));
-
-       if (AutoLoadFail) {
-               for (rfPath = 0; rfPath < RF_PATH_MAX; rfPath++) {
-                       /* 2.4G default value */
-                       for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
-                               pwrInfo24G->IndexCCK_Base[rfPath][group] =      EEPROM_DEFAULT_24G_INDEX;
-                               pwrInfo24G->IndexBW40_Base[rfPath][group] =     EEPROM_DEFAULT_24G_INDEX;
-                       }
-                       for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
-                               if (TxCount == 0) {
-                                       pwrInfo24G->BW20_Diff[rfPath][0] = EEPROM_DEFAULT_24G_HT20_DIFF;
-                                       pwrInfo24G->OFDM_Diff[rfPath][0] = EEPROM_DEFAULT_24G_OFDM_DIFF;
-                               } else {
-                                       pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
-                                       pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
-                                       pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
-                                       pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
-                               }
-                       }
-               }
-               return;
-       }
-
-       for (rfPath = 0; rfPath < RF_PATH_MAX; rfPath++) {
-               /* 2.4G default value */
-               for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
-                       pwrInfo24G->IndexCCK_Base[rfPath][group] =      PROMContent[eeAddr++];
-                       if (pwrInfo24G->IndexCCK_Base[rfPath][group] == 0xFF)
-                               pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
-               }
-               for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) {
-                       pwrInfo24G->IndexBW40_Base[rfPath][group] =     PROMContent[eeAddr++];
-                       if (pwrInfo24G->IndexBW40_Base[rfPath][group] == 0xFF)
-                               pwrInfo24G->IndexBW40_Base[rfPath][group] =     EEPROM_DEFAULT_24G_INDEX;
-               }
-               for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
-                       if (TxCount == 0) {
-                               pwrInfo24G->BW40_Diff[rfPath][TxCount] = 0;
-                               if (PROMContent[eeAddr] == 0xFF) {
-                                       pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_24G_HT20_DIFF;
-                               } else {
-                                       pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0xf0) >> 4;
-                                       if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT(3))            /* 4bit sign number to 8 bit sign number */
-                                               pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
-                               }
-
-                               if (PROMContent[eeAddr] == 0xFF) {
-                                       pwrInfo24G->OFDM_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_24G_OFDM_DIFF;
-                               } else {
-                                       pwrInfo24G->OFDM_Diff[rfPath][TxCount] =        (PROMContent[eeAddr] & 0x0f);
-                                       if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT(3))            /* 4bit sign number to 8 bit sign number */
-                                               pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
-                               }
-                               pwrInfo24G->CCK_Diff[rfPath][TxCount] = 0;
-                               eeAddr++;
-                       } else {
-                               if (PROMContent[eeAddr] == 0xFF) {
-                                       pwrInfo24G->BW40_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_DIFF;
-                               } else {
-                                       pwrInfo24G->BW40_Diff[rfPath][TxCount] =        (PROMContent[eeAddr] & 0xf0) >> 4;
-                                       if (pwrInfo24G->BW40_Diff[rfPath][TxCount] & BIT(3))            /* 4bit sign number to 8 bit sign number */
-                                               pwrInfo24G->BW40_Diff[rfPath][TxCount] |= 0xF0;
-                               }
-
-                               if (PROMContent[eeAddr] == 0xFF) {
-                                       pwrInfo24G->BW20_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_DIFF;
-                               } else {
-                                       pwrInfo24G->BW20_Diff[rfPath][TxCount] =        (PROMContent[eeAddr] & 0x0f);
-                                       if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT(3))            /* 4bit sign number to 8 bit sign number */
-                                               pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
-                               }
-                               eeAddr++;
-
-                               if (PROMContent[eeAddr] == 0xFF) {
-                                       pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
-                               } else {
-                                       pwrInfo24G->OFDM_Diff[rfPath][TxCount] =        (PROMContent[eeAddr] & 0xf0) >> 4;
-                                       if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT(3))            /* 4bit sign number to 8 bit sign number */
-                                               pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
-                               }
-
-                               if (PROMContent[eeAddr] == 0xFF) {
-                                       pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
-                               } else {
-                                       pwrInfo24G->CCK_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0x0f);
-                                       if (pwrInfo24G->CCK_Diff[rfPath][TxCount] & BIT(3))             /* 4bit sign number to 8 bit sign number */
-                                               pwrInfo24G->CCK_Diff[rfPath][TxCount] |= 0xF0;
-                               }
-                               eeAddr++;
-                       }
-               }
-       }
-}
-
-static void hal_get_chnl_group_88e(u8 chnl, u8 *group)
-{
-       if (chnl < 3)                   /*  Channel 1-2 */
-               *group = 0;
-       else if (chnl < 6)              /*  Channel 3-5 */
-               *group = 1;
-       else if (chnl < 9)              /*  Channel 6-8 */
-               *group = 2;
-       else if (chnl < 12)             /*  Channel 9-11 */
-               *group = 3;
-       else if (chnl < 14)             /*  Channel 12-13 */
-               *group = 4;
-       else if (chnl == 14)            /*  Channel 14 */
-               *group = 5;
-}
-
-void Hal_ReadPowerSavingMode88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
-{
-       if (AutoLoadFail)
-               padapter->pwrctrlpriv.bSupportRemoteWakeup = false;
-       else
-               /* hw power down mode selection , 0:rf-off / 1:power down */
-
-               /*  decide hw if support remote wakeup function */
-               /*  if hw supported, 8051 (SIE) will generate WeakUP signal(D+/D- toggle) when autoresume */
-               padapter->pwrctrlpriv.bSupportRemoteWakeup = (hwinfo[EEPROM_USB_OPTIONAL_FUNCTION0] & BIT(1)) ? true : false;
-}
-
-void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *PROMContent, bool AutoLoadFail)
-{
-       struct hal_data_8188e *pHalData = &padapter->haldata;
-       struct txpowerinfo24g pwrInfo24G;
-       u8 ch, group;
-       u8 TxCount;
-
-       Hal_ReadPowerValueFromPROM_8188E(&pwrInfo24G, PROMContent, AutoLoadFail);
-
-       for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
-               hal_get_chnl_group_88e(ch, &group);
-
-               pHalData->Index24G_CCK_Base[ch] = pwrInfo24G.IndexCCK_Base[0][group];
-               if (ch == 14)
-                       pHalData->Index24G_BW40_Base[ch] = pwrInfo24G.IndexBW40_Base[0][4];
-               else
-                       pHalData->Index24G_BW40_Base[ch] = pwrInfo24G.IndexBW40_Base[0][group];
-       }
-       for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
-               pHalData->OFDM_24G_Diff[TxCount] = pwrInfo24G.OFDM_Diff[0][TxCount];
-               pHalData->BW20_24G_Diff[TxCount] = pwrInfo24G.BW20_Diff[0][TxCount];
-       }
-
-       /*  2010/10/19 MH Add Regulator recognize for CU. */
-       if (!AutoLoadFail) {
-               pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_88E] & 0x7);   /* bit0~2 */
-               if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
-                       pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION & 0x7);       /* bit0~2 */
-       } else {
-               pHalData->EEPROMRegulatory = 0;
-       }
-}
-
-void Hal_EfuseParseXtal_8188E(struct adapter *pAdapter, u8 *hwinfo, bool AutoLoadFail)
-{
-       struct hal_data_8188e *pHalData = &pAdapter->haldata;
-
-       if (!AutoLoadFail) {
-               pHalData->CrystalCap = hwinfo[EEPROM_XTAL_88E];
-               if (pHalData->CrystalCap == 0xFF)
-                       pHalData->CrystalCap = EEPROM_Default_CrystalCap_88E;
-       } else {
-               pHalData->CrystalCap = EEPROM_Default_CrystalCap_88E;
-       }
-}
-
-void rtl8188e_EfuseParseChnlPlan(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
-{
-       padapter->mlmepriv.ChannelPlan =
-                hal_com_get_channel_plan(padapter,
-                                         hwinfo ? hwinfo[EEPROM_ChannelPlan_88E] : 0xFF,
-                                         padapter->registrypriv.channel_plan,
-                                         RT_CHANNEL_DOMAIN_WORLD_WIDE_13, AutoLoadFail);
-}
-
-void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter, u8 *PROMContent, bool AutoLoadFail)
-{
-       struct hal_data_8188e *pHalData = &pAdapter->haldata;
-       struct registry_priv    *registry_par = &pAdapter->registrypriv;
-
-       if (!AutoLoadFail) {
-               /*  Antenna Diversity setting. */
-               if (registry_par->antdiv_cfg == 2) { /*  2:By EFUSE */
-                       pHalData->AntDivCfg = (PROMContent[EEPROM_RF_BOARD_OPTION_88E] & 0x18) >> 3;
-                       if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
-                               pHalData->AntDivCfg = (EEPROM_DEFAULT_BOARD_OPTION & 0x18) >> 3;
-               } else {
-                       pHalData->AntDivCfg = registry_par->antdiv_cfg;  /*  0:OFF , 1:ON, 2:By EFUSE */
-               }
-
-               if (registry_par->antdiv_type == 0) {
-                       /* If TRxAntDivType is AUTO in advanced setting, use EFUSE value instead. */
-                       pHalData->TRxAntDivType = PROMContent[EEPROM_RF_ANTENNA_OPT_88E];
-                       if (pHalData->TRxAntDivType == 0xFF)
-                               pHalData->TRxAntDivType = CG_TRX_HW_ANTDIV; /*  For 88EE, 1Tx and 1RxCG are fixed.(1Ant, Tx and RxCG are both on aux port) */
-               } else {
-                       pHalData->TRxAntDivType = registry_par->antdiv_type;
-               }
-
-               if (pHalData->TRxAntDivType == CG_TRX_HW_ANTDIV || pHalData->TRxAntDivType == CGCS_RX_HW_ANTDIV)
-                       pHalData->AntDivCfg = 1; /*  0xC1[3] is ignored. */
-       } else {
-               pHalData->AntDivCfg = 0;
-       }
-}
-
-void Hal_ReadThermalMeter_88E(struct adapter *Adapter, u8 *PROMContent, bool AutoloadFail)
-{
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-
-       /*  ThermalMeter from EEPROM */
-       if (!AutoloadFail)
-               pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_88E];
-       else
-               pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E;
-
-       if (pHalData->EEPROMThermalMeter == 0xff || AutoloadFail)
-               pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E;
-}
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
deleted file mode 100644 (file)
index f4edf4a..0000000
+++ /dev/null
@@ -1,705 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#define _RTL8188E_PHYCFG_C_
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/rtw_iol.h"
-#include "../include/rtl8188e_hal.h"
-
-/*  */
-/*  1. BB register R/W API */
-/*  */
-
-/* Get shifted position of the bit mask */
-static u32 phy_calculate_bit_shift(u32 bitmask)
-{
-       u32 i = ffs(bitmask);
-
-       return i ? i - 1 : 32;
-}
-
-/**
-* Function:    PHY_QueryBBReg
-*
-* Overview:    Read "sepcific bits" from BB register
-*
-* Input:
-*                      struct adapter *Adapter,
-*                      u32                     RegAddr,        The target address to be readback
-*                      u32                     BitMask         The target bit position in the target address
-*                                                              to be readback
-* Output:      None
-* Return:              u32                     Data            The readback register value
-* Note:                This function is equal to "GetRegSetting" in PHY programming guide
-*/
-u32
-rtl8188e_PHY_QueryBBReg(
-               struct adapter *Adapter,
-               u32 RegAddr,
-               u32 BitMask
-       )
-{
-       u32 ReturnValue = 0, OriginalValue, BitShift;
-       int res;
-
-       res = rtw_read32(Adapter, RegAddr, &OriginalValue);
-       if (res)
-               return 0;
-
-       BitShift = phy_calculate_bit_shift(BitMask);
-       ReturnValue = (OriginalValue & BitMask) >> BitShift;
-       return ReturnValue;
-}
-
-/**
-* Function:    PHY_SetBBReg
-*
-* Overview:    Write "Specific bits" to BB register (page 8~)
-*
-* Input:
-*                      struct adapter *Adapter,
-*                      u32                     RegAddr,        The target address to be modified
-*                      u32                     BitMask         The target bit position in the target address
-*                                                                      to be modified
-*                      u32                     Data            The new register value in the target bit position
-*                                                                      of the target address
-*
-* Output:      None
-* Return:              None
-* Note:                This function is equal to "PutRegSetting" in PHY programming guide
-*/
-
-void rtl8188e_PHY_SetBBReg(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data)
-{
-       u32 OriginalValue, BitShift;
-       int res;
-
-       if (BitMask != bMaskDWord) { /* if not "double word" write */
-               res = rtw_read32(Adapter, RegAddr, &OriginalValue);
-               if (res)
-                       return;
-
-               BitShift = phy_calculate_bit_shift(BitMask);
-               Data = ((OriginalValue & (~BitMask)) | (Data << BitShift));
-       }
-
-       rtw_write32(Adapter, RegAddr, Data);
-}
-
-/*  */
-/*  2. RF register R/W API */
-/*  */
-/**
-* Function:    phy_RFSerialRead
-*
-* Overview:    Read register from RF chips
-*
-* Input:
-*                      struct adapter *Adapter,
-*                      u32                     Offset,         The target address to be read
-*
-* Output:      None
-* Return:              u32                     reback value
-* Note:                Threre are three types of serial operations:
-*                      1. Software serial write
-*                      2. Hardware LSSI-Low Speed Serial Interface
-*                      3. Hardware HSSI-High speed
-*                      serial write. Driver need to implement (1) and (2).
-*                      This function is equal to the combination of RF_ReadReg() and  RFLSSIRead()
-*/
-static u32
-phy_RFSerialRead(
-               struct adapter *Adapter,
-               u32 Offset
-       )
-{
-       u32 retValue = 0;
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-       struct bb_reg_def *pPhyReg = &pHalData->PHYRegDef;
-       u32 NewOffset;
-       u32 tmplong, tmplong2;
-       u8      RfPiEnable = 0;
-       /*  */
-       /*  Make sure RF register offset is correct */
-       /*  */
-       Offset &= 0xff;
-
-       /*  */
-       /*  Switch page for 8256 RF IC */
-       /*  */
-       NewOffset = Offset;
-
-       /*  For 92S LSSI Read RFLSSIRead */
-       /*  For RF A/B write 0x824/82c(does not work in the future) */
-       /*  We must use 0x824 for RF A and B to execute read trigger */
-       tmplong = rtl8188e_PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord);
-       tmplong2 = tmplong;
-
-       tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset << 23) | bLSSIReadEdge;        /* T65 RF */
-
-       rtl8188e_PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord, tmplong & (~bLSSIReadEdge));
-       udelay(10);/*  PlatformStallExecution(10); */
-
-       rtl8188e_PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, bMaskDWord, tmplong2);
-       udelay(100);/* PlatformStallExecution(100); */
-
-       udelay(10);/* PlatformStallExecution(10); */
-
-       RfPiEnable = (u8)rtl8188e_PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter1, BIT(8));
-
-       if (RfPiEnable) {       /*  Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF */
-               retValue = rtl8188e_PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBackPi, bLSSIReadBackData);
-       } else {        /* Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF */
-               retValue = rtl8188e_PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBack, bLSSIReadBackData);
-       }
-       return retValue;
-}
-
-/**
-* Function:    phy_RFSerialWrite
-*
-* Overview:    Write data to RF register (page 8~)
-*
-* Input:
-*                      struct adapter *Adapter,
-*                      enum rf_radio_path eRFPath,     Radio path of A/B/C/D
-*                      u32                     Offset,         The target address to be read
-*                      u32                     Data            The new register Data in the target bit position
-*                                                                      of the target to be read
-*
-* Output:      None
-* Return:              None
-* Note:                Threre are three types of serial operations:
-*                      1. Software serial write
-*                      2. Hardware LSSI-Low Speed Serial Interface
-*                      3. Hardware HSSI-High speed
-*                      serial write. Driver need to implement (1) and (2).
-*                      This function is equal to the combination of RF_ReadReg() and  RFLSSIRead()
- *
- * Note:                 For RF8256 only
- *                      The total count of RTL8256(Zebra4) register is around 36 bit it only employs
- *                      4-bit RF address. RTL8256 uses "register mode control bit" (Reg00[12], Reg00[10])
- *                      to access register address bigger than 0xf. See "Appendix-4 in PHY Configuration
- *                      programming guide" for more details.
- *                      Thus, we define a sub-finction for RTL8526 register address conversion
- *                    ===========================================================
- *                      Register Mode          RegCTL[1]               RegCTL[0]               Note
- *                                                             (Reg00[12])             (Reg00[10])
- *                    ===========================================================
- *                      Reg_Mode0                              0                               x                       Reg 0 ~15(0x0 ~ 0xf)
- *                    ------------------------------------------------------------------
- *                      Reg_Mode1                              1                               0                       Reg 16 ~30(0x1 ~ 0xf)
- *                    ------------------------------------------------------------------
- *                      Reg_Mode2                              1                               1                       Reg 31 ~ 45(0x1 ~ 0xf)
- *                    ------------------------------------------------------------------
- *
- *     2008/09/02      MH      Add 92S RF definition
- *
- *
- *
-*/
-static void
-phy_RFSerialWrite(
-               struct adapter *Adapter,
-               u32 Offset,
-               u32 Data
-       )
-{
-       u32 DataAndAddr = 0;
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-       struct bb_reg_def *pPhyReg = &pHalData->PHYRegDef;
-       u32 NewOffset;
-
-       /*  2009/06/17 MH We can not execute IO for power save or other accident mode. */
-
-       Offset &= 0xff;
-
-       /*  */
-       /*  Switch page for 8256 RF IC */
-       /*  */
-       NewOffset = Offset;
-
-       /*  */
-       /*  Put write addr in [5:0]  and write data in [31:16] */
-       /*  */
-       DataAndAddr = ((NewOffset << 20) | (Data & 0x000fffff)) & 0x0fffffff;   /*  T65 RF */
-
-       /*  */
-       /*  Write Operation */
-       /*  */
-       rtl8188e_PHY_SetBBReg(Adapter, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr);
-}
-
-/**
-* Function:    PHY_QueryRFReg
-*
-* Overview:    Query "Specific bits" to RF register (page 8~)
-*
-* Input:
-*                      struct adapter *Adapter,
-*                      u32                     RegAddr,        The target address to be read
-*                      u32                     BitMask         The target bit position in the target address
-*                                                                      to be read
-*
-* Output:      None
-* Return:              u32                     Readback value
-* Note:                This function is equal to "GetRFRegSetting" in PHY programming guide
-*/
-u32 rtl8188e_PHY_QueryRFReg(struct adapter *Adapter, u32 RegAddr, u32 BitMask)
-{
-       u32 Original_Value, Readback_Value, BitShift;
-
-       Original_Value = phy_RFSerialRead(Adapter, RegAddr);
-
-       BitShift =  phy_calculate_bit_shift(BitMask);
-       Readback_Value = (Original_Value & BitMask) >> BitShift;
-       return Readback_Value;
-}
-
-/**
-* Function:    PHY_SetRFReg
-*
-* Overview:    Write "Specific bits" to RF register (page 8~)
-*
-* Input:
-*                      struct adapter *Adapter,
-*                      u32                     RegAddr,        The target address to be modified
-*                      u32                     BitMask         The target bit position in the target address
-*                                                                      to be modified
-*                      u32                     Data            The new register Data in the target bit position
-*                                                                      of the target address
-*
-* Output:      None
-* Return:              None
-* Note:                This function is equal to "PutRFRegSetting" in PHY programming guide
-*/
-void
-rtl8188e_PHY_SetRFReg(
-               struct adapter *Adapter,
-               u32 RegAddr,
-               u32 BitMask,
-               u32 Data
-       )
-{
-       u32 Original_Value, BitShift;
-
-       /*  RF data is 12 bits only */
-       if (BitMask != bRFRegOffsetMask) {
-               Original_Value = phy_RFSerialRead(Adapter, RegAddr);
-               BitShift =  phy_calculate_bit_shift(BitMask);
-               Data = ((Original_Value & (~BitMask)) | (Data << BitShift));
-       }
-
-       phy_RFSerialWrite(Adapter, RegAddr, Data);
-}
-
-/*  */
-/*  3. Initial MAC/BB/RF config by reading MAC/BB/RF txt. */
-/*  */
-
-/*-----------------------------------------------------------------------------
- * Function:    PHY_MACConfig8192C
- *
- * Overview:   Condig MAC by header file or parameter file.
- *
- * Input:       NONE
- *
- * Output:      NONE
- *
- * Return:      NONE
- *
- * Revised History:
- *  When               Who             Remark
- *  08/12/2008 MHC             Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-int PHY_MACConfig8188E(struct adapter *Adapter)
-{
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-       int err;
-
-       /*  */
-       /*  Config MAC */
-       /*  */
-       err = ODM_ReadAndConfig_MAC_REG_8188E(&pHalData->odmpriv);
-
-       /*  2010.07.13 AMPDU aggregation number B */
-       rtw_write16(Adapter, REG_MAX_AGGR_NUM, MAX_AGGR_NUM);
-
-       return err;
-}
-
-/**
-* Function:    phy_InitBBRFRegisterDefinition
-*
-* Overview:    Initialize Register definition offset for Radio Path A/B/C/D
-*
-* Input:
-*                      struct adapter *Adapter,
-*
-* Output:      None
-* Return:              None
-* Note:                The initialization value is constant and it should never be changes
-*/
-static void
-phy_InitBBRFRegisterDefinition(
-               struct adapter *Adapter
-)
-{
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-
-       /*  RF Interface Sowrtware Control */
-       pHalData->PHYRegDef.rfintfs = rFPGA0_XAB_RFInterfaceSW; /*  16 LSBs if read 32-bit from 0x870 */
-
-       /*  RF Interface Readback Value */
-       pHalData->PHYRegDef.rfintfi = rFPGA0_XAB_RFInterfaceRB; /*  16 LSBs if read 32-bit from 0x8E0 */
-
-       /*  RF Interface Output (and Enable) */
-       pHalData->PHYRegDef.rfintfo = rFPGA0_XA_RFInterfaceOE; /*  16 LSBs if read 32-bit from 0x860 */
-
-       /*  RF Interface (Output and)  Enable */
-       pHalData->PHYRegDef.rfintfe = rFPGA0_XA_RFInterfaceOE; /*  16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */
-
-       /* Addr of LSSI. Write RF register by driver */
-       pHalData->PHYRegDef.rf3wireOffset = rFPGA0_XA_LSSIParameter; /* LSSI Parameter */
-
-       /*  RF parameter */
-       pHalData->PHYRegDef.rfLSSI_Select = rFPGA0_XAB_RFParameter;  /* BB Band Select */
-
-       /*  Tx AGC Gain Stage (same for all path. Should we remove this?) */
-       pHalData->PHYRegDef.rfTxGainStage = rFPGA0_TxGainStage; /* Tx gain stage */
-
-       /*  Transceiver A~D HSSI Parameter-1 */
-       pHalData->PHYRegDef.rfHSSIPara1 = rFPGA0_XA_HSSIParameter1;  /* wire control parameter1 */
-
-       /*  Transceiver A~D HSSI Parameter-2 */
-       pHalData->PHYRegDef.rfHSSIPara2 = rFPGA0_XA_HSSIParameter2;  /* wire control parameter2 */
-
-       /*  RF switch Control */
-       pHalData->PHYRegDef.rfSwitchControl = rFPGA0_XAB_SwitchControl; /* TR/Ant switch control */
-
-       /*  AGC control 1 */
-       pHalData->PHYRegDef.rfAGCControl1 = rOFDM0_XAAGCCore1;
-
-       /*  AGC control 2 */
-       pHalData->PHYRegDef.rfAGCControl2 = rOFDM0_XAAGCCore2;
-
-       /*  RX AFE control 1 */
-       pHalData->PHYRegDef.rfRxIQImbalance = rOFDM0_XARxIQImbalance;
-
-       /*  RX AFE control 1 */
-       pHalData->PHYRegDef.rfRxAFE = rOFDM0_XARxAFE;
-
-       /*  Tx AFE control 1 */
-       pHalData->PHYRegDef.rfTxIQImbalance = rOFDM0_XATxIQImbalance;
-
-       /*  Tx AFE control 2 */
-       pHalData->PHYRegDef.rfTxAFE = rOFDM0_XATxAFE;
-
-       /*  Transceiver LSSI Readback SI mode */
-       pHalData->PHYRegDef.rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
-
-       /*  Transceiver LSSI Readback PI mode */
-       pHalData->PHYRegDef.rfLSSIReadBackPi = TransceiverA_HSPI_Readback;
-}
-
-void storePwrIndexDiffRateOffset(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data)
-{
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-
-       if (RegAddr == rTxAGC_A_Rate18_06)
-               pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][0] = Data;
-       if (RegAddr == rTxAGC_A_Rate54_24)
-               pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][1] = Data;
-       if (RegAddr == rTxAGC_A_CCK1_Mcs32)
-               pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][6] = Data;
-       if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0xffffff00)
-               pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][7] = Data;
-       if (RegAddr == rTxAGC_A_Mcs03_Mcs00)
-               pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][2] = Data;
-       if (RegAddr == rTxAGC_A_Mcs07_Mcs04)
-               pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][3] = Data;
-       if (RegAddr == rTxAGC_A_Mcs11_Mcs08)
-               pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][4] = Data;
-       if (RegAddr == rTxAGC_A_Mcs15_Mcs12) {
-               pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][5] = Data;
-               pHalData->pwrGroupCnt++;
-       }
-       if (RegAddr == rTxAGC_B_Rate18_06)
-               pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][8] = Data;
-       if (RegAddr == rTxAGC_B_Rate54_24)
-               pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][9] = Data;
-       if (RegAddr == rTxAGC_B_CCK1_55_Mcs32)
-               pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][14] = Data;
-       if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0x000000ff)
-               pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][15] = Data;
-       if (RegAddr == rTxAGC_B_Mcs03_Mcs00)
-               pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][10] = Data;
-       if (RegAddr == rTxAGC_B_Mcs07_Mcs04)
-               pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][11] = Data;
-       if (RegAddr == rTxAGC_B_Mcs11_Mcs08)
-               pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][12] = Data;
-       if (RegAddr == rTxAGC_B_Mcs15_Mcs12)
-               pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][13] = Data;
-}
-
-static int phy_BB8188E_Config_ParaFile(struct adapter *Adapter)
-{
-       struct eeprom_priv *pEEPROM = &Adapter->eeprompriv;
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-       int err;
-
-       /*  */
-       /*  1. Read PHY_REG.TXT BB INIT!! */
-       /*  We will separate as 88C / 92C according to chip version */
-       /*  */
-       err = ODM_ReadAndConfig_PHY_REG_1T_8188E(&pHalData->odmpriv);
-       if (err)
-               return err;
-
-       /*  2. If EEPROM or EFUSE autoload OK, We must config by PHY_REG_PG.txt */
-       if (!pEEPROM->bautoload_fail_flag) {
-               pHalData->pwrGroupCnt = 0;
-               ODM_ReadAndConfig_PHY_REG_PG_8188E(&pHalData->odmpriv);
-       }
-
-       /*  3. BB AGC table Initialization */
-       err = ODM_ReadAndConfig_AGC_TAB_1T_8188E(&pHalData->odmpriv);
-       if (err)
-               return err;
-
-       return 0;
-}
-
-int
-PHY_BBConfig8188E(
-               struct adapter *Adapter
-       )
-{
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-       u16 RegVal;
-       u8 CrystalCap;
-       int err;
-
-       phy_InitBBRFRegisterDefinition(Adapter);
-
-       /*  Enable BB and RF */
-       err = rtw_read16(Adapter, REG_SYS_FUNC_EN, &RegVal);
-       if (err)
-               return err;
-
-       rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal | BIT(13) | BIT(0) | BIT(1)));
-
-       /*  20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF. */
-
-       rtw_write8(Adapter, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
-
-       rtw_write8(Adapter, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD | FEN_BB_GLB_RSTn | FEN_BBRSTB);
-
-       /*  Config BB and AGC */
-       err = phy_BB8188E_Config_ParaFile(Adapter);
-
-       /*  write 0x24[16:11] = 0x24[22:17] = CrystalCap */
-       CrystalCap = pHalData->CrystalCap & 0x3F;
-       rtl8188e_PHY_SetBBReg(Adapter, REG_AFE_XTAL_CTRL, 0x7ff800, (CrystalCap | (CrystalCap << 6)));
-
-       return err;
-}
-
-static void getTxPowerIndex88E(struct adapter *Adapter, u8 channel, u8 *cckPowerLevel,
-                              u8 *ofdmPowerLevel, u8 *BW20PowerLevel,
-                              u8 *BW40PowerLevel)
-{
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-       u8 index = (channel - 1);
-
-       /*  1. CCK */
-       cckPowerLevel[RF_PATH_A] = pHalData->Index24G_CCK_Base[index];
-       /* 2. OFDM */
-       ofdmPowerLevel[RF_PATH_A] = pHalData->Index24G_BW40_Base[index] +
-               pHalData->OFDM_24G_Diff[RF_PATH_A];
-       /*  1. BW20 */
-       BW20PowerLevel[RF_PATH_A] = pHalData->Index24G_BW40_Base[index] +
-               pHalData->BW20_24G_Diff[RF_PATH_A];
-       /* 2. BW40 */
-       BW40PowerLevel[RF_PATH_A] = pHalData->Index24G_BW40_Base[index];
-}
-
-/*-----------------------------------------------------------------------------
- * Function:    SetTxPowerLevel8190()
- *
- * Overview:    This function is export to "HalCommon" moudule
- *                     We must consider RF path later!!!!!!!
- *
- * Input:       struct adapter *Adapter
- *                     u8              channel
- *
- * Output:      NONE
- *
- * Return:      NONE
- *     2008/11/04      MHC             We remove EEPROM_93C56.
- *                                             We need to move CCX relative code to independet file.
- *     2009/01/21      MHC             Support new EEPROM format from SD3 requirement.
- *
- *---------------------------------------------------------------------------*/
-void
-PHY_SetTxPowerLevel8188E(
-               struct adapter *Adapter,
-               u8 channel
-       )
-{
-       u8 cckPowerLevel[MAX_TX_COUNT] = {0};
-       u8 ofdmPowerLevel[MAX_TX_COUNT] = {0};/*  [0]:RF-A, [1]:RF-B */
-       u8 BW20PowerLevel[MAX_TX_COUNT] = {0};
-       u8 BW40PowerLevel[MAX_TX_COUNT] = {0};
-
-       getTxPowerIndex88E(Adapter, channel, &cckPowerLevel[0], &ofdmPowerLevel[0], &BW20PowerLevel[0], &BW40PowerLevel[0]);
-
-       rtl8188e_PHY_RF6052SetCckTxPower(Adapter, &cckPowerLevel[0]);
-       rtl8188e_PHY_RF6052SetOFDMTxPower(Adapter, &ofdmPowerLevel[0], &BW20PowerLevel[0], &BW40PowerLevel[0], channel);
-}
-
-/*-----------------------------------------------------------------------------
- * Function:    PHY_SetBWModeCallback8192C()
- *
- * Overview:    Timer callback function for SetSetBWMode
- *
- * Input:              PRT_TIMER               pTimer
- *
- * Output:      NONE
- *
- * Return:      NONE
- *
- * Note:               (1) We do not take j mode into consideration now
- *                     (2) Will two workitem of "switch channel" and "switch channel bandwidth" run
- *                          concurrently?
- *---------------------------------------------------------------------------*/
-static void
-_PHY_SetBWMode92C(
-               struct adapter *Adapter
-)
-{
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-       u8 regBwOpMode;
-       u8 regRRSR_RSC;
-       int res;
-
-       if (Adapter->bDriverStopped)
-               return;
-
-       /* 3 */
-       /* 3<1>Set MAC register */
-       /* 3 */
-
-       res = rtw_read8(Adapter, REG_BWOPMODE, &regBwOpMode);
-       if (res)
-               return;
-
-       res = rtw_read8(Adapter, REG_RRSR + 2, &regRRSR_RSC);
-       if (res)
-               return;
-
-       switch (pHalData->CurrentChannelBW) {
-       case HT_CHANNEL_WIDTH_20:
-               regBwOpMode |= BW_OPMODE_20MHZ;
-               /*  2007/02/07 Mark by Emily because we have not verify whether this register works */
-               rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode);
-               break;
-       case HT_CHANNEL_WIDTH_40:
-               regBwOpMode &= ~BW_OPMODE_20MHZ;
-               /*  2007/02/07 Mark by Emily because we have not verify whether this register works */
-               rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode);
-               regRRSR_RSC = (regRRSR_RSC & 0x90) | (pHalData->nCur40MhzPrimeSC << 5);
-               rtw_write8(Adapter, REG_RRSR + 2, regRRSR_RSC);
-               break;
-       default:
-               break;
-       }
-
-       /* 3  */
-       /* 3 <2>Set PHY related register */
-       /* 3 */
-       switch (pHalData->CurrentChannelBW) {
-       /* 20 MHz channel*/
-       case HT_CHANNEL_WIDTH_20:
-               rtl8188e_PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0);
-               rtl8188e_PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0);
-               break;
-       /* 40 MHz channel*/
-       case HT_CHANNEL_WIDTH_40:
-               rtl8188e_PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1);
-               rtl8188e_PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1);
-               /*  Set Control channel to upper or lower. These settings are required only for 40MHz */
-               rtl8188e_PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand, (pHalData->nCur40MhzPrimeSC >> 1));
-               rtl8188e_PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00, pHalData->nCur40MhzPrimeSC);
-               rtl8188e_PHY_SetBBReg(Adapter, 0x818, (BIT(26) | BIT(27)),
-                            (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
-               break;
-       default:
-               break;
-       }
-       /* Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315 */
-
-       rtl8188e_PHY_RF6052SetBandwidth(Adapter, pHalData->CurrentChannelBW);
-}
-
- /*-----------------------------------------------------------------------------
- * Function:   SetBWMode8190Pci()
- *
- * Overview:  This function is export to "HalCommon" moudule
- *
- * Input:              struct adapter *Adapter
- *                     enum ht_channel_width Bandwidth 20M or 40M
- *
- * Output:      NONE
- *
- * Return:      NONE
- *
- * Note:               We do not take j mode into consideration now
- *---------------------------------------------------------------------------*/
-void PHY_SetBWMode8188E(struct adapter *Adapter, enum ht_channel_width Bandwidth,      /*  20M or 40M */
-                       unsigned char   Offset)         /*  Upper, Lower, or Don't care */
-{
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-       enum ht_channel_width tmpBW = pHalData->CurrentChannelBW;
-
-       pHalData->CurrentChannelBW = Bandwidth;
-
-       pHalData->nCur40MhzPrimeSC = Offset;
-
-       if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved))
-               _PHY_SetBWMode92C(Adapter);
-       else
-               pHalData->CurrentChannelBW = tmpBW;
-}
-
-static void _PHY_SwChnl8192C(struct adapter *Adapter, u8 channel)
-{
-       u32 param1, param2;
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-
-       /* s1. pre common command - CmdID_SetTxPowerLevel */
-       PHY_SetTxPowerLevel8188E(Adapter, channel);
-
-       /* s2. RF dependent command - CmdID_RF_WriteReg, param1=RF_CHNLBW, param2=channel */
-       param1 = RF_CHNLBW;
-       param2 = channel;
-       pHalData->RfRegChnlVal = ((pHalData->RfRegChnlVal & 0xfffffc00) | param2);
-       rtl8188e_PHY_SetRFReg(Adapter, param1, bRFRegOffsetMask, pHalData->RfRegChnlVal);
-}
-
-void PHY_SwChnl8188E(struct adapter *Adapter, u8 channel)
-{
-       /*  Call after initialization */
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-
-       if (channel == 0)
-               channel = 1;
-
-       if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) {
-               pHalData->CurrentChannel = channel;
-               _PHY_SwChnl8192C(Adapter, channel);
-       }
-}
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_rf6052.c b/drivers/staging/r8188eu/hal/rtl8188e_rf6052.c
deleted file mode 100644 (file)
index 1988fb6..0000000
+++ /dev/null
@@ -1,405 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-/******************************************************************************
- *
- *
- * Module:     rtl8192c_rf6052.c       ( Source C File)
- *
- * Note:       Provide RF 6052 series relative API.
- *
- * Function:
- *
- * Export:
- *
- * Abbrev:
- *
- * History:
- * Data                        Who             Remark
- *
- * 09/25/2008  MHC             Create initial version.
- * 11/05/2008  MHC             Add API for tw power setting.
- *
- *
-******************************************************************************/
-
-#define _RTL8188E_RF6052_C_
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/rtl8188e_hal.h"
-
-/*-----------------------------------------------------------------------------
- * Function:    PHY_RF6052SetBandwidth()
- *
- * Overview:    This function is called by SetBWModeCallback8190Pci() only
- *
- * Input:       struct adapter *Adapter
- *                     WIRELESS_BANDWIDTH_E    Bandwidth       20M or 40M
- *
- * Output:      NONE
- *
- * Return:      NONE
- *
- * Note:               For RF type 0222D
- *---------------------------------------------------------------------------*/
-void rtl8188e_PHY_RF6052SetBandwidth(struct adapter *Adapter,
-                                    enum ht_channel_width Bandwidth)
-{
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-
-       switch (Bandwidth) {
-       case HT_CHANNEL_WIDTH_20:
-               pHalData->RfRegChnlVal = ((pHalData->RfRegChnlVal & 0xfffff3ff) | BIT(10) | BIT(11));
-               rtl8188e_PHY_SetRFReg(Adapter, RF_CHNLBW, bRFRegOffsetMask, pHalData->RfRegChnlVal);
-               break;
-       case HT_CHANNEL_WIDTH_40:
-               pHalData->RfRegChnlVal = ((pHalData->RfRegChnlVal & 0xfffff3ff) | BIT(10));
-               rtl8188e_PHY_SetRFReg(Adapter, RF_CHNLBW, bRFRegOffsetMask, pHalData->RfRegChnlVal);
-               break;
-       default:
-               break;
-       }
-}
-
-/*-----------------------------------------------------------------------------
- * Function:   PHY_RF6052SetCckTxPower
- *
- * Overview:
- *
- * Input:       NONE
- *
- * Output:      NONE
- *
- * Return:      NONE
- *
- * Revised History:
- * When                        Who             Remark
- * 11/05/2008  MHC             Simulate 8192series..
- *
- *---------------------------------------------------------------------------*/
-
-void
-rtl8188e_PHY_RF6052SetCckTxPower(
-               struct adapter *Adapter,
-               u8 *pPowerlevel)
-{
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-       struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
-       u32 TxAGC[2] = {0, 0}, tmpval = 0, pwrtrac_value;
-       u8 idx1, idx2;
-       u8 *ptr;
-       u8 direction;
-
-       if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
-               TxAGC[RF_PATH_A] = 0x3f3f3f3f;
-               TxAGC[RF_PATH_B] = 0x3f3f3f3f;
-
-               for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) {
-                       TxAGC[idx1] =
-                               pPowerlevel[idx1] | (pPowerlevel[idx1] << 8) |
-                               (pPowerlevel[idx1] << 16) | (pPowerlevel[idx1] << 24);
-               }
-       } else {
-               for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) {
-                       TxAGC[idx1] =
-                               pPowerlevel[idx1] | (pPowerlevel[idx1] << 8) |
-                               (pPowerlevel[idx1] << 16) | (pPowerlevel[idx1] << 24);
-               }
-               if (pHalData->EEPROMRegulatory == 0) {
-                       tmpval = (pHalData->MCSTxPowerLevelOriginalOffset[0][6]) +
-                                       (pHalData->MCSTxPowerLevelOriginalOffset[0][7] << 8);
-                       TxAGC[RF_PATH_A] += tmpval;
-
-                       tmpval = (pHalData->MCSTxPowerLevelOriginalOffset[0][14]) +
-                                       (pHalData->MCSTxPowerLevelOriginalOffset[0][15] << 24);
-                       TxAGC[RF_PATH_B] += tmpval;
-               }
-       }
-       for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) {
-               ptr = (u8 *)(&TxAGC[idx1]);
-               for (idx2 = 0; idx2 < 4; idx2++) {
-                       if (*ptr > RF6052_MAX_TX_PWR)
-                               *ptr = RF6052_MAX_TX_PWR;
-                       ptr++;
-               }
-       }
-       ODM_TxPwrTrackAdjust88E(&pHalData->odmpriv, 1, &direction, &pwrtrac_value);
-
-       if (direction == 1) {
-               /*  Increase TX power */
-               TxAGC[0] += pwrtrac_value;
-               TxAGC[1] += pwrtrac_value;
-       } else if (direction == 2) {
-               /*  Decrease TX power */
-               TxAGC[0] -=  pwrtrac_value;
-               TxAGC[1] -=  pwrtrac_value;
-       }
-
-       /*  rf-A cck tx power */
-       tmpval = TxAGC[RF_PATH_A] & 0xff;
-       rtl8188e_PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, tmpval);
-       tmpval = TxAGC[RF_PATH_A] >> 8;
-       rtl8188e_PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
-
-       /*  rf-B cck tx power */
-       tmpval = TxAGC[RF_PATH_B] >> 24;
-       rtl8188e_PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte0, tmpval);
-       tmpval = TxAGC[RF_PATH_B] & 0x00ffffff;
-       rtl8188e_PHY_SetBBReg(Adapter, rTxAGC_B_CCK1_55_Mcs32, 0xffffff00, tmpval);
-}      /* PHY_RF6052SetCckTxPower */
-
-/*  */
-/*  powerbase0 for OFDM rates */
-/*  powerbase1 for HT MCS rates */
-/*  */
-static void getpowerbase88e(struct adapter *Adapter, u8 *pPowerLevelOFDM,
-                           u8 *pPowerLevelBW20, u8 *pPowerLevelBW40, u8 Channel, u32 *OfdmBase, u32 *MCSBase)
-{
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-       u32 powerBase0, powerBase1;
-       u8 i;
-
-       for (i = 0; i < 2; i++) {
-               powerBase0 = pPowerLevelOFDM[i];
-
-               powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) | (powerBase0 << 8) | powerBase0;
-               *(OfdmBase + i) = powerBase0;
-       }
-
-       /* Check HT20 to HT40 diff */
-       if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
-               powerBase1 = pPowerLevelBW20[0];
-       else
-               powerBase1 = pPowerLevelBW40[0];
-       powerBase1 = (powerBase1 << 24) | (powerBase1 << 16) | (powerBase1 << 8) | powerBase1;
-       *MCSBase = powerBase1;
-}
-
-static void get_rx_power_val_by_reg(struct adapter *Adapter, u8 Channel,
-                                   u8 index, u32 *powerBase0, u32 *powerBase1,
-                                   u32 *pOutWriteVal)
-{
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-       u8      i, chnlGroup = 0, pwr_diff_limit[4], customer_pwr_limit;
-       s8      pwr_diff = 0;
-       u32     writeVal, customer_limit, rf;
-       u8      Regulatory = pHalData->EEPROMRegulatory;
-
-       /*  Index 0 & 1= legacy OFDM, 2-5=HT_MCS rate */
-
-       for (rf = 0; rf < 2; rf++) {
-               switch (Regulatory) {
-               case 0: /*  Realtek better performance */
-                               /*  increase power diff defined by Realtek for large power */
-                       chnlGroup = 0;
-                       writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index + (rf ? 8 : 0)] +
-                               ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
-                       break;
-               case 1: /*  Realtek regulatory */
-                       /*  increase power diff defined by Realtek for regulatory */
-                       if (pHalData->pwrGroupCnt == 1)
-                               chnlGroup = 0;
-                       if (pHalData->pwrGroupCnt >= MAX_PG_GROUP) {
-                               if (Channel < 3)                        /*  Channel 1-2 */
-                                       chnlGroup = 0;
-                               else if (Channel < 6)           /*  Channel 3-5 */
-                                       chnlGroup = 1;
-                               else     if (Channel < 9)               /*  Channel 6-8 */
-                                       chnlGroup = 2;
-                               else if (Channel < 12)          /*  Channel 9-11 */
-                                       chnlGroup = 3;
-                               else if (Channel < 14)          /*  Channel 12-13 */
-                                       chnlGroup = 4;
-                               else if (Channel == 14)         /*  Channel 14 */
-                                       chnlGroup = 5;
-                       }
-                       writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index + (rf ? 8 : 0)] +
-                                       ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
-                       break;
-               case 2: /*  Better regulatory */
-                               /*  don't increase any power diff */
-                       writeVal = ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
-                       break;
-               case 3: /*  Customer defined power diff. */
-                               /*  increase power diff defined by customer. */
-                       chnlGroup = 0;
-
-                       if (index < 2)
-                               pwr_diff = pHalData->TxPwrLegacyHtDiff[rf][Channel - 1];
-                       else if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
-                               pwr_diff = pHalData->TxPwrHt20Diff[rf][Channel - 1];
-
-                       if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_40)
-                               customer_pwr_limit = pHalData->PwrGroupHT40[rf][Channel - 1];
-                       else
-                               customer_pwr_limit = pHalData->PwrGroupHT20[rf][Channel - 1];
-
-                       if (pwr_diff >= customer_pwr_limit)
-                               pwr_diff = 0;
-                       else
-                               pwr_diff = customer_pwr_limit - pwr_diff;
-
-                       for (i = 0; i < 4; i++) {
-                               pwr_diff_limit[i] = (u8)((pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index + (rf ? 8 : 0)] & (0x7f << (i * 8))) >> (i * 8));
-
-                               if (pwr_diff_limit[i] > pwr_diff)
-                                       pwr_diff_limit[i] = pwr_diff;
-                       }
-                       customer_limit = (pwr_diff_limit[3] << 24) | (pwr_diff_limit[2] << 16) |
-                                        (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]);
-                       writeVal = customer_limit + ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
-                       break;
-               default:
-                       chnlGroup = 0;
-                       writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index + (rf ? 8 : 0)] +
-                                       ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
-                       break;
-               }
-
-               *(pOutWriteVal + rf) = writeVal;
-       }
-}
-static void writeOFDMPowerReg88E(struct adapter *Adapter, u8 index, u32 *pValue)
-{
-       u16 regoffset_a[6] = {
-               rTxAGC_A_Rate18_06, rTxAGC_A_Rate54_24,
-               rTxAGC_A_Mcs03_Mcs00, rTxAGC_A_Mcs07_Mcs04,
-               rTxAGC_A_Mcs11_Mcs08, rTxAGC_A_Mcs15_Mcs12};
-       u16 regoffset_b[6] = {
-               rTxAGC_B_Rate18_06, rTxAGC_B_Rate54_24,
-               rTxAGC_B_Mcs03_Mcs00, rTxAGC_B_Mcs07_Mcs04,
-               rTxAGC_B_Mcs11_Mcs08, rTxAGC_B_Mcs15_Mcs12};
-       u8 i, rf, pwr_val[4];
-       u32 writeVal;
-       u16 regoffset;
-
-       for (rf = 0; rf < 2; rf++) {
-               writeVal = pValue[rf];
-               for (i = 0; i < 4; i++) {
-                       pwr_val[i] = (u8)((writeVal & (0x7f << (i * 8))) >> (i * 8));
-                       if (pwr_val[i]  > RF6052_MAX_TX_PWR)
-                               pwr_val[i]  = RF6052_MAX_TX_PWR;
-               }
-               writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) | (pwr_val[1] << 8) | pwr_val[0];
-
-               if (rf == 0)
-                       regoffset = regoffset_a[index];
-               else
-                       regoffset = regoffset_b[index];
-
-               rtl8188e_PHY_SetBBReg(Adapter, regoffset, bMaskDWord, writeVal);
-
-               /*  201005115 Joseph: Set Tx Power diff for Tx power training mechanism. */
-               if (regoffset == rTxAGC_A_Mcs07_Mcs04 || regoffset == rTxAGC_B_Mcs07_Mcs04) {
-                       writeVal = pwr_val[3];
-                       if (regoffset == rTxAGC_A_Mcs15_Mcs12 || regoffset == rTxAGC_A_Mcs07_Mcs04)
-                               regoffset = 0xc90;
-                       if (regoffset == rTxAGC_B_Mcs15_Mcs12 || regoffset == rTxAGC_B_Mcs07_Mcs04)
-                               regoffset = 0xc98;
-                       for (i = 0; i < 3; i++) {
-                               if (i != 2)
-                                       writeVal = (writeVal > 8) ? (writeVal - 8) : 0;
-                               else
-                                       writeVal = (writeVal > 6) ? (writeVal - 6) : 0;
-                               rtw_write8(Adapter, (u32)(regoffset + i), (u8)writeVal);
-                       }
-               }
-       }
-}
-
-/*-----------------------------------------------------------------------------
- * Function:   PHY_RF6052SetOFDMTxPower
- *
- * Overview:   For legacy and HY OFDM, we must read EEPROM TX power index for
- *                     different channel and read original value in TX power register area from
- *                     0xe00. We increase offset and original value to be correct tx pwr.
- *
- * Input:       NONE
- *
- * Output:      NONE
- *
- * Return:      NONE
- *
- * Revised History:
- * When                        Who             Remark
- * 11/05/2008  MHC             Simulate 8192 series method.
- * 01/06/2009  MHC             1. Prevent Path B tx power overflow or underflow dure to
- *                                             A/B pwr difference or legacy/HT pwr diff.
- *                                             2. We concern with path B legacy/HT OFDM difference.
- * 01/22/2009  MHC             Support new EPRO format from SD3.
- *
- *---------------------------------------------------------------------------*/
-
-void
-rtl8188e_PHY_RF6052SetOFDMTxPower(
-               struct adapter *Adapter,
-               u8 *pPowerLevelOFDM,
-               u8 *pPowerLevelBW20,
-               u8 *pPowerLevelBW40,
-               u8 Channel)
-{
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-       u32 writeVal[2], powerBase0[2], powerBase1[2], pwrtrac_value;
-       u8 direction;
-       u8 index = 0;
-
-       getpowerbase88e(Adapter, pPowerLevelOFDM, pPowerLevelBW20, pPowerLevelBW40, Channel, &powerBase0[0], &powerBase1[0]);
-
-       /*  2012/04/23 MH According to power tracking value, we need to revise OFDM tx power. */
-       /*  This is ued to fix unstable power tracking mode. */
-       ODM_TxPwrTrackAdjust88E(&pHalData->odmpriv, 0, &direction, &pwrtrac_value);
-
-       for (index = 0; index < 6; index++) {
-               get_rx_power_val_by_reg(Adapter, Channel, index,
-                                       &powerBase0[0], &powerBase1[0],
-                                       &writeVal[0]);
-
-               if (direction == 1) {
-                       writeVal[0] += pwrtrac_value;
-                       writeVal[1] += pwrtrac_value;
-               } else if (direction == 2) {
-                       writeVal[0] -= pwrtrac_value;
-                       writeVal[1] -= pwrtrac_value;
-               }
-               writeOFDMPowerReg88E(Adapter, index, &writeVal[0]);
-       }
-}
-
-int phy_RF6052_Config_ParaFile(struct adapter *Adapter)
-{
-       struct bb_reg_def *pPhyReg;
-       struct hal_data_8188e *pHalData = &Adapter->haldata;
-       u32 u4RegValue = 0;
-       int err;
-
-       /* Initialize RF */
-
-       pPhyReg = &pHalData->PHYRegDef;
-
-       /*----Store original RFENV control type----*/
-       u4RegValue = rtl8188e_PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV);
-
-       /*----Set RF_ENV enable----*/
-       rtl8188e_PHY_SetBBReg(Adapter, pPhyReg->rfintfe, bRFSI_RFENV << 16, 0x1);
-       udelay(1);/* PlatformStallExecution(1); */
-
-       /*----Set RF_ENV output high----*/
-       rtl8188e_PHY_SetBBReg(Adapter, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
-       udelay(1);/* PlatformStallExecution(1); */
-
-       /* Set bit number of Address and Data for RF register */
-       rtl8188e_PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); /*  Set 1 to 4 bits for 8255 */
-       udelay(1);/* PlatformStallExecution(1); */
-
-       rtl8188e_PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0);    /*  Set 0 to 12  bits for 8255 */
-       udelay(1);/* PlatformStallExecution(1); */
-
-       /*----Initialize RF fom connfiguration file----*/
-       err = ODM_ReadAndConfig_RadioA_1T_8188E(&pHalData->odmpriv);
-
-       /*----Restore RFENV control type----*/;
-       rtl8188e_PHY_SetBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue);
-
-       return err;
-}
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c b/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c
deleted file mode 100644 (file)
index d1ac296..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#define _RTL8188E_REDESC_C_
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/rtl8188e_hal.h"
-
-static void process_rssi(struct adapter *padapter, struct recv_frame *prframe)
-{
-       struct rx_pkt_attrib *pattrib = &prframe->attrib;
-       struct signal_stat *signal_stat = &padapter->recvpriv.signal_strength_data;
-
-       if (signal_stat->update_req) {
-               signal_stat->total_num = 0;
-               signal_stat->total_val = 0;
-               signal_stat->update_req = 0;
-       }
-
-       signal_stat->total_num++;
-       signal_stat->total_val  += pattrib->phy_info.SignalStrength;
-       signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num;
-} /*  Process_UI_RSSI_8192C */
-
-static void process_link_qual(struct adapter *padapter, struct recv_frame *prframe)
-{
-       struct rx_pkt_attrib *pattrib;
-       struct signal_stat *signal_stat;
-
-       if (!prframe || !padapter)
-               return;
-
-       pattrib = &prframe->attrib;
-       signal_stat = &padapter->recvpriv.signal_qual_data;
-
-       if (signal_stat->update_req) {
-               signal_stat->total_num = 0;
-               signal_stat->total_val = 0;
-               signal_stat->update_req = 0;
-       }
-
-       signal_stat->total_num++;
-       signal_stat->total_val  += pattrib->phy_info.SignalQuality;
-       signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num;
-}
-
-static void rtl8188e_process_phy_info(struct adapter *padapter, void *prframe)
-{
-       struct recv_frame *precvframe = (struct recv_frame *)prframe;
-
-       /*  Check RSSI */
-       process_rssi(padapter, precvframe);
-       /*  Check EVM */
-       process_link_qual(padapter,  precvframe);
-}
-
-void update_recvframe_attrib_88e(struct recv_frame *precvframe, struct recv_stat *prxstat)
-{
-       struct rx_pkt_attrib *pattrib = &precvframe->attrib;
-       memset(pattrib, 0, sizeof(struct rx_pkt_attrib));
-
-       pattrib->crc_err = (le32_to_cpu(prxstat->rxdw0) >> 14) & 0x1;
-
-       pattrib->pkt_rpt_type = (le32_to_cpu(prxstat->rxdw3) >> 14) & 0x3;
-
-       if (pattrib->pkt_rpt_type == NORMAL_RX) {
-               pattrib->pkt_len = le32_to_cpu(prxstat->rxdw0) & 0x00003fff;
-               pattrib->icv_err = (le32_to_cpu(prxstat->rxdw0) >> 15) & 0x1;
-               pattrib->drvinfo_sz = ((le32_to_cpu(prxstat->rxdw0) >> 16) & 0xf) * 8;
-               pattrib->encrypt = (u8)((le32_to_cpu(prxstat->rxdw0) >> 20) & 0x7);
-               pattrib->qos = (le32_to_cpu(prxstat->rxdw0) >> 23) & 0x1;
-               pattrib->shift_sz = (le32_to_cpu(prxstat->rxdw0) >> 24) & 0x3;
-               pattrib->physt = (le32_to_cpu(prxstat->rxdw0) >> 26) & 0x1;
-               pattrib->bdecrypted = (le32_to_cpu(prxstat->rxdw0) & BIT(27)) ? 0 : 1;
-
-               pattrib->priority = (le32_to_cpu(prxstat->rxdw1) >> 8) & 0xf;
-               pattrib->amsdu = (le32_to_cpu(prxstat->rxdw1) >> 13) & 0x1;
-               pattrib->mdata = (le32_to_cpu(prxstat->rxdw1) >> 26) & 0x1;
-               pattrib->mfrag = (le32_to_cpu(prxstat->rxdw1) >> 27) & 0x1;
-
-               pattrib->seq_num = le32_to_cpu(prxstat->rxdw2) & 0x00000fff;
-               pattrib->frag_num = (le32_to_cpu(prxstat->rxdw2) >> 12) & 0xf;
-
-               pattrib->mcs_rate = le32_to_cpu(prxstat->rxdw3) & 0x3f;
-               pattrib->rxht = (le32_to_cpu(prxstat->rxdw3) >> 6) & 0x1;
-
-       } else if (pattrib->pkt_rpt_type == TX_REPORT1) { /* CCX */
-               pattrib->pkt_len = TX_RPT1_PKT_LEN;
-       } else if (pattrib->pkt_rpt_type == TX_REPORT2) {
-               pattrib->pkt_len = le32_to_cpu(prxstat->rxdw0) & 0x3FF;
-
-               pattrib->MacIDValidEntry[0] = le32_to_cpu(prxstat->rxdw4);
-               pattrib->MacIDValidEntry[1] = le32_to_cpu(prxstat->rxdw5);
-
-       } else if (pattrib->pkt_rpt_type == HIS_REPORT) {
-               pattrib->pkt_len = le32_to_cpu(prxstat->rxdw0) & 0x00003fff;
-       }
-}
-
-/*
- * Notice:
- *     Before calling this function,
- *     precvframe->rx_data should be ready!
- */
-void update_recvframe_phyinfo_88e(struct recv_frame *precvframe, struct phy_stat *pphy_status)
-{
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precvframe->rx_data;
-       struct adapter *padapter = precvframe->adapter;
-       struct rx_pkt_attrib *pattrib = &precvframe->attrib;
-       struct hal_data_8188e *pHalData = &padapter->haldata;
-       struct phy_info *pPHYInfo  = &pattrib->phy_info;
-       u8 *wlanhdr = precvframe->rx_data;
-       struct odm_per_pkt_info pkt_info;
-       u8 *sa = NULL;
-       struct sta_priv *pstapriv;
-       struct sta_info *psta;
-
-       pkt_info.bPacketMatchBSSID = ((!ieee80211_is_ctl(hdr->frame_control)) &&
-               !pattrib->icv_err && !pattrib->crc_err &&
-               !memcmp(get_hdr_bssid(wlanhdr),
-                get_bssid(&padapter->mlmepriv), ETH_ALEN));
-
-       pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID &&
-                                ether_addr_equal(ieee80211_get_DA(hdr),
-                                                 myid(&padapter->eeprompriv));
-
-       pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID &&
-                                ieee80211_is_beacon(hdr->frame_control);
-       if (pkt_info.bPacketBeacon) {
-               if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE))
-                       sa = padapter->mlmepriv.cur_network.network.MacAddress;
-               /* to do Ad-hoc */
-       } else {
-               sa = ieee80211_get_SA(hdr);
-       }
-
-       pstapriv = &padapter->stapriv;
-       pkt_info.StationID = 0xFF;
-       psta = rtw_get_stainfo(pstapriv, sa);
-       if (psta)
-               pkt_info.StationID = psta->mac_id;
-       pkt_info.Rate = pattrib->mcs_rate;
-
-       ODM_PhyStatusQuery(&pHalData->odmpriv, pPHYInfo, (u8 *)pphy_status, &(pkt_info), padapter);
-
-       precvframe->psta = NULL;
-       if (pkt_info.bPacketMatchBSSID &&
-           (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE))) {
-               if (psta) {
-                       precvframe->psta = psta;
-                       rtl8188e_process_phy_info(padapter, precvframe);
-               }
-       } else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon) {
-               if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
-                       if (psta)
-                               precvframe->psta = psta;
-               }
-               rtl8188e_process_phy_info(padapter, precvframe);
-       }
-}
diff --git a/drivers/staging/r8188eu/hal/rtl8188eu_xmit.c b/drivers/staging/r8188eu/hal/rtl8188eu_xmit.c
deleted file mode 100644 (file)
index 3ffab49..0000000
+++ /dev/null
@@ -1,627 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#define _RTL8188E_XMIT_C_
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/wifi.h"
-#include "../include/osdep_intf.h"
-#include "../include/usb_ops.h"
-#include "../include/rtl8188e_hal.h"
-
-static void rtl8188eu_cal_txdesc_chksum(struct tx_desc *ptxdesc)
-{
-       u16     *usptr = (u16 *)ptxdesc;
-       u32 count = 16;         /*  (32 bytes / 2 bytes per XOR) => 16 times */
-       u32 index;
-       u16 checksum = 0;
-
-       /* Clear first */
-       ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
-
-       for (index = 0; index < count; index++)
-               checksum = checksum ^ le16_to_cpu(*(__le16 *)(usptr + index));
-       ptxdesc->txdw7 |= cpu_to_le32(0x0000ffff & checksum);
-}
-
-/*  Description: In normal chip, we should send some packet to Hw which will be used by Fw */
-/*                     in FW LPS mode. The function is to fill the Tx descriptor of this packets, then */
-/*                     Fw can tell Hw to send these packet derectly. */
-void rtl8188e_fill_fake_txdesc(struct adapter *adapt, u8 *desc, u32 BufferLen, u8  ispspoll, u8  is_btqosnull)
-{
-       struct tx_desc *ptxdesc;
-
-       /*  Clear all status */
-       ptxdesc = (struct tx_desc *)desc;
-       memset(desc, 0, TXDESC_SIZE);
-
-       /* offset 0 */
-       ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); /* own, bFirstSeg, bLastSeg; */
-
-       ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00ff0000); /* 32 bytes for TX Desc */
-
-       ptxdesc->txdw0 |= cpu_to_le32(BufferLen & 0x0000ffff); /*  Buffer size + command header */
-
-       /* offset 4 */
-       ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT << QSEL_SHT) & 0x00001f00); /*  Fixed queue of Mgnt queue */
-
-       /* Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw. */
-       if (ispspoll) {
-               ptxdesc->txdw1 |= cpu_to_le32(NAVUSEHDR);
-       } else {
-               ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); /*  Hw set sequence number */
-               ptxdesc->txdw3 |= cpu_to_le32((8 << 28)); /* set bit3 to 1. Suugested by TimChen. 2009.12.29. */
-       }
-
-       if (is_btqosnull)
-               ptxdesc->txdw2 |= cpu_to_le32(BIT(23)); /*  BT NULL */
-
-       /* offset 16 */
-       ptxdesc->txdw4 |= cpu_to_le32(BIT(8));/* driver uses rate */
-
-       /*  USB interface drop packet if the checksum of descriptor isn't correct. */
-       /*  Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.). */
-       rtl8188eu_cal_txdesc_chksum(ptxdesc);
-}
-
-static void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc)
-{
-       if ((pattrib->encrypt > 0) && !pattrib->bswenc) {
-               switch (pattrib->encrypt) {
-               /* SEC_TYPE : 0:NO_ENC,1:WEP40/TKIP,2:WAPI,3:AES */
-               case _WEP40_:
-               case _WEP104_:
-                       ptxdesc->txdw1 |= cpu_to_le32((0x01 << SEC_TYPE_SHT) & 0x00c00000);
-                       ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT);
-                       break;
-               case _TKIP_:
-               case _TKIP_WTMIC_:
-                       ptxdesc->txdw1 |= cpu_to_le32((0x01 << SEC_TYPE_SHT) & 0x00c00000);
-                       ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT);
-                       break;
-               case _AES_:
-                       ptxdesc->txdw1 |= cpu_to_le32((0x03 << SEC_TYPE_SHT) & 0x00c00000);
-                       ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT);
-                       break;
-               case _NO_PRIVACY_:
-               default:
-                       break;
-               }
-       }
-}
-
-static void fill_txdesc_vcs(struct pkt_attrib *pattrib, __le32 *pdw)
-{
-       switch (pattrib->vcs_mode) {
-       case RTS_CTS:
-               *pdw |= cpu_to_le32(RTS_EN);
-               break;
-       case CTS_TO_SELF:
-               *pdw |= cpu_to_le32(CTS_2_SELF);
-               break;
-       case NONE_VCS:
-       default:
-               break;
-       }
-       if (pattrib->vcs_mode) {
-               *pdw |= cpu_to_le32(HW_RTS_EN);
-               /*  Set RTS BW */
-               if (pattrib->ht_en) {
-                       *pdw |= (pattrib->bwmode & HT_CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(27)) : 0;
-
-                       if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
-                               *pdw |= cpu_to_le32((0x01 << 28) & 0x30000000);
-                       else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
-                               *pdw |= cpu_to_le32((0x02 << 28) & 0x30000000);
-                       else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
-                               *pdw |= 0;
-                       else
-                               *pdw |= cpu_to_le32((0x03 << 28) & 0x30000000);
-               }
-       }
-}
-
-static void fill_txdesc_phy(struct pkt_attrib *pattrib, __le32 *pdw)
-{
-       if (pattrib->ht_en) {
-               *pdw |= (pattrib->bwmode & HT_CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(25)) : 0;
-
-               if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
-                       *pdw |= cpu_to_le32((0x01 << DATA_SC_SHT) & 0x003f0000);
-               else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
-                       *pdw |= cpu_to_le32((0x02 << DATA_SC_SHT) & 0x003f0000);
-               else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
-                       *pdw |= 0;
-               else
-                       *pdw |= cpu_to_le32((0x03 << DATA_SC_SHT) & 0x003f0000);
-       }
-}
-
-static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz)
-{
-       uint    qsel;
-       u8 data_rate, pwr_status, offset;
-       struct adapter          *adapt = pxmitframe->padapter;
-       struct pkt_attrib       *pattrib = &pxmitframe->attrib;
-       struct hal_data_8188e *haldata = &adapt->haldata;
-       struct tx_desc  *ptxdesc = (struct tx_desc *)pmem;
-       struct mlme_ext_priv    *pmlmeext = &adapt->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-
-       memset(ptxdesc, 0, sizeof(struct tx_desc));
-
-       /* 4 offset 0 */
-       ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
-       ptxdesc->txdw0 |= cpu_to_le32(sz & 0x0000ffff);/* update TXPKTSIZE */
-
-       offset = TXDESC_SIZE + OFFSET_SZ;
-
-       ptxdesc->txdw0 |= cpu_to_le32(((offset) << OFFSET_SHT) & 0x00ff0000);/* 32 bytes for TX Desc */
-
-       if (is_multicast_ether_addr(pattrib->ra))
-               ptxdesc->txdw0 |= cpu_to_le32(BMC);
-
-       /*  pkt_offset, unit:8 bytes padding */
-       if (pxmitframe->pkt_offset > 0)
-               ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000);
-
-       /* driver uses rate */
-       ptxdesc->txdw4 |= cpu_to_le32(USERATE);/* rate control always by driver */
-
-       if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) {
-               /* offset 4 */
-               ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id & 0x3F);
-
-               qsel = (uint)(pattrib->qsel & 0x0000001f);
-               ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
-
-               ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000F0000);
-
-               fill_txdesc_sectype(pattrib, ptxdesc);
-
-               if (pattrib->ampdu_en) {
-                       ptxdesc->txdw2 |= cpu_to_le32(AGG_EN);/* AGG EN */
-                       ptxdesc->txdw6 = cpu_to_le32(0x6666f800);
-               } else {
-                       ptxdesc->txdw2 |= cpu_to_le32(AGG_BK);/* AGG BK */
-               }
-
-               /* offset 8 */
-
-               /* offset 12 */
-               ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0x0FFF0000);
-
-               /* offset 16 , offset 20 */
-               if (pattrib->qos_en)
-                       ptxdesc->txdw4 |= cpu_to_le32(QOS);/* QoS */
-
-               /* offset 20 */
-               if (pxmitframe->agg_num > 1)
-                       ptxdesc->txdw5 |= cpu_to_le32((pxmitframe->agg_num << USB_TXAGG_NUM_SHT) & 0xFF000000);
-
-               if ((pattrib->ether_type != 0x888e) &&
-                   (pattrib->ether_type != 0x0806) &&
-                   (pattrib->ether_type != 0x88b4) &&
-                   (pattrib->dhcp_pkt != 1)) {
-                       /* Non EAP & ARP & DHCP type data packet */
-
-                       fill_txdesc_vcs(pattrib, &ptxdesc->txdw4);
-                       fill_txdesc_phy(pattrib, &ptxdesc->txdw4);
-
-                       ptxdesc->txdw4 |= cpu_to_le32(0x00000008);/* RTS Rate=24M */
-                       ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00);/* DATA/RTS  Rate FB LMT */
-
-                       if (pattrib->ht_en) {
-                               if (ODM_RA_GetShortGI_8188E(&haldata->odmpriv, pattrib->mac_id))
-                                       ptxdesc->txdw5 |= cpu_to_le32(SGI);/* SGI */
-                       }
-                       data_rate = ODM_RA_GetDecisionRate_8188E(&haldata->odmpriv, pattrib->mac_id);
-                       ptxdesc->txdw5 |= cpu_to_le32(data_rate & 0x3F);
-                       pwr_status = ODM_RA_GetHwPwrStatus_8188E(&haldata->odmpriv, pattrib->mac_id);
-                       ptxdesc->txdw4 |= cpu_to_le32((pwr_status & 0x7) << PWR_STATUS_SHT);
-               } else {
-                       /*  EAP data packet and ARP packet and DHCP. */
-                       /*  Use the 1M data rate to send the EAP/ARP packet. */
-                       /*  This will maybe make the handshake smooth. */
-                       ptxdesc->txdw2 |= cpu_to_le32(AGG_BK);/* AGG BK */
-                       if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
-                               ptxdesc->txdw4 |= cpu_to_le32(BIT(24));/*  DATA_SHORT */
-                       ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
-               }
-       } else if ((pxmitframe->frame_tag & 0x0f) == MGNT_FRAMETAG) {
-               /* offset 4 */
-               ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id & 0x3f);
-
-               qsel = (uint)(pattrib->qsel & 0x0000001f);
-               ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
-
-               ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000f0000);
-
-               /* offset 8 */
-               /* CCX-TXRPT ack for xmit mgmt frames. */
-               if (pxmitframe->ack_report)
-                       ptxdesc->txdw2 |= cpu_to_le32(BIT(19));
-
-               /* offset 12 */
-               ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0x0FFF0000);
-
-               /* offset 20 */
-               ptxdesc->txdw5 |= cpu_to_le32(RTY_LMT_EN);/* retry limit enable */
-               if (pattrib->retry_ctrl)
-                       ptxdesc->txdw5 |= cpu_to_le32(0x00180000);/* retry limit = 6 */
-               else
-                       ptxdesc->txdw5 |= cpu_to_le32(0x00300000);/* retry limit = 12 */
-
-               ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
-       } else if ((pxmitframe->frame_tag & 0x0f) != TXAGG_FRAMETAG) {
-               /* offset 4 */
-               ptxdesc->txdw1 |= cpu_to_le32((4) & 0x3f);/* CAM_ID(MAC_ID) */
-
-               ptxdesc->txdw1 |= cpu_to_le32((6 << RATE_ID_SHT) & 0x000f0000);/* raid */
-
-               /* offset 8 */
-
-               /* offset 12 */
-               ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0x0fff0000);
-
-               /* offset 20 */
-               ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
-       }
-
-       /*  2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. */
-       /*  (1) The sequence number of each non-Qos frame / broadcast / multicast / */
-       /*  mgnt frame should be controlled by Hw because Fw will also send null data */
-       /*  which we cannot control when Fw LPS enable. */
-       /*  --> default enable non-Qos data sequense number. 2010.06.23. by tynli. */
-       /*  (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. */
-       /*  (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. */
-       /*  2010.06.23. Added by tynli. */
-       if (!pattrib->qos_en) {
-               ptxdesc->txdw3 |= cpu_to_le32(EN_HWSEQ); /*  Hw set sequence number */
-               ptxdesc->txdw4 |= cpu_to_le32(HW_SSN);  /*  Hw set sequence number */
-       }
-
-       ODM_SetTxAntByTxInfo_88E(&haldata->odmpriv, pmem, pattrib->mac_id);
-
-       rtl8188eu_cal_txdesc_chksum(ptxdesc);
-       return 0;
-}
-
-/* for non-agg data frame or  management frame */
-static s32 rtw_dump_xframe(struct adapter *adapt, struct xmit_frame *pxmitframe)
-{
-       s32 ret = _SUCCESS;
-       s32 inner_ret = _SUCCESS;
-       int t, sz, w_sz, pull = 0;
-       u8 *mem_addr;
-       u32 ff_hwaddr;
-       struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf;
-       struct pkt_attrib *pattrib = &pxmitframe->attrib;
-       struct xmit_priv *pxmitpriv = &adapt->xmitpriv;
-       struct security_priv *psecuritypriv = &adapt->securitypriv;
-       if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
-           (pxmitframe->attrib.ether_type != 0x0806) &&
-           (pxmitframe->attrib.ether_type != 0x888e) &&
-           (pxmitframe->attrib.ether_type != 0x88b4) &&
-           (pxmitframe->attrib.dhcp_pkt != 1))
-               rtw_issue_addbareq_cmd(adapt, pxmitframe);
-       mem_addr = pxmitframe->buf_addr;
-
-       for (t = 0; t < pattrib->nr_frags; t++) {
-               if (inner_ret != _SUCCESS && ret == _SUCCESS)
-                       ret = _FAIL;
-
-               if (t != (pattrib->nr_frags - 1)) {
-                       sz = pxmitpriv->frag_len;
-                       sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len);
-               } else {
-                       /* no frag */
-                       sz = pattrib->last_txcmdsz;
-               }
-
-               pull = update_txdesc(pxmitframe, mem_addr, sz);
-
-               if (pull) {
-                       mem_addr += PACKET_OFFSET_SZ; /* pull txdesc head */
-                       pxmitframe->buf_addr = mem_addr;
-                       w_sz = sz + TXDESC_SIZE;
-               } else {
-                       w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ;
-               }
-               ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
-
-               inner_ret = rtw_write_port(adapt, ff_hwaddr, w_sz, (unsigned char *)pxmitbuf);
-
-               rtw_count_tx_stats(adapt, pxmitframe, sz);
-
-               mem_addr += w_sz;
-
-               mem_addr = PTR_ALIGN(mem_addr, 4);
-       }
-
-       rtw_free_xmitframe(pxmitpriv, pxmitframe);
-
-       if  (ret != _SUCCESS)
-               rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
-
-       return ret;
-}
-
-static u32 xmitframe_need_length(struct xmit_frame *pxmitframe)
-{
-       struct pkt_attrib *pattrib = &pxmitframe->attrib;
-
-       u32 len = 0;
-
-       /*  no consider fragement */
-       len = pattrib->hdrlen + pattrib->iv_len +
-               SNAP_SIZE + sizeof(u16) +
-               pattrib->pktlen +
-               ((pattrib->bswenc) ? pattrib->icv_len : 0);
-
-       if (pattrib->encrypt == _TKIP_)
-               len += 8;
-
-       return len;
-}
-
-bool rtl8188eu_xmitframe_complete(struct adapter *adapt)
-{
-       struct xmit_priv *pxmitpriv = &adapt->xmitpriv;
-       struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(adapt);
-       struct xmit_frame *pxmitframe = NULL;
-       struct xmit_frame *pfirstframe = NULL;
-       struct xmit_buf *pxmitbuf;
-
-       /*  aggregate variable */
-       struct hw_xmit *phwxmit;
-       struct sta_info *psta = NULL;
-       struct tx_servq *ptxservq = NULL;
-       struct list_head *xmitframe_plist = NULL, *xmitframe_phead = NULL;
-
-       u32 pbuf;       /*  next pkt address */
-       u32 pbuf_tail;  /*  last pkt tail */
-       u32 len;        /*  packet length, except TXDESC_SIZE and PKT_OFFSET */
-
-       u32 bulksize;
-       u8 desc_cnt;
-       u32 bulkptr;
-
-       /*  dump frame variable */
-       u32 ff_hwaddr;
-
-       if (pdvobjpriv->pusbdev->speed == USB_SPEED_HIGH)
-               bulksize = USB_HIGH_SPEED_BULK_SIZE;
-       else
-               bulksize = USB_FULL_SPEED_BULK_SIZE;
-
-       pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
-       if (!pxmitbuf)
-               return false;
-
-       pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits);
-       if (!pxmitframe) {
-               /*  no more xmit frame, release xmit buffer */
-               rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
-               return false;
-       }
-
-       pxmitframe->pxmitbuf = pxmitbuf;
-       pxmitframe->buf_addr = pxmitbuf->pbuf;
-       pxmitbuf->priv_data = pxmitframe;
-
-       pxmitframe->agg_num = 1; /*  alloc xmitframe should assign to 1. */
-       pxmitframe->pkt_offset = 1; /*  first frame of aggregation, reserve offset */
-
-       rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe);
-
-       /*  always return ndis_packet after rtw_xmitframe_coalesce */
-       rtw_xmit_complete(adapt, pxmitframe);
-
-       /* 3 2. aggregate same priority and same DA(AP or STA) frames */
-       pfirstframe = pxmitframe;
-       len = xmitframe_need_length(pfirstframe) + TXDESC_SIZE + (pfirstframe->pkt_offset * PACKET_OFFSET_SZ);
-       pbuf_tail = len;
-       pbuf = round_up(pbuf_tail, 8);
-
-       /*  check pkt amount in one bulk */
-       desc_cnt = 0;
-       bulkptr = bulksize;
-       if (pbuf < bulkptr) {
-               desc_cnt++;
-       } else {
-               desc_cnt = 0;
-               bulkptr = ((pbuf / bulksize) + 1) * bulksize; /*  round to next bulksize */
-       }
-
-       /*  dequeue same priority packet from station tx queue */
-       psta = pfirstframe->attrib.psta;
-       switch (pfirstframe->attrib.priority) {
-       case 1:
-       case 2:
-               ptxservq = &psta->sta_xmitpriv.bk_q;
-               phwxmit = pxmitpriv->hwxmits + 3;
-               break;
-       case 4:
-       case 5:
-               ptxservq = &psta->sta_xmitpriv.vi_q;
-               phwxmit = pxmitpriv->hwxmits + 1;
-               break;
-       case 6:
-       case 7:
-               ptxservq = &psta->sta_xmitpriv.vo_q;
-               phwxmit = pxmitpriv->hwxmits;
-               break;
-       case 0:
-       case 3:
-       default:
-               ptxservq = &psta->sta_xmitpriv.be_q;
-               phwxmit = pxmitpriv->hwxmits + 2;
-               break;
-       }
-       spin_lock_bh(&pxmitpriv->lock);
-
-       xmitframe_phead = &ptxservq->sta_pending;
-       xmitframe_plist = xmitframe_phead->next;
-
-       while (xmitframe_phead != xmitframe_plist) {
-               pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
-               xmitframe_plist = xmitframe_plist->next;
-
-               pxmitframe->agg_num = 0; /*  not first frame of aggregation */
-               pxmitframe->pkt_offset = 0; /*  not first frame of aggregation, no need to reserve offset */
-
-               len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
-
-               if (pbuf + len > MAX_XMITBUF_SZ) {
-                       pxmitframe->agg_num = 1;
-                       pxmitframe->pkt_offset = 1;
-                       break;
-               }
-               list_del_init(&pxmitframe->list);
-               ptxservq->qcnt--;
-               phwxmit->accnt--;
-
-               pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
-
-               rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe);
-               /*  always return ndis_packet after rtw_xmitframe_coalesce */
-               rtw_xmit_complete(adapt, pxmitframe);
-
-               /*  (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz */
-               update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz);
-
-               /*  don't need xmitframe any more */
-               rtw_free_xmitframe(pxmitpriv, pxmitframe);
-
-               /*  handle pointer and stop condition */
-               pbuf_tail = pbuf + len;
-               pbuf = round_up(pbuf_tail, 8);
-
-               pfirstframe->agg_num++;
-               if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
-                       break;
-
-               if (pbuf < bulkptr) {
-                       desc_cnt++;
-                       if (desc_cnt == USB_TXAGG_DESC_NUM)
-                               break;
-               } else {
-                       desc_cnt = 0;
-                       bulkptr = ((pbuf / bulksize) + 1) * bulksize;
-               }
-       } /* end while (aggregate same priority and same DA(AP or STA) frames) */
-
-       if (list_empty(&ptxservq->sta_pending))
-               list_del_init(&ptxservq->tx_pending);
-
-       spin_unlock_bh(&pxmitpriv->lock);
-       if ((pfirstframe->attrib.ether_type != 0x0806) &&
-           (pfirstframe->attrib.ether_type != 0x888e) &&
-           (pfirstframe->attrib.ether_type != 0x88b4) &&
-           (pfirstframe->attrib.dhcp_pkt != 1))
-               rtw_issue_addbareq_cmd(adapt, pfirstframe);
-       /* 3 3. update first frame txdesc */
-       if ((pbuf_tail % bulksize) == 0) {
-               /*  remove pkt_offset */
-               pbuf_tail -= PACKET_OFFSET_SZ;
-               pfirstframe->buf_addr += PACKET_OFFSET_SZ;
-               pfirstframe->pkt_offset--;
-       }
-
-       update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz);
-
-       /* 3 4. write xmit buffer to USB FIFO */
-       ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
-       rtw_write_port(adapt, ff_hwaddr, pbuf_tail, (u8 *)pxmitbuf);
-
-       /* 3 5. update statisitc */
-       pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
-       pbuf_tail -= (pfirstframe->pkt_offset * PACKET_OFFSET_SZ);
-
-       rtw_count_tx_stats(adapt, pfirstframe, pbuf_tail);
-
-       rtw_free_xmitframe(pxmitpriv, pfirstframe);
-
-       return true;
-}
-
-static s32 xmitframe_direct(struct adapter *adapt, struct xmit_frame *pxmitframe)
-{
-       s32 res = _SUCCESS;
-
-       res = rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe);
-       if (res == _SUCCESS)
-               rtw_dump_xframe(adapt, pxmitframe);
-
-       return res;
-}
-
-/*
- * Return
- *     true    dump packet directly
- *     false   enqueue packet
- */
-static s32 pre_xmitframe(struct adapter *adapt, struct xmit_frame *pxmitframe)
-{
-       s32 res;
-       struct xmit_buf *pxmitbuf = NULL;
-       struct xmit_priv *pxmitpriv = &adapt->xmitpriv;
-       struct pkt_attrib *pattrib = &pxmitframe->attrib;
-       struct mlme_priv *pmlmepriv = &adapt->mlmepriv;
-
-       spin_lock_bh(&pxmitpriv->lock);
-
-       if (rtw_txframes_sta_ac_pending(adapt, pattrib) > 0)
-               goto enqueue;
-
-       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING))
-               goto enqueue;
-
-       pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
-       if (!pxmitbuf)
-               goto enqueue;
-
-       spin_unlock_bh(&pxmitpriv->lock);
-
-       pxmitframe->pxmitbuf = pxmitbuf;
-       pxmitframe->buf_addr = pxmitbuf->pbuf;
-       pxmitbuf->priv_data = pxmitframe;
-
-       if (xmitframe_direct(adapt, pxmitframe) != _SUCCESS) {
-               rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
-               rtw_free_xmitframe(pxmitpriv, pxmitframe);
-       }
-
-       return true;
-
-enqueue:
-       res = rtw_xmit_classifier(adapt, pxmitframe);
-       spin_unlock_bh(&pxmitpriv->lock);
-
-       if (res != _SUCCESS) {
-               rtw_free_xmitframe(pxmitpriv, pxmitframe);
-
-               /*  Trick, make the statistics correct */
-               pxmitpriv->tx_pkts--;
-               pxmitpriv->tx_drop++;
-               return true;
-       }
-
-       return false;
-}
-
-s32 rtl8188eu_mgnt_xmit(struct adapter *adapt, struct xmit_frame *pmgntframe)
-{
-       return rtw_dump_xframe(adapt, pmgntframe);
-}
-
-/*
- * Return
- *     true    dump packet directly ok
- *     false   temporary can't transmit packets to hardware
- */
-s32 rtl8188eu_hal_xmit(struct adapter *adapt, struct xmit_frame *pxmitframe)
-{
-       return pre_xmitframe(adapt, pxmitframe);
-}
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
deleted file mode 100644 (file)
index a1051ac..0000000
+++ /dev/null
@@ -1,1069 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#define _HCI_HAL_INIT_C_
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/rtw_efuse.h"
-#include "../include/rtw_fw.h"
-#include "../include/rtl8188e_hal.h"
-#include "../include/rtw_iol.h"
-#include "../include/usb_ops.h"
-#include "../include/usb_osintf.h"
-#include "../include/HalPwrSeqCmd.h"
-
-static void one_out_pipe(struct adapter *adapter)
-{
-       struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(adapter);
-
-       pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
-       pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
-       pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
-       pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
-}
-
-static void two_out_pipe(struct adapter *adapter, bool wifi_cfg)
-{
-       struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(adapter);
-
-       /* 0:H, 1:L */
-
-       pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
-       pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
-
-       if (wifi_cfg) {
-               pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
-               pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
-       } else {
-               pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
-               pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
-       }
-}
-
-static void three_out_pipe(struct adapter *adapter, bool wifi_cfg)
-{
-       struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(adapter);
-
-       /* 0:H, 1:N, 2:L */
-
-       pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
-       pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
-       pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
-
-       pdvobjpriv->Queue2Pipe[3] = wifi_cfg ?
-               pdvobjpriv->RtOutPipe[1] : pdvobjpriv->RtOutPipe[2];/* BK */
-}
-
-int rtl8188eu_interface_configure(struct adapter *adapt)
-{
-       struct registry_priv *pregistrypriv = &adapt->registrypriv;
-       struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(adapt);
-       struct hal_data_8188e *haldata = &adapt->haldata;
-       bool wifi_cfg = pregistrypriv->wifi_spec;
-
-       pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
-       pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
-       pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
-       pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
-
-       switch (pdvobjpriv->RtNumOutPipes) {
-       case 3:
-               haldata->out_ep_extra_queues = TX_SELE_LQ | TX_SELE_NQ;
-               three_out_pipe(adapt, wifi_cfg);
-               break;
-       case 2:
-               haldata->out_ep_extra_queues = TX_SELE_NQ;
-               two_out_pipe(adapt, wifi_cfg);
-               break;
-       case 1:
-               one_out_pipe(adapt);
-               break;
-       default:
-               return -ENXIO;
-       }
-
-       return 0;
-}
-
-u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
-{
-       u16 value16;
-       int res;
-
-       /*  HW Power on sequence */
-       struct hal_data_8188e *haldata = &adapt->haldata;
-       if (haldata->bMacPwrCtrlOn)
-               return _SUCCESS;
-
-       if (!HalPwrSeqCmdParsing(adapt, PWR_ON_FLOW))
-               return _FAIL;
-
-       /*  Enable MAC DMA/WMAC/SCHEDULE/SEC block */
-       /*  Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */
-       rtw_write16(adapt, REG_CR, 0x00);  /* suggseted by zhouzhou, by page, 20111230 */
-
-               /*  Enable MAC DMA/WMAC/SCHEDULE/SEC block */
-       res = rtw_read16(adapt, REG_CR, &value16);
-       if (res)
-               return _FAIL;
-
-       value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN
-                               | PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_EN);
-       /*  for SDIO - Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */
-
-       rtw_write16(adapt, REG_CR, value16);
-       haldata->bMacPwrCtrlOn = true;
-
-       return _SUCCESS;
-}
-
-/*  Shall USB interface init this? */
-static void _InitInterrupt(struct adapter *Adapter)
-{
-       u32 imr, imr_ex;
-       u8  usb_opt;
-       int res;
-
-       /* HISR write one to clear */
-       rtw_write32(Adapter, REG_HISR_88E, 0xFFFFFFFF);
-       /*  HIMR - */
-       imr = IMR_PSTIMEOUT_88E | IMR_TBDER_88E | IMR_CPWM_88E | IMR_CPWM2_88E;
-       rtw_write32(Adapter, REG_HIMR_88E, imr);
-
-       imr_ex = IMR_TXERR_88E | IMR_RXERR_88E | IMR_TXFOVW_88E | IMR_RXFOVW_88E;
-       rtw_write32(Adapter, REG_HIMRE_88E, imr_ex);
-
-       /*  REG_USB_SPECIAL_OPTION - BIT(4) */
-       /*  0; Use interrupt endpoint to upload interrupt pkt */
-       /*  1; Use bulk endpoint to upload interrupt pkt, */
-       res = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION, &usb_opt);
-       if (res)
-               return;
-
-       if (adapter_to_dvobj(Adapter)->pusbdev->speed == USB_SPEED_HIGH)
-               usb_opt = usb_opt | (INT_BULK_SEL);
-       else
-               usb_opt = usb_opt & (~INT_BULK_SEL);
-
-       rtw_write8(Adapter, REG_USB_SPECIAL_OPTION, usb_opt);
-}
-
-static void _InitQueueReservedPage(struct adapter *Adapter)
-{
-       struct hal_data_8188e *haldata = &Adapter->haldata;
-       struct registry_priv    *pregistrypriv = &Adapter->registrypriv;
-       u8 numLQ = 0;
-       u8 numNQ = 0;
-       u8 numPubQ;
-
-       if (pregistrypriv->wifi_spec) {
-               if (haldata->out_ep_extra_queues & TX_SELE_LQ)
-                       numLQ = 0x1C;
-
-               /*  NOTE: This step shall be proceed before writing REG_RQPN. */
-               if (haldata->out_ep_extra_queues & TX_SELE_NQ)
-                       numNQ = 0x1C;
-
-               rtw_write8(Adapter, REG_RQPN_NPQ, numNQ);
-
-               numPubQ = 0xA8 - NUM_HQ - numLQ - numNQ;
-
-               /*  TX DMA */
-               rtw_write32(Adapter, REG_RQPN, LD_RQPN | numPubQ << 16 | numLQ << 8 | NUM_HQ);
-       } else {
-               rtw_write16(Adapter, REG_RQPN_NPQ, 0x0000);/* Just follow MP Team,??? Georgia 03/28 */
-               rtw_write16(Adapter, REG_RQPN_NPQ, 0x0d);
-               rtw_write32(Adapter, REG_RQPN, 0x808E000d);/* reserve 7 page for LPS */
-       }
-}
-
-static void _InitTxBufferBoundary(struct adapter *Adapter, u8 txpktbuf_bndy)
-{
-       rtw_write8(Adapter, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
-       rtw_write8(Adapter, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
-       rtw_write8(Adapter, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy);
-       rtw_write8(Adapter, REG_TRXFF_BNDY, txpktbuf_bndy);
-       rtw_write8(Adapter, REG_TDECTRL + 1, txpktbuf_bndy);
-}
-
-static void _InitPageBoundary(struct adapter *Adapter)
-{
-       /*  RX Page Boundary */
-       /*  */
-       u16 rxff_bndy = MAX_RX_DMA_BUFFER_SIZE_88E - 1;
-
-       rtw_write16(Adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
-}
-
-static void _InitNormalChipRegPriority(struct adapter *Adapter, u16 beQ,
-                                      u16 bkQ, u16 viQ, u16 voQ, u16 mgtQ,
-                                      u16 hiQ)
-{
-       u16 value16;
-       int res;
-
-       res = rtw_read16(Adapter, REG_TRXDMA_CTRL, &value16);
-       if (res)
-               return;
-
-       value16 &= 0x7;
-
-       value16 |= _TXDMA_BEQ_MAP(beQ)  | _TXDMA_BKQ_MAP(bkQ) |
-                  _TXDMA_VIQ_MAP(viQ)  | _TXDMA_VOQ_MAP(voQ) |
-                  _TXDMA_MGQ_MAP(mgtQ) | _TXDMA_HIQ_MAP(hiQ);
-
-       rtw_write16(Adapter, REG_TRXDMA_CTRL, value16);
-}
-
-static void _InitNormalChipTwoOutEpPriority(struct adapter *Adapter)
-{
-       struct registry_priv *pregistrypriv = &Adapter->registrypriv;
-       u16 bkQ, voQ;
-
-       if (!pregistrypriv->wifi_spec) {
-               bkQ     = QUEUE_NORMAL;
-               voQ     = QUEUE_HIGH;
-       } else {/* for WMM ,CONFIG_OUT_EP_WIFI_MODE */
-               bkQ     = QUEUE_HIGH;
-               voQ     = QUEUE_NORMAL;
-       }
-       _InitNormalChipRegPriority(Adapter, QUEUE_NORMAL, bkQ, QUEUE_HIGH,
-                                  voQ, QUEUE_HIGH, QUEUE_HIGH);
-}
-
-static void _InitNormalChipThreeOutEpPriority(struct adapter *Adapter)
-{
-       struct registry_priv *pregistrypriv = &Adapter->registrypriv;
-       u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ;
-
-       if (!pregistrypriv->wifi_spec) {/*  typical setting */
-               beQ     = QUEUE_LOW;
-               bkQ     = QUEUE_LOW;
-               viQ     = QUEUE_NORMAL;
-               voQ     = QUEUE_HIGH;
-               mgtQ    = QUEUE_HIGH;
-               hiQ     = QUEUE_HIGH;
-       } else {/*  for WMM */
-               beQ     = QUEUE_LOW;
-               bkQ     = QUEUE_NORMAL;
-               viQ     = QUEUE_NORMAL;
-               voQ     = QUEUE_HIGH;
-               mgtQ    = QUEUE_HIGH;
-               hiQ     = QUEUE_HIGH;
-       }
-       _InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ);
-}
-
-static void _InitQueuePriority(struct adapter *Adapter)
-{
-       struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(Adapter);
-
-       switch (pdvobjpriv->RtNumOutPipes) {
-       case 1:
-               _InitNormalChipRegPriority(Adapter, QUEUE_HIGH, QUEUE_HIGH, QUEUE_HIGH,
-                                          QUEUE_HIGH, QUEUE_HIGH, QUEUE_HIGH);
-               break;
-       case 2:
-               _InitNormalChipTwoOutEpPriority(Adapter);
-               break;
-       case 3:
-               _InitNormalChipThreeOutEpPriority(Adapter);
-               break;
-       default:
-               break;
-       }
-}
-
-static void _InitNetworkType(struct adapter *Adapter)
-{
-       u32 value32;
-       int res;
-
-       res = rtw_read32(Adapter, REG_CR, &value32);
-       if (res)
-               return;
-
-       /*  TODO: use the other function to set network type */
-       value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP);
-
-       rtw_write32(Adapter, REG_CR, value32);
-}
-
-static void _InitTransferPageSize(struct adapter *Adapter)
-{
-       /*  Tx page size is always 128. */
-
-       u8 value8;
-       value8 = _PSRX(PBP_128) | _PSTX(PBP_128);
-       rtw_write8(Adapter, REG_PBP, value8);
-}
-
-static void _InitDriverInfoSize(struct adapter *Adapter, u8 drvInfoSize)
-{
-       rtw_write8(Adapter, REG_RX_DRVINFO_SZ, drvInfoSize);
-}
-
-static void _InitWMACSetting(struct adapter *Adapter)
-{
-       u32 receive_config = RCR_AAP | RCR_APM | RCR_AM | RCR_AB |
-                            RCR_CBSSID_DATA | RCR_CBSSID_BCN |
-                            RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL |
-                            RCR_APP_MIC | RCR_APP_PHYSTS;
-
-       /*  some REG_RCR will be modified later by phy_ConfigMACWithHeaderFile() */
-       rtw_write32(Adapter, REG_RCR, receive_config);
-
-       /*  Accept all multicast address */
-       rtw_write32(Adapter, REG_MAR, 0xFFFFFFFF);
-       rtw_write32(Adapter, REG_MAR + 4, 0xFFFFFFFF);
-}
-
-static void _InitAdaptiveCtrl(struct adapter *Adapter)
-{
-       u16 value16;
-       u32 value32;
-       int res;
-
-       /*  Response Rate Set */
-       res = rtw_read32(Adapter, REG_RRSR, &value32);
-       if (res)
-               return;
-
-       value32 &= ~RATE_BITMAP_ALL;
-       value32 |= RATE_RRSR_CCK_ONLY_1M;
-       rtw_write32(Adapter, REG_RRSR, value32);
-
-       /*  CF-END Threshold */
-
-       /*  SIFS (used in NAV) */
-       value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10);
-       rtw_write16(Adapter, REG_SPEC_SIFS, value16);
-
-       /*  Retry Limit */
-       value16 = _LRL(0x30) | _SRL(0x30);
-       rtw_write16(Adapter, REG_RL, value16);
-}
-
-static void _InitEDCA(struct adapter *Adapter)
-{
-       /*  Set Spec SIFS (used in NAV) */
-       rtw_write16(Adapter, REG_SPEC_SIFS, 0x100a);
-       rtw_write16(Adapter, REG_MAC_SPEC_SIFS, 0x100a);
-
-       /*  Set SIFS for CCK */
-       rtw_write16(Adapter, REG_SIFS_CTX, 0x100a);
-
-       /*  Set SIFS for OFDM */
-       rtw_write16(Adapter, REG_SIFS_TRX, 0x100a);
-
-       /*  TXOP */
-       rtw_write32(Adapter, REG_EDCA_BE_PARAM, 0x005EA42B);
-       rtw_write32(Adapter, REG_EDCA_BK_PARAM, 0x0000A44F);
-       rtw_write32(Adapter, REG_EDCA_VI_PARAM, 0x005EA324);
-       rtw_write32(Adapter, REG_EDCA_VO_PARAM, 0x002FA226);
-}
-
-static void _InitRetryFunction(struct adapter *Adapter)
-{
-       u8 value8;
-       int res;
-
-       res = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL, &value8);
-       if (res)
-               return;
-
-       value8 |= EN_AMPDU_RTY_NEW;
-       rtw_write8(Adapter, REG_FWHW_TXQ_CTRL, value8);
-
-       /*  Set ACK timeout */
-       rtw_write8(Adapter, REG_ACKTO, 0x40);
-}
-
-/*-----------------------------------------------------------------------------
- * Function:   usb_AggSettingTxUpdate()
- *
- * Overview:   Separate TX/RX parameters update independent for TP detection and
- *                     dynamic TX/RX aggreagtion parameters update.
- *
- * Input:                      struct adapter *
- *
- * Output/Return:      NONE
- *
- * Revised History:
- *     When            Who             Remark
- *     12/10/2010      MHC             Separate to smaller function.
- *
- *---------------------------------------------------------------------------*/
-static void usb_AggSettingTxUpdate(struct adapter *Adapter)
-{
-       u32 value32;
-       int res;
-
-       if (Adapter->registrypriv.wifi_spec)
-               return;
-
-       res = rtw_read32(Adapter, REG_TDECTRL, &value32);
-       if (res)
-               return;
-
-       value32 = value32 & ~(BLK_DESC_NUM_MASK << BLK_DESC_NUM_SHIFT);
-       value32 |= ((USB_TXAGG_DESC_NUM & BLK_DESC_NUM_MASK) << BLK_DESC_NUM_SHIFT);
-
-       rtw_write32(Adapter, REG_TDECTRL, value32);
-}
-
-/*-----------------------------------------------------------------------------
- * Function:   usb_AggSettingRxUpdate()
- *
- * Overview:   Separate TX/RX parameters update independent for TP detection and
- *                     dynamic TX/RX aggreagtion parameters update.
- *
- * Input:                      struct adapter *
- *
- * Output/Return:      NONE
- *
- * Revised History:
- *     When            Who             Remark
- *     12/10/2010      MHC             Separate to smaller function.
- *
- *---------------------------------------------------------------------------*/
-static void
-usb_AggSettingRxUpdate(
-               struct adapter *Adapter
-       )
-{
-       u8 valueDMA;
-       u8 valueUSB;
-       int res;
-
-       res = rtw_read8(Adapter, REG_TRXDMA_CTRL, &valueDMA);
-       if (res)
-               return;
-
-       res = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION, &valueUSB);
-       if (res)
-               return;
-
-       valueDMA |= RXDMA_AGG_EN;
-       valueUSB &= ~USB_AGG_EN;
-
-       rtw_write8(Adapter, REG_TRXDMA_CTRL, valueDMA);
-       rtw_write8(Adapter, REG_USB_SPECIAL_OPTION, valueUSB);
-
-       rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, USB_RXAGG_PAGE_COUNT);
-       rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH + 1, USB_RXAGG_PAGE_TIMEOUT);
-}
-
-static void InitUsbAggregationSetting(struct adapter *Adapter)
-{
-       /*  Tx aggregation setting */
-       usb_AggSettingTxUpdate(Adapter);
-
-       /*  Rx aggregation setting */
-       usb_AggSettingRxUpdate(Adapter);
-}
-
-/* FIXME: add error handling in callers */
-static int _InitBeaconParameters(struct adapter *Adapter)
-{
-       struct hal_data_8188e *haldata = &Adapter->haldata;
-       int res;
-
-       rtw_write16(Adapter, REG_BCN_CTRL, 0x1010);
-
-       /*  TODO: Remove these magic number */
-       rtw_write16(Adapter, REG_TBTT_PROHIBIT, 0x6404);/*  ms */
-       rtw_write8(Adapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME);/*  5ms */
-       rtw_write8(Adapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME); /*  2ms */
-
-       /*  Suggested by designer timchen. Change beacon AIFS to the largest number */
-       /*  beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */
-       rtw_write16(Adapter, REG_BCNTCFG, 0x660F);
-
-       res = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2, &haldata->RegFwHwTxQCtrl);
-       if (res)
-               return res;
-
-       res = rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2, &haldata->RegReg542);
-       if (res)
-               return res;
-
-       res = rtw_read8(Adapter, REG_CR + 1, &haldata->RegCR_1);
-       if (res)
-               return res;
-
-       return 0;
-}
-
-static void _BeaconFunctionEnable(struct adapter *Adapter)
-{
-       rtw_write8(Adapter, REG_BCN_CTRL, (BIT(4) | BIT(3) | BIT(1)));
-
-       rtw_write8(Adapter, REG_RD_CTRL + 1, 0x6F);
-}
-
-/*  Set CCK and OFDM Block "ON" */
-static void _BBTurnOnBlock(struct adapter *Adapter)
-{
-       rtl8188e_PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bCCKEn, 0x1);
-       rtl8188e_PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bOFDMEn, 0x1);
-}
-
-static void _InitAntenna_Selection(struct adapter *Adapter)
-{
-       struct hal_data_8188e *haldata = &Adapter->haldata;
-       int res;
-       u32 reg;
-
-       if (haldata->AntDivCfg == 0)
-               return;
-
-       res = rtw_read32(Adapter, REG_LEDCFG0, &reg);
-       if (res)
-               return;
-
-       rtw_write32(Adapter, REG_LEDCFG0, reg | BIT(23));
-       rtl8188e_PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, BIT(13), 0x01);
-
-       if (rtl8188e_PHY_QueryBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300) == Antenna_A)
-               haldata->CurAntenna = Antenna_A;
-       else
-               haldata->CurAntenna = Antenna_B;
-}
-
-static void hw_var_set_macaddr(struct adapter *Adapter, u8 *val)
-{
-       u8 idx = 0;
-       u32 reg_macid;
-
-       reg_macid = REG_MACID;
-
-       for (idx = 0; idx < 6; idx++)
-               rtw_write8(Adapter, (reg_macid + idx), val[idx]);
-}
-
-u32 rtl8188eu_hal_init(struct adapter *Adapter)
-{
-       u8 value8 = 0;
-       u16  value16;
-       u32 status = _SUCCESS;
-       int res;
-       struct hal_data_8188e *haldata = &Adapter->haldata;
-       struct pwrctrl_priv             *pwrctrlpriv = &Adapter->pwrctrlpriv;
-       struct registry_priv    *pregistrypriv = &Adapter->registrypriv;
-       u32 reg;
-
-       if (Adapter->pwrctrlpriv.bkeepfwalive) {
-               if (haldata->odmpriv.RFCalibrateInfo.bIQKInitialized) {
-                       PHY_IQCalibrate_8188E(Adapter, true);
-               } else {
-                       PHY_IQCalibrate_8188E(Adapter, false);
-                       haldata->odmpriv.RFCalibrateInfo.bIQKInitialized = true;
-               }
-
-               ODM_TXPowerTrackingCheck(&haldata->odmpriv);
-               PHY_LCCalibrate_8188E(Adapter);
-
-               goto exit;
-       }
-
-       status = rtl8188eu_InitPowerOn(Adapter);
-       if (status == _FAIL)
-               goto exit;
-
-       /*  Save target channel */
-       haldata->CurrentChannel = 6;/* default set to 6 */
-
-       /*  2010/08/09 MH We need to check if we need to turnon or off RF after detecting */
-       /*  HW GPIO pin. Before PHY_RFConfig8192C. */
-       /*  2010/08/26 MH If Efuse does not support sective suspend then disable the function. */
-
-       _InitQueueReservedPage(Adapter);
-       _InitQueuePriority(Adapter);
-       _InitPageBoundary(Adapter);
-       _InitTransferPageSize(Adapter);
-
-       _InitTxBufferBoundary(Adapter, 0);
-
-       status = rtl8188e_firmware_download(Adapter);
-
-       if (status != _SUCCESS) {
-               Adapter->bFWReady = false;
-               haldata->fw_ractrl = false;
-               return status;
-       } else {
-               Adapter->bFWReady = true;
-               haldata->fw_ractrl = false;
-       }
-       /* Initialize firmware vars */
-       Adapter->pwrctrlpriv.bFwCurrentInPSMode = false;
-       haldata->LastHMEBoxNum = 0;
-
-       if (PHY_MACConfig8188E(Adapter))
-               return _FAIL;
-
-       /*  */
-       /* d. Initialize BB related configurations. */
-       /*  */
-       if (PHY_BBConfig8188E(Adapter))
-               return _FAIL;
-
-       if (phy_RF6052_Config_ParaFile(Adapter))
-               return _FAIL;
-
-       status = rtl8188e_iol_efuse_patch(Adapter);
-       if (status == _FAIL)
-               goto exit;
-
-       _InitTxBufferBoundary(Adapter, TX_PAGE_BOUNDARY_88E);
-
-       status =  InitLLTTable(Adapter, TX_PAGE_BOUNDARY_88E);
-       if (status == _FAIL)
-               goto exit;
-
-       /*  Get Rx PHY status in order to report RSSI and others. */
-       _InitDriverInfoSize(Adapter, DRVINFO_SZ);
-
-       _InitInterrupt(Adapter);
-       hw_var_set_macaddr(Adapter, Adapter->eeprompriv.mac_addr);
-       _InitNetworkType(Adapter);/* set msr */
-       _InitWMACSetting(Adapter);
-       _InitAdaptiveCtrl(Adapter);
-       _InitEDCA(Adapter);
-       _InitRetryFunction(Adapter);
-       InitUsbAggregationSetting(Adapter);
-       _InitBeaconParameters(Adapter);
-
-       /*  */
-       /*  Init CR MACTXEN, MACRXEN after setting RxFF boundary REG_TRXFF_BNDY to patch */
-       /*  Hw bug which Hw initials RxFF boundary size to a value which is larger than the real Rx buffer size in 88E. */
-       /*  */
-       /*  Enable MACTXEN/MACRXEN block */
-       res = rtw_read16(Adapter, REG_CR, &value16);
-       if (res)
-               return _FAIL;
-
-       value16 |= (MACTXEN | MACRXEN);
-       rtw_write8(Adapter, REG_CR, value16);
-
-       /* Enable TX Report */
-       /* Enable Tx Report Timer */
-       res = rtw_read8(Adapter, REG_TX_RPT_CTRL, &value8);
-       if (res)
-               return _FAIL;
-
-       rtw_write8(Adapter,  REG_TX_RPT_CTRL, (value8 | BIT(1) | BIT(0)));
-       /* Set MAX RPT MACID */
-       rtw_write8(Adapter,  REG_TX_RPT_CTRL + 1, 2);/* FOR sta mode ,0: bc/mc ,1:AP */
-       /* Tx RPT Timer. Unit: 32us */
-       rtw_write16(Adapter, REG_TX_RPT_TIME, 0xCdf0);
-
-       rtw_write8(Adapter, REG_EARLY_MODE_CONTROL, 0);
-
-       rtw_write16(Adapter, REG_PKT_VO_VI_LIFE_TIME, 0x0400);  /*  unit: 256us. 256ms */
-       rtw_write16(Adapter, REG_PKT_BE_BK_LIFE_TIME, 0x0400);  /*  unit: 256us. 256ms */
-
-       /* Keep RfRegChnlVal for later use. */
-       haldata->RfRegChnlVal = rtl8188e_PHY_QueryRFReg(Adapter, RF_CHNLBW, bRFRegOffsetMask);
-
-       _BBTurnOnBlock(Adapter);
-
-       invalidate_cam_all(Adapter);
-
-       /*  2010/12/17 MH We need to set TX power according to EFUSE content at first. */
-       PHY_SetTxPowerLevel8188E(Adapter, haldata->CurrentChannel);
-
-/*  Move by Neo for USB SS to below setp */
-/* _RfPowerSave(Adapter); */
-
-       _InitAntenna_Selection(Adapter);
-
-       /*  */
-       /*  Disable BAR, suggested by Scott */
-       /*  2010.04.09 add by hpfan */
-       /*  */
-       rtw_write32(Adapter, REG_BAR_MODE_CTRL, 0x0201ffff);
-
-       /*  HW SEQ CTRL */
-       /* set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. */
-       rtw_write8(Adapter, REG_HWSEQ_CTRL, 0xFF);
-
-       if (pregistrypriv->wifi_spec)
-               rtw_write16(Adapter, REG_FAST_EDCA_CTRL, 0);
-
-       /* Nav limit , suggest by scott */
-       rtw_write8(Adapter, 0x652, 0x0);
-
-       rtl8188e_InitHalDm(Adapter);
-
-       /*  2010/08/11 MH Merge from 8192SE for Minicard init. We need to confirm current radio status */
-       /*  and then decide to enable RF or not.!!!??? For Selective suspend mode. We may not */
-       /*  call initstruct adapter. May cause some problem?? */
-       /*  Fix the bug that Hw/Sw radio off before S3/S4, the RF off action will not be executed */
-       /*  in MgntActSet_RF_State() after wake up, because the value of haldata->eRFPowerState */
-       /*  is the same as eRfOff, we should change it to eRfOn after we config RF parameters. */
-       /*  Added by tynli. 2010.03.30. */
-       pwrctrlpriv->rf_pwrstate = rf_on;
-
-       /*  enable Tx report. */
-       rtw_write8(Adapter,  REG_FWHW_TXQ_CTRL + 1, 0x0F);
-
-       /*  Suggested by SD1 pisa. Added by tynli. 2011.10.21. */
-       rtw_write8(Adapter, REG_EARLY_MODE_CONTROL + 3, 0x01);/* Pretx_en, for WEP/TKIP SEC */
-
-       /* tynli_test_tx_report. */
-       rtw_write16(Adapter, REG_TX_RPT_TIME, 0x3DF0);
-
-       /* enable tx DMA to drop the redundate data of packet */
-       res = rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK, &value16);
-       if (res)
-               return _FAIL;
-
-       rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (value16 | DROP_DATA_EN));
-
-       /*  2010/08/26 MH Merge from 8192CE. */
-       if (pwrctrlpriv->rf_pwrstate == rf_on) {
-               if (haldata->odmpriv.RFCalibrateInfo.bIQKInitialized) {
-                       PHY_IQCalibrate_8188E(Adapter, true);
-               } else {
-                       PHY_IQCalibrate_8188E(Adapter, false);
-                       haldata->odmpriv.RFCalibrateInfo.bIQKInitialized = true;
-               }
-
-               ODM_TXPowerTrackingCheck(&haldata->odmpriv);
-
-               PHY_LCCalibrate_8188E(Adapter);
-       }
-
-/*     _InitPABias(Adapter); */
-       rtw_write8(Adapter, REG_USB_HRPWM, 0);
-
-       /* ack for xmit mgmt frames. */
-       res = rtw_read32(Adapter, REG_FWHW_TXQ_CTRL, &reg);
-       if (res)
-               return _FAIL;
-
-       rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, reg | BIT(12));
-
-exit:
-       return status;
-}
-
-static void CardDisableRTL8188EU(struct adapter *Adapter)
-{
-       u8 val8;
-       struct hal_data_8188e *haldata = &Adapter->haldata;
-       int res;
-
-       /* Stop Tx Report Timer. 0x4EC[Bit1]=b'0 */
-       res = rtw_read8(Adapter, REG_TX_RPT_CTRL, &val8);
-       if (res)
-               return;
-
-       rtw_write8(Adapter, REG_TX_RPT_CTRL, val8 & (~BIT(1)));
-
-       /*  stop rx */
-       rtw_write8(Adapter, REG_CR, 0x0);
-
-       /*  Run LPS WL RFOFF flow */
-       HalPwrSeqCmdParsing(Adapter, LPS_ENTER_FLOW);
-
-       /*  2. 0x1F[7:0] = 0            turn off RF */
-
-       res = rtw_read8(Adapter, REG_MCUFWDL, &val8);
-       if (res)
-               return;
-
-       if ((val8 & RAM_DL_SEL) && Adapter->bFWReady) { /* 8051 RAM code */
-               /*  Reset MCU 0x2[10]=0. */
-               res = rtw_read8(Adapter, REG_SYS_FUNC_EN + 1, &val8);
-               if (res)
-                       return;
-
-               val8 &= ~BIT(2);        /*  0x2[10], FEN_CPUEN */
-               rtw_write8(Adapter, REG_SYS_FUNC_EN + 1, val8);
-       }
-
-       /*  reset MCU ready status */
-       rtw_write8(Adapter, REG_MCUFWDL, 0);
-
-       /* YJ,add,111212 */
-       /* Disable 32k */
-       res = rtw_read8(Adapter, REG_32K_CTRL, &val8);
-       if (res)
-               return;
-
-       rtw_write8(Adapter, REG_32K_CTRL, val8 & (~BIT(0)));
-
-       /*  Card disable power action flow */
-       HalPwrSeqCmdParsing(Adapter, DISABLE_FLOW);
-
-       /*  Reset MCU IO Wrapper */
-       res = rtw_read8(Adapter, REG_RSV_CTRL + 1, &val8);
-       if (res)
-               return;
-
-       rtw_write8(Adapter, REG_RSV_CTRL + 1, (val8 & (~BIT(3))));
-
-       res = rtw_read8(Adapter, REG_RSV_CTRL + 1, &val8);
-       if (res)
-               return;
-
-       rtw_write8(Adapter, REG_RSV_CTRL + 1, val8 | BIT(3));
-
-       /* YJ,test add, 111207. For Power Consumption. */
-       res = rtw_read8(Adapter, GPIO_IN, &val8);
-       if (res)
-               return;
-
-       rtw_write8(Adapter, GPIO_OUT, val8);
-       rtw_write8(Adapter, GPIO_IO_SEL, 0xFF);/* Reg0x46 */
-
-       res = rtw_read8(Adapter, REG_GPIO_IO_SEL, &val8);
-       if (res)
-               return;
-
-       rtw_write8(Adapter, REG_GPIO_IO_SEL, (val8 << 4));
-       res = rtw_read8(Adapter, REG_GPIO_IO_SEL + 1, &val8);
-       if (res)
-               return;
-
-       rtw_write8(Adapter, REG_GPIO_IO_SEL + 1, val8 | 0x0F);/* Reg0x43 */
-       rtw_write32(Adapter, REG_BB_PAD_CTRL, 0x00080808);/* set LNA ,TRSW,EX_PA Pin to output mode */
-       haldata->bMacPwrCtrlOn = false;
-       Adapter->bFWReady = false;
-}
-
-u32 rtl8188eu_hal_deinit(struct adapter *Adapter)
-{
-       rtw_write32(Adapter, REG_HIMR_88E, IMR_DISABLED_88E);
-       rtw_write32(Adapter, REG_HIMRE_88E, IMR_DISABLED_88E);
-
-       if (!Adapter->pwrctrlpriv.bkeepfwalive) {
-               if (Adapter->hw_init_completed) {
-                       CardDisableRTL8188EU(Adapter);
-               }
-       }
-       return _SUCCESS;
- }
-
-int rtl8188eu_inirp_init(struct adapter *Adapter)
-{
-       u8 i;
-       struct recv_buf *precvbuf;
-       struct recv_priv *precvpriv = &Adapter->recvpriv;
-       int ret;
-
-       /* issue Rx irp to receive data */
-       precvbuf = (struct recv_buf *)precvpriv->precv_buf;
-       for (i = 0; i < NR_RECVBUFF; i++) {
-               ret = rtw_read_port(Adapter, precvbuf);
-               if (ret)
-                       return ret;
-
-               precvbuf++;
-               precvpriv->free_recv_buf_queue_cnt--;
-       }
-
-       return 0;
-}
-
-/*  */
-/*  */
-/*     EEPROM/EFUSE Content Parsing */
-/*  */
-/*  */
-
-static void Hal_EfuseParseMACAddr_8188EU(struct adapter *adapt, u8 *hwinfo, bool AutoLoadFail)
-{
-       struct eeprom_priv *eeprom = &adapt->eeprompriv;
-
-       if (AutoLoadFail) {
-               eth_random_addr(eeprom->mac_addr);
-       } else {
-               /* Read Permanent MAC address */
-               memcpy(eeprom->mac_addr, &hwinfo[EEPROM_MAC_ADDR_88EU], ETH_ALEN);
-       }
-}
-
-int ReadAdapterInfo8188EU(struct adapter *Adapter)
-{
-       struct eeprom_priv *eeprom = &Adapter->eeprompriv;
-       struct led_priv *ledpriv = &Adapter->ledpriv;
-       u8 *efuse_buf;
-       u8 eeValue;
-       int res;
-
-       /* check system boot selection */
-       res = rtw_read8(Adapter, REG_9346CR, &eeValue);
-       if (res)
-               return res;
-
-       eeprom->bautoload_fail_flag     = !(eeValue & EEPROM_EN);
-
-       efuse_buf = kmalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL);
-       if (!efuse_buf)
-               return -ENOMEM;
-       memset(efuse_buf, 0xFF, EFUSE_MAP_LEN_88E);
-
-       if (!(eeValue & BOOT_FROM_EEPROM) && !eeprom->bautoload_fail_flag) {
-               rtl8188e_EfusePowerSwitch(Adapter, true);
-               rtl8188e_ReadEFuse(Adapter, EFUSE_MAP_LEN_88E, efuse_buf);
-               rtl8188e_EfusePowerSwitch(Adapter, false);
-       }
-
-       /* parse the eeprom/efuse content */
-       Hal_EfuseParseIDCode88E(Adapter, efuse_buf);
-       Hal_EfuseParseMACAddr_8188EU(Adapter, efuse_buf, eeprom->bautoload_fail_flag);
-
-       Hal_ReadPowerSavingMode88E(Adapter, efuse_buf, eeprom->bautoload_fail_flag);
-       Hal_ReadTxPowerInfo88E(Adapter, efuse_buf, eeprom->bautoload_fail_flag);
-       rtl8188e_EfuseParseChnlPlan(Adapter, efuse_buf, eeprom->bautoload_fail_flag);
-       Hal_EfuseParseXtal_8188E(Adapter, efuse_buf, eeprom->bautoload_fail_flag);
-       Hal_ReadAntennaDiversity88E(Adapter, efuse_buf, eeprom->bautoload_fail_flag);
-       Hal_ReadThermalMeter_88E(Adapter, efuse_buf, eeprom->bautoload_fail_flag);
-
-       ledpriv->bRegUseLed = true;
-       kfree(efuse_buf);
-       return 0;
-}
-
-void UpdateHalRAMask8188EUsb(struct adapter *adapt, u32 mac_id, u8 rssi_level)
-{
-       u8 init_rate = 0;
-       u8 networkType, raid;
-       u32 mask, rate_bitmap;
-       u8 shortGIrate = false;
-       int     supportRateNum = 0;
-       struct sta_info *psta;
-       struct hal_data_8188e *haldata = &adapt->haldata;
-       struct mlme_ext_priv    *pmlmeext = &adapt->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_bssid_ex    *cur_network = &pmlmeinfo->network;
-
-       if (mac_id >= NUM_STA) /* CAM_SIZE */
-               return;
-       psta = pmlmeinfo->FW_sta_info[mac_id].psta;
-       if (!psta)
-               return;
-       switch (mac_id) {
-       case 0:/*  for infra mode */
-               supportRateNum = rtw_get_rateset_len(cur_network->SupportedRates);
-               networkType = judge_network_type(adapt, cur_network->SupportedRates, supportRateNum) & 0xf;
-               raid = networktype_to_raid(networkType);
-               mask = update_supported_rate(cur_network->SupportedRates, supportRateNum);
-               mask |= (pmlmeinfo->HT_enable) ? update_MSC_rate(&pmlmeinfo->HT_caps) : 0;
-               if (support_short_GI(adapt, &pmlmeinfo->HT_caps))
-                       shortGIrate = true;
-               break;
-       case 1:/* for broadcast/multicast */
-               supportRateNum = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[mac_id].SupportedRates);
-               if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
-                       networkType = WIRELESS_11B;
-               else
-                       networkType = WIRELESS_11G;
-               raid = networktype_to_raid(networkType);
-               mask = update_basic_rate(cur_network->SupportedRates, supportRateNum);
-               break;
-       default: /* for each sta in IBSS */
-               supportRateNum = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[mac_id].SupportedRates);
-               networkType = judge_network_type(adapt, pmlmeinfo->FW_sta_info[mac_id].SupportedRates, supportRateNum) & 0xf;
-               raid = networktype_to_raid(networkType);
-               mask = update_supported_rate(cur_network->SupportedRates, supportRateNum);
-
-               /* todo: support HT in IBSS */
-               break;
-       }
-
-       rate_bitmap = 0x0fffffff;
-       rate_bitmap = ODM_Get_Rate_Bitmap(&haldata->odmpriv, mac_id, mask, rssi_level);
-
-       mask &= rate_bitmap;
-
-       init_rate = get_highest_rate_idx(mask) & 0x3f;
-
-       if (haldata->fw_ractrl) {
-               mask |= ((raid << 28) & 0xf0000000);
-               psta->ra_mask = mask;
-               mask |= ((raid << 28) & 0xf0000000);
-
-               /* to do ,for 8188E-SMIC */
-               rtl8188e_set_raid_cmd(adapt, mask);
-       } else {
-               ODM_RA_UpdateRateInfo_8188E(&haldata->odmpriv,
-                               mac_id,
-                               raid,
-                               mask,
-                               shortGIrate
-                               );
-       }
-       /* set ra_id */
-       psta->raid = raid;
-       psta->init_rate = init_rate;
-}
-
-void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
-{
-       u32 value32;
-       struct mlme_ext_priv    *pmlmeext = &adapt->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
-       u32 bcn_ctrl_reg                        = REG_BCN_CTRL;
-       int res;
-       u8 reg;
-       /* reset TSF, enable update TSF, correcting TSF On Beacon */
-
-       /* BCN interval */
-       rtw_write16(adapt, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
-       rtw_write8(adapt, REG_ATIMWND, 0x02);/*  2ms */
-
-       _InitBeaconParameters(adapt);
-
-       rtw_write8(adapt, REG_SLOT, 0x09);
-
-       res = rtw_read32(adapt, REG_TCR, &value32);
-       if (res)
-               return;
-
-       value32 &= ~TSFRST;
-       rtw_write32(adapt,  REG_TCR, value32);
-
-       value32 |= TSFRST;
-       rtw_write32(adapt, REG_TCR, value32);
-
-       /*  NOTE: Fix test chip's bug (about contention windows's randomness) */
-       rtw_write8(adapt,  REG_RXTSF_OFFSET_CCK, 0x50);
-       rtw_write8(adapt, REG_RXTSF_OFFSET_OFDM, 0x50);
-
-       _BeaconFunctionEnable(adapt);
-
-       rtw_resume_tx_beacon(adapt);
-
-       res = rtw_read8(adapt, bcn_ctrl_reg, &reg);
-       if (res)
-               return;
-
-       rtw_write8(adapt, bcn_ctrl_reg, reg | BIT(1));
-}
-
-void rtl8188eu_init_default_value(struct adapter *adapt)
-{
-       struct hal_data_8188e *haldata = &adapt->haldata;
-       struct pwrctrl_priv *pwrctrlpriv;
-       u8 i;
-
-       pwrctrlpriv = &adapt->pwrctrlpriv;
-
-       /* init default value */
-       haldata->fw_ractrl = false;
-       if (!pwrctrlpriv->bkeepfwalive)
-               haldata->LastHMEBoxNum = 0;
-
-       /* init dm default value */
-       haldata->odmpriv.RFCalibrateInfo.bIQKInitialized = false;
-       haldata->odmpriv.RFCalibrateInfo.TM_Trigger = 0;/* for IQK */
-       haldata->pwrGroupCnt = 0;
-       haldata->odmpriv.RFCalibrateInfo.ThermalValue_HP_index = 0;
-       for (i = 0; i < HP_THERMAL_NUM; i++)
-               haldata->odmpriv.RFCalibrateInfo.ThermalValue_HP[i] = 0;
-}
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c
deleted file mode 100644 (file)
index 9611b19..0000000
+++ /dev/null
@@ -1,476 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/osdep_intf.h"
-#include "../include/usb_ops.h"
-#include "../include/rtl8188e_hal.h"
-
-#define VENDOR_CMD_MAX_DATA_LEN        254
-
-#define RTW_USB_CONTROL_MSG_TIMEOUT    500/* ms */
-
-static int usb_read(struct adapter *adapt, u16 value, void *data, u8 size)
-{
-       struct dvobj_priv *dvobjpriv = adapter_to_dvobj(adapt);
-       struct usb_device *udev = dvobjpriv->pusbdev;
-       int status;
-       u8 io_buf[4];
-
-       if (adapt->bSurpriseRemoved)
-               return -EPERM;
-
-       status = usb_control_msg_recv(udev, 0, REALTEK_USB_VENQT_CMD_REQ,
-                                     REALTEK_USB_VENQT_READ, value,
-                                     REALTEK_USB_VENQT_CMD_IDX, io_buf,
-                                     size, RTW_USB_CONTROL_MSG_TIMEOUT,
-                                     GFP_KERNEL);
-
-       if (status == -ESHUTDOWN ||
-           status == -ENODEV ||
-           status == -ENOENT) {
-               /*
-                * device or controller has been disabled due to
-                * some problem that could not be worked around,
-                * device or bus doesn’t exist, endpoint does not
-                * exist or is not enabled.
-                */
-               adapt->bSurpriseRemoved = true;
-               return status;
-       }
-
-       if (status < 0) {
-               if (rtw_inc_and_chk_continual_urb_error(dvobjpriv))
-                       adapt->bSurpriseRemoved = true;
-
-               return status;
-       }
-
-       rtw_reset_continual_urb_error(dvobjpriv);
-       memcpy(data, io_buf, size);
-
-       return status;
-}
-
-static int usb_write(struct adapter *adapt, u16 value, void *data, u8 size)
-{
-       struct dvobj_priv *dvobjpriv = adapter_to_dvobj(adapt);
-       struct usb_device *udev = dvobjpriv->pusbdev;
-       int status;
-       u8 io_buf[VENDOR_CMD_MAX_DATA_LEN];
-
-       if (adapt->bSurpriseRemoved)
-               return -EPERM;
-
-       memcpy(io_buf, data, size);
-       status = usb_control_msg_send(udev, 0, REALTEK_USB_VENQT_CMD_REQ,
-                                     REALTEK_USB_VENQT_WRITE, value,
-                                     REALTEK_USB_VENQT_CMD_IDX, io_buf,
-                                     size, RTW_USB_CONTROL_MSG_TIMEOUT,
-                                     GFP_KERNEL);
-
-       if (status == -ESHUTDOWN ||
-           status == -ENODEV ||
-           status == -ENOENT) {
-               /*
-                * device or controller has been disabled due to
-                * some problem that could not be worked around,
-                * device or bus doesn’t exist, endpoint does not
-                * exist or is not enabled.
-                */
-               adapt->bSurpriseRemoved = true;
-               return status;
-       }
-
-       if (status < 0) {
-               if (rtw_inc_and_chk_continual_urb_error(dvobjpriv))
-                       adapt->bSurpriseRemoved = true;
-
-               return status;
-       }
-
-       rtw_reset_continual_urb_error(dvobjpriv);
-
-       return status;
-}
-
-int __must_check rtw_read8(struct adapter *adapter, u32 addr, u8 *data)
-{
-       u16 value = addr & 0xffff;
-
-       return usb_read(adapter, value, data, 1);
-}
-
-int __must_check rtw_read16(struct adapter *adapter, u32 addr, u16 *data)
-{
-       u16 value = addr & 0xffff;
-       __le16 le_data;
-       int res;
-
-       res = usb_read(adapter, value, &le_data, 2);
-       if (res)
-               return res;
-
-       *data = le16_to_cpu(le_data);
-
-       return 0;
-}
-
-int __must_check rtw_read32(struct adapter *adapter, u32 addr, u32 *data)
-{
-       u16 value = addr & 0xffff;
-       __le32 le_data;
-       int res;
-
-       res = usb_read(adapter, value, &le_data, 4);
-       if (res)
-               return res;
-
-       *data = le32_to_cpu(le_data);
-
-       return 0;
-}
-
-int rtw_write8(struct adapter *adapter, u32 addr, u8 val)
-{
-       u16 value = addr & 0xffff;
-       int ret;
-
-       ret = usb_write(adapter, value, &val, 1);
-
-       return RTW_STATUS_CODE(ret);
-}
-
-int rtw_write16(struct adapter *adapter, u32 addr, u16 val)
-{
-       u16 value = addr & 0xffff;
-       __le16 data = cpu_to_le16(val);
-       int ret;
-
-       ret = usb_write(adapter, value, &data, 2);
-
-       return RTW_STATUS_CODE(ret);
-}
-
-int rtw_write32(struct adapter *adapter, u32 addr, u32 val)
-{
-       u16 value = addr & 0xffff;
-       __le32 data = cpu_to_le32(val);
-       int ret;
-
-       ret = usb_write(adapter, value, &data, 4);
-
-       return RTW_STATUS_CODE(ret);
-}
-
-int rtw_writeN(struct adapter *adapter, u32 addr, u32 length, u8 *data)
-{
-       u16 value = addr & 0xffff;
-
-       if (length > VENDOR_CMD_MAX_DATA_LEN)
-               return -EINVAL;
-
-       return usb_write(adapter, value, data, length);
-}
-
-static void handle_txrpt_ccx_88e(struct adapter *adapter, u8 *buf)
-{
-       struct txrpt_ccx_88e *txrpt_ccx = (struct txrpt_ccx_88e *)buf;
-
-       if (txrpt_ccx->int_ccx) {
-               if (txrpt_ccx->pkt_ok)
-                       rtw_ack_tx_done(&adapter->xmitpriv,
-                                       RTW_SCTX_DONE_SUCCESS);
-               else
-                       rtw_ack_tx_done(&adapter->xmitpriv,
-                                       RTW_SCTX_DONE_CCX_PKT_FAIL);
-       }
-}
-
-static int recvbuf2recvframe(struct adapter *adapt, struct sk_buff *pskb)
-{
-       u8      *pbuf;
-       u8      shift_sz = 0;
-       u16     pkt_cnt;
-       u32     pkt_offset, skb_len, alloc_sz;
-       s32     transfer_len;
-       struct recv_stat        *prxstat;
-       struct phy_stat *pphy_status = NULL;
-       struct sk_buff *pkt_copy = NULL;
-       struct recv_frame       *precvframe = NULL;
-       struct rx_pkt_attrib    *pattrib = NULL;
-       struct hal_data_8188e *haldata = &adapt->haldata;
-       struct recv_priv        *precvpriv = &adapt->recvpriv;
-       struct __queue *pfree_recv_queue = &precvpriv->free_recv_queue;
-
-       transfer_len = (s32)pskb->len;
-       pbuf = pskb->data;
-
-       prxstat = (struct recv_stat *)pbuf;
-       pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff;
-
-       do {
-               prxstat = (struct recv_stat *)pbuf;
-
-               precvframe = rtw_alloc_recvframe(pfree_recv_queue);
-               if (!precvframe)
-                       goto _exit_recvbuf2recvframe;
-
-               INIT_LIST_HEAD(&precvframe->list);
-               precvframe->precvbuf = NULL;    /* can't access the precvbuf for new arch. */
-               precvframe->len = 0;
-
-               update_recvframe_attrib_88e(precvframe, prxstat);
-
-               pattrib = &precvframe->attrib;
-
-               if ((pattrib->crc_err) || (pattrib->icv_err)) {
-                       rtw_free_recvframe(precvframe, pfree_recv_queue);
-                       goto _exit_recvbuf2recvframe;
-               }
-
-               if ((pattrib->physt) && (pattrib->pkt_rpt_type == NORMAL_RX))
-                       pphy_status = (struct phy_stat *)(pbuf + RXDESC_OFFSET);
-
-               pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->shift_sz + pattrib->pkt_len;
-
-               if ((pattrib->pkt_len <= 0) || (pkt_offset > transfer_len)) {
-                       rtw_free_recvframe(precvframe, pfree_recv_queue);
-                       goto _exit_recvbuf2recvframe;
-               }
-
-               /*      Modified by Albert 20101213 */
-               /*      For 8 bytes IP header alignment. */
-               if (pattrib->qos)       /*      Qos data, wireless lan header length is 26 */
-                       shift_sz = 6;
-               else
-                       shift_sz = 0;
-
-               skb_len = pattrib->pkt_len;
-
-               /*  for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet. */
-               /*  modify alloc_sz for recvive crc error packet by thomas 2011-06-02 */
-               if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) {
-                       if (skb_len <= 1650)
-                               alloc_sz = 1664;
-                       else
-                               alloc_sz = skb_len + 14;
-               } else {
-                       alloc_sz = skb_len;
-                       /*      6 is for IP header 8 bytes alignment in QoS packet case. */
-                       /*      8 is for skb->data 4 bytes alignment. */
-                       alloc_sz += 14;
-               }
-
-               pkt_copy = netdev_alloc_skb(adapt->pnetdev, alloc_sz);
-               if (pkt_copy) {
-                       precvframe->pkt = pkt_copy;
-                       precvframe->rx_head = pkt_copy->data;
-                       precvframe->rx_end = pkt_copy->data + alloc_sz;
-                       skb_reserve(pkt_copy, 8 - ((size_t)(pkt_copy->data) & 7));/* force pkt_copy->data at 8-byte alignment address */
-                       skb_reserve(pkt_copy, shift_sz);/* force ip_hdr at 8-byte alignment address according to shift_sz. */
-                       memcpy(pkt_copy->data, (pbuf + pattrib->drvinfo_sz + RXDESC_SIZE), skb_len);
-                       precvframe->rx_tail = pkt_copy->data;
-                       precvframe->rx_data = pkt_copy->data;
-               } else {
-                       if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) {
-                               rtw_free_recvframe(precvframe, pfree_recv_queue);
-                               goto _exit_recvbuf2recvframe;
-                       }
-                       precvframe->pkt = skb_clone(pskb, GFP_ATOMIC);
-                       if (precvframe->pkt) {
-                               precvframe->rx_tail = pbuf + pattrib->drvinfo_sz + RXDESC_SIZE;
-                               precvframe->rx_head = precvframe->rx_tail;
-                               precvframe->rx_data = precvframe->rx_tail;
-                               precvframe->rx_end =  pbuf + pattrib->drvinfo_sz + RXDESC_SIZE + alloc_sz;
-                       } else {
-                               rtw_free_recvframe(precvframe, pfree_recv_queue);
-                               goto _exit_recvbuf2recvframe;
-                       }
-               }
-
-               recvframe_put(precvframe, skb_len);
-
-               pkt_offset = (u16)round_up(pkt_offset, 128);
-
-               if (pattrib->pkt_rpt_type == NORMAL_RX) { /* Normal rx packet */
-                       if (pattrib->physt)
-                               update_recvframe_phyinfo_88e(precvframe, (struct phy_stat *)pphy_status);
-                       rtw_recv_entry(precvframe);
-               } else {
-                       /* enqueue recvframe to txrtp queue */
-                       if (pattrib->pkt_rpt_type == TX_REPORT1) {
-                               /* CCX-TXRPT ack for xmit mgmt frames. */
-                               handle_txrpt_ccx_88e(adapt, precvframe->rx_data);
-                       } else if (pattrib->pkt_rpt_type == TX_REPORT2) {
-                               ODM_RA_TxRPT2Handle_8188E(
-                                                       &haldata->odmpriv,
-                                                       precvframe->rx_data,
-                                                       pattrib->pkt_len,
-                                                       pattrib->MacIDValidEntry[0],
-                                                       pattrib->MacIDValidEntry[1]
-                                                       );
-                       }
-                       rtw_free_recvframe(precvframe, pfree_recv_queue);
-               }
-               pkt_cnt--;
-               transfer_len -= pkt_offset;
-               pbuf += pkt_offset;
-               precvframe = NULL;
-               pkt_copy = NULL;
-
-               if (transfer_len > 0 && pkt_cnt == 0)
-                       pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff;
-
-       } while ((transfer_len > 0) && (pkt_cnt > 0));
-
-_exit_recvbuf2recvframe:
-
-       return _SUCCESS;
-}
-
-void rtl8188eu_recv_tasklet(unsigned long priv)
-{
-       struct sk_buff *pskb;
-       struct adapter *adapt = (struct adapter *)priv;
-       struct recv_priv *precvpriv = &adapt->recvpriv;
-
-       while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) {
-               if ((adapt->bDriverStopped) || (adapt->bSurpriseRemoved)) {
-                       dev_kfree_skb_any(pskb);
-                       break;
-               }
-               recvbuf2recvframe(adapt, pskb);
-               skb_reset_tail_pointer(pskb);
-               pskb->len = 0;
-               skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
-       }
-}
-
-static void usb_read_port_complete(struct urb *purb)
-{
-       struct recv_buf *precvbuf = (struct recv_buf *)purb->context;
-       struct adapter  *adapt = (struct adapter *)precvbuf->adapter;
-       struct recv_priv *precvpriv = &adapt->recvpriv;
-
-       precvpriv->rx_pending_cnt--;
-
-       if (adapt->bSurpriseRemoved || adapt->bDriverStopped || adapt->bReadPortCancel) {
-               precvbuf->reuse = true;
-               return;
-       }
-
-       if (purb->status == 0) { /* SUCCESS */
-               if ((purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)) {
-                       precvbuf->reuse = true;
-                       rtw_read_port(adapt, precvbuf);
-               } else {
-                       rtw_reset_continual_urb_error(adapter_to_dvobj(adapt));
-
-                       skb_put(precvbuf->pskb, purb->actual_length);
-                       skb_queue_tail(&precvpriv->rx_skb_queue, precvbuf->pskb);
-
-                       if (skb_queue_len(&precvpriv->rx_skb_queue) <= 1)
-                               tasklet_schedule(&precvpriv->recv_tasklet);
-
-                       precvbuf->pskb = NULL;
-                       precvbuf->reuse = false;
-                       rtw_read_port(adapt, precvbuf);
-               }
-       } else {
-               skb_put(precvbuf->pskb, purb->actual_length);
-               precvbuf->pskb = NULL;
-
-               if (rtw_inc_and_chk_continual_urb_error(adapter_to_dvobj(adapt)))
-                       adapt->bSurpriseRemoved = true;
-
-               switch (purb->status) {
-               case -EINVAL:
-               case -EPIPE:
-               case -ENODEV:
-               case -ESHUTDOWN:
-               case -ENOENT:
-                       adapt->bDriverStopped = true;
-                       break;
-               case -EPROTO:
-               case -EOVERFLOW:
-                       precvbuf->reuse = true;
-                       rtw_read_port(adapt, precvbuf);
-                       break;
-               case -EINPROGRESS:
-                       break;
-               default:
-                       break;
-               }
-       }
-}
-
-int rtw_read_port(struct adapter *adapter, struct recv_buf *precvbuf)
-{
-       struct urb *purb = NULL;
-       struct dvobj_priv       *pdvobj = adapter_to_dvobj(adapter);
-       struct recv_priv        *precvpriv = &adapter->recvpriv;
-       struct usb_device       *pusbd = pdvobj->pusbdev;
-       int err;
-       unsigned int pipe;
-       size_t tmpaddr = 0;
-       size_t alignment = 0;
-
-       if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
-               return -EPERM;
-
-       if (!precvbuf)
-               return -ENOMEM;
-
-       if (!precvbuf->reuse || !precvbuf->pskb) {
-               precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue);
-               if (precvbuf->pskb)
-                       precvbuf->reuse = true;
-       }
-
-       /* re-assign for linux based on skb */
-       if (!precvbuf->reuse || !precvbuf->pskb) {
-               precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
-               if (!precvbuf->pskb)
-                       return -ENOMEM;
-
-               tmpaddr = (size_t)precvbuf->pskb->data;
-               alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1);
-               skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
-       } else { /* reuse skb */
-               precvbuf->reuse = false;
-       }
-
-       precvpriv->rx_pending_cnt++;
-
-       purb = precvbuf->purb;
-
-       /* translate DMA FIFO addr to pipehandle */
-       pipe = usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe);
-
-       usb_fill_bulk_urb(purb, pusbd, pipe,
-                         precvbuf->pskb->data,
-                         MAX_RECVBUF_SZ,
-                         usb_read_port_complete,
-                         precvbuf);/* context is precvbuf */
-
-       err = usb_submit_urb(purb, GFP_ATOMIC);
-       if ((err) && (err != (-EPERM)))
-               return err;
-
-       return 0;
-}
-
-void rtl8188eu_xmit_tasklet(unsigned long priv)
-{
-       struct adapter *adapt = (struct adapter *)priv;
-
-       if (check_fwstate(&adapt->mlmepriv, _FW_UNDER_SURVEY))
-               return;
-
-       do {
-               if (adapt->bDriverStopped || adapt->bSurpriseRemoved || adapt->bWritePortCancel)
-                       break;
-       } while (rtl8188eu_xmitframe_complete(adapt));
-}
diff --git a/drivers/staging/r8188eu/include/Hal8188EPhyCfg.h b/drivers/staging/r8188eu/include/Hal8188EPhyCfg.h
deleted file mode 100644 (file)
index 4a0b782..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __INC_HAL8188EPHYCFG_H__
-#define __INC_HAL8188EPHYCFG_H__
-
-#define MAX_AGGR_NUM                   0x07
-
-enum rf_radio_path {
-       RF_PATH_A = 0,                  /* Radio Path A */
-       RF_PATH_B = 1,                  /* Radio Path B */
-};
-
-#define MAX_PG_GROUP 13
-
-#define        RF_PATH_MAX                     3
-#define                MAX_TX_COUNT            4 /* path numbers */
-
-#define CHANNEL_MAX_NUMBER             14      /*  14 is the max chnl number */
-#define MAX_CHNL_GROUP_24G             6       /*  ch1~2, ch3~5, ch6~8,
-                                                *ch9~11, ch12~13, CH 14
-                                                * total three groups */
-
-struct bb_reg_def {
-       u32 rfintfs;            /*  set software control: */
-                               /*      0x870~0x877[8 bytes] */
-       u32 rfintfi;            /*  readback data: */
-                               /*      0x8e0~0x8e7[8 bytes] */
-       u32 rfintfo;            /*  output data: */
-                               /*      0x860~0x86f [16 bytes] */
-       u32 rfintfe;            /*  output enable: */
-                               /*      0x860~0x86f [16 bytes] */
-       u32 rf3wireOffset;      /*  LSSI data: */
-                               /*      0x840~0x84f [16 bytes] */
-       u32 rfLSSI_Select;      /*  BB Band Select: */
-                               /*      0x878~0x87f [8 bytes] */
-       u32 rfTxGainStage;      /*  Tx gain stage: */
-                               /*      0x80c~0x80f [4 bytes] */
-       u32 rfHSSIPara1;        /*  wire parameter control1 : */
-                               /*      0x820~0x823,0x828~0x82b,
-                                *      0x830~0x833, 0x838~0x83b [16 bytes] */
-       u32 rfHSSIPara2;        /*  wire parameter control2 : */
-                               /*      0x824~0x827,0x82c~0x82f, 0x834~0x837,
-                                *      0x83c~0x83f [16 bytes] */
-       u32 rfSwitchControl;    /* Tx Rx antenna control : */
-                               /*      0x858~0x85f [16 bytes] */
-       u32 rfAGCControl1;      /* AGC parameter control1 : */
-                               /*      0xc50~0xc53,0xc58~0xc5b, 0xc60~0xc63,
-                                * 0xc68~0xc6b [16 bytes] */
-       u32 rfAGCControl2;      /* AGC parameter control2 : */
-                               /*      0xc54~0xc57,0xc5c~0xc5f, 0xc64~0xc67,
-                                *      0xc6c~0xc6f [16 bytes] */
-       u32 rfRxIQImbalance;    /* OFDM Rx IQ imbalance matrix : */
-                               /*      0xc14~0xc17,0xc1c~0xc1f, 0xc24~0xc27,
-                                *      0xc2c~0xc2f [16 bytes] */
-       u32 rfRxAFE;            /* Rx IQ DC ofset and Rx digital filter,
-                                * Rx DC notch filter : */
-                               /*      0xc10~0xc13,0xc18~0xc1b, 0xc20~0xc23,
-                                *      0xc28~0xc2b [16 bytes] */
-       u32 rfTxIQImbalance;    /* OFDM Tx IQ imbalance matrix */
-                               /*      0xc80~0xc83,0xc88~0xc8b, 0xc90~0xc93,
-                                *       0xc98~0xc9b [16 bytes] */
-       u32 rfTxAFE;            /* Tx IQ DC Offset and Tx DFIR type */
-                               /*      0xc84~0xc87,0xc8c~0xc8f, 0xc94~0xc97,
-                                *      0xc9c~0xc9f [16 bytes] */
-       u32 rfLSSIReadBack;     /* LSSI RF readback data SI mode */
-                               /*      0x8a0~0x8af [16 bytes] */
-       u32 rfLSSIReadBackPi;   /* LSSI RF readback data PI mode 0x8b8-8bc for
-                                * Path A and B */
-};
-
-/*  BB and RF register read/write */
-u32 rtl8188e_PHY_QueryBBReg(struct adapter *adapter, u32 regaddr, u32 mask);
-void rtl8188e_PHY_SetBBReg(struct adapter *Adapter, u32 RegAddr,
-                          u32 mask, u32 data);
-u32 rtl8188e_PHY_QueryRFReg(struct adapter *adapter, u32 regaddr, u32 mask);
-void rtl8188e_PHY_SetRFReg(struct adapter *adapter, u32 regaddr, u32 mask, u32 data);
-
-/*  Initialization related function */
-/* MAC/BB/RF HAL config */
-int PHY_MACConfig8188E(struct adapter *adapter);
-int PHY_BBConfig8188E(struct adapter *adapter);
-
-/*  BB TX Power R/W */
-void PHY_SetTxPowerLevel8188E(struct adapter *adapter, u8 channel);
-
-/*  Switch bandwidth for 8192S */
-void PHY_SetBWMode8188E(struct adapter *adapter,
-                       enum ht_channel_width chnlwidth, unsigned char offset);
-
-/*  channel switch related funciton */
-void PHY_SwChnl8188E(struct adapter *adapter, u8 channel);
-
-void storePwrIndexDiffRateOffset(struct adapter *adapter, u32 regaddr,
-                                u32 mask, u32 data);
-
-#endif
diff --git a/drivers/staging/r8188eu/include/Hal8188EPhyReg.h b/drivers/staging/r8188eu/include/Hal8188EPhyReg.h
deleted file mode 100644 (file)
index da2329b..0000000
+++ /dev/null
@@ -1,1072 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __INC_HAL8188EPHYREG_H__
-#define __INC_HAL8188EPHYREG_H__
-/*--------------------------Define Parameters-------------------------------*/
-/*  */
-/*  BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF */
-/*  1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF */
-/*  2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 */
-/*  3. RF register 0x00-2E */
-/*  4. Bit Mask for BB/RF register */
-/*  5. Other definition for BB/RF R/W */
-/*  */
-
-/*  */
-/*  1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF */
-/*  1. Page1(0x100) */
-/*  */
-#define        rPMAC_Reset             0x100
-#define        rPMAC_TxStart           0x104
-#define        rPMAC_TxLegacySIG       0x108
-#define        rPMAC_TxHTSIG1          0x10c
-#define        rPMAC_TxHTSIG2          0x110
-#define        rPMAC_PHYDebug          0x114
-#define        rPMAC_TxPacketNum       0x118
-#define        rPMAC_TxIdle            0x11c
-#define        rPMAC_TxMACHeader0      0x120
-#define        rPMAC_TxMACHeader1      0x124
-#define        rPMAC_TxMACHeader2      0x128
-#define        rPMAC_TxMACHeader3      0x12c
-#define        rPMAC_TxMACHeader4      0x130
-#define        rPMAC_TxMACHeader5      0x134
-#define        rPMAC_TxDataType        0x138
-#define        rPMAC_TxRandomSeed      0x13c
-#define        rPMAC_CCKPLCPPreamble   0x140
-#define        rPMAC_CCKPLCPHeader     0x144
-#define        rPMAC_CCKCRC16          0x148
-#define        rPMAC_OFDMRxCRC32OK     0x170
-#define        rPMAC_OFDMRxCRC32Er     0x174
-#define        rPMAC_OFDMRxParityEr    0x178
-#define        rPMAC_OFDMRxCRC8Er      0x17c
-#define        rPMAC_CCKCRxRC16Er      0x180
-#define        rPMAC_CCKCRxRC32Er      0x184
-#define        rPMAC_CCKCRxRC32OK      0x188
-#define        rPMAC_TxStatus          0x18c
-
-/*  2. Page2(0x200) */
-/*  The following two definition are only used for USB interface. */
-#define        RF_BB_CMD_ADDR          0x02c0  /*  RF/BB r/w cmd address. */
-#define        RF_BB_CMD_DATA          0x02c4  /*  RF/BB r/w cmd data. */
-
-/*  3. Page8(0x800) */
-#define        rFPGA0_RFMOD            0x800   /* RF mode & CCK TxSC RF BW Setting */
-
-#define        rFPGA0_TxInfo           0x804   /*  Status report?? */
-#define        rFPGA0_PSDFunction      0x808
-
-#define        rFPGA0_TxGainStage      0x80c   /*  Set TX PWR init gain? */
-
-#define        rFPGA0_RFTiming1        0x810   /*  Useless now */
-#define        rFPGA0_RFTiming2        0x814
-
-#define        rFPGA0_XA_HSSIParameter1        0x820   /*  RF 3 wire register */
-#define        rFPGA0_XA_HSSIParameter2        0x824
-#define        rFPGA0_XB_HSSIParameter1        0x828
-#define        rFPGA0_XB_HSSIParameter2        0x82c
-
-#define        rFPGA0_XA_LSSIParameter         0x840
-#define        rFPGA0_XB_LSSIParameter         0x844
-
-#define        rFPGA0_RFWakeUpParameter        0x850   /*  Useless now */
-#define        rFPGA0_RFSleepUpParameter       0x854
-
-#define        rFPGA0_XAB_SwitchControl        0x858   /*  RF Channel switch */
-#define        rFPGA0_XCD_SwitchControl        0x85c
-
-#define        rFPGA0_XA_RFInterfaceOE         0x860   /*  RF Channel switch */
-#define        rFPGA0_XB_RFInterfaceOE         0x864
-
-#define        rFPGA0_XAB_RFInterfaceSW        0x870   /*  RF Iface Software Control */
-#define        rFPGA0_XCD_RFInterfaceSW        0x874
-
-#define        rFPGA0_XAB_RFParameter          0x878   /*  RF Parameter */
-#define        rFPGA0_XCD_RFParameter          0x87c
-
-/* Crystal cap setting RF-R/W protection for parameter4?? */
-#define        rFPGA0_AnalogParameter1         0x880
-#define        rFPGA0_AnalogParameter2         0x884
-#define        rFPGA0_AnalogParameter3         0x888
-/*  enable ad/da clock1 for dual-phy */
-#define        rFPGA0_AdDaClockEn              0x888
-#define        rFPGA0_AnalogParameter4         0x88c
-
-#define        rFPGA0_XA_LSSIReadBack          0x8a0   /*  Transceiver LSSI Readback */
-#define        rFPGA0_XB_LSSIReadBack          0x8a4
-#define        rFPGA0_XC_LSSIReadBack          0x8a8
-#define        rFPGA0_XD_LSSIReadBack          0x8ac
-
-#define        rFPGA0_PSDReport                0x8b4   /*  Useless now */
-/*  Transceiver A HSPI Readback */
-#define        TransceiverA_HSPI_Readback      0x8b8
-/*  Transceiver B HSPI Readback */
-#define        TransceiverB_HSPI_Readback      0x8bc
-/*  Useless now RF Interface Readback Value */
-#define        rFPGA0_XAB_RFInterfaceRB        0x8e0
-#define        rFPGA0_XCD_RFInterfaceRB        0x8e4   /*  Useless now */
-
-/*  4. Page9(0x900) */
-/* RF mode & OFDM TxSC RF BW Setting?? */
-#define        rFPGA1_RFMOD                    0x900
-
-#define        rFPGA1_TxBlock                  0x904   /*  Useless now */
-#define        rFPGA1_DebugSelect              0x908   /*  Useless now */
-#define        rFPGA1_TxInfo                   0x90c   /*  Useless now Status report */
-
-/*  5. PageA(0xA00) */
-/*  Set Control channel to upper or lower - required only for 40MHz */
-#define        rCCK0_System                    0xa00
-
-/*  Disable init gain now Select RX path by RSSI */
-#define        rCCK0_AFESetting                0xa04
-/*  Disable init gain now Init gain */
-#define        rCCK0_CCA                       0xa08
-
-/* AGC default value, saturation level Antenna Diversity, RX AGC, LNA Threshold,
- * RX LNA Threshold useless now. Not the same as 90 series */
-#define        rCCK0_RxAGC1                    0xa0c
-#define        rCCK0_RxAGC2                    0xa10   /* AGC & DAGC */
-
-#define        rCCK0_RxHP                      0xa14
-
-/* Timing recovery & Channel estimation threshold */
-#define        rCCK0_DSPParameter1             0xa18
-#define        rCCK0_DSPParameter2             0xa1c   /* SQ threshold */
-
-#define        rCCK0_TxFilter1                 0xa20
-#define        rCCK0_TxFilter2                 0xa24
-#define        rCCK0_DebugPort                 0xa28   /* debug port and Tx filter3 */
-#define        rCCK0_FalseAlarmReport          0xa2c   /* 0xa2d useless now */
-#define        rCCK0_TRSSIReport               0xa50
-#define        rCCK0_RxReport                  0xa54  /* 0xa57 */
-#define        rCCK0_FACounterLower            0xa5c  /* 0xa5b */
-#define        rCCK0_FACounterUpper            0xa58  /* 0xa5c */
-
-/*  */
-/*  PageB(0xB00) */
-/*  */
-#define        rPdp_AntA                       0xb00
-#define        rPdp_AntA_4                     0xb04
-#define        rConfig_Pmpd_AntA               0xb28
-#define        rConfig_AntA                    0xb68
-#define        rConfig_AntB                    0xb6c
-#define        rPdp_AntB                       0xb70
-#define        rPdp_AntB_4                     0xb74
-#define        rConfig_Pmpd_AntB               0xb98
-#define        rAPK                            0xbd8
-
-/*  */
-/*  6. PageC(0xC00) */
-/*  */
-#define        rOFDM0_LSTF                     0xc00
-
-#define        rOFDM0_TRxPathEnable            0xc04
-#define        rOFDM0_TRMuxPar                 0xc08
-#define        rOFDM0_TRSWIsolation            0xc0c
-
-/* RxIQ DC offset, Rx digital filter, DC notch filter */
-#define        rOFDM0_XARxAFE                  0xc10
-#define        rOFDM0_XARxIQImbalance          0xc14  /* RxIQ imbalance matrix */
-#define        rOFDM0_XBRxAFE                  0xc18
-#define        rOFDM0_XBRxIQImbalance          0xc1c
-#define        rOFDM0_XCRxAFE                  0xc20
-#define        rOFDM0_XCRxIQImbalance          0xc24
-#define        rOFDM0_XDRxAFE                  0xc28
-#define        rOFDM0_XDRxIQImbalance          0xc2c
-
-#define        rOFDM0_RxDetector1              0xc30  /*PD,BW & SBD DM tune init gain*/
-#define        rOFDM0_RxDetector2              0xc34  /* SBD & Fame Sync. */
-#define        rOFDM0_RxDetector3              0xc38  /* Frame Sync. */
-#define        rOFDM0_RxDetector4              0xc3c  /* PD, SBD, Frame Sync & Short-GI */
-
-#define        rOFDM0_RxDSP                    0xc40  /* Rx Sync Path */
-#define        rOFDM0_CFOandDAGC               0xc44  /* CFO & DAGC */
-#define        rOFDM0_CCADropThreshold         0xc48 /* CCA Drop threshold */
-#define        rOFDM0_ECCAThreshold            0xc4c /*  energy CCA */
-
-#define        rOFDM0_XAAGCCore1               0xc50   /*  DIG */
-#define        rOFDM0_XAAGCCore2               0xc54
-#define        rOFDM0_XBAGCCore1               0xc58
-#define        rOFDM0_XBAGCCore2               0xc5c
-#define        rOFDM0_XCAGCCore1               0xc60
-#define        rOFDM0_XCAGCCore2               0xc64
-#define        rOFDM0_XDAGCCore1               0xc68
-#define        rOFDM0_XDAGCCore2               0xc6c
-
-#define        rOFDM0_AGCParameter1            0xc70
-#define        rOFDM0_AGCParameter2            0xc74
-#define        rOFDM0_AGCRSSITable             0xc78
-#define        rOFDM0_HTSTFAGC                 0xc7c
-
-#define        rOFDM0_XATxIQImbalance          0xc80   /*  TX PWR TRACK and DIG */
-#define        rOFDM0_XATxAFE                  0xc84
-#define        rOFDM0_XBTxIQImbalance          0xc88
-#define        rOFDM0_XBTxAFE                  0xc8c
-#define        rOFDM0_XCTxIQImbalance          0xc90
-#define        rOFDM0_XCTxAFE                  0xc94
-#define        rOFDM0_XDTxIQImbalance          0xc98
-#define        rOFDM0_XDTxAFE                  0xc9c
-
-#define        rOFDM0_RxIQExtAnta              0xca0
-#define        rOFDM0_TxCoeff1                 0xca4
-#define        rOFDM0_TxCoeff2                 0xca8
-#define        rOFDM0_TxCoeff3                 0xcac
-#define        rOFDM0_TxCoeff4                 0xcb0
-#define        rOFDM0_TxCoeff5                 0xcb4
-#define        rOFDM0_TxCoeff6                 0xcb8
-#define        rOFDM0_RxHPParameter            0xce0
-#define        rOFDM0_TxPseudoNoiseWgt         0xce4
-#define        rOFDM0_FrameSync                0xcf0
-#define        rOFDM0_DFSReport                0xcf4
-
-/*  */
-/*  7. PageD(0xD00) */
-/*  */
-#define        rOFDM1_LSTF                     0xd00
-#define        rOFDM1_TRxPathEnable            0xd04
-
-#define        rOFDM1_CFO                      0xd08   /*  No setting now */
-#define        rOFDM1_CSI1                     0xd10
-#define        rOFDM1_SBD                      0xd14
-#define        rOFDM1_CSI2                     0xd18
-#define        rOFDM1_CFOTracking              0xd2c
-#define        rOFDM1_TRxMesaure1              0xd34
-#define        rOFDM1_IntfDet                  0xd3c
-#define        rOFDM1_PseudoNoiseStateAB       0xd50
-#define        rOFDM1_PseudoNoiseStateCD       0xd54
-#define        rOFDM1_RxPseudoNoiseWgt         0xd58
-
-#define        rOFDM_PHYCounter1               0xda0  /* cca, parity fail */
-#define        rOFDM_PHYCounter2               0xda4  /* rate illegal, crc8 fail */
-#define        rOFDM_PHYCounter3               0xda8  /* MCS not support */
-
-#define        rOFDM_ShortCFOAB                0xdac   /*  No setting now */
-#define        rOFDM_ShortCFOCD                0xdb0
-#define        rOFDM_LongCFOAB                 0xdb4
-#define        rOFDM_LongCFOCD                 0xdb8
-#define        rOFDM_TailCFOAB                 0xdbc
-#define        rOFDM_TailCFOCD                 0xdc0
-#define        rOFDM_PWMeasure1                0xdc4
-#define        rOFDM_PWMeasure2                0xdc8
-#define        rOFDM_BWReport                  0xdcc
-#define        rOFDM_AGCReport                 0xdd0
-#define        rOFDM_RxSNR                     0xdd4
-#define        rOFDM_RxEVMCSI                  0xdd8
-#define        rOFDM_SIGReport                 0xddc
-
-/*  */
-/*  8. PageE(0xE00) */
-/*  */
-#define        rTxAGC_A_Rate18_06              0xe00
-#define        rTxAGC_A_Rate54_24              0xe04
-#define        rTxAGC_A_CCK1_Mcs32             0xe08
-#define        rTxAGC_A_Mcs03_Mcs00            0xe10
-#define        rTxAGC_A_Mcs07_Mcs04            0xe14
-#define        rTxAGC_A_Mcs11_Mcs08            0xe18
-#define        rTxAGC_A_Mcs15_Mcs12            0xe1c
-
-#define        rTxAGC_B_Rate18_06              0x830
-#define        rTxAGC_B_Rate54_24              0x834
-#define        rTxAGC_B_CCK1_55_Mcs32          0x838
-#define        rTxAGC_B_Mcs03_Mcs00            0x83c
-#define        rTxAGC_B_Mcs07_Mcs04            0x848
-#define        rTxAGC_B_Mcs11_Mcs08            0x84c
-#define        rTxAGC_B_Mcs15_Mcs12            0x868
-#define        rTxAGC_B_CCK11_A_CCK2_11        0x86c
-
-#define        rFPGA0_IQK                      0xe28
-#define        rTx_IQK_Tone_A                  0xe30
-#define        rRx_IQK_Tone_A                  0xe34
-#define        rTx_IQK_PI_A                    0xe38
-#define        rRx_IQK_PI_A                    0xe3c
-
-#define        rTx_IQK                         0xe40
-#define        rRx_IQK                         0xe44
-#define        rIQK_AGC_Pts                    0xe48
-#define        rIQK_AGC_Rsp                    0xe4c
-#define        rTx_IQK_Tone_B                  0xe50
-#define        rRx_IQK_Tone_B                  0xe54
-#define        rTx_IQK_PI_B                    0xe58
-#define        rRx_IQK_PI_B                    0xe5c
-#define        rIQK_AGC_Cont                   0xe60
-
-#define        rBlue_Tooth                     0xe6c
-#define        rRx_Wait_CCA                    0xe70
-#define        rTx_CCK_RFON                    0xe74
-#define        rTx_CCK_BBON                    0xe78
-#define        rTx_OFDM_RFON                   0xe7c
-#define        rTx_OFDM_BBON                   0xe80
-#define        rTx_To_Rx                       0xe84
-#define        rTx_To_Tx                       0xe88
-#define        rRx_CCK                         0xe8c
-
-#define        rTx_Power_Before_IQK_A          0xe94
-#define        rTx_Power_After_IQK_A           0xe9c
-
-#define        rRx_Power_Before_IQK_A          0xea0
-#define        rRx_Power_Before_IQK_A_2        0xea4
-#define        rRx_Power_After_IQK_A           0xea8
-#define        rRx_Power_After_IQK_A_2         0xeac
-
-#define        rTx_Power_Before_IQK_B          0xeb4
-#define        rTx_Power_After_IQK_B           0xebc
-
-#define        rRx_Power_Before_IQK_B          0xec0
-#define        rRx_Power_Before_IQK_B_2        0xec4
-#define        rRx_Power_After_IQK_B           0xec8
-#define        rRx_Power_After_IQK_B_2         0xecc
-
-#define        rRx_OFDM                        0xed0
-#define        rRx_Wait_RIFS                   0xed4
-#define        rRx_TO_Rx                       0xed8
-#define        rStandby                        0xedc
-#define        rSleep                          0xee0
-#define        rPMPD_ANAEN                     0xeec
-
-/*  */
-/*  7. RF Register 0x00-0x2E (RF 8256) */
-/*     RF-0222D 0x00-3F */
-/*  */
-/* Zebra1 */
-#define        rZebra1_HSSIEnable              0x0     /*  Useless now */
-#define        rZebra1_TRxEnable1              0x1
-#define        rZebra1_TRxEnable2              0x2
-#define        rZebra1_AGC                     0x4
-#define        rZebra1_ChargePump              0x5
-#define        rZebra1_Channel                 0x7     /*  RF channel switch */
-
-/* endif */
-#define        rZebra1_TxGain                  0x8     /*  Useless now */
-#define        rZebra1_TxLPF                   0x9
-#define        rZebra1_RxLPF                   0xb
-#define        rZebra1_RxHPFCorner             0xc
-
-/* Zebra4 */
-#define        rGlobalCtrl             0       /*  Useless now */
-#define        rRTL8256_TxLPF          19
-#define        rRTL8256_RxLPF          11
-
-/* RTL8258 */
-#define        rRTL8258_TxLPF          0x11    /*  Useless now */
-#define        rRTL8258_RxLPF          0x13
-#define        rRTL8258_RSSILPF        0xa
-
-/*  */
-/*  RL6052 Register definition */
-/*  */
-#define        RF_AC                   0x00    /*  */
-
-#define        RF_IQADJ_G1             0x01    /*  */
-#define        RF_IQADJ_G2             0x02    /*  */
-
-#define        RF_POW_TRSW             0x05    /*  */
-
-#define        RF_GAIN_RX              0x06    /*  */
-#define        RF_GAIN_TX              0x07    /*  */
-
-#define        RF_TXM_IDAC             0x08    /*  */
-#define        RF_IPA_G                0x09    /*  */
-#define        RF_TXBIAS_G             0x0A
-#define        RF_TXPA_AG              0x0B
-#define        RF_IPA_A                0x0C    /*  */
-#define        RF_TXBIAS_A             0x0D
-#define        RF_BS_PA_APSET_G9_G11   0x0E
-#define        RF_BS_IQGEN             0x0F    /*  */
-
-#define        RF_MODE1                0x10    /*  */
-#define        RF_MODE2                0x11    /*  */
-
-#define        RF_RX_AGC_HP            0x12    /*  */
-#define        RF_TX_AGC               0x13    /*  */
-#define        RF_BIAS                 0x14    /*  */
-#define        RF_IPA                  0x15    /*  */
-#define        RF_TXBIAS               0x16
-#define        RF_POW_ABILITY          0x17    /*  */
-#define        RF_CHNLBW               0x18    /*  RF channel and BW switch */
-#define        RF_TOP                  0x19    /*  */
-
-#define        RF_RX_G1                0x1A    /*  */
-#define        RF_RX_G2                0x1B    /*  */
-
-#define        RF_RX_BB2               0x1C    /*  */
-#define        RF_RX_BB1               0x1D    /*  */
-
-#define        RF_RCK1                 0x1E    /*  */
-#define        RF_RCK2                 0x1F    /*  */
-
-#define        RF_TX_G1                0x20    /*  */
-#define        RF_TX_G2                0x21    /*  */
-#define        RF_TX_G3                0x22    /*  */
-
-#define        RF_TX_BB1               0x23    /*  */
-
-#define        RF_T_METER_92D          0x42    /*  */
-#define        RF_T_METER_88E          0x42    /*  */
-#define        RF_T_METER              0x24    /*  */
-
-#define        RF_SYN_G1               0x25    /*  RF TX Power control */
-#define        RF_SYN_G2               0x26    /*  RF TX Power control */
-#define        RF_SYN_G3               0x27    /*  RF TX Power control */
-#define        RF_SYN_G4               0x28    /*  RF TX Power control */
-#define        RF_SYN_G5               0x29    /*  RF TX Power control */
-#define        RF_SYN_G6               0x2A    /*  RF TX Power control */
-#define        RF_SYN_G7               0x2B    /*  RF TX Power control */
-#define        RF_SYN_G8               0x2C    /*  RF TX Power control */
-
-#define        RF_RCK_OS               0x30    /*  RF TX PA control */
-#define        RF_TXPA_G1              0x31    /*  RF TX PA control */
-#define        RF_TXPA_G2              0x32    /*  RF TX PA control */
-#define        RF_TXPA_G3              0x33    /*  RF TX PA control */
-#define        RF_TX_BIAS_A            0x35
-#define        RF_TX_BIAS_D            0x36
-#define        RF_LOBF_9               0x38
-#define        RF_RXRF_A3              0x3C    /*  */
-#define        RF_TRSW                 0x3F
-
-#define        RF_TXRF_A2              0x41
-#define        RF_TXPA_G4              0x46
-#define        RF_TXPA_A4              0x4B
-#define        RF_0x52                 0x52
-#define        RF_WE_LUT               0xEF
-
-/*  */
-/* Bit Mask */
-/*  */
-/*  1. Page1(0x100) */
-#define        bBBResetB               0x100   /*  Useless now? */
-#define        bGlobalResetB           0x200
-#define        bOFDMTxStart            0x4
-#define        bCCKTxStart             0x8
-#define        bCRC32Debug             0x100
-#define        bPMACLoopback           0x10
-#define        bTxLSIG                 0xffffff
-#define        bOFDMTxRate             0xf
-#define        bOFDMTxReserved         0x10
-#define        bOFDMTxLength           0x1ffe0
-#define        bOFDMTxParity           0x20000
-#define        bTxHTSIG1               0xffffff
-#define        bTxHTMCSRate            0x7f
-#define        bTxHTBW                 0x80
-#define        bTxHTLength             0xffff00
-#define        bTxHTSIG2               0xffffff
-#define        bTxHTSmoothing          0x1
-#define        bTxHTSounding           0x2
-#define        bTxHTReserved           0x4
-#define        bTxHTAggreation         0x8
-#define        bTxHTSTBC               0x30
-#define        bTxHTAdvanceCoding      0x40
-#define        bTxHTShortGI            0x80
-#define        bTxHTNumberHT_LTF       0x300
-#define        bTxHTCRC8               0x3fc00
-#define        bCounterReset           0x10000
-#define        bNumOfOFDMTx            0xffff
-#define        bNumOfCCKTx             0xffff0000
-#define        bTxIdleInterval         0xffff
-#define        bOFDMService            0xffff0000
-#define        bTxMACHeader            0xffffffff
-#define        bTxDataInit             0xff
-#define        bTxHTMode               0x100
-#define        bTxDataType             0x30000
-#define        bTxRandomSeed           0xffffffff
-#define        bCCKTxPreamble          0x1
-#define        bCCKTxSFD               0xffff0000
-#define        bCCKTxSIG               0xff
-#define        bCCKTxService           0xff00
-#define        bCCKLengthExt           0x8000
-#define        bCCKTxLength            0xffff0000
-#define        bCCKTxCRC16             0xffff
-#define        bCCKTxStatus            0x1
-#define        bOFDMTxStatus           0x2
-
-#define        IS_BB_REG_OFFSET_92S(_Offset)                   \
-       ((_Offset >= 0x800) && (_Offset <= 0xfff))
-
-/*  2. Page8(0x800) */
-#define        bRFMOD                  0x1     /*  Reg 0x800 rFPGA0_RFMOD */
-#define        bJapanMode              0x2
-#define        bCCKTxSC                0x30
-#define        bCCKEn                  0x1000000
-#define        bOFDMEn                 0x2000000
-
-#define        bOFDMRxADCPhase         0x10000 /*  Useless now */
-#define        bOFDMTxDACPhase         0x40000
-#define        bXATxAGC                0x3f
-
-#define        bAntennaSelect          0x0300
-
-#define        bXBTxAGC                0xf00   /*  Reg 80c rFPGA0_TxGainStage */
-#define        bXCTxAGC                0xf000
-#define        bXDTxAGC                0xf0000
-
-#define        bPAStart                0xf0000000      /*  Useless now */
-#define        bTRStart                0x00f00000
-#define        bRFStart                0x0000f000
-#define        bBBStart                0x000000f0
-#define        bBBCCKStart             0x0000000f
-#define        bPAEnd                  0xf          /* Reg0x814 */
-#define        bTREnd                  0x0f000000
-#define        bRFEnd                  0x000f0000
-#define        bCCAMask                0x000000f0   /* T2R */
-#define        bR2RCCAMask             0x00000f00
-#define        bHSSI_R2TDelay          0xf8000000
-#define        bHSSI_T2RDelay          0xf80000
-#define        bContTxHSSI             0x400     /* change gain at continue Tx */
-#define        bIGFromCCK              0x200
-#define        bAGCAddress             0x3f
-#define        bRxHPTx                 0x7000
-#define        bRxHPT2R                0x38000
-#define        bRxHPCCKIni             0xc0000
-#define        bAGCTxCode              0xc00000
-#define        bAGCRxCode              0x300000
-
-/* Reg 0x820~84f rFPGA0_XA_HSSIParameter1 */
-#define        b3WireDataLength        0x800
-#define        b3WireAddressLength     0x400
-
-#define        b3WireRFPowerDown       0x1     /*  Useless now */
-#define        b5GPAPEPolarity         0x40000000
-#define        b2GPAPEPolarity         0x80000000
-#define        bRFSW_TxDefaultAnt      0x3
-#define        bRFSW_TxOptionAnt       0x30
-#define        bRFSW_RxDefaultAnt      0x300
-#define        bRFSW_RxOptionAnt       0x3000
-#define        bRFSI_3WireData         0x1
-#define        bRFSI_3WireClock        0x2
-#define        bRFSI_3WireLoad         0x4
-#define        bRFSI_3WireRW           0x8
-#define        bRFSI_3Wire             0xf
-
-#define        bRFSI_RFENV             0x10    /* Reg 0x870 rFPGA0_XAB_RFInterfaceSW */
-
-#define        bRFSI_TRSW              0x20    /*  Useless now */
-#define        bRFSI_TRSWB             0x40
-#define        bRFSI_ANTSW             0x100
-#define        bRFSI_ANTSWB            0x200
-#define        bRFSI_PAPE              0x400
-#define        bRFSI_PAPE5G            0x800
-#define        bBandSelect             0x1
-#define        bHTSIG2_GI              0x80
-#define        bHTSIG2_Smoothing       0x01
-#define        bHTSIG2_Sounding        0x02
-#define        bHTSIG2_Aggreaton       0x08
-#define        bHTSIG2_STBC            0x30
-#define        bHTSIG2_AdvCoding       0x40
-#define        bHTSIG2_NumOfHTLTF      0x300
-#define        bHTSIG2_CRC8            0x3fc
-#define        bHTSIG1_MCS             0x7f
-#define        bHTSIG1_BandWidth       0x80
-#define        bHTSIG1_HTLength        0xffff
-#define        bLSIG_Rate              0xf
-#define        bLSIG_Reserved          0x10
-#define        bLSIG_Length            0x1fffe
-#define        bLSIG_Parity            0x20
-#define        bCCKRxPhase             0x4
-
-#define        bLSSIReadAddress        0x7f800000   /*  T65 RF */
-
-#define        bLSSIReadEdge           0x80000000   /* LSSI "Read" edge signal */
-
-#define        bLSSIReadBackData       0xfffff         /*  T65 RF */
-
-#define        bLSSIReadOKFlag         0x1000  /*  Useless now */
-#define        bCCKSampleRate          0x8       /* 0: 44MHz, 1:88MHz */
-#define        bRegulator0Standby      0x1
-#define        bRegulatorPLLStandby    0x2
-#define        bRegulator1Standby      0x4
-#define        bPLLPowerUp             0x8
-#define        bDPLLPowerUp            0x10
-#define        bDA10PowerUp            0x20
-#define        bAD7PowerUp             0x200
-#define        bDA6PowerUp             0x2000
-#define        bXtalPowerUp            0x4000
-#define        b40MDClkPowerUP         0x8000
-#define        bDA6DebugMode           0x20000
-#define        bDA6Swing               0x380000
-
-/*  Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ */
-#define        bADClkPhase             0x4000000
-
-#define        b80MClkDelay            0x18000000      /*  Useless */
-#define        bAFEWatchDogEnable      0x20000000
-
-/*  Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap */
-#define        bXtalCap01              0xc0000000
-#define        bXtalCap23              0x3
-#define        bXtalCap92x             0x0f000000
-#define        bXtalCap                0x0f000000
-
-#define        bIntDifClkEnable        0x400   /*  Useless */
-#define        bExtSigClkEnable        0x800
-#define        bBandgapMbiasPowerUp    0x10000
-#define        bAD11SHGain             0xc0000
-#define        bAD11InputRange         0x700000
-#define        bAD11OPCurrent          0x3800000
-#define        bIPathLoopback          0x4000000
-#define        bQPathLoopback          0x8000000
-#define        bAFELoopback            0x10000000
-#define        bDA10Swing              0x7e0
-#define        bDA10Reverse            0x800
-#define        bDAClkSource            0x1000
-#define        bAD7InputRange          0x6000
-#define        bAD7Gain                0x38000
-#define        bAD7OutputCMMode        0x40000
-#define        bAD7InputCMMode         0x380000
-#define        bAD7Current             0xc00000
-#define        bRegulatorAdjust        0x7000000
-#define        bAD11PowerUpAtTx        0x1
-#define        bDA10PSAtTx             0x10
-#define        bAD11PowerUpAtRx        0x100
-#define        bDA10PSAtRx             0x1000
-#define        bCCKRxAGCFormat         0x200
-#define        bPSDFFTSamplepPoint     0xc000
-#define        bPSDAverageNum          0x3000
-#define        bIQPathControl          0xc00
-#define        bPSDFreq                0x3ff
-#define        bPSDAntennaPath         0x30
-#define        bPSDIQSwitch            0x40
-#define        bPSDRxTrigger           0x400000
-#define        bPSDTxTrigger           0x80000000
-#define        bPSDSineToneScale       0x7f000000
-#define        bPSDReport              0xffff
-
-/*  3. Page9(0x900) */
-#define        bOFDMTxSC               0x30000000      /*  Useless */
-#define        bCCKTxOn                0x1
-#define        bOFDMTxOn               0x2
-#define        bDebugPage              0xfff  /* reset debug page and HWord, LWord */
-#define        bDebugItem              0xff   /* reset debug page and LWord */
-#define        bAntL                   0x10
-#define        bAntNonHT               0x100
-#define        bAntHT1                 0x1000
-#define        bAntHT2                 0x10000
-#define        bAntHT1S1               0x100000
-#define        bAntNonHTS1             0x1000000
-
-/*  4. PageA(0xA00) */
-#define        bCCKBBMode              0x3     /*  Useless */
-#define        bCCKTxPowerSaving       0x80
-#define        bCCKRxPowerSaving       0x40
-
-#define        bCCKSideBand            0x10    /*  Reg 0xa00 rCCK0_System 20/40 */
-
-#define        bCCKScramble            0x8     /*  Useless */
-#define        bCCKAntDiversity        0x8000
-#define        bCCKCarrierRecovery     0x4000
-#define        bCCKTxRate              0x3000
-#define        bCCKDCCancel            0x0800
-#define        bCCKISICancel           0x0400
-#define        bCCKMatchFilter         0x0200
-#define        bCCKEqualizer           0x0100
-#define        bCCKPreambleDetect      0x800000
-#define        bCCKFastFalseCCA        0x400000
-#define        bCCKChEstStart          0x300000
-#define        bCCKCCACount            0x080000
-#define        bCCKcs_lim              0x070000
-#define        bCCKBistMode            0x80000000
-#define        bCCKCCAMask             0x40000000
-#define        bCCKTxDACPhase          0x4
-#define        bCCKRxADCPhase          0x20000000   /* r_rx_clk */
-#define        bCCKr_cp_mode0          0x0100
-#define        bCCKTxDCOffset          0xf0
-#define        bCCKRxDCOffset          0xf
-#define        bCCKCCAMode             0xc000
-#define        bCCKFalseCS_lim         0x3f00
-#define        bCCKCS_ratio            0xc00000
-#define        bCCKCorgBit_sel         0x300000
-#define        bCCKPD_lim              0x0f0000
-#define        bCCKNewCCA              0x80000000
-#define        bCCKRxHPofIG            0x8000
-#define        bCCKRxIG                0x7f00
-#define        bCCKLNAPolarity         0x800000
-#define        bCCKRx1stGain           0x7f0000
-#define        bCCKRFExtend            0x20000000 /* CCK Rx Iinital gain polarity */
-#define        bCCKRxAGCSatLevel       0x1f000000
-#define        bCCKRxAGCSatCount       0xe0
-#define        bCCKRxRFSettle          0x1f       /* AGCsamp_dly */
-#define        bCCKFixedRxAGC          0x8000
-#define        bCCKAntennaPolarity     0x2000
-#define        bCCKTxFilterType        0x0c00
-#define        bCCKRxAGCReportType     0x0300
-#define        bCCKRxDAGCEn            0x80000000
-#define        bCCKRxDAGCPeriod        0x20000000
-#define        bCCKRxDAGCSatLevel      0x1f000000
-#define        bCCKTimingRecovery      0x800000
-#define        bCCKTxC0                0x3f0000
-#define        bCCKTxC1                0x3f000000
-#define        bCCKTxC2                0x3f
-#define        bCCKTxC3                0x3f00
-#define        bCCKTxC4                0x3f0000
-#define        bCCKTxC5                0x3f000000
-#define        bCCKTxC6                0x3f
-#define        bCCKTxC7                0x3f00
-#define        bCCKDebugPort           0xff0000
-#define        bCCKDACDebug            0x0f000000
-#define        bCCKFalseAlarmEnable    0x8000
-#define        bCCKFalseAlarmRead      0x4000
-#define        bCCKTRSSI               0x7f
-#define        bCCKRxAGCReport         0xfe
-#define        bCCKRxReport_AntSel     0x80000000
-#define        bCCKRxReport_MFOff      0x40000000
-#define        bCCKRxRxReport_SQLoss   0x20000000
-#define        bCCKRxReport_Pktloss    0x10000000
-#define        bCCKRxReport_Lockedbit  0x08000000
-#define        bCCKRxReport_RateError  0x04000000
-#define        bCCKRxReport_RxRate     0x03000000
-#define        bCCKRxFACounterLower    0xff
-#define        bCCKRxFACounterUpper    0xff000000
-#define        bCCKRxHPAGCStart        0xe000
-#define        bCCKRxHPAGCFinal        0x1c00
-#define        bCCKRxFalseAlarmEnable  0x8000
-#define        bCCKFACounterFreeze     0x4000
-#define        bCCKTxPathSel           0x10000000
-#define        bCCKDefaultRxPath       0xc000000
-#define        bCCKOptionRxPath        0x3000000
-
-/*  5. PageC(0xC00) */
-#define        bNumOfSTF               0x3     /*  Useless */
-#define        bShift_L                0xc0
-#define        bGI_TH                  0xc
-#define        bRxPathA                0x1
-#define        bRxPathB                0x2
-#define        bRxPathC                0x4
-#define        bRxPathD                0x8
-#define        bTxPathA                0x1
-#define        bTxPathB                0x2
-#define        bTxPathC                0x4
-#define        bTxPathD                0x8
-#define        bTRSSIFreq              0x200
-#define        bADCBackoff             0x3000
-#define        bDFIRBackoff            0xc000
-#define        bTRSSILatchPhase        0x10000
-#define        bRxIDCOffset            0xff
-#define        bRxQDCOffset            0xff00
-#define        bRxDFIRMode             0x1800000
-#define        bRxDCNFType             0xe000000
-#define        bRXIQImb_A              0x3ff
-#define        bRXIQImb_B              0xfc00
-#define        bRXIQImb_C              0x3f0000
-#define        bRXIQImb_D              0xffc00000
-#define        bDC_dc_Notch            0x60000
-#define        bRxNBINotch             0x1f000000
-#define        bPD_TH                  0xf
-#define        bPD_TH_Opt2             0xc000
-#define        bPWED_TH                0x700
-#define        bIfMF_Win_L             0x800
-#define        bPD_Option              0x1000
-#define        bMF_Win_L               0xe000
-#define        bBW_Search_L            0x30000
-#define        bwin_enh_L              0xc0000
-#define        bBW_TH                  0x700000
-#define        bED_TH2                 0x3800000
-#define        bBW_option              0x4000000
-#define        bRatio_TH               0x18000000
-#define        bWindow_L               0xe0000000
-#define        bSBD_Option             0x1
-#define        bFrame_TH               0x1c
-#define        bFS_Option              0x60
-#define        bDC_Slope_check         0x80
-#define        bFGuard_Counter_DC_L    0xe00
-#define        bFrame_Weight_Short     0x7000
-#define        bSub_Tune               0xe00000
-#define        bFrame_DC_Length        0xe000000
-#define        bSBD_start_offset       0x30000000
-#define        bFrame_TH_2             0x7
-#define        bFrame_GI2_TH           0x38
-#define        bGI2_Sync_en            0x40
-#define        bSarch_Short_Early      0x300
-#define        bSarch_Short_Late       0xc00
-#define        bSarch_GI2_Late         0x70000
-#define        bCFOAntSum              0x1
-#define        bCFOAcc                 0x2
-#define        bCFOStartOffset         0xc
-#define        bCFOLookBack            0x70
-#define        bCFOSumWeight           0x80
-#define        bDAGCEnable             0x10000
-#define        bTXIQImb_A              0x3ff
-#define        bTXIQImb_B              0xfc00
-#define        bTXIQImb_C              0x3f0000
-#define        bTXIQImb_D              0xffc00000
-#define        bTxIDCOffset            0xff
-#define        bTxQDCOffset            0xff00
-#define        bTxDFIRMode             0x10000
-#define        bTxPesudoNoiseOn        0x4000000
-#define        bTxPesudoNoise_A        0xff
-#define        bTxPesudoNoise_B        0xff00
-#define        bTxPesudoNoise_C        0xff0000
-#define        bTxPesudoNoise_D        0xff000000
-#define        bCCADropOption          0x20000
-#define        bCCADropThres           0xfff00000
-#define        bEDCCA_H                0xf
-#define        bEDCCA_L                0xf0
-#define        bLambda_ED              0x300
-#define        bRxInitialGain          0x7f
-#define        bRxAntDivEn             0x80
-#define        bRxAGCAddressForLNA     0x7f00
-#define        bRxHighPowerFlow        0x8000
-#define        bRxAGCFreezeThres       0xc0000
-#define        bRxFreezeStep_AGC1      0x300000
-#define        bRxFreezeStep_AGC2      0xc00000
-#define        bRxFreezeStep_AGC3      0x3000000
-#define        bRxFreezeStep_AGC0      0xc000000
-#define        bRxRssi_Cmp_En          0x10000000
-#define        bRxQuickAGCEn           0x20000000
-#define        bRxAGCFreezeThresMode   0x40000000
-#define        bRxOverFlowCheckType    0x80000000
-#define        bRxAGCShift             0x7f
-#define        bTRSW_Tri_Only          0x80
-#define        bPowerThres             0x300
-#define        bRxAGCEn                0x1
-#define        bRxAGCTogetherEn        0x2
-#define        bRxAGCMin               0x4
-#define        bRxHP_Ini               0x7
-#define        bRxHP_TRLNA             0x70
-#define        bRxHP_RSSI              0x700
-#define        bRxHP_BBP1              0x7000
-#define        bRxHP_BBP2              0x70000
-#define        bRxHP_BBP3              0x700000
-#define        bRSSI_H                 0x7f0000     /* threshold for high power */
-#define        bRSSI_Gen               0x7f000000   /* threshold for ant diversity */
-#define        bRxSettle_TRSW          0x7
-#define        bRxSettle_LNA           0x38
-#define        bRxSettle_RSSI          0x1c0
-#define        bRxSettle_BBP           0xe00
-#define        bRxSettle_RxHP          0x7000
-#define        bRxSettle_AntSW_RSSI    0x38000
-#define        bRxSettle_AntSW         0xc0000
-#define        bRxProcessTime_DAGC     0x300000
-#define        bRxSettle_HSSI          0x400000
-#define        bRxProcessTime_BBPPW    0x800000
-#define        bRxAntennaPowerShift    0x3000000
-#define        bRSSITableSelect        0xc000000
-#define        bRxHP_Final             0x7000000
-#define        bRxHTSettle_BBP         0x7
-#define        bRxHTSettle_HSSI        0x8
-#define        bRxHTSettle_RxHP        0x70
-#define        bRxHTSettle_BBPPW       0x80
-#define        bRxHTSettle_Idle        0x300
-#define        bRxHTSettle_Reserved    0x1c00
-#define        bRxHTRxHPEn             0x8000
-#define        bRxHTAGCFreezeThres     0x30000
-#define        bRxHTAGCTogetherEn      0x40000
-#define        bRxHTAGCMin             0x80000
-#define        bRxHTAGCEn              0x100000
-#define        bRxHTDAGCEn             0x200000
-#define        bRxHTRxHP_BBP           0x1c00000
-#define        bRxHTRxHP_Final         0xe0000000
-#define        bRxPWRatioTH            0x3
-#define        bRxPWRatioEn            0x4
-#define        bRxMFHold               0x3800
-#define        bRxPD_Delay_TH1         0x38
-#define        bRxPD_Delay_TH2         0x1c0
-#define        bRxPD_DC_COUNT_MAX      0x600
-#define        bRxPD_Delay_TH          0x8000
-#define        bRxProcess_Delay        0xf0000
-#define        bRxSearchrange_GI2_Early        0x700000
-#define        bRxFrame_Guard_Counter_L        0x3800000
-#define        bRxSGI_Guard_L          0xc000000
-#define        bRxSGI_Search_L         0x30000000
-#define        bRxSGI_TH               0xc0000000
-#define        bDFSCnt0                0xff
-#define        bDFSCnt1                0xff00
-#define        bDFSFlag                0xf0000
-#define        bMFWeightSum            0x300000
-#define        bMinIdxTH               0x7f000000
-#define        bDAFormat               0x40000
-#define        bTxChEmuEnable          0x01000000
-#define        bTRSWIsolation_A        0x7f
-#define        bTRSWIsolation_B        0x7f00
-#define        bTRSWIsolation_C        0x7f0000
-#define        bTRSWIsolation_D        0x7f000000
-#define        bExtLNAGain             0x7c00
-
-/*  6. PageE(0xE00) */
-#define        bSTBCEn                 0x4     /*  Useless */
-#define        bAntennaMapping         0x10
-#define        bNss                    0x20
-#define        bCFOAntSumD             0x200
-#define        bPHYCounterReset        0x8000000
-#define        bCFOReportGet           0x4000000
-#define        bOFDMContinueTx         0x10000000
-#define        bOFDMSingleCarrier      0x20000000
-#define        bOFDMSingleTone         0x40000000
-#define        bHTDetect               0x100
-#define        bCFOEn                  0x10000
-#define        bCFOValue               0xfff00000
-#define        bSigTone_Re             0x3f
-#define        bSigTone_Im             0x7f00
-#define        bCounter_CCA            0xffff
-#define        bCounter_ParityFail     0xffff0000
-#define        bCounter_RateIllegal    0xffff
-#define        bCounter_CRC8Fail       0xffff0000
-#define        bCounter_MCSNoSupport   0xffff
-#define        bCounter_FastSync       0xffff
-#define        bShortCFO               0xfff
-#define        bShortCFOTLength        12   /* total */
-#define        bShortCFOFLength        11   /* fraction */
-#define        bLongCFO                0x7ff
-#define        bLongCFOTLength         11
-#define        bLongCFOFLength         11
-#define        bTailCFO                0x1fff
-#define        bTailCFOTLength         13
-#define        bTailCFOFLength         12
-#define        bmax_en_pwdB            0xffff
-#define        bCC_power_dB            0xffff0000
-#define        bnoise_pwdB             0xffff
-#define        bPowerMeasTLength       10
-#define        bPowerMeasFLength       3
-#define        bRx_HT_BW               0x1
-#define        bRxSC                   0x6
-#define        bRx_HT                  0x8
-#define        bNB_intf_det_on         0x1
-#define        bIntf_win_len_cfg       0x30
-#define        bNB_Intf_TH_cfg         0x1c0
-#define        bRFGain                 0x3f
-#define        bTableSel               0x40
-#define        bTRSW                   0x80
-#define        bRxSNR_A                0xff
-#define        bRxSNR_B                0xff00
-#define        bRxSNR_C                0xff0000
-#define        bRxSNR_D                0xff000000
-#define        bSNREVMTLength          8
-#define        bSNREVMFLength          1
-#define        bCSI1st                 0xff
-#define        bCSI2nd                 0xff00
-#define        bRxEVM1st               0xff0000
-#define        bRxEVM2nd               0xff000000
-#define        bSIGEVM                 0xff
-#define        bPWDB                   0xff00
-#define        bSGIEN                  0x10000
-
-#define        bSFactorQAM1            0xf     /*  Useless */
-#define        bSFactorQAM2            0xf0
-#define        bSFactorQAM3            0xf00
-#define        bSFactorQAM4            0xf000
-#define        bSFactorQAM5            0xf0000
-#define        bSFactorQAM6            0xf0000
-#define        bSFactorQAM7            0xf00000
-#define        bSFactorQAM8            0xf000000
-#define        bSFactorQAM9            0xf0000000
-#define        bCSIScheme              0x100000
-
-#define        bNoiseLvlTopSet         0x3     /*  Useless */
-#define        bChSmooth               0x4
-#define        bChSmoothCfg1           0x38
-#define        bChSmoothCfg2           0x1c0
-#define        bChSmoothCfg3           0xe00
-#define        bChSmoothCfg4           0x7000
-#define        bMRCMode                0x800000
-#define        bTHEVMCfg               0x7000000
-
-#define        bLoopFitType            0x1     /*  Useless */
-#define        bUpdCFO                 0x40
-#define        bUpdCFOOffData          0x80
-#define        bAdvUpdCFO              0x100
-#define        bAdvTimeCtrl            0x800
-#define        bUpdClko                0x1000
-#define        bFC                     0x6000
-#define        bTrackingMode           0x8000
-#define        bPhCmpEnable            0x10000
-#define        bUpdClkoLTF             0x20000
-#define        bComChCFO               0x40000
-#define        bCSIEstiMode            0x80000
-#define        bAdvUpdEqz              0x100000
-#define        bUChCfg                 0x7000000
-#define        bUpdEqz                 0x8000000
-
-/* Rx Pseduo noise */
-#define        bRxPesudoNoiseOn        0x20000000      /*  Useless */
-#define        bRxPesudoNoise_A        0xff
-#define        bRxPesudoNoise_B        0xff00
-#define        bRxPesudoNoise_C        0xff0000
-#define        bRxPesudoNoise_D        0xff000000
-#define        bPesudoNoiseState_A     0xffff
-#define        bPesudoNoiseState_B     0xffff0000
-#define        bPesudoNoiseState_C     0xffff
-#define        bPesudoNoiseState_D     0xffff0000
-
-/* 7. RF Register */
-/* Zebra1 */
-#define        bZebra1_HSSIEnable      0x8             /*  Useless */
-#define        bZebra1_TRxControl      0xc00
-#define        bZebra1_TRxGainSetting  0x07f
-#define        bZebra1_RxCorner        0xc00
-#define        bZebra1_TxChargePump    0x38
-#define        bZebra1_RxChargePump    0x7
-#define        bZebra1_ChannelNum      0xf80
-#define        bZebra1_TxLPFBW         0x400
-#define        bZebra1_RxLPFBW         0x600
-
-/* Zebra4 */
-#define        bRTL8256RegModeCtrl1    0x100   /*  Useless */
-#define        bRTL8256RegModeCtrl0    0x40
-#define        bRTL8256_TxLPFBW        0x18
-#define        bRTL8256_RxLPFBW        0x600
-
-/* RTL8258 */
-#define        bRTL8258_TxLPFBW        0xc     /*  Useless */
-#define        bRTL8258_RxLPFBW        0xc00
-#define        bRTL8258_RSSILPFBW      0xc0
-
-/*  */
-/*  Other Definition */
-/*  */
-
-/* byte endable for sb_write */
-#define        bByte0                  0x1     /*  Useless */
-#define        bByte1                  0x2
-#define        bByte2                  0x4
-#define        bByte3                  0x8
-#define        bWord0                  0x3
-#define        bWord1                  0xc
-#define        bDWord                  0xf
-
-/* for PutRegsetting & GetRegSetting BitMask */
-#define        bMaskByte0              0xff    /*  Reg 0xc50 rOFDM0_XAAGCCore~0xC6f */
-#define        bMaskByte1              0xff00
-#define        bMaskByte2              0xff0000
-#define        bMaskByte3              0xff000000
-#define        bMaskHWord              0xffff0000
-#define        bMaskLWord              0x0000ffff
-#define        bMaskDWord              0xffffffff
-#define        bMask12Bits             0xfff
-#define        bMaskH4Bits             0xf0000000
-#define        bMaskOFDM_D             0xffc00000
-#define        bMaskCCK                0x3f3f3f3f
-
-/* for PutRFRegsetting & GetRFRegSetting BitMask */
-#define        bRFRegOffsetMask        0xfffff
-
-#define        bEnable                 0x1     /*  Useless */
-#define        bDisable                0x0
-
-#define        LeftAntenna             0x0     /*  Useless */
-#define        RightAntenna            0x1
-
-#define        tCheckTxStatus          500   /* 500ms Useless */
-#define        tUpdateRxCounter        100   /* 100ms */
-
-#define        rateCCK                 0       /*  Useless */
-#define        rateOFDM                1
-#define        rateHT                  2
-
-/* define Register-End */
-#define        bPMAC_End               0x1ff   /*  Useless */
-#define        bFPGAPHY0_End           0x8ff
-#define        bFPGAPHY1_End           0x9ff
-#define        bCCKPHY0_End            0xaff
-#define        bOFDMPHY0_End           0xcff
-#define        bOFDMPHY1_End           0xdff
-
-#define        bPMACControl            0x0     /*  Useless */
-#define        bWMACControl            0x1
-#define        bWNICControl            0x2
-
-#define        PathA                   0x0     /*  Useless */
-#define        PathB                   0x1
-#define        PathC                   0x2
-#define        PathD                   0x3
-
-/*--------------------------Define Parameters-------------------------------*/
-
-#endif
diff --git a/drivers/staging/r8188eu/include/Hal8188ERateAdaptive.h b/drivers/staging/r8188eu/include/Hal8188ERateAdaptive.h
deleted file mode 100644 (file)
index c571ad9..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright (c) 2011 Realtek Semiconductor Corp. */
-
-#ifndef __INC_RA_H
-#define __INC_RA_H
-/* Module Name: RateAdaptive.h
- * Abstract: Prototype of RA and related data structure.
- */
-
-#include <linux/bitfield.h>
-
-/*  Rate adaptive define */
-#define        PERENTRY        23
-#define        RETRYSIZE       5
-#define        RATESIZE        28
-#define        TX_RPT2_ITEM_SIZE       8
-
-/*  TX report 2 format in Rx desc */
-#define GET_TX_RPT2_DESC_PKT_LEN_88E(__rxstatusdesc)           \
-       le32_get_bits(*(__le32 *)__rxstatusdesc, GENMASK(8, 0))
-#define GET_TX_RPT2_DESC_MACID_VALID_1_88E(__rxstatusdesc)     \
-       le32_to_cpu((*(__le32 *)(__rxstatusdesc + 16))
-#define GET_TX_RPT2_DESC_MACID_VALID_2_88E(__rxstatusdesc)     \
-       le32_to_cpu((*(__le32 *)(__rxstatusdesc + 20))
-/*  End rate adaptive define */
-
-int ODM_RAInfo_Init_all(struct odm_dm_struct *dm_odm);
-
-int ODM_RAInfo_Init(struct odm_dm_struct *dm_odm, u8 MacID);
-
-u8 ODM_RA_GetShortGI_8188E(struct odm_dm_struct *dm_odm, u8 MacID);
-
-u8 ODM_RA_GetDecisionRate_8188E(struct odm_dm_struct *dm_odm, u8 MacID);
-
-u8 ODM_RA_GetHwPwrStatus_8188E(struct odm_dm_struct *dm_odm, u8 MacID);
-void ODM_RA_UpdateRateInfo_8188E(struct odm_dm_struct *dm_odm, u8 MacID,
-                                u8 RateID, u32 RateMask,
-                                u8 SGIEnable);
-
-void ODM_RA_SetRSSI_8188E(struct odm_dm_struct *dm_odm, u8 macid,
-                         u8 rssi);
-
-void ODM_RA_TxRPT2Handle_8188E(struct odm_dm_struct *dm_odm,
-                              u8 *txrpt_buf, u16 txrpt_len,
-                              u32 validentry0, u32 validentry1);
-
-void ODM_RA_Set_TxRPT_Time(struct odm_dm_struct *dm_odm, u16 minRptTime);
-
-#endif
diff --git a/drivers/staging/r8188eu/include/HalHWImg8188E_BB.h b/drivers/staging/r8188eu/include/HalHWImg8188E_BB.h
deleted file mode 100644 (file)
index 0a290bc..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __INC_BB_8188E_HW_IMG_H
-#define __INC_BB_8188E_HW_IMG_H
-
-/* static bool CheckCondition(const u32 Condition, const u32 Hex); */
-
-/******************************************************************************
-*                           AGC_TAB_1T.TXT
-******************************************************************************/
-
-int ODM_ReadAndConfig_AGC_TAB_1T_8188E(struct odm_dm_struct *odm);
-
-/******************************************************************************
-*                           PHY_REG_1T.TXT
-******************************************************************************/
-
-int ODM_ReadAndConfig_PHY_REG_1T_8188E(struct odm_dm_struct *odm);
-
-/******************************************************************************
-*                           PHY_REG_PG.TXT
-******************************************************************************/
-
-void ODM_ReadAndConfig_PHY_REG_PG_8188E(struct odm_dm_struct *dm_odm);
-
-#endif
diff --git a/drivers/staging/r8188eu/include/HalHWImg8188E_MAC.h b/drivers/staging/r8188eu/include/HalHWImg8188E_MAC.h
deleted file mode 100644 (file)
index b3d67c1..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __INC_MAC_8188E_HW_IMG_H
-#define __INC_MAC_8188E_HW_IMG_H
-
-/******************************************************************************
-*                           MAC_REG.TXT
-******************************************************************************/
-int ODM_ReadAndConfig_MAC_REG_8188E(struct odm_dm_struct *pDM_Odm);
-
-#endif /*  end of HWIMG_SUPPORT */
diff --git a/drivers/staging/r8188eu/include/HalHWImg8188E_RF.h b/drivers/staging/r8188eu/include/HalHWImg8188E_RF.h
deleted file mode 100644 (file)
index 880fead..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __INC_RF_8188E_HW_IMG_H
-#define __INC_RF_8188E_HW_IMG_H
-
-/******************************************************************************
- *                           RadioA_1T.TXT
- ******************************************************************************/
-
-int ODM_ReadAndConfig_RadioA_1T_8188E(struct odm_dm_struct *odm);
-
-#endif /*  end of HWIMG_SUPPORT */
diff --git a/drivers/staging/r8188eu/include/HalPhyRf_8188e.h b/drivers/staging/r8188eu/include/HalPhyRf_8188e.h
deleted file mode 100644 (file)
index b75a5d8..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __HAL_PHY_RF_8188E_H__
-#define __HAL_PHY_RF_8188E_H__
-
-/*--------------------------Define Parameters-------------------------------*/
-#define        IQK_DELAY_TIME_88E              10              /* ms */
-#define        index_mapping_NUM_88E   15
-#define AVG_THERMAL_NUM_88E    4
-
-void ODM_TxPwrTrackAdjust88E(struct odm_dm_struct *pDM_Odm,
-                            u8 Type,   /* 0 = OFDM, 1 = CCK */
-                            u8 *pDirection,/* 1 = +(incr) 2 = -(decr) */
-                            u32 *pOutWriteVal); /* Tx tracking CCK/OFDM BB
-                                                    * swing index adjust */
-
-void odm_TXPowerTrackingCallback_ThermalMeter_8188E(struct adapter *Adapter);
-
-/* 1 7.        IQK */
-
-void PHY_IQCalibrate_8188E(struct adapter *Adapter, bool ReCovery);
-
-/*  LC calibrate */
-void PHY_LCCalibrate_8188E(struct adapter *pAdapter);
-
-/*  AP calibrate */
-void PHY_DigitalPredistortion_8188E(struct adapter *pAdapter);
-
-void _PHY_SaveADDARegisters(struct adapter *pAdapter, u32 *ADDAReg,
-                           u32 *ADDABackup, u32 RegisterNum);
-
-void _PHY_MACSettingCalibration(struct adapter *pAdapter, u32 *MACReg,
-                               u32 *MACBackup);
-
-#endif /*  #ifndef __HAL_PHY_RF_8188E_H__ */
diff --git a/drivers/staging/r8188eu/include/HalPwrSeqCmd.h b/drivers/staging/r8188eu/include/HalPwrSeqCmd.h
deleted file mode 100644 (file)
index 0886300..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __HALPWRSEQCMD_H__
-#define __HALPWRSEQCMD_H__
-
-#include "drv_types.h"
-
-enum r8188eu_pwr_seq {
-       PWR_ON_FLOW,
-       DISABLE_FLOW,
-       LPS_ENTER_FLOW,
-};
-
-/*     Prototype of protected function. */
-u8 HalPwrSeqCmdParsing(struct adapter *padapter, enum r8188eu_pwr_seq seq);
-
-#endif
diff --git a/drivers/staging/r8188eu/include/HalVerDef.h b/drivers/staging/r8188eu/include/HalVerDef.h
deleted file mode 100644 (file)
index 7a530c7..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-#ifndef __HAL_VERSION_DEF_H__
-#define __HAL_VERSION_DEF_H__
-
-enum HAL_CHIP_TYPE {
-       TEST_CHIP       =       0,
-       NORMAL_CHIP     =       1,
-};
-
-enum HAL_CUT_VERSION {
-       A_CUT_VERSION   =       0,
-       B_CUT_VERSION   =       1,
-       C_CUT_VERSION   =       2,
-       D_CUT_VERSION   =       3,
-       E_CUT_VERSION   =       4,
-};
-
-enum HAL_VENDOR {
-       CHIP_VENDOR_TSMC        =       0,
-       CHIP_VENDOR_UMC         =       1,
-};
-
-struct HAL_VERSION {
-       enum HAL_CHIP_TYPE      ChipType;
-       enum HAL_CUT_VERSION    CUTVersion;
-       enum HAL_VENDOR         VendorType;
-};
-
-/*  Get element */
-#define GET_CVID_CHIP_TYPE(version)    (((version).ChipType))
-#define GET_CVID_MANUFACTUER(version)  (((version).VendorType))
-
-/* HAL_CHIP_TYPE_E */
-#define IS_NORMAL_CHIP(version)                                \
-       (GET_CVID_CHIP_TYPE(version) == NORMAL_CHIP)
-
-/* HAL_VENDOR_E */
-#define IS_CHIP_VENDOR_TSMC(version)                   \
-       (GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_TSMC)
-
-#endif
diff --git a/drivers/staging/r8188eu/include/drv_types.h b/drivers/staging/r8188eu/include/drv_types.h
deleted file mode 100644 (file)
index 159990f..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-/*-----------------------------------------------------------------------------
-
-       For type defines and data structure defines
-
-------------------------------------------------------------------------------*/
-
-#ifndef __DRV_TYPES_H__
-#define __DRV_TYPES_H__
-
-#include "osdep_service.h"
-#include "wlan_bssdef.h"
-#include "rtw_ht.h"
-#include "rtw_cmd.h"
-#include "rtw_xmit.h"
-#include "rtw_recv.h"
-#include "hal_intf.h"
-#include "hal_com.h"
-#include "rtw_security.h"
-#include "rtw_pwrctrl.h"
-#include "rtw_io.h"
-#include "rtw_eeprom.h"
-#include "sta_info.h"
-#include "rtw_mlme.h"
-#include "rtw_rf.h"
-#include "rtw_event.h"
-#include "rtw_led.h"
-#include "rtw_mlme_ext.h"
-#include "rtw_p2p.h"
-#include "rtw_ap.h"
-#include "rtw_br_ext.h"
-#include "rtl8188e_hal.h"
-#include "rtw_fw.h"
-
-#define FW_RTL8188EU   "rtlwifi/rtl8188eufw.bin"
-
-struct registry_priv {
-       u8      rfintfs;
-       u8      lbkmode;
-       u8      hci;
-       struct ndis_802_11_ssid ssid;
-       u8      network_mode;   /* infra, ad-hoc, auto */
-       u8      channel;/* ad-hoc support requirement */
-       u8      wireless_mode;/* A, B, G, auto */
-       u8      scan_mode;/* active, passive */
-       u8      radio_enable;
-       u8      preamble;/* long, short, auto */
-       u8      vrtl_carrier_sense;/* Enable, Disable, Auto */
-       u8      vcs_type;/* RTS/CTS, CTS-to-self */
-       u16     rts_thresh;
-       u16     frag_thresh;
-       u8      adhoc_tx_pwr;
-       u8      soft_ap;
-       u8      power_mgnt;
-       u8      ips_mode;
-       u8      smart_ps;
-       u8      long_retry_lmt;
-       u8      short_retry_lmt;
-       u16     busy_thresh;
-       u8      ack_policy;
-       u8      software_encrypt;
-       u8      software_decrypt;
-       u8      acm_method;
-         /* UAPSD */
-       u8      wmm_enable;
-       u8      uapsd_enable;
-       u8      uapsd_max_sp;
-       u8      uapsd_acbk_en;
-       u8      uapsd_acbe_en;
-       u8      uapsd_acvi_en;
-       u8      uapsd_acvo_en;
-
-       u8      led_enable;
-
-       struct wlan_bssid_ex    dev_network;
-
-       u8      ht_enable;
-       u8      cbw40_enable;
-       u8      ampdu_enable;/* for tx */
-       u8      rx_stbc;
-       u8      ampdu_amsdu;/* A-MPDU Supports A-MSDU is permitted */
-       u8      lowrate_two_xmit;
-
-       u8      low_power;
-
-       u8      wifi_spec;/*  !turbo_mode */
-
-       u8      channel_plan;
-       bool    bAcceptAddbaReq;
-
-       u8      antdiv_cfg;
-       u8      antdiv_type;
-
-       u8      usbss_enable;/* 0:disable,1:enable */
-       u8      hwpdn_mode;/* 0:disable,1:enable,2:decide by EFUSE config */
-       u8      hwpwrp_detect;/* 0:disable,1:enable */
-
-       u8      hw_wps_pbc;/* 0:disable,1:enable */
-
-       u8      max_roaming_times; /*  the max number driver will try */
-
-       u8      fw_iol; /* enable iol without other concern */
-
-       u8      enable80211d;
-
-       u8      ifname[16];
-       u8      if2name[16];
-
-       u8      notch_filter;
-};
-
-#define MAX_CONTINUAL_URB_ERR          4
-
-struct dvobj_priv {
-       struct adapter *if1;
-
-       /* For 92D, DMDP have 2 interface. */
-       u8      InterfaceNumber;
-       u8      NumInterfaces;
-
-       /* In /Out Pipe information */
-       int     RtInPipe;
-       int     RtOutPipe[3];
-       u8      Queue2Pipe[HW_QUEUE_ENTRY];/* for out pipe mapping */
-
-       struct rt_firmware firmware;
-
-/*-------- below is for USB INTERFACE --------*/
-
-       u8      RtNumOutPipes;
-
-       struct usb_interface *pusbintf;
-       struct usb_device *pusbdev;
-
-       atomic_t continual_urb_error;
-};
-
-static inline struct device *dvobj_to_dev(struct dvobj_priv *dvobj)
-{
-       /* todo: get interface type from dvobj and the return
-        * the dev accordingly */
-       return &dvobj->pusbintf->dev;
-};
-
-struct adapter {
-       int     pid[3];/* process id from UI, 0:wps, 1:hostapd, 2:dhcpcd */
-
-       struct dvobj_priv *dvobj;
-       struct  mlme_priv mlmepriv;
-       struct  mlme_ext_priv mlmeextpriv;
-       struct  cmd_priv        cmdpriv;
-       struct  evt_priv        evtpriv;
-       struct  xmit_priv       xmitpriv;
-       struct  recv_priv       recvpriv;
-       struct  sta_priv        stapriv;
-       struct  security_priv   securitypriv;
-       struct  registry_priv   registrypriv;
-       struct  pwrctrl_priv    pwrctrlpriv;
-       struct  eeprom_priv eeprompriv;
-       struct  led_priv        ledpriv;
-       struct wifidirect_info  wdinfo;
-
-       struct hal_data_8188e haldata;
-
-       s32     bDriverStopped;
-       s32     bSurpriseRemoved;
-
-       u8      hw_init_completed;
-       s8      signal_strength;
-
-       void *cmdThread;
-       struct  net_device *pnetdev;
-
-       /*  used by rtw_rereg_nd_name related function */
-       struct rereg_nd_name_data {
-               struct  net_device *old_pnetdev;
-               char old_ifname[IFNAMSIZ];
-               u8 old_ips_mode;
-               u8 old_bRegUseLed;
-       } rereg_nd_name_priv;
-
-       int bup;
-       struct net_device_stats stats;
-       struct iw_statistics iwstats;
-
-       int net_closed;
-       u8 bFWReady;
-       u8 bReadPortCancel;
-       u8 bWritePortCancel;
-       u8 bRxRSSIDisplay;
-       /* The driver will show up the desired channel number
-        * when this flag is 1. */
-       u8 bNotifyChannelChange;
-       /* The driver will show the current P2P status when the
-        * upper application reads it. */
-       u8 bShowGetP2PState;
-       struct adapter *pbuddy_adapter;
-
-       struct mutex *hw_init_mutex;
-
-       spinlock_t br_ext_lock;
-       struct nat25_network_db_entry   *nethash[NAT25_HASH_SIZE];
-       int                             pppoe_connection_in_progress;
-       unsigned char                   pppoe_addr[ETH_ALEN];
-       unsigned char                   scdb_mac[ETH_ALEN];
-       unsigned char                   scdb_ip[4];
-       struct nat25_network_db_entry   *scdb_entry;
-       unsigned char                   br_mac[ETH_ALEN];
-       unsigned char                   br_ip[4];
-       struct br_ext_info              ethBrExtInfo;
-};
-
-#define adapter_to_dvobj(adapter) (adapter->dvobj)
-
-void rtw_handle_dualmac(struct adapter *adapter, bool init);
-
-static inline u8 *myid(struct eeprom_priv *peepriv)
-{
-       return peepriv->mac_addr;
-}
-
-#endif /* __DRV_TYPES_H__ */
diff --git a/drivers/staging/r8188eu/include/hal_com.h b/drivers/staging/r8188eu/include/hal_com.h
deleted file mode 100644 (file)
index cd3f845..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __HAL_COMMON_H__
-#define __HAL_COMMON_H__
-
-/*  */
-/*        Rate Definition */
-/*  */
-/* CCK */
-#define        RATR_1M                                 0x00000001
-#define        RATR_2M                                 0x00000002
-#define        RATR_55M                                0x00000004
-#define        RATR_11M                                0x00000008
-/* OFDM */
-#define        RATR_6M                                 0x00000010
-#define        RATR_9M                                 0x00000020
-#define        RATR_12M                                0x00000040
-#define        RATR_18M                                0x00000080
-#define        RATR_24M                                0x00000100
-#define        RATR_36M                                0x00000200
-#define        RATR_48M                                0x00000400
-#define        RATR_54M                                0x00000800
-/* MCS 1 Spatial Stream */
-#define        RATR_MCS0                               0x00001000
-#define        RATR_MCS1                               0x00002000
-#define        RATR_MCS2                               0x00004000
-#define        RATR_MCS3                               0x00008000
-#define        RATR_MCS4                               0x00010000
-#define        RATR_MCS5                               0x00020000
-#define        RATR_MCS6                               0x00040000
-#define        RATR_MCS7                               0x00080000
-/* MCS 2 Spatial Stream */
-#define        RATR_MCS8                               0x00100000
-#define        RATR_MCS9                               0x00200000
-#define        RATR_MCS10                              0x00400000
-#define        RATR_MCS11                              0x00800000
-#define        RATR_MCS12                              0x01000000
-#define        RATR_MCS13                              0x02000000
-#define        RATR_MCS14                              0x04000000
-#define        RATR_MCS15                              0x08000000
-
-/* CCK */
-#define RATE_1M                                        BIT(0)
-#define RATE_2M                                        BIT(1)
-#define RATE_5_5M                              BIT(2)
-#define RATE_11M                               BIT(3)
-/* OFDM */
-#define RATE_6M                                        BIT(4)
-#define RATE_9M                                        BIT(5)
-#define RATE_12M                               BIT(6)
-#define RATE_18M                               BIT(7)
-#define RATE_24M                               BIT(8)
-#define RATE_36M                               BIT(9)
-#define RATE_48M                               BIT(10)
-#define RATE_54M                               BIT(11)
-/* MCS 1 Spatial Stream */
-#define RATE_MCS0                              BIT(12)
-#define RATE_MCS1                              BIT(13)
-#define RATE_MCS2                              BIT(14)
-#define RATE_MCS3                              BIT(15)
-#define RATE_MCS4                              BIT(16)
-#define RATE_MCS5                              BIT(17)
-#define RATE_MCS6                              BIT(18)
-#define RATE_MCS7                              BIT(19)
-/* MCS 2 Spatial Stream */
-#define RATE_MCS8                              BIT(20)
-#define RATE_MCS9                              BIT(21)
-#define RATE_MCS10                             BIT(22)
-#define RATE_MCS11                             BIT(23)
-#define RATE_MCS12                             BIT(24)
-#define RATE_MCS13                             BIT(25)
-#define RATE_MCS14                             BIT(26)
-#define RATE_MCS15                             BIT(27)
-
-/*  ALL CCK Rate */
-#define        RATE_ALL_CCK            (RATR_1M | RATR_2M | RATR_55M | RATR_11M)
-#define        RATE_ALL_OFDM_AG        (RATR_6M | RATR_9M | RATR_12M | RATR_18M | \
-                                RATR_24M | RATR_36M | RATR_48M | RATR_54M)
-#define        RATE_ALL_OFDM_1SS       (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 |    \
-                                RATR_MCS3 | RATR_MCS4 | RATR_MCS5|RATR_MCS6 | \
-                                RATR_MCS7)
-#define        RATE_ALL_OFDM_2SS       (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | \
-                                RATR_MCS11 | RATR_MCS12 | RATR_MCS13 | \
-                                RATR_MCS14 | RATR_MCS15)
-
-/*------------------------------ Tx Desc definition Macro --------------------*/
-/* pragma mark -- Tx Desc related definition. -- */
-/*     Rate */
-/*  CCK Rates, TxHT = 0 */
-#define DESC_RATE1M                            0x00
-#define DESC_RATE2M                            0x01
-#define DESC_RATE5_5M                          0x02
-#define DESC_RATE11M                           0x03
-
-/*  OFDM Rates, TxHT = 0 */
-#define DESC_RATE6M                            0x04
-#define DESC_RATE9M                            0x05
-#define DESC_RATE12M                           0x06
-#define DESC_RATE18M                           0x07
-#define DESC_RATE24M                           0x08
-#define DESC_RATE36M                           0x09
-#define DESC_RATE48M                           0x0a
-#define DESC_RATE54M                           0x0b
-
-/*  MCS Rates, TxHT = 1 */
-#define DESC_RATEMCS0                          0x0c
-#define DESC_RATEMCS1                          0x0d
-#define DESC_RATEMCS2                          0x0e
-#define DESC_RATEMCS3                          0x0f
-#define DESC_RATEMCS4                          0x10
-#define DESC_RATEMCS5                          0x11
-#define DESC_RATEMCS6                          0x12
-#define DESC_RATEMCS7                          0x13
-#define DESC_RATEMCS8                          0x14
-#define DESC_RATEMCS9                          0x15
-#define DESC_RATEMCS10                         0x16
-#define DESC_RATEMCS11                         0x17
-#define DESC_RATEMCS12                         0x18
-#define DESC_RATEMCS13                         0x19
-#define DESC_RATEMCS14                         0x1a
-#define DESC_RATEMCS15                         0x1b
-#define DESC_RATEMCS15_SG                      0x1c
-#define DESC_RATEMCS32                         0x20
-
-/*  1 Byte long (in unit of TU) */
-#define REG_P2P_CTWIN                          0x0572
-#define REG_NOA_DESC_SEL                       0x05CF
-#define REG_NOA_DESC_DURATION                  0x05E0
-#define REG_NOA_DESC_INTERVAL                  0x05E4
-#define REG_NOA_DESC_START                     0x05E8
-#define REG_NOA_DESC_COUNT                     0x05EC
-
-/* return the final channel plan decision */
-u8 hal_com_get_channel_plan(struct adapter *padapter,
-                           u8 hw_channel_plan,
-                           u8 sw_channel_plan,
-                           u8 def_channel_plan,
-                           bool AutoLoadFail
-);
-
-u8 MRateToHwRate(u8 rate);
-
-void HalSetBrateCfg(struct adapter *Adapter, u8 *mBratesOS, u16 *pBrateCfg);
-
-#endif /* __HAL_COMMON_H__ */
diff --git a/drivers/staging/r8188eu/include/hal_intf.h b/drivers/staging/r8188eu/include/hal_intf.h
deleted file mode 100644 (file)
index 296aa5b..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-#ifndef __HAL_INTF_H__
-#define __HAL_INTF_H__
-
-#include "osdep_service.h"
-#include "drv_types.h"
-#include "Hal8188EPhyCfg.h"
-
-typedef s32 (*c2h_id_filter)(u8 id);
-
-int rtl8188eu_interface_configure(struct adapter *adapt);
-int ReadAdapterInfo8188EU(struct adapter *Adapter);
-void rtl8188eu_init_default_value(struct adapter *adapt);
-void rtl8188e_SetHalODMVar(struct adapter *Adapter, void *pValue1, bool bSet);
-u32 rtl8188eu_InitPowerOn(struct adapter *adapt);
-void rtl8188e_EfusePowerSwitch(struct adapter *pAdapter, u8 PwrState);
-void rtl8188e_ReadEFuse(struct adapter *Adapter, u16 _size_byte, u8 *pbuf);
-
-void hal_notch_filter_8188e(struct adapter *adapter, bool enable);
-
-void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt);
-void UpdateHalRAMask8188EUsb(struct adapter *adapt, u32 mac_id, u8 rssi_level);
-
-int rtl8188e_IOL_exec_cmds_sync(struct adapter *adapter,
-                               struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt);
-
-int rtl8188eu_inirp_init(struct adapter *Adapter);
-
-uint rtw_hal_init(struct adapter *padapter);
-uint rtw_hal_deinit(struct adapter *padapter);
-void rtw_hal_stop(struct adapter *padapter);
-
-u32 rtl8188eu_hal_init(struct adapter *Adapter);
-u32 rtl8188eu_hal_deinit(struct adapter *Adapter);
-
-void rtw_hal_update_ra_mask(struct adapter *padapter, u32 mac_id, u8 level);
-void   rtw_hal_clone_data(struct adapter *dst_adapt,
-                          struct adapter *src_adapt);
-
-u8 rtw_do_join(struct adapter *padapter);
-
-#endif /* __HAL_INTF_H__ */
diff --git a/drivers/staging/r8188eu/include/ieee80211.h b/drivers/staging/r8188eu/include/ieee80211.h
deleted file mode 100644 (file)
index e7a4f8a..0000000
+++ /dev/null
@@ -1,817 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __IEEE80211_H
-#define __IEEE80211_H
-
-#include "osdep_service.h"
-#include "drv_types.h"
-#include "wifi.h"
-#include <linux/wireless.h>
-
-#define MGMT_QUEUE_NUM 5
-
-#define ETH_TYPE_LEN           2
-#define PAYLOAD_TYPE_LEN       1
-
-#define RTL_IOCTL_HOSTAPD (SIOCIWFIRSTPRIV + 28)
-
-/* STA flags */
-#define WLAN_STA_AUTH BIT(0)
-#define WLAN_STA_ASSOC BIT(1)
-#define WLAN_STA_PS BIT(2)
-#define WLAN_STA_TIM BIT(3)
-#define WLAN_STA_PERM BIT(4)
-#define WLAN_STA_AUTHORIZED BIT(5)
-#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */
-#define WLAN_STA_SHORT_PREAMBLE BIT(7)
-#define WLAN_STA_PREAUTH BIT(8)
-#define WLAN_STA_WME BIT(9)
-#define WLAN_STA_MFP BIT(10)
-#define WLAN_STA_HT BIT(11)
-#define WLAN_STA_WPS BIT(12)
-#define WLAN_STA_MAYBE_WPS BIT(13)
-#define WLAN_STA_NONERP BIT(31)
-
-#define IEEE_CMD_SET_WPA_PARAM                 1
-#define IEEE_CMD_SET_WPA_IE                            2
-#define IEEE_CMD_SET_ENCRYPTION                        3
-#define IEEE_CMD_MLME                                          4
-
-#define IEEE_PARAM_WPA_ENABLED                         1
-#define IEEE_PARAM_TKIP_COUNTERMEASURES                2
-#define IEEE_PARAM_DROP_UNENCRYPTED                    3
-#define IEEE_PARAM_PRIVACY_INVOKED                     4
-#define IEEE_PARAM_AUTH_ALGS                                   5
-#define IEEE_PARAM_IEEE_802_1X                         6
-#define IEEE_PARAM_WPAX_SELECT                         7
-
-#define AUTH_ALG_OPEN_SYSTEM                   0x1
-#define AUTH_ALG_SHARED_KEY                    0x2
-#define AUTH_ALG_LEAP                          0x00000004
-
-#define IEEE_MLME_STA_DEAUTH                           1
-#define IEEE_MLME_STA_DISASSOC                 2
-
-#define IEEE_CRYPT_ERR_UNKNOWN_ALG                     2
-#define IEEE_CRYPT_ERR_UNKNOWN_ADDR                    3
-#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED               4
-#define IEEE_CRYPT_ERR_KEY_SET_FAILED                  5
-#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED               6
-#define IEEE_CRYPT_ERR_CARD_CONF_FAILED                7
-
-#define        IEEE_CRYPT_ALG_NAME_LEN                 16
-
-#define WPA_CIPHER_NONE                BIT(0)
-#define WPA_CIPHER_WEP40       BIT(1)
-#define WPA_CIPHER_WEP104 BIT(2)
-#define WPA_CIPHER_TKIP                BIT(3)
-#define WPA_CIPHER_CCMP                BIT(4)
-
-
-#define WPA_SELECTOR_LEN 4
-extern u8 RTW_WPA_OUI_TYPE[];
-extern u16 RTW_WPA_VERSION;
-extern u8 WPA_AUTH_KEY_MGMT_NONE[];
-extern u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[];
-extern u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[];
-extern u8 WPA_CIPHER_SUITE_NONE[];
-extern u8 WPA_CIPHER_SUITE_WEP40[];
-extern u8 WPA_CIPHER_SUITE_TKIP[];
-extern u8 WPA_CIPHER_SUITE_WRAP[];
-extern u8 WPA_CIPHER_SUITE_CCMP[];
-extern u8 WPA_CIPHER_SUITE_WEP104[];
-
-#define RSN_HEADER_LEN 4
-#define RSN_SELECTOR_LEN 4
-
-extern u16 RSN_VERSION_BSD;
-extern u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[];
-extern u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[];
-extern u8 RSN_CIPHER_SUITE_NONE[];
-extern u8 RSN_CIPHER_SUITE_WEP40[];
-extern u8 RSN_CIPHER_SUITE_TKIP[];
-extern u8 RSN_CIPHER_SUITE_WRAP[];
-extern u8 RSN_CIPHER_SUITE_CCMP[];
-extern u8 RSN_CIPHER_SUITE_WEP104[];
-
-enum ratr_table_mode {
-       RATR_INX_WIRELESS_NGB = 0,      /*  BGN 40 Mhz 2SS 1SS */
-       RATR_INX_WIRELESS_NG = 1,       /*  GN or N */
-       RATR_INX_WIRELESS_NB = 2,       /*  BGN 20 Mhz 2SS 1SS  or BN */
-       RATR_INX_WIRELESS_N = 3,
-       RATR_INX_WIRELESS_GB = 4,
-       RATR_INX_WIRELESS_G = 5,
-       RATR_INX_WIRELESS_B = 6,
-       RATR_INX_WIRELESS_MC = 7,
-       RATR_INX_WIRELESS_AC_N = 8,
-};
-
-enum NETWORK_TYPE {
-       WIRELESS_INVALID = 0,
-       /* Sub-Element */
-       WIRELESS_11B = BIT(0), /* tx:cck only, rx:cck only, hw: cck */
-       WIRELESS_11G = BIT(1), /* tx:ofdm only, rx:ofdm & cck, hw:cck & ofdm*/
-       WIRELESS_11_24N = BIT(3), /* tx:MCS only, rx:MCS & cck, hw:MCS & cck */
-
-       /* Combination */
-       /*  tx: cck & ofdm, rx: cck & ofdm & MCS, hw: cck & ofdm */
-       WIRELESS_11BG = (WIRELESS_11B | WIRELESS_11G),
-       /*  tx: ofdm & MCS, rx: ofdm & cck & MCS, hw: cck & ofdm */
-       WIRELESS_11G_24N = (WIRELESS_11G | WIRELESS_11_24N),
-       /*  tx: ofdm & cck & MCS, rx: ofdm & cck & MCS, hw: ofdm & cck */
-       WIRELESS_11BG_24N = (WIRELESS_11B | WIRELESS_11G | WIRELESS_11_24N),
-};
-
-struct ieee_param {
-       u32 cmd;
-       u8 sta_addr[ETH_ALEN];
-       union {
-               struct {
-                       u8 name;
-                       u32 value;
-               } wpa_param;
-               struct {
-                       u32 len;
-                       u8 reserved[32];
-                       u8 data[];
-               } wpa_ie;
-               struct {
-                       int command;
-                       int reason_code;
-               } mlme;
-               struct {
-                       u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
-                       u8 set_tx;
-                       u32 err;
-                       u8 idx;
-                       u8 seq[8]; /* sequence counter (set: RX, get: TX) */
-                       u16 key_len;
-                       u8 key[];
-               } crypt;
-               struct {
-                       u16 aid;
-                       u16 capability;
-                       int flags;
-                       u8 tx_supp_rates[16];
-                       struct ieee80211_ht_cap ht_cap;
-               } add_sta;
-               struct {
-                       u8      reserved[2];/* for set max_num_sta */
-                       u8      buf[];
-               } bcn_ie;
-       } u;
-};
-
-#define IEEE80211_DATA_LEN             2304
-/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
-   6.2.1.1.2.
-
-   The figure in section 7.1.2 suggests a body size of up to 2312
-   bytes is allowed, which is a bit confusing, I suspect this
-   represents the 2304 bytes of real data, plus a possible 8 bytes of
-   WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
-
-#define IEEE80211_HLEN                 30
-#define IEEE80211_FRAME_LEN            (IEEE80211_DATA_LEN + IEEE80211_HLEN)
-
-/* this is stolen from ipw2200 driver */
-#define IEEE_IBSS_MAC_HASH_SIZE 31
-
-#define IEEE80211_3ADDR_LEN 24
-#define IEEE80211_4ADDR_LEN 30
-#define IEEE80211_FCS_LEN    4
-
-#define MIN_FRAG_THRESHOLD     256U
-#define        MAX_FRAG_THRESHOLD     2346U
-
-/* Frame control field constants */
-#define RTW_IEEE80211_FCTL_VERS                0x0003
-#define RTW_IEEE80211_FCTL_FTYPE       0x000c
-#define RTW_IEEE80211_FCTL_STYPE       0x00f0
-#define RTW_IEEE80211_FCTL_TODS                0x0100
-#define RTW_IEEE80211_FCTL_FROMDS      0x0200
-#define RTW_IEEE80211_FCTL_MOREFRAGS   0x0400
-#define RTW_IEEE80211_FCTL_RETRY       0x0800
-#define RTW_IEEE80211_FCTL_PM          0x1000
-#define RTW_IEEE80211_FCTL_MOREDATA    0x2000
-#define RTW_IEEE80211_FCTL_PROTECTED   0x4000
-#define RTW_IEEE80211_FCTL_ORDER       0x8000
-#define RTW_IEEE80211_FCTL_CTL_EXT     0x0f00
-
-#define RTW_IEEE80211_FTYPE_MGMT       0x0000
-#define RTW_IEEE80211_FTYPE_CTL                0x0004
-#define RTW_IEEE80211_FTYPE_DATA       0x0008
-#define RTW_IEEE80211_FTYPE_EXT                0x000c
-
-/* management */
-#define RTW_IEEE80211_STYPE_ASSOC_REQ  0x0000
-#define RTW_IEEE80211_STYPE_ASSOC_RESP 0x0010
-#define RTW_IEEE80211_STYPE_REASSOC_REQ        0x0020
-#define RTW_IEEE80211_STYPE_REASSOC_RESP       0x0030
-#define RTW_IEEE80211_STYPE_PROBE_REQ  0x0040
-#define RTW_IEEE80211_STYPE_PROBE_RESP 0x0050
-#define RTW_IEEE80211_STYPE_BEACON     0x0080
-#define RTW_IEEE80211_STYPE_ATIM       0x0090
-#define RTW_IEEE80211_STYPE_DISASSOC   0x00A0
-#define RTW_IEEE80211_STYPE_AUTH       0x00B0
-#define RTW_IEEE80211_STYPE_DEAUTH     0x00C0
-#define RTW_IEEE80211_STYPE_ACTION     0x00D0
-
-/* control */
-#define RTW_IEEE80211_STYPE_CTL_EXT    0x0060
-#define RTW_IEEE80211_STYPE_BACK_REQ   0x0080
-#define RTW_IEEE80211_STYPE_BACK       0x0090
-#define RTW_IEEE80211_STYPE_PSPOLL     0x00A0
-#define RTW_IEEE80211_STYPE_RTS                0x00B0
-#define RTW_IEEE80211_STYPE_CTS                0x00C0
-#define RTW_IEEE80211_STYPE_ACK                0x00D0
-#define RTW_IEEE80211_STYPE_CFEND      0x00E0
-#define RTW_IEEE80211_STYPE_CFENDACK   0x00F0
-
-/* data */
-#define RTW_IEEE80211_STYPE_DATA       0x0000
-#define RTW_IEEE80211_STYPE_DATA_CFACK 0x0010
-#define RTW_IEEE80211_STYPE_DATA_CFPOLL        0x0020
-#define RTW_IEEE80211_STYPE_DATA_CFACKPOLL     0x0030
-#define RTW_IEEE80211_STYPE_NULLFUNC   0x0040
-#define RTW_IEEE80211_STYPE_CFACK      0x0050
-#define RTW_IEEE80211_STYPE_CFPOLL     0x0060
-#define RTW_IEEE80211_STYPE_CFACKPOLL  0x0070
-#define RTW_IEEE80211_STYPE_QOS_DATA   0x0080
-#define RTW_IEEE80211_STYPE_QOS_DATA_CFACK     0x0090
-#define RTW_IEEE80211_STYPE_QOS_DATA_CFPOLL    0x00A0
-#define RTW_IEEE80211_STYPE_QOS_DATA_CFACKPOLL 0x00B0
-#define RTW_IEEE80211_STYPE_QOS_NULLFUNC       0x00C0
-#define RTW_IEEE80211_STYPE_QOS_CFACK          0x00D0
-#define RTW_IEEE80211_STYPE_QOS_CFPOLL         0x00E0
-#define RTW_IEEE80211_STYPE_QOS_CFACKPOLL      0x00F0
-
-/* sequence control field */
-#define RTW_IEEE80211_SCTL_FRAG        0x000F
-#define RTW_IEEE80211_SCTL_SEQ 0xFFF0
-
-#define RTW_ERP_INFO_NON_ERP_PRESENT BIT(0)
-#define RTW_ERP_INFO_USE_PROTECTION BIT(1)
-#define RTW_ERP_INFO_BARKER_PREAMBLE_MODE BIT(2)
-
-/* QoS, QOS */
-#define NORMAL_ACK                     0
-#define NO_ACK                         1
-#define NON_EXPLICIT_ACK               2
-#define BLOCK_ACK                      3
-
-#ifndef ETH_P_PAE
-#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
-#endif /* ETH_P_PAE */
-
-#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
-
-#define ETH_P_ECONET   0x0018
-
-#ifndef ETH_P_80211_RAW
-#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
-#endif
-
-/* IEEE 802.11 defines */
-
-#define P80211_OUI_LEN 3
-
-struct ieee80211_snap_hdr {
-       u8    dsap;   /* always 0xAA */
-       u8    ssap;   /* always 0xAA */
-       u8    ctrl;   /* always 0x03 */
-       u8    oui[P80211_OUI_LEN];    /* organizational universal id */
-} __packed;
-
-#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
-
-#define WLAN_FC_GET_TYPE(fc) ((fc) & RTW_IEEE80211_FCTL_FTYPE)
-#define WLAN_FC_GET_STYPE(fc) ((fc) & RTW_IEEE80211_FCTL_STYPE)
-
-#define WLAN_QC_GET_TID(qc) ((qc) & 0x0f)
-
-#define WLAN_GET_SEQ_FRAG(seq) ((seq) & RTW_IEEE80211_SCTL_FRAG)
-#define WLAN_GET_SEQ_SEQ(seq)  ((seq) & RTW_IEEE80211_SCTL_SEQ)
-
-/* Authentication algorithms */
-#define WLAN_AUTH_OPEN 0
-#define WLAN_AUTH_SHARED_KEY 1
-
-#define WLAN_AUTH_CHALLENGE_LEN 128
-
-#define WLAN_CAPABILITY_BSS (1<<0)
-#define WLAN_CAPABILITY_IBSS (1<<1)
-#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
-#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
-#define WLAN_CAPABILITY_PRIVACY (1<<4)
-#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
-#define WLAN_CAPABILITY_PBCC (1<<6)
-#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
-#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
-
-/* Status codes */
-#define WLAN_STATUS_SUCCESS 0
-#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
-#define WLAN_STATUS_CAPS_UNSUPPORTED 10
-#define WLAN_STATUS_REASSOC_NO_ASSOC 11
-#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
-#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13
-#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14
-#define WLAN_STATUS_CHALLENGE_FAIL 15
-#define WLAN_STATUS_AUTH_TIMEOUT 16
-#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
-#define WLAN_STATUS_ASSOC_DENIED_RATES 18
-/* 802.11b */
-#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
-#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
-#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
-
-/* Reason codes */
-#define WLAN_REASON_UNSPECIFIED 1
-#define WLAN_REASON_PREV_AUTH_NOT_VALID 2
-#define WLAN_REASON_DEAUTH_LEAVING 3
-#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4
-#define WLAN_REASON_DISASSOC_AP_BUSY 5
-#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
-#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7
-#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8
-#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
-#define WLAN_REASON_JOIN_WRONG_CHANNEL       65534
-#define WLAN_REASON_EXPIRATION_CHK 65535
-
-/* Information Element IDs */
-#define WLAN_EID_SSID 0
-#define WLAN_EID_SUPP_RATES 1
-#define WLAN_EID_FH_PARAMS 2
-#define WLAN_EID_DS_PARAMS 3
-#define WLAN_EID_CF_PARAMS 4
-#define WLAN_EID_TIM 5
-#define WLAN_EID_IBSS_PARAMS 6
-#define WLAN_EID_CHALLENGE 16
-/* EIDs defined by IEEE 802.11h - START */
-#define WLAN_EID_PWR_CONSTRAINT 32
-#define WLAN_EID_PWR_CAPABILITY 33
-#define WLAN_EID_TPC_REQUEST 34
-#define WLAN_EID_TPC_REPORT 35
-#define WLAN_EID_SUPPORTED_CHANNELS 36
-#define WLAN_EID_CHANNEL_SWITCH 37
-#define WLAN_EID_MEASURE_REQUEST 38
-#define WLAN_EID_MEASURE_REPORT 39
-#define WLAN_EID_QUITE 40
-#define WLAN_EID_IBSS_DFS 41
-/* EIDs defined by IEEE 802.11h - END */
-#define WLAN_EID_ERP_INFO 42
-#define WLAN_EID_HT_CAP 45
-#define WLAN_EID_RSN 48
-#define WLAN_EID_EXT_SUPP_RATES 50
-#define WLAN_EID_MOBILITY_DOMAIN 54
-#define WLAN_EID_FAST_BSS_TRANSITION 55
-#define WLAN_EID_TIMEOUT_INTERVAL 56
-#define WLAN_EID_RIC_DATA 57
-#define WLAN_EID_HT_OPERATION 61
-#define WLAN_EID_SECONDARY_CHANNEL_OFFSET 62
-#define WLAN_EID_20_40_BSS_COEXISTENCE 72
-#define WLAN_EID_20_40_BSS_INTOLERANT 73
-#define WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS 74
-#define WLAN_EID_MMIE 76
-#define WLAN_EID_VENDOR_SPECIFIC 221
-#define WLAN_EID_GENERIC (WLAN_EID_VENDOR_SPECIFIC)
-
-#define IEEE80211_MGMT_HDR_LEN 24
-#define IEEE80211_DATA_HDR3_LEN 24
-#define IEEE80211_DATA_HDR4_LEN 30
-
-#define IEEE80211_STATMASK_SIGNAL (1<<0)
-#define IEEE80211_STATMASK_RSSI (1<<1)
-#define IEEE80211_STATMASK_NOISE (1<<2)
-#define IEEE80211_STATMASK_RATE (1<<3)
-#define IEEE80211_STATMASK_WEMASK 0x7
-
-#define IEEE80211_CCK_MODULATION    (1<<0)
-#define IEEE80211_OFDM_MODULATION   (1<<1)
-
-#define IEEE80211_24GHZ_BAND     (1<<0)
-#define IEEE80211_52GHZ_BAND     (1<<1)
-
-#define IEEE80211_CCK_RATE_LEN                 4
-#define IEEE80211_NUM_OFDM_RATESLEN    8
-
-#define IEEE80211_CCK_RATE_1MB                 0x02
-#define IEEE80211_CCK_RATE_2MB                 0x04
-#define IEEE80211_CCK_RATE_5MB                 0x0B
-#define IEEE80211_CCK_RATE_11MB                        0x16
-#define IEEE80211_OFDM_RATE_LEN                        8
-#define IEEE80211_OFDM_RATE_6MB                        0x0C
-#define IEEE80211_OFDM_RATE_9MB                        0x12
-#define IEEE80211_OFDM_RATE_12MB               0x18
-#define IEEE80211_OFDM_RATE_18MB               0x24
-#define IEEE80211_OFDM_RATE_24MB               0x30
-#define IEEE80211_OFDM_RATE_36MB               0x48
-#define IEEE80211_OFDM_RATE_48MB               0x60
-#define IEEE80211_OFDM_RATE_54MB               0x6C
-#define IEEE80211_BASIC_RATE_MASK              0x80
-
-#define IEEE80211_CCK_RATE_1MB_MASK            (1<<0)
-#define IEEE80211_CCK_RATE_2MB_MASK            (1<<1)
-#define IEEE80211_CCK_RATE_5MB_MASK            (1<<2)
-#define IEEE80211_CCK_RATE_11MB_MASK           (1<<3)
-#define IEEE80211_OFDM_RATE_6MB_MASK           (1<<4)
-#define IEEE80211_OFDM_RATE_9MB_MASK           (1<<5)
-#define IEEE80211_OFDM_RATE_12MB_MASK          (1<<6)
-#define IEEE80211_OFDM_RATE_18MB_MASK          (1<<7)
-#define IEEE80211_OFDM_RATE_24MB_MASK          (1<<8)
-#define IEEE80211_OFDM_RATE_36MB_MASK          (1<<9)
-#define IEEE80211_OFDM_RATE_48MB_MASK          (1<<10)
-#define IEEE80211_OFDM_RATE_54MB_MASK          (1<<11)
-
-#define IEEE80211_CCK_RATES_MASK               0x0000000F
-#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
-       IEEE80211_CCK_RATE_2MB_MASK)
-#define IEEE80211_CCK_DEFAULT_RATES_MASK                               \
-       (IEEE80211_CCK_BASIC_RATES_MASK |                               \
-       IEEE80211_CCK_RATE_5MB_MASK |                                   \
-       IEEE80211_CCK_RATE_11MB_MASK)
-
-#define IEEE80211_OFDM_RATES_MASK              0x00000FF0
-#define IEEE80211_OFDM_BASIC_RATES_MASK        (IEEE80211_OFDM_RATE_6MB_MASK | \
-       IEEE80211_OFDM_RATE_12MB_MASK |                                 \
-       IEEE80211_OFDM_RATE_24MB_MASK)
-#define IEEE80211_OFDM_DEFAULT_RATES_MASK                              \
-       (IEEE80211_OFDM_BASIC_RATES_MASK |                              \
-       IEEE80211_OFDM_RATE_9MB_MASK  |                                 \
-       IEEE80211_OFDM_RATE_18MB_MASK |                                 \
-       IEEE80211_OFDM_RATE_36MB_MASK |                                 \
-       IEEE80211_OFDM_RATE_48MB_MASK |                                 \
-       IEEE80211_OFDM_RATE_54MB_MASK)
-#define IEEE80211_DEFAULT_RATES_MASK                                   \
-       (IEEE80211_OFDM_DEFAULT_RATES_MASK |                            \
-        IEEE80211_CCK_DEFAULT_RATES_MASK)
-
-#define IEEE80211_NUM_OFDM_RATES       8
-#define IEEE80211_NUM_CCK_RATES                4
-#define IEEE80211_OFDM_SHIFT_MASK_A    4
-
-/* IEEE 802.11 requires that STA supports concurrent reception of at least
- * three fragmented frames. This define can be increased to support more
- * concurrent frames, but it should be noted that each entry can consume about
- * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
-#define IEEE80211_FRAG_CACHE_LEN 4
-
-#define SEC_KEY_1      (1<<0)
-#define SEC_KEY_2      (1<<1)
-#define SEC_KEY_3      (1<<2)
-#define SEC_KEY_4      (1<<3)
-#define SEC_ACTIVE_KEY  (1<<4)
-#define SEC_AUTH_MODE   (1<<5)
-#define SEC_UNICAST_GROUP (1<<6)
-#define SEC_LEVEL      (1<<7)
-#define SEC_ENABLED     (1<<8)
-
-#define SEC_LEVEL_0      0 /* None */
-#define SEC_LEVEL_1      1 /* WEP 40 and 104 bit */
-#define SEC_LEVEL_2      2 /* Level 1 + TKIP */
-#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
-#define SEC_LEVEL_3      4 /* Level 2 + CCMP */
-
-#define WEP_KEYS 4
-#define WEP_KEY_LEN 13
-
-/*
-
- 802.11 data frame from AP
-
-      ,-------------------------------------------------------------------.
-Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
-      |------|------|---------|---------|---------|------|---------|------|
-Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  frame  |  fcs |
-      |      | tion | (BSSID) |         |       | ence |  data   |      |
-      `-------------------------------------------------------------------'
-
-Total: 28-2340 bytes
-
-*/
-
-#define BEACON_PROBE_SSID_ID_POSITION 12
-
-/* Management Frame Information Element Types */
-#define MFIE_TYPE_SSID         0
-#define MFIE_TYPE_RATES                1
-#define MFIE_TYPE_FH_SET       2
-#define MFIE_TYPE_DS_SET       3
-#define MFIE_TYPE_CF_SET       4
-#define MFIE_TYPE_TIM          5
-#define MFIE_TYPE_IBSS_SET     6
-#define MFIE_TYPE_CHALLENGE    16
-#define MFIE_TYPE_ERP          42
-#define MFIE_TYPE_RSN          48
-#define MFIE_TYPE_RATES_EX     50
-#define MFIE_TYPE_GENERIC      221
-
-/*
- * These are the data types that can make up management packets
- *
-       u16 auth_algorithm;
-       u16 auth_sequence;
-       u16 beacon_interval;
-       u16 capability;
-       u8 current_ap[ETH_ALEN];
-       u16 listen_interval;
-       struct {
-               u16 association_id:14, reserved:2;
-       } __packed;
-       u32 time_stamp[2];
-       u16 reason;
-       u16 status;
-*/
-
-#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
-#define IEEE80211_DEFAULT_BASIC_RATE 10
-
-/* SWEEP TABLE ENTRIES NUMBER*/
-#define MAX_SWEEP_TAB_ENTRIES            42
-#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET  7
-/* MAX_RATES_LENGTH needs to be 12.  The spec says 8, and many APs
- * only use 8, and then use extended rates for the remaining supported
- * rates.  Other APs, however, stick all of their supported rates on the
- * main rates information element... */
-#define MAX_RATES_LENGTH               ((u8)12)
-#define MAX_RATES_EX_LENGTH            ((u8)16)
-#define MAX_NETWORK_COUNT              128
-#define MAX_CHANNEL_NUMBER             161
-#define IEEE80211_SOFTMAC_SCAN_TIME    400
-/* HZ / 2) */
-#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
-
-#define CRC_LENGTH              4U
-
-#define MAX_WPA_IE_LEN (256)
-#define MAX_WPS_IE_LEN (512)
-#define MAX_P2P_IE_LEN (256)
-#define MAX_WFD_IE_LEN (128)
-
-#define NETWORK_EMPTY_ESSID (1<<0)
-#define NETWORK_HAS_OFDM    (1<<1)
-#define NETWORK_HAS_CCK     (1<<2)
-
-#define IEEE80211_DTIM_MBCAST 4
-#define IEEE80211_DTIM_UCAST 2
-#define IEEE80211_DTIM_VALID 1
-#define IEEE80211_DTIM_INVALID 0
-
-#define IEEE80211_PS_DISABLED 0
-#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
-#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
-#define IW_ESSID_MAX_SIZE 32
-/*
-join_res:
--1: authentication fail
--2: association fail
-> 0: TID
-*/
-
-#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
-#define DEFAULT_FTS 2346
-
-static inline int is_multicast_mac_addr(const u8 *addr)
-{
-       return ((addr[0] != 0xff) && (0x01 & addr[0]));
-}
-
-static inline int is_broadcast_mac_addr(const u8 *addr)
-{
-       return (addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
-              (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff);
-}
-
-#define CFG_IEEE80211_RESERVE_FCS (1<<0)
-#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
-
-#define MAXTID 16
-
-/* Action category code */
-enum rtw_ieee80211_category {
-       RTW_WLAN_CATEGORY_P2P = 0x7f,/* P2P action frames */
-};
-
-/* SPECTRUM_MGMT action code */
-enum rtw_ieee80211_spectrum_mgmt_actioncode {
-       RTW_WLAN_ACTION_SPCT_MSR_REQ = 0,
-       RTW_WLAN_ACTION_SPCT_MSR_RPRT = 1,
-       RTW_WLAN_ACTION_SPCT_TPC_REQ = 2,
-       RTW_WLAN_ACTION_SPCT_TPC_RPRT = 3,
-       RTW_WLAN_ACTION_SPCT_CHL_SWITCH = 4,
-       RTW_WLAN_ACTION_SPCT_EXT_CHL_SWITCH = 5,
-};
-
-enum _PUBLIC_ACTION {
-       ACT_PUBLIC_BSSCOEXIST = 0, /*  20/40 BSS Coexistence */
-       ACT_PUBLIC_DSE_ENABLE = 1,
-       ACT_PUBLIC_DSE_DEENABLE = 2,
-       ACT_PUBLIC_DSE_REG_LOCATION = 3,
-       ACT_PUBLIC_EXT_CHL_SWITCH = 4,
-       ACT_PUBLIC_DSE_MSR_REQ = 5,
-       ACT_PUBLIC_DSE_MSR_RPRT = 6,
-       ACT_PUBLIC_MP = 7, /*  Measurement Pilot */
-       ACT_PUBLIC_DSE_PWR_CONSTRAINT = 8,
-       ACT_PUBLIC_VENDOR = 9, /*  for WIFI_DIRECT */
-       ACT_PUBLIC_GAS_INITIAL_REQ = 10,
-       ACT_PUBLIC_GAS_INITIAL_RSP = 11,
-       ACT_PUBLIC_GAS_COMEBACK_REQ = 12,
-       ACT_PUBLIC_GAS_COMEBACK_RSP = 13,
-       ACT_PUBLIC_TDLS_DISCOVERY_RSP = 14,
-       ACT_PUBLIC_LOCATION_TRACK = 15,
-       ACT_PUBLIC_MAX
-};
-
-#define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs)
-                               * 00:50:F2 */
-#define WME_OUI_TYPE 2
-#define WME_OUI_SUBTYPE_INFORMATION_ELEMENT 0
-#define WME_OUI_SUBTYPE_PARAMETER_ELEMENT 1
-#define WME_OUI_SUBTYPE_TSPEC_ELEMENT 2
-#define WME_VERSION 1
-
-#define WME_ACTION_CODE_SETUP_REQUEST 0
-#define WME_ACTION_CODE_SETUP_RESPONSE 1
-#define WME_ACTION_CODE_TEARDOWN 2
-
-#define WME_SETUP_RESPONSE_STATUS_ADMISSION_ACCEPTED 0
-#define WME_SETUP_RESPONSE_STATUS_INVALID_PARAMETERS 1
-#define WME_SETUP_RESPONSE_STATUS_REFUSED 3
-
-#define WME_TSPEC_DIRECTION_UPLINK 0
-#define WME_TSPEC_DIRECTION_DOWNLINK 1
-#define WME_TSPEC_DIRECTION_BI_DIRECTIONAL 3
-
-#define OUI_BROADCOM 0x00904c /* Broadcom (Epigram) */
-
-#define VENDOR_HT_CAPAB_OUI_TYPE 0x33 /* 00-90-4c:0x33 */
-
-/**
- * enum rtw_ieee80211_channel_flags - channel flags
- *
- * Channel flags set by the regulatory control code.
- *
- * @RTW_IEEE80211_CHAN_DISABLED: This channel is disabled.
- * @RTW_IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted
- *      on this channel.
- * @RTW_IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel.
- * @RTW_IEEE80211_CHAN_RADAR: Radar detection is required on this channel.
- * @RTW_IEEE80211_CHAN_NO_HT40PLUS: extension channel above this channel
- *      is not permitted.
- * @RTW_IEEE80211_CHAN_NO_HT40MINUS: extension channel below this channel
- *      is not permitted.
- */
-enum rtw_ieee80211_channel_flags {
-       RTW_IEEE80211_CHAN_DISABLED      = 1<<0,
-       RTW_IEEE80211_CHAN_PASSIVE_SCAN     = 1<<1,
-       RTW_IEEE80211_CHAN_NO_IBSS        = 1<<2,
-       RTW_IEEE80211_CHAN_RADAR            = 1<<3,
-       RTW_IEEE80211_CHAN_NO_HT40PLUS      = 1<<4,
-       RTW_IEEE80211_CHAN_NO_HT40MINUS     = 1<<5,
-};
-
-#define RTW_IEEE80211_CHAN_NO_HT40 \
-         (RTW_IEEE80211_CHAN_NO_HT40PLUS | RTW_IEEE80211_CHAN_NO_HT40MINUS)
-
-/* Represent channel details, subset of ieee80211_channel */
-struct rtw_ieee80211_channel {
-       u16 hw_value;
-       u32 flags;
-};
-
-#define CHAN_FMT \
-       "hw_value:%u, " \
-       "flags:0x%08x" \
-
-#define CHAN_ARG(channel) \
-       (channel)->hw_value \
-       , (channel)->flags \
-
-/* Parsed Information Elements */
-struct rtw_ieee802_11_elems {
-       u8 *ssid;
-       u8 ssid_len;
-       u8 *supp_rates;
-       u8 supp_rates_len;
-       u8 *fh_params;
-       u8 fh_params_len;
-       u8 *ds_params;
-       u8 ds_params_len;
-       u8 *cf_params;
-       u8 cf_params_len;
-       u8 *tim;
-       u8 tim_len;
-       u8 *ibss_params;
-       u8 ibss_params_len;
-       u8 *challenge;
-       u8 challenge_len;
-       u8 *erp_info;
-       u8 erp_info_len;
-       u8 *ext_supp_rates;
-       u8 ext_supp_rates_len;
-       u8 *wpa_ie;
-       u8 wpa_ie_len;
-       u8 *rsn_ie;
-       u8 rsn_ie_len;
-       u8 *wme;
-       u8 wme_len;
-       u8 *wme_tspec;
-       u8 wme_tspec_len;
-       u8 *wps_ie;
-       u8 wps_ie_len;
-       u8 *power_cap;
-       u8 power_cap_len;
-       u8 *supp_channels;
-       u8 supp_channels_len;
-       u8 *mdie;
-       u8 mdie_len;
-       u8 *ftie;
-       u8 ftie_len;
-       u8 *timeout_int;
-       u8 timeout_int_len;
-       u8 *ht_capabilities;
-       u8 ht_capabilities_len;
-       u8 *ht_operation;
-       u8 ht_operation_len;
-       u8 *vendor_ht_cap;
-       u8 vendor_ht_cap_len;
-};
-
-enum parse_res {
-       ParseOK = 0,
-       ParseUnknown = 1,
-       ParseFailed = -1
-};
-
-enum parse_res rtw_ieee802_11_parse_elems(u8 *start, uint len,
-                                         struct rtw_ieee802_11_elems *elems,
-                                         int show_errors);
-
-u8 *rtw_set_fixed_ie(unsigned char *pbuf, unsigned int len,
-                    unsigned char *source, unsigned int *frlen);
-u8 *rtw_set_ie(u8 *pbuf, int index, uint len, u8 *source, uint *frlen);
-u8 *rtw_get_ie(u8 *pbuf, int index, int *len, int limit);
-
-void rtw_set_supported_rate(u8 *SupportedRates, uint mode);
-
-unsigned char *rtw_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit);
-unsigned char *rtw_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len, int limit);
-int rtw_get_wpa_cipher_suite(u8 *s);
-int rtw_get_wpa2_cipher_suite(u8 *s);
-int rtw_get_wapi_ie(u8 *in_ie, uint in_len, u8 *wapi_ie, u16 *wapi_len);
-int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher,
-                    int *pairwise_cipher, int *is_8021x);
-int rtw_parse_wpa2_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher,
-                     int *pairwise_cipher, int *is_8021x);
-
-int rtw_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len,
-                  u8 *wpa_ie, u16 *wpa_len);
-
-u8 rtw_is_wps_ie(u8 *ie_ptr, uint *wps_ielen);
-u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen);
-u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id,
-                    u8 *buf_attr, u32 *len_attr);
-u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id,
-                            u8 *buf_content, uint *len_content);
-
-/**
- * for_each_ie - iterate over continuous IEs
- * @ie:
- * @buf:
- * @buf_len:
- */
-#define for_each_ie(ie, buf, buf_len) \
-       for (ie = (void *)buf; (((u8 *)ie) - ((u8 *)buf) + 1) < buf_len;        \
-               ie = (void *)(((u8 *)ie) + *(((u8 *)ie)+1) + 2))
-
-u8 *rtw_get_p2p_ie(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen);
-u8 *rtw_get_p2p_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id,
-                    u8 *buf_attr, u32 *len_attr);
-u8 *rtw_get_p2p_attr_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id,
-                            u8 *buf_content, uint *len_content);
-u32 rtw_set_p2p_attr_content(u8 *pbuf, u8 attr_id, u16 attr_len,
-                            u8 *pdata_attr);
-void rtw_wlan_bssid_ex_remove_p2p_attr(struct wlan_bssid_ex *bss_ex,
-                                      u8 attr_id);
-uint   rtw_get_rateset_len(u8  *rateset);
-
-struct registry_priv;
-int rtw_generate_ie(struct registry_priv *pregistrypriv);
-
-int rtw_get_bit_value_from_ieee_value(u8 val);
-
-bool   rtw_is_cckrates_included(u8 *rate);
-
-bool   rtw_is_cckratesonly_included(u8 *rate);
-
-int rtw_check_network_type(unsigned char *rate, int ratelen, int channel);
-
-void rtw_get_bcn_info(struct wlan_network *pnetwork);
-
-void rtw_macaddr_cfg(u8 *mac_addr);
-
-u16 rtw_mcs_rate(u8 bw_40MHz, u8 short_GI_20, u8 short_GI_40, unsigned char *MCS_rate);
-
-#endif /* IEEE80211_H */
diff --git a/drivers/staging/r8188eu/include/odm.h b/drivers/staging/r8188eu/include/odm.h
deleted file mode 100644 (file)
index 8cea166..0000000
+++ /dev/null
@@ -1,416 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef        __HALDMOUTSRC_H__
-#define __HALDMOUTSRC_H__
-
-struct rtw_dig {
-       u8              PreIGValue;
-       u8              CurIGValue;
-       u8              BackupIGValue;
-
-       u8              rx_gain_range_max;
-       u8              rx_gain_range_min;
-
-       u8              CurCCK_CCAThres;
-
-       u8              LargeFAHit;
-       u8              ForbiddenIGI;
-       u32             Recover_cnt;
-
-       u8              DIG_Dynamic_MIN_0;
-       bool            bMediaConnect_0;
-
-       u32             AntDiv_RSSI_max;
-       u32             RSSI_max;
-};
-
-struct rtl_ps {
-       u8              pre_rf_state;
-       u8              cur_rf_state;
-       u8              initialize;
-       u32             reg_874;
-       u32             reg_c70;
-       u32             reg_85c;
-       u32             reg_a74;
-
-};
-
-struct false_alarm_stats {
-       u32     Cnt_Parity_Fail;
-       u32     Cnt_Rate_Illegal;
-       u32     Cnt_Crc8_fail;
-       u32     Cnt_Mcs_fail;
-       u32     Cnt_Ofdm_fail;
-       u32     Cnt_Cck_fail;
-       u32     Cnt_all;
-       u32     Cnt_Fast_Fsync;
-       u32     Cnt_SB_Search_fail;
-       u32     Cnt_OFDM_CCA;
-       u32     Cnt_CCK_CCA;
-       u32     Cnt_CCA_all;
-       u32     Cnt_BW_USC;     /* Gary */
-       u32     Cnt_BW_LSC;     /* Gary */
-};
-
-#define ODM_ASSOCIATE_ENTRY_NUM        32 /*  Max size of AsocEntry[]. */
-
-struct sw_ant_switch {
-       u8      CurAntenna;
-       u8      SWAS_NoLink_State; /* Before link Antenna Switch check */
-       u8      RxIdleAnt;
-};
-
-struct edca_turbo {
-       bool bCurrentTurboEDCA;
-       bool bIsCurRDLState;
-       u32     prv_traffic_idx; /*  edca turbo */
-};
-
-struct odm_rate_adapt {
-       u8      HighRSSIThresh; /*  if RSSI > HighRSSIThresh    => RATRState is DM_RATR_STA_HIGH */
-       u8      LowRSSIThresh;  /*  if RSSI <= LowRSSIThresh    => RATRState is DM_RATR_STA_LOW */
-       u8      RATRState;      /*  Current RSSI level, DM_RATR_STA_HIGH/DM_RATR_STA_MIDDLE/DM_RATR_STA_LOW */
-       u32     LastRATR;       /*  RATR Register Content */
-};
-
-#define IQK_MAC_REG_NUM                4
-#define IQK_ADDA_REG_NUM       16
-#define IQK_BB_REG_NUM         9
-#define HP_THERMAL_NUM         8
-
-#define AVG_THERMAL_NUM                8
-
-struct odm_phy_dbg_info {
-       /* ODM Write,debug info */
-       s8      RxSNRdB[MAX_PATH_NUM_92CS];
-       u64     NumQryPhyStatus;
-       /* Others */
-       s32     RxEVM[MAX_PATH_NUM_92CS];
-};
-
-struct odm_per_pkt_info {
-       s8      Rate;
-       u8      StationID;
-       bool    bPacketMatchBSSID;
-       bool    bPacketToSelf;
-       bool    bPacketBeacon;
-};
-
-/*  2011/10/20 MH Define Common info enum for all team. */
-
-enum odm_common_info_def {
-       /*  Fixed value: */
-
-       /* HOOK BEFORE REG INIT----------- */
-       ODM_CMNINFO_MP_TEST_CHIP,
-       /* HOOK BEFORE REG INIT-----------  */
-
-/* CALL BY VALUE------------- */
-       ODM_CMNINFO_RF_ANTENNA_TYPE,            /*  u8 */
-/* CALL BY VALUE-------------*/
-};
-
-enum odm_ability_def {
-       /*  BB ODM section BIT 0-15 */
-       ODM_BB_RSSI_MONITOR             = BIT(4),
-       ODM_BB_ANT_DIV                  = BIT(6),
-       ODM_BB_PWR_TRA                  = BIT(8),
-};
-
-#define ODM_ITRF_USB   0x2
-#define ODM_CE         0x04
-
-/*  ODM_CMNINFO_WM_MODE */
-enum odm_wireless_mode {
-       ODM_WM_UNKNOW   = 0x0,
-       ODM_WM_B        = BIT(0),
-       ODM_WM_G        = BIT(1),
-       ODM_WM_N24G     = BIT(3),
-       ODM_WM_AUTO     = BIT(5),
-};
-
-struct odm_ra_info {
-       u8 RateID;
-       u32 RateMask;
-       u32 RAUseRate;
-       u8 RateSGI;
-       u8 RssiStaRA;
-       u8 PreRssiStaRA;
-       u8 SGIEnable;
-       u8 DecisionRate;
-       u8 PreRate;
-       u8 HighestRate;
-       u8 LowestRate;
-       u32 NscUp;
-       u32 NscDown;
-       u16 RTY[5];
-       u32 TOTAL;
-       u16 DROP;
-       u8 Active;
-       u16 RptTime;
-       u8 RAWaitingCounter;
-       u8 RAPendingCounter;
-       u8 PTActive;    /*  on or off */
-       u8 PTTryState;  /*  0 trying state, 1 for decision state */
-       u8 PTStage;     /*  0~6 */
-       u8 PTStopCount; /* Stop PT counter */
-       u8 PTPreRate;   /*  if rate change do PT */
-       u8 PTPreRssi;   /*  if RSSI change 5% do PT */
-       u8 PTModeSS;    /*  decide whitch rate should do PT */
-       u8 RAstage;     /*  StageRA, decide how many times RA will be done
-                        * between PT */
-       u8 PTSmoothFactor;
-};
-
-struct odm_rf_cal {
-       /* for tx power tracking */
-       u32     RegA24; /*  for TempCCK */
-       s32     RegE94;
-       s32     RegE9C;
-       s32     RegEB4;
-       s32     RegEBC;
-
-       u8      TxPowerTrackControl; /* for mp mode, turn off txpwrtracking
-                                     * as default */
-       u8      TM_Trigger;
-       u8      InternalPA5G[2];        /* pathA / pathB */
-
-       u8      ThermalMeter[2];    /* ThermalMeter, index 0 for RFIC0,
-                                    * and 1 for RFIC1 */
-       u8      ThermalValue;
-       u8      ThermalValue_LCK;
-       u8      ThermalValue_IQK;
-       u8      ThermalValue_DPK;
-       u8      ThermalValue_AVG[AVG_THERMAL_NUM];
-       u8      ThermalValue_AVG_index;
-       u8      ThermalValue_RxGain;
-       u8      ThermalValue_Crystal;
-       u8      ThermalValue_DPKstore;
-       u8      ThermalValue_DPKtrack;
-       bool    TxPowerTrackingInProgress;
-       bool    bDPKenable;
-
-       bool    bReloadtxpowerindex;
-       u8      bRfPiEnable;
-
-       u8      CCK_index;
-       u8      OFDM_index;
-       bool bDoneTxpower;
-
-       u8      ThermalValue_HP[HP_THERMAL_NUM];
-       u8      ThermalValue_HP_index;
-
-       u8      Delta_IQK;
-       u8      Delta_LCK;
-
-       /* for IQK */
-       u32     RegC04;
-       u32     Reg874;
-       u32     RegC08;
-       u32     RegB68;
-       u32     RegB6C;
-       u32     Reg870;
-       u32     Reg860;
-       u32     Reg864;
-
-       bool    bIQKInitialized;
-       bool    bAntennaDetected;
-       u32     ADDA_backup[IQK_ADDA_REG_NUM];
-       u32     IQK_MAC_backup[IQK_MAC_REG_NUM];
-       u32     IQK_BB_backup_recover[9];
-       u32     IQK_BB_backup[IQK_BB_REG_NUM];
-
-       /* for APK */
-       u32     APKoutput[2][2]; /* path A/B; output1_1a/output1_2a */
-       u8      bAPKdone;
-       u8      bAPKThermalMeterIgnore;
-       u8      bDPdone;
-       u8      bDPPathAOK;
-       u8      bDPPathBOK;
-};
-
-/*  ODM Dynamic common info value definition */
-
-struct fast_ant_train {
-       u8      antsel_rx_keep_0;
-       u8      antsel_rx_keep_1;
-       u8      antsel_rx_keep_2;
-       u8      antsel_a[ODM_ASSOCIATE_ENTRY_NUM];
-       u8      antsel_b[ODM_ASSOCIATE_ENTRY_NUM];
-       u8      antsel_c[ODM_ASSOCIATE_ENTRY_NUM];
-       u32     MainAnt_Sum[ODM_ASSOCIATE_ENTRY_NUM];
-       u32     AuxAnt_Sum[ODM_ASSOCIATE_ENTRY_NUM];
-       u32     MainAnt_Cnt[ODM_ASSOCIATE_ENTRY_NUM];
-       u32     AuxAnt_Cnt[ODM_ASSOCIATE_ENTRY_NUM];
-       u8      RxIdleAnt;
-       bool    bBecomeLinked;
-};
-
-enum ant_div_type {
-       NO_ANTDIV                       = 0xFF,
-       CG_TRX_HW_ANTDIV                = 0x01,
-       CGCS_RX_HW_ANTDIV               = 0x02,
-       FIXED_HW_ANTDIV                 = 0x03,
-       CG_TRX_SMART_ANTDIV             = 0x04,
-};
-
-/* Copy from SD4 defined structure. We use to support PHY DM integration. */
-struct odm_dm_struct {
-       struct adapter *Adapter;        /*  For CE/NIC team */
-
-/*  ODM HANDLE, DRIVER NEEDS NOT TO HOOK------ */
-       bool    bCckHighPower;
-       u8      RFPathRxEnable;         /*  ODM_CMNINFO_RFPATH_ENABLE */
-       u8      ControlChannel;
-/*  ODM HANDLE, DRIVER NEEDS NOT TO HOOK------ */
-
-/* 1  COMMON INFORMATION */
-       /*  Init Value */
-/* HOOK BEFORE REG INIT----------- */
-       /*  ODM Support Ability DIG/RATR/TX_PWR_TRACK/ �K�K = 1/2/3/�K */
-       u32     SupportAbility;
-
-       u32     BK_SupportAbility;
-       u8      AntDivType;
-/* HOOK BEFORE REG INIT----------- */
-
-       /*  Dynamic Value */
-/*  POINTER REFERENCE----------- */
-       /*  Wireless mode B/G/A/N = BIT(0)/BIT(1)/BIT(2)/BIT(3) */
-       u8      *pWirelessMode; /* ODM_WIRELESS_MODE_E */
-       /*  Secondary channel offset don't_care/below/above = 0/1/2 */
-       u8      *pSecChOffset;
-       /*  BW info 20M/40M/80M = 0/1/2 */
-       enum ht_channel_width *pBandWidth;
-       /*  Central channel location Ch1/Ch2/.... */
-       u8      *pChannel;      /* central channel number */
-
-       /*  Common info for Status */
-       bool    *pbScanInProcess;
-       bool    *pbPowerSaving;
-/*  POINTER REFERENCE----------- */
-       /*  */
-/* CALL BY VALUE------------- */
-       bool    bLinked;
-       u8      RSSI_Min;
-       bool    bIsMPChip;
-       bool    bOneEntryOnly;
-/* CALL BY VALUE------------- */
-
-       /* 2 Define STA info. */
-       /*  _ODM_STA_INFO */
-       /*  For MP, we need to reduce one array pointer for default port.?? */
-       struct sta_info *pODM_StaInfo[ODM_ASSOCIATE_ENTRY_NUM];
-
-       u16     CurrminRptTime;
-       struct odm_ra_info RAInfo[ODM_ASSOCIATE_ENTRY_NUM]; /* Use MacID as
-                       * array index. STA MacID=0,
-                       * VWiFi Client MacID={1, ODM_ASSOCIATE_ENTRY_NUM-1} */
-
-       /*  Latest packet phy info (ODM write) */
-       struct odm_phy_dbg_info PhyDbgInfo;
-
-       /* ODM Structure */
-       struct fast_ant_train DM_FatTable;
-       struct rtw_dig  DM_DigTable;
-       struct rtl_ps   DM_PSTable;
-       struct false_alarm_stats FalseAlmCnt;
-       struct sw_ant_switch DM_SWAT_Table;
-
-       struct edca_turbo DM_EDCA_Table;
-
-       /* PSD */
-       bool    bDMInitialGainEnable;
-
-       struct odm_rate_adapt RateAdaptive;
-
-       struct odm_rf_cal RFCalibrateInfo;
-
-       /*  TX power tracking */
-       u8      BbSwingIdxOfdm;
-       u8      BbSwingIdxOfdmCurrent;
-       u8      BbSwingIdxOfdmBase;
-       bool    BbSwingFlagOfdm;
-       u8      BbSwingIdxCck;
-       u8      BbSwingIdxCckCurrent;
-       u8      BbSwingIdxCckBase;
-       bool    BbSwingFlagCck;
-};
-
-enum odm_bb_config_type {
-    CONFIG_BB_PHY_REG,
-    CONFIG_BB_AGC_TAB,
-    CONFIG_BB_AGC_TAB_2G,
-    CONFIG_BB_PHY_REG_PG,
-};
-
-#define                DM_DIG_MAX_NIC                  0x4e
-#define                DM_DIG_MIN_NIC                  0x1e /* 0x22/0x1c */
-
-#define                DM_DIG_MAX_AP                   0x32
-
-/* vivi 92c&92d has different definition, 20110504 */
-/* this is for 92c */
-#define                DM_DIG_FA_TH0                   0x200/* 0x20 */
-#define                DM_DIG_FA_TH1                   0x300/* 0x100 */
-#define                DM_DIG_FA_TH2                   0x400/* 0x200 */
-
-/* 3=========================================================== */
-/* 3 Rate Adaptive */
-/* 3=========================================================== */
-#define                DM_RATR_STA_INIT                0
-#define                DM_RATR_STA_HIGH                1
-#define                DM_RATR_STA_MIDDLE              2
-#define                DM_RATR_STA_LOW                 3
-
-/* 3=========================================================== */
-/* 3 BB Power Save */
-/* 3=========================================================== */
-
-enum dm_rf {
-       RF_Save = 0,
-       RF_Normal = 1,
-       RF_MAX = 2,
-};
-
-/* 3=========================================================== */
-/* 3 Antenna Diversity */
-/* 3=========================================================== */
-enum dm_swas {
-       Antenna_A = 1,
-       Antenna_B = 2,
-       Antenna_MAX = 3,
-};
-
-/*  Extern Global Variables. */
-#define        OFDM_TABLE_SIZE_92D     43
-#define        CCK_TABLE_SIZE          33
-
-extern u32 OFDMSwingTable[OFDM_TABLE_SIZE_92D];
-extern u8 cck_swing_table[CCK_TABLE_SIZE][8];
-
-/*  check Sta pointer valid or not */
-#define IS_STA_VALID(pSta)             (pSta)
-
-void ODM_Write_DIG(struct odm_dm_struct *pDM_Odm, u8 CurrentIGI);
-void ODM_Write_CCK_CCA_Thres(struct odm_dm_struct *pDM_Odm, u8 CurCCK_CCAThres);
-
-void ODM_RF_Saving(struct odm_dm_struct *pDM_Odm, u8 bForceInNormal);
-
-void ODM_TXPowerTrackingCheck(struct odm_dm_struct *pDM_Odm);
-
-bool ODM_RAStateCheck(struct odm_dm_struct *pDM_Odm, s32 RSSI,
-                     bool bForceUpdate, u8 *pRATRState);
-
-u32 ODM_Get_Rate_Bitmap(struct odm_dm_struct *pDM_Odm, u32 macid,
-                       u32 ra_mask, u8 rssi_level);
-
-void ODM_DMInit(struct odm_dm_struct *pDM_Odm);
-
-void ODM_DMWatchdog(struct odm_dm_struct *pDM_Odm);
-
-void ODM_CmnInfoInit(struct odm_dm_struct *pDM_Odm,
-                    enum odm_common_info_def CmnInfo, u32 Value);
-
-#endif
diff --git a/drivers/staging/r8188eu/include/odm_HWConfig.h b/drivers/staging/r8188eu/include/odm_HWConfig.h
deleted file mode 100644 (file)
index 3f71857..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef        __HALHWOUTSRC_H__
-#define __HALHWOUTSRC_H__
-
-/*  CCK Rates, TxHT = 0 */
-#define DESC92C_RATE1M                         0x00
-#define DESC92C_RATE11M                                0x03
-
-/*  MCS Rates, TxHT = 1 */
-#define DESC92C_RATEMCS8                       0x14
-#define DESC92C_RATEMCS15                      0x1b
-
-/*  structure and define */
-
-struct phy_rx_agc_info {
-       #ifdef __LITTLE_ENDIAN
-               u8      gain:7, trsw:1;
-       #else
-               u8      trsw:1, gain:7;
-       #endif
-};
-
-struct phy_status_rpt {
-       struct phy_rx_agc_info path_agc[3];
-       u8      ch_corr[2];
-       u8      cck_sig_qual_ofdm_pwdb_all;
-       u8      cck_agc_rpt_ofdm_cfosho_a;
-       u8      cck_rpt_b_ofdm_cfosho_b;
-       u8      rsvd_1;/* ch_corr_msb; */
-       u8      noise_power_db_msb;
-       u8      path_cfotail[2];
-       u8      pcts_mask[2];
-       s8      stream_rxevm[2];
-       u8      path_rxsnr[3];
-       u8      noise_power_db_lsb;
-       u8      rsvd_2[3];
-       u8      stream_csi[2];
-       u8      stream_target_csi[2];
-       s8      sig_evm;
-       u8      rsvd_3;
-
-#ifdef __LITTLE_ENDIAN
-       u8      antsel_rx_keep_2:1;     /* ex_intf_flg:1; */
-       u8      sgi_en:1;
-       u8      rxsc:2;
-       u8      idle_long:1;
-       u8      r_ant_train_en:1;
-       u8      ant_sel_b:1;
-       u8      ant_sel:1;
-#else  /*  _BIG_ENDIAN_ */
-       u8      ant_sel:1;
-       u8      ant_sel_b:1;
-       u8      r_ant_train_en:1;
-       u8      idle_long:1;
-       u8      rxsc:2;
-       u8      sgi_en:1;
-       u8      antsel_rx_keep_2:1;     /* ex_intf_flg:1; */
-#endif
-};
-
-void ODM_PhyStatusQuery(struct odm_dm_struct *pDM_Odm,
-                       struct phy_info *pPhyInfo,
-                       u8 *pPhyStatus,
-                       struct odm_per_pkt_info *pPktinfo,
-                       struct adapter *adapt);
-
-#endif
diff --git a/drivers/staging/r8188eu/include/odm_RTL8188E.h b/drivers/staging/r8188eu/include/odm_RTL8188E.h
deleted file mode 100644 (file)
index 4f16af2..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef        __ODM_RTL8188E_H__
-#define __ODM_RTL8188E_H__
-
-#define        MAIN_ANT        0
-#define        AUX_ANT 1
-#define        MAIN_ANT_CG_TRX 1
-#define        AUX_ANT_CG_TRX  0
-#define        MAIN_ANT_CGCS_RX        0
-#define        AUX_ANT_CGCS_RX 1
-
-#define SET_TX_DESC_ANTSEL_A_88E(__ptxdesc, __value)                   \
-       le32p_replace_bits((__le32 *)(__ptxdesc + 8), __value, BIT(24))
-#define SET_TX_DESC_ANTSEL_B_88E(__ptxdesc, __value)                   \
-       le32p_replace_bits((__le32 *)(__ptxdesc + 8), __value, BIT(25))
-#define SET_TX_DESC_ANTSEL_C_88E(__ptxdesc, __value)                   \
-       le32p_replace_bits((__le32 *)(__ptxdesc + 28), __value, BIT(29))
-
-void ODM_AntennaDiversityInit_88E(struct odm_dm_struct *pDM_Odm);
-
-void ODM_AntennaDiversity_88E(struct odm_dm_struct *pDM_Odm);
-
-void ODM_SetTxAntByTxInfo_88E(struct odm_dm_struct *pDM_Odm, u8 *pDesc,
-                             u8 macId);
-
-void ODM_UpdateRxIdleAnt_88E(struct odm_dm_struct *pDM_Odm, u8 Ant);
-
-void ODM_AntselStatistics_88E(struct odm_dm_struct *pDM_Odm, u8        antsel_tr_mux,
-                             u32 MacId, u8 RxPWDBAll);
-
-void odm_FastAntTraining(struct odm_dm_struct *pDM_Odm);
-
-#endif
diff --git a/drivers/staging/r8188eu/include/odm_RegDefine11N.h b/drivers/staging/r8188eu/include/odm_RegDefine11N.h
deleted file mode 100644 (file)
index 82a602b..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef        __ODM_REGDEFINE11N_H__
-#define __ODM_REGDEFINE11N_H__
-
-/* 2 BB REG LIST */
-/* PAGE 8 */
-#define        ODM_REG_TX_ANT_CTRL_11N                 0x80C
-#define        ODM_REG_RX_DEFUALT_A_11N                0x858
-#define        ODM_REG_ANTSEL_CTRL_11N                 0x860
-#define        ODM_REG_RX_ANT_CTRL_11N                 0x864
-#define        ODM_REG_PIN_CTRL_11N                    0x870
-#define        ODM_REG_SC_CNT_11N                      0x8C4
-/* PAGE 9 */
-#define        ODM_REG_ANT_MAPPING1_11N                0x914
-/* PAGE A */
-#define        ODM_REG_CCK_ANTDIV_PARA1_11N            0xA00
-#define        ODM_REG_CCK_CCA_11N                     0xA0A
-#define        ODM_REG_CCK_ANTDIV_PARA2_11N            0xA0C
-#define        ODM_REG_CCK_FA_RST_11N                  0xA2C
-#define        ODM_REG_CCK_FA_MSB_11N                  0xA58
-#define        ODM_REG_CCK_FA_LSB_11N                  0xA5C
-#define        ODM_REG_CCK_CCA_CNT_11N                 0xA60
-#define        ODM_REG_BB_PWR_SAV4_11N                 0xA74
-/* PAGE B */
-#define        ODM_REG_LNA_SWITCH_11N                  0xB2C
-/* PAGE C */
-#define        ODM_REG_OFDM_FA_HOLDC_11N               0xC00
-#define        ODM_REG_OFDM_FA_RSTC_11N                0xC0C
-#define        ODM_REG_IGI_A_11N                       0xC50
-#define        ODM_REG_ANTDIV_PARA1_11N                0xCA4
-#define        ODM_REG_OFDM_FA_TYPE1_11N               0xCF0
-/* PAGE D */
-#define        ODM_REG_OFDM_FA_RSTD_11N                0xD00
-#define        ODM_REG_OFDM_FA_TYPE2_11N               0xDA0
-#define        ODM_REG_OFDM_FA_TYPE3_11N               0xDA4
-#define        ODM_REG_OFDM_FA_TYPE4_11N               0xDA8
-
-/* 2 MAC REG LIST */
-#define        ODM_REG_ANTSEL_PIN_11N                  0x4C
-#define        ODM_REG_RESP_TX_11N                     0x6D8
-
-/* DIG Related */
-#define        ODM_BIT_IGI_11N                         0x0000007F
-
-#endif
diff --git a/drivers/staging/r8188eu/include/osdep_intf.h b/drivers/staging/r8188eu/include/osdep_intf.h
deleted file mode 100644 (file)
index 457fb38..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __OSDEP_INTF_H_
-#define __OSDEP_INTF_H_
-
-#include "osdep_service.h"
-#include "drv_types.h"
-
-int netdev_open(struct net_device *pnetdev);
-int netdev_close(struct net_device *pnetdev);
-
-u8 rtw_init_drv_sw(struct adapter *padapter);
-void rtw_free_drv_sw(struct adapter *padapter);
-void rtw_reset_drv_sw(struct adapter *padapter);
-
-int rtw_start_drv_threads(struct adapter *padapter);
-void rtw_stop_drv_threads (struct adapter *padapter);
-void rtw_cancel_all_timer(struct adapter *padapter);
-
-int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname);
-struct net_device *rtw_init_netdev(struct adapter *padapter);
-u16 rtw_recv_select_queue(struct sk_buff *skb);
-
-void rtw_ips_dev_unload(struct adapter *padapter);
-
-int rtw_ips_pwr_up(struct adapter *padapter);
-void rtw_ips_pwr_down(struct adapter *padapter);
-
-#endif /* _OSDEP_INTF_H_ */
diff --git a/drivers/staging/r8188eu/include/osdep_service.h b/drivers/staging/r8188eu/include/osdep_service.h
deleted file mode 100644 (file)
index f8ed04f..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __OSDEP_SERVICE_H_
-#define __OSDEP_SERVICE_H_
-
-#include <linux/sched/signal.h>
-
-#define _FAIL          0
-#define _SUCCESS       1
-#define RTW_RX_HANDLED 2
-
-#include <linux/spinlock.h>
-#include <linux/compiler.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/kref.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <linux/circ_buf.h>
-#include <linux/uaccess.h>
-#include <asm/byteorder.h>
-#include <asm/atomic.h>
-#include <linux/io.h>
-#include <linux/semaphore.h>
-#include <linux/sem.h>
-#include <linux/sched.h>
-#include <linux/etherdevice.h>
-#include <linux/wireless.h>
-#include <net/iw_handler.h>
-#include <linux/if_arp.h>
-#include <linux/rtnetlink.h>
-#include <linux/delay.h>
-#include <linux/proc_fs.h>     /*  Necessary because we use the proc fs */
-#include <linux/interrupt.h>   /*  for struct tasklet_struct */
-#include <linux/ip.h>
-#include <linux/kthread.h>
-#include <linux/vmalloc.h>
-
-#include <linux/usb.h>
-#include <linux/usb/ch9.h>
-
-struct __queue {
-       struct  list_head       queue;
-       spinlock_t lock;
-};
-
-static inline struct list_head *get_list_head(struct __queue *queue)
-{
-       return (&(queue->queue));
-}
-
-static inline void _set_timer(struct timer_list *ptimer, u32 delay_time)
-{
-       mod_timer(ptimer, jiffies + msecs_to_jiffies(delay_time));
-}
-
-static inline int rtw_netif_queue_stopped(struct net_device *pnetdev)
-{
-       return  netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 0)) &&
-               netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 1)) &&
-               netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 2)) &&
-               netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 3));
-}
-
-int RTW_STATUS_CODE(int error_code);
-
-void *rtw_malloc2d(int h, int w, int size);
-
-#define rtw_init_queue(q)                                      \
-       do {                                                    \
-               INIT_LIST_HEAD(&((q)->queue));                  \
-               spin_lock_init(&((q)->lock));                   \
-       } while (0)
-
-static inline unsigned char _cancel_timer_ex(struct timer_list *ptimer)
-{
-       return del_timer_sync(ptimer);
-}
-
-static inline void flush_signals_thread(void)
-{
-       if (signal_pending (current))
-               flush_signals(current);
-}
-
-struct rtw_netdev_priv_indicator {
-       void *priv;
-       u32 sizeof_priv;
-};
-struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv,
-                                                   void *old_priv);
-struct net_device *rtw_alloc_etherdev(int sizeof_priv);
-
-#define rtw_netdev_priv(netdev)                                        \
-       (((struct rtw_netdev_priv_indicator *)netdev_priv(netdev))->priv)
-void rtw_free_netdev(struct net_device *netdev);
-
-#define NDEV_FMT "%s"
-#define NDEV_ARG(ndev) ndev->name
-#define ADPT_FMT "%s"
-#define ADPT_ARG(adapter) adapter->pnetdev->name
-#define FUNC_NDEV_FMT "%s(%s)"
-#define FUNC_NDEV_ARG(ndev) __func__, ndev->name
-#define FUNC_ADPT_FMT "%s(%s)"
-#define FUNC_ADPT_ARG(adapter) __func__, adapter->pnetdev->name
-
-#define rtw_signal_process(pid, sig) kill_pid(find_vpid((pid)), (sig), 1)
-
-/* Macros for handling unaligned memory accesses */
-
-#define RTW_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1]))
-#define RTW_PUT_BE16(a, val)                   \
-       do {                                    \
-               (a)[0] = ((u16) (val)) >> 8;    \
-               (a)[1] = ((u16) (val)) & 0xff;  \
-       } while (0)
-
-#define RTW_PUT_LE16(a, val)                   \
-       do {                                    \
-               (a)[1] = ((u16) (val)) >> 8;    \
-               (a)[0] = ((u16) (val)) & 0xff;  \
-       } while (0)
-
-#define RTW_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \
-                        ((u32) (a)[2]))
-
-#define RTW_PUT_BE32(a, val)                                   \
-       do {                                                    \
-               (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff);   \
-               (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff);   \
-               (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff);    \
-               (a)[3] = (u8) (((u32) (val)) & 0xff);           \
-       } while (0)
-
-void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len);
-
-struct rtw_cbuf {
-       u32 write;
-       u32 read;
-       u32 size;
-       void *bufs[];
-};
-
-bool rtw_cbuf_empty(struct rtw_cbuf *cbuf);
-void *rtw_cbuf_pop(struct rtw_cbuf *cbuf);
-struct rtw_cbuf *rtw_cbuf_alloc(u32 size);
-int wifirate2_ratetbl_inx(unsigned char rate);
-
-#endif
diff --git a/drivers/staging/r8188eu/include/rtl8188e_cmd.h b/drivers/staging/r8188eu/include/rtl8188e_cmd.h
deleted file mode 100644 (file)
index c785cf8..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __RTL8188E_CMD_H__
-#define __RTL8188E_CMD_H__
-
-enum RTL8188E_H2C_CMD_ID {
-       /* Class Common */
-       H2C_COM_RSVD_PAGE               = 0x00,
-       H2C_COM_MEDIA_STATUS_RPT        = 0x01,
-       H2C_COM_SCAN                    = 0x02,
-       H2C_COM_KEEP_ALIVE              = 0x03,
-       H2C_COM_DISCNT_DECISION         = 0x04,
-       H2C_COM_INIT_OFFLOAD            = 0x06,
-       H2C_COM_REMOTE_WAKE_CTL         = 0x07,
-       H2C_COM_AP_OFFLOAD              = 0x08,
-       H2C_COM_BCN_RSVD_PAGE           = 0x09,
-       H2C_COM_PROB_RSP_RSVD_PAGE      = 0x0A,
-
-       /* Class PS */
-       H2C_PS_PWR_MODE                 = 0x20,
-       H2C_PS_TUNE_PARA                = 0x21,
-       H2C_PS_TUNE_PARA_2              = 0x22,
-       H2C_PS_LPS_PARA                 = 0x23,
-       H2C_PS_P2P_OFFLOAD              = 0x24,
-
-       /* Class DM */
-       H2C_DM_MACID_CFG                = 0x40,
-       H2C_DM_TXBF                     = 0x41,
-};
-
-struct cmd_msg_parm {
-       u8 eid; /* element id */
-       u8 sz; /*  sz */
-       u8 buf[6];
-};
-
-struct setpwrmode_parm {
-       u8 Mode;/* 0:Active,1:LPS,2:WMMPS */
-       u8 SmartPS_RLBM;/* LPS= 0:PS_Poll,1:PS_Poll,2:NullData,WMM= 0:PS_Poll,1:NullData */
-       u8 AwakeInterval;       /*  unit: beacon interval */
-       u8 bAllQueueUAPSD;
-       u8 PwrState;/* AllON(0x0c),RFON(0x04),RFOFF(0x00) */
-};
-
-struct H2C_SS_RFOFF_PARAM {
-       u8 ROFOn; /*  1: on, 0:off */
-       u16 gpio_period; /*  unit: 1024 us */
-} __packed;
-
-struct joinbssrpt_parm {
-       u8 OpMode;      /*  RT_MEDIA_STATUS */
-};
-
-struct rsvdpage_loc {
-       u8 LocProbeRsp;
-       u8 LocPsPoll;
-       u8 LocNullData;
-       u8 LocQosNull;
-       u8 LocBTQosNull;
-};
-
-struct P2P_PS_Offload_t {
-       u8 Offload_En:1;
-       u8 role:1; /*  1: Owner, 0: Client */
-       u8 CTWindow_En:1;
-       u8 NoA0_En:1;
-       u8 NoA1_En:1;
-       u8 AllStaSleep:1; /*  Only valid in Owner */
-       u8 discovery:1;
-       u8 rsvd:1;
-};
-
-struct P2P_PS_CTWPeriod_t {
-       u8 CTWPeriod;   /* TU */
-};
-
-/*  host message to firmware cmd */
-void rtl8188e_set_FwPwrMode_cmd(struct adapter *padapter, u8 Mode);
-void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *padapter, u8 mstatus);
-u8 rtl8188e_set_raid_cmd(struct adapter *padapter, u32 mask);
-void rtl8188e_Add_RateATid(struct adapter *padapter, u32 bitmap, u8 arg,
-                          u8 rssi_level);
-
-void rtl8188e_set_p2p_ps_offload_cmd(struct adapter *adapt, u8 p2p_ps_state);
-
-void CheckFwRsvdPageContent(struct adapter *adapt);
-void rtl8188e_set_FwMediaStatus_cmd(struct adapter *adapt, u16 mstatus_rpt);
-
-#endif/* __RTL8188E_CMD_H__ */
diff --git a/drivers/staging/r8188eu/include/rtl8188e_dm.h b/drivers/staging/r8188eu/include/rtl8188e_dm.h
deleted file mode 100644 (file)
index d62cdfc..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __RTL8188E_DM_H__
-#define __RTL8188E_DM_H__
-
-enum{
-       UP_LINK,
-       DOWN_LINK,
-};
-
-struct dm_priv {
-       u32     InitODMFlag;
-
-       /* Lower Signal threshold for Rate Adaptive */
-       int     EntryMinUndecoratedSmoothedPWDB;
-       int     MinUndecoratedPWDBForDM;
-};
-
-void rtl8188e_init_dm_priv(struct adapter *adapt);
-void rtl8188e_InitHalDm(struct adapter *adapt);
-void rtl8188e_HalDmWatchDog(struct adapter *adapt);
-
-void AntDivCompare8188E(struct adapter *adapt, struct wlan_bssid_ex *dst,
-                       struct wlan_bssid_ex *src);
-u8 AntDivBeforeLink8188E(struct adapter *adapt);
-
-#endif
diff --git a/drivers/staging/r8188eu/include/rtl8188e_hal.h b/drivers/staging/r8188eu/include/rtl8188e_hal.h
deleted file mode 100644 (file)
index feeb37c..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __RTL8188E_HAL_H__
-#define __RTL8188E_HAL_H__
-
-/* include HAL Related header after HAL Related compiling flags */
-#include "rtl8188e_spec.h"
-#include "Hal8188EPhyReg.h"
-#include "Hal8188EPhyCfg.h"
-#include "rtl8188e_rf.h"
-#include "rtl8188e_dm.h"
-#include "rtl8188e_recv.h"
-#include "rtl8188e_xmit.h"
-#include "rtl8188e_cmd.h"
-#include "rtw_efuse.h"
-#include "odm.h"
-#include "odm_HWConfig.h"
-#include "odm_RegDefine11N.h"
-#include "HalPhyRf_8188e.h"
-#include "Hal8188ERateAdaptive.h"
-#include "HalHWImg8188E_MAC.h"
-#include "HalHWImg8188E_RF.h"
-#include "HalHWImg8188E_BB.h"
-#include "odm_RTL8188E.h"
-
-#define DRVINFO_SZ     4 /*  unit is 8bytes */
-#define PageNum_128(_Len)      (u32)(((_Len)>>7) + ((_Len) & 0x7F ? 1 : 0))
-
-#define DRIVER_EARLY_INT_TIME          0x05
-#define BCN_DMA_ATIME_INT_TIME         0x02
-
-#define MAX_RX_DMA_BUFFER_SIZE_88E                             \
-      0x2400 /* 9k for 88E nornal chip , MaxRxBuff=10k-max(TxReportSize(64*8),
-             * WOLPattern(16*24)) */
-
-#define TX_SELE_LQ                     BIT(1)          /*  Low Queue */
-#define TX_SELE_NQ                     BIT(2)          /*  Normal Queue */
-
-/*  Note: We will divide number of page equally for each queue other
- *  than public queue! */
-/*  22k = 22528 bytes = 176 pages (@page =  128 bytes) */
-/*  must reserved about 7 pages for LPS =>  176-7 = 169 (0xA9) */
-/*  2*BCN / 1*ps-poll / 1*null-data /1*prob_rsp /1*QOS null-data /1*BT QOS
- *  null-data */
-
-#define TX_TOTAL_PAGE_NUMBER_88E               0xA9/*   169 (21632=> 21k) */
-
-#define TX_PAGE_BOUNDARY_88E (TX_TOTAL_PAGE_NUMBER_88E + 1)
-
-#include "HalVerDef.h"
-#include "hal_com.h"
-
-/*     Channel Plan */
-enum ChannelPlan {
-       CHPL_FCC        = 0,
-       CHPL_IC         = 1,
-       CHPL_ETSI       = 2,
-       CHPL_SPA        = 3,
-       CHPL_FRANCE     = 4,
-       CHPL_MKK        = 5,
-       CHPL_MKK1       = 6,
-       CHPL_ISRAEL     = 7,
-       CHPL_TELEC      = 8,
-       CHPL_GLOBAL     = 9,
-       CHPL_WORLD      = 10,
-};
-
-struct txpowerinfo24g {
-       u8 IndexCCK_Base[RF_PATH_MAX][MAX_CHNL_GROUP_24G];
-       u8 IndexBW40_Base[RF_PATH_MAX][MAX_CHNL_GROUP_24G];
-       /* If only one tx, only BW20 and OFDM are used. */
-       s8 CCK_Diff[RF_PATH_MAX][MAX_TX_COUNT];
-       s8 OFDM_Diff[RF_PATH_MAX][MAX_TX_COUNT];
-       s8 BW20_Diff[RF_PATH_MAX][MAX_TX_COUNT];
-       s8 BW40_Diff[RF_PATH_MAX][MAX_TX_COUNT];
-};
-
-#define EFUSE_REAL_CONTENT_LEN         512
-#define AVAILABLE_EFUSE_ADDR(addr)     (addr < EFUSE_REAL_CONTENT_LEN)
-
-#define                EFUSE_REAL_CONTENT_LEN_88E      256
-#define                EFUSE_MAP_LEN_88E               512
-#define                EFUSE_MAX_SECTION_88E           64
-/*  To prevent out of boundary programming case, leave 1byte and program
- *  full section */
-/*  9bytes + 1byt + 5bytes and pre 1byte. */
-/*  For worst case: */
-/*  | 2byte|----8bytes----|1byte|--7bytes--| 92D */
-/*  PG data exclude header, dummy 7 bytes from CP test and reserved 1byte. */
-#define                EFUSE_OOB_PROTECT_BYTES_88E     18
-
-#define EFUSE_PROTECT_BYTES_BANK       16
-
-#define USB_RXAGG_PAGE_COUNT   48
-#define USB_RXAGG_PAGE_TIMEOUT 0x4
-
-struct hal_data_8188e {
-       struct HAL_VERSION      VersionID;
-       /* current WIFI_PHY values */
-       enum ht_channel_width CurrentChannelBW;
-       u8      CurrentChannel;
-       u8      nCur40MhzPrimeSC;/*  Control channel sub-carrier */
-
-       u8      EEPROMRegulatory;
-       u8      EEPROMThermalMeter;
-
-       u8      Index24G_CCK_Base[CHANNEL_MAX_NUMBER];
-       u8      Index24G_BW40_Base[CHANNEL_MAX_NUMBER];
-       /* If only one tx, only BW20 and OFDM are used. */
-       s8      OFDM_24G_Diff[MAX_TX_COUNT];
-       s8      BW20_24G_Diff[MAX_TX_COUNT];
-
-       /*  HT 20<->40 Pwr diff */
-       u8      TxPwrHt20Diff[RF_PATH_MAX][CHANNEL_MAX_NUMBER];
-       /*  For HT<->legacy pwr diff */
-       u8      TxPwrLegacyHtDiff[RF_PATH_MAX][CHANNEL_MAX_NUMBER];
-       /*  For power group */
-       u8      PwrGroupHT20[RF_PATH_MAX][CHANNEL_MAX_NUMBER];
-       u8      PwrGroupHT40[RF_PATH_MAX][CHANNEL_MAX_NUMBER];
-
-       /*  Read/write are allow for following hardware information variables */
-       u8      pwrGroupCnt;
-       u32     MCSTxPowerLevelOriginalOffset[MAX_PG_GROUP][16];
-
-       u8      CrystalCap;
-
-       u32     AcParam_BE; /* Original parameter for BE, use for EDCA turbo. */
-
-       struct bb_reg_def PHYRegDef;
-
-       u32     RfRegChnlVal;
-
-       /* for host message to fw */
-       u8      LastHMEBoxNum;
-
-       u8      fw_ractrl;
-       u8      RegFwHwTxQCtrl;
-       u8      RegReg542;
-       u8      RegCR_1;
-
-       struct dm_priv  dmpriv;
-       struct odm_dm_struct odmpriv;
-
-       u8      CurAntenna;
-       u8      AntDivCfg;
-       u8      TRxAntDivType;
-
-       u8      out_ep_extra_queues;
-
-       struct P2P_PS_Offload_t p2p_ps_offload;
-
-       /*  Auto FSM to Turn On, include clock, isolation, power control
-        *  for MAC only */
-       u8      bMacPwrCtrlOn;
-};
-
-s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy);
-
-/*  EFuse */
-void Hal_EfuseParseIDCode88E(struct adapter *padapter, u8 *hwinfo);
-void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *hwinfo,
-                           bool AutoLoadFail);
-
-void rtl8188e_EfuseParseChnlPlan(struct adapter *padapter, u8 *hwinfo,
-                                bool AutoLoadFail);
-void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter, u8 *PROMContent,
-                                bool AutoLoadFail);
-void Hal_ReadThermalMeter_88E(struct adapter *padapter, u8 *PROMContent,
-                             bool AutoloadFail);
-void Hal_EfuseParseXtal_8188E(struct adapter *pAdapter, u8 *hwinfo,
-                             bool AutoLoadFail);
-void Hal_ReadPowerSavingMode88E(struct adapter *pAdapter, u8 *hwinfo,
-                               bool AutoLoadFail);
-
-void rtl8188e_read_chip_version(struct adapter *padapter);
-
-s32 rtl8188e_iol_efuse_patch(struct adapter *padapter);
-void rtw_cancel_all_timer(struct adapter *padapter);
-
-#endif /* __RTL8188E_HAL_H__ */
diff --git a/drivers/staging/r8188eu/include/rtl8188e_recv.h b/drivers/staging/r8188eu/include/rtl8188e_recv.h
deleted file mode 100644 (file)
index dc4f358..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __RTL8188E_RECV_H__
-#define __RTL8188E_RECV_H__
-
-#define TX_RPT1_PKT_LEN 8
-
-#define NR_PREALLOC_RECV_SKB (8)
-
-#define NR_RECVBUFF (4)
-
-#define MAX_RECVBUF_SZ (15360) /*  15k < 16k */
-
-struct phy_stat {
-       unsigned int phydw0;
-       unsigned int phydw1;
-       unsigned int phydw2;
-       unsigned int phydw3;
-       unsigned int phydw4;
-       unsigned int phydw5;
-       unsigned int phydw6;
-       unsigned int phydw7;
-};
-
-/*  Rx smooth factor */
-#define        Rx_Smooth_Factor (20)
-
-enum rx_packet_type {
-       NORMAL_RX,/* Normal rx packet */
-       TX_REPORT1,/* CCX */
-       TX_REPORT2,/* TX RPT */
-       HIS_REPORT,/*  USB HISR RPT */
-};
-
-void rtl8188eu_recv_tasklet(unsigned long priv);
-void update_recvframe_phyinfo_88e(struct recv_frame *fra, struct phy_stat *phy);
-void update_recvframe_attrib_88e(struct recv_frame *fra, struct recv_stat *stat);
-
-#endif
diff --git a/drivers/staging/r8188eu/include/rtl8188e_rf.h b/drivers/staging/r8188eu/include/rtl8188e_rf.h
deleted file mode 100644 (file)
index 63ac0ac..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __RTL8188E_RF_H__
-#define __RTL8188E_RF_H__
-
-#define                RF6052_MAX_TX_PWR               0x3F
-#define                RF6052_MAX_REG                  0x3F
-#define                RF6052_MAX_PATH                 2
-
-int phy_RF6052_Config_ParaFile(struct adapter *Adapter);
-void rtl8188e_PHY_RF6052SetBandwidth(struct adapter *Adapter,
-                                    enum ht_channel_width Bandwidth);
-void   rtl8188e_PHY_RF6052SetCckTxPower(struct adapter *Adapter, u8 *level);
-void   rtl8188e_PHY_RF6052SetOFDMTxPower(struct adapter *Adapter, u8 *ofdm,
-                                         u8 *pwrbw20, u8 *pwrbw40, u8 channel);
-
-#endif/* __RTL8188E_RF_H__ */
diff --git a/drivers/staging/r8188eu/include/rtl8188e_spec.h b/drivers/staging/r8188eu/include/rtl8188e_spec.h
deleted file mode 100644 (file)
index 25b3141..0000000
+++ /dev/null
@@ -1,1142 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __RTL8188E_SPEC_H__
-#define __RTL8188E_SPEC_H__
-
-/*        8192C Register offset definition */
-
-#define                HAL_PS_TIMER_INT_DELAY  50      /*   50 microseconds */
-#define                HAL_92C_NAV_UPPER_UNIT  128     /*  micro-second */
-
-/*  8188E PKT_BUFF_ACCESS_CTRL value */
-#define TXPKT_BUF_SELECT               0x69
-#define RXPKT_BUF_SELECT               0xA5
-#define DISABLE_TRXPKT_BUF_ACCESS      0x0
-
-/*     0x0000h ~ 0x00FFh       System Configuration */
-#define REG_SYS_ISO_CTRL               0x0000
-#define REG_SYS_FUNC_EN                        0x0002
-#define REG_APS_FSMCO                  0x0004
-#define REG_SYS_CLKR                   0x0008
-#define REG_9346CR                     0x000A
-#define REG_EE_VPD                     0x000C
-#define REG_AFE_MISC                   0x0010
-#define REG_SPS0_CTRL                  0x0011
-#define REG_SPS_OCP_CFG                        0x0018
-#define REG_RSV_CTRL                   0x001C
-#define REG_RF_CTRL                    0x001F
-#define REG_LDOA15_CTRL                        0x0020
-#define REG_LDOV12D_CTRL               0x0021
-#define REG_LDOHCI12_CTRL              0x0022
-#define REG_LPLDO_CTRL                 0x0023
-#define REG_AFE_XTAL_CTRL              0x0024
-#define REG_AFE_PLL_CTRL               0x0028
-#define REG_APE_PLL_CTRL_EXT           0x002c
-#define REG_EFUSE_CTRL                 0x0030
-#define REG_EFUSE_TEST                 0x0034
-#define REG_GPIO_MUXCFG                        0x0040
-#define REG_GPIO_IO_SEL                        0x0042
-#define REG_MAC_PINMUX_CFG             0x0043
-#define REG_GPIO_PIN_CTRL              0x0044
-#define REG_GPIO_INTM                  0x0048
-#define REG_LEDCFG0                    0x004C
-#define REG_LEDCFG1                    0x004D
-#define REG_LEDCFG2                    0x004E
-#define REG_LEDCFG3                    0x004F
-#define REG_FSIMR                      0x0050
-#define REG_FSISR                      0x0054
-#define REG_HSIMR                      0x0058
-#define REG_HSISR                      0x005c
-#define REG_GPIO_PIN_CTRL_2            0x0060 /*  RTL8723 WIFI/BT/GPS
-                                * Multi-Function GPIO Pin Control. */
-#define REG_GPIO_IO_SEL_2              0x0062 /*  RTL8723 WIFI/BT/GPS
-                                * Multi-Function GPIO Select. */
-#define REG_BB_PAD_CTRL                        0x0064
-#define REG_MULTI_FUNC_CTRL            0x0068 /*  RTL8723 WIFI/BT/GPS
-                                * Multi-Function control source. */
-#define REG_GPIO_OUTPUT                        0x006c
-#define REG_AFE_XTAL_CTRL_EXT          0x0078 /* RTL8188E */
-#define REG_XCK_OUT_CTRL               0x007c /* RTL8188E */
-#define REG_MCUFWDL                    0x0080
-#define REG_WOL_EVENT                  0x0081 /* RTL8188E */
-#define REG_MCUTSTCFG                  0x0084
-#define REG_HMEBOX_E0                  0x0088
-#define REG_HMEBOX_E1                  0x008A
-#define REG_HMEBOX_E2                  0x008C
-#define REG_HMEBOX_E3                  0x008E
-#define REG_HMEBOX_EXT_0               0x01F0
-#define REG_HMEBOX_EXT_1               0x01F4
-#define REG_HMEBOX_EXT_2               0x01F8
-#define REG_HMEBOX_EXT_3               0x01FC
-#define REG_HIMR_88E                   0x00B0
-#define REG_HISR_88E                   0x00B4
-#define REG_HIMRE_88E                  0x00B8
-#define REG_HISRE_88E                  0x00BC
-#define REG_EFUSE_ACCESS               0x00CF  /*  Efuse access protection
-                                                * for RTL8723 */
-#define REG_BIST_SCAN                  0x00D0
-#define REG_BIST_RPT                   0x00D4
-#define REG_BIST_ROM_RPT               0x00D8
-#define REG_USB_SIE_INTF               0x00E0
-#define REG_PCIE_MIO_INTF              0x00E4
-#define REG_PCIE_MIO_INTD              0x00E8
-#define REG_HPON_FSM                   0x00EC
-#define REG_SYS_CFG                    0x00F0
-#define REG_GPIO_OUTSTS                        0x00F4  /*  For RTL8723 only. */
-#define REG_TYPE_ID                    0x00FC
-
-#define REG_MAC_PHY_CTRL_NORMAL                0x00f8
-
-/*     0x0100h ~ 0x01FFh       MACTOP General Configuration */
-#define REG_CR                         0x0100
-#define REG_PBP                                0x0104
-#define REG_PKT_BUFF_ACCESS_CTRL       0x0106
-#define REG_TRXDMA_CTRL                        0x010C
-#define REG_TRXFF_BNDY                 0x0114
-#define REG_TRXFF_STATUS               0x0118
-#define REG_RXFF_PTR                   0x011C
-/* define REG_HIMR                     0x0120 */
-/* define REG_HISR                     0x0124 */
-#define REG_HIMRE                      0x0128
-#define REG_HISRE                      0x012C
-#define REG_CPWM                       0x012F
-#define REG_FWIMR                      0x0130
-#define REG_FTIMR                      0x0138
-#define REG_FWISR                      0x0134
-#define REG_PKTBUF_DBG_CTRL            0x0140
-#define REG_PKTBUF_DBG_ADDR            (REG_PKTBUF_DBG_CTRL)
-#define REG_RXPKTBUF_DBG               (REG_PKTBUF_DBG_CTRL+2)
-#define REG_TXPKTBUF_DBG               (REG_PKTBUF_DBG_CTRL+3)
-#define REG_RXPKTBUF_CTRL              (REG_PKTBUF_DBG_CTRL+2)
-#define REG_PKTBUF_DBG_DATA_L          0x0144
-#define REG_PKTBUF_DBG_DATA_H          0x0148
-
-#define REG_TC0_CTRL                   0x0150
-#define REG_TC1_CTRL                   0x0154
-#define REG_TC2_CTRL                   0x0158
-#define REG_TC3_CTRL                   0x015C
-#define REG_TC4_CTRL                   0x0160
-#define REG_TCUNIT_BASE                        0x0164
-#define REG_MBIST_START                        0x0174
-#define REG_MBIST_DONE                 0x0178
-#define REG_MBIST_FAIL                 0x017C
-#define REG_32K_CTRL                   0x0194 /* RTL8188E */
-#define REG_C2HEVT_MSG_NORMAL          0x01A0
-#define REG_C2HEVT_CLEAR               0x01AF
-#define REG_MCUTST_1                   0x01c0
-#define REG_FMETHR                     0x01C8
-#define REG_HMETFR                     0x01CC
-#define REG_HMEBOX_0                   0x01D0
-#define REG_HMEBOX_1                   0x01D4
-#define REG_HMEBOX_2                   0x01D8
-#define REG_HMEBOX_3                   0x01DC
-
-#define REG_LLT_INIT                   0x01E0
-
-/*     0x0200h ~ 0x027Fh       TXDMA Configuration */
-#define REG_RQPN                       0x0200
-#define REG_FIFOPAGE                   0x0204
-#define REG_TDECTRL                    0x0208
-#define REG_TXDMA_OFFSET_CHK           0x020C
-#define REG_TXDMA_STATUS               0x0210
-#define REG_RQPN_NPQ                   0x0214
-
-/*     0x0280h ~ 0x02FFh       RXDMA Configuration */
-#define                REG_RXDMA_AGG_PG_TH     0x0280
-#define        REG_RXPKT_NUM                   0x0284
-#define                REG_RXDMA_STATUS        0x0288
-
-/*     0x0300h ~ 0x03FFh       PCIe */
-#define        REG_PCIE_CTRL_REG               0x0300
-#define        REG_INT_MIG                     0x0304  /*  Interrupt Migration */
-#define        REG_BCNQ_DESA                   0x0308  /*  TX Beacon Descr Address */
-#define        REG_HQ_DESA                     0x0310  /*  TX High Queue Descr Addr */
-#define        REG_MGQ_DESA                    0x0318  /*  TX Manage Queue Descr Addr*/
-#define        REG_VOQ_DESA                    0x0320  /*  TX VO Queue Descr Addr */
-#define        REG_VIQ_DESA                    0x0328  /*  TX VI Queue Descr Addr */
-#define        REG_BEQ_DESA                    0x0330  /*  TX BE Queue Descr Addr */
-#define        REG_BKQ_DESA                    0x0338  /*  TX BK Queue Descr Addr */
-#define        REG_RX_DESA                     0x0340  /*  RX Queue Descr Addr */
-#define        REG_MDIO                        0x0354  /*  MDIO for Access PCIE PHY */
-#define        REG_DBG_SEL                     0x0360  /*  Debug Selection Register */
-#define        REG_PCIE_HRPWM                  0x0361  /* PCIe RPWM */
-#define        REG_PCIE_HCPWM                  0x0363  /* PCIe CPWM */
-#define        REG_WATCH_DOG                   0x0368
-
-/*  RTL8723 series ------------------------------ */
-#define        REG_PCIE_HISR                   0x03A0
-
-/*  spec version 11 */
-/*     0x0400h ~ 0x047Fh       Protocol Configuration */
-#define REG_VOQ_INFORMATION            0x0400
-#define REG_VIQ_INFORMATION            0x0404
-#define REG_BEQ_INFORMATION            0x0408
-#define REG_BKQ_INFORMATION            0x040C
-#define REG_MGQ_INFORMATION            0x0410
-#define REG_HGQ_INFORMATION            0x0414
-#define REG_BCNQ_INFORMATION           0x0418
-#define REG_TXPKT_EMPTY                        0x041A
-
-#define REG_CPU_MGQ_INFORMATION                0x041C
-#define REG_FWHW_TXQ_CTRL              0x0420
-#define REG_HWSEQ_CTRL                 0x0423
-#define REG_TXPKTBUF_BCNQ_BDNY         0x0424
-#define REG_TXPKTBUF_MGQ_BDNY          0x0425
-#define REG_LIFETIME_EN                        0x0426
-#define REG_MULTI_BCNQ_OFFSET          0x0427
-#define REG_SPEC_SIFS                  0x0428
-#define REG_RL                         0x042A
-#define REG_DARFRC                     0x0430
-#define REG_RARFRC                     0x0438
-#define REG_RRSR                       0x0440
-#define REG_ARFR0                      0x0444
-#define REG_ARFR1                      0x0448
-#define REG_ARFR2                      0x044C
-#define REG_ARFR3                      0x0450
-#define REG_AGGLEN_LMT                 0x0458
-#define REG_AMPDU_MIN_SPACE            0x045C
-#define REG_TXPKTBUF_WMAC_LBK_BF_HD    0x045D
-#define REG_FAST_EDCA_CTRL             0x0460
-#define REG_RD_RESP_PKT_TH             0x0463
-#define REG_INIRTS_RATE_SEL            0x0480
-/* define REG_INIDATA_RATE_SEL         0x0484 */
-#define REG_POWER_STATUS               0x04A4
-#define REG_POWER_STAGE1               0x04B4
-#define REG_POWER_STAGE2               0x04B8
-#define REG_PKT_VO_VI_LIFE_TIME                0x04C0
-#define REG_PKT_BE_BK_LIFE_TIME                0x04C2
-#define REG_STBC_SETTING               0x04C4
-#define REG_PROT_MODE_CTRL             0x04C8
-#define REG_MAX_AGGR_NUM               0x04CA
-#define REG_RTS_MAX_AGGR_NUM           0x04CB
-#define REG_BAR_MODE_CTRL              0x04CC
-#define REG_RA_TRY_RATE_AGG_LMT                0x04CF
-#define REG_EARLY_MODE_CONTROL         0x4D0
-#define REG_NQOS_SEQ                   0x04DC
-#define REG_QOS_SEQ                    0x04DE
-#define REG_NEED_CPU_HANDLE            0x04E0
-#define REG_PKT_LOSE_RPT               0x04E1
-#define REG_PTCL_ERR_STATUS            0x04E2
-#define REG_TX_RPT_CTRL                        0x04EC
-#define REG_TX_RPT_TIME                        0x04F0  /*  2 byte */
-#define REG_DUMMY                      0x04FC
-
-/*     0x0500h ~ 0x05FFh       EDCA Configuration */
-#define REG_EDCA_VO_PARAM              0x0500
-#define REG_EDCA_VI_PARAM              0x0504
-#define REG_EDCA_BE_PARAM              0x0508
-#define REG_EDCA_BK_PARAM              0x050C
-#define REG_BCNTCFG                    0x0510
-#define REG_PIFS                       0x0512
-#define REG_RDG_PIFS                   0x0513
-#define REG_SIFS_CTX                   0x0514
-#define REG_SIFS_TRX                   0x0516
-#define REG_TSFTR_SYN_OFFSET           0x0518
-#define REG_AGGR_BREAK_TIME            0x051A
-#define REG_SLOT                       0x051B
-#define REG_TX_PTCL_CTRL               0x0520
-#define REG_TXPAUSE                    0x0522
-#define REG_DIS_TXREQ_CLR              0x0523
-#define REG_RD_CTRL                    0x0524
-/*  Format for offset 540h-542h: */
-/*     [3:0]:   TBTT prohibit setup in unit of 32us. The time for HW getting
- *              beacon content before TBTT. */
-/*     [7:4]:   Reserved. */
-/*     [19:8]:  TBTT prohibit hold in unit of 32us. The time for HW holding
- *              to send the beacon packet. */
-/*     [23:20]: Reserved */
-/*  Description: */
-/*                   | */
-/*      |<--Setup--|--Hold------------>| */
-/*     --------------|---------------------- */
-/*                 | */
-/*                TBTT */
-/*  Note: We cannot update beacon content to HW or send any AC packets during
- *       the time between Setup and Hold. */
-#define REG_TBTT_PROHIBIT              0x0540
-#define REG_RD_NAV_NXT                 0x0544
-#define REG_NAV_PROT_LEN               0x0546
-#define REG_BCN_CTRL                   0x0550
-#define REG_BCN_CTRL_1                 0x0551
-#define REG_MBID_NUM                   0x0552
-#define REG_DUAL_TSF_RST               0x0553
-#define REG_BCN_INTERVAL               0x0554
-#define REG_DRVERLYINT                 0x0558
-#define REG_BCNDMATIM                  0x0559
-#define REG_ATIMWND                    0x055A
-#define REG_BCN_MAX_ERR                        0x055D
-#define REG_RXTSF_OFFSET_CCK           0x055E
-#define REG_RXTSF_OFFSET_OFDM          0x055F
-#define REG_TSFTR                      0x0560
-#define REG_TSFTR1                     0x0568
-#define REG_ATIMWND_1                  0x0570
-#define REG_PSTIMER                    0x0580
-#define REG_TIMER0                     0x0584
-#define REG_TIMER1                     0x0588
-#define REG_ACMHWCTRL                  0x05C0
-
-/* define REG_FW_TSF_SYNC_CNT          0x04A0 */
-#define REG_FW_RESET_TSF_CNT_1         0x05FC
-#define REG_FW_RESET_TSF_CNT_0         0x05FD
-#define REG_FW_BCN_DIS_CNT             0x05FE
-
-/*     0x0600h ~ 0x07FFh       WMAC Configuration */
-#define REG_APSD_CTRL                  0x0600
-#define REG_BWOPMODE                   0x0603
-#define REG_TCR                                0x0604
-#define REG_RCR                                0x0608
-#define REG_RX_PKT_LIMIT               0x060C
-#define REG_RX_DLK_TIME                        0x060D
-#define REG_RX_DRVINFO_SZ              0x060F
-
-#define REG_MACID                      0x0610
-#define REG_BSSID                      0x0618
-#define REG_MAR                                0x0620
-#define REG_MBIDCAMCFG                 0x0628
-
-#define REG_USTIME_EDCA                        0x0638
-#define REG_MAC_SPEC_SIFS              0x063A
-
-/*  20100719 Joseph: Hardware register definition change. (HW datasheet v54) */
-/*  [15:8]SIFS_R2T_OFDM, [7:0]SIFS_R2T_CCK */
-#define REG_R2T_SIFS                   0x063C
-/*  [15:8]SIFS_T2T_OFDM, [7:0]SIFS_T2T_CCK */
-#define REG_T2T_SIFS                   0x063E
-#define REG_ACKTO                      0x0640
-#define REG_CTS2TO                     0x0641
-#define REG_EIFS                       0x0642
-
-/* RXERR_RPT */
-#define RXERR_TYPE_OFDM_PPDU           0
-#define RXERR_TYPE_OFDM_false_ALARM    1
-#define RXERR_TYPE_OFDM_MPDU_OK                2
-#define RXERR_TYPE_OFDM_MPDU_FAIL      3
-#define RXERR_TYPE_CCK_PPDU            4
-#define RXERR_TYPE_CCK_false_ALARM     5
-#define RXERR_TYPE_CCK_MPDU_OK         6
-#define RXERR_TYPE_CCK_MPDU_FAIL       7
-#define RXERR_TYPE_HT_PPDU             8
-#define RXERR_TYPE_HT_false_ALARM      9
-#define RXERR_TYPE_HT_MPDU_TOTAL       10
-#define RXERR_TYPE_HT_MPDU_OK          11
-#define RXERR_TYPE_HT_MPDU_FAIL                12
-#define RXERR_TYPE_RX_FULL_DROP                15
-
-#define RXERR_COUNTER_MASK             0xFFFFF
-#define RXERR_RPT_RST                  BIT(27)
-#define _RXERR_RPT_SEL(type)           ((type) << 28)
-
-/*  Note: */
-/*     The NAV upper value is very important to WiFi 11n 5.2.3 NAV test.
- *     The default value is always too small, but the WiFi TestPlan test
- *     by 25,000 microseconds of NAV through sending CTS in the air.
- *     We must update this value greater than 25,000 microseconds to pass
- *     the item. The offset of NAV_UPPER in 8192C Spec is incorrect, and
- *     the offset should be 0x0652. */
-#define REG_NAV_UPPER                  0x0652  /*  unit of 128 */
-
-/* WMA, BA, CCX */
-/* define REG_NAV_CTRL                 0x0650 */
-#define REG_BACAMCMD                   0x0654
-#define REG_BACAMCONTENT               0x0658
-#define REG_LBDLY                      0x0660
-#define REG_FWDLY                      0x0661
-#define REG_RXERR_RPT                  0x0664
-#define REG_WMAC_TRXPTCL_CTL           0x0668
-
-/*  Security */
-#define REG_CAMCMD                     0x0670
-#define REG_CAMWRITE                   0x0674
-#define REG_CAMREAD                    0x0678
-#define REG_CAMDBG                     0x067C
-#define REG_SECCFG                     0x0680
-
-/*  Power */
-#define REG_WOW_CTRL                   0x0690
-#define REG_PS_RX_INFO                 0x0692
-#define REG_UAPSD_TID                  0x0693
-#define REG_WKFMCAM_CMD                        0x0698
-#define REG_WKFMCAM_NUM_88E            0x698
-#define REG_RXFLTMAP0                  0x06A0
-#define REG_RXFLTMAP1                  0x06A2
-#define REG_RXFLTMAP2                  0x06A4
-#define REG_BCN_PSR_RPT                        0x06A8
-#define REG_BT_COEX_TABLE              0x06C0
-
-/*  Hardware Port 2 */
-#define REG_MACID1                     0x0700
-#define REG_BSSID1                     0x0708
-
-/*     0xFE00h ~ 0xFE55h       USB Configuration */
-#define REG_USB_INFO                   0xFE17
-#define REG_USB_SPECIAL_OPTION         0xFE55
-#define REG_USB_DMA_AGG_TO             0xFE5B
-#define REG_USB_AGG_TO                 0xFE5C
-#define REG_USB_AGG_TH                 0xFE5D
-
-/*  For normal chip */
-#define REG_NORMAL_SIE_VID             0xFE60          /*  0xFE60~0xFE61 */
-#define REG_NORMAL_SIE_PID             0xFE62          /*  0xFE62~0xFE63 */
-#define REG_NORMAL_SIE_OPTIONAL                0xFE64
-#define REG_NORMAL_SIE_EP              0xFE65          /*  0xFE65~0xFE67 */
-#define REG_NORMAL_SIE_PHY             0xFE68          /*  0xFE68~0xFE6B */
-#define REG_NORMAL_SIE_OPTIONAL2       0xFE6C
-#define REG_NORMAL_SIE_GPS_EP          0xFE6D  /*  0xFE6D, for RTL8723 only. */
-#define REG_NORMAL_SIE_MAC_ADDR                0xFE70          /*  0xFE70~0xFE75 */
-#define REG_NORMAL_SIE_STRING          0xFE80          /*  0xFE80~0xFEDF */
-
-/*  TODO: use these definition when using REG_xxx naming rule. */
-/*  NOTE: DO NOT Remove these definition. Use later. */
-
-#define        EFUSE_CTRL                      REG_EFUSE_CTRL  /*  E-Fuse Control. */
-#define        EFUSE_TEST                      REG_EFUSE_TEST  /*  E-Fuse Test. */
-#define        MSR                             (REG_CR + 2)    /*  Media Status reg */
-#define        ISR                             REG_HISR_88E
-/*  Timing Sync Function Timer Register. */
-#define        TSFR                            REG_TSFTR
-
-#define                PBP                     REG_PBP
-
-/*  Redifine MACID register, to compatible prior ICs. */
-/*  MAC ID Register, Offset 0x0050-0x0053 */
-#define        IDR0                            REG_MACID
-/*  MAC ID Register, Offset 0x0054-0x0055 */
-#define        IDR4                            (REG_MACID + 4)
-
-/*  9. Security Control Registers      (Offset: ) */
-/* IN 8190 Data Sheet is called CAMcmd */
-#define        RWCAM                           REG_CAMCMD
-/*  Software write CAM input content */
-#define        WCAMI                           REG_CAMWRITE
-/*  Software read/write CAM config */
-#define        RCAMO                           REG_CAMREAD
-#define        CAMDBG                          REG_CAMDBG
-/* Security Configuration Register */
-#define        SECR                            REG_SECCFG
-
-/*  Unused register */
-#define        UnusedRegister                  0x1BF
-#define        DCAM                            UnusedRegister
-#define        PSR                             UnusedRegister
-#define        BBAddr                          UnusedRegister
-#define        PhyDataR                        UnusedRegister
-
-/*  Min Spacing related settings. */
-#define        MAX_MSS_DENSITY_2T              0x13
-#define        MAX_MSS_DENSITY_1T              0x0A
-
-/*        8192C GPIO MUX Configuration Register (offset 0x40, 4 byte) */
-#define        GPIOSEL_GPIO                    0
-#define        GPIOSEL_ENBT                    BIT(5)
-
-/*        8192C GPIO PIN Control Register (offset 0x44, 4 byte) */
-/*  GPIO pins input value */
-#define        GPIO_IN                         REG_GPIO_PIN_CTRL
-/*  GPIO pins output value */
-#define        GPIO_OUT                        (REG_GPIO_PIN_CTRL+1)
-/*  GPIO pins output enable when a bit is set to "1"; otherwise,
- *  input is configured. */
-#define        GPIO_IO_SEL                     (REG_GPIO_PIN_CTRL+2)
-#define        GPIO_MOD                        (REG_GPIO_PIN_CTRL+3)
-
-/* 8723/8188E Host System Interrupt Mask Register (offset 0x58, 32 byte) */
-#define        HSIMR_GPIO12_0_INT_EN           BIT(0)
-#define        HSIMR_SPS_OCP_INT_EN            BIT(5)
-#define        HSIMR_RON_INT_EN                BIT(6)
-#define        HSIMR_PDN_INT_EN                BIT(7)
-#define        HSIMR_GPIO9_INT_EN              BIT(25)
-
-/* 8723/8188E Host System Interrupt Status Register (offset 0x5C, 32 byte) */
-#define        HSISR_GPIO12_0_INT              BIT(0)
-#define        HSISR_SPS_OCP_INT               BIT(5)
-#define        HSISR_RON_INT_EN                BIT(6)
-#define        HSISR_PDNINT                    BIT(7)
-#define        HSISR_GPIO9_INT                 BIT(25)
-
-/*   8192C (MSR) Media Status Register (Offset 0x4C, 8 bits) */
-/*
-Network Type
-00: No link
-01: Link in ad hoc network
-10: Link in infrastructure network
-11: AP mode
-Default: 00b.
-*/
-#define        MSR_NOLINK                      0x00
-#define        MSR_ADHOC                       0x01
-#define        MSR_INFRA                       0x02
-#define        MSR_AP                          0x03
-
-/*  88E Driver Initialization Offload REG_FDHM0(Offset 0x88, 8 bits) */
-/* IOL config for REG_FDHM0(Reg0x88) */
-#define CMD_INIT_LLT                   BIT(0)
-#define CMD_READ_EFUSE_MAP             BIT(1)
-#define CMD_EFUSE_PATCH                        BIT(2)
-#define CMD_IOCONFIG                   BIT(3)
-#define CMD_INIT_LLT_ERR               BIT(4)
-#define CMD_READ_EFUSE_MAP_ERR         BIT(5)
-#define CMD_EFUSE_PATCH_ERR            BIT(6)
-#define CMD_IOCONFIG_ERR               BIT(7)
-
-/*  6. Adaptive Control Registers  (Offset: 0x0160 - 0x01CF) */
-/*  8192C Response Rate Set Register   (offset 0x181, 24bits) */
-#define        RRSR_1M                         BIT(0)
-#define        RRSR_2M                         BIT(1)
-#define        RRSR_5_5M                       BIT(2)
-#define        RRSR_11M                        BIT(3)
-#define        RRSR_6M                         BIT(4)
-#define        RRSR_9M                         BIT(5)
-#define        RRSR_12M                        BIT(6)
-#define        RRSR_18M                        BIT(7)
-#define        RRSR_24M                        BIT(8)
-#define        RRSR_36M                        BIT(9)
-#define        RRSR_48M                        BIT(10)
-#define        RRSR_54M                        BIT(11)
-#define        RRSR_MCS0                       BIT(12)
-#define        RRSR_MCS1                       BIT(13)
-#define        RRSR_MCS2                       BIT(14)
-#define        RRSR_MCS3                       BIT(15)
-#define        RRSR_MCS4                       BIT(16)
-#define        RRSR_MCS5                       BIT(17)
-#define        RRSR_MCS6                       BIT(18)
-#define        RRSR_MCS7                       BIT(19)
-
-/*  8192C Response Rate Set Register   (offset 0x1BF, 8bits) */
-/*  WOL bit information */
-#define        HAL92C_WOL_PTK_UPDATE_EVENT     BIT(0)
-#define        HAL92C_WOL_GTK_UPDATE_EVENT     BIT(1)
-
-/*        8192C BW_OPMODE bits         (Offset 0x203, 8bit) */
-#define        BW_OPMODE_20MHZ                 BIT(2)
-
-#define        CAM_WRITE                       BIT(16)
-#define        CAM_POLLINIG                    BIT(31)
-
-#define        SCR_UseDK                       0x01
-#define        SCR_TxSecEnable                 0x02
-#define        SCR_RxSecEnable                 0x04
-
-/*  10. Power Save Control Registers    (Offset: 0x0260 - 0x02DF) */
-#define        WOW_PMEN                        BIT(0) /*  Power management Enable. */
-#define        WOW_WOMEN                       BIT(1) /*  WoW function on or off. */
-#define        WOW_MAGIC                       BIT(2) /*  Magic packet */
-#define        WOW_UWF                         BIT(3) /*  Unicast Wakeup frame. */
-
-/*  12. Host Interrupt Status Registers         (Offset: 0x0300 - 0x030F) */
-/*        8188 IMR/ISR bits */
-#define        IMR_DISABLED_88E                0x0
-/*  IMR DW0(0x0060-0063) Bit 0-31 */
-#define        IMR_TXCCK_88E                   BIT(30) /*  TXRPT interrupt when CCX bit of the packet is set */
-#define        IMR_PSTIMEOUT_88E               BIT(29) /*  Power Save Time Out Interrupt */
-#define        IMR_GTINT4_88E                  BIT(28) /*  When GTIMER4 expires, this bit is set to 1 */
-#define        IMR_GTINT3_88E                  BIT(27) /*  When GTIMER3 expires, this bit is set to 1 */
-#define        IMR_TBDER_88E                   BIT(26) /*  Transmit Beacon0 Error */
-#define        IMR_TBDOK_88E                   BIT(25) /*  Transmit Beacon0 OK */
-#define        IMR_TSF_BIT32_TOGGLE_88E        BIT(24) /*  TSF Timer BIT32 toggle indication interrupt */
-#define        IMR_BCNDMAINT0_88E              BIT(20) /*  Beacon DMA Interrupt 0 */
-#define        IMR_BCNDERR0_88E                BIT(16) /*  Beacon Queue DMA Error 0 */
-#define        IMR_HSISR_IND_ON_INT_88E        BIT(15) /*  HSISR Indicator (HSIMR & HSISR is true, this bit is set to 1) */
-#define        IMR_BCNDMAINT_E_88E             BIT(14) /*  Beacon DMA Interrupt Extension for Win7 */
-#define        IMR_ATIMEND_88E                 BIT(12) /*  CTWidnow End or ATIM Window End */
-#define        IMR_HISR1_IND_INT_88E           BIT(11) /*  HISR1 Indicator (HISR1 & HIMR1 is true, this bit is set to 1) */
-#define        IMR_C2HCMD_88E                  BIT(10) /*  CPU to Host Command INT Status, Write 1 clear */
-#define        IMR_CPWM2_88E                   BIT(9)  /*  CPU power Mode exchange INT Status, Write 1 clear */
-#define        IMR_CPWM_88E                    BIT(8)  /*  CPU power Mode exchange INT Status, Write 1 clear */
-#define        IMR_HIGHDOK_88E                 BIT(7)  /*  High Queue DMA OK */
-#define        IMR_MGNTDOK_88E                 BIT(6)  /*  Management Queue DMA OK */
-#define        IMR_BKDOK_88E                   BIT(5)  /*  AC_BK DMA OK */
-#define        IMR_BEDOK_88E                   BIT(4)  /*  AC_BE DMA OK */
-#define        IMR_VIDOK_88E                   BIT(3)  /*  AC_VI DMA OK */
-#define        IMR_VODOK_88E                   BIT(2)  /*  AC_VO DMA OK */
-#define        IMR_RDU_88E                     BIT(1)  /*  Rx Descriptor Unavailable */
-#define        IMR_ROK_88E                     BIT(0)  /*  Receive DMA OK */
-
-/*  IMR DW1(0x00B4-00B7) Bit 0-31 */
-#define        IMR_BCNDMAINT7_88E              BIT(27) /*  Beacon DMA Interrupt 7 */
-#define        IMR_BCNDMAINT6_88E              BIT(26) /*  Beacon DMA Interrupt 6 */
-#define        IMR_BCNDMAINT5_88E              BIT(25) /*  Beacon DMA Interrupt 5 */
-#define        IMR_BCNDMAINT4_88E              BIT(24) /*  Beacon DMA Interrupt 4 */
-#define        IMR_BCNDMAINT3_88E              BIT(23) /*  Beacon DMA Interrupt 3 */
-#define        IMR_BCNDMAINT2_88E              BIT(22) /*  Beacon DMA Interrupt 2 */
-#define        IMR_BCNDMAINT1_88E              BIT(21) /*  Beacon DMA Interrupt 1 */
-#define        IMR_BCNDERR7_88E                BIT(20) /*  Beacon DMA Error Int 7 */
-#define        IMR_BCNDERR6_88E                BIT(19) /*  Beacon DMA Error Int 6 */
-#define        IMR_BCNDERR5_88E                BIT(18) /*  Beacon DMA Error Int 5 */
-#define        IMR_BCNDERR4_88E                BIT(17) /*  Beacon DMA Error Int 4 */
-#define        IMR_BCNDERR3_88E                BIT(16) /*  Beacon DMA Error Int 3 */
-#define        IMR_BCNDERR2_88E                BIT(15) /*  Beacon DMA Error Int 2 */
-#define        IMR_BCNDERR1_88E                BIT(14) /*  Beacon DMA Error Int 1 */
-#define        IMR_ATIMEND_E_88E               BIT(13) /*  ATIM Window End Ext for Win7 */
-#define        IMR_TXERR_88E                   BIT(11) /*  Tx Err Flag Int Status, write 1 clear. */
-#define        IMR_RXERR_88E                   BIT(10) /*  Rx Err Flag INT Status, Write 1 clear */
-#define        IMR_TXFOVW_88E                  BIT(9)  /*  Transmit FIFO Overflow */
-#define        IMR_RXFOVW_88E                  BIT(8)  /*  Receive FIFO Overflow */
-
-#define        HAL_NIC_UNPLUG_ISR              0xFFFFFFFF      /*  The value when the NIC is unplugged for PCI. */
-
-/*  8192C EFUSE */
-#define                HWSET_MAX_SIZE                  256
-#define                HWSET_MAX_SIZE_88E              512
-
-/*===================================================================
-=====================================================================
-Here the register defines are for 92C. When the define is as same with 92C,
-we will use the 92C's define for the consistency
-So the following defines for 92C is not entire!!!!!!
-=====================================================================
-=====================================================================*/
-/*
-Based on Datasheet V33---090401
-Register Summary
-Current IOREG MAP
-0x0000h ~ 0x00FFh   System Configuration (256 Bytes)
-0x0100h ~ 0x01FFh   MACTOP General Configuration (256 Bytes)
-0x0200h ~ 0x027Fh   TXDMA Configuration (128 Bytes)
-0x0280h ~ 0x02FFh   RXDMA Configuration (128 Bytes)
-0x0300h ~ 0x03FFh   PCIE EMAC Reserved Region (256 Bytes)
-0x0400h ~ 0x04FFh   Protocol Configuration (256 Bytes)
-0x0500h ~ 0x05FFh   EDCA Configuration (256 Bytes)
-0x0600h ~ 0x07FFh   WMAC Configuration (512 Bytes)
-0x2000h ~ 0x3FFFh   8051 FW Download Region (8196 Bytes)
-*/
-/*              8192C (TXPAUSE) transmission pause (Offset 0x522, 8 bits) */
-/*  Note: */
-/*     The bits of stopping AC(VO/VI/BE/BK) queue in datasheet
- *     RTL8192S/RTL8192C are wrong, */
-/*     the correct arragement is VO - Bit0, VI - Bit1, BE - Bit2,
- *     and BK - Bit3. */
-/*     8723 and 88E may be not correct either in the earlier version. */
-#define                StopBecon                       BIT(6)
-#define                StopHigh                        BIT(5)
-#define                StopMgt                         BIT(4)
-#define                StopBK                          BIT(3)
-#define                StopBE                          BIT(2)
-#define                StopVI                          BIT(1)
-#define                StopVO                          BIT(0)
-
-/*        8192C (RCR) Receive Configuration Register(Offset 0x608, 32 bits) */
-#define        RCR_APPFCS              BIT(31) /* WMAC append FCS after payload */
-#define        RCR_APP_MIC             BIT(30)
-#define        RCR_APP_PHYSTS          BIT(28)
-#define        RCR_APP_ICV             BIT(29)
-#define        RCR_APP_PHYST_RXFF      BIT(28)
-#define        RCR_APP_BA_SSN          BIT(27) /* Accept BA SSN */
-#define        RCR_ENMBID              BIT(24) /* Enable Multiple BssId. */
-#define        RCR_LSIGEN              BIT(23)
-#define        RCR_MFBEN               BIT(22)
-#define        RCR_HTC_LOC_CTRL        BIT(14)   /* MFC<--HTC=1 MFC-->HTC=0 */
-#define        RCR_AMF                 BIT(13) /* Accept management type frame */
-#define        RCR_ACF                 BIT(12) /* Accept control type frame */
-#define        RCR_ADF                 BIT(11) /* Accept data type frame */
-#define        RCR_AICV                BIT(9)  /* Accept ICV error packet */
-#define        RCR_ACRC32              BIT(8)  /* Accept CRC32 error packet */
-#define        RCR_CBSSID_BCN          BIT(7)  /* Accept BSSID match packet
-                                        * (Rx beacon, probe rsp) */
-#define        RCR_CBSSID_DATA         BIT(6)  /* Accept BSSID match (Data)*/
-#define        RCR_CBSSID              RCR_CBSSID_DATA /* Accept BSSID match */
-#define        RCR_APWRMGT             BIT(5)  /* Accept power management pkt*/
-#define        RCR_ADD3                BIT(4)  /* Accept address 3 match pkt */
-#define        RCR_AB                  BIT(3)  /* Accept broadcast packet */
-#define        RCR_AM                  BIT(2)  /* Accept multicast packet */
-#define        RCR_APM                 BIT(1)  /* Accept physical match pkt */
-#define        RCR_AAP                 BIT(0)  /* Accept all unicast packet */
-#define        RCR_MXDMA_OFFSET        8
-#define        RCR_FIFO_OFFSET         13
-
-/*     0xFE00h ~ 0xFE55h       USB Configuration */
-#define REG_USB_INFO                   0xFE17
-#define REG_USB_SPECIAL_OPTION         0xFE55
-#define REG_USB_DMA_AGG_TO             0xFE5B
-#define REG_USB_AGG_TO                 0xFE5C
-#define REG_USB_AGG_TH                 0xFE5D
-
-#define REG_USB_HRPWM                  0xFE58
-#define REG_USB_HCPWM                  0xFE57
-/*        8192C Register Bit and Content definition */
-/*     0x0000h ~ 0x00FFh       System Configuration */
-
-/* 2 SYS_ISO_CTRL */
-#define ISO_MD2PP                      BIT(0)
-#define ISO_UA2USB                     BIT(1)
-#define ISO_UD2CORE                    BIT(2)
-#define ISO_PA2PCIE                    BIT(3)
-#define ISO_PD2CORE                    BIT(4)
-#define ISO_IP2MAC                     BIT(5)
-#define ISO_DIOP                       BIT(6)
-#define ISO_DIOE                       BIT(7)
-#define ISO_EB2CORE                    BIT(8)
-#define ISO_DIOR                       BIT(9)
-#define PWC_EV12V                      BIT(15)
-
-/* 2 SYS_FUNC_EN */
-#define FEN_BBRSTB                     BIT(0)
-#define FEN_BB_GLB_RSTn                        BIT(1)
-#define FEN_USBA                       BIT(2)
-#define FEN_UPLL                       BIT(3)
-#define FEN_USBD                       BIT(4)
-#define FEN_DIO_PCIE                   BIT(5)
-#define FEN_PCIEA                      BIT(6)
-#define FEN_PPLL                       BIT(7)
-#define FEN_PCIED                      BIT(8)
-#define FEN_DIOE                       BIT(9)
-#define FEN_CPUEN                      BIT(10)
-#define FEN_DCORE                      BIT(11)
-#define FEN_ELDR                       BIT(12)
-#define FEN_DIO_RF                     BIT(13)
-#define FEN_HWPDN                      BIT(14)
-#define FEN_MREGEN                     BIT(15)
-
-/* 2 APS_FSMCO */
-#define PFM_LDALL                      BIT(0)
-#define PFM_ALDN                       BIT(1)
-#define PFM_LDKP                       BIT(2)
-#define PFM_WOWL                       BIT(3)
-#define EnPDN                          BIT(4)
-#define PDN_PL                         BIT(5)
-#define APFM_ONMAC                     BIT(8)
-#define APFM_OFF                       BIT(9)
-#define APFM_RSM                       BIT(10)
-#define AFSM_HSUS                      BIT(11)
-#define AFSM_PCIE                      BIT(12)
-#define APDM_MAC                       BIT(13)
-#define APDM_HOST                      BIT(14)
-#define APDM_HPDN                      BIT(15)
-#define RDY_MACON                      BIT(16)
-#define SUS_HOST                       BIT(17)
-#define ROP_ALD                                BIT(20)
-#define ROP_PWR                                BIT(21)
-#define ROP_SPS                                BIT(22)
-#define SOP_MRST                       BIT(25)
-#define SOP_FUSE                       BIT(26)
-#define SOP_ABG                                BIT(27)
-#define SOP_AMB                                BIT(28)
-#define SOP_RCK                                BIT(29)
-#define SOP_A8M                                BIT(30)
-#define XOP_BTCK                       BIT(31)
-
-/* 2 SYS_CLKR */
-#define ANAD16V_EN                     BIT(0)
-#define ANA8M                          BIT(1)
-#define MACSLP                         BIT(4)
-#define LOADER_CLK_EN                  BIT(5)
-
-/* 2 9346CR */
-
-#define                BOOT_FROM_EEPROM        BIT(4)
-#define                EEPROM_EN               BIT(5)
-
-/* 2 SPS0_CTRL */
-
-/* 2 SPS_OCP_CFG */
-
-/* 2 RF_CTRL */
-#define RF_EN                          BIT(0)
-#define RF_RSTB                                BIT(1)
-#define RF_SDMRSTB                     BIT(2)
-
-/* 2 LDOV12D_CTRL */
-#define LDV12_EN                       BIT(0)
-#define LDV12_SDBY                     BIT(1)
-#define LPLDO_HSM                      BIT(2)
-#define LPLDO_LSM_DIS                  BIT(3)
-#define _LDV12_VADJ(x)                 (((x) & 0xF) << 4)
-
-/* 2EFUSE_CTRL */
-#define ALD_EN                         BIT(18)
-#define EF_PD                          BIT(19)
-#define EF_FLAG                                BIT(31)
-
-/* 2 EFUSE_TEST (For RTL8723 partially) */
-#define EF_TRPT                                BIT(7)
-/*  00: Wifi Efuse, 01: BT Efuse0, 10: BT Efuse1, 11: BT Efuse2 */
-#define EF_CELL_SEL                    (BIT(8)|BIT(9))
-#define LDOE25_EN                      BIT(31)
-#define EFUSE_SEL(x)                   (((x) & 0x3) << 8)
-#define EFUSE_SEL_MASK                 0x300
-#define EFUSE_WIFI_SEL_0               0x0
-#define EFUSE_BT_SEL_0                 0x1
-#define EFUSE_BT_SEL_1                 0x2
-#define EFUSE_BT_SEL_2                 0x3
-
-#define EFUSE_ACCESS_ON                        0x69    /*  For RTL8723 only. */
-#define EFUSE_ACCESS_OFF               0x00    /*  For RTL8723 only. */
-
-/* 2 8051FWDL */
-/* 2 MCUFWDL */
-#define MCUFWDL_EN                     BIT(0)
-#define MCUFWDL_RDY                    BIT(1)
-#define FWDL_CHKSUM_RPT                        BIT(2)
-#define MACINI_RDY                     BIT(3)
-#define BBINI_RDY                      BIT(4)
-#define RFINI_RDY                      BIT(5)
-#define WINTINI_RDY                    BIT(6)
-#define RAM_DL_SEL                     BIT(7) /*  1:RAM, 0:ROM */
-#define ROM_DLEN                       BIT(19)
-#define CPRST                          BIT(23)
-
-/* 2 REG_SYS_CFG */
-#define XCLK_VLD                       BIT(0)
-#define ACLK_VLD                       BIT(1)
-#define UCLK_VLD                       BIT(2)
-#define PCLK_VLD                       BIT(3)
-#define PCIRSTB                                BIT(4)
-#define V15_VLD                                BIT(5)
-#define SW_OFFLOAD_EN                  BIT(7)
-#define SIC_IDLE                       BIT(8)
-#define BD_MAC2                                BIT(9)
-#define BD_MAC1                                BIT(10)
-#define IC_MACPHY_MODE                 BIT(11)
-#define CHIP_VER                       (BIT(12)|BIT(13)|BIT(14)|BIT(15))
-#define BT_FUNC                                BIT(16)
-#define VENDOR_ID                      BIT(19)
-#define PAD_HWPD_IDN                   BIT(22)
-#define TRP_VAUX_EN                    BIT(23) /*  RTL ID */
-#define TRP_BT_EN                      BIT(24)
-#define BD_PKG_SEL                     BIT(25)
-#define BD_HCI_SEL                     BIT(26)
-#define TYPE_ID                                BIT(27)
-
-#define CHIP_VER_RTL_MASK              0xF000  /* Bit 12 ~ 15 */
-#define CHIP_VER_RTL_SHIFT             12
-
-/* 2REG_GPIO_OUTSTS (For RTL8723 only) */
-#define        EFS_HCI_SEL                     (BIT(0)|BIT(1))
-#define        PAD_HCI_SEL                     (BIT(2)|BIT(3))
-#define        HCI_SEL                         (BIT(4)|BIT(5))
-#define        PKG_SEL_HCI                     BIT(6)
-#define        FEN_GPS                         BIT(7)
-#define        FEN_BT                          BIT(8)
-#define        FEN_WL                          BIT(9)
-#define        FEN_PCI                         BIT(10)
-#define        FEN_USB                         BIT(11)
-#define        BTRF_HWPDN_N                    BIT(12)
-#define        WLRF_HWPDN_N                    BIT(13)
-#define        PDN_BT_N                        BIT(14)
-#define        PDN_GPS_N                       BIT(15)
-#define        BT_CTL_HWPDN                    BIT(16)
-#define        GPS_CTL_HWPDN                   BIT(17)
-#define        PPHY_SUSB                       BIT(20)
-#define        UPHY_SUSB                       BIT(21)
-#define        PCI_SUSEN                       BIT(22)
-#define        USB_SUSEN                       BIT(23)
-#define        RF_RL_ID                        (BIT(31)|BIT(30)|BIT(29)|BIT(28))
-
-/* 2SYS_CFG */
-#define RTL_ID                         BIT(23) /*  TestChip ID, 1:Test(RLE); 0:MP(RL) */
-
-/*     0x0100h ~ 0x01FFh       MACTOP General Configuration */
-
-/* 2 Function Enable Registers */
-/* 2 CR */
-
-#define HCI_TXDMA_EN                   BIT(0)
-#define HCI_RXDMA_EN                   BIT(1)
-#define TXDMA_EN                       BIT(2)
-#define RXDMA_EN                       BIT(3)
-#define PROTOCOL_EN                    BIT(4)
-#define SCHEDULE_EN                    BIT(5)
-#define MACTXEN                                BIT(6)
-#define MACRXEN                                BIT(7)
-#define ENSWBCN                                BIT(8)
-#define ENSEC                          BIT(9)
-#define CALTMR_EN                      BIT(10) /*  32k CAL TMR enable */
-
-/*  Network type */
-#define _NETTYPE(x)                    (((x) & 0x3) << 16)
-#define MASK_NETTYPE                   0x30000
-#define NT_NO_LINK                     0x0
-#define NT_LINK_AD_HOC                 0x1
-#define NT_LINK_AP                     0x2
-#define NT_AS_AP                       0x3
-
-/* 2 PBP - Page Size Register */
-#define GET_RX_PAGE_SIZE(value)                ((value) & 0xF)
-#define GET_TX_PAGE_SIZE(value)                (((value) & 0xF0) >> 4)
-#define _PSRX_MASK                     0xF
-#define _PSTX_MASK                     0xF0
-#define _PSRX(x)                       (x)
-#define _PSTX(x)                       ((x) << 4)
-
-#define PBP_128                                0x1
-
-/* 2 TX/RXDMA */
-#define RXDMA_ARBBW_EN                 BIT(0)
-#define RXSHFT_EN                      BIT(1)
-#define RXDMA_AGG_EN                   BIT(2)
-#define QS_VO_QUEUE                    BIT(8)
-#define QS_VI_QUEUE                    BIT(9)
-#define QS_BE_QUEUE                    BIT(10)
-#define QS_BK_QUEUE                    BIT(11)
-#define QS_MANAGER_QUEUE               BIT(12)
-#define QS_HIGH_QUEUE                  BIT(13)
-
-#define HQSEL_VOQ                      BIT(0)
-#define HQSEL_VIQ                      BIT(1)
-#define HQSEL_BEQ                      BIT(2)
-#define HQSEL_BKQ                      BIT(3)
-#define HQSEL_MGTQ                     BIT(4)
-#define HQSEL_HIQ                      BIT(5)
-
-/*  For normal driver, 0x10C */
-#define _TXDMA_HIQ_MAP(x)              (((x) & 0x3) << 14)
-#define _TXDMA_MGQ_MAP(x)              (((x) & 0x3) << 12)
-#define _TXDMA_BKQ_MAP(x)              (((x) & 0x3) << 10)
-#define _TXDMA_BEQ_MAP(x)              (((x) & 0x3) << 8)
-#define _TXDMA_VIQ_MAP(x)              (((x) & 0x3) << 6)
-#define _TXDMA_VOQ_MAP(x)              (((x) & 0x3) << 4)
-
-#define QUEUE_LOW                      1
-#define QUEUE_NORMAL                   2
-#define QUEUE_HIGH                     3
-
-/* 2 TRXFF_BNDY */
-
-/* 2 LLT_INIT */
-#define _LLT_NO_ACTIVE                 0x0
-#define _LLT_WRITE_ACCESS              0x1
-#define _LLT_READ_ACCESS               0x2
-
-#define _LLT_INIT_DATA(x)              ((x) & 0xFF)
-#define _LLT_INIT_ADDR(x)              (((x) & 0xFF) << 8)
-#define _LLT_OP(x)                     (((x) & 0x3) << 30)
-#define _LLT_OP_VALUE(x)               (((x) >> 30) & 0x3)
-
-/*     0x0200h ~ 0x027Fh       TXDMA Configuration */
-
-#define NUM_HQ 0x29
-
-#define LD_RQPN                                BIT(31)
-
-/* 2TDECTRL */
-#define BCN_VALID                      BIT(16)
-#define BCN_HEAD(x)                    (((x) & 0xFF) << 8)
-#define        BCN_HEAD_MASK                   0xFF00
-
-/* 2 TDECTL */
-#define BLK_DESC_NUM_SHIFT             4
-#define BLK_DESC_NUM_MASK              0xF
-
-/* 2 TXDMA_OFFSET_CHK */
-#define DROP_DATA_EN                   BIT(9)
-
-/*     0x0280h ~ 0x028Bh       RX DMA Configuration */
-
-/*     REG_RXDMA_CONTROL, 0x0286h */
-
-/* 2 REG_RXPKT_NUM, 0x0284 */
-#define                RXPKT_RELEASE_POLL      BIT(16)
-#define        RXDMA_IDLE                      BIT(17)
-#define        RW_RELEASE_EN                   BIT(18)
-
-/*     0x0400h ~ 0x047Fh       Protocol Configuration */
-/* 2 FWHW_TXQ_CTRL */
-#define EN_AMPDU_RTY_NEW               BIT(7)
-
-/* 2 SPEC SIFS */
-#define _SPEC_SIFS_CCK(x)              ((x) & 0xFF)
-#define _SPEC_SIFS_OFDM(x)             (((x) & 0xFF) << 8)
-
-/* 2 RL */
-#define        RETRY_LIMIT_SHORT_SHIFT         8
-#define        RETRY_LIMIT_LONG_SHIFT          0
-
-/*     0x0500h ~ 0x05FFh       EDCA Configuration */
-
-/* 2 EDCA setting */
-#define AC_PARAM_TXOP_LIMIT_OFFSET     16
-#define AC_PARAM_ECW_MAX_OFFSET                12
-#define AC_PARAM_ECW_MIN_OFFSET                8
-#define AC_PARAM_AIFS_OFFSET           0
-
-#define _LRL(x)                        ((x) & 0x3F)
-#define _SRL(x)                        (((x) & 0x3F) << 8)
-
-/* 2 BCN_CTRL */
-#define EN_MBSSID              BIT(1)
-#define EN_TXBCN_RPT           BIT(2)
-#define EN_BCN_FUNCTION                BIT(3)
-#define DIS_TSF_UPDATE         BIT(3)
-
-/*  The same function but different bit field. */
-#define DIS_TSF_UDT0_NORMAL_CHIP       BIT(4)
-#define DIS_TSF_UDT0_TEST_CHIP BIT(5)
-#define STOP_BCNQ              BIT(6)
-
-/* 2 ACMHWCTRL */
-#define ACMHW_BEQEN            BIT(1)
-#define ACMHW_VIQEN            BIT(2)
-#define ACMHW_VOQEN            BIT(3)
-
-/*     0x0600h ~ 0x07FFh       WMAC Configuration */
-/* 2APSD_CTRL */
-#define APSDOFF                        BIT(6)
-#define APSDOFF_STATUS         BIT(7)
-
-#define RATE_BITMAP_ALL                0xFFFFF
-
-/*  Only use CCK 1M rate for ACK */
-#define RATE_RRSR_CCK_ONLY_1M  0xFFFF1
-
-/* 2 TCR */
-#define TSFRST                 BIT(0)
-#define DIS_GCLK               BIT(1)
-#define PAD_SEL                        BIT(2)
-#define PWR_ST                 BIT(6)
-#define PWRBIT_OW_EN           BIT(7)
-#define ACRC                   BIT(8)
-#define CFENDFORM              BIT(9)
-#define ICV                    BIT(10)
-
-/* 2 RCR */
-#define AAP                    BIT(0)
-#define APM                    BIT(1)
-#define AM                     BIT(2)
-#define AB                     BIT(3)
-#define ADD3                   BIT(4)
-#define APWRMGT                        BIT(5)
-#define CBSSID                 BIT(6)
-#define CBSSID_DATA            BIT(6)
-#define CBSSID_BCN             BIT(7)
-#define ACRC32                 BIT(8)
-#define AICV                   BIT(9)
-#define ADF                    BIT(11)
-#define ACF                    BIT(12)
-#define AMF                    BIT(13)
-#define HTC_LOC_CTRL           BIT(14)
-#define UC_DATA_EN             BIT(16)
-#define BM_DATA_EN             BIT(17)
-#define MFBEN                  BIT(22)
-#define LSIGEN                 BIT(23)
-#define EnMBID                 BIT(24)
-#define APP_BASSN              BIT(27)
-#define APP_PHYSTS             BIT(28)
-#define APP_ICV                        BIT(29)
-#define APP_MIC                        BIT(30)
-#define APP_FCS                        BIT(31)
-
-/* 2 SECCFG */
-#define        SCR_TxUseDK             BIT(0)  /* Force Tx Use Default Key */
-#define        SCR_RxUseDK             BIT(1)  /* Force Rx Use Default Key */
-#define        SCR_TxEncEnable         BIT(2)  /* Enable Tx Encryption */
-#define        SCR_RxDecEnable         BIT(3)  /* Enable Rx Decryption */
-#define        SCR_SKByA2              BIT(4)  /* Search kEY BY A2 */
-#define        SCR_NoSKMC              BIT(5)  /* No Key Search Multicast */
-#define SCR_TXBCUSEDK          BIT(6)  /* Force Tx Bcast pkt Use Default Key */
-#define SCR_RXBCUSEDK          BIT(7)  /* Force Rx Bcast pkt Use Default Key */
-
-/*     0xFE00h ~ 0xFE55h       USB Configuration */
-
-/* 2 USB Information (0xFE17) */
-#define USB_IS_HIGH_SPEED                      0
-#define USB_IS_FULL_SPEED                      1
-#define USB_SPEED_MASK                         BIT(5)
-
-#define USB_NORMAL_SIE_EP_MASK                 0xF
-#define USB_NORMAL_SIE_EP_SHIFT                        4
-
-/* 2 Special Option */
-#define USB_AGG_EN                             BIT(3)
-
-/*  0; Use interrupt endpoint to upload interrupt pkt */
-/*  1; Use bulk endpoint to upload interrupt pkt, */
-#define INT_BULK_SEL                           BIT(4)
-
-/* 2REG_C2HEVT_CLEAR */
-/*  Set by driver and notify FW that the driver has read
- *  the C2H command message */
-#define        C2H_EVT_HOST_CLOSE      0x00
-/*  Set by FW indicating that FW had set the C2H command
- *  message and it's not yet read by driver. */
-#define C2H_EVT_FW_CLOSE       0xFF
-
-/* 2REG_MULTI_FUNC_CTRL(For RTL8723 Only) */
-/*  Enable GPIO[9] as WiFi HW PDn source */
-#define        WL_HWPDN_EN                             BIT(0)
-/*  WiFi HW PDn polarity control */
-#define        WL_HWPDN_SL                             BIT(1)
-/*  WiFi function enable */
-#define        WL_FUNC_EN                              BIT(2)
-/*  Enable GPIO[9] as WiFi RF HW PDn source */
-#define        WL_HWROF_EN                             BIT(3)
-/*  Enable GPIO[11] as BT HW PDn source */
-#define        BT_HWPDN_EN                             BIT(16)
-/*  BT HW PDn polarity control */
-#define        BT_HWPDN_SL                             BIT(17)
-/*  BT function enable */
-#define        BT_FUNC_EN                              BIT(18)
-/*  Enable GPIO[11] as BT/GPS RF HW PDn source */
-#define        BT_HWROF_EN                             BIT(19)
-/*  Enable GPIO[10] as GPS HW PDn source */
-#define        GPS_HWPDN_EN                            BIT(20)
-/*  GPS HW PDn polarity control */
-#define        GPS_HWPDN_SL                            BIT(21)
-/*  GPS function enable */
-#define        GPS_FUNC_EN                             BIT(22)
-
-/* 3 REG_LIFECTRL_CTRL */
-#define        HAL92C_EN_PKT_LIFE_TIME_BK              BIT(3)
-#define        HAL92C_EN_PKT_LIFE_TIME_BE              BIT(2)
-#define        HAL92C_EN_PKT_LIFE_TIME_VI              BIT(1)
-#define        HAL92C_EN_PKT_LIFE_TIME_VO              BIT(0)
-
-#define        HAL92C_MSDU_LIFE_TIME_UNIT              128     /*  in us */
-
-/*  General definitions */
-#define LAST_ENTRY_OF_TX_PKT_BUFFER            176 /*  22k 22528 bytes */
-
-#define POLLING_LLT_THRESHOLD                  20
-#define POLLING_READY_TIMEOUT_COUNT            1000
-/*  GPIO BIT */
-#define        HAL_8192C_HW_GPIO_WPS_BIT               BIT(2)
-
-/*     8192C EEPROM/EFUSE share register definition. */
-
-/*     EEPROM/Efuse PG Offset for 88EE/88EU/88ES */
-#define        EEPROM_TX_PWR_INX_88E                   0x10
-
-#define        EEPROM_ChannelPlan_88E                  0xB8
-#define        EEPROM_XTAL_88E                         0xB9
-#define        EEPROM_THERMAL_METER_88E                0xBA
-#define        EEPROM_IQK_LCK_88E                      0xBB
-
-#define        EEPROM_RF_BOARD_OPTION_88E              0xC1
-#define        EEPROM_RF_FEATURE_OPTION_88E            0xC2
-#define        EEPROM_RF_ANTENNA_OPT_88E               0xC9
-
-/* RTL88EU */
-#define        EEPROM_MAC_ADDR_88EU                    0xD7
-#define EEPROM_USB_OPTIONAL_FUNCTION0          0xD4
-
-/*  RTL88ES */
-#define        EEPROM_MAC_ADDR_88ES                    0x11A
-
-#define EEPROM_Default_CrystalCap_88E          0x20
-#define        EEPROM_Default_ThermalMeter_88E         0x18
-
-/* New EFUSE default value */
-#define                EEPROM_DEFAULT_24G_INDEX        0x2D
-#define                EEPROM_DEFAULT_24G_HT20_DIFF    0X02
-#define                EEPROM_DEFAULT_24G_OFDM_DIFF    0X04
-
-#define                EEPROM_DEFAULT_DIFF             0XFE
-#define        EEPROM_DEFAULT_BOARD_OPTION             0x00
-
-#define EEPROM_CHANNEL_PLAN_FCC                        0x0
-#define EEPROM_CHANNEL_PLAN_IC                 0x1
-#define EEPROM_CHANNEL_PLAN_ETSI               0x2
-#define EEPROM_CHANNEL_PLAN_SPA                        0x3
-#define EEPROM_CHANNEL_PLAN_FRANCE             0x4
-#define EEPROM_CHANNEL_PLAN_MKK                        0x5
-#define EEPROM_CHANNEL_PLAN_MKK1               0x6
-#define EEPROM_CHANNEL_PLAN_ISRAEL             0x7
-#define EEPROM_CHANNEL_PLAN_TELEC              0x8
-#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMA                0x9
-#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13      0xA
-#define EEPROM_CHANNEL_PLAN_NCC                        0xB
-#define EEPROM_USB_OPTIONAL1                   0xE
-#define EEPROM_CHANNEL_PLAN_BY_HW_MASK         0x80
-
-#define        RTL_EEPROM_ID                   0x8129
-
-#endif /* __RTL8188E_SPEC_H__ */
diff --git a/drivers/staging/r8188eu/include/rtl8188e_xmit.h b/drivers/staging/r8188eu/include/rtl8188e_xmit.h
deleted file mode 100644 (file)
index a023dd7..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __RTL8188E_XMIT_H__
-#define __RTL8188E_XMIT_H__
-
-#define                MAX_TX_AGG_PACKET_NUMBER        0xFF
-#define QSLT_MGNT                                              0x12
-
-/* For 88e early mode */
-#define SET_EARLYMODE_PKTNUM(__paddr, __value)                 \
-       le32p_replace_bits((__le32 *)__paddr, __value, GENMASK(2, 0))
-#define SET_EARLYMODE_LEN0(__pAddr, __Value)                   \
-       le32p_replace_bits((__le32 *)__paddr, __value, GENMASK(15, 4))
-#define SET_EARLYMODE_LEN1(__paddr, __value)                   \
-       le32p_replace_bits((__le32 *)__paddr, __value, GENMASK(27, 16))
-#define SET_EARLYMODE_LEN2_1(__pdr, __vValue)                  \
-       le32p_replace_bits((__le32 *)__paddr, __value, GENMASK(31, 28))
-#define SET_EARLYMODE_LEN2_2(__paddr, __value)                 \
-       le32p_replace_bits((__le32 *)(__paddr + 4), __value, GENMASK(7, 0))
-#define SET_EARLYMODE_LEN3(__pAddr, __Value)                   \
-       le32p_replace_bits((__le32 *)(__paddr + 4), __value, GENMASK(19, 8))
-#define SET_EARLYMODE_LEN4(__paAddr, __vValue)                 \
-       le32p_replace_bits((__le32 *)(__paddr + 4), __value, GENMASK(31, 20))
-
-/* defined for TX DESC Operation */
-
-#define MAX_TID (15)
-
-/* OFFSET 0 */
-#define OFFSET_SZ      0
-#define OFFSET_SHT     16
-#define BMC            BIT(24)
-#define LSG            BIT(26)
-#define FSG            BIT(27)
-#define OWN            BIT(31)
-
-/* OFFSET 4 */
-#define PKT_OFFSET_SZ          0
-#define QSEL_SHT               8
-#define RATE_ID_SHT            16
-#define NAVUSEHDR              BIT(20)
-#define SEC_TYPE_SHT           22
-#define PKT_OFFSET_SHT         26
-
-/* OFFSET 8 */
-#define AGG_EN                 BIT(12)
-#define AGG_BK                 BIT(16)
-#define AMPDU_DENSITY_SHT      20
-#define ANTSEL_A               BIT(24)
-#define ANTSEL_B               BIT(25)
-#define TX_ANT_CCK_SHT         26
-#define TX_ANTL_SHT            28
-#define TX_ANT_HT_SHT          30
-
-/* OFFSET 12 */
-#define SEQ_SHT                        16
-#define EN_HWSEQ               BIT(31)
-
-/* OFFSET 16 */
-#define QOS                    BIT(6)
-#define        HW_SSN                  BIT(7)
-#define USERATE                        BIT(8)
-#define DISDATAFB              BIT(10)
-#define CTS_2_SELF             BIT(11)
-#define        RTS_EN                  BIT(12)
-#define        HW_RTS_EN               BIT(13)
-#define DATA_SHORT             BIT(24)
-#define PWR_STATUS_SHT         15
-#define DATA_SC_SHT            20
-#define DATA_BW                        BIT(25)
-
-/* OFFSET 20 */
-#define        RTY_LMT_EN              BIT(17)
-
-/* OFFSET 20 */
-#define SGI                    BIT(6)
-#define USB_TXAGG_NUM_SHT      24
-
-#define USB_TXAGG_DESC_NUM     0x6
-
-#define txdesc_set_ccx_sw_88e(txdesc, value) \
-       do { \
-               ((struct txdesc_88e *)(txdesc))->sw1 = (((value)>>8) & 0x0f); \
-               ((struct txdesc_88e *)(txdesc))->sw0 = ((value) & 0xff); \
-       } while (0)
-
-struct txrpt_ccx_88e {
-       /* offset 0 */
-       u8 tag1:1;
-       u8 pkt_num:3;
-       u8 txdma_underflow:1;
-       u8 int_bt:1;
-       u8 int_tri:1;
-       u8 int_ccx:1;
-
-       /* offset 1 */
-       u8 mac_id:6;
-       u8 pkt_ok:1;
-       u8 bmc:1;
-
-       /* offset 2 */
-       u8 retry_cnt:6;
-       u8 lifetime_over:1;
-       u8 retry_over:1;
-
-       /* offset 3 */
-       u8 ccx_qtime0;
-       u8 ccx_qtime1;
-
-       /* offset 5 */
-       u8 final_data_rate;
-
-       /* offset 6 */
-       u8 sw1:4;
-       u8 qsel:4;
-
-       /* offset 7 */
-       u8 sw0;
-};
-
-void rtl8188e_fill_fake_txdesc(struct adapter *padapter, u8 *pDesc,
-                              u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull);
-s32 rtl8188eu_hal_xmit(struct adapter *padapter, struct xmit_frame *frame);
-s32 rtl8188eu_mgnt_xmit(struct adapter *padapter, struct xmit_frame *frame);
-s32 rtl8188eu_xmit_buf_handler(struct adapter *padapter);
-void rtl8188eu_xmit_tasklet(unsigned long priv);
-bool rtl8188eu_xmitframe_complete(struct adapter *padapter);
-
-#endif /* __RTL8188E_XMIT_H__ */
diff --git a/drivers/staging/r8188eu/include/rtw_ap.h b/drivers/staging/r8188eu/include/rtw_ap.h
deleted file mode 100644 (file)
index 89b02c9..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-#ifndef __RTW_AP_H_
-#define __RTW_AP_H_
-
-#include "osdep_service.h"
-#include "drv_types.h"
-
-/* external function */
-void rtw_indicate_sta_assoc_event(struct adapter *padapter,
-                                 struct sta_info *psta);
-void init_mlme_ap_info(struct adapter *padapter);
-void free_mlme_ap_info(struct adapter *padapter);
-void update_beacon(struct adapter *padapter, u8 ie_id,
-                  u8 *oui, u8 tx);
-void add_RATid(struct adapter *padapter, struct sta_info *psta,
-              u8 rssi_level);
-void expire_timeout_chk(struct adapter *padapter);
-void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta);
-void rtw_ap_restore_network(struct adapter *padapter);
-
-void associated_clients_update(struct adapter *padapter, u8 updated);
-void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta);
-u8 bss_cap_update_on_sta_leave(struct adapter *padapter, struct sta_info *psta);
-void sta_info_update(struct adapter *padapter, struct sta_info *psta);
-u8 ap_free_sta(struct adapter *padapter, struct sta_info *psta,
-              bool active, u16 reason);
-void rtw_sta_flush(struct adapter *padapter);
-void start_ap_mode(struct adapter *padapter);
-void stop_ap_mode(struct adapter *padapter);
-void update_bmc_sta(struct adapter *padapter);
-
-#endif
diff --git a/drivers/staging/r8188eu/include/rtw_br_ext.h b/drivers/staging/r8188eu/include/rtw_br_ext.h
deleted file mode 100644 (file)
index 56772af..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef _RTW_BR_EXT_H_
-#define _RTW_BR_EXT_H_
-
-#define GET_MY_HWADDR(padapter)                ((padapter)->eeprompriv.mac_addr)
-
-#define NAT25_HASH_BITS                4
-#define NAT25_HASH_SIZE                (1 << NAT25_HASH_BITS)
-#define NAT25_AGEING_TIME      300
-
-#define MAX_NETWORK_ADDR_LEN   17
-
-struct nat25_network_db_entry {
-       struct nat25_network_db_entry   *next_hash;
-       struct nat25_network_db_entry   **pprev_hash;
-       atomic_t        use_count;
-       unsigned char   macAddr[6];
-       unsigned long   ageing_timer;
-       unsigned char   networkAddr[MAX_NETWORK_ADDR_LEN];
-};
-
-enum NAT25_METHOD {
-       NAT25_MIN,
-       NAT25_CHECK,
-       NAT25_INSERT,
-       NAT25_PARSE,
-       NAT25_MAX
-};
-
-struct br_ext_info {
-       unsigned int    nat25_disable;
-       unsigned int    macclone_enable;
-       unsigned int    dhcp_bcst_disable;
-       int     addPPPoETag;            /* 1: Add PPPoE relay-SID, 0: disable */
-       unsigned char   nat25_dmzMac[ETH_ALEN];
-       unsigned int    nat25sc_disable;
-};
-
-void nat25_db_cleanup(struct adapter *priv);
-
-#endif /*  _RTW_BR_EXT_H_ */
diff --git a/drivers/staging/r8188eu/include/rtw_cmd.h b/drivers/staging/r8188eu/include/rtw_cmd.h
deleted file mode 100644 (file)
index e8eecd5..0000000
+++ /dev/null
@@ -1,925 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __RTW_CMD_H_
-#define __RTW_CMD_H_
-
-#include "wlan_bssdef.h"
-#include "rtw_rf.h"
-
-#include "osdep_service.h"
-#include "ieee80211.h" /*  <ieee80211/ieee80211.h> */
-
-#define MAX_CMDSZ      1024
-#define MAX_RSPSZ      512
-#define MAX_EVTSZ      1024
-
-#define CMDBUFF_ALIGN_SZ 512
-
-struct cmd_obj {
-       struct adapter *padapter;
-       u16     cmdcode;
-       u8      res;
-       u8      *parmbuf;
-       u32     cmdsz;
-       u8      *rsp;
-       u32     rspsz;
-       struct list_head list;
-};
-
-struct cmd_priv {
-       struct completion enqueue_cmd;
-       struct completion start_cmd_thread;
-       struct completion stop_cmd_thread;
-       struct __queue cmd_queue;
-       u8      *cmd_buf;       /* shall be non-paged, and 4 bytes aligned */
-       u8      *cmd_allocated_buf;
-       u8      *rsp_buf;       /* shall be non-paged, and 4 bytes aligned */
-       u8      *rsp_allocated_buf;
-       u32     cmd_done_cnt;
-       u32     rsp_cnt;
-       u8 cmdthd_running;
-       struct adapter *padapter;
-};
-
-struct evt_priv {
-       struct work_struct c2h_wk;
-       bool c2h_wk_alive;
-       struct rtw_cbuf *c2h_queue;
-       #define C2H_QUEUE_MAX_LEN 10
-       atomic_t event_seq;
-       u8      *evt_buf;       /* shall be non-paged, and 4 bytes aligned */
-};
-
-#define init_h2fwcmd_w_parm_no_rsp(pcmd, pparm, code) \
-do {\
-       INIT_LIST_HEAD(&pcmd->list);\
-       pcmd->cmdcode = code;\
-       pcmd->parmbuf = (u8 *)(pparm);\
-       pcmd->cmdsz = sizeof(*pparm);\
-       pcmd->rsp = NULL;\
-       pcmd->rspsz = 0;\
-} while (0)
-
-struct c2h_evt_hdr {
-       u8 id:4;
-       u8 plen:4;
-       u8 seq;
-       u8 payload[];
-};
-
-#define c2h_evt_exist(c2h_evt) ((c2h_evt)->id || (c2h_evt)->plen)
-
-u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *obj);
-struct cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv);
-void rtw_free_cmd_obj(struct cmd_obj *pcmd);
-
-int rtw_cmd_thread(void *context);
-
-int rtw_init_cmd_priv(struct cmd_priv *pcmdpriv);
-void rtw_free_cmd_priv(struct cmd_priv *pcmdpriv);
-
-int rtw_init_evt_priv(struct evt_priv *pevtpriv);
-void rtw_free_evt_priv(struct evt_priv *pevtpriv);
-void rtw_evt_notify_isr(struct evt_priv *pevtpriv);
-u8 p2p_protocol_wk_cmd(struct adapter *padapter, int intCmdType);
-
-enum rtw_drvextra_cmd_id {
-       NONE_WK_CID,
-       DYNAMIC_CHK_WK_CID,
-       DM_CTRL_WK_CID,
-       PBC_POLLING_WK_CID,
-       POWER_SAVING_CTRL_WK_CID,/* IPS,AUTOSuspend */
-       LPS_CTRL_WK_CID,
-       ANT_SELECT_WK_CID,
-       P2P_PS_WK_CID,
-       P2P_PROTO_WK_CID,
-       CHECK_HIQ_WK_CID,/* for softap mode, check hi queue if empty */
-       INTEl_WIDI_WK_CID,
-       C2H_WK_CID,
-       RTP_TIMER_CFG_WK_CID,
-       MAX_WK_CID
-};
-
-enum LPS_CTRL_TYPE {
-       LPS_CTRL_SCAN = 0,
-       LPS_CTRL_JOINBSS = 1,
-       LPS_CTRL_CONNECT = 2,
-       LPS_CTRL_DISCONNECT = 3,
-       LPS_CTRL_SPECIAL_PACKET = 4,
-       LPS_CTRL_LEAVE = 5,
-};
-
-enum RFINTFS {
-       SWSI,
-       HWSI,
-       HWPI,
-};
-
-/*
-Caller Mode: Infra, Ad-HoC
-
-Notes: To join a known BSS.
-
-Command-Event Mode
-
-*/
-
-/*
-Caller Mode: Infra, Ad-Hoc
-
-Notes: To join the specified bss
-
-Command Event Mode
-
-*/
-struct joinbss_parm {
-       struct wlan_bssid_ex network;
-};
-
-/*
-Caller Mode: Infra, Ad-HoC(C)
-
-Notes: To disconnect the current associated BSS
-
-Command Mode
-
-*/
-struct disconnect_parm {
-       u32 deauth_timeout_ms;
-};
-
-/*
-Caller Mode: AP, Ad-HoC(M)
-
-Notes: To create a BSS
-
-Command Mode
-*/
-struct createbss_parm {
-       struct wlan_bssid_ex network;
-};
-
-struct setopmode_parm {
-       u8      mode;
-       u8      rsvd[3];
-};
-
-/*
-Caller Mode: AP, Ad-HoC, Infra
-
-Notes: To ask RTL8711 performing site-survey
-
-Command-Event Mode
-
-*/
-
-#define RTW_SSID_SCAN_AMOUNT 9 /*  for WEXT_CSCAN_AMOUNT 9 */
-#define RTW_CHANNEL_SCAN_AMOUNT (14+37)
-struct sitesurvey_parm {
-       int scan_mode;  /* active: 1, passive: 0 */
-       u8 ssid_num;
-       u8 ch_num;
-       struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT];
-       struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
-};
-
-/*
-Caller Mode: Any
-
-Notes: To set the auth type of RTL8711. open/shared/802.1x
-
-Command Mode
-
-*/
-struct setauth_parm {
-       u8 mode;  /* 0: legacy open, 1: legacy shared 2: 802.1x */
-       u8 _1x;   /* 0: PSK, 1: TLS */
-       u8 rsvd[2];
-};
-
-/*
-Caller Mode: Infra
-
-a. algorithm: wep40, wep104, tkip & aes
-b. keytype: grp key/unicast key
-c. key contents
-
-when shared key ==> keyid is the camid
-when 802.1x ==> keyid [0:1] ==> grp key
-when 802.1x ==> keyid > 2 ==> unicast key
-
-*/
-struct setkey_parm {
-       u8      algorithm;      /* could be none, wep40, TKIP, CCMP, wep104 */
-       u8      keyid;
-       u8      grpkey;         /* 1: this is the grpkey for 802.1x.
-                                * 0: this is the unicast key for 802.1x */
-       u8      set_tx;         /* 1: main tx key for wep. 0: other key. */
-       u8      key[16];        /* this could be 40 or 104 */
-};
-
-/*
-When in AP or Ad-Hoc mode, this is used to
-allocate an sw/hw entry for a newly associated sta.
-
-Command
-
-when shared key ==> algorithm/keyid
-
-*/
-struct set_stakey_parm {
-       u8      addr[ETH_ALEN];
-       u8      algorithm;
-       u8      id;/* currently for erasing cam entry if
-                   * algorithm == _NO_PRIVACY_ */
-       u8      key[16];
-};
-
-struct set_stakey_rsp {
-       u8      addr[ETH_ALEN];
-       u8      keyid;
-       u8      rsvd;
-};
-
-/*
-Caller Ad-Hoc/AP
-
-Command -Rsp(AID == CAMID) mode
-
-This is to force fw to add an sta_data entry per driver's request.
-
-FW will write an cam entry associated with it.
-
-*/
-struct set_assocsta_parm {
-       u8      addr[ETH_ALEN];
-};
-
-struct set_assocsta_rsp {
-       u8      cam_id;
-       u8      rsvd[3];
-};
-
-/*
-       Caller Ad-Hoc/AP
-
-       Command mode
-
-       This is to force fw to del an sta_data entry per driver's request
-
-       FW will invalidate the cam entry associated with it.
-
-*/
-struct del_assocsta_parm {
-       u8      addr[ETH_ALEN];
-};
-
-/*
-Caller Mode: AP/Ad-HoC(M)
-
-Notes: To notify fw that given staid has changed its power state
-
-Command Mode
-
-*/
-struct setstapwrstate_parm {
-       u8      staid;
-       u8      status;
-       u8      hwaddr[6];
-};
-
-/*
-Caller Mode: Any
-
-Notes: To setup the basic rate of RTL8711
-
-Command Mode
-
-*/
-struct setbasicrate_parm {
-       u8      basicrates[NumRates];
-};
-
-/*
-Caller Mode: Any
-
-Notes: To read the current basic rate
-
-Command-Rsp Mode
-
-*/
-struct getbasicrate_parm {
-       u32 rsvd;
-};
-
-struct getbasicrate_rsp {
-       u8 basicrates[NumRates];
-};
-
-/*
-Caller Mode: Any
-
-Notes: To setup the data rate of RTL8711
-
-Command Mode
-
-*/
-struct setdatarate_parm {
-       u8      mac_id;
-       u8      datarates[NumRates];
-};
-
-/*
-Caller Mode: Any
-
-Notes: To read the current data rate
-
-Command-Rsp Mode
-
-*/
-struct getdatarate_parm {
-       u32 rsvd;
-
-};
-struct getdatarate_rsp {
-       u8 datarates[NumRates];
-};
-
-/*
-Caller Mode: Any
-AP: AP can use the info for the contents of beacon frame
-Infra: STA can use the info when sitesurveying
-Ad-HoC(M): Like AP
-Ad-HoC(C): Like STA
-
-Notes: To set the phy capability of the NIC
-
-Command Mode
-
-*/
-
-struct setphyinfo_parm {
-       struct regulatory_class class_sets[NUM_REGULATORYS];
-       u8      status;
-};
-
-struct getphyinfo_parm {
-       u32 rsvd;
-};
-
-struct getphyinfo_rsp {
-       struct regulatory_class class_sets[NUM_REGULATORYS];
-       u8      status;
-};
-
-/*
-Caller Mode: Any
-
-Notes: To set the channel/modem/band
-This command will be used when channel/modem/band is changed.
-
-Command Mode
-
-*/
-struct setphy_parm {
-       u8      rfchannel;
-       u8      modem;
-};
-
-/*
-Caller Mode: Any
-
-Notes: To get the current setting of channel/modem/band
-
-Command-Rsp Mode
-
-*/
-struct getphy_parm {
-       u32 rsvd;
-
-};
-struct getphy_rsp {
-       u8      rfchannel;
-       u8      modem;
-};
-
-struct readBB_parm {
-       u8      offset;
-};
-struct readBB_rsp {
-       u8      value;
-};
-
-struct readTSSI_parm {
-       u8      offset;
-};
-struct readTSSI_rsp {
-       u8      value;
-};
-
-struct writeBB_parm {
-       u8      offset;
-       u8      value;
-};
-
-struct readRF_parm {
-       u8      offset;
-};
-struct readRF_rsp {
-       u32     value;
-};
-
-struct writeRF_parm {
-       u32     offset;
-       u32     value;
-};
-
-struct getrfintfs_parm {
-       u8      rfintfs;
-};
-
-struct Tx_Beacon_param {
-       struct wlan_bssid_ex network;
-};
-
-/*
-       Notes: This command is used for H2C/C2H loopback testing
-
-       mac[0] == 0
-       ==> CMD mode, return H2C_SUCCESS.
-       The following condition must be true under CMD mode
-               mac[1] == mac[4], mac[2] == mac[3], mac[0]=mac[5]= 0;
-               s0 == 0x1234, s1 == 0xabcd, w0 == 0x78563412, w1 == 0x5aa5def7;
-               s2 == (b1 << 8 | b0);
-
-       mac[0] == 1
-       ==> CMD_RSP mode, return H2C_SUCCESS_RSP
-
-       The rsp layout shall be:
-       rsp:                    parm:
-               mac[0]  =   mac[5];
-               mac[1]  =   mac[4];
-               mac[2]  =   mac[3];
-               mac[3]  =   mac[2];
-               mac[4]  =   mac[1];
-               mac[5]  =   mac[0];
-               s0              =   s1;
-               s1              =   swap16(s0);
-               w0              =       swap32(w1);
-               b0              =       b1
-               s2              =       s0 + s1
-               b1              =       b0
-               w1              =       w0
-
-       mac[0] ==       2
-       ==> CMD_EVENT mode, return      H2C_SUCCESS
-       The event layout shall be:
-       event:                  parm:
-               mac[0]  =   mac[5];
-               mac[1]  =   mac[4];
-               mac[2]  =   event's seq no, starting from 1 to parm's marc[3]
-               mac[3]  =   mac[2];
-               mac[4]  =   mac[1];
-               mac[5]  =   mac[0];
-               s0              =   swap16(s0) - event.mac[2];
-               s1              =   s1 + event.mac[2];
-               w0              =       swap32(w0);
-               b0              =       b1
-               s2              =       s0 + event.mac[2]
-               b1              =       b0
-               w1              =       swap32(w1) - event.mac[2];
-
-               parm->mac[3] is the total event counts that host requested.
-       event will be the same with the cmd's param.
-*/
-
-/*  CMD param Format for driver extra cmd handler */
-struct drvextra_cmd_parm {
-       int ec_id; /* extra cmd id */
-       int type_size; /*  Can use this field as the type id or command size */
-       unsigned char *pbuf;
-};
-
-/*------------------- Below are used for RF/BB tuning ---------------------*/
-
-struct setantenna_parm {
-       u8      tx_antset;
-       u8      rx_antset;
-       u8      tx_antenna;
-       u8      rx_antenna;
-};
-
-struct enrateadaptive_parm {
-       u32     en;
-};
-
-struct settxagctbl_parm {
-       u32     txagc[MAX_RATES_LENGTH];
-};
-
-struct gettxagctbl_parm {
-       u32 rsvd;
-};
-struct gettxagctbl_rsp {
-       u32     txagc[MAX_RATES_LENGTH];
-};
-
-struct setagcctrl_parm {
-       u32     agcctrl;                /*  0: pure hw, 1: fw */
-};
-
-struct setssup_parm    {
-       u32     ss_ForceUp[MAX_RATES_LENGTH];
-};
-
-struct getssup_parm    {
-       u32 rsvd;
-};
-
-struct getssup_rsp     {
-       u8      ss_ForceUp[MAX_RATES_LENGTH];
-};
-
-struct setssdlevel_parm        {
-       u8      ss_DLevel[MAX_RATES_LENGTH];
-};
-
-struct getssdlevel_parm        {
-       u32 rsvd;
-};
-
-struct getssdlevel_rsp {
-       u8      ss_DLevel[MAX_RATES_LENGTH];
-};
-
-struct setssulevel_parm        {
-       u8      ss_ULevel[MAX_RATES_LENGTH];
-};
-
-struct getssulevel_parm        {
-       u32 rsvd;
-};
-
-struct getssulevel_rsp {
-       u8      ss_ULevel[MAX_RATES_LENGTH];
-};
-
-struct setcountjudge_parm {
-       u8      count_judge[MAX_RATES_LENGTH];
-};
-
-struct getcountjudge_parm {
-       u32 rsvd;
-};
-
-struct getcountjudge_rsp {
-       u8      count_judge[MAX_RATES_LENGTH];
-};
-
-struct setratable_parm {
-       u8 ss_ForceUp[NumRates];
-       u8 ss_ULevel[NumRates];
-       u8 ss_DLevel[NumRates];
-       u8 count_judge[NumRates];
-};
-
-struct getratable_parm {
-       uint rsvd;
-};
-
-struct getratable_rsp {
-       u8 ss_ForceUp[NumRates];
-       u8 ss_ULevel[NumRates];
-       u8 ss_DLevel[NumRates];
-       u8 count_judge[NumRates];
-};
-
-/* to get TX,RX retry count */
-
-struct gettxretrycnt_parm {
-       unsigned int rsvd;
-};
-
-struct gettxretrycnt_rsp {
-       unsigned long tx_retrycnt;
-};
-
-struct getrxretrycnt_parm {
-       unsigned int rsvd;
-};
-
-struct getrxretrycnt_rsp {
-       unsigned long rx_retrycnt;
-};
-
-/* to get BCNOK,BCNERR count */
-struct getbcnokcnt_parm {
-       unsigned int rsvd;
-};
-
-struct getbcnokcnt_rsp {
-       unsigned long  bcnokcnt;
-};
-
-struct getbcnerrcnt_parm {
-       unsigned int rsvd;
-};
-
-struct getbcnerrcnt_rsp {
-       unsigned long bcnerrcnt;
-};
-
-/*  to get current TX power level */
-struct getcurtxpwrlevel_parm {
-       unsigned int rsvd;
-};
-struct getcurtxpwrlevel_rspi {
-       unsigned short tx_power;
-};
-
-struct setprobereqextraie_parm {
-       unsigned char e_id;
-       unsigned char ie_len;
-       unsigned char ie[];
-};
-
-struct setassocreqextraie_parm {
-       unsigned char e_id;
-       unsigned char ie_len;
-       unsigned char ie[];
-};
-
-struct setproberspextraie_parm {
-       unsigned char e_id;
-       unsigned char ie_len;
-       unsigned char ie[];
-};
-
-struct setassocrspextraie_parm {
-       unsigned char e_id;
-       unsigned char ie_len;
-       unsigned char ie[];
-};
-
-struct addBaReq_parm {
-       unsigned int tid;
-       u8      addr[ETH_ALEN];
-};
-
-/*H2C Handler index: 46 */
-struct set_ch_parm {
-       u8 ch;
-       u8 bw;
-       u8 ch_offset;
-};
-
-/*H2C Handler index: 59 */
-struct SetChannelPlan_param {
-       u8 channel_plan;
-};
-
-/*H2C Handler index: 60 */
-struct LedBlink_param {
-       struct LED_871x *pLed;
-};
-
-/*H2C Handler index: 61 */
-struct SetChannelSwitch_param {
-       u8 new_ch_no;
-};
-
-/*H2C Handler index: 62 */
-struct TDLSoption_param {
-       u8 addr[ETH_ALEN];
-       u8 option;
-};
-
-#define GEN_CMD_CODE(cmd)      cmd ## _CMD_
-
-/*
-
-Result:
-0x00: success
-0x01: success, and check Response.
-0x02: cmd ignored due to duplicated sequcne number
-0x03: cmd dropped due to invalid cmd code
-0x04: reserved.
-
-*/
-
-#define H2C_RSP_OFFSET         512
-
-#define H2C_SUCCESS            0x00
-#define H2C_SUCCESS_RSP                0x01
-#define H2C_DUPLICATED         0x02
-#define H2C_DROPPED            0x03
-#define H2C_PARAMETERS_ERROR   0x04
-#define H2C_REJECTED           0x05
-#define H2C_CMD_OVERFLOW       0x06
-#define H2C_RESERVED           0x07
-
-u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, int ssid_num);
-u8 rtw_createbss_cmd(struct adapter *padapter);
-u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key);
-u8 rtw_clearstakey_cmd(struct adapter *padapter, u8 *psta, u8 entry, u8 enqueue);
-u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork);
-u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueue);
-u8 rtw_setopmode_cmd(struct adapter *padapter, enum ndis_802_11_network_infra networktype);
-int rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset);
-u8 rtw_setrfintfs_cmd(struct adapter *padapter, u8 mode);
-
-u8 rtw_gettssi_cmd(struct adapter *padapter, u8 offset, u8 *pval);
-u8 rtw_setfwdig_cmd(struct adapter *padapter, u8 type);
-u8 rtw_setfwra_cmd(struct adapter *padapter, u8 type);
-
-u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr);
-
-u8 rtw_dynamic_chk_wk_cmd(struct adapter *adapter);
-
-u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue);
-u8 rtw_rpt_timer_cfg_cmd(struct adapter *padapter, u16 minRptTime);
-
-u8 rtw_antenna_select_cmd(struct adapter *padapter, u8 antenna, u8 enqueue);
-u8 rtw_ps_cmd(struct adapter *padapter);
-
-void rtw_chk_hi_queue_cmd(struct adapter *padapter);
-
-u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan);
-
-u8 rtw_c2h_wk_cmd(struct adapter *padapter, u8 *c2h_evt);
-
-u8 rtw_drvextra_cmd_hdl(struct adapter *padapter, unsigned char *pbuf);
-
-void rtw_survey_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd);
-void rtw_disassoc_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd);
-void rtw_joinbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd);
-void rtw_createbss_cmd_callback(struct adapter *adapt, struct cmd_obj *pcmd);
-void rtw_getbbrfreg_cmdrsp_callback(struct adapter *adapt, struct cmd_obj *cmd);
-
-void rtw_setstaKey_cmdrsp_callback(struct adapter *adapt, struct cmd_obj *cmd);
-void rtw_setassocsta_cmdrsp_callback(struct adapter *adapt, struct cmd_obj *cm);
-void rtw_getrttbl_cmdrsp_callback(struct adapter *adapt, struct cmd_obj *cmd);
-
-struct _cmd_callback {
-       u32     cmd_code;
-       void (*callback)(struct adapter  *padapter, struct cmd_obj *cmd);
-};
-
-enum rtw_h2c_cmd {
-       GEN_CMD_CODE(_Read_MACREG),     /*0*/
-       GEN_CMD_CODE(_Write_MACREG),
-       GEN_CMD_CODE(_Read_BBREG),
-       GEN_CMD_CODE(_Write_BBREG),
-       GEN_CMD_CODE(_Read_RFREG),
-       GEN_CMD_CODE(_Write_RFREG), /*5*/
-       GEN_CMD_CODE(_Read_EEPROM),
-       GEN_CMD_CODE(_Write_EEPROM),
-       GEN_CMD_CODE(_Read_EFUSE),
-       GEN_CMD_CODE(_Write_EFUSE),
-
-       GEN_CMD_CODE(_Read_CAM),        /*10*/
-       GEN_CMD_CODE(_Write_CAM),
-       GEN_CMD_CODE(_setBCNITV),
-       GEN_CMD_CODE(_setMBIDCFG),
-       GEN_CMD_CODE(_JoinBss),   /*14*/
-       GEN_CMD_CODE(_DisConnect), /*15*/
-       GEN_CMD_CODE(_CreateBss),
-       GEN_CMD_CODE(_SetOpMode),
-       GEN_CMD_CODE(_SiteSurvey),  /*18*/
-       GEN_CMD_CODE(_SetAuth),
-
-       GEN_CMD_CODE(_SetKey),  /*20*/
-       GEN_CMD_CODE(_SetStaKey),
-       GEN_CMD_CODE(_SetAssocSta),
-       GEN_CMD_CODE(_DelAssocSta),
-       GEN_CMD_CODE(_SetStaPwrState),
-       GEN_CMD_CODE(_SetBasicRate), /*25*/
-       GEN_CMD_CODE(_GetBasicRate),
-       GEN_CMD_CODE(_SetDataRate),
-       GEN_CMD_CODE(_GetDataRate),
-       GEN_CMD_CODE(_SetPhyInfo),
-
-       GEN_CMD_CODE(_GetPhyInfo),      /*30*/
-       GEN_CMD_CODE(_SetPhy),
-       GEN_CMD_CODE(_GetPhy),
-       GEN_CMD_CODE(_readRssi),
-       GEN_CMD_CODE(_readGain),
-       GEN_CMD_CODE(_SetAtim), /*35*/
-       GEN_CMD_CODE(_SetPwrMode),
-       GEN_CMD_CODE(_JoinbssRpt),
-       GEN_CMD_CODE(_SetRaTable),
-       GEN_CMD_CODE(_GetRaTable),
-
-       GEN_CMD_CODE(_GetCCXReport), /*40*/
-       GEN_CMD_CODE(_GetDTMReport),
-       GEN_CMD_CODE(_GetTXRateStatistics),
-       GEN_CMD_CODE(_SetUsbSuspend),
-       GEN_CMD_CODE(_SetH2cLbk),
-       GEN_CMD_CODE(_AddBAReq), /*45*/
-       GEN_CMD_CODE(_SetChannel), /*46*/
-       GEN_CMD_CODE(_SetTxPower),
-       GEN_CMD_CODE(_SwitchAntenna),
-       GEN_CMD_CODE(_SetCrystalCap),
-       GEN_CMD_CODE(_SetSingleCarrierTx), /*50*/
-
-       GEN_CMD_CODE(_SetSingleToneTx),/*51*/
-       GEN_CMD_CODE(_SetCarrierSuppressionTx),
-       GEN_CMD_CODE(_SetContinuousTx),
-       GEN_CMD_CODE(_SwitchBandwidth), /*54*/
-       GEN_CMD_CODE(_TX_Beacon), /*55*/
-
-       GEN_CMD_CODE(_Set_MLME_EVT), /*56*/
-       GEN_CMD_CODE(_Set_Drv_Extra), /*57*/
-       GEN_CMD_CODE(_Set_H2C_MSG), /*58*/
-
-       GEN_CMD_CODE(_SetChannelPlan), /*59*/
-       GEN_CMD_CODE(_LedBlink), /*60*/
-
-       GEN_CMD_CODE(_SetChannelSwitch), /*61*/
-       GEN_CMD_CODE(_TDLS), /*62*/
-
-       MAX_H2CCMD
-};
-
-#define _GetBBReg_CMD_         _Read_BBREG_CMD_
-#define _SetBBReg_CMD_         _Write_BBREG_CMD_
-#define _GetRFReg_CMD_         _Read_RFREG_CMD_
-#define _SetRFReg_CMD_         _Write_RFREG_CMD_
-
-#ifdef _RTW_CMD_C_
-static struct _cmd_callback    rtw_cmd_callback[] = {
-       {GEN_CMD_CODE(_Read_MACREG), NULL}, /*0*/
-       {GEN_CMD_CODE(_Write_MACREG), NULL},
-       {GEN_CMD_CODE(_Read_BBREG), &rtw_getbbrfreg_cmdrsp_callback},
-       {GEN_CMD_CODE(_Write_BBREG), NULL},
-       {GEN_CMD_CODE(_Read_RFREG), &rtw_getbbrfreg_cmdrsp_callback},
-       {GEN_CMD_CODE(_Write_RFREG), NULL}, /*5*/
-       {GEN_CMD_CODE(_Read_EEPROM), NULL},
-       {GEN_CMD_CODE(_Write_EEPROM), NULL},
-       {GEN_CMD_CODE(_Read_EFUSE), NULL},
-       {GEN_CMD_CODE(_Write_EFUSE), NULL},
-
-       {GEN_CMD_CODE(_Read_CAM),       NULL},  /*10*/
-       {GEN_CMD_CODE(_Write_CAM),       NULL},
-       {GEN_CMD_CODE(_setBCNITV), NULL},
-       {GEN_CMD_CODE(_setMBIDCFG), NULL},
-       {GEN_CMD_CODE(_JoinBss), &rtw_joinbss_cmd_callback},  /*14*/
-       {GEN_CMD_CODE(_DisConnect), &rtw_disassoc_cmd_callback}, /*15*/
-       {GEN_CMD_CODE(_CreateBss), &rtw_createbss_cmd_callback},
-       {GEN_CMD_CODE(_SetOpMode), NULL},
-       {GEN_CMD_CODE(_SiteSurvey), &rtw_survey_cmd_callback}, /*18*/
-       {GEN_CMD_CODE(_SetAuth), NULL},
-
-       {GEN_CMD_CODE(_SetKey), NULL},  /*20*/
-       {GEN_CMD_CODE(_SetStaKey), &rtw_setstaKey_cmdrsp_callback},
-       {GEN_CMD_CODE(_SetAssocSta), &rtw_setassocsta_cmdrsp_callback},
-       {GEN_CMD_CODE(_DelAssocSta), NULL},
-       {GEN_CMD_CODE(_SetStaPwrState), NULL},
-       {GEN_CMD_CODE(_SetBasicRate), NULL}, /*25*/
-       {GEN_CMD_CODE(_GetBasicRate), NULL},
-       {GEN_CMD_CODE(_SetDataRate), NULL},
-       {GEN_CMD_CODE(_GetDataRate), NULL},
-       {GEN_CMD_CODE(_SetPhyInfo), NULL},
-
-       {GEN_CMD_CODE(_GetPhyInfo), NULL}, /*30*/
-       {GEN_CMD_CODE(_SetPhy), NULL},
-       {GEN_CMD_CODE(_GetPhy), NULL},
-       {GEN_CMD_CODE(_readRssi), NULL},
-       {GEN_CMD_CODE(_readGain), NULL},
-       {GEN_CMD_CODE(_SetAtim), NULL}, /*35*/
-       {GEN_CMD_CODE(_SetPwrMode), NULL},
-       {GEN_CMD_CODE(_JoinbssRpt), NULL},
-       {GEN_CMD_CODE(_SetRaTable), NULL},
-       {GEN_CMD_CODE(_GetRaTable), NULL},
-
-       {GEN_CMD_CODE(_GetCCXReport), NULL}, /*40*/
-       {GEN_CMD_CODE(_GetDTMReport),   NULL},
-       {GEN_CMD_CODE(_GetTXRateStatistics), NULL},
-       {GEN_CMD_CODE(_SetUsbSuspend), NULL},
-       {GEN_CMD_CODE(_SetH2cLbk), NULL},
-       {GEN_CMD_CODE(_AddBAReq), NULL}, /*45*/
-       {GEN_CMD_CODE(_SetChannel), NULL},              /*46*/
-       {GEN_CMD_CODE(_SetTxPower), NULL},
-       {GEN_CMD_CODE(_SwitchAntenna), NULL},
-       {GEN_CMD_CODE(_SetCrystalCap), NULL},
-       {GEN_CMD_CODE(_SetSingleCarrierTx), NULL},      /*50*/
-
-       {GEN_CMD_CODE(_SetSingleToneTx), NULL}, /*51*/
-       {GEN_CMD_CODE(_SetCarrierSuppressionTx), NULL},
-       {GEN_CMD_CODE(_SetContinuousTx), NULL},
-       {GEN_CMD_CODE(_SwitchBandwidth), NULL},         /*54*/
-       {GEN_CMD_CODE(_TX_Beacon), NULL},/*55*/
-
-       {GEN_CMD_CODE(_Set_MLME_EVT), NULL},/*56*/
-       {GEN_CMD_CODE(_Set_Drv_Extra), NULL},/*57*/
-       {GEN_CMD_CODE(_Set_H2C_MSG), NULL},/*58*/
-       {GEN_CMD_CODE(_SetChannelPlan), NULL},/*59*/
-       {GEN_CMD_CODE(_LedBlink), NULL},/*60*/
-
-       {GEN_CMD_CODE(_SetChannelSwitch), NULL},/*61*/
-       {GEN_CMD_CODE(_TDLS), NULL},/*62*/
-};
-#endif
-
-#endif /*  _CMD_H_ */
diff --git a/drivers/staging/r8188eu/include/rtw_eeprom.h b/drivers/staging/r8188eu/include/rtw_eeprom.h
deleted file mode 100644 (file)
index 94d735b..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __RTW_EEPROM_H__
-#define __RTW_EEPROM_H__
-
-#include "osdep_service.h"
-#include "drv_types.h"
-
-struct eeprom_priv {
-       u8              bautoload_fail_flag;
-       u8              mac_addr[ETH_ALEN] __aligned(2); /* PermanentAddress */
-};
-
-#endif  /* __RTL871X_EEPROM_H__ */
diff --git a/drivers/staging/r8188eu/include/rtw_efuse.h b/drivers/staging/r8188eu/include/rtw_efuse.h
deleted file mode 100644 (file)
index 3d688a0..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __RTW_EFUSE_H__
-#define __RTW_EFUSE_H__
-
-#define                EFUSE_MAX_WORD_UNIT                     4
-
-void ReadEFuseByte(struct adapter *adapter, u16 _offset, u8 *pbuf);
-
-#endif
diff --git a/drivers/staging/r8188eu/include/rtw_event.h b/drivers/staging/r8188eu/include/rtw_event.h
deleted file mode 100644 (file)
index 54dc1ea..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef _RTW_EVENT_H_
-#define _RTW_EVENT_H_
-
-#include "osdep_service.h"
-
-#include "wlan_bssdef.h"
-#include <linux/semaphore.h>
-#include <linux/sem.h>
-
-/*
-Used to report a bss has been scanned
-*/
-struct survey_event    {
-       struct wlan_bssid_ex bss;
-};
-
-/*
-Used to report that the requested site survey has been done.
-
-bss_cnt indicates the number of bss that has been reported.
-
-*/
-struct surveydone_event {
-       unsigned int    bss_cnt;
-
-};
-
-/*
-Used to report the link result of joinning the given bss
-
-join_res:
--1: authentication fail
--2: association fail
-> 0: TID
-
-*/
-struct joinbss_event {
-       struct  wlan_network    network;
-};
-
-/*
-Used to report a given STA has joinned the created BSS.
-It is used in AP/Ad-HoC(M) mode.
-*/
-
-struct stassoc_event {
-       unsigned char macaddr[6];
-       unsigned char rsvd[2];
-       int    cam_id;
-};
-
-struct stadel_event {
-       unsigned char macaddr[6];
-       unsigned char rsvd[2]; /* for reason */
-       int mac_id;
-};
-
-struct addba_event {
-       unsigned int tid;
-};
-
-#define GEN_EVT_CODE(event)    event ## _EVT_
-
-struct fwevent {
-       u32     parmsize;
-       void (*event_callback)(struct adapter *dev, u8 *pbuf);
-};
-
-#define C2HEVENT_SZ                    32
-
-struct event_node {
-       unsigned char *node;
-       unsigned char evt_code;
-       unsigned short evt_sz;
-       int     *caller_ff_tail;
-       int     caller_ff_sz;
-};
-
-struct c2hevent_queue {
-       int     head;
-       int     tail;
-       struct  event_node      nodes[C2HEVENT_SZ];
-       unsigned char   seq;
-};
-
-#define NETWORK_QUEUE_SZ       4
-
-struct network_queue {
-       int     head;
-       int     tail;
-       struct wlan_bssid_ex networks[NETWORK_QUEUE_SZ];
-};
-
-#endif /*  _WLANEVENT_H_ */
diff --git a/drivers/staging/r8188eu/include/rtw_fw.h b/drivers/staging/r8188eu/include/rtw_fw.h
deleted file mode 100644 (file)
index 8f74157..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __RTW_FW_H__
-#define __RTW_FW_H__
-
-struct rt_firmware {
-       u8 *data;
-       u32 size;
-};
-
-#include "drv_types.h"
-
-int rtl8188e_firmware_download(struct adapter *padapter);
-void rtw_reset_8051(struct adapter *padapter);
-
-#endif
diff --git a/drivers/staging/r8188eu/include/rtw_ht.h b/drivers/staging/r8188eu/include/rtw_ht.h
deleted file mode 100644 (file)
index 2b56b7c..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef _RTW_HT_H_
-#define _RTW_HT_H_
-
-#include "osdep_service.h"
-#include "wifi.h"
-
-struct ht_priv {
-       u32     ht_option;
-       u32     ampdu_enable;/* for enable Tx A-MPDU */
-       u32     tx_amsdu_enable;/* for enable Tx A-MSDU */
-       u32     tx_amdsu_maxlen; /*  1: 8k, 0:4k ; default:8k, for tx */
-       u32     rx_ampdu_maxlen; /* for rx reordering ctrl win_sz,
-                                 * updated when join_callback. */
-       u8      bwmode;/*  */
-       u8      ch_offset;/* PRIME_CHNL_OFFSET */
-       u8      sgi;/* short GI */
-
-       /* for processing Tx A-MPDU */
-       u8      agg_enable_bitmap;
-       u8      candidate_tid_bitmap;
-
-       struct ieee80211_ht_cap ht_cap;
-};
-
-#endif /* _RTL871X_HT_H_ */
diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h
deleted file mode 100644 (file)
index e1718f7..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef _RTW_IO_H_
-#define _RTW_IO_H_
-
-#include "osdep_service.h"
-#include "osdep_intf.h"
-
-#include <asm/byteorder.h>
-#include <linux/semaphore.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <asm/atomic.h>
-
-#include <linux/usb.h>
-#include <linux/usb/ch9.h>
-
-int __must_check rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
-int __must_check rtw_read16(struct adapter *adapter, u32 addr, u16 *data);
-int __must_check rtw_read32(struct adapter *adapter, u32 addr, u32 *data);
-int rtw_read_port(struct adapter *adapter, struct recv_buf *precvbuf);
-void rtw_read_port_cancel(struct adapter *adapter);
-
-int rtw_write8(struct adapter *adapter, u32 addr, u8 val);
-int rtw_write16(struct adapter *adapter, u32 addr, u16 val);
-int rtw_write32(struct adapter *adapter, u32 addr, u32 val);
-int rtw_writeN(struct adapter *adapter, u32 addr, u32 length, u8 *pdata);
-
-u32 rtw_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-void rtw_write_port_cancel(struct adapter *adapter);
-
-#endif /* _RTL8711_IO_H_ */
diff --git a/drivers/staging/r8188eu/include/rtw_ioctl.h b/drivers/staging/r8188eu/include/rtw_ioctl.h
deleted file mode 100644 (file)
index c704f30..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef _RTW_IOCTL_H_
-#define _RTW_IOCTL_H_
-
-#include "osdep_service.h"
-#include "drv_types.h"
-
-extern struct iw_handler_def  rtw_handlers_def;
-extern int ui_pid[3];
-
-#endif /*  #ifndef __INC_CEINFO_ */
diff --git a/drivers/staging/r8188eu/include/rtw_ioctl_set.h b/drivers/staging/r8188eu/include/rtw_ioctl_set.h
deleted file mode 100644 (file)
index c3eb247..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __RTW_IOCTL_SET_H_
-#define __RTW_IOCTL_SET_H_
-
-#include "drv_types.h"
-
-typedef u8 NDIS_802_11_PMKID_VALUE[16];
-
-u8 rtw_set_802_11_authentication_mode(struct adapter *adapt,
-                                     enum ndis_802_11_auth_mode authmode);
-u8 rtw_set_802_11_bssid(struct adapter *adapter, u8 *bssid);
-u8 rtw_set_802_11_add_wep(struct adapter *adapter, struct ndis_802_11_wep *wep);
-void rtw_set_802_11_disassociate(struct adapter *adapter);
-u8 rtw_set_802_11_bssid_list_scan(struct adapter *adapter,
-                                 struct ndis_802_11_ssid *pssid,
-                                 int ssid_max_num);
-u8 rtw_set_802_11_infrastructure_mode(struct adapter *adapter,
-                                     enum ndis_802_11_network_infra type);
-u8 rtw_set_802_11_ssid(struct adapter *adapt, struct ndis_802_11_ssid *ssid);
-u16 rtw_get_cur_max_rate(struct adapter *adapter);
-int rtw_change_ifname(struct adapter *padapter, const char *ifname);
-
-#endif
diff --git a/drivers/staging/r8188eu/include/rtw_iol.h b/drivers/staging/r8188eu/include/rtw_iol.h
deleted file mode 100644 (file)
index 099f5a0..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __RTW_IOL_H_
-#define __RTW_IOL_H_
-
-#include "osdep_service.h"
-#include "drv_types.h"
-
-#define IOREG_CMD_END_LEN      4
-
-struct ioreg_cfg {
-       u8      length;
-       u8      cmd_id;
-       __le16  address;
-       __le32  data;
-       __le32  mask;
-};
-
-enum ioreg_cmd {
-       IOREG_CMD_LLT           = 0x01,
-       IOREG_CMD_REFUSE        = 0x02,
-       IOREG_CMD_EFUSE_PATH    = 0x03,
-       IOREG_CMD_WB_REG        = 0x04,
-       IOREG_CMD_WW_REG        = 0x05,
-       IOREG_CMD_WD_REG        = 0x06,
-       IOREG_CMD_W_RF          = 0x07,
-       IOREG_CMD_DELAY_US      = 0x10,
-       IOREG_CMD_DELAY_MS      = 0x11,
-       IOREG_CMD_END           = 0xFF,
-};
-
-struct xmit_frame *rtw_IOL_accquire_xmit_frame(struct adapter *adapter);
-int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds,
-                       u32 cmd_len);
-bool rtw_IOL_applied(struct adapter  *adapter);
-int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us);
-int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms);
-int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame);
-
-void read_efuse_from_txpktbuf(struct adapter *adapter, int bcnhead,
-                             u8 *content, u16 *size);
-
-int rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr,
-                         u8 value, u8 mask);
-int rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr,
-                         u16 value, u16 mask);
-int rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr,
-                         u32 value, u32 mask);
-int rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path,
-                          u16 addr, u32 value, u32 mask);
-
-u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame);
-
-#endif /* __RTW_IOL_H_ */
diff --git a/drivers/staging/r8188eu/include/rtw_led.h b/drivers/staging/r8188eu/include/rtw_led.h
deleted file mode 100644 (file)
index ea5f5ed..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __RTW_LED_H_
-#define __RTW_LED_H_
-
-#include "osdep_service.h"
-#include "drv_types.h"
-
-enum LED_CTL_MODE {
-       LED_CTL_LINK = 2,
-       LED_CTL_NO_LINK = 3,
-       LED_CTL_TX = 4,
-       LED_CTL_RX = 5,
-       LED_CTL_SITE_SURVEY = 6,
-       LED_CTL_POWER_OFF = 7,
-       LED_CTL_START_TO_LINK = 8,
-       LED_CTL_START_WPS = 9,
-       LED_CTL_STOP_WPS = 10,
-       LED_CTL_STOP_WPS_FAIL = 12,
-};
-
-enum LED_STATE_871x {
-       RTW_LED_OFF = 2,
-       LED_BLINK_NORMAL = 3,
-       LED_BLINK_SLOWLY = 4,
-       LED_BLINK_SCAN = 6, /*  LED is blinking during scanning period,
-                            * the # of times to blink is depend on time
-                            * for scanning. */
-       LED_BLINK_TXRX = 9,
-       LED_BLINK_WPS = 10,     /*  LED is blinkg during WPS communication */
-       LED_BLINK_WPS_STOP = 11,
-};
-
-struct led_priv {
-       bool bRegUseLed;
-
-       enum LED_STATE_871x     CurrLedState; /*  Current LED state. */
-
-       bool bLedOn; /*  true if LED is ON, false if LED is OFF. */
-
-       bool bLedBlinkInProgress; /*  true if it is blinking, false o.w.. */
-
-       bool bLedWPSBlinkInProgress;
-
-       u32 BlinkTimes; /*  Number of times to toggle led state for blinking. */
-
-       bool bLedScanBlinkInProgress;
-       struct delayed_work blink_work;
-};
-
-void rtl8188eu_InitSwLeds(struct adapter *padapter);
-void rtl8188eu_DeInitSwLeds(struct adapter *padapter);
-
-void rtw_led_control(struct adapter *padapter, enum LED_CTL_MODE LedAction);
-
-#endif /* __RTW_LED_H_ */
diff --git a/drivers/staging/r8188eu/include/rtw_mlme.h b/drivers/staging/r8188eu/include/rtw_mlme.h
deleted file mode 100644 (file)
index 3ff653f..0000000
+++ /dev/null
@@ -1,574 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __RTW_MLME_H_
-#define __RTW_MLME_H_
-
-#include "osdep_service.h"
-#include "drv_types.h"
-#include "wlan_bssdef.h"
-
-#define        MAX_BSS_CNT     128
-#define   MAX_JOIN_TIMEOUT     6500
-
-/* Increase the scanning timeout because of increasing the SURVEY_TO value. */
-
-#define                SCANNING_TIMEOUT        8000
-
-#define        SCAN_INTERVAL   (30) /*  unit:2sec, 30*2=60sec */
-
-#define        SCANQUEUE_LIFETIME 20 /*  unit:sec */
-
-#define        WIFI_NULL_STATE                 0x00000000
-
-#define        WIFI_ASOC_STATE                 0x00000001      /* Under Linked state */
-#define        WIFI_REASOC_STATE               0x00000002
-#define        WIFI_SLEEP_STATE                0x00000004
-#define        WIFI_STATION_STATE              0x00000008
-
-#define        WIFI_AP_STATE                   0x00000010
-#define        WIFI_ADHOC_STATE                0x00000020
-#define WIFI_ADHOC_MASTER_STATE                0x00000040
-#define WIFI_UNDER_LINKING             0x00000080
-
-#define        WIFI_UNDER_WPS                  0x00000100
-#define        WIFI_STA_ALIVE_CHK_STATE        0x00000400
-#define        WIFI_SITE_MONITOR               0x00000800      /* to indicate the station is under site surveying */
-
-#define        WIFI_MP_STATE                   0x00010000
-#define        WIFI_MP_CTX_BACKGROUND          0x00020000      /*  in continuous tx background */
-#define        WIFI_MP_CTX_ST                  0x00040000      /*  in continuous tx with single-tone */
-#define        WIFI_MP_CTX_BACKGROUND_PENDING  0x00080000      /*  pending in continuous tx background due to out of skb */
-#define        WIFI_MP_CTX_CCK_HW              0x00100000      /*  in continuous tx */
-#define        WIFI_MP_CTX_CCK_CS              0x00200000      /*  in continuous tx with carrier suppression */
-#define WIFI_MP_LPBK_STATE             0x00400000
-
-#define _FW_UNDER_LINKING      WIFI_UNDER_LINKING
-#define _FW_LINKED                     WIFI_ASOC_STATE
-#define _FW_UNDER_SURVEY       WIFI_SITE_MONITOR
-
-enum dot11AuthAlgrthmNum {
-       dot11AuthAlgrthm_Open = 0,
-       dot11AuthAlgrthm_Shared,
-       dot11AuthAlgrthm_8021X,
-       dot11AuthAlgrthm_Auto,
-       dot11AuthAlgrthm_WAPI,
-       dot11AuthAlgrthm_MaxNum
-};
-
-/*  Scan type including active and passive scan. */
-enum rt_scan_type {
-       SCAN_PASSIVE,
-       SCAN_ACTIVE,
-       SCAN_MIX,
-};
-
-/*
-there are several "locks" in mlme_priv,
-since mlme_priv is a shared resource between many threads,
-like ISR/Call-Back functions, the OID handlers, and even timer functions.
-
-Each _queue has its own locks, already.
-Other items are protected by mlme_priv.lock.
-
-To avoid possible dead lock, any thread trying to modifiying mlme_priv
-SHALL not lock up more than one lock at a time!
-*/
-
-#define traffic_threshold      10
-#define        traffic_scan_period     500
-
-struct sitesurvey_ctrl {
-       u64     last_tx_pkts;
-       uint    last_rx_pkts;
-       int     traffic_busy;
-       struct timer_list sitesurvey_ctrl_timer;
-};
-
-struct rt_link_detect {
-       u32     NumTxOkInPeriod;
-       u32     NumRxOkInPeriod;
-       u32     NumRxUnicastOkInPeriod;
-       bool    bBusyTraffic;
-       bool    bTxBusyTraffic;
-       bool    bRxBusyTraffic;
-       bool    bHigherBusyTraffic; /*  For interrupt migration purpose. */
-       bool    bHigherBusyRxTraffic; /* We may disable Tx interrupt according
-                                      * to Rx traffic. */
-       bool    bHigherBusyTxTraffic; /* We may disable Tx interrupt according
-                                      * to Tx traffic. */
-};
-
-struct profile_info {
-       u8      ssidlen;
-       u8      ssid[WLAN_SSID_MAXLEN];
-       u8      peermac[ETH_ALEN];
-};
-
-struct tx_invite_req_info {
-       u8      token;
-       u8      benable;
-       u8      go_ssid[WLAN_SSID_MAXLEN];
-       u8      ssidlen;
-       u8      go_bssid[ETH_ALEN];
-       u8      peer_macaddr[ETH_ALEN];
-       u8      operating_ch;   /* This information will be set by using the
-                                * p2p_set op_ch=x */
-       u8      peer_ch;        /* The listen channel for peer P2P device */
-};
-
-struct tx_invite_resp_info {
-       u8      token;  /* Used to record the dialog token of p2p invitation
-                        * request frame. */
-};
-
-struct tx_provdisc_req_info {
-       u16     wps_config_method_request;      /* Used when sending the
-                                                * provisioning request frame*/
-       u16     peer_channel_num[2];            /* The channel number which the
-                                                * receiver stands. */
-       struct ndis_802_11_ssid ssid;
-       u8      peerDevAddr[ETH_ALEN];          /* Peer device address */
-       u8      peerIFAddr[ETH_ALEN];           /* Peer interface address */
-       u8      benable;                        /* This provision discovery
-                                                * request frame is trigger
-                                                * to send or not */
-};
-
-/* When peer device issue prov_disc_req first, we should store the following
- * information */
-/* The UI must know this information to know which config method the
- * remote p2p device needs. */
-struct rx_provdisc_req_info {
-       u8      peerDevAddr[ETH_ALEN];          /* Peer device address */
-       u8      strconfig_method_desc_of_prov_disc_req[4];      /* description
-                       * for the config method located in the provisioning
-                       * discovery request frame. */
-};
-
-struct tx_nego_req_info {
-       u16     peer_channel_num[2];    /* The channel number. */
-       u8      peerDevAddr[ETH_ALEN];  /* Peer device address */
-       u8      benable;                /* This negotiation request frame is
-                                        * trigger to send or not */
-};
-
-struct group_id_info {
-       u8      go_device_addr[ETH_ALEN];       /* The GO's device address of
-                                                * this P2P group */
-       u8      ssid[WLAN_SSID_MAXLEN]; /* The SSID of this P2P group */
-};
-
-struct scan_limit_info {
-       u8      scan_op_ch_only;        /* When this flag is set, the driver
-                                        * should only scan the op. channel */
-       u8      operation_ch[2];        /* Store the op. chan of invitation */
-};
-
-struct wifidirect_info {
-       struct adapter *padapter;
-       struct timer_list find_phase_timer;
-       struct timer_list restore_p2p_state_timer;
-
-       /* Used to do the scanning. After confirming the peer is availalble,
-        * the driver transmits the P2P frame to peer. */
-       struct timer_list pre_tx_scan_timer;
-       struct timer_list reset_ch_sitesurvey;
-       struct timer_list reset_ch_sitesurvey2; /* Just for resetting the scan
-                                        * limit function by using p2p nego */
-       struct tx_provdisc_req_info     tx_prov_disc_info;
-       struct rx_provdisc_req_info rx_prov_disc_info;
-       struct tx_invite_req_info       invitereq_info;
-       /* Store the profile information of persistent group */
-       struct profile_info profileinfo[P2P_MAX_PERSISTENT_GROUP_NUM];
-       struct tx_invite_resp_info      inviteresp_info;
-       struct tx_nego_req_info nego_req_info;
-       /* Store the group id info when doing the group negot handshake. */
-       struct group_id_info groupid_info;
-       /* Used for get the limit scan channel from the Invitation procedure */
-       struct scan_limit_info rx_invitereq_info;
-       /* Used for get the limit scan chan from the P2P negotiation handshake*/
-       struct scan_limit_info p2p_info;
-       enum P2P_ROLE role;
-       enum P2P_STATE pre_p2p_state;
-       enum P2P_STATE p2p_state;
-       /* The device address should be the mac address of this device. */
-       u8 device_addr[ETH_ALEN];
-       u8 interface_addr[ETH_ALEN];
-       u8 social_chan[4];
-       u8 listen_channel;
-       u8 operating_channel;
-       u8 listen_dwell;        /* This value should be between 1 and 3 */
-       u8 support_rate[8];
-       u8 p2p_wildcard_ssid[P2P_WILDCARD_SSID_LEN];
-       u8 intent;      /* should only include the intent value. */
-       u8 p2p_peer_interface_addr[ETH_ALEN];
-       u8 p2p_peer_device_addr[ETH_ALEN];
-       u8 peer_intent; /* Included the intent value and tie breaker value. */
-       /* Device name for displaying on searching device screen */
-       u8 device_name[WPS_MAX_DEVICE_NAME_LEN];
-       u8 device_name_len;
-       u8 profileindex; /* Used to point to the index of profileinfo array */
-       u8 peer_operating_ch;
-       u8 find_phase_state_exchange_cnt;
-       /* The device password ID for group negotiation */
-       u16 device_password_id_for_nego;
-       u8 negotiation_dialog_token;
-       /* SSID information for group negotitation */
-       u8 nego_ssid[WLAN_SSID_MAXLEN];
-       u8 nego_ssidlen;
-       u8 p2p_group_ssid[WLAN_SSID_MAXLEN];
-       u8 p2p_group_ssid_len;
-       /* Flag to know if the persistent function should be supported or not.*/
-       u8 persistent_supported;
-       /* In the Sigma test, the Sigma will provide this enable from the
-        * sta_set_p2p CAPI. */
-       /*      0: disable */
-       /*      1: enable */
-       u8 session_available;   /* Flag to set the WFD session available to
-                                * enable or disable "by Sigma" */
-       /* In the Sigma test, the Sigma will disable the session available
-        * by using the sta_preset CAPI. */
-       /*      0: disable */
-       /*      1: enable */
-
-       /* This field will store the WPS value (PIN value or PBC) that UI had
-        * got from the user. */
-       enum    P2P_WPSINFO ui_got_wps_info;
-       u16 supported_wps_cm;   /* This field describes the WPS config method
-                                * which this driver supported. */
-                               /* The value should be the combination of config
-                                * method defined in page104 of WPS v2.0 spec.*/
-       /* This field will contain the length of body of P2P Channel List
-        * attribute of group negotiation response frame. */
-       uint channel_list_attr_len;
-       /* This field will contain the body of P2P Channel List attribute of
-        * group negotitation response frame. */
-       /* We will use the channel_cnt and channel_list fields when constructing
-        * the group negotiation confirm frame. */
-       u8 channel_list_attr[100];
-       enum P2P_PS_MODE p2p_ps_mode; /*  indicate p2p ps mode */
-       enum P2P_PS_STATE p2p_ps_state; /*  indicate p2p ps state */
-       u8 noa_index; /*  Identifies and instance of Notice of Absence timing. */
-       u8 ctwindow; /*  Client traffic window. A period of time in TU after TBTT. */
-       u8 opp_ps; /*  opportunistic power save. */
-       u8 noa_num; /*  number of NoA descriptor in P2P IE. */
-       u8 noa_count[P2P_MAX_NOA_NUM]; /*  Count for owner, Type of client. */
-       /* Max duration for owner, preferred or min acceptable duration for
-        * client. */
-       u32 noa_duration[P2P_MAX_NOA_NUM];
-       /* Length of interval for owner, preferred or max acceptable interval
-        * of client. */
-       u32 noa_interval[P2P_MAX_NOA_NUM];
-       /* schedule expressed in terms of the lower 4 bytes of the TSF timer. */
-       u32 noa_start_time[P2P_MAX_NOA_NUM];
-};
-
-struct tdls_ss_record {        /* signal strength record */
-       u8 macaddr[ETH_ALEN];
-       u8 RxPWDBAll;
-       u8 is_tdls_sta; /*  true: direct link sta, false: else */
-};
-
-struct tdls_info {
-       u8 ap_prohibited;
-       uint setup_state;
-       u8 sta_cnt;
-       u8 sta_maximum; /*  1:tdls sta is equal (NUM_STA-1), reach max direct link number; 0: else; */
-       struct tdls_ss_record   ss_record;
-       u8 macid_index; /* macid entry that is ready to write */
-       u8 clear_cam;   /* cam entry that is trying to clear, using it in direct link teardown */
-       u8 ch_sensing;
-       u8 cur_channel;
-       u8 candidate_ch;
-       u8 collect_pkt_num[MAX_CHANNEL_NUM];
-       spinlock_t cmd_lock;
-       spinlock_t hdl_lock;
-       u8 watchdog_count;
-       u8 dev_discovered;              /* WFD_TDLS: for sigma test */
-       u8 enable;
-};
-
-struct qos_priv {
-       /* bit mask option: u-apsd,
-        * s-apsd, ts, block ack... */
-       unsigned int qos_option;
-};
-
-struct mlme_priv {
-       spinlock_t lock;
-       int fw_state;   /* shall we protect this variable? maybe not necessarily... */
-       bool bScanInProcess;
-       u8 to_join; /* flag */
-       u8 to_roaming; /*  roaming trying times */
-
-       u8 *nic_hdl;
-
-       struct list_head *pscanned;
-       struct __queue free_bss_pool;
-       struct __queue scanned_queue;
-       u8 *free_bss_buf;
-       u8      key_mask; /* use to restore wep key after hal_init */
-       u32     num_of_scanned;
-
-       struct ndis_802_11_ssid assoc_ssid;
-       u8      assoc_bssid[6];
-
-       struct wlan_network     cur_network;
-       struct wlan_network *cur_network_scanned;
-
-       u32     scan_interval;
-
-       struct timer_list assoc_timer;
-
-       uint assoc_by_bssid;
-       uint assoc_by_rssi;
-
-       struct timer_list scan_to_timer; /*  driver itself handles scan_timeout status. */
-       u32 scan_start_time; /*  used to evaluate the time spent in scanning */
-
-       struct qos_priv qospriv;
-
-       /* Number of non-HT AP/stations */
-       int num_sta_no_ht;
-
-       /* Number of HT AP/stations 20 MHz */
-       /* int num_sta_ht_20mhz; */
-
-       int num_FortyMHzIntolerant;
-       struct ht_priv  htpriv;
-       struct rt_link_detect LinkDetectInfo;
-       struct timer_list dynamic_chk_timer; /* dynamic/periodic check timer */
-
-       u8      acm_mask; /*  for wmm acm mask */
-       u8      ChannelPlan;
-       enum rt_scan_type scan_mode; /*  active: 1, passive: 0 */
-
-       /* u8 probereq_wpsie[MAX_WPS_IE_LEN];added in probe req */
-       /* int probereq_wpsie_len; */
-       u8 *wps_probe_req_ie;
-       u32 wps_probe_req_ie_len;
-
-       u8 *assoc_req;
-       u32 assoc_req_len;
-
-       /* Number of associated Non-ERP stations (i.e., stations using 802.11b
-        * in 802.11g BSS) */
-       int num_sta_non_erp;
-
-       /* Number of associated stations that do not support Short Slot Time */
-       int num_sta_no_short_slot_time;
-
-       /* Number of associated stations that do not support Short Preamble */
-       int num_sta_no_short_preamble;
-
-       int olbc; /* Overlapping Legacy BSS Condition */
-
-       /* Number of HT assoc sta that do not support greenfield */
-       int num_sta_ht_no_gf;
-
-       /* Number of associated non-HT stations */
-       /* int num_sta_no_ht; */
-
-       /* Number of HT associated stations 20 MHz */
-       int num_sta_ht_20mhz;
-
-       /* Overlapping BSS information */
-       int olbc_ht;
-
-       u16 ht_op_mode;
-
-       u8 *wps_beacon_ie;
-       /* u8 *wps_probe_req_ie; */
-       u8 *wps_probe_resp_ie;
-       u8 *wps_assoc_resp_ie;
-
-       u32 wps_beacon_ie_len;
-       u32 wps_probe_resp_ie_len;
-       u32 wps_assoc_resp_ie_len;
-
-       u8 *p2p_beacon_ie;
-       u8 *p2p_probe_req_ie;
-       u8 *p2p_probe_resp_ie;
-       u8 *p2p_go_probe_resp_ie; /* for GO */
-       u8 *p2p_assoc_req_ie;
-
-       u32 p2p_beacon_ie_len;
-       u32 p2p_probe_req_ie_len;
-       u32 p2p_probe_resp_ie_len;
-       u32 p2p_go_probe_resp_ie_len; /* for GO */
-       u32 p2p_assoc_req_ie_len;
-       spinlock_t bcn_update_lock;
-       u8              update_bcn;
-};
-
-int hostapd_mode_init(struct adapter *padapter);
-void hostapd_mode_unload(struct adapter *padapter);
-
-extern unsigned char WPA_TKIP_CIPHER[4];
-extern unsigned char RSN_TKIP_CIPHER[4];
-extern unsigned char REALTEK_96B_IE[];
-extern unsigned char   MCS_rate_2R[16];
-extern unsigned char   MCS_rate_1R[16];
-
-void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf);
-void rtw_survey_event_callback(struct adapter *adapter, u8 *pbuf);
-void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf);
-void rtw_joinbss_event_callback(struct adapter *adapter, u8 *pbuf);
-void rtw_stassoc_event_callback(struct adapter *adapter, u8 *pbuf);
-void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf);
-void indicate_wx_scan_complete_event(struct adapter *padapter);
-void rtw_indicate_wx_assoc_event(struct adapter *padapter);
-void rtw_indicate_wx_disassoc_event(struct adapter *padapter);
-int event_thread(void *context);
-void rtw_free_network_queue(struct adapter *adapter, u8 isfreeall);
-int rtw_init_mlme_priv(struct adapter *adapter);
-void rtw_free_mlme_priv (struct mlme_priv *pmlmepriv);
-int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv);
-int rtw_set_key(struct adapter *adapter, struct security_priv *psecuritypriv,
-               int keyid, u8 set_tx);
-int rtw_set_auth(struct adapter *adapter, struct security_priv *psecuritypriv);
-
-static inline u8 *get_bssid(struct mlme_priv *pmlmepriv)
-{      /* if sta_mode:pmlmepriv->cur_network.network.MacAddress=> bssid */
-       /*  if adhoc_mode:pmlmepriv->cur_network.network.MacAddress=> ibss mac address */
-       return pmlmepriv->cur_network.network.MacAddress;
-}
-
-static inline bool check_fwstate(struct mlme_priv *pmlmepriv, int state)
-{
-       if (pmlmepriv->fw_state & state)
-               return true;
-
-       return false;
-}
-
-/*
- * No Limit on the calling context,
- * therefore set it to be the critical section...
- *
- * ### NOTE:#### (!!!!)
- * MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock
- */
-static inline void set_fwstate(struct mlme_priv *pmlmepriv, int state)
-{
-       pmlmepriv->fw_state |= state;
-       /* FOR HW integration */
-       if (_FW_UNDER_SURVEY == state)
-               pmlmepriv->bScanInProcess = true;
-}
-
-static inline void _clr_fwstate_(struct mlme_priv *pmlmepriv, int state)
-{
-       pmlmepriv->fw_state &= ~state;
-       /* FOR HW integration */
-       if (_FW_UNDER_SURVEY == state)
-               pmlmepriv->bScanInProcess = false;
-}
-
-/*
- * No Limit on the calling context,
- * therefore set it to be the critical section...
- */
-static inline void clr_fwstate(struct mlme_priv *pmlmepriv, int state)
-{
-       spin_lock_bh(&pmlmepriv->lock);
-       if (check_fwstate(pmlmepriv, state))
-               pmlmepriv->fw_state ^= state;
-       spin_unlock_bh(&pmlmepriv->lock);
-}
-
-static inline void clr_fwstate_ex(struct mlme_priv *pmlmepriv, int state)
-{
-       spin_lock_bh(&pmlmepriv->lock);
-       _clr_fwstate_(pmlmepriv, state);
-       spin_unlock_bh(&pmlmepriv->lock);
-}
-
-static inline void up_scanned_network(struct mlme_priv *pmlmepriv)
-{
-       spin_lock_bh(&pmlmepriv->lock);
-       pmlmepriv->num_of_scanned++;
-       spin_unlock_bh(&pmlmepriv->lock);
-}
-
-static inline void down_scanned_network(struct mlme_priv *pmlmepriv)
-{
-       spin_lock_bh(&pmlmepriv->lock);
-       pmlmepriv->num_of_scanned--;
-       spin_unlock_bh(&pmlmepriv->lock);
-}
-
-static inline void set_scanned_network_val(struct mlme_priv *pmlmepriv, int val)
-{
-       spin_lock_bh(&pmlmepriv->lock);
-       pmlmepriv->num_of_scanned = val;
-       spin_unlock_bh(&pmlmepriv->lock);
-}
-
-u16 rtw_get_capability(struct wlan_bssid_ex *bss);
-void rtw_update_scanned_network(struct adapter *adapter,
-                               struct wlan_bssid_ex *target);
-void rtw_disconnect_hdl_under_linked(struct adapter *adapter,
-                                    struct sta_info *psta, u8 free_assoc);
-void rtw_generate_random_ibss(u8 *pibss);
-struct wlan_network *rtw_find_network(struct __queue *scanned_queue, u8 *addr);
-struct wlan_network *rtw_get_oldest_wlan_network(struct __queue *scanned_queue);
-
-void rtw_free_assoc_resources(struct adapter *adapter, int lock_scanned_queue);
-void rtw_indicate_disconnect(struct adapter *adapter);
-void rtw_indicate_connect(struct adapter *adapter);
-void rtw_indicate_scan_done(struct adapter *padapter);
-
-int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie,
-                       uint in_len);
-int rtw_restruct_wmm_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie,
-                       uint in_len, uint initial_out_len);
-void rtw_init_registrypriv_dev_network(struct adapter *adapter);
-
-void rtw_update_registrypriv_dev_network(struct adapter *adapter);
-
-void _rtw_join_timeout_handler(struct adapter *adapter);
-void rtw_scan_timeout_handler(struct adapter *adapter);
-
- void rtw_dynamic_check_timer_handlder(struct adapter *adapter);
-
-void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv);
-
-struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv);
-
-void _rtw_free_network(struct mlme_priv *pmlmepriv,
-                      struct wlan_network *pnetwork, u8 isfreeall);
-
-struct wlan_network *_rtw_find_network(struct __queue *scanned_queue, u8 *addr);
-
-void _rtw_free_network_queue(struct adapter *padapter, u8 isfreeall);
-
-int rtw_if_up(struct adapter *padapter);
-
-u8 *rtw_get_capability_from_ie(u8 *ie);
-u8 *rtw_get_beacon_interval_from_ie(u8 *ie);
-
-void rtw_joinbss_reset(struct adapter *padapter);
-
-unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie,
-                                  u8 *out_ie, uint in_len, uint *pout_len);
-void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len);
-void rtw_issue_addbareq_cmd(struct adapter *padapter,
-                           struct xmit_frame *pxmitframe);
-
-int rtw_is_same_ibss(struct adapter *adapter, struct wlan_network *pnetwork);
-int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst);
-
-void rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network);
-void _rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network);
-void rtw_set_roaming(struct adapter *adapter, u8 to_roaming);
-u8 rtw_to_roaming(struct adapter *adapter);
-
-void rtw_set_max_rpt_macid(struct adapter *adapter, u8 macid);
-void rtw_sta_media_status_rpt(struct adapter *adapter, struct sta_info *psta,
-                             u32 mstatus);
-
-u8 rtw_current_antenna(struct adapter *adapter);
-
-#endif /* __RTL871X_MLME_H_ */
diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h
deleted file mode 100644 (file)
index 589de7c..0000000
+++ /dev/null
@@ -1,753 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __RTW_MLME_EXT_H_
-#define __RTW_MLME_EXT_H_
-
-#include "osdep_service.h"
-#include "drv_types.h"
-#include "wlan_bssdef.h"
-
-/*     Commented by Albert 20101105 */
-/*     Increase the SURVEY_TO value from 100 to 150  ( 100ms to 150ms ) */
-/*     The Realtek 8188CE SoftAP will spend around 100ms to send the probe response after receiving the probe request. */
-/*     So, this driver tried to extend the dwell time for each scanning channel. */
-/*     This will increase the chance to receive the probe response from SoftAP. */
-
-#define SURVEY_TO              (100)
-#define REAUTH_TO              (300) /* 50) */
-#define REASSOC_TO             (300) /* 50) */
-/* define DISCONNECT_TO        (3000) */
-#define ADDBA_TO                       (2000)
-
-#define LINKED_TO (1) /* unit:2 sec, 1x2=2 sec */
-
-#define REAUTH_LIMIT   (4)
-#define REASSOC_LIMIT  (4)
-
-#define        DYNAMIC_FUNC_DISABLE                    (0x0)
-
-/*  ====== ODM_ABILITY_E ======== */
-/*  BB ODM section BIT 0-15 */
-#define        DYNAMIC_BB_DIG                          BIT(0)
-
-#define                DYNAMIC_ALL_FUNC_ENABLE         0xFFFFFFF
-
-#define _HW_STATE_NOLINK_              0x00
-#define _HW_STATE_ADHOC_               0x01
-#define _HW_STATE_STATION_     0x02
-#define _HW_STATE_AP_                  0x03
-
-#define                _1M_RATE_       0
-#define                _2M_RATE_       1
-#define                _5M_RATE_       2
-#define                _11M_RATE_      3
-#define                _6M_RATE_       4
-#define                _9M_RATE_       5
-#define                _12M_RATE_      6
-#define                _18M_RATE_      7
-#define                _24M_RATE_      8
-#define                _36M_RATE_      9
-#define                _48M_RATE_      10
-#define                _54M_RATE_      11
-
-extern unsigned char RTW_WPA_OUI[];
-extern unsigned char WMM_OUI[];
-extern unsigned char WPS_OUI[];
-extern unsigned char WFD_OUI[];
-extern unsigned char P2P_OUI[];
-
-extern unsigned char WMM_INFO_OUI[];
-extern unsigned char WMM_PARA_OUI[];
-
-/*  Channel Plan Type. */
-/*  Note: */
-/*     We just add new channel plan when the new channel plan is different
- *      from any of the following channel plan. */
-/*     If you just want to customize the actions(scan period or join actions)
- *      about one of the channel plan, */
-/*     customize them in struct rt_channel_info in the RT_CHANNEL_LIST. */
-enum RT_CHANNEL_DOMAIN {
-       /*  old channel plan mapping =====  */
-       RT_CHANNEL_DOMAIN_FCC = 0x00,
-       RT_CHANNEL_DOMAIN_IC = 0x01,
-       RT_CHANNEL_DOMAIN_ETSI = 0x02,
-       RT_CHANNEL_DOMAIN_SPAIN = 0x03,
-       RT_CHANNEL_DOMAIN_FRANCE = 0x04,
-       RT_CHANNEL_DOMAIN_MKK = 0x05,
-       RT_CHANNEL_DOMAIN_MKK1 = 0x06,
-       RT_CHANNEL_DOMAIN_ISRAEL = 0x07,
-       RT_CHANNEL_DOMAIN_TELEC = 0x08,
-       RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN = 0x09,
-       RT_CHANNEL_DOMAIN_WORLD_WIDE_13 = 0x0A,
-       RT_CHANNEL_DOMAIN_TAIWAN = 0x0B,
-       RT_CHANNEL_DOMAIN_CHINA = 0x0C,
-       RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO = 0x0D,
-       RT_CHANNEL_DOMAIN_KOREA = 0x0E,
-       RT_CHANNEL_DOMAIN_TURKEY = 0x0F,
-       RT_CHANNEL_DOMAIN_JAPAN = 0x10,
-       RT_CHANNEL_DOMAIN_FCC_NO_DFS = 0x11,
-       RT_CHANNEL_DOMAIN_JAPAN_NO_DFS = 0x12,
-       RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS = 0x14,
-
-       /*  new channel plan mapping, (2GDOMAIN_5GDOMAIN) ===== */
-       RT_CHANNEL_DOMAIN_WORLD_NULL = 0x20,
-       RT_CHANNEL_DOMAIN_ETSI1_NULL = 0x21,
-       RT_CHANNEL_DOMAIN_FCC1_NULL = 0x22,
-       RT_CHANNEL_DOMAIN_MKK1_NULL = 0x23,
-       RT_CHANNEL_DOMAIN_ETSI2_NULL = 0x24,
-       RT_CHANNEL_DOMAIN_FCC1_FCC1 = 0x25,
-       RT_CHANNEL_DOMAIN_WORLD_ETSI1 = 0x26,
-       RT_CHANNEL_DOMAIN_MKK1_MKK1 = 0x27,
-       RT_CHANNEL_DOMAIN_WORLD_KCC1 = 0x28,
-       RT_CHANNEL_DOMAIN_WORLD_FCC2 = 0x29,
-       RT_CHANNEL_DOMAIN_WORLD_FCC3 = 0x30,
-       RT_CHANNEL_DOMAIN_WORLD_FCC4 = 0x31,
-       RT_CHANNEL_DOMAIN_WORLD_FCC5 = 0x32,
-       RT_CHANNEL_DOMAIN_WORLD_FCC6 = 0x33,
-       RT_CHANNEL_DOMAIN_FCC1_FCC7 = 0x34,
-       RT_CHANNEL_DOMAIN_WORLD_ETSI2 = 0x35,
-       RT_CHANNEL_DOMAIN_WORLD_ETSI3 = 0x36,
-       RT_CHANNEL_DOMAIN_MKK1_MKK2 = 0x37,
-       RT_CHANNEL_DOMAIN_MKK1_MKK3 = 0x38,
-       RT_CHANNEL_DOMAIN_FCC1_NCC1 = 0x39,
-       RT_CHANNEL_DOMAIN_FCC1_NCC2 = 0x40,
-       RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G = 0x41,
-       /*  Add new channel plan above this line=============== */
-       RT_CHANNEL_DOMAIN_MAX,
-       RT_CHANNEL_DOMAIN_REALTEK_DEFINE = 0x7F,
-};
-
-enum RT_CHANNEL_DOMAIN_2G {
-       RT_CHANNEL_DOMAIN_2G_WORLD = 0x00,              /* Worldwide 13 */
-       RT_CHANNEL_DOMAIN_2G_ETSI1 = 0x01,              /* Europe */
-       RT_CHANNEL_DOMAIN_2G_FCC1 = 0x02,               /* US */
-       RT_CHANNEL_DOMAIN_2G_MKK1 = 0x03,               /* Japan */
-       RT_CHANNEL_DOMAIN_2G_ETSI2 = 0x04,              /* France */
-       RT_CHANNEL_DOMAIN_2G_NULL = 0x05,
-       /*  Add new channel plan above this line=============== */
-       RT_CHANNEL_DOMAIN_2G_MAX,
-};
-
-#define rtw_is_channel_plan_valid(chplan)                      \
-       (chplan < RT_CHANNEL_DOMAIN_MAX ||                      \
-        chplan == RT_CHANNEL_DOMAIN_REALTEK_DEFINE)
-
-struct rt_channel_plan {
-       unsigned char   Channel[MAX_CHANNEL_NUM];
-       unsigned char   Len;
-};
-
-struct rt_channel_plan_map {
-       unsigned char   Index2G;
-};
-
-enum Associated_AP {
-       atherosAP       = 0,
-       broadcomAP      = 1,
-       ciscoAP         = 2,
-       marvellAP       = 3,
-       ralinkAP        = 4,
-       realtekAP       = 5,
-       airgocapAP      = 6,
-       unknownAP       = 7,
-       maxAP,
-};
-
-enum HT_IOT_PEER {
-       HT_IOT_PEER_UNKNOWN             = 0,
-       HT_IOT_PEER_REALTEK             = 1,
-       HT_IOT_PEER_REALTEK_92SE        = 2,
-       HT_IOT_PEER_BROADCOM            = 3,
-       HT_IOT_PEER_RALINK              = 4,
-       HT_IOT_PEER_ATHEROS             = 5,
-       HT_IOT_PEER_CISCO               = 6,
-       HT_IOT_PEER_MERU                = 7,
-       HT_IOT_PEER_MARVELL             = 8,
-       HT_IOT_PEER_REALTEK_SOFTAP      = 9,/*  peer is RealTek SOFT_AP */
-       HT_IOT_PEER_SELF_SOFTAP         = 10, /*  Self is SoftAP */
-       HT_IOT_PEER_AIRGO               = 11,
-       HT_IOT_PEER_INTEL               = 12,
-       HT_IOT_PEER_RTK_APCLIENT        = 13,
-       HT_IOT_PEER_REALTEK_81XX        = 14,
-       HT_IOT_PEER_REALTEK_WOW         = 15,
-       HT_IOT_PEER_TENDA               = 16,
-       HT_IOT_PEER_MAX                 = 17
-};
-
-enum SCAN_STATE {
-       SCAN_DISABLE = 0,
-       SCAN_START = 1,
-       SCAN_TXNULL = 2,
-       SCAN_PROCESS = 3,
-       SCAN_COMPLETE = 4,
-       SCAN_STATE_MAX,
-};
-
-typedef void (*mlme_handler)(struct adapter *adapt, struct recv_frame *frame);
-
-struct ss_res {
-       int     state;
-       int     bss_cnt;
-       int     channel_idx;
-       int     scan_mode;
-       u8 ssid_num;
-       u8 ch_num;
-       struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT];
-       struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
-};
-
-/* define AP_MODE                              0x0C */
-/* define STATION_MODE 0x08 */
-/* define AD_HOC_MODE          0x04 */
-/* define NO_LINK_MODE 0x00 */
-
-#define WIFI_FW_NULL_STATE             _HW_STATE_NOLINK_
-#define        WIFI_FW_STATION_STATE           _HW_STATE_STATION_
-#define        WIFI_FW_AP_STATE                _HW_STATE_AP_
-#define        WIFI_FW_ADHOC_STATE             _HW_STATE_ADHOC_
-
-#define        WIFI_FW_AUTH_NULL               0x00000100
-#define        WIFI_FW_AUTH_STATE              0x00000200
-#define        WIFI_FW_AUTH_SUCCESS            0x00000400
-
-#define        WIFI_FW_ASSOC_STATE             0x00002000
-#define        WIFI_FW_ASSOC_SUCCESS           0x00004000
-
-#define        WIFI_FW_LINKING_STATE           (WIFI_FW_AUTH_NULL |            \
-                                       WIFI_FW_AUTH_STATE |            \
-                                       WIFI_FW_AUTH_SUCCESS |          \
-                                       WIFI_FW_ASSOC_STATE)
-
-struct FW_Sta_Info {
-       struct sta_info *psta;
-       u32     status;
-       u32     rx_pkt;
-       u32     retry;
-       unsigned char SupportedRates[NDIS_802_11_LENGTH_RATES_EX];
-};
-
-/*
- * Usage:
- * When one iface acted as AP mode and the other iface is STA mode and scanning,
- * it should switch back to AP's operating channel periodically.
- * Parameters info:
- * When the driver scanned RTW_SCAN_NUM_OF_CH channels, it would switch back to
- * AP's operating channel for
- * RTW_STAY_AP_CH_MILLISECOND * SURVEY_TO milliseconds.
- * Example:
- * For chip supports 2.4G + 5GHz and AP mode is operating in channel 1,
- * RTW_SCAN_NUM_OF_CH is 8, RTW_STAY_AP_CH_MS is 3 and SURVEY_TO is 100.
- * When it's STA mode gets set_scan command,
- * it would
- * 1. Doing the scan on channel 1.2.3.4.5.6.7.8
- * 2. Back to channel 1 for 300 milliseconds
- * 3. Go through doing site survey on channel 9.10.11.36.40.44.48.52
- * 4. Back to channel 1 for 300 milliseconds
- * 5. ... and so on, till survey done.
- */
-
-struct mlme_ext_info {
-       u32     state;
-       u32     reauth_count;
-       u32     reassoc_count;
-       u32     link_count;
-       u32     auth_seq;
-       u32     auth_algo;      /*  802.11 auth, could be open, shared, auto */
-       u32     authModeToggle;
-       u32     enc_algo;/* encrypt algorithm; */
-       u32     key_index;      /*  this is only valid for legacy wep,
-                                *  0~3 for key id. */
-       u32     iv;
-       u8      chg_txt[128];
-       u16     aid;
-       u16     bcn_interval;
-       u16     capability;
-       u8      assoc_AP_vendor;
-       u8      slotTime;
-       u8      preamble_mode;
-       u8      WMM_enable;
-       u8      ERP_enable;
-       u8      ERP_IE;
-       u8      HT_enable;
-       u8      HT_caps_enable;
-       u8      HT_info_enable;
-       u8      HT_protection;
-       u8      turboMode_cts2self;
-       u8      turboMode_rtsen;
-       u8      SM_PS;
-       u8      agg_enable_bitmap;
-       u8      ADDBA_retry_count;
-       u8      candidate_tid_bitmap;
-       u8      dialogToken;
-       /*  Accept ADDBA Request */
-       bool bAcceptAddbaReq;
-       u8      bwmode_updated;
-       u8      hidden_ssid_mode;
-
-       struct WMM_para_element WMM_param;
-       struct HT_caps_element  HT_caps;
-       struct HT_info_element  HT_info;
-       struct wlan_bssid_ex    network;/* join network or bss_network,
-                                        * if in ap mode, it is the same
-                                        * as cur_network.network */
-       struct FW_Sta_Info      FW_sta_info[NUM_STA];
-};
-
-/*  The channel information about this channel including joining,
- *  scanning, and power constraints. */
-struct rt_channel_info {
-       u8      ChannelNum;     /*  The channel number. */
-       enum rt_scan_type ScanType;     /*  Scan type such as passive
-                                        *  or active scan. */
-       u32     rx_count;
-};
-
-int rtw_ch_set_search_ch(struct rt_channel_info *ch_set, const u32 ch);
-
-/*  P2P_MAX_REG_CLASSES - Maximum number of regulatory classes */
-#define P2P_MAX_REG_CLASSES 10
-
-/*  P2P_MAX_REG_CLASS_CHANNELS - Maximum number of chan per regulatory class */
-#define P2P_MAX_REG_CLASS_CHANNELS 20
-
-/*   struct p2p_channels - List of supported channels */
-struct p2p_channels {
-       /*  struct p2p_reg_class - Supported regulatory class */
-       struct p2p_reg_class {
-               /*  reg_class - Regulatory class (IEEE 802.11-2007, Annex J) */
-               u8 reg_class;
-
-               /*  channel - Supported channels */
-               u8 channel[P2P_MAX_REG_CLASS_CHANNELS];
-
-               /*  channels - Number of channel entries in use */
-               size_t channels;
-       } reg_class[P2P_MAX_REG_CLASSES];
-
-       /*  reg_classes - Number of reg_class entries in use */
-       size_t reg_classes;
-};
-
-struct p2p_oper_class_map {
-       enum hw_mode {IEEE80211G} mode;
-       u8 op_class;
-       u8 min_chan;
-       u8 max_chan;
-       u8 inc;
-       enum {BW20, BW40PLUS, BW40MINUS} bw;
-};
-
-struct mlme_ext_priv {
-       struct adapter  *padapter;
-       u8      mlmeext_init;
-       atomic_t event_seq;
-       u16     mgnt_seq;
-
-       unsigned char   cur_channel;
-       unsigned char   cur_bwmode;
-       unsigned char   cur_ch_offset;/* PRIME_CHNL_OFFSET */
-       unsigned char   cur_wireless_mode;      /*  NETWORK_TYPE */
-
-       unsigned char   oper_channel; /* saved chan info when call
-                                      * set_channel_bw */
-       unsigned char   oper_bwmode;
-       unsigned char   oper_ch_offset;/* PRIME_CHNL_OFFSET */
-
-       unsigned char   max_chan_nums;
-       struct rt_channel_info channel_set[MAX_CHANNEL_NUM];
-       struct p2p_channels channel_list;
-       unsigned char   basicrate[NumRates];
-       unsigned char   datarate[NumRates];
-
-       struct ss_res           sitesurvey_res;
-       struct mlme_ext_info    mlmext_info;/* for sta/adhoc mode, including
-                                            * current scan/connecting/connected
-                                            * related info. For ap mode,
-                                            * network includes ap's cap_info*/
-       struct timer_list survey_timer;
-       struct timer_list link_timer;
-       u16     chan_scan_time;
-
-       u8      scan_abort;
-       u8      tx_rate; /*  TXRATE when USERATE is set. */
-
-       u32     retry; /* retry for issue probereq */
-
-       u64 TSFValue;
-
-       unsigned char bstart_bss;
-       u8 update_channel_plan_by_ap_done;
-       /* recv_decache check for Action_public frame */
-       u8 action_public_dialog_token;
-       u16      action_public_rxseq;
-       u8 active_keep_alive_check;
-};
-
-void init_mlme_ext_priv(struct adapter *adapter);
-int init_hw_mlme_ext(struct adapter *padapter);
-void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext);
-struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv);
-
-unsigned char networktype_to_raid(unsigned char network_type);
-u8 judge_network_type(struct adapter *padapter, unsigned char *rate, int len);
-void get_rate_set(struct adapter *padapter, unsigned char *pbssrate, int *len);
-
-void Save_DM_Func_Flag(struct adapter *padapter);
-void Restore_DM_Func_Flag(struct adapter *padapter);
-
-void Set_MSR(struct adapter *padapter, u8 type);
-
-u8 rtw_get_oper_ch(struct adapter *adapter);
-void rtw_set_oper_ch(struct adapter *adapter, u8 ch);
-void rtw_set_oper_bw(struct adapter *adapter, u8 bw);
-void rtw_set_oper_choffset(struct adapter *adapter, u8 offset);
-
-void set_channel_bwmode(struct adapter *padapter, unsigned char channel,
-                       unsigned char channel_offset, unsigned short bwmode);
-void SelectChannel(struct adapter *padapter, unsigned char channel);
-void SetBWMode(struct adapter *padapter, unsigned short bwmode,
-              unsigned char channel_offset);
-
-unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval);
-
-void write_cam(struct adapter *padapter, u8 entry, u16 ctrl, u8 *mac, u8 *key);
-void clear_cam_entry(struct adapter *padapter, u8 entry);
-
-void invalidate_cam_all(struct adapter *padapter);
-
-int allocate_fw_sta_entry(struct adapter *padapter);
-void flush_all_cam_entry(struct adapter *padapter);
-
-void rtw_mlme_under_site_survey(struct adapter *adapter);
-void rtw_mlme_site_survey_done(struct adapter *adapter);
-
-void site_survey(struct adapter *padapter);
-u8 collect_bss_info(struct adapter *padapter, struct recv_frame *precv_frame,
-                   struct wlan_bssid_ex *bssid);
-void update_network(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src,
-                   struct adapter *adapter, bool update_ie);
-
-u8 *get_my_bssid(struct wlan_bssid_ex *pnetwork);
-u16 get_beacon_interval(struct wlan_bssid_ex *bss);
-
-bool r8188eu_is_client_associated_to_ap(struct adapter *padapter);
-bool r8188eu_is_client_associated_to_ibss(struct adapter *padapter);
-bool r8188eu_is_ibss_empty(struct adapter *padapter);
-
-unsigned char check_assoc_AP(u8 *pframe, uint len);
-
-int WMM_param_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE);
-void WMMOnAssocRsp(struct adapter *padapter);
-
-void HT_caps_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE);
-void HT_info_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE);
-void HTOnAssocRsp(struct adapter *padapter);
-
-void ERP_IE_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE);
-void VCS_update(struct adapter *padapter, struct sta_info *psta);
-
-void update_beacon_info(struct adapter *padapter, u8 *ie_ptr, uint ie_len, struct sta_info *psta);
-int rtw_check_bcn_info(struct adapter  *Adapter, u8 *pframe, u32 packet_len);
-void update_IOT_info(struct adapter *padapter);
-void update_capinfo(struct adapter *adapter, u16 updatecap);
-void update_wireless_mode(struct adapter *padapter);
-void rtw_set_basic_rate(struct adapter *adapter, u8 *rates);
-void update_tx_basic_rate(struct adapter *padapter, u8 modulation);
-void update_bmc_sta_support_rate(struct adapter *padapter, u32 mac_id);
-int update_sta_support_rate(struct adapter *padapter, u8 *pvar_ie,
-                           uint var_ie_len, int cam_idx);
-
-/* for sta/adhoc mode */
-void update_sta_info(struct adapter *padapter, struct sta_info *psta);
-unsigned int update_basic_rate(unsigned char *ptn, unsigned int ptn_sz);
-unsigned int update_supported_rate(unsigned char *ptn, unsigned int ptn_sz);
-unsigned int update_MSC_rate(struct HT_caps_element *pHT_caps);
-void Update_RA_Entry(struct adapter *padapter, u32 mac_id);
-void set_sta_rate(struct adapter *padapter, struct sta_info *psta);
-
-void receive_disconnect(struct adapter *padapter, unsigned char *macaddr, unsigned short reason);
-
-unsigned char get_highest_rate_idx(u32 mask);
-int support_short_GI(struct adapter *padapter, struct HT_caps_element *caps);
-bool is_ap_in_tkip(struct adapter *padapter);
-
-void report_join_res(struct adapter *padapter, int res);
-void report_survey_event(struct adapter *padapter, struct recv_frame *precv_frame);
-void report_surveydone_event(struct adapter *padapter);
-void report_del_sta_event(struct adapter *padapter,
-                         unsigned char *addr, unsigned short reason);
-void report_add_sta_event(struct adapter *padapter, unsigned char *addr,
-                         int cam_idx);
-
-void beacon_timing_control(struct adapter *padapter);
-u8 set_tx_beacon_cmd(struct adapter *padapter);
-unsigned int setup_beacon_frame(struct adapter *padapter,
-                               unsigned char *beacon_frame);
-void update_mgnt_tx_rate(struct adapter *padapter, u8 rate);
-void update_mgntframe_attrib(struct adapter *padapter,
-                            struct pkt_attrib *pattrib);
-void dump_mgntframe(struct adapter *padapter, struct xmit_frame *pmgntframe);
-s32 dump_mgntframe_and_wait(struct adapter *padapter,
-                           struct xmit_frame *pmgntframe, int timeout_ms);
-s32 dump_mgntframe_and_wait_ack(struct adapter *padapter,
-                               struct xmit_frame *pmgntframe);
-
-void issue_probersp_p2p(struct adapter *padapter, unsigned char *da);
-void issue_p2p_provision_request(struct adapter *padapter, u8 *pssid,
-                                u8 ussidlen, u8 *pdev_raddr);
-void issue_p2p_GO_request(struct adapter *padapter, u8 *raddr);
-void issue_probereq_p2p(struct adapter *padapter);
-void issue_p2p_invitation_response(struct adapter *padapter, u8 *raddr,
-                                  u8 dialogToken, u8 success);
-void issue_p2p_invitation_request(struct adapter *padapter, u8 *raddr);
-void issue_beacon(struct adapter *padapter, int timeout_ms);
-void issue_probersp(struct adapter *padapter, unsigned char *da,
-                   u8 is_valid_p2p_probereq);
-void issue_assocreq(struct adapter *padapter);
-void issue_asocrsp(struct adapter *padapter, unsigned short status,
-                  struct sta_info *pstat, int pkt_type);
-void issue_auth(struct adapter *padapter, struct sta_info *psta,
-               unsigned short status);
-void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid,
-                   u8 *da);
-void issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da);
-int issue_nulldata(struct adapter *padapter, unsigned char *da,
-                  unsigned int power_mode, int try_cnt, int wait_ms);
-int issue_qos_nulldata(struct adapter *padapter, unsigned char *da,
-                      u16 tid, int try_cnt, int wait_ms);
-int issue_deauth(struct adapter *padapter, unsigned char *da,
-                unsigned short reason);
-int issue_deauth_ex(struct adapter *padapter, u8 *da, unsigned short reason,
-                   int try_cnt, int wait_ms);
-void issue_action_BA(struct adapter *padapter, unsigned char *raddr, u8 action,
-                    u16 status, struct ieee80211_mgmt *mgmt_req);
-unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr);
-unsigned int send_beacon(struct adapter *padapter);
-bool get_beacon_valid_bit(struct adapter *adapter);
-void clear_beacon_valid_bit(struct adapter *adapter);
-void rtw_resume_tx_beacon(struct adapter *adapt);
-void rtw_stop_tx_beacon(struct adapter *adapt);
-
-void start_clnt_assoc(struct adapter *padapter);
-void start_clnt_auth(struct adapter *padapter);
-void start_clnt_join(struct adapter *padapter);
-void start_create_ibss(struct adapter *padapter);
-
-void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res);
-void mlmeext_sta_del_event_callback(struct adapter *padapter);
-void mlmeext_sta_add_event_callback(struct adapter *padapter,
-                                   struct sta_info *psta);
-
-void linked_status_chk(struct adapter *padapter);
-
-void survey_timer_hdl (struct adapter *padapter);
-void link_timer_hdl (struct adapter *padapter);
-void addba_timer_hdl(struct sta_info *psta);
-
-#define set_survey_timer(mlmeext, ms) \
-       do { \
-               _set_timer(&(mlmeext)->survey_timer, (ms)); \
-       } while (0)
-
-#define set_link_timer(mlmeext, ms) \
-       do { \
-               _set_timer(&(mlmeext)->link_timer, (ms)); \
-       } while (0)
-
-bool cckrates_included(unsigned char *rate, int ratelen);
-bool cckratesonly_included(unsigned char *rate, int ratelen);
-
-struct cmd_hdl {
-       uint    parmsize;
-       u8 (*h2cfuns)(struct adapter  *padapter, u8 *pbuf);
-};
-
-u8 read_macreg_hdl(struct adapter *padapter, u8 *pbuf);
-u8 write_macreg_hdl(struct adapter *padapter, u8 *pbuf);
-u8 read_bbreg_hdl(struct adapter *padapter, u8 *pbuf);
-u8 write_bbreg_hdl(struct adapter *padapter, u8 *pbuf);
-u8 read_rfreg_hdl(struct adapter *padapter, u8 *pbuf);
-u8 write_rfreg_hdl(struct adapter *padapter, u8 *pbuf);
-u8 NULL_hdl(struct adapter *padapter, u8 *pbuf);
-u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf);
-u8 disconnect_hdl(struct adapter *padapter, u8 *pbuf);
-u8 createbss_hdl(struct adapter *padapter, u8 *pbuf);
-u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf);
-u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf);
-u8 setauth_hdl(struct adapter *padapter, u8 *pbuf);
-u8 setkey_hdl(struct adapter *padapter, u8 *pbuf);
-u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf);
-u8 set_assocsta_hdl(struct adapter *padapter, u8 *pbuf);
-u8 del_assocsta_hdl(struct adapter *padapter, u8 *pbuf);
-u8 add_ba_hdl(struct adapter *padapter, unsigned char *pbuf);
-
-u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf);
-u8 h2c_msg_hdl(struct adapter *padapter, unsigned char *pbuf);
-u8 tx_beacon_hdl(struct adapter *padapter, unsigned char *pbuf);
-u8 set_ch_hdl(struct adapter *padapter, u8 *pbuf);
-u8 set_chplan_hdl(struct adapter *padapter, unsigned char *pbuf);
-u8 led_blink_hdl(struct adapter *padapter, unsigned char *pbuf);
-/* Handling DFS channel switch announcement ie. */
-u8 set_csa_hdl(struct adapter *padapter, unsigned char *pbuf);
-u8 tdls_hdl(struct adapter *padapter, unsigned char *pbuf);
-
-#define GEN_DRV_CMD_HANDLER(size, cmd) {size, &cmd ## _hdl},
-#define GEN_MLME_EXT_HANDLER(size, cmd)        {size, cmd},
-
-#ifdef _RTW_CMD_C_
-
-static struct cmd_hdl wlancmds[] = {
-       GEN_DRV_CMD_HANDLER(0, NULL) /*0*/
-       GEN_DRV_CMD_HANDLER(0, NULL)
-       GEN_DRV_CMD_HANDLER(0, NULL)
-       GEN_DRV_CMD_HANDLER(0, NULL)
-       GEN_DRV_CMD_HANDLER(0, NULL)
-       GEN_DRV_CMD_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL) /*10*/
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(sizeof (struct joinbss_parm), join_cmd_hdl) /*14*/
-       GEN_MLME_EXT_HANDLER(sizeof (struct disconnect_parm), disconnect_hdl)
-       GEN_MLME_EXT_HANDLER(sizeof (struct createbss_parm), createbss_hdl)
-       GEN_MLME_EXT_HANDLER(sizeof (struct setopmode_parm), setopmode_hdl)
-       GEN_MLME_EXT_HANDLER(sizeof (struct sitesurvey_parm),
-                            sitesurvey_cmd_hdl) /*18*/
-       GEN_MLME_EXT_HANDLER(sizeof (struct setauth_parm), setauth_hdl)
-       GEN_MLME_EXT_HANDLER(sizeof (struct setkey_parm), setkey_hdl) /*20*/
-       GEN_MLME_EXT_HANDLER(sizeof (struct set_stakey_parm), set_stakey_hdl)
-       GEN_MLME_EXT_HANDLER(sizeof (struct set_assocsta_parm), NULL)
-       GEN_MLME_EXT_HANDLER(sizeof (struct del_assocsta_parm), NULL)
-       GEN_MLME_EXT_HANDLER(sizeof (struct setstapwrstate_parm), NULL)
-       GEN_MLME_EXT_HANDLER(sizeof (struct setbasicrate_parm), NULL)
-       GEN_MLME_EXT_HANDLER(sizeof (struct getbasicrate_parm), NULL)
-       GEN_MLME_EXT_HANDLER(sizeof (struct setdatarate_parm), NULL)
-       GEN_MLME_EXT_HANDLER(sizeof (struct getdatarate_parm), NULL)
-       GEN_MLME_EXT_HANDLER(sizeof (struct setphyinfo_parm), NULL)
-       GEN_MLME_EXT_HANDLER(sizeof (struct getphyinfo_parm), NULL)  /*30*/
-       GEN_MLME_EXT_HANDLER(sizeof (struct setphy_parm), NULL)
-       GEN_MLME_EXT_HANDLER(sizeof (struct getphy_parm), NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)   /*40*/
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(sizeof(struct addBaReq_parm), add_ba_hdl)
-       GEN_MLME_EXT_HANDLER(sizeof(struct set_ch_parm), set_ch_hdl) /* 46 */
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL) /*50*/
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(0, NULL)
-       GEN_MLME_EXT_HANDLER(sizeof(struct Tx_Beacon_param),
-                            tx_beacon_hdl) /*55*/
-
-       GEN_MLME_EXT_HANDLER(0, mlme_evt_hdl) /*56*/
-       GEN_MLME_EXT_HANDLER(0, rtw_drvextra_cmd_hdl) /*57*/
-
-       GEN_MLME_EXT_HANDLER(0, h2c_msg_hdl) /*58*/
-       GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelPlan_param),
-                            set_chplan_hdl) /*59*/
-       GEN_MLME_EXT_HANDLER(sizeof(struct LedBlink_param),
-                            led_blink_hdl) /*60*/
-
-       GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelSwitch_param),
-                            set_csa_hdl) /*61*/
-       GEN_MLME_EXT_HANDLER(sizeof(struct TDLSoption_param),
-                            tdls_hdl) /*62*/
-};
-
-#endif
-
-struct C2HEvent_Header {
-#ifdef __LITTLE_ENDIAN
-       unsigned int len:16;
-       unsigned int ID:8;
-       unsigned int seq:8;
-#elif defined(__BIG_ENDIAN)
-       unsigned int seq:8;
-       unsigned int ID:8;
-       unsigned int len:16;
-#endif
-       unsigned int rsvd;
-};
-
-enum rtw_c2h_event {
-       GEN_EVT_CODE(_Read_MACREG) = 0, /*0*/
-       GEN_EVT_CODE(_Read_BBREG),
-       GEN_EVT_CODE(_Read_RFREG),
-       GEN_EVT_CODE(_Read_EEPROM),
-       GEN_EVT_CODE(_Read_EFUSE),
-       GEN_EVT_CODE(_Read_CAM),        /*5*/
-       GEN_EVT_CODE(_Get_BasicRate),
-       GEN_EVT_CODE(_Get_DataRate),
-       GEN_EVT_CODE(_Survey),   /*8*/
-       GEN_EVT_CODE(_SurveyDone),       /*9*/
-
-       GEN_EVT_CODE(_JoinBss), /*10*/
-       GEN_EVT_CODE(_AddSTA),
-       GEN_EVT_CODE(_DelSTA),
-       GEN_EVT_CODE(_AtimDone),
-       GEN_EVT_CODE(_TX_Report),
-       GEN_EVT_CODE(_CCX_Report),              /*15*/
-       GEN_EVT_CODE(_DTM_Report),
-       GEN_EVT_CODE(_TX_Rate_Statistics),
-       GEN_EVT_CODE(_C2HLBK),
-       GEN_EVT_CODE(_FWDBG),
-       GEN_EVT_CODE(_C2HFEEDBACK),             /*20*/
-       GEN_EVT_CODE(_ADDBA),
-       GEN_EVT_CODE(_C2HBCN),
-       GEN_EVT_CODE(_ReportPwrState),  /* filen: only for PCIE, USB */
-       GEN_EVT_CODE(_CloseRF),         /* filen: only for PCIE,
-                                        * work around ASPM */
-       MAX_C2HEVT
-};
-
-#ifdef _RTW_MLME_EXT_C_
-
-static struct fwevent wlanevents[] = {
-       {0, NULL},      /*0*/
-       {0, NULL},
-       {0, NULL},
-       {0, NULL},
-       {0, NULL},
-       {0, NULL},
-       {0, NULL},
-       {0, NULL},
-       {0, &rtw_survey_event_callback},                /*8*/
-       {sizeof (struct surveydone_event), &rtw_surveydone_event_callback},/*9*/
-       {0, &rtw_joinbss_event_callback},               /*10*/
-       {sizeof(struct stassoc_event), &rtw_stassoc_event_callback},
-       {sizeof(struct stadel_event), &rtw_stadel_event_callback},
-       {0, NULL},
-       {0, NULL},
-       {0, NULL},      /*15*/
-       {0, NULL},
-       {0, NULL},
-       {0, NULL},
-       {0, NULL},
-       {0, NULL},       /*20*/
-       {0, NULL},
-       {0, NULL},
-       {0, NULL},
-       {0, NULL},
-};
-
-#endif/* _RTL_MLME_EXT_C_ */
-
-#endif /* __RTW_MLME_EXT_H_ */
diff --git a/drivers/staging/r8188eu/include/rtw_p2p.h b/drivers/staging/r8188eu/include/rtw_p2p.h
deleted file mode 100644 (file)
index b91322a..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __RTW_P2P_H_
-#define __RTW_P2P_H_
-
-#include "drv_types.h"
-
-u32 build_beacon_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf);
-u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf);
-u32 build_prov_disc_request_p2p_ie(struct wifidirect_info *pwdinfo,
-                                  u8 *pbuf, u8 *pssid, u8 ussidlen,
-                                  u8 *pdev_raddr);
-u32 build_assoc_resp_p2p_ie(struct wifidirect_info *pwdinfo,
-                           u8 *pbuf, u8 status_code);
-u32 process_probe_req_p2p_ie(struct wifidirect_info *pwdinfo,
-                            u8 *pframe, uint len);
-u32 process_assoc_req_p2p_ie(struct wifidirect_info *pwdinfo,
-                            u8 *pframe, uint len, struct sta_info *psta);
-u32 process_p2p_devdisc_req(struct wifidirect_info *pwdinfo,
-                           u8 *pframe, uint len);
-u32 process_p2p_devdisc_resp(struct wifidirect_info *pwdinfo,
-                            u8 *pframe, uint len);
-u8 process_p2p_provdisc_req(struct wifidirect_info *pwdinfo,
-                           u8 *pframe, uint len);
-u8 process_p2p_provdisc_resp(struct wifidirect_info *pwdinfo,  u8 *pframe);
-u8 process_p2p_group_negotation_req(struct wifidirect_info *pwdinfo,
-                                   u8 *pframe, uint len);
-u8 process_p2p_group_negotation_resp(struct wifidirect_info *pwdinfo,
-                                    u8 *pframe, uint len);
-u8 process_p2p_group_negotation_confirm(struct wifidirect_info *pwdinfo,
-                                       u8 *pframe, uint len);
-u8 process_p2p_presence_req(struct wifidirect_info *pwdinfo, u8 *pframe,
-                           uint len);
-void p2p_protocol_wk_hdl(struct adapter *padapter, int intcmdtype);
-void process_p2p_ps_ie(struct adapter *padapter, u8 *ies, u32 ielength);
-void p2p_ps_wk_hdl(struct adapter *padapter, u8 p2p_ps_state);
-u8 p2p_ps_wk_cmd(struct adapter *padapter, u8 p2p_ps_state, u8 enqueue);
-void reset_global_wifidirect_info(struct adapter *padapter);
-int rtw_init_wifi_display_info(struct adapter *padapter);
-void rtw_init_wifidirect_timers(struct adapter *padapter);
-void rtw_init_wifidirect_addrs(struct adapter *padapter, u8 *dev_addr,
-                              u8 *iface_addr);
-void init_wifidirect_info(struct adapter *padapter, enum P2P_ROLE role);
-int rtw_p2p_enable(struct adapter *padapter, enum P2P_ROLE role);
-
-static inline void _rtw_p2p_set_state(struct wifidirect_info *wdinfo,
-                                     enum P2P_STATE state)
-{
-       if (wdinfo->p2p_state != state)
-               wdinfo->p2p_state = state;
-}
-
-static inline void _rtw_p2p_set_pre_state(struct wifidirect_info *wdinfo,
-                                         enum P2P_STATE state)
-{
-       if (wdinfo->pre_p2p_state != state)
-               wdinfo->pre_p2p_state = state;
-}
-
-static inline void _rtw_p2p_set_role(struct wifidirect_info *wdinfo,
-                                    enum P2P_ROLE role)
-{
-       if (wdinfo->role != role)
-               wdinfo->role = role;
-}
-
-static inline int _rtw_p2p_state(struct wifidirect_info *wdinfo)
-{
-       return wdinfo->p2p_state;
-}
-
-static inline int _rtw_p2p_pre_state(struct wifidirect_info *wdinfo)
-{
-       return wdinfo->pre_p2p_state;
-}
-
-static inline int _rtw_p2p_role(struct wifidirect_info *wdinfo)
-{
-       return wdinfo->role;
-}
-
-static inline bool _rtw_p2p_chk_state(struct wifidirect_info *wdinfo,
-                                     enum P2P_STATE state)
-{
-       return wdinfo->p2p_state == state;
-}
-
-static inline bool _rtw_p2p_chk_role(struct wifidirect_info *wdinfo,
-                                    enum P2P_ROLE role)
-{
-       return wdinfo->role == role;
-}
-
-#define rtw_p2p_set_state(wdinfo, state) _rtw_p2p_set_state(wdinfo, state)
-#define rtw_p2p_set_pre_state(wdinfo, state)                           \
-        _rtw_p2p_set_pre_state(wdinfo, state)
-#define rtw_p2p_set_role(wdinfo, role) _rtw_p2p_set_role(wdinfo, role)
-
-#define rtw_p2p_state(wdinfo) _rtw_p2p_state(wdinfo)
-#define rtw_p2p_pre_state(wdinfo) _rtw_p2p_pre_state(wdinfo)
-#define rtw_p2p_role(wdinfo) _rtw_p2p_role(wdinfo)
-#define rtw_p2p_chk_state(wdinfo, state) _rtw_p2p_chk_state(wdinfo, state)
-#define rtw_p2p_chk_role(wdinfo, role) _rtw_p2p_chk_role(wdinfo, role)
-
-#define rtw_p2p_findphase_ex_set(wdinfo, value) \
-       ((wdinfo)->find_phase_state_exchange_cnt = (value))
-
-/* is this find phase exchange for social channel scan? */
-#define rtw_p2p_findphase_ex_is_social(wdinfo)   \
-((wdinfo)->find_phase_state_exchange_cnt >= P2P_FINDPHASE_EX_SOCIAL_FIRST)
-
-/* should we need find phase exchange anymore? */
-#define rtw_p2p_findphase_ex_is_needed(wdinfo) \
-       ((wdinfo)->find_phase_state_exchange_cnt < P2P_FINDPHASE_EX_MAX && \
-       (wdinfo)->find_phase_state_exchange_cnt != P2P_FINDPHASE_EX_NONE)
-
-#endif
diff --git a/drivers/staging/r8188eu/include/rtw_pwrctrl.h b/drivers/staging/r8188eu/include/rtw_pwrctrl.h
deleted file mode 100644 (file)
index 9f5cffd..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-#ifndef __RTW_PWRCTRL_H_
-#define __RTW_PWRCTRL_H_
-
-#include "osdep_service.h"
-#include "drv_types.h"
-
-#define XMIT_ALIVE     BIT(0)
-#define RECV_ALIVE     BIT(1)
-#define CMD_ALIVE      BIT(2)
-#define EVT_ALIVE      BIT(3)
-
-enum power_mgnt {
-       PS_MODE_ACTIVE = 0,
-       PS_MODE_MIN,
-       PS_MODE_MAX,
-       PS_MODE_DTIM,
-       PS_MODE_VOIP,
-       PS_MODE_UAPSD_WMM,
-       PM_Card_Disable,
-       PS_MODE_NUM
-};
-
-#define LPS_DELAY_TIME 1*HZ /*  1 sec */
-
-/*  RF state. */
-enum rt_rf_power_state {
-       rf_on,          /*  RF is on after RFSleep or RFOff */
-       rf_sleep,       /*  802.11 Power Save mode */
-       rf_off,         /*  HW/SW Radio OFF or Inactive Power Save */
-       /* Add the new RF state above this line===== */
-       rf_max
-};
-
-enum { /*  for ips_mode */
-       IPS_NONE = 0,
-       IPS_NORMAL,
-       IPS_LEVEL_2,
-};
-
-struct pwrctrl_priv {
-       struct mutex lock; /* Mutex used to protect struct pwrctrl_priv */
-
-       u8      pwr_mode;
-       u8      smart_ps;
-       u8      bcn_ant_mode;
-
-       bool    bpower_saving;
-
-       uint    ips_enter_cnts;
-       uint    ips_leave_cnts;
-
-       u8      ips_mode;
-       u8      ips_mode_req;   /*  used to accept the mode setting request,
-                                *  will update to ipsmode later */
-       uint bips_processing;
-       unsigned long ips_deny_time; /* will deny IPS when system time less than this */
-       u8 ps_processing; /* temp used to mark whether in rtw_ps_processor */
-
-       u8      bLeisurePs;
-       u8      LpsIdleCount;
-       u8      power_mgnt;
-       u8      bFwCurrentInPSMode;
-       u32     DelayLPSLastTimeStamp;
-
-       u8              bInSuspend;
-       u8              bSupportRemoteWakeup;
-       struct timer_list pwr_state_check_timer;
-       int             pwr_state_check_interval;
-
-       enum rt_rf_power_state  rf_pwrstate;/* cur power state */
-
-       u8              bkeepfwalive;
-};
-
-#define rtw_get_ips_mode_req(pwrctrlpriv) \
-       (pwrctrlpriv)->ips_mode_req
-
-#define rtw_ips_mode_req(pwrctrlpriv, ips_mode) \
-       ((pwrctrlpriv)->ips_mode_req = (ips_mode))
-
-#define RTW_PWR_STATE_CHK_INTERVAL 2000
-
-#define _rtw_set_pwr_state_check_timer(pwrctrlpriv, ms) \
-       do { \
-               _set_timer(&(pwrctrlpriv)->pwr_state_check_timer, (ms)); \
-       } while (0)
-
-#define rtw_set_pwr_state_check_timer(pwrctrl)                 \
-       _rtw_set_pwr_state_check_timer((pwrctrl),               \
-                                      (pwrctrl)->pwr_state_check_interval)
-
-void rtw_init_pwrctrl_priv(struct adapter *adapter);
-
-void rtw_set_firmware_ps_mode(struct adapter *adapter, u8 mode);
-void rtw_set_ps_mode(struct adapter *adapter, u8 ps_mode, u8 smart_ps,
-                    u8 bcn_ant_mode);
-void LeaveAllPowerSaveMode(struct adapter *adapter);
-
-void rtw_ps_processor(struct adapter *padapter);
-
-void LPS_Enter(struct adapter *adapter);
-void LPS_Leave(struct adapter *adapter);
-
-int rtw_pwr_wakeup(struct adapter *adapter);
-int rtw_pm_set_ips(struct adapter *adapter, u8 mode);
-int rtw_pm_set_lps(struct adapter *adapter, u8 mode);
-
-#endif  /* __RTL871X_PWRCTRL_H_ */
diff --git a/drivers/staging/r8188eu/include/rtw_recv.h b/drivers/staging/r8188eu/include/rtw_recv.h
deleted file mode 100644 (file)
index 1202643..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-#ifndef _RTW_RECV_H_
-#define _RTW_RECV_H_
-
-#include "osdep_service.h"
-#include "drv_types.h"
-
-#define NR_RECVFRAME 256
-
-#define RXFRAME_ALIGN  8
-#define RXFRAME_ALIGN_SZ       (1<<RXFRAME_ALIGN)
-
-#define MAX_RXFRAME_CNT        512
-#define MAX_RX_NUMBLKS         (32)
-#define RECVFRAME_HDR_ALIGN 128
-
-#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
-
-#define MAX_SUBFRAME_COUNT     64
-
-#define LLC_HEADER_SIZE 6
-
-/* for Rx reordering buffer control */
-struct recv_reorder_ctrl {
-       struct adapter  *padapter;
-       u8 enable;
-       u16 indicate_seq;/* wstart_b, init_value=0xffff */
-       u16 wend_b;
-       u8 wsize_b;
-       struct __queue pending_recvframe_queue;
-       struct timer_list reordering_ctrl_timer;
-};
-
-struct stainfo_rxcache {
-       u16     tid_rxseq[16];
-/*
-       unsigned short  tid0_rxseq;
-       unsigned short  tid1_rxseq;
-       unsigned short  tid2_rxseq;
-       unsigned short  tid3_rxseq;
-       unsigned short  tid4_rxseq;
-       unsigned short  tid5_rxseq;
-       unsigned short  tid6_rxseq;
-       unsigned short  tid7_rxseq;
-       unsigned short  tid8_rxseq;
-       unsigned short  tid9_rxseq;
-       unsigned short  tid10_rxseq;
-       unsigned short  tid11_rxseq;
-       unsigned short  tid12_rxseq;
-       unsigned short  tid13_rxseq;
-       unsigned short  tid14_rxseq;
-       unsigned short  tid15_rxseq;
-*/
-};
-
-struct signal_stat {
-       u8      update_req;             /* used to indicate */
-       u8      avg_val;                /* avg of valid elements */
-       u32     total_num;              /* num of valid elements */
-       u32     total_val;              /* sum of valid elements */
-};
-#define MAX_PATH_NUM_92CS              3
-struct phy_info {
-       u8      RxPWDBAll;
-       u8      SignalQuality;   /*  in 0-100 index. */
-       u8      RxMIMOSignalStrength[MAX_PATH_NUM_92CS];/*  in 0~100 index */
-       s8      RxPower; /*  in dBm Translate from PWdB */
-/*  Real power in dBm for this packet, no beautification and aggregation.
- * Keep this raw info to be used for the other procedures. */
-       s8      recvpower;
-       u8      SignalStrength; /*  in 0-100 index. */
-       u8      RxPwr[MAX_PATH_NUM_92CS];/* per-path's pwdb */
-};
-
-struct rx_pkt_attrib {
-       u16     pkt_len;
-       u8      physt;
-       u8      drvinfo_sz;
-       u8      shift_sz;
-       u8      hdrlen; /* the WLAN Header Len */
-       u8      amsdu;
-       bool    qos;
-       u8      priority;
-       u8      pw_save;
-       u8      mdata;
-       u16     seq_num;
-       u8      frag_num;
-       u8      mfrag;
-       u8      order;
-       u8      privacy; /* in frame_ctrl field */
-       u8      bdecrypted;
-       u8      encrypt; /* when 0 indicate no encrypt. when non-zero,
-                         * indicate the encrypt algorithm */
-       u8      iv_len;
-       u8      icv_len;
-       u8      crc_err;
-       u8      icv_err;
-
-       u16 eth_type;
-
-       u8      dst[ETH_ALEN] __aligned(2);
-       u8      src[ETH_ALEN] __aligned(2);
-       u8      ta[ETH_ALEN] __aligned(2);
-       u8      ra[ETH_ALEN] __aligned(2);
-       u8      bssid[ETH_ALEN] __aligned(2);
-
-       u8 ack_policy;
-
-       u8      key_index;
-
-       u8      mcs_rate;
-       u8      rxht;
-       u8      sgi;
-       u8      pkt_rpt_type;
-       u32     MacIDValidEntry[2];     /*  64 bits present 64 entry. */
-
-       struct phy_info phy_info;
-};
-
-/* These definition is used for Rx packet reordering. */
-#define SN_LESS(a, b)          (((a - b) & 0x800) != 0)
-#define SN_EQUAL(a, b) (a == b)
-#define REORDER_WAIT_TIME      (50) /*  (ms) */
-
-#define RECVBUFF_ALIGN_SZ 8
-
-#define RXDESC_SIZE    24
-#define RXDESC_OFFSET RXDESC_SIZE
-
-struct recv_stat {
-       __le32 rxdw0;
-       __le32 rxdw1;
-       __le32 rxdw2;
-       __le32 rxdw3;
-       __le32 rxdw4;
-       __le32 rxdw5;
-};
-
-#define EOR BIT(30)
-
-/*
-accesser of recv_priv: rtw_recv_entry(dispatch / passive level);
-recv_thread(passive) ; returnpkt(dispatch)
-; halt(passive) ;
-
-using enter_critical section to protect
-*/
-struct recv_priv {
-       spinlock_t lock;
-       struct __queue free_recv_queue;
-       struct __queue recv_pending_queue;
-       struct __queue uc_swdec_pending_queue;
-       u8 *pallocated_frame_buf;
-       u8 *precv_frame_buf;
-       uint free_recvframe_cnt;
-       struct adapter  *adapter;
-       u32     bIsAnyNonBEPkts;
-       u64     rx_bytes;
-       u64     rx_pkts;
-       u64     rx_drop;
-       u64     last_rx_bytes;
-
-       uint  rx_icv_err;
-       uint  rx_largepacket_crcerr;
-       uint  rx_smallpacket_crcerr;
-       uint  rx_middlepacket_crcerr;
-       u8      rx_pending_cnt;
-
-       struct tasklet_struct recv_tasklet;
-       struct sk_buff_head free_recv_skb_queue;
-       struct sk_buff_head rx_skb_queue;
-       u8 *pallocated_recv_buf;
-       u8 *precv_buf;    /*  4 alignment */
-       struct __queue free_recv_buf_queue;
-       u32     free_recv_buf_queue_cnt;
-       /* For display the phy information */
-       u8 is_signal_dbg;       /*  for debug */
-       u8 signal_strength_dbg; /*  for debug */
-       s8 rssi;
-       s8 rxpwdb;
-       u8 signal_strength;
-       u8 signal_qual;
-       u8 noise;
-       int RxSNRdB[2];
-       s8 RxRssi[2];
-       int FalseAlmCnt_all;
-
-       struct timer_list signal_stat_timer;
-       u32 signal_stat_sampling_interval;
-       struct signal_stat signal_qual_data;
-       struct signal_stat signal_strength_data;
-};
-
-#define rtw_set_signal_stat_timer(recvpriv)                    \
-       _set_timer(&(recvpriv)->signal_stat_timer,              \
-                  (recvpriv)->signal_stat_sampling_interval)
-
-struct sta_recv_priv {
-       spinlock_t lock;
-       int     option;
-       struct __queue defrag_q; /* keeping the fragment frame until defrag */
-       struct  stainfo_rxcache rxcache;
-};
-
-struct recv_buf {
-       struct adapter *adapter;
-       struct urb *purb;
-       struct sk_buff *pskb;
-       u8      reuse;
-};
-
-/*
-       head  ----->
-
-               data  ----->
-
-                       payload
-
-               tail  ----->
-
-       end   ----->
-
-       len = (unsigned int )(tail - data);
-
-*/
-struct recv_frame {
-       struct list_head list;
-       struct sk_buff   *pkt;
-       struct adapter  *adapter;
-       u8 fragcnt;
-       int frame_tag;
-       struct rx_pkt_attrib attrib;
-       uint  len;
-       u8 *rx_head;
-       u8 *rx_data;
-       u8 *rx_tail;
-       u8 *rx_end;
-       void *precvbuf;
-       struct sta_info *psta;
-       /* for A-MPDU Rx reordering buffer control */
-       struct recv_reorder_ctrl *preorder_ctrl;
-};
-
-int _rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter);
-void _rtw_free_recv_priv(struct recv_priv *precvpriv);
-s32 rtw_recv_entry(struct recv_frame *precv_frame);
-struct recv_frame *_rtw_alloc_recvframe(struct __queue *pfree_recv_queue);
-struct recv_frame *rtw_alloc_recvframe(struct __queue *pfree_recv_queue);
-int  rtw_free_recvframe(struct recv_frame *precvframe,
-                       struct __queue *pfree_recv_queue);
-int _rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue);
-int rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue);
-void rtw_free_recvframe_queue(struct __queue *pframequeue,
-                             struct __queue *pfree_recv_queue);
-u32 rtw_free_uc_swdec_pending_queue(struct adapter *adapter);
-
-void rtw_reordering_ctrl_timeout_handler(void *pcontext);
-
-static inline u8 *get_rxmem(struct recv_frame *precvframe)
-{
-       /* always return rx_head... */
-       if (precvframe == NULL)
-               return NULL;
-       return precvframe->rx_head;
-}
-
-static inline u8 *recvframe_pull(struct recv_frame *precvframe, int sz)
-{
-       /*  rx_data += sz; move rx_data sz bytes  hereafter */
-
-       /* used for extract sz bytes from rx_data, update rx_data and return
-        * the updated rx_data to the caller */
-
-       if (precvframe == NULL)
-               return NULL;
-       precvframe->rx_data += sz;
-       if (precvframe->rx_data > precvframe->rx_tail) {
-               precvframe->rx_data -= sz;
-               return NULL;
-       }
-       precvframe->len -= sz;
-       return precvframe->rx_data;
-}
-
-static inline u8 *recvframe_put(struct recv_frame *precvframe, int sz)
-{
-       /* used for append sz bytes from ptr to rx_tail, update rx_tail
-        * and return the updated rx_tail to the caller */
-       /* after putting, rx_tail must be still larger than rx_end. */
-
-       if (precvframe == NULL)
-               return NULL;
-
-       precvframe->rx_tail += sz;
-
-       if (precvframe->rx_tail > precvframe->rx_end) {
-               precvframe->rx_tail -= sz;
-               return NULL;
-       }
-       precvframe->len += sz;
-       return precvframe->rx_tail;
-}
-
-static inline u8 *recvframe_pull_tail(struct recv_frame *precvframe, int sz)
-{
-       /*  rmv data from rx_tail (by yitsen) */
-
-       /* used for extract sz bytes from rx_end, update rx_end and return
-        * the updated rx_end to the caller */
-       /* after pulling, rx_end must be still larger than rx_data. */
-
-       if (precvframe == NULL)
-               return NULL;
-       precvframe->rx_tail -= sz;
-       if (precvframe->rx_tail < precvframe->rx_data) {
-               precvframe->rx_tail += sz;
-               return NULL;
-       }
-       precvframe->len -= sz;
-       return precvframe->rx_tail;
-}
-
-static inline int get_recvframe_len(struct recv_frame *precvframe)
-{
-       return precvframe->len;
-}
-
-static inline s32 translate_percentage_to_dbm(u32 sig_stren_index)
-{
-       s32     power; /*  in dBm. */
-
-       /*  Translate to dBm (x=0.5y-95). */
-       power = (s32)((sig_stren_index + 1) >> 1);
-       power -= 95;
-
-       return power;
-}
-
-struct sta_info;
-
-void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv);
-
-void  mgt_dispatcher(struct adapter *padapter, struct recv_frame *precv_frame);
-
-#endif
diff --git a/drivers/staging/r8188eu/include/rtw_rf.h b/drivers/staging/r8188eu/include/rtw_rf.h
deleted file mode 100644 (file)
index b7267e7..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef        __RTW_RF_H_
-#define __RTW_RF_H_
-
-#include "rtw_cmd.h"
-
-#define NumRates       (13)
-
-/*  slot time for 11g */
-#define SHORT_SLOT_TIME                        9
-#define NON_SHORT_SLOT_TIME            20
-
-#define        MAX_CHANNEL_NUM                 14      /* 2.4 GHz only */
-
-#define NUM_REGULATORYS        1
-
-struct regulatory_class {
-       u32     starting_freq;                          /* MHz, */
-       u8      channel_set[MAX_CHANNEL_NUM];
-       u8      channel_cck_power[MAX_CHANNEL_NUM];     /* dbm */
-       u8      channel_ofdm_power[MAX_CHANNEL_NUM];    /* dbm */
-       u8      txpower_limit;                          /* dbm */
-       u8      channel_spacing;                        /* MHz */
-       u8      modem;
-};
-
-enum capability {
-       cESS            = 0x0001,
-       cIBSS           = 0x0002,
-       cPollable       = 0x0004,
-       cPollReq        = 0x0008,
-       cPrivacy        = 0x0010,
-       cShortPreamble  = 0x0020,
-       cPBCC           = 0x0040,
-       cChannelAgility = 0x0080,
-       cSpectrumMgnt   = 0x0100,
-       cQos            = 0x0200,       /* For HCCA, use with CF-Pollable
-                                        * and CF-PollReq */
-       cShortSlotTime  = 0x0400,
-       cAPSD           = 0x0800,
-       cRM             = 0x1000,       /*  RRM (Radio Request Measurement) */
-       cDSSS_OFDM      = 0x2000,
-       cDelayedBA      = 0x4000,
-       cImmediateBA    = 0x8000,
-};
-
-enum   _REG_PREAMBLE_MODE {
-       PREAMBLE_LONG   = 1,
-       PREAMBLE_AUTO   = 2,
-       PREAMBLE_SHORT  = 3,
-};
-
-/*  Bandwidth Offset */
-#define HAL_PRIME_CHNL_OFFSET_DONT_CARE        0
-#define HAL_PRIME_CHNL_OFFSET_LOWER    1
-#define HAL_PRIME_CHNL_OFFSET_UPPER    2
-
-/*  Represent Channel Width in HT Capabilities */
-/*  */
-enum ht_channel_width {
-       HT_CHANNEL_WIDTH_20 = 0,
-       HT_CHANNEL_WIDTH_40 = 1,
-};
-
-/*  */
-/*  Represent Extension Channel Offset in HT Capabilities */
-/*  This is available only in 40Mhz mode. */
-/*  */
-enum ht_extchnl_offset {
-       HT_EXTCHNL_OFFSET_NO_EXT = 0,
-       HT_EXTCHNL_OFFSET_UPPER = 1,
-       HT_EXTCHNL_OFFSET_NO_DEF = 2,
-       HT_EXTCHNL_OFFSET_LOWER = 3,
-};
-
-u32 rtw_ch2freq(u32 ch);
-
-#endif /* _RTL8711_RF_H_ */
diff --git a/drivers/staging/r8188eu/include/rtw_security.h b/drivers/staging/r8188eu/include/rtw_security.h
deleted file mode 100644 (file)
index 783ae18..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __RTW_SECURITY_H_
-#define __RTW_SECURITY_H_
-
-#include "osdep_service.h"
-#include "drv_types.h"
-#include <crypto/arc4.h>
-
-#define _NO_PRIVACY_                   0x0
-#define _WEP40_                                0x1
-#define _TKIP_                         0x2
-#define _TKIP_WTMIC_                   0x3
-#define _AES_                          0x4
-#define _WEP104_                       0x5
-#define _SMS4_                         0x06
-
-#define _WPA_IE_ID_    0xdd
-#define _WPA2_IE_ID_   0x30
-
-enum {
-       ENCRYP_PROTOCOL_OPENSYS,   /* open system */
-       ENCRYP_PROTOCOL_WEP,       /* WEP */
-       ENCRYP_PROTOCOL_WPA,       /* WPA */
-       ENCRYP_PROTOCOL_WPA2,      /* WPA2 */
-       ENCRYP_PROTOCOL_WAPI,      /* WAPI: Not support in this version */
-       ENCRYP_PROTOCOL_MAX
-};
-
-#ifndef Ndis802_11AuthModeWPA2
-#define Ndis802_11AuthModeWPA2 (Ndis802_11AuthModeWPANone + 1)
-#endif
-
-#ifndef Ndis802_11AuthModeWPA2PSK
-#define Ndis802_11AuthModeWPA2PSK (Ndis802_11AuthModeWPANone + 2)
-#endif
-
-union pn48     {
-       u64     val;
-
-#ifdef __LITTLE_ENDIAN
-       struct {
-               u8 TSC0;
-               u8 TSC1;
-               u8 TSC2;
-               u8 TSC3;
-               u8 TSC4;
-               u8 TSC5;
-               u8 TSC6;
-               u8 TSC7;
-       } _byte_;
-
-#elif defined(__BIG_ENDIAN)
-
-       struct {
-               u8 TSC7;
-               u8 TSC6;
-               u8 TSC5;
-               u8 TSC4;
-               u8 TSC3;
-               u8 TSC2;
-               u8 TSC1;
-               u8 TSC0;
-       } _byte_;
-#endif
-};
-
-union Keytype {
-       u8   skey[16];
-       u32    lkey[4];
-};
-
-struct rt_pmkid_list {
-       u8      bUsed;
-       u8      Bssid[6];
-       u8      PMKID[16];
-       u8      SsidBuf[33];
-       u8      *ssid_octet;
-       u16     ssid_length;
-};
-
-struct security_priv {
-       u32       dot11AuthAlgrthm;     /*  802.11 auth, could be open,
-                                        * shared, 8021x and authswitch */
-       u32       dot11PrivacyAlgrthm;  /*  This specify the privacy for
-                                        * shared auth. algorithm. */
-       /* WEP */
-       u32       dot11PrivacyKeyIndex; /*  this is only valid for legendary
-                                        * wep, 0~3 for key id.(tx key index) */
-       union Keytype dot11DefKey[4];   /*  this is only valid for def. key */
-       u32     dot11DefKeylen[4];
-       u32 dot118021XGrpPrivacy;       /*  This specify the privacy algthm.
-                                        * used for Grp key */
-       u32     dot118021XGrpKeyid;     /*  key id used for Grp Key
-                                        * ( tx key index) */
-       union Keytype   dot118021XGrpKey[4];    /*  802.1x Group Key,
-                                                * for inx0 and inx1 */
-       union Keytype   dot118021XGrptxmickey[4];
-       union Keytype   dot118021XGrprxmickey[4];
-       union pn48      dot11Grptxpn;           /* PN48 used for Grp Key xmit.*/
-       union pn48      dot11Grprxpn;           /* PN48 used for Grp Key recv.*/
-
-       struct arc4_ctx xmit_arc4_ctx;
-       struct arc4_ctx recv_arc4_ctx;
-
-       /* extend security capabilities for AP_MODE */
-       unsigned int dot8021xalg;/* 0:disable, 1:psk, 2:802.1x */
-       unsigned int wpa_psk;/* 0:disable, bit(0): WPA, bit(1):WPA2 */
-       unsigned int wpa_group_cipher;
-       unsigned int wpa2_group_cipher;
-       unsigned int wpa_pairwise_cipher;
-       unsigned int wpa2_pairwise_cipher;
-       u8 wps_ie[MAX_WPS_IE_LEN];/* added in assoc req */
-       int wps_ie_len;
-       u8      binstallGrpkey;
-       u8      busetkipkey;
-       u8      bcheck_grpkey;
-       u8      bgrpkey_handshake;
-       s32     sw_encrypt;/* from registry_priv */
-       s32     sw_decrypt;/* from registry_priv */
-       s32     hw_decrypted;/* if the rx packets is hw_decrypted==false,i
-                             * it means the hw has not been ready. */
-
-       /* keeps the auth_type & enc_status from upper layer
-        * ioctl(wpa_supplicant or wzc) */
-       u32 ndisauthtype;       /*  NDIS_802_11_AUTHENTICATION_MODE */
-       u32 ndisencryptstatus;  /*  NDIS_802_11_ENCRYPTION_STATUS */
-       struct wlan_bssid_ex sec_bss;  /* for joinbss (h2c buffer) usage */
-       struct ndis_802_11_wep ndiswep;
-       u8 assoc_info[600];
-       u8 szofcapability[256]; /* for wpa2 usage */
-       u8 oidassociation[512]; /* for wpa/wpa2 usage */
-       u8 authenticator_ie[256];  /* store ap security information element */
-       u8 supplicant_ie[256];  /* store sta security information element */
-
-       /* for tkip countermeasure */
-       u32 last_mic_err_time;
-       u8      btkip_countermeasure;
-       u8      btkip_wait_report;
-       u32 btkip_countermeasure_time;
-
-       /*  */
-       /*  For WPA2 Pre-Authentication. */
-       /*  */
-       struct rt_pmkid_list PMKIDList[NUM_PMKID_CACHE];
-       u8      PMKIDIndex;
-       u8 bWepDefaultKeyIdxSet;
-};
-
-#define GET_ENCRY_ALGO(psecuritypriv, psta, encry_algo, bmcst)         \
-do {                                                                   \
-       switch (psecuritypriv->dot11AuthAlgrthm) {                      \
-       case dot11AuthAlgrthm_Open:                                     \
-       case dot11AuthAlgrthm_Shared:                                   \
-       case dot11AuthAlgrthm_Auto:                                     \
-               encry_algo = (u8)psecuritypriv->dot11PrivacyAlgrthm;    \
-               break;                                                  \
-       case dot11AuthAlgrthm_8021X:                                    \
-               if (bmcst)                                              \
-                       encry_algo = (u8)psecuritypriv->dot118021XGrpPrivacy;\
-               else                                                    \
-                       encry_algo = (u8)psta->dot118021XPrivacy;       \
-               break;                                                  \
-       case dot11AuthAlgrthm_WAPI:                                     \
-               encry_algo = (u8)psecuritypriv->dot11PrivacyAlgrthm;    \
-               break;                                                  \
-       }                                                               \
-} while (0)
-
-#define SET_ICE_IV_LEN(iv_len, icv_len, encrypt)                       \
-do {                                                                   \
-       switch (encrypt) {                                              \
-       case _WEP40_:                                                   \
-       case _WEP104_:                                                  \
-               iv_len = 4;                                             \
-               icv_len = 4;                                            \
-               break;                                                  \
-       case _TKIP_:                                                    \
-               iv_len = 8;                                             \
-               icv_len = 4;                                            \
-               break;                                                  \
-       case _AES_:                                                     \
-               iv_len = 8;                                             \
-               icv_len = 8;                                            \
-               break;                                                  \
-       case _SMS4_:                                                    \
-               iv_len = 18;                                            \
-               icv_len = 16;                                           \
-               break;                                                  \
-       default:                                                        \
-               iv_len = 0;                                             \
-               icv_len = 0;                                            \
-               break;                                                  \
-       }                                                               \
-} while (0)
-
-#define GET_TKIP_PN(iv, dot11txpn)                                     \
-do {                                                                   \
-       dot11txpn._byte_.TSC0 = iv[2];                                  \
-       dot11txpn._byte_.TSC1 = iv[0];                                  \
-       dot11txpn._byte_.TSC2 = iv[4];                                  \
-       dot11txpn._byte_.TSC3 = iv[5];                                  \
-       dot11txpn._byte_.TSC4 = iv[6];                                  \
-       dot11txpn._byte_.TSC5 = iv[7];                                  \
-} while (0)
-
-#define ROL32(A, n)    (((A) << (n)) | (((A)>>(32-(n)))  & ((1UL << (n)) - 1)))
-#define ROR32(A, n)    ROL32((A), 32-(n))
-
-struct mic_data {
-       u32  K0, K1;         /*  Key */
-       u32  L, R;           /*  Current state */
-       u32  M;              /*  Message accumulator (single word) */
-       u32  nBytesInM;      /*  # bytes in M */
-};
-
-void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key);
-void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b);
-void rtw_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nBytes);
-void rtw_secgetmic(struct mic_data *pmicdata, u8 *dst);
-void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len,
-                       u8 *Miccode, u8   priority);
-u32 rtw_aes_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe);
-u32 rtw_tkip_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe);
-void rtw_wep_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe);
-u32 rtw_aes_decrypt(struct adapter *padapter, struct recv_frame *precvframe);
-u32 rtw_tkip_decrypt(struct adapter *padapter, struct recv_frame *precvframe);
-void rtw_wep_decrypt(struct adapter *padapter, struct recv_frame *precvframe);
-
-#endif /* __RTL871X_SECURITY_H_ */
diff --git a/drivers/staging/r8188eu/include/rtw_xmit.h b/drivers/staging/r8188eu/include/rtw_xmit.h
deleted file mode 100644 (file)
index feeac85..0000000
+++ /dev/null
@@ -1,334 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef _RTW_XMIT_H_
-#define _RTW_XMIT_H_
-
-#include "osdep_service.h"
-#include "drv_types.h"
-
-#define NR_XMITFRAME           256
-#define WMM_XMIT_THRESHOLD     (NR_XMITFRAME * 2 / 5)
-
-#define MAX_XMITBUF_SZ (20480) /*  20k */
-#define NR_XMITBUFF            (4)
-
-#define XMITBUF_ALIGN_SZ       4
-
-/*  xmit extension buff defination */
-#define MAX_XMIT_EXTBUF_SZ     (1536)
-#define NR_XMIT_EXTBUFF                (32)
-
-#define MAX_NUMBLKS            (1)
-
-#define XMIT_VO_QUEUE          (0)
-#define XMIT_VI_QUEUE          (1)
-#define XMIT_BE_QUEUE          (2)
-#define XMIT_BK_QUEUE          (3)
-
-#define VO_QUEUE_INX           0
-#define VI_QUEUE_INX           1
-#define BE_QUEUE_INX           2
-#define BK_QUEUE_INX           3
-#define BCN_QUEUE_INX          4
-#define MGT_QUEUE_INX          5
-#define HIGH_QUEUE_INX         6
-#define TXCMD_QUEUE_INX                7
-
-#define HW_QUEUE_ENTRY         8
-
-#define WEP_IV(pattrib_iv, dot11txpn, keyidx)\
-do {\
-       pattrib_iv[0] = dot11txpn._byte_.TSC0;\
-       pattrib_iv[1] = dot11txpn._byte_.TSC1;\
-       pattrib_iv[2] = dot11txpn._byte_.TSC2;\
-       pattrib_iv[3] = ((keyidx & 0x3)<<6);\
-       dot11txpn.val = (dot11txpn.val == 0xffffff) ? 0 : (dot11txpn.val+1);\
-} while (0)
-
-#define TKIP_IV(pattrib_iv, dot11txpn, keyidx)\
-do {\
-       pattrib_iv[0] = dot11txpn._byte_.TSC1;\
-       pattrib_iv[1] = (dot11txpn._byte_.TSC1 | 0x20) & 0x7f;\
-       pattrib_iv[2] = dot11txpn._byte_.TSC0;\
-       pattrib_iv[3] = BIT(5) | ((keyidx & 0x3)<<6);\
-       pattrib_iv[4] = dot11txpn._byte_.TSC2;\
-       pattrib_iv[5] = dot11txpn._byte_.TSC3;\
-       pattrib_iv[6] = dot11txpn._byte_.TSC4;\
-       pattrib_iv[7] = dot11txpn._byte_.TSC5;\
-       dot11txpn.val = dot11txpn.val == 0xffffffffffffULL ? 0 : (dot11txpn.val+1);\
-} while (0)
-
-#define AES_IV(pattrib_iv, dot11txpn, keyidx)\
-do {                                                   \
-       pattrib_iv[0] = dot11txpn._byte_.TSC0;          \
-       pattrib_iv[1] = dot11txpn._byte_.TSC1;          \
-       pattrib_iv[2] = 0;                              \
-       pattrib_iv[3] = BIT(5) | ((keyidx & 0x3)<<6);   \
-       pattrib_iv[4] = dot11txpn._byte_.TSC2;          \
-       pattrib_iv[5] = dot11txpn._byte_.TSC3;          \
-       pattrib_iv[6] = dot11txpn._byte_.TSC4;          \
-       pattrib_iv[7] = dot11txpn._byte_.TSC5;          \
-       dot11txpn.val = dot11txpn.val == 0xffffffffffffULL ? 0 : (dot11txpn.val+1);\
-} while (0)
-
-#define HWXMIT_ENTRY   4
-
-#define TXDESC_SIZE 32
-
-#define PACKET_OFFSET_SZ (8)
-#define TXDESC_OFFSET (TXDESC_SIZE + PACKET_OFFSET_SZ)
-
-struct tx_desc {
-       /* DWORD 0 */
-       __le32 txdw0;
-       __le32 txdw1;
-       __le32 txdw2;
-       __le32 txdw3;
-       __le32 txdw4;
-       __le32 txdw5;
-       __le32 txdw6;
-       __le32 txdw7;
-};
-
-union txdesc {
-       struct tx_desc txdesc;
-       unsigned int value[TXDESC_SIZE>>2];
-};
-
-struct hw_xmit {
-       struct list_head *sta_list;
-       int     accnt;
-};
-
-/* reduce size */
-struct pkt_attrib {
-       u8      type;
-       u8      subtype;
-       u8      bswenc;
-       u8      dhcp_pkt;
-       u16     ether_type;
-       u16     seqnum;
-       u16     pkt_hdrlen;     /* the original 802.3 pkt header len */
-       u16     hdrlen;         /* the WLAN Header Len */
-       u32     pktlen;         /* the original 802.3 pkt raw_data len (not include
-                                * ether_hdr data) */
-       u32     last_txcmdsz;
-       u8      nr_frags;
-       u8      encrypt;        /* when 0 indicate no encrypt. when non-zero,
-                                * indicate the encrypt algorithm */
-       u8      iv_len;
-       u8      icv_len;
-       u8      iv[18];
-       u8      icv[16];
-       u8      priority;
-       u8      ack_policy;
-       u8      mac_id;
-       u8      vcs_mode;       /* virtual carrier sense method */
-       u8      dst[ETH_ALEN] __aligned(2);
-       u8      src[ETH_ALEN] __aligned(2);
-       u8      ta[ETH_ALEN] __aligned(2);
-       u8      ra[ETH_ALEN] __aligned(2);
-       u8      key_idx;
-       u8      qos_en;
-       u8      ht_en;
-       u8      raid;/* rate adpative id */
-       u8      bwmode;
-       u8      ch_offset;/* PRIME_CHNL_OFFSET */
-       u8      sgi;/* short GI */
-       u8      ampdu_en;/* tx ampdu enable */
-       u8      mdata;/* more data bit */
-       u8      pctrl;/* per packet txdesc control enable */
-       u8      triggered;/* for ap mode handling Power Saving sta */
-       u8      qsel;
-       u8      eosp;
-       u8      rate;
-       u8      intel_proxim;
-       u8      retry_ctrl;
-       struct sta_info *psta;
-};
-
-#define WLANHDR_OFFSET 64
-
-#define NULL_FRAMETAG          (0x0)
-#define DATA_FRAMETAG          0x01
-#define MGNT_FRAMETAG          0x03
-
-#define TXAGG_FRAMETAG 0x08
-
-struct  submit_ctx {
-       u32 submit_time; /* */
-       u32 timeout_ms; /* <0: not synchronous, 0: wait forever, >0: up to ms waiting */
-       int status; /* status for operation */
-       struct completion done;
-};
-
-enum {
-       RTW_SCTX_SUBMITTED = -1,
-       RTW_SCTX_DONE_SUCCESS = 0,
-       RTW_SCTX_DONE_UNKNOWN,
-       RTW_SCTX_DONE_TIMEOUT,
-       RTW_SCTX_DONE_BUF_ALLOC,
-       RTW_SCTX_DONE_BUF_FREE,
-       RTW_SCTX_DONE_WRITE_PORT_ERR,
-       RTW_SCTX_DONE_TX_DESC_NA,
-       RTW_SCTX_DONE_TX_DENY,
-       RTW_SCTX_DONE_CCX_PKT_FAIL,
-       RTW_SCTX_DONE_DRV_STOP,
-       RTW_SCTX_DONE_DEV_REMOVE,
-};
-
-void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms);
-int rtw_sctx_wait(struct submit_ctx *sctx);
-void rtw_sctx_done_err(struct submit_ctx **sctx, int status);
-
-struct xmit_buf {
-       struct list_head list;
-       struct adapter *padapter;
-       u8 *pallocated_buf;
-       u8 *pbuf;
-       void *priv_data;
-       u16 ext_tag; /*  0: Normal xmitbuf, 1: extension xmitbuf. */
-       bool high_queue;
-       u32 alloc_sz;
-       u32  len;
-       struct submit_ctx *sctx;
-       struct urb *pxmit_urb;
-       int last[8];
-};
-
-struct xmit_frame {
-       struct list_head list;
-       struct pkt_attrib attrib;
-       struct sk_buff *pkt;
-       int     frame_tag;
-       struct adapter *padapter;
-       u8      *buf_addr;
-       struct xmit_buf *pxmitbuf;
-
-       u8      agg_num;
-       s8      pkt_offset;
-       u8 ack_report;
-};
-
-struct tx_servq {
-       struct list_head tx_pending;
-       struct list_head sta_pending;
-       int qcnt;
-};
-
-struct sta_xmit_priv {
-       spinlock_t lock;
-       struct tx_servq be_q;                   /* priority == 0,3 */
-       struct tx_servq bk_q;                   /* priority == 1,2 */
-       struct tx_servq vi_q;                   /* priority == 4,5 */
-       struct tx_servq vo_q;                   /* priority == 6,7 */
-       u16 txseq_tid[16];
-};
-
-struct hw_txqueue {
-       volatile int    head;
-       volatile int    tail;
-       volatile int    free_sz;        /* in units of 64 bytes */
-       volatile int      free_cmdsz;
-       volatile int     txsz[8];
-       uint    ff_hwaddr;
-       uint    cmd_hwaddr;
-       int     ac_tag;
-};
-
-struct xmit_priv {
-       spinlock_t lock;
-       struct list_head be_pending;
-       struct list_head bk_pending;
-       struct list_head vi_pending;
-       struct list_head vo_pending;
-       u8 *pallocated_frame_buf;
-       u8 *pxmit_frame_buf;
-       uint free_xmitframe_cnt;
-       struct __queue free_xmit_queue;
-       uint    frag_len;
-       struct adapter  *adapter;
-       u64     tx_bytes;
-       u64     tx_pkts;
-       u64     tx_drop;
-       u64     last_tx_bytes;
-       u64     last_tx_pkts;
-       struct hw_xmit *hwxmits;
-       u8      wmm_para_seq[4];/* sequence for wmm ac parameter strength
-                                * from large to small. it's value is 0->vo,
-                                * 1->vi, 2->be, 3->bk. */
-       struct tasklet_struct xmit_tasklet;
-       struct __queue free_xmitbuf_queue;
-       struct __queue pending_xmitbuf_queue;
-       u8 *pallocated_xmitbuf;
-       u8 *pxmitbuf;
-       uint free_xmitbuf_cnt;
-       struct __queue free_xmit_extbuf_queue;
-       u8 *pallocated_xmit_extbuf;
-       u8 *pxmit_extbuf;
-       uint free_xmit_extbuf_cnt;
-       u16     nqos_ssn;
-       int     ack_tx;
-       struct mutex ack_tx_mutex;
-       struct submit_ctx ack_tx_ops;
-};
-
-struct pkt_file {
-       struct sk_buff *pkt;
-       size_t pkt_len;  /* the remainder length of the open_file */
-       unsigned char *cur_buffer;
-       u8 *buf_start;
-       u8 *cur_addr;
-       size_t buf_len;
-};
-
-struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv);
-s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv,
-                        struct xmit_buf *pxmitbuf);
-struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv);
-s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv,
-                    struct xmit_buf *pxmitbuf);
-void rtw_count_tx_stats(struct adapter *padapter,
-                       struct xmit_frame *pxmitframe, int sz);
-s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr,
-                    struct pkt_attrib *pattrib);
-s32 rtw_put_snap(u8 *data, u16 h_proto);
-
-struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv);
-s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv,
-                      struct xmit_frame *pxmitframe);
-void rtw_free_xmitframe_list(struct xmit_priv *pxmitpriv, struct list_head *xframe_list);
-struct tx_servq *rtw_get_sta_pending(struct adapter *padapter,
-                                    struct sta_info *psta, int up, u8 *ac);
-struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv,
-                                     struct hw_xmit *phwxmit_i);
-
-s32 rtw_xmit_classifier(struct adapter *padapter,
-                       struct xmit_frame *pxmitframe);
-s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt,
-                          struct xmit_frame *pxmitframe);
-s32 _rtw_init_hw_txqueue(struct hw_txqueue *phw_txqueue, u8 ac_tag);
-void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv);
-s32 rtw_txframes_pending(struct adapter *padapter);
-s32 rtw_txframes_sta_ac_pending(struct adapter *padapter,
-                               struct pkt_attrib *pattrib);
-int _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter);
-void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv);
-int rtw_alloc_hwxmits(struct adapter *padapter);
-s32 rtw_xmit(struct adapter *padapter, struct sk_buff **pkt);
-
-int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_frame *pxmitframe);
-void stop_sta_xmit(struct adapter *padapter, struct sta_info *psta);
-void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta);
-void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *psta);
-
-u8     qos_acm(u8 acm_mask, u8 priority);
-u32    rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe);
-int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms);
-void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status);
-
-void rtw_xmit_complete(struct adapter *padapter, struct xmit_frame *pxframe);
-netdev_tx_t rtw_xmit_entry(struct sk_buff *pkt, struct net_device *pnetdev);
-
-#endif /* _RTL871X_XMIT_H_ */
diff --git a/drivers/staging/r8188eu/include/sta_info.h b/drivers/staging/r8188eu/include/sta_info.h
deleted file mode 100644 (file)
index e42f4b4..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __STA_INFO_H_
-#define __STA_INFO_H_
-
-#include "osdep_service.h"
-#include "drv_types.h"
-#include "wifi.h"
-
-#define IBSS_START_MAC_ID      2
-#define NUM_STA 32
-#define NUM_ACL 16
-
-/* if mode ==0, then the sta is allowed once the addr is hit. */
-/* if mode ==1, then the sta is rejected once the addr is non-hit. */
-struct rtw_wlan_acl_node {
-       struct list_head list;
-       u8       addr[ETH_ALEN];
-       u8       valid;
-};
-
-/* mode=0, disable */
-/* mode=1, accept unless in deny list */
-/* mode=2, deny unless in accept list */
-struct wlan_acl_pool {
-       int mode;
-       int num;
-       struct rtw_wlan_acl_node aclnode[NUM_ACL];
-       struct __queue acl_node_q;
-};
-
-struct rssi_sta {
-       s32     UndecoratedSmoothedPWDB;
-       s32     UndecoratedSmoothedCCK;
-       s32     UndecoratedSmoothedOFDM;
-       u64     PacketMap;
-       u8      ValidBit;
-};
-
-struct stainfo_stats   {
-       u64 rx_mgnt_pkts;
-       u64 rx_beacon_pkts;
-       u64 rx_probereq_pkts;
-       u64 rx_probersp_pkts;
-       u64 rx_probersp_bm_pkts;
-       u64 rx_probersp_uo_pkts;
-       u64 rx_ctrl_pkts;
-       u64 rx_data_pkts;
-
-       u64 last_rx_beacon_pkts;
-       u64 last_rx_probereq_pkts;
-       u64 last_rx_probersp_pkts;
-       u64 last_rx_probersp_bm_pkts;
-       u64 last_rx_probersp_uo_pkts;
-       u64     last_rx_ctrl_pkts;
-       u64     last_rx_data_pkts;
-       u64     rx_bytes;
-       u64     rx_drops;
-       u64     tx_pkts;
-       u64     tx_bytes;
-       u64  tx_drops;
-};
-
-struct sta_info {
-       spinlock_t lock;
-       struct list_head list; /* free_sta_queue */
-       struct list_head hash_list; /* sta_hash */
-
-       struct sta_xmit_priv sta_xmitpriv;
-       struct sta_recv_priv sta_recvpriv;
-
-       struct __queue sleep_q;
-       unsigned int sleepq_len;
-
-       uint state;
-       uint aid;
-       uint mac_id;
-       uint qos_option;
-       u8      hwaddr[ETH_ALEN];
-
-       uint    ieee8021x_blocked;      /* 0: allowed, 1:blocked */
-       uint    dot118021XPrivacy; /* aes, tkip... */
-       union Keytype   dot11tkiptxmickey;
-       union Keytype   dot11tkiprxmickey;
-       union Keytype   dot118021x_UncstKey;
-       union pn48              dot11txpn;                      /*  PN48 used for Unicast xmit. */
-       union pn48              dot11rxpn;                      /*  PN48 used for Unicast recv. */
-       u8      bssrateset[16];
-       u32     bssratelen;
-       s32  rssi;
-       s32     signal_quality;
-
-       u8      cts2self;
-       u8      rtsen;
-
-       u8      raid;
-       u8      init_rate;
-       u32     ra_mask;
-       u8      wireless_mode;  /*  NETWORK_TYPE */
-       struct stainfo_stats sta_stats;
-
-       /* for A-MPDU TX, ADDBA timeout check */
-       struct timer_list addba_retry_timer;
-
-       /* for A-MPDU Rx reordering buffer control */
-       struct recv_reorder_ctrl recvreorder_ctrl[16];
-
-       /* for A-MPDU Tx */
-       /* unsigned char                ampdu_txen_bitmap; */
-       u16     BA_starting_seqctrl[16];
-
-       struct ht_priv  htpriv;
-
-       /* Notes: */
-       /* STA_Mode: */
-       /* curr_network(mlme_priv/security_priv/qos/ht) +
-        * sta_info: (STA & AP) CAP/INFO */
-       /* scan_q: AP CAP/INFO */
-
-       /* AP_Mode: */
-       /* curr_network(mlme_priv/security_priv/qos/ht) : AP CAP/INFO */
-       /* sta_info: (AP & STA) CAP/INFO */
-
-       struct list_head asoc_list;
-       struct list_head auth_list;
-
-       unsigned int expire_to;
-       unsigned int auth_seq;
-       unsigned int authalg;
-       unsigned char chg_txt[128];
-
-       u16 capability;
-       int flags;
-
-       int dot8021xalg;/* 0:disable, 1:psk, 2:802.1x */
-       int wpa_psk;/* 0:disable, bit(0): WPA, bit(1):WPA2 */
-       int wpa_group_cipher;
-       int wpa2_group_cipher;
-       int wpa_pairwise_cipher;
-       int wpa2_pairwise_cipher;
-
-       u8 bpairwise_key_installed;
-
-       u8 wpa_ie[32];
-
-       u8 nonerp_set;
-       u8 no_short_slot_time_set;
-       u8 no_short_preamble_set;
-       u8 no_ht_gf_set;
-       u8 no_ht_set;
-       u8 ht_20mhz_set;
-
-       unsigned int tx_ra_bitmap;
-       u8 qos_info;
-
-       u8 max_sp_len;
-       u8 uapsd_bk;/* BIT(0): Delivery enabled, BIT(1): Trigger enabled */
-       u8 uapsd_be;
-       u8 uapsd_vi;
-       u8 uapsd_vo;
-
-       u8 has_legacy_ac;
-       unsigned int sleepq_ac_len;
-
-       /* p2p priv data */
-       u8 is_p2p_device;
-       u8 p2p_status_code;
-
-       /* p2p client info */
-       u8 dev_addr[ETH_ALEN];
-       u8 dev_cap;
-       u16 config_methods;
-       u8 primary_dev_type[8];
-       u8 num_of_secdev_type;
-       u8 secdev_types_list[32];/*  32/8 == 4; */
-       u16 dev_name_len;
-       u8 dev_name[32];
-       u8 under_exist_checking;
-       u8 keep_alive_trycnt;
-
-       /* for DM */
-       struct rssi_sta rssi_stat;
-
-       /*  ================ODM Relative Info======================= */
-       /*  Please be careful, don't declare too much structure here.
-        *  It will cost memory * STA support num. */
-       /*  2011/10/20 MH Add for ODM STA info. */
-       /*  Driver Write */
-       u8      bValid;         /*  record the sta status link or not? */
-       u8      IOTPeer;        /*  Enum value. HT_IOT_PEER_E */
-       u8      rssi_level;     /* for Refresh RA mask */
-       /*  ODM Write */
-       /* 1 PHY_STATUS_INFO */
-       u8              RSSI_Path[4];           /*  */
-       u8              RSSI_Ave;
-       u8              RXEVM[4];
-       u8              RXSNR[4];
-
-       /*  ================ODM Relative Info======================= */
-       /*  */
-
-       /* To store the sequence number of received management frame */
-       u16 RxMgmtFrameSeqNum;
-};
-
-#define sta_rx_pkts(sta) \
-       (sta->sta_stats.rx_mgnt_pkts \
-       + sta->sta_stats.rx_ctrl_pkts \
-       + sta->sta_stats.rx_data_pkts)
-
-#define sta_rx_data_pkts(sta) \
-       (sta->sta_stats.rx_data_pkts)
-
-#define sta_last_rx_data_pkts(sta) \
-       (sta->sta_stats.last_rx_data_pkts)
-
-#define sta_rx_beacon_pkts(sta) \
-       (sta->sta_stats.rx_beacon_pkts)
-
-#define sta_last_rx_beacon_pkts(sta) \
-       (sta->sta_stats.last_rx_beacon_pkts)
-
-#define sta_rx_probersp_pkts(sta) \
-       (sta->sta_stats.rx_probersp_pkts)
-
-#define sta_last_rx_probersp_pkts(sta) \
-       (sta->sta_stats.last_rx_probersp_pkts)
-
-#define sta_update_last_rx_pkts(sta) \
-do { \
-       sta->sta_stats.last_rx_beacon_pkts = sta->sta_stats.rx_beacon_pkts; \
-       sta->sta_stats.last_rx_probereq_pkts = sta->sta_stats.rx_probereq_pkts; \
-       sta->sta_stats.last_rx_probersp_pkts = sta->sta_stats.rx_probersp_pkts; \
-       sta->sta_stats.last_rx_probersp_bm_pkts = sta->sta_stats.rx_probersp_bm_pkts; \
-       sta->sta_stats.last_rx_probersp_uo_pkts = sta->sta_stats.rx_probersp_uo_pkts; \
-       sta->sta_stats.last_rx_ctrl_pkts = sta->sta_stats.rx_ctrl_pkts; \
-       sta->sta_stats.last_rx_data_pkts = sta->sta_stats.rx_data_pkts; \
-} while (0)
-
-struct sta_priv {
-       u8 *pallocated_stainfo_buf;
-       u8 *pstainfo_buf;
-       struct __queue free_sta_queue;
-
-       spinlock_t sta_hash_lock;
-       struct list_head sta_hash[NUM_STA];
-       int asoc_sta_count;
-       struct __queue sleep_q;
-       struct __queue wakeup_q;
-
-       struct adapter *padapter;
-
-       spinlock_t asoc_list_lock;
-       struct list_head asoc_list;
-
-       struct list_head auth_list;
-       spinlock_t auth_list_lock;
-       u8 asoc_list_cnt;
-       u8 auth_list_cnt;
-
-       unsigned int auth_to;  /* sec, time to expire in authenticating. */
-       unsigned int assoc_to; /* sec, time to expire before associating. */
-       unsigned int expire_to; /* sec , time to expire after associated. */
-
-       /* pointers to STA info; based on allocated AID or NULL if AID free
-        * AID is in the range 1-2007, so sta_aid[0] corresponders to AID 1
-        * and so on
-        */
-       struct sta_info *sta_aid[NUM_STA];
-
-       u16 sta_dz_bitmap;/* only support 15 stations, station aid bitmap
-                          * for sleeping sta. */
-       u16 tim_bitmap; /* only support 15 stations, aid=0~15 mapping
-                        * bit0~bit15 */
-
-       u16 max_num_sta;
-
-       struct wlan_acl_pool acl_list;
-};
-
-static inline u32 wifi_mac_hash(u8 *mac)
-{
-       u32 x;
-
-       x = mac[0];
-       x = (x << 2) ^ mac[1];
-       x = (x << 2) ^ mac[2];
-       x = (x << 2) ^ mac[3];
-       x = (x << 2) ^ mac[4];
-       x = (x << 2) ^ mac[5];
-
-       x ^= x >> 8;
-       x  = x & (NUM_STA - 1);
-       return x;
-}
-
-int _rtw_init_sta_priv(struct sta_priv *pstapriv);
-void _rtw_free_sta_priv(struct sta_priv *pstapriv);
-
-#define stainfo_offset_valid(offset) (offset < NUM_STA && offset >= 0)
-int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta);
-struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int off);
-
-struct sta_info *rtw_alloc_stainfo(struct sta_priv *stapriv, u8 *hwaddr);
-void rtw_free_stainfo(struct adapter *adapt, struct sta_info *psta);
-void rtw_free_all_stainfo(struct adapter *adapt);
-struct sta_info *rtw_get_stainfo(struct sta_priv *stapriv, u8 *hwaddr);
-u32 rtw_init_bcmc_stainfo(struct adapter *adapt);
-struct sta_info *rtw_get_bcmc_stainfo(struct adapter *padapter);
-u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr);
-
-#endif /* _STA_INFO_H_ */
diff --git a/drivers/staging/r8188eu/include/usb_ops.h b/drivers/staging/r8188eu/include/usb_ops.h
deleted file mode 100644 (file)
index 5bd8ce3..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __USB_OPS_H_
-#define __USB_OPS_H_
-
-#include "osdep_service.h"
-#include "drv_types.h"
-#include "osdep_intf.h"
-
-#define REALTEK_USB_VENQT_READ         (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE)
-#define REALTEK_USB_VENQT_WRITE                (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE)
-#define REALTEK_USB_VENQT_CMD_REQ      0x05
-#define REALTEK_USB_VENQT_CMD_IDX      0x00
-
-#define ALIGNMENT_UNIT                 16
-#define MAX_VENDOR_REQ_CMD_SIZE        254     /* 8188cu SIE Support */
-#define MAX_USB_IO_CTL_SIZE    (MAX_VENDOR_REQ_CMD_SIZE + ALIGNMENT_UNIT)
-
-/*
- * Increase and check if the continual_urb_error of this @param dvobjprivei
- * is larger than MAX_CONTINUAL_URB_ERR
- * @return true:
- * @return false:
- */
-static inline bool rtw_inc_and_chk_continual_urb_error(struct dvobj_priv *dvobj)
-{
-       int value = atomic_inc_return(&dvobj->continual_urb_error);
-
-       if (value > MAX_CONTINUAL_URB_ERR)
-               return true;
-
-       return false;
-}
-
-/*
-* Set the continual_urb_error of this @param dvobjprive to 0
-*/
-static inline void rtw_reset_continual_urb_error(struct dvobj_priv *dvobj)
-{
-       atomic_set(&dvobj->continual_urb_error, 0);
-}
-
-#define USB_HIGH_SPEED_BULK_SIZE       512
-#define USB_FULL_SPEED_BULK_SIZE       64
-
-static inline bool rtw_usb_bulk_size_boundary(struct adapter *padapter, int buf_len)
-{
-       struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
-
-       if (pdvobjpriv->pusbdev->speed == USB_SPEED_HIGH)
-               return buf_len % USB_HIGH_SPEED_BULK_SIZE == 0;
-       else
-               return buf_len % USB_FULL_SPEED_BULK_SIZE == 0;
-}
-
-#endif /* __USB_OPS_H_ */
diff --git a/drivers/staging/r8188eu/include/usb_osintf.h b/drivers/staging/r8188eu/include/usb_osintf.h
deleted file mode 100644 (file)
index f271e93..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __USB_OSINTF_H
-#define __USB_OSINTF_H
-
-#include "osdep_service.h"
-#include "drv_types.h"
-
-extern char *rtw_initmac;
-extern int rtw_mc2u_disable;
-
-#define USBD_HALTED(Status) ((u32)(Status) >> 30 == 3)
-
-void netdev_br_init(struct net_device *netdev);
-void dhcp_flag_bcast(struct adapter *priv, struct sk_buff *skb);
-void *scdb_findEntry(struct adapter *priv, unsigned char *ipAddr);
-void nat25_db_expire(struct adapter *priv);
-int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method);
-
-#endif
diff --git a/drivers/staging/r8188eu/include/wifi.h b/drivers/staging/r8188eu/include/wifi.h
deleted file mode 100644 (file)
index 254a4bc..0000000
+++ /dev/null
@@ -1,773 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-#ifndef _WIFI_H_
-#define _WIFI_H_
-
-#include <linux/bits.h>
-#include <linux/ieee80211.h>
-
-#define WLAN_ETHHDR_LEN                14
-#define WLAN_HDR_A3_LEN                24
-#define WLAN_HDR_A3_QOS_LEN    26
-#define WLAN_SSID_MAXLEN       32
-
-enum WIFI_FRAME_SUBTYPE {
-       /*  below is for mgt frame */
-       WIFI_ASSOCREQ       = (0 | IEEE80211_FTYPE_MGMT),
-       WIFI_ASSOCRSP       = (BIT(4) | IEEE80211_FTYPE_MGMT),
-       WIFI_REASSOCREQ     = (BIT(5) | IEEE80211_FTYPE_MGMT),
-       WIFI_REASSOCRSP     = (BIT(5) | BIT(4) | IEEE80211_FTYPE_MGMT),
-       WIFI_PROBEREQ       = (BIT(6) | IEEE80211_FTYPE_MGMT),
-       WIFI_PROBERSP       = (BIT(6) | BIT(4) | IEEE80211_FTYPE_MGMT),
-       WIFI_BEACON         = (BIT(7) | IEEE80211_FTYPE_MGMT),
-       WIFI_ATIM           = (BIT(7) | BIT(4) | IEEE80211_FTYPE_MGMT),
-       WIFI_DISASSOC       = (BIT(7) | BIT(5) | IEEE80211_FTYPE_MGMT),
-       WIFI_AUTH           = (BIT(7) | BIT(5) | BIT(4) | IEEE80211_FTYPE_MGMT),
-       WIFI_DEAUTH         = (BIT(7) | BIT(6) | IEEE80211_FTYPE_MGMT),
-       WIFI_ACTION         = (BIT(7) | BIT(6) | BIT(4) | IEEE80211_FTYPE_MGMT),
-
-       /*  below is for control frame */
-       WIFI_PSPOLL         = (BIT(7) | BIT(5) | IEEE80211_FTYPE_CTL),
-
-       /*  below is for data frame */
-       WIFI_DATA           = (0 | IEEE80211_FTYPE_DATA),
-       WIFI_DATA_CFACK     = (BIT(4) | IEEE80211_FTYPE_DATA),
-       WIFI_DATA_CFPOLL    = (BIT(5) | IEEE80211_FTYPE_DATA),
-       WIFI_DATA_CFACKPOLL = (BIT(5) | BIT(4) | IEEE80211_FTYPE_DATA),
-       WIFI_DATA_NULL      = (BIT(6) | IEEE80211_FTYPE_DATA),
-       WIFI_QOS_DATA_NULL      = (BIT(6) | IEEE80211_STYPE_QOS_DATA | IEEE80211_FTYPE_DATA),
-};
-
-enum WIFI_REASON_CODE  {
-       _RSON_RESERVED_                 = 0,
-       _RSON_UNSPECIFIED_              = 1,
-       _RSON_AUTH_NO_LONGER_VALID_     = 2,
-       _RSON_DEAUTH_STA_LEAVING_       = 3,
-       _RSON_INACTIVITY_               = 4,
-       _RSON_UNABLE_HANDLE_            = 5,
-       _RSON_CLS2_                     = 6,
-       _RSON_CLS3_                     = 7,
-       _RSON_DISAOC_STA_LEAVING_       = 8,
-       _RSON_ASOC_NOT_AUTH_            = 9,
-
-       /*  WPA reason */
-       _RSON_INVALID_IE_               = 13,
-       _RSON_MIC_FAILURE_              = 14,
-       _RSON_4WAY_HNDSHK_TIMEOUT_      = 15,
-       _RSON_GROUP_KEY_UPDATE_TIMEOUT_ = 16,
-       _RSON_DIFF_IE_                  = 17,
-       _RSON_MLTCST_CIPHER_NOT_VALID_  = 18,
-       _RSON_UNICST_CIPHER_NOT_VALID_  = 19,
-       _RSON_AKMP_NOT_VALID_           = 20,
-       _RSON_UNSUPPORT_RSNE_VER_       = 21,
-       _RSON_INVALID_RSNE_CAP_         = 22,
-       _RSON_IEEE_802DOT1X_AUTH_FAIL_  = 23,
-
-       /* belowing are Realtek definition */
-       _RSON_PMK_NOT_AVAILABLE_        = 24,
-       _RSON_TDLS_TEAR_TOOFAR_         = 25,
-       _RSON_TDLS_TEAR_UN_RSN_         = 26,
-};
-
-enum WIFI_STATUS_CODE {
-       _STATS_SUCCESSFUL_              = 0,
-       _STATS_FAILURE_                 = 1,
-       _STATS_CAP_FAIL_                = 10,
-       _STATS_NO_ASOC_                 = 11,
-       _STATS_OTHER_                   = 12,
-       _STATS_NO_SUPP_ALG_             = 13,
-       _STATS_OUT_OF_AUTH_SEQ_         = 14,
-       _STATS_CHALLENGE_FAIL_          = 15,
-       _STATS_AUTH_TIMEOUT_            = 16,
-       _STATS_UNABLE_HANDLE_STA_       = 17,
-       _STATS_RATE_FAIL_               = 18,
-};
-
-/* entended */
-/* IEEE 802.11b */
-#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
-#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
-#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
-/* IEEE 802.11h */
-#define WLAN_STATUS_SPEC_MGMT_REQUIRED 22
-#define WLAN_STATUS_PWR_CAPABILITY_NOT_VALID 23
-#define WLAN_STATUS_SUPPORTED_CHANNEL_NOT_VALID 24
-/* IEEE 802.11g */
-#define WLAN_STATUS_ASSOC_DENIED_NO_SHORT_SLOT_TIME 25
-#define WLAN_STATUS_ASSOC_DENIED_NO_ER_PBCC 26
-#define WLAN_STATUS_ASSOC_DENIED_NO_DSSS_OFDM 27
-/* IEEE 802.11w */
-#define WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY 30
-#define WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31
-/* IEEE 802.11i */
-#define WLAN_STATUS_INVALID_IE 40
-#define WLAN_STATUS_GROUP_CIPHER_NOT_VALID 41
-#define WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID 42
-#define WLAN_STATUS_AKMP_NOT_VALID 43
-#define WLAN_STATUS_UNSUPPORTED_RSN_IE_VERSION 44
-#define WLAN_STATUS_INVALID_RSN_IE_CAPAB 45
-#define WLAN_STATUS_CIPHER_REJECTED_PER_POLICY 46
-#define WLAN_STATUS_TS_NOT_CREATED 47
-#define WLAN_STATUS_DIRECT_LINK_NOT_ALLOWED 48
-#define WLAN_STATUS_DEST_STA_NOT_PRESENT 49
-#define WLAN_STATUS_DEST_STA_NOT_QOS_STA 50
-#define WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE 51
-/* IEEE 802.11r */
-#define WLAN_STATUS_INVALID_FT_ACTION_FRAME_COUNT 52
-#define WLAN_STATUS_INVALID_PMKID 53
-#define WLAN_STATUS_INVALID_MDIE 54
-#define WLAN_STATUS_INVALID_FTIE 55
-
-enum WIFI_REG_DOMAIN {
-       DOMAIN_FCC      = 1,
-       DOMAIN_IC       = 2,
-       DOMAIN_ETSI     = 3,
-       DOMAIN_SPA      = 4,
-       DOMAIN_FRANCE   = 5,
-       DOMAIN_MKK      = 6,
-       DOMAIN_ISRAEL   = 7,
-       DOMAIN_MKK1     = 8,
-       DOMAIN_MKK2     = 9,
-       DOMAIN_MKK3     = 10,
-       DOMAIN_MAX
-};
-
-#define _TO_DS_                BIT(8)
-#define _FROM_DS_      BIT(9)
-#define _MORE_FRAG_    BIT(10)
-#define _RETRY_                BIT(11)
-#define _PWRMGT_       BIT(12)
-#define _MORE_DATA_    BIT(13)
-#define _PRIVACY_      BIT(14)
-
-#define SetToDs(pbuf)  \
-       *(__le16 *)(pbuf) |= cpu_to_le16(_TO_DS_)
-
-#define GetToDs(pbuf)  (((*(__le16 *)(pbuf)) & cpu_to_le16(_TO_DS_)) != 0)
-
-#define SetFrDs(pbuf)  \
-       *(__le16 *)(pbuf) |= cpu_to_le16(_FROM_DS_)
-
-#define GetFrDs(pbuf)  (((*(__le16 *)(pbuf)) & cpu_to_le16(_FROM_DS_)) != 0)
-
-#define SetMFrag(pbuf) \
-       *(__le16 *)(pbuf) |= cpu_to_le16(_MORE_FRAG_)
-
-#define ClearMFrag(pbuf)       \
-       *(__le16 *)(pbuf) &= (~cpu_to_le16(_MORE_FRAG_))
-
-#define GetRetry(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(_RETRY_)) != 0)
-
-#define SetPwrMgt(pbuf)        \
-       *(__le16 *)(pbuf) |= cpu_to_le16(_PWRMGT_)
-
-#define GetPwrMgt(pbuf)        (((*(__le16 *)(pbuf)) & cpu_to_le16(_PWRMGT_)) != 0)
-
-#define SetMData(pbuf) \
-       *(__le16 *)(pbuf) |= cpu_to_le16(_MORE_DATA_)
-
-#define SetPrivacy(pbuf)       \
-       *(__le16 *)(pbuf) |= cpu_to_le16(_PRIVACY_)
-
-#define GetFrameType(pbuf)                             \
-       (le16_to_cpu(*(__le16 *)(pbuf)) & (BIT(3) | BIT(2)))
-
-#define GetFrameSubType(pbuf)  (le16_to_cpu(*(__le16 *)(pbuf)) & (BIT(7) |\
-        BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2)))
-
-#define SetFrameSubType(pbuf, type) \
-       do {    \
-               *(__le16 *)(pbuf) &= cpu_to_le16(~(BIT(7) | BIT(6) |    \
-                BIT(5) | BIT(4) | BIT(3) | BIT(2))); \
-               *(__le16 *)(pbuf) |= cpu_to_le16(type); \
-       } while (0)
-
-#define SetSeqNum(pbuf, num) \
-       do {    \
-               *(__le16 *)((size_t)(pbuf) + 22) = \
-                       ((*(__le16 *)((size_t)(pbuf) + 22)) & cpu_to_le16((unsigned short)0x000f)) | \
-                       cpu_to_le16((unsigned short)(0xfff0 & (num << 4))); \
-       } while (0)
-
-#define SetDuration(pbuf, dur) \
-       *(__le16 *)((size_t)(pbuf) + 2) = cpu_to_le16(0xffff & (dur))
-
-#define SetPriority(pbuf, tid) \
-       *(__le16 *)(pbuf) |= cpu_to_le16(tid & 0xf)
-
-#define SetEOSP(pbuf, eosp)    \
-               *(__le16 *)(pbuf) |= cpu_to_le16((eosp & 1) << 4)
-
-#define SetAckpolicy(pbuf, ack)        \
-       *(__le16 *)(pbuf) |= cpu_to_le16((ack & 3) << 5)
-
-#define GetAckpolicy(pbuf) (((le16_to_cpu(*(__le16 *)pbuf)) >> 5) & 0x3)
-
-#define GetAMsdu(pbuf) (((le16_to_cpu(*(__le16 *)pbuf)) >> 7) & 0x1)
-
-#define GetAddr1Ptr(pbuf)      ((unsigned char *)((size_t)(pbuf) + 4))
-
-#define GetAddr2Ptr(pbuf)      ((unsigned char *)((size_t)(pbuf) + 10))
-
-#define GetAddr3Ptr(pbuf)      ((unsigned char *)((size_t)(pbuf) + 16))
-
-#define GetAddr4Ptr(pbuf)      ((unsigned char *)((size_t)(pbuf) + 24))
-
-static inline unsigned char *get_sa(unsigned char *pframe)
-{
-       unsigned char   *sa;
-       unsigned int    to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe);
-
-       switch (to_fr_ds) {
-       case 0x00:      /*  ToDs=0, FromDs=0 */
-               sa = GetAddr2Ptr(pframe);
-               break;
-       case 0x01:      /*  ToDs=0, FromDs=1 */
-               sa = GetAddr3Ptr(pframe);
-               break;
-       case 0x02:      /*  ToDs=1, FromDs=0 */
-               sa = GetAddr2Ptr(pframe);
-               break;
-       default:        /*  ToDs=1, FromDs=1 */
-               sa = GetAddr4Ptr(pframe);
-               break;
-       }
-       return sa;
-}
-
-static inline unsigned char *get_hdr_bssid(unsigned char *pframe)
-{
-       unsigned char   *sa;
-       unsigned int    to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe);
-
-       switch (to_fr_ds) {
-       case 0x00:      /*  ToDs=0, FromDs=0 */
-               sa = GetAddr3Ptr(pframe);
-               break;
-       case 0x01:      /*  ToDs=0, FromDs=1 */
-               sa = GetAddr2Ptr(pframe);
-               break;
-       case 0x02:      /*  ToDs=1, FromDs=0 */
-               sa = GetAddr1Ptr(pframe);
-               break;
-       case 0x03:      /*  ToDs=1, FromDs=1 */
-               sa = GetAddr1Ptr(pframe);
-               break;
-       default:
-               sa = NULL; /*  */
-               break;
-       }
-       return sa;
-}
-
-/*-----------------------------------------------------------------------------
-                       Below is for the security related definition
-------------------------------------------------------------------------------*/
-#define _RESERVED_FRAME_TYPE_          0
-#define _SKB_FRAME_TYPE_               2
-#define _PRE_ALLOCMEM_                 1
-#define _PRE_ALLOCHDR_                 3
-#define _PRE_ALLOCLLCHDR_              4
-#define _PRE_ALLOCICVHDR_              5
-#define _PRE_ALLOCMICHDR_              6
-
-#define _SIFSTIME_                             \
-       (priv->pmib->dot11BssType.net_work_type = 10)
-#define _ACKCTSLNG_            14      /* 14 bytes long, including crclng */
-#define _CRCLNG_               4
-
-#define _ASOCREQ_IE_OFFSET_    4       /*  excluding wlan_hdr */
-#define        _ASOCRSP_IE_OFFSET_     6
-#define _REASOCREQ_IE_OFFSET_  10
-#define _REASOCRSP_IE_OFFSET_  6
-#define _PROBEREQ_IE_OFFSET_   0
-#define        _PROBERSP_IE_OFFSET_    12
-#define _AUTH_IE_OFFSET_       6
-#define _DEAUTH_IE_OFFSET_     0
-#define _BEACON_IE_OFFSET_     12
-#define _PUBLIC_ACTION_IE_OFFSET_      8
-
-#define _FIXED_IE_LENGTH_      _BEACON_IE_OFFSET_
-
-#define _SSID_IE_              0
-#define _SUPPORTEDRATES_IE_    1
-#define _DSSET_IE_             3
-#define _TIM_IE_               5
-#define _IBSS_PARA_IE_         6
-#define _COUNTRY_IE_           7
-#define _CHLGETXT_IE_          16
-#define _SUPPORTED_CH_IE_      36
-#define _CH_SWTICH_ANNOUNCE_   37      /* Secondary Channel Offset */
-#define _RSN_IE_2_             48
-#define _SSN_IE_1_             221
-#define _ERPINFO_IE_           42
-#define _EXT_SUPPORTEDRATES_IE_        50
-
-#define _HT_CAPABILITY_IE_     45
-#define _FTIE_                 55
-#define _TIMEOUT_ITVL_IE_      56
-#define _SRC_IE_               59
-#define _HT_EXTRA_INFO_IE_     61
-#define _HT_ADD_INFO_IE_       61 /* _HT_EXTRA_INFO_IE_ */
-#define _WAPI_IE_              68
-
-#define        EID_BSSCoexistence      72 /*  20/40 BSS Coexistence */
-#define        EID_BSSIntolerantChlReport      73
-#define _RIC_Descriptor_IE_    75
-
-#define _LINK_ID_IE_           101
-#define _CH_SWITCH_TIMING_     104
-#define _PTI_BUFFER_STATUS_    106
-#define _EXT_CAP_IE_           127
-#define _VENDOR_SPECIFIC_IE_   221
-
-#define        _RESERVED47_            47
-
-/* ---------------------------------------------------------------------------
-                                       Below is the fixed elements...
------------------------------------------------------------------------------*/
-#define _AUTH_ALGM_NUM_                2
-#define _AUTH_SEQ_NUM_         2
-#define _BEACON_ITERVAL_       2
-#define _CAPABILITY_           2
-#define _CURRENT_APADDR_       6
-#define _LISTEN_INTERVAL_      2
-#define _RSON_CODE_            2
-#define _ASOC_ID_              2
-#define _STATUS_CODE_          2
-#define _TIMESTAMP_            8
-
-#define cap_ESS                BIT(0)
-#define cap_IBSS       BIT(1)
-#define cap_CFPollable BIT(2)
-#define cap_CFRequest  BIT(3)
-#define cap_Privacy    BIT(4)
-#define cap_ShortPremble BIT(5)
-#define cap_PBCC       BIT(6)
-#define cap_ChAgility  BIT(7)
-#define cap_SpecMgmt   BIT(8)
-#define cap_QoSi       BIT(9)
-#define cap_ShortSlot  BIT(10)
-
-/*-----------------------------------------------------------------------------
-                               Below is the definition for 802.11i / 802.1x
-------------------------------------------------------------------------------*/
-#define _IEEE8021X_MGT_                        1       /*  WPA */
-#define _IEEE8021X_PSK_                        2       /*  WPA with pre-shared key */
-
-/*-----------------------------------------------------------------------------
-                               Below is the definition for WMM
-------------------------------------------------------------------------------*/
-#define _WMM_IE_Length_                                7  /*  for WMM STA */
-#define _WMM_Para_Element_Length_              24
-
-/*-----------------------------------------------------------------------------
-                               Below is the definition for 802.11n
-------------------------------------------------------------------------------*/
-
-/**
- * struct rtw_ieee80211_bar - HT Block Ack Request
- *
- * This structure refers to "HT BlockAckReq" as
- * described in 802.11n draft section 7.2.1.7.1
- */
-struct rtw_ieee80211_bar {
-       __le16 frame_control;
-       __le16 duration;
-       unsigned char ra[ETH_ALEN];
-       unsigned char ta[ETH_ALEN];
-       __le16 control;
-       __le16 start_seq_num;
-} __packed;
-
-/**
- * struct ieee80211_ht_cap - HT additional information
- *
- * This structure refers to "HT information element" as
- * described in 802.11n draft section 7.3.2.53
- */
-struct ieee80211_ht_addt_info {
-       unsigned char   control_chan;
-       unsigned char   ht_param;
-       __le16  operation_mode;
-       __le16  stbc_param;
-       unsigned char   basic_set[16];
-} __packed;
-
-struct HT_caps_element {
-       union {
-               struct {
-                       __le16  HT_caps_info;
-                       unsigned char   AMPDU_para;
-                       unsigned char   MCS_rate[16];
-                       __le16  HT_ext_caps;
-                       __le16  Beamforming_caps;
-                       unsigned char   ASEL_caps;
-               } HT_cap_element;
-               unsigned char HT_cap[26];
-       } u;
-} __packed;
-
-struct HT_info_element {
-       unsigned char   primary_channel;
-       unsigned char   infos[5];
-       unsigned char   MCS_rate[16];
-} __packed;
-
-struct AC_param {
-       unsigned char           ACI_AIFSN;
-       unsigned char           CW;
-       __le16  TXOP_limit;
-} __packed;
-
-struct WMM_para_element {
-       unsigned char           QoS_info;
-       unsigned char           reserved;
-       struct AC_param ac_param[4];
-} __packed;
-
-#define MAX_AMPDU_FACTOR_64K   3
-
-/* Spatial Multiplexing Power Save Modes */
-#define WLAN_HT_CAP_SM_PS_STATIC       0
-#define WLAN_HT_CAP_SM_PS_DYNAMIC      1
-#define WLAN_HT_CAP_SM_PS_INVALID      2
-#define WLAN_HT_CAP_SM_PS_DISABLED     3
-
-#define OP_MODE_PURE                    0
-#define OP_MODE_MAY_BE_LEGACY_STAS      1
-#define OP_MODE_20MHZ_HT_STA_ASSOCED    2
-#define OP_MODE_MIXED                   3
-
-#define HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK       ((u8) BIT(0) | BIT(1))
-#define HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE          ((u8) BIT(0))
-#define HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW          ((u8) BIT(0) | BIT(1))
-#define HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH          ((u8) BIT(2))
-#define HT_INFO_HT_PARAM_RIFS_MODE                     ((u8) BIT(3))
-#define HT_INFO_HT_PARAM_CTRL_ACCESS_ONLY              ((u8) BIT(4))
-#define HT_INFO_HT_PARAM_SRV_INTERVAL_GRANULARITY      ((u8) BIT(5))
-
-#define HT_INFO_OPERATION_MODE_OP_MODE_MASK    \
-               ((u16) (0x0001 | 0x0002))
-#define HT_INFO_OPERATION_MODE_OP_MODE_OFFSET          0
-#define HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT     ((u8) BIT(2))
-#define HT_INFO_OPERATION_MODE_TRANSMIT_BURST_LIMIT    ((u8) BIT(3))
-#define HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT      ((u8) BIT(4))
-
-/*     ===============WPS Section=============== */
-/*     For WPSv1.0 */
-#define WPSOUI                                 0x0050f204
-/*     WPS attribute ID */
-#define WPS_ATTR_VER1                          0x104A
-#define WPS_ATTR_SIMPLE_CONF_STATE             0x1044
-#define WPS_ATTR_RESP_TYPE                     0x103B
-#define WPS_ATTR_UUID_E                                0x1047
-#define WPS_ATTR_MANUFACTURER                  0x1021
-#define WPS_ATTR_MODEL_NAME                    0x1023
-#define WPS_ATTR_MODEL_NUMBER                  0x1024
-#define WPS_ATTR_SERIAL_NUMBER                 0x1042
-#define WPS_ATTR_PRIMARY_DEV_TYPE              0x1054
-#define WPS_ATTR_SEC_DEV_TYPE_LIST             0x1055
-#define WPS_ATTR_DEVICE_NAME                   0x1011
-#define WPS_ATTR_CONF_METHOD                   0x1008
-#define WPS_ATTR_RF_BANDS                      0x103C
-#define WPS_ATTR_DEVICE_PWID                   0x1012
-#define WPS_ATTR_REQUEST_TYPE                  0x103A
-#define WPS_ATTR_ASSOCIATION_STATE             0x1002
-#define WPS_ATTR_CONFIG_ERROR                  0x1009
-#define WPS_ATTR_VENDOR_EXT                    0x1049
-#define WPS_ATTR_SELECTED_REGISTRAR            0x1041
-
-/*     Value of WPS attribute "WPS_ATTR_DEVICE_NAME */
-#define WPS_MAX_DEVICE_NAME_LEN                        32
-
-/*     Value of WPS Request Type Attribute */
-#define WPS_REQ_TYPE_ENROLLEE_INFO_ONLY                0x00
-#define WPS_REQ_TYPE_ENROLLEE_OPEN_8021X       0x01
-#define WPS_REQ_TYPE_REGISTRAR                 0x02
-#define WPS_REQ_TYPE_WLAN_MANAGER_REGISTRAR    0x03
-
-/*     Value of WPS Response Type Attribute */
-#define WPS_RESPONSE_TYPE_INFO_ONLY    0x00
-#define WPS_RESPONSE_TYPE_8021X                0x01
-#define WPS_RESPONSE_TYPE_REGISTRAR    0x02
-#define WPS_RESPONSE_TYPE_AP           0x03
-
-/*     Value of WPS WiFi Simple Configuration State Attribute */
-#define WPS_WSC_STATE_NOT_CONFIG       0x01
-#define WPS_WSC_STATE_CONFIG           0x02
-
-/*     Value of WPS Version Attribute */
-#define WPS_VERSION_1                  0x10
-
-/*     Value of WPS Configuration Method Attribute */
-#define WPS_CONFIG_METHOD_FLASH                0x0001
-#define WPS_CONFIG_METHOD_ETHERNET     0x0002
-#define WPS_CONFIG_METHOD_LABEL                0x0004
-#define WPS_CONFIG_METHOD_DISPLAY      0x0008
-#define WPS_CONFIG_METHOD_E_NFC                0x0010
-#define WPS_CONFIG_METHOD_I_NFC                0x0020
-#define WPS_CONFIG_METHOD_NFC          0x0040
-#define WPS_CONFIG_METHOD_PBC          0x0080
-#define WPS_CONFIG_METHOD_KEYPAD       0x0100
-#define WPS_CONFIG_METHOD_VPBC         0x0280
-#define WPS_CONFIG_METHOD_PPBC         0x0480
-#define WPS_CONFIG_METHOD_VDISPLAY     0x2008
-#define WPS_CONFIG_METHOD_PDISPLAY     0x4008
-
-/*     Value of Category ID of WPS Primary Device Type Attribute */
-#define WPS_PDT_CID_DISPLAYS           0x0007
-#define WPS_PDT_CID_MULIT_MEDIA                0x0008
-#define WPS_PDT_CID_RTK_WIDI           WPS_PDT_CID_MULIT_MEDIA
-
-/*     Value of Sub Category ID of WPS Primary Device Type Attribute */
-#define WPS_PDT_SCID_MEDIA_SERVER      0x0005
-#define WPS_PDT_SCID_RTK_DMP           WPS_PDT_SCID_MEDIA_SERVER
-
-/*     Value of Device Password ID */
-#define WPS_DPID_P                     0x0000
-#define WPS_DPID_USER_SPEC             0x0001
-#define WPS_DPID_MACHINE_SPEC          0x0002
-#define WPS_DPID_REKEY                 0x0003
-#define WPS_DPID_PBC                   0x0004
-#define WPS_DPID_REGISTRAR_SPEC                0x0005
-
-/*     Value of WPS RF Bands Attribute */
-#define WPS_RF_BANDS_2_4_GHZ           0x01
-#define WPS_RF_BANDS_5_GHZ             0x02
-
-/*     Value of WPS Association State Attribute */
-#define WPS_ASSOC_STATE_NOT_ASSOCIATED         0x00
-#define WPS_ASSOC_STATE_CONNECTION_SUCCESS     0x01
-#define WPS_ASSOC_STATE_CONFIGURATION_FAILURE  0x02
-#define WPS_ASSOC_STATE_ASSOCIATION_FAILURE    0x03
-#define WPS_ASSOC_STATE_IP_FAILURE             0x04
-
-/*     =====================P2P Section===================== */
-/*     For P2P */
-#define        P2POUI                                  0x506F9A09
-
-/*     P2P Attribute ID */
-#define        P2P_ATTR_STATUS                         0x00
-#define        P2P_ATTR_MINOR_REASON_CODE              0x01
-#define        P2P_ATTR_CAPABILITY                     0x02
-#define        P2P_ATTR_DEVICE_ID                      0x03
-#define        P2P_ATTR_GO_INTENT                      0x04
-#define        P2P_ATTR_CONF_TIMEOUT                   0x05
-#define        P2P_ATTR_LISTEN_CH                      0x06
-#define        P2P_ATTR_GROUP_BSSID                    0x07
-#define        P2P_ATTR_EX_LISTEN_TIMING               0x08
-#define        P2P_ATTR_INTENTED_IF_ADDR               0x09
-#define        P2P_ATTR_MANAGEABILITY                  0x0A
-#define        P2P_ATTR_CH_LIST                        0x0B
-#define        P2P_ATTR_NOA                            0x0C
-#define        P2P_ATTR_DEVICE_INFO                    0x0D
-#define        P2P_ATTR_GROUP_INFO                     0x0E
-#define        P2P_ATTR_GROUP_ID                       0x0F
-#define        P2P_ATTR_INTERFACE                      0x10
-#define        P2P_ATTR_OPERATING_CH                   0x11
-#define        P2P_ATTR_INVITATION_FLAGS               0x12
-
-/*     Value of Status Attribute */
-#define        P2P_STATUS_SUCCESS                              0x00
-#define        P2P_STATUS_FAIL_INFO_UNAVAILABLE                0x01
-#define        P2P_STATUS_FAIL_INCOMPATIBLE_PARAM              0x02
-#define        P2P_STATUS_FAIL_LIMIT_REACHED                   0x03
-#define        P2P_STATUS_FAIL_INVALID_PARAM                   0x04
-#define        P2P_STATUS_FAIL_REQUEST_UNABLE                  0x05
-#define        P2P_STATUS_FAIL_PREVOUS_PROTO_ERR               0x06
-#define        P2P_STATUS_FAIL_NO_COMMON_CH                    0x07
-#define        P2P_STATUS_FAIL_UNKNOWN_P2PGROUP                0x08
-#define        P2P_STATUS_FAIL_BOTH_GOINTENT_15                0x09
-#define        P2P_STATUS_FAIL_INCOMPATIBLE_PROVSION           0x0A
-#define        P2P_STATUS_FAIL_USER_REJECT                     0x0B
-
-/*     Value of Inviation Flags Attribute */
-#define        P2P_INVITATION_FLAGS_PERSISTENT                 BIT(0)
-
-#define        DMP_P2P_DEVCAP_SUPPORT  (P2P_DEVCAP_SERVICE_DISCOVERY | \
-                               P2P_DEVCAP_CLIENT_DISCOVERABILITY | \
-                               P2P_DEVCAP_CONCURRENT_OPERATION | \
-                               P2P_DEVCAP_INVITATION_PROC)
-
-#define        DMP_P2P_GRPCAP_SUPPORT  (P2P_GRPCAP_INTRABSS)
-
-/*     Value of Device Capability Bitmap */
-#define        P2P_DEVCAP_SERVICE_DISCOVERY            BIT(0)
-#define        P2P_DEVCAP_CLIENT_DISCOVERABILITY       BIT(1)
-#define        P2P_DEVCAP_CONCURRENT_OPERATION         BIT(2)
-#define        P2P_DEVCAP_INFRA_MANAGED                BIT(3)
-#define        P2P_DEVCAP_DEVICE_LIMIT                 BIT(4)
-#define        P2P_DEVCAP_INVITATION_PROC              BIT(5)
-
-/*     Value of Group Capability Bitmap */
-#define        P2P_GRPCAP_GO                           BIT(0)
-#define        P2P_GRPCAP_PERSISTENT_GROUP             BIT(1)
-#define        P2P_GRPCAP_GROUP_LIMIT                  BIT(2)
-#define        P2P_GRPCAP_INTRABSS                     BIT(3)
-#define        P2P_GRPCAP_CROSS_CONN                   BIT(4)
-#define        P2P_GRPCAP_PERSISTENT_RECONN            BIT(5)
-#define        P2P_GRPCAP_GROUP_FORMATION              BIT(6)
-
-/*     P2P Public Action Frame (Management Frame) */
-#define        P2P_PUB_ACTION_ACTION                   0x09
-
-/*     P2P Public Action Frame Type */
-#define        P2P_GO_NEGO_REQ                         0
-#define        P2P_GO_NEGO_RESP                        1
-#define        P2P_GO_NEGO_CONF                        2
-#define        P2P_INVIT_REQ                           3
-#define        P2P_INVIT_RESP                          4
-#define        P2P_DEVDISC_REQ                         5
-#define        P2P_DEVDISC_RESP                        6
-#define        P2P_PROVISION_DISC_REQ                  7
-#define        P2P_PROVISION_DISC_RESP                 8
-
-/*     P2P Action Frame Type */
-#define        P2P_NOTICE_OF_ABSENCE                   0
-#define        P2P_PRESENCE_REQUEST                    1
-#define        P2P_PRESENCE_RESPONSE                   2
-#define        P2P_GO_DISC_REQUEST                     3
-
-#define        P2P_MAX_PERSISTENT_GROUP_NUM            10
-
-#define        P2P_PROVISIONING_SCAN_CNT               3
-
-#define        P2P_WILDCARD_SSID_LEN                   7
-
-/* default value, used when: (1)p2p disabled or (2)p2p enabled
- * but only do 1 scan phase */
-#define        P2P_FINDPHASE_EX_NONE           0
-/*  used when p2p enabled and want to do 1 scan phase and
- *  P2P_FINDPHASE_EX_MAX-1 find phase */
-#define        P2P_FINDPHASE_EX_FULL           1
-#define        P2P_FINDPHASE_EX_SOCIAL_FIRST   (P2P_FINDPHASE_EX_FULL+1)
-#define        P2P_FINDPHASE_EX_MAX            4
-#define        P2P_FINDPHASE_EX_SOCIAL_LAST    P2P_FINDPHASE_EX_MAX
-
-/* 5 seconds timeout for sending the provision discovery request */
-#define        P2P_PROVISION_TIMEOUT           5000
-/* 3 seconds timeout for sending the prov disc request concurrent mode */
-#define        P2P_CONCURRENT_PROVISION_TIME   3000
-/* 5 seconds timeout for receiving the group negotiation response */
-#define        P2P_GO_NEGO_TIMEOUT             5000
-/* 3 seconds timeout for sending the negotiation request under concurrent mode */
-#define        P2P_CONCURRENT_GO_NEGO_TIME     3000
-/* 100ms */
-#define        P2P_TX_PRESCAN_TIMEOUT          100
-/* 5 seconds timeout for sending the invitation request */
-#define        P2P_INVITE_TIMEOUT              5000
-/* 3 seconds timeout for sending the invitation request under concurrent mode */
-#define        P2P_CONCURRENT_INVITE_TIME      3000
-/* 25 seconds timeout to reset the scan channel (based on channel plan) */
-#define        P2P_RESET_SCAN_CH               25000
-#define        P2P_MAX_INTENT                  15
-
-#define        P2P_MAX_NOA_NUM                 2
-
-/*     WPS Configuration Method */
-#define        WPS_CM_NONE                     0x0000
-#define        WPS_CM_LABEL                    0x0004
-#define        WPS_CM_DISPLYA                  0x0008
-#define        WPS_CM_EXTERNAL_NFC_TOKEN       0x0010
-#define        WPS_CM_INTEGRATED_NFC_TOKEN     0x0020
-#define        WPS_CM_NFC_INTERFACE            0x0040
-#define        WPS_CM_PUSH_BUTTON              0x0080
-#define        WPS_CM_KEYPAD                   0x0100
-#define        WPS_CM_SW_PUHS_BUTTON           0x0280
-#define        WPS_CM_HW_PUHS_BUTTON           0x0480
-#define        WPS_CM_SW_DISPLAY_P             0x2008
-#define        WPS_CM_LCD_DISPLAY_P            0x4008
-
-enum P2P_ROLE {
-       P2P_ROLE_DISABLE = 0,
-       P2P_ROLE_DEVICE = 1,
-       P2P_ROLE_CLIENT = 2,
-       P2P_ROLE_GO = 3
-};
-
-enum P2P_STATE {
-       P2P_STATE_NONE = 0,                     /* P2P disable */
-       /* P2P had enabled and do nothing */
-       P2P_STATE_IDLE = 1,
-       P2P_STATE_LISTEN = 2,                   /* In pure listen state */
-       P2P_STATE_SCAN = 3,                     /* In scan phase */
-       /* In the listen state of find phase */
-       P2P_STATE_FIND_PHASE_LISTEN = 4,
-       /* In the search state of find phase */
-       P2P_STATE_FIND_PHASE_SEARCH = 5,
-       /* In P2P provisioning discovery */
-       P2P_STATE_TX_PROVISION_DIS_REQ = 6,
-       P2P_STATE_RX_PROVISION_DIS_RSP = 7,
-       P2P_STATE_RX_PROVISION_DIS_REQ = 8,
-       /* Doing the group owner negotiation handshake */
-       P2P_STATE_GONEGO_ING = 9,
-       /* finish the group negotiation handshake with success */
-       P2P_STATE_GONEGO_OK = 10,
-       /* finish the group negotiation handshake with failure */
-       P2P_STATE_GONEGO_FAIL = 11,
-       /* receiving the P2P Inviation request and match with the profile. */
-       P2P_STATE_RECV_INVITE_REQ_MATCH = 12,
-       /* Doing the P2P WPS */
-       P2P_STATE_PROVISIONING_ING = 13,
-       /* Finish the P2P WPS */
-       P2P_STATE_PROVISIONING_DONE = 14,
-       /* Transmit the P2P Invitation request */
-       P2P_STATE_TX_INVITE_REQ = 15,
-       /* Receiving the P2P Invitation response */
-       P2P_STATE_RX_INVITE_RESP_OK = 16,
-       /* receiving the P2P Inviation request and dismatch with the profile. */
-       P2P_STATE_RECV_INVITE_REQ_DISMATCH = 17,
-       /* receiving the P2P Inviation request and this wifi is GO. */
-       P2P_STATE_RECV_INVITE_REQ_GO = 18,
-       /* receiving the P2P Inviation request to join an existing P2P Group. */
-       P2P_STATE_RECV_INVITE_REQ_JOIN = 19,
-       /* recveing the P2P Inviation response with failure */
-       P2P_STATE_RX_INVITE_RESP_FAIL = 20,
-       /* receiving p2p negotiation response with information is not available */
-       P2P_STATE_RX_INFOR_NOREADY = 21,
-       /* sending p2p negotiation response with information is not available */
-       P2P_STATE_TX_INFOR_NOREADY = 22,
-};
-
-enum P2P_WPSINFO {
-       P2P_NO_WPSINFO                          = 0,
-       P2P_GOT_WPSINFO_PEER_DISPLAY_PIN        = 1,
-       P2P_GOT_WPSINFO_SELF_DISPLAY_PIN        = 2,
-       P2P_GOT_WPSINFO_PBC                     = 3,
-};
-
-#define        P2P_PRIVATE_IOCTL_SET_LEN               64
-
-enum P2P_PROTO_WK_ID {
-       P2P_FIND_PHASE_WK = 0,
-       P2P_RESTORE_STATE_WK = 1,
-       P2P_PRE_TX_PROVDISC_PROCESS_WK = 2,
-       P2P_PRE_TX_NEGOREQ_PROCESS_WK = 3,
-       P2P_PRE_TX_INVITEREQ_PROCESS_WK = 4,
-       P2P_AP_P2P_CH_SWITCH_PROCESS_WK = 5,
-       P2P_RO_CH_WK = 6,
-};
-
-enum P2P_PS_STATE {
-       P2P_PS_DISABLE = 0,
-       P2P_PS_ENABLE = 1,
-       P2P_PS_SCAN = 2,
-       P2P_PS_SCAN_DONE = 3,
-       P2P_PS_ALLSTASLEEP = 4, /*  for P2P GO */
-};
-
-enum P2P_PS_MODE {
-       P2P_PS_NONE = 0,
-       P2P_PS_CTWINDOW = 1,
-       P2P_PS_NOA       = 2,
-       P2P_PS_MIX = 3, /*  CTWindow and NoA */
-};
-
-#define IP_MCAST_MAC(mac)                              \
-       ((mac[0] == 0x01) && (mac[1] == 0x00) && (mac[2] == 0x5e))
-#define ICMPV6_MCAST_MAC(mac)                          \
-       ((mac[0] == 0x33) && (mac[1] == 0x33) && (mac[2] != 0xff))
-
-#endif /*  _WIFI_H_ */
diff --git a/drivers/staging/r8188eu/include/wlan_bssdef.h b/drivers/staging/r8188eu/include/wlan_bssdef.h
deleted file mode 100644 (file)
index ffeafa1..0000000
+++ /dev/null
@@ -1,272 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __WLAN_BSSDEF_H__
-#define __WLAN_BSSDEF_H__
-
-#define MAX_IE_SZ                      768
-
-#define NDIS_802_11_LENGTH_SSID         32
-#define NDIS_802_11_LENGTH_RATES        8
-#define NDIS_802_11_LENGTH_RATES_EX     16
-
-#define NDIS_802_11_RSSI long           /*  in dBm */
-
-struct ndis_802_11_ssid {
-       u32  SsidLength;
-       u8  Ssid[32];
-};
-
-struct ndis_802_11_config_fh {
-       u32           Length;           /*  Length of structure */
-       u32           HopPattern;       /*  As defined by 802.11, MSB set */
-       u32           HopSet;           /*  to one if non-802.11 */
-       u32           DwellTime;        /*  units are Kusec */
-};
-
-/*
- *     FW will only save the channel number in DSConfig.
- *     ODI Handler will convert the channel number to freq. number.
- */
-struct ndis_802_11_config {
-       u32           Length;             /*  Length of structure */
-       u32           BeaconPeriod;       /*  units are Kusec */
-       u32           ATIMWindow;         /*  units are Kusec */
-       u32           DSConfig;           /*  Frequency, units are kHz */
-       struct ndis_802_11_config_fh    FHConfig;
-};
-
-enum ndis_802_11_network_infra {
-       Ndis802_11IBSS,
-       Ndis802_11Infrastructure,
-       Ndis802_11AutoUnknown,
-       Ndis802_11InfrastructureMax,     /*  dummy upper bound */
-       Ndis802_11APMode
-};
-
-struct ndis_802_11_fixed_ie {
-       u8  Timestamp[8];
-       u16  BeaconInterval;
-       u16  Capabilities;
-};
-
-struct ndis_802_11_var_ie {
-       u8  ElementID;
-       u8  Length;
-       u8  data[];
-};
-
-/*
- * Length is the 4 bytes multiples of the sume of
- *     [ETH_ALEN] + 2 + sizeof (struct ndis_802_11_ssid) + sizeof (u32)
- *     + sizeof (NDIS_802_11_RSSI) + sizeof (enum NDIS_802_11_NETWORK_TYPE)
- *     + sizeof (struct ndis_802_11_config)
- *     + NDIS_802_11_LENGTH_RATES_EX + IELength
- *
- * Except the IELength, all other fields are fixed length.
- * Therefore, we can define a macro to represent the partial sum. */
-
-enum ndis_802_11_auth_mode {
-       Ndis802_11AuthModeOpen,
-       Ndis802_11AuthModeShared,
-       Ndis802_11AuthModeAutoSwitch,
-       Ndis802_11AuthModeWPA,
-       Ndis802_11AuthModeWPAPSK,
-       Ndis802_11AuthModeWPANone,
-       Ndis802_11AuthModeWAPI,
-       Ndis802_11AuthModeMax   /*  Not a real mode, upper bound */
-};
-
-enum ndis_802_11_wep_status {
-       Ndis802_11WEPEnabled,
-       Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
-       Ndis802_11WEPDisabled,
-       Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
-       Ndis802_11WEPKeyAbsent,
-       Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
-       Ndis802_11WEPNotSupported,
-       Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
-       Ndis802_11Encryption2Enabled,
-       Ndis802_11Encryption2KeyAbsent,
-       Ndis802_11Encryption3Enabled,
-       Ndis802_11Encryption3KeyAbsent,
-       Ndis802_11_EncryptionWAPI
-};
-
-#define NDIS_802_11_AI_REQFI_CAPABILITIES      1
-#define NDIS_802_11_AI_REQFI_LISTENINTERVAL    2
-#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS  4
-
-#define NDIS_802_11_AI_RESFI_CAPABILITIES      1
-#define NDIS_802_11_AI_RESFI_STATUSCODE        2
-#define NDIS_802_11_AI_RESFI_ASSOCIATIONID     4
-
-struct ndis_802_11_ai_reqfi {
-    u16 Capabilities;
-    u16 ListenInterval;
-    unsigned char CurrentAPAddress[ETH_ALEN];
-};
-
-struct ndis_802_11_ai_resfi {
-    u16 Capabilities;
-    u16 StatusCode;
-    u16 AssociationId;
-};
-
-struct ndis_802_11_assoc_info {
-       u32  Length;
-       u16 AvailableRequestFixedIEs;
-       struct ndis_802_11_ai_reqfi    RequestFixedIEs;
-       u32  RequestIELength;
-       u32  OffsetRequestIEs;
-       u16 AvailableResponseFixedIEs;
-       struct ndis_802_11_ai_resfi    ResponseFixedIEs;
-       u32  ResponseIELength;
-       u32  OffsetResponseIEs;
-};
-
-/*  Key mapping keys require a BSSID */
-struct ndis_802_11_key {
-       u32           Length;             /*  Length of this structure */
-       u32           KeyIndex;
-       u32           KeyLength;          /*  length of key in bytes */
-       unsigned char BSSID[ETH_ALEN];
-       unsigned long long KeyRSC;
-       u8           KeyMaterial[32];  /* var len depending on above field */
-};
-
-struct ndis_802_11_remove_key {
-       u32                   Length;        /*  Length */
-       u32                   KeyIndex;
-       unsigned char BSSID[ETH_ALEN];
-};
-
-struct ndis_802_11_wep {
-       u32     Length;        /*  Length of this structure */
-       u32     KeyIndex;      /*  0 is the per-client key,
-                                 * 1-N are the global keys */
-       u32     KeyLength;     /*  length of key in bytes */
-       u8     KeyMaterial[16];/*  variable len depending on above field */
-};
-
-struct ndis_802_11_auth_req {
-       u32 Length;            /*  Length of structure */
-       unsigned char Bssid[ETH_ALEN];
-       u32 Flags;
-};
-
-enum ndis_802_11_status_type {
-       Ndis802_11StatusType_Authentication,
-       Ndis802_11StatusType_MediaStreamMode,
-       Ndis802_11StatusType_PMKID_CandidateList,
-       Ndis802_11StatusTypeMax    /*  not a real type, defined as
-                                   * an upper bound */
-};
-
-struct ndis_802_11_status_ind {
-       enum ndis_802_11_status_type StatusType;
-};
-
-/*  mask for authentication/integrity fields */
-#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS           0x0f
-#define NDIS_802_11_AUTH_REQUEST_REAUTH                        0x01
-#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE             0x02
-#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR                0x06
-#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR           0x0E
-
-/*  MIC check time, 60 seconds. */
-#define MIC_CHECK_TIME 60000000
-
-#ifndef Ndis802_11APMode
-#define Ndis802_11APMode (Ndis802_11InfrastructureMax+1)
-#endif
-
-struct wlan_phy_info {
-       u8      SignalStrength;/* in percentage) */
-       u8      SignalQuality;/* in percentage) */
-       u8      Optimum_antenna;  /* for Antenna diversity */
-       u8      Reserved_0;
-};
-
-struct wlan_bcn_info {
-       /* these infor get from rtw_get_encrypt_info when
-        *       * translate scan to UI */
-       u8 encryp_protocol;/* ENCRYP_PROTOCOL_E: OPEN/WEP/WPA/WPA2/WAPI */
-       int group_cipher; /* WPA/WPA2 group cipher */
-       int pairwise_cipher;/* WPA/WPA2/WEP pairwise cipher */
-       int is_8021x;
-
-       /* bwmode 20/40 and ch_offset UP/LOW */
-       unsigned short  ht_cap_info;
-       unsigned char   ht_info_infos_0;
-};
-
-/* temporally add #pragma pack for structure alignment issue of
-*   struct wlan_bssid_ex and get_struct wlan_bssid_ex_sz()
-*/
-struct wlan_bssid_ex {
-       u32  Length;
-       unsigned char MacAddress[ETH_ALEN];
-       u8  Reserved[2];/* 0]: IS beacon frame */
-       struct ndis_802_11_ssid  Ssid;
-       u32  Privacy;
-       NDIS_802_11_RSSI  Rssi;/* in dBM,raw data ,get from PHY) */
-       struct ndis_802_11_config  Configuration;
-       enum ndis_802_11_network_infra  InfrastructureMode;
-       unsigned char SupportedRates[NDIS_802_11_LENGTH_RATES_EX];
-       struct wlan_phy_info    PhyInfo;
-       u32  IELength;
-       u8  IEs[MAX_IE_SZ];     /* timestamp, beacon interval, and
-                                * capability information) */
-} __packed;
-
-static inline uint get_wlan_bssid_ex_sz(struct wlan_bssid_ex *bss)
-{
-       return sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + bss->IELength;
-}
-
-struct wlan_network {
-       struct list_head list;
-       int     network_type;   /* refer to ieee80211.h for WIRELESS_11B/G */
-       int     fixed;          /*  set fixed when not to be removed
-                                *  in site-surveying */
-       unsigned long   last_scanned; /* timestamp for the network */
-       int     aid;            /* will only be valid when a BSS is joinned. */
-       int     join_res;
-       struct wlan_bssid_ex    network; /* must be the last item */
-       struct wlan_bcn_info    BcnInfo;
-};
-
-enum VRTL_CARRIER_SENSE {
-       DISABLE_VCS,
-       ENABLE_VCS,
-       AUTO_VCS
-};
-
-enum VCS_TYPE {
-       NONE_VCS,
-       RTS_CTS,
-       CTS_TO_SELF
-};
-
-#define PWR_CAM 0
-#define PWR_MINPS 1
-#define PWR_MAXPS 2
-#define PWR_UAPSD 3
-#define PWR_VOIP 4
-
-enum UAPSD_MAX_SP {
-       NO_LIMIT,
-       TWO_MSDU,
-       FOUR_MSDU,
-       SIX_MSDU
-};
-
-#define NUM_PRE_AUTH_KEY 16
-#define NUM_PMKID_CACHE NUM_PRE_AUTH_KEY
-
-u8 key_2char2num(u8 hch, u8 lch);
-u8 key_char2num(u8 ch);
-u8 str_2char2num(u8 hch, u8 lch);
-
-#endif /* ifndef WLAN_BSSDEF_H_ */
diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
deleted file mode 100644 (file)
index e0a8199..0000000
+++ /dev/null
@@ -1,3775 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/wlan_bssdef.h"
-#include "../include/wifi.h"
-#include "../include/rtw_mlme.h"
-#include "../include/rtw_mlme_ext.h"
-#include "../include/rtw_ioctl.h"
-#include "../include/rtw_ioctl_set.h"
-#include "../include/usb_ops.h"
-#include "../include/rtl8188e_hal.h"
-#include "../include/rtw_led.h"
-
-#include "../include/rtw_iol.h"
-
-#define RTL_IOCTL_WPA_SUPPLICANT       (SIOCIWFIRSTPRIV + 30)
-
-#define SCAN_ITEM_SIZE 768
-#define MAX_CUSTOM_LEN 64
-#define RATE_COUNT 4
-
-/*  combo scan */
-#define WEXT_CSCAN_AMOUNT 9
-#define WEXT_CSCAN_BUF_LEN             360
-#define WEXT_CSCAN_HEADER              "CSCAN S\x01\x00\x00S\x00"
-#define WEXT_CSCAN_HEADER_SIZE         12
-#define WEXT_CSCAN_SSID_SECTION                'S'
-#define WEXT_CSCAN_CHANNEL_SECTION     'C'
-#define WEXT_CSCAN_NPROBE_SECTION      'N'
-#define WEXT_CSCAN_ACTV_DWELL_SECTION  'A'
-#define WEXT_CSCAN_PASV_DWELL_SECTION  'P'
-#define WEXT_CSCAN_HOME_DWELL_SECTION  'H'
-#define WEXT_CSCAN_TYPE_SECTION                'T'
-
-static u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000,
-       6000000, 9000000, 12000000, 18000000, 24000000, 36000000,
-       48000000, 54000000};
-
-void indicate_wx_scan_complete_event(struct adapter *padapter)
-{
-       union iwreq_data wrqu;
-
-       memset(&wrqu, 0, sizeof(union iwreq_data));
-       wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL);
-}
-
-void rtw_indicate_wx_assoc_event(struct adapter *padapter)
-{
-       union iwreq_data wrqu;
-       struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
-       memset(&wrqu, 0, sizeof(union iwreq_data));
-
-       wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-
-       memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);
-
-       wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
-}
-
-void rtw_indicate_wx_disassoc_event(struct adapter *padapter)
-{
-       union iwreq_data wrqu;
-
-       memset(&wrqu, 0, sizeof(union iwreq_data));
-
-       wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-       memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
-
-       wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
-}
-
-static char *translate_scan(struct adapter *padapter,
-                           struct iw_request_info *info,
-                           struct wlan_network *pnetwork,
-                           char *start, char *stop)
-{
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct iw_event iwe;
-       u16 cap;
-       __le16 le_tmp;
-       u32 ht_ielen = 0;
-       char *custom;
-       char *p;
-       u16 max_rate = 0, rate, ht_cap = false;
-       u32 i = 0;
-       u8 bw_40MHz = 0, short_GI = 0;
-       u16 mcs_rate = 0;
-       u8 ss, sq;
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
-               u32     blnGotP2PIE = false;
-
-               /*      User is doing the P2P device discovery */
-               /*      The prefix of SSID should be "DIRECT-" and the IE should contains the P2P IE. */
-               /*      If not, the driver should ignore this AP and go to the next AP. */
-
-               /*      Verifying the SSID */
-               if (!memcmp(pnetwork->network.Ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN)) {
-                       u32     p2pielen = 0;
-
-                       if (pnetwork->network.Reserved[0] == 2) {/*  Probe Request */
-                               /*      Verifying the P2P IE */
-                               if (rtw_get_p2p_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &p2pielen))
-                                       blnGotP2PIE = true;
-                       } else {/*  Beacon or Probe Respones */
-                               /*      Verifying the P2P IE */
-                               if (rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen))
-                                       blnGotP2PIE = true;
-                       }
-               }
-
-               if (!blnGotP2PIE)
-                       return start;
-       }
-
-       /*  AP MAC address  */
-       iwe.cmd = SIOCGIWAP;
-       iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-
-       memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
-       start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
-
-       /* Add the ESSID */
-       iwe.cmd = SIOCGIWESSID;
-       iwe.u.data.flags = 1;
-       iwe.u.data.length = min_t(u16, pnetwork->network.Ssid.SsidLength, 32);
-       start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
-
-       /* parsing HT_CAP_IE */
-       p = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength - 12);
-
-       if (p && ht_ielen > 0) {
-               struct ieee80211_ht_cap *pht_capie;
-
-               ht_cap = true;
-               pht_capie = (struct ieee80211_ht_cap *)(p + 2);
-               memcpy(&mcs_rate, pht_capie->mcs.rx_mask, 2);
-               bw_40MHz = (le16_to_cpu(pht_capie->cap_info) &
-                           IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
-               short_GI = (le16_to_cpu(pht_capie->cap_info) &
-                           (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
-       }
-
-       /* Add the protocol name */
-       iwe.cmd = SIOCGIWNAME;
-       if ((rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates))) {
-               if (ht_cap)
-                       snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
-               else
-               snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
-       } else if ((rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates))) {
-               if (ht_cap)
-                       snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
-               else
-                       snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
-       } else {
-               if (ht_cap)
-                       snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
-               else
-                       snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
-       }
-
-       start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
-
-         /* Add mode */
-       iwe.cmd = SIOCGIWMODE;
-       memcpy(&le_tmp, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
-
-       cap = le16_to_cpu(le_tmp);
-
-       if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) {
-               if (cap & WLAN_CAPABILITY_BSS)
-                       iwe.u.mode = IW_MODE_MASTER;
-               else
-                       iwe.u.mode = IW_MODE_ADHOC;
-
-               start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
-       }
-
-       if (pnetwork->network.Configuration.DSConfig < 1)
-               pnetwork->network.Configuration.DSConfig = 1;
-
-        /* Add frequency/channel */
-       iwe.cmd = SIOCGIWFREQ;
-       iwe.u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
-       iwe.u.freq.e = 1;
-       iwe.u.freq.i = pnetwork->network.Configuration.DSConfig;
-       start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
-
-       /* Add encryption capability */
-       iwe.cmd = SIOCGIWENCODE;
-       if (cap & WLAN_CAPABILITY_PRIVACY)
-               iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-       else
-               iwe.u.data.flags = IW_ENCODE_DISABLED;
-       iwe.u.data.length = 0;
-       start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
-
-       /*Add basic and extended rates */
-       max_rate = 0;
-       custom = kzalloc(MAX_CUSTOM_LEN, GFP_ATOMIC);
-       if (!custom)
-               return start;
-       p = custom;
-       p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
-       while (pnetwork->network.SupportedRates[i] != 0) {
-               rate = pnetwork->network.SupportedRates[i] & 0x7F;
-               if (rate > max_rate)
-                       max_rate = rate;
-               p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
-                             "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
-               i++;
-       }
-
-       if (ht_cap) {
-               if (mcs_rate & 0x8000)/* MCS15 */
-                       max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : ((short_GI) ? 144 : 130);
-               else if (mcs_rate & 0x0080)/* MCS7 */
-                       ;
-               else/* default MCS7 */
-                       max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);
-
-               max_rate = max_rate * 2;/* Mbps/2; */
-       }
-
-       iwe.cmd = SIOCGIWRATE;
-       iwe.u.bitrate.fixed = 0;
-       iwe.u.bitrate.disabled = 0;
-       iwe.u.bitrate.value = max_rate * 500000;
-       start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
-
-       /* parsing WPA/WPA2 IE */
-       {
-               u8 *buf;
-               u8 *wpa_ie, *rsn_ie;
-               u16 wpa_len = 0, rsn_len = 0;
-               u8 *p;
-
-               buf = kzalloc(MAX_WPA_IE_LEN, GFP_ATOMIC);
-               if (!buf)
-                       goto exit;
-               wpa_ie = kzalloc(255, GFP_ATOMIC);
-               if (!wpa_ie) {
-                       kfree(buf);
-                       goto exit;
-               }
-               rsn_ie = kzalloc(255, GFP_ATOMIC);
-               if (!rsn_ie) {
-                       kfree(buf);
-                       kfree(wpa_ie);
-                       goto exit;
-               }
-               rtw_get_sec_ie(pnetwork->network.IEs, pnetwork->network.IELength, rsn_ie, &rsn_len, wpa_ie, &wpa_len);
-
-               if (wpa_len > 0) {
-                       p = buf;
-                       memset(buf, 0, MAX_WPA_IE_LEN);
-                       p += sprintf(p, "wpa_ie =");
-                       for (i = 0; i < wpa_len; i++)
-                               p += sprintf(p, "%02x", wpa_ie[i]);
-
-                       memset(&iwe, 0, sizeof(iwe));
-                       iwe.cmd = IWEVCUSTOM;
-                       iwe.u.data.length = strlen(buf);
-                       start = iwe_stream_add_point(info, start, stop, &iwe, buf);
-
-                       memset(&iwe, 0, sizeof(iwe));
-                       iwe.cmd = IWEVGENIE;
-                       iwe.u.data.length = wpa_len;
-                       start = iwe_stream_add_point(info, start, stop, &iwe, wpa_ie);
-               }
-               if (rsn_len > 0) {
-                       p = buf;
-                       memset(buf, 0, MAX_WPA_IE_LEN);
-                       p += sprintf(p, "rsn_ie =");
-                       for (i = 0; i < rsn_len; i++)
-                               p += sprintf(p, "%02x", rsn_ie[i]);
-                       memset(&iwe, 0, sizeof(iwe));
-                       iwe.cmd = IWEVCUSTOM;
-                       iwe.u.data.length = strlen(buf);
-                       start = iwe_stream_add_point(info, start, stop, &iwe, buf);
-
-                       memset(&iwe, 0, sizeof(iwe));
-                       iwe.cmd = IWEVGENIE;
-                       iwe.u.data.length = rsn_len;
-                       start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie);
-               }
-               kfree(buf);
-               kfree(wpa_ie);
-               kfree(rsn_ie);
-       }
-
-       {/* parsing WPS IE */
-               uint cnt = 0, total_ielen;
-               u8 *wpsie_ptr = NULL;
-               uint wps_ielen = 0;
-
-               u8 *ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
-               total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
-
-               while (cnt < total_ielen) {
-                       if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen > 2)) {
-                               wpsie_ptr = &ie_ptr[cnt];
-                               iwe.cmd = IWEVGENIE;
-                               iwe.u.data.length = (u16)wps_ielen;
-                               start = iwe_stream_add_point(info, start, stop, &iwe, wpsie_ptr);
-                       }
-                       cnt += ie_ptr[cnt + 1] + 2; /* goto next */
-               }
-       }
-
-       /* Add quality statistics */
-       iwe.cmd = IWEVQUAL;
-       iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID;
-
-       if (check_fwstate(pmlmepriv, _FW_LINKED) &&
-           is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network)) {
-               ss = padapter->recvpriv.signal_strength;
-               sq = padapter->recvpriv.signal_qual;
-       } else {
-               ss = pnetwork->network.PhyInfo.SignalStrength;
-               sq = pnetwork->network.PhyInfo.SignalQuality;
-       }
-
-       iwe.u.qual.level = (u8)ss;
-       iwe.u.qual.qual = (u8)sq;   /*  signal quality */
-       iwe.u.qual.noise = 0; /*  noise level */
-       start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
-exit:
-       kfree(custom);
-       return start;
-}
-
-static int wpa_set_auth_algs(struct net_device *dev, u32 value)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       int ret = 0;
-
-       if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
-               padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
-               padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
-               padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
-       } else if (value & AUTH_ALG_SHARED_KEY) {
-               padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
-
-               padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
-               padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
-       } else if (value & AUTH_ALG_OPEN_SYSTEM) {
-               if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) {
-                       padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
-                       padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
-               }
-       } else if (!(value & AUTH_ALG_LEAP)) {
-               ret = -EINVAL;
-       }
-       return ret;
-}
-
-static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
-{
-       int ret = 0;
-       u32 wep_key_idx, wep_key_len, wep_total_len;
-       struct ndis_802_11_wep   *pwep = NULL;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-       struct security_priv *psecuritypriv = &padapter->securitypriv;
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       param->u.crypt.err = 0;
-       param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
-
-       if (param_len < (u32)((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) {
-               ret =  -EINVAL;
-               goto exit;
-       }
-
-       if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
-           param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
-           param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
-               if (param->u.crypt.idx >= WEP_KEYS) {
-                       ret = -EINVAL;
-                       goto exit;
-               }
-       } else {
-               ret = -EINVAL;
-               goto exit;
-       }
-
-       if (strcmp(param->u.crypt.alg, "WEP") == 0) {
-               padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
-               padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
-               padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
-
-               wep_key_idx = param->u.crypt.idx;
-               wep_key_len = param->u.crypt.key_len;
-
-               if (wep_key_idx > WEP_KEYS)
-                       return -EINVAL;
-
-               if (wep_key_len > 0) {
-                       wep_key_len = wep_key_len <= 5 ? 5 : 13;
-                       wep_total_len = wep_key_len + sizeof(*pwep);
-                       pwep = kzalloc(wep_total_len, GFP_KERNEL);
-                       if (!pwep)
-                               goto exit;
-
-                       pwep->KeyLength = wep_key_len;
-                       pwep->Length = wep_total_len;
-                       if (wep_key_len == 13) {
-                               padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
-                               padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
-                       }
-               } else {
-                       ret = -EINVAL;
-                       goto exit;
-               }
-               pwep->KeyIndex = wep_key_idx;
-               pwep->KeyIndex |= 0x80000000;
-               memcpy(pwep->KeyMaterial,  param->u.crypt.key, pwep->KeyLength);
-               if (param->u.crypt.set_tx) {
-                       if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
-                               ret = -EOPNOTSUPP;
-               } else {
-                       if (wep_key_idx >= WEP_KEYS) {
-                               ret = -EOPNOTSUPP;
-                               goto exit;
-                       }
-                       memcpy(&psecuritypriv->dot11DefKey[wep_key_idx].skey[0], pwep->KeyMaterial, pwep->KeyLength);
-                       psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
-                       rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0);
-               }
-               goto exit;
-       }
-
-       if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /*  802_1x */
-               struct sta_info *psta, *pbcmc_sta;
-               struct sta_priv *pstapriv = &padapter->stapriv;
-
-               if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE)) { /* sta mode */
-                       psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
-                       if (!psta) {
-                               ;
-                       } else {
-                               if (strcmp(param->u.crypt.alg, "none") != 0)
-                                       psta->ieee8021x_blocked = false;
-
-                               if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
-                                   (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
-                                       psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
-
-                               if (param->u.crypt.set_tx == 1) { /* pairwise key */
-                                       memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
-
-                                       if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
-                                               memcpy(psta->dot11tkiptxmickey.skey, &param->u.crypt.key[16], 8);
-                                               memcpy(psta->dot11tkiprxmickey.skey, &param->u.crypt.key[24], 8);
-                                               padapter->securitypriv.busetkipkey = false;
-                                       }
-
-                                       rtw_setstakey_cmd(padapter, (unsigned char *)psta, true);
-                               } else { /* group key */
-                                       memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
-                                       memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &param->u.crypt.key[16], 8);
-                                       memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &param->u.crypt.key[24], 8);
-                                       padapter->securitypriv.binstallGrpkey = true;
-
-                                       padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
-
-                                       rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1);
-                                       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
-                                               rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
-                               }
-                       }
-                       pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
-                       if (!pbcmc_sta) {
-                               ;
-                       } else {
-                               /* Jeff: don't disable ieee8021x_blocked while clearing key */
-                               if (strcmp(param->u.crypt.alg, "none") != 0)
-                                       pbcmc_sta->ieee8021x_blocked = false;
-
-                               if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
-                                   (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
-                                       pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
-                       }
-               }
-       }
-
-exit:
-
-       kfree(pwep);
-
-       return ret;
-}
-
-static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ielen)
-{
-       u8 *buf = NULL;
-       int group_cipher = 0, pairwise_cipher = 0;
-       int ret = 0;
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       if (ielen > MAX_WPA_IE_LEN || !pie) {
-               _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
-               if (!pie)
-                       return ret;
-               else
-                       return -EINVAL;
-       }
-
-       if (ielen) {
-               buf = kmemdup(pie, ielen, GFP_KERNEL);
-               if (!buf) {
-                       ret =  -ENOMEM;
-                       goto exit;
-               }
-
-               if (ielen < RSN_HEADER_LEN) {
-                       ret  = -1;
-                       goto exit;
-               }
-
-               if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
-                       padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
-                       padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
-                       memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
-               }
-
-               if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
-                       padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
-                       padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
-                       memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
-               }
-
-               switch (group_cipher) {
-               case WPA_CIPHER_NONE:
-                       padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
-                       padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
-                       break;
-               case WPA_CIPHER_WEP40:
-                       padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
-                       padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
-                       break;
-               case WPA_CIPHER_TKIP:
-                       padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
-                       padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
-                       break;
-               case WPA_CIPHER_CCMP:
-                       padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
-                       padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
-                       break;
-               case WPA_CIPHER_WEP104:
-                       padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
-                       padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
-                       break;
-               }
-
-               switch (pairwise_cipher) {
-               case WPA_CIPHER_NONE:
-                       padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
-                       padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
-                       break;
-               case WPA_CIPHER_WEP40:
-                       padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
-                       padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
-                       break;
-               case WPA_CIPHER_TKIP:
-                       padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
-                       padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
-                       break;
-               case WPA_CIPHER_CCMP:
-                       padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
-                       padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
-                       break;
-               case WPA_CIPHER_WEP104:
-                       padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
-                       padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
-                       break;
-               }
-
-               _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
-               {/* set wps_ie */
-                       u16 cnt = 0;
-                       u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
-
-                       while (cnt < ielen) {
-                               eid = buf[cnt];
-                               if ((eid == _VENDOR_SPECIFIC_IE_) && (!memcmp(&buf[cnt + 2], wps_oui, 4))) {
-                                       padapter->securitypriv.wps_ie_len = ((buf[cnt + 1] + 2) < (MAX_WPA_IE_LEN << 2)) ? (buf[cnt + 1] + 2) : (MAX_WPA_IE_LEN << 2);
-
-                                       memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
-
-                                       set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
-                                       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK))
-                                               rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_ING);
-                                       cnt += buf[cnt + 1] + 2;
-                                       break;
-                               } else {
-                                       cnt += buf[cnt + 1] + 2; /* goto next */
-                               }
-                       }
-               }
-       }
-
-exit:
-       kfree(buf);
-       return ret;
-}
-
-typedef unsigned char   NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX];
-
-static int rtw_wx_get_name(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       u32 ht_ielen = 0;
-       char *p;
-       u8 ht_cap = false;
-       struct  mlme_priv       *pmlmepriv = &padapter->mlmepriv;
-       struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
-       NDIS_802_11_RATES_EX *prates = NULL;
-
-       if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
-               /* parsing HT_CAP_IE */
-               p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength - 12);
-               if (p && ht_ielen > 0)
-                       ht_cap = true;
-
-               prates = &pcur_bss->SupportedRates;
-
-               if (rtw_is_cckratesonly_included((u8 *)prates)) {
-                       if (ht_cap)
-                               snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");
-                       else
-                               snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
-               } else if (rtw_is_cckrates_included((u8 *)prates)) {
-                       if (ht_cap)
-                               snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");
-                       else
-                               snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
-               } else {
-                       if (ht_cap)
-                               snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
-                       else
-                               snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
-               }
-       } else {
-               snprintf(wrqu->name, IFNAMSIZ, "unassociated");
-       }
-
-
-
-       return 0;
-}
-
-static int rtw_wx_get_freq(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct  mlme_priv       *pmlmepriv = &padapter->mlmepriv;
-       struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
-
-       if (check_fwstate(pmlmepriv, _FW_LINKED)) {
-               /* wrqu->freq.m = ieee80211_wlan_frequencies[pcur_bss->Configuration.DSConfig-1] * 100000; */
-               wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
-               wrqu->freq.e = 1;
-               wrqu->freq.i = pcur_bss->Configuration.DSConfig;
-       } else {
-               wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
-               wrqu->freq.e = 1;
-               wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
-       }
-
-       return 0;
-}
-
-static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *b)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       enum ndis_802_11_network_infra networkType;
-       int ret = 0;
-
-       ret = rtw_pwr_wakeup(padapter);
-       if (ret)
-               goto exit;
-
-       if (!padapter->hw_init_completed) {
-               ret = -EPERM;
-               goto exit;
-       }
-
-       switch (wrqu->mode) {
-       case IW_MODE_AUTO:
-               networkType = Ndis802_11AutoUnknown;
-               break;
-       case IW_MODE_ADHOC:
-               networkType = Ndis802_11IBSS;
-               break;
-       case IW_MODE_MASTER:
-               networkType = Ndis802_11APMode;
-               break;
-       case IW_MODE_INFRA:
-               networkType = Ndis802_11Infrastructure;
-               break;
-       default:
-               ret = -EINVAL;
-               goto exit;
-       }
-       if (!rtw_set_802_11_infrastructure_mode(padapter, networkType)) {
-               ret = -EPERM;
-               goto exit;
-       }
-       rtw_setopmode_cmd(padapter, networkType);
-exit:
-
-       return ret;
-}
-
-static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *b)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct  mlme_priv       *pmlmepriv = &padapter->mlmepriv;
-
-       if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
-               wrqu->mode = IW_MODE_INFRA;
-       else if  ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) ||
-                 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)))
-               wrqu->mode = IW_MODE_ADHOC;
-       else if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
-               wrqu->mode = IW_MODE_MASTER;
-       else
-               wrqu->mode = IW_MODE_AUTO;
-
-
-
-       return 0;
-}
-
-static int rtw_wx_set_pmkid(struct net_device *dev,
-                           struct iw_request_info *a,
-                           union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       u8   j, blInserted = false;
-       int  ret = false;
-       struct security_priv *psecuritypriv = &padapter->securitypriv;
-       struct iw_pmksa *pPMK = (struct iw_pmksa *)extra;
-       u8     strZeroMacAddress[ETH_ALEN] = {0x00};
-       u8     strIssueBssid[ETH_ALEN] = {0x00};
-
-       memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
-       if (pPMK->cmd == IW_PMKSA_ADD) {
-               if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
-                       return ret;
-               else
-                       ret = true;
-               blInserted = false;
-
-               /* overwrite PMKID */
-               for (j = 0; j < NUM_PMKID_CACHE; j++) {
-                       if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
-                               /*  BSSID is matched, the same AP => rewrite with new PMKID. */
-                               memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
-                               psecuritypriv->PMKIDList[j].bUsed = true;
-                               psecuritypriv->PMKIDIndex = j + 1;
-                               blInserted = true;
-                               break;
-                       }
-               }
-
-               if (!blInserted) {
-                       /*  Find a new entry */
-                       memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
-                       memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
-
-                       psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = true;
-                       psecuritypriv->PMKIDIndex++;
-                       if (psecuritypriv->PMKIDIndex == 16)
-                               psecuritypriv->PMKIDIndex = 0;
-               }
-       } else if (pPMK->cmd == IW_PMKSA_REMOVE) {
-               ret = true;
-               for (j = 0; j < NUM_PMKID_CACHE; j++) {
-                       if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
-                               /*  BSSID is matched, the same AP => Remove this PMKID information and reset it. */
-                               memset(psecuritypriv->PMKIDList[j].Bssid, 0x00, ETH_ALEN);
-                               psecuritypriv->PMKIDList[j].bUsed = false;
-                               break;
-                       }
-              }
-       } else if (pPMK->cmd == IW_PMKSA_FLUSH) {
-               memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
-               psecuritypriv->PMKIDIndex = 0;
-               ret = true;
-       }
-       return ret;
-}
-
-static int rtw_wx_get_sens(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
-{
-       wrqu->sens.value = 0;
-       wrqu->sens.fixed = 0;   /* no auto select */
-       wrqu->sens.disabled = 1;
-       return 0;
-}
-
-static int rtw_wx_get_range(struct net_device *dev,
-                               struct iw_request_info *info,
-                               union iwreq_data *wrqu, char *extra)
-{
-       struct iw_range *range = (struct iw_range *)extra;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-
-       u16 val;
-       int i;
-
-       wrqu->data.length = sizeof(*range);
-       memset(range, 0, sizeof(*range));
-
-       /* Let's try to keep this struct in the same order as in
-        * linux/include/wireless.h
-        */
-
-       /* TODO: See what values we can set, and remove the ones we can't
-        * set, or fill them with some default data.
-        */
-
-       /* ~5 Mb/s real (802.11b) */
-       range->throughput = 5 * 1000 * 1000;
-
-       /* signal level threshold range */
-
-       /* percent values between 0 and 100. */
-       range->max_qual.qual = 100;
-       range->max_qual.level = 100;
-       range->max_qual.noise = 100;
-       range->max_qual.updated = 7; /* Updated all three */
-
-       range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
-       /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
-       range->avg_qual.level = 178; /* -78 dBm */
-       range->avg_qual.noise = 0;
-       range->avg_qual.updated = 7; /* Updated all three */
-
-       range->num_bitrates = RATE_COUNT;
-
-       for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
-               range->bitrate[i] = rtw_rates[i];
-
-       range->min_frag = MIN_FRAG_THRESHOLD;
-       range->max_frag = MAX_FRAG_THRESHOLD;
-
-       range->pm_capa = 0;
-
-       range->we_version_compiled = WIRELESS_EXT;
-       range->we_version_source = 16;
-
-       for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) {
-               /*  Include only legal frequencies for some countries */
-               if (pmlmeext->channel_set[i].ChannelNum != 0) {
-                       range->freq[val].i = pmlmeext->channel_set[i].ChannelNum;
-                       range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000;
-                       range->freq[val].e = 1;
-                       val++;
-               }
-
-               if (val == IW_MAX_FREQUENCIES)
-                       break;
-       }
-
-       range->num_channels = val;
-       range->num_frequency = val;
-
-/*  The following code will proivde the security capability to network manager. */
-/*  If the driver doesn't provide this capability to network manager, */
-/*  the WPA/WPA2 routers can't be chosen in the network manager. */
-
-/*
-#define IW_SCAN_CAPA_NONE              0x00
-#define IW_SCAN_CAPA_ESSID             0x01
-#define IW_SCAN_CAPA_BSSID             0x02
-#define IW_SCAN_CAPA_CHANNEL           0x04
-#define IW_SCAN_CAPA_MODE              0x08
-#define IW_SCAN_CAPA_RATE              0x10
-#define IW_SCAN_CAPA_TYPE              0x20
-#define IW_SCAN_CAPA_TIME              0x40
-*/
-
-       range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
-                         IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
-
-       range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE |
-                          IW_SCAN_CAPA_BSSID | IW_SCAN_CAPA_CHANNEL |
-                          IW_SCAN_CAPA_MODE | IW_SCAN_CAPA_RATE;
-
-
-       return 0;
-}
-
-/* set bssid flow */
-/* s1. rtw_set_802_11_infrastructure_mode() */
-/* s2. rtw_set_802_11_authentication_mode() */
-/* s3. set_802_11_encryption_mode() */
-/* s4. rtw_set_802_11_bssid() */
-static int rtw_wx_set_wap(struct net_device *dev,
-                        struct iw_request_info *info,
-                        union iwreq_data *awrq,
-                        char *extra)
-{
-       uint ret = 0;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct sockaddr *temp = (struct sockaddr *)awrq;
-       struct  mlme_priv       *pmlmepriv = &padapter->mlmepriv;
-       struct list_head *phead;
-       u8 *dst_bssid, *src_bssid;
-       struct __queue *queue   = &pmlmepriv->scanned_queue;
-       struct  wlan_network    *pnetwork = NULL;
-       enum ndis_802_11_auth_mode      authmode;
-
-       ret = rtw_pwr_wakeup(padapter);
-       if (ret)
-               goto exit;
-
-       if (!padapter->bup) {
-               ret = -1;
-               goto exit;
-       }
-
-       if (temp->sa_family != ARPHRD_ETHER) {
-               ret = -EINVAL;
-               goto exit;
-       }
-
-       authmode = padapter->securitypriv.ndisauthtype;
-       spin_lock_bh(&queue->lock);
-       phead = get_list_head(queue);
-       pmlmepriv->pscanned = phead->next;
-
-       while (phead != pmlmepriv->pscanned) {
-
-               pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
-
-               pmlmepriv->pscanned = pmlmepriv->pscanned->next;
-
-               dst_bssid = pnetwork->network.MacAddress;
-
-               src_bssid = temp->sa_data;
-
-               if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN))) {
-                       if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) {
-                               ret = -1;
-                               spin_unlock_bh(&queue->lock);
-                               goto exit;
-                       }
-
-                       break;
-               }
-       }
-       spin_unlock_bh(&queue->lock);
-
-       rtw_set_802_11_authentication_mode(padapter, authmode);
-       /* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
-       if (!rtw_set_802_11_bssid(padapter, temp->sa_data)) {
-               ret = -1;
-               goto exit;
-       }
-
-exit:
-
-
-
-       return ret;
-}
-
-static int rtw_wx_get_wap(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct  mlme_priv       *pmlmepriv = &padapter->mlmepriv;
-       struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
-
-       wrqu->ap_addr.sa_family = ARPHRD_ETHER;
-
-       memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
-
-       if (check_fwstate(pmlmepriv, _FW_LINKED) ||
-           check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
-           check_fwstate(pmlmepriv, WIFI_AP_STATE))
-               memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
-       else
-               memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
-
-
-
-       return 0;
-}
-
-static int rtw_wx_set_mlme(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct iw_mlme *mlme = (struct iw_mlme *)extra;
-
-       if (!mlme)
-               return -1;
-
-       switch (mlme->cmd) {
-       case IW_MLME_DEAUTH:
-               rtw_set_802_11_disassociate(padapter);
-               break;
-       case IW_MLME_DISASSOC:
-               rtw_set_802_11_disassociate(padapter);
-               break;
-       default:
-               return -EOPNOTSUPP;
-       }
-       return 0;
-}
-
-static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *extra)
-{
-       u8 _status = false;
-       int ret = 0;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT];
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       ret = rtw_pwr_wakeup(padapter);
-       if (ret)
-               goto exit;
-
-       if (padapter->bDriverStopped) {
-               ret = -1;
-               goto exit;
-       }
-
-       if (!padapter->bup) {
-               ret = -1;
-               goto exit;
-       }
-
-       if (!padapter->hw_init_completed) {
-               ret = -1;
-               goto exit;
-       }
-
-       /*  When Busy Traffic, driver do not site survey. So driver return success. */
-       /*  wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */
-       /*  modify by thomas 2011-02-22. */
-       if (pmlmepriv->LinkDetectInfo.bBusyTraffic) {
-               indicate_wx_scan_complete_event(padapter);
-               goto exit;
-       }
-
-       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) {
-               indicate_wx_scan_complete_event(padapter);
-               goto exit;
-       }
-
-/*     For the DMP WiFi Display project, the driver won't to scan because */
-/*     the pmlmepriv->scan_interval is always equal to 3. */
-/*     So, the wpa_supplicant won't find out the WPS SoftAP. */
-
-       if (pwdinfo->p2p_state != P2P_STATE_NONE) {
-               rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
-               rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
-               rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL);
-               rtw_free_network_queue(padapter, true);
-       }
-
-       memset(ssid, 0, sizeof(struct ndis_802_11_ssid) * RTW_SSID_SCAN_AMOUNT);
-
-       if (wrqu->data.length == sizeof(struct iw_scan_req)) {
-               struct iw_scan_req *req = (struct iw_scan_req *)extra;
-
-               if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
-                       int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE);
-
-                       memcpy(ssid[0].Ssid, req->essid, len);
-                       ssid[0].SsidLength = len;
-
-                       spin_lock_bh(&pmlmepriv->lock);
-
-                       _status = rtw_sitesurvey_cmd(padapter, ssid, 1);
-
-                       spin_unlock_bh(&pmlmepriv->lock);
-               }
-       } else {
-               if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE &&
-                   !memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
-                       int len = wrqu->data.length - WEXT_CSCAN_HEADER_SIZE;
-                       char *pos = extra + WEXT_CSCAN_HEADER_SIZE;
-                       char section;
-                       char sec_len;
-                       int ssid_index = 0;
-
-                       while (len >= 1) {
-                               section = *(pos++);
-                               len -= 1;
-
-                               switch (section) {
-                               case WEXT_CSCAN_SSID_SECTION:
-                                       if (len < 1) {
-                                               len = 0;
-                                               break;
-                                       }
-                                       sec_len = *(pos++); len -= 1;
-                                       if (sec_len > 0 &&
-                                           sec_len <= len &&
-                                           sec_len <= 32) {
-                                               ssid[ssid_index].SsidLength = sec_len;
-                                               memcpy(ssid[ssid_index].Ssid, pos, sec_len);
-                                               ssid_index++;
-                                       }
-                                       pos += sec_len;
-                                       len -= sec_len;
-                                       break;
-                               case WEXT_CSCAN_TYPE_SECTION:
-                               case WEXT_CSCAN_CHANNEL_SECTION:
-                                       pos += 1;
-                                       len -= 1;
-                                       break;
-                               case WEXT_CSCAN_PASV_DWELL_SECTION:
-                               case WEXT_CSCAN_HOME_DWELL_SECTION:
-                               case WEXT_CSCAN_ACTV_DWELL_SECTION:
-                                       pos += 2;
-                                       len -= 2;
-                                       break;
-                               default:
-                                       len = 0; /*  stop parsing */
-                               }
-                       }
-
-                       /* it has still some scan parameter to parse, we only do this now... */
-                       _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT);
-               } else {
-                       _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
-               }
-       }
-
-       if (!_status)
-               ret = -1;
-
-exit:
-
-       return ret;
-}
-
-static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *extra)
-{
-       struct list_head *plist, *phead;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct  mlme_priv       *pmlmepriv = &padapter->mlmepriv;
-       struct __queue *queue   = &pmlmepriv->scanned_queue;
-       struct  wlan_network    *pnetwork = NULL;
-       char *ev = extra;
-       char *stop = ev + wrqu->data.length;
-       u32 ret = 0;
-       u32 cnt = 0;
-       u32 wait_for_surveydone;
-       int wait_status;
-       struct  wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
-               /*      P2P is enabled */
-               wait_for_surveydone = 200;
-       } else {
-               /*      P2P is disabled */
-               wait_for_surveydone = 100;
-       }
-
-       wait_status = _FW_UNDER_SURVEY | _FW_UNDER_LINKING;
-
-       while (check_fwstate(pmlmepriv, wait_status)) {
-               msleep(30);
-               cnt++;
-               if (cnt > wait_for_surveydone)
-                       break;
-       }
-
-       spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-
-       phead = get_list_head(queue);
-       plist = phead->next;
-
-       while (phead != plist) {
-               if ((stop - ev) < SCAN_ITEM_SIZE) {
-                       ret = -E2BIG;
-                       break;
-               }
-
-               pnetwork = container_of(plist, struct wlan_network, list);
-
-               /* report network only if the current channel set contains the channel to which this network belongs */
-               if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0)
-                       ev = translate_scan(padapter, a, pnetwork, ev, stop);
-
-               plist = plist->next;
-       }
-
-       spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
-       wrqu->data.length = ev - extra;
-       wrqu->data.flags = 0;
-
-       return ret;
-}
-
-/* set ssid flow */
-/* s1. rtw_set_802_11_infrastructure_mode() */
-/* s2. set_802_11_authenticaion_mode() */
-/* s3. set_802_11_encryption_mode() */
-/* s4. rtw_set_802_11_ssid() */
-static int rtw_wx_set_essid(struct net_device *dev,
-                             struct iw_request_info *a,
-                             union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct __queue *queue = &pmlmepriv->scanned_queue;
-       struct list_head *phead;
-       struct wlan_network *pnetwork = NULL;
-       enum ndis_802_11_auth_mode authmode;
-       struct ndis_802_11_ssid ndis_ssid;
-       u8 *dst_ssid, *src_ssid;
-
-       uint ret = 0, len;
-
-       ret = rtw_pwr_wakeup(padapter);
-       if (ret)
-               goto exit;
-
-       if (!padapter->bup) {
-               ret = -1;
-               goto exit;
-       }
-
-       if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {
-               ret = -E2BIG;
-               goto exit;
-       }
-
-       if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
-               ret = -1;
-               goto exit;
-       }
-
-       authmode = padapter->securitypriv.ndisauthtype;
-       if (wrqu->essid.flags && wrqu->essid.length) {
-               len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
-
-               memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
-               ndis_ssid.SsidLength = len;
-               memcpy(ndis_ssid.Ssid, extra, len);
-               src_ssid = ndis_ssid.Ssid;
-
-               spin_lock_bh(&queue->lock);
-               phead = get_list_head(queue);
-               pmlmepriv->pscanned = phead->next;
-
-               while (phead != pmlmepriv->pscanned) {
-                       pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
-
-                       pmlmepriv->pscanned = pmlmepriv->pscanned->next;
-
-                       dst_ssid = pnetwork->network.Ssid.Ssid;
-
-                       if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) &&
-                           (pnetwork->network.Ssid.SsidLength == ndis_ssid.SsidLength)) {
-
-                               if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
-                                       if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
-                                               continue;
-                               }
-
-                               if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) {
-                                       ret = -1;
-                                       spin_unlock_bh(&queue->lock);
-                                       goto exit;
-                               }
-
-                               break;
-                       }
-               }
-               spin_unlock_bh(&queue->lock);
-               rtw_set_802_11_authentication_mode(padapter, authmode);
-               if (!rtw_set_802_11_ssid(padapter, &ndis_ssid)) {
-                       ret = -1;
-                       goto exit;
-               }
-       }
-
-exit:
-       return ret;
-}
-
-static int rtw_wx_get_essid(struct net_device *dev,
-                             struct iw_request_info *a,
-                             union iwreq_data *wrqu, char *extra)
-{
-       u32 len;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct  mlme_priv       *pmlmepriv = &padapter->mlmepriv;
-       struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
-
-       if ((check_fwstate(pmlmepriv, _FW_LINKED)) ||
-           (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) {
-               len = pcur_bss->Ssid.SsidLength;
-               memcpy(extra, pcur_bss->Ssid.Ssid, len);
-       } else {
-               len = 0;
-               *extra = 0;
-       }
-       wrqu->essid.length = len;
-       wrqu->essid.flags = 1;
-
-       return 0;
-}
-
-static int rtw_wx_set_rate(struct net_device *dev,
-                             struct iw_request_info *a,
-                             union iwreq_data *wrqu, char *extra)
-{
-       int i;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       u8 datarates[NumRates];
-       u32     target_rate = wrqu->bitrate.value;
-       u32     fixed = wrqu->bitrate.fixed;
-       u32     ratevalue = 0;
-       u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
-
-       if (target_rate == -1) {
-               ratevalue = 11;
-               goto set_rate;
-       }
-       target_rate = target_rate / 100000;
-
-       switch (target_rate) {
-       case 10:
-               ratevalue = 0;
-               break;
-       case 20:
-               ratevalue = 1;
-               break;
-       case 55:
-               ratevalue = 2;
-               break;
-       case 60:
-               ratevalue = 3;
-               break;
-       case 90:
-               ratevalue = 4;
-               break;
-       case 110:
-               ratevalue = 5;
-               break;
-       case 120:
-               ratevalue = 6;
-               break;
-       case 180:
-               ratevalue = 7;
-               break;
-       case 240:
-               ratevalue = 8;
-               break;
-       case 360:
-               ratevalue = 9;
-               break;
-       case 480:
-               ratevalue = 10;
-               break;
-       case 540:
-               ratevalue = 11;
-               break;
-       default:
-               ratevalue = 11;
-               break;
-       }
-
-set_rate:
-
-       for (i = 0; i < NumRates; i++) {
-               if (ratevalue == mpdatarate[i]) {
-                       datarates[i] = mpdatarate[i];
-                       if (fixed == 0)
-                               break;
-               } else {
-                       datarates[i] = 0xff;
-               }
-       }
-
-       return rtw_setdatarate_cmd(padapter, datarates);
-}
-
-static int rtw_wx_get_rate(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
-{
-       u16 max_rate = 0;
-
-       max_rate = rtw_get_cur_max_rate((struct adapter *)rtw_netdev_priv(dev));
-
-       if (max_rate == 0)
-               return -EPERM;
-
-       wrqu->bitrate.fixed = 0;        /* no auto select */
-       wrqu->bitrate.value = max_rate * 100000;
-
-       return 0;
-}
-
-static int rtw_wx_set_rts(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-
-
-
-       if (wrqu->rts.disabled) {
-               padapter->registrypriv.rts_thresh = 2347;
-       } else {
-               if (wrqu->rts.value < 0 ||
-                   wrqu->rts.value > 2347)
-                       return -EINVAL;
-
-               padapter->registrypriv.rts_thresh = wrqu->rts.value;
-       }
-
-       return 0;
-}
-
-static int rtw_wx_get_rts(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-
-
-
-       wrqu->rts.value = padapter->registrypriv.rts_thresh;
-       wrqu->rts.fixed = 0;    /* no auto select */
-       /* wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); */
-
-
-
-       return 0;
-}
-
-static int rtw_wx_set_frag(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-
-
-
-       if (wrqu->frag.disabled) {
-               padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
-       } else {
-               if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
-                   wrqu->frag.value > MAX_FRAG_THRESHOLD)
-                       return -EINVAL;
-
-               padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
-       }
-
-       return 0;
-}
-
-static int rtw_wx_get_frag(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-
-
-
-       wrqu->frag.value = padapter->xmitpriv.frag_len;
-       wrqu->frag.fixed = 0;   /* no auto select */
-
-
-
-       return 0;
-}
-
-static int rtw_wx_get_retry(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
-{
-       wrqu->retry.value = 7;
-       wrqu->retry.fixed = 0;  /* no auto select */
-       wrqu->retry.disabled = 1;
-
-       return 0;
-}
-
-static int rtw_wx_set_enc(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu, char *keybuf)
-{
-       u32 key, ret = 0;
-       u32 keyindex_provided;
-       struct ndis_802_11_wep   wep;
-       enum ndis_802_11_auth_mode authmode;
-
-       struct iw_point *erq = &wrqu->encoding;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
-
-       memset(&wep, 0, sizeof(struct ndis_802_11_wep));
-
-       key = erq->flags & IW_ENCODE_INDEX;
-
-
-
-       if (erq->flags & IW_ENCODE_DISABLED) {
-               padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
-               padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
-               padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
-               padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
-               authmode = Ndis802_11AuthModeOpen;
-               padapter->securitypriv.ndisauthtype = authmode;
-
-               goto exit;
-       }
-
-       if (key) {
-               if (key > WEP_KEYS)
-                       return -EINVAL;
-               key--;
-               keyindex_provided = 1;
-       } else {
-               keyindex_provided = 0;
-               key = padapter->securitypriv.dot11PrivacyKeyIndex;
-       }
-
-       /* set authentication mode */
-       if (erq->flags & IW_ENCODE_OPEN) {
-               padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
-               padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
-               padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
-               padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
-               authmode = Ndis802_11AuthModeOpen;
-               padapter->securitypriv.ndisauthtype = authmode;
-       } else if (erq->flags & IW_ENCODE_RESTRICTED) {
-               padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
-               padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
-               padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
-               padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
-               authmode = Ndis802_11AuthModeShared;
-               padapter->securitypriv.ndisauthtype = authmode;
-       } else {
-               padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
-               padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
-               padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
-               padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
-               authmode = Ndis802_11AuthModeOpen;
-               padapter->securitypriv.ndisauthtype = authmode;
-       }
-
-       wep.KeyIndex = key;
-       if (erq->length > 0) {
-               wep.KeyLength = erq->length <= 5 ? 5 : 13;
-
-               wep.Length = wep.KeyLength + offsetof(struct ndis_802_11_wep, KeyMaterial);
-       } else {
-               wep.KeyLength = 0;
-
-               if (keyindex_provided == 1) {
-                       /*  set key_id only, no given KeyMaterial(erq->length == 0). */
-                       padapter->securitypriv.dot11PrivacyKeyIndex = key;
-
-                       switch (padapter->securitypriv.dot11DefKeylen[key]) {
-                       case 5:
-                               padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
-                               break;
-                       case 13:
-                               padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
-                               break;
-                       default:
-                               padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
-                               break;
-                       }
-
-                       goto exit;
-               }
-       }
-
-       wep.KeyIndex |= 0x80000000;
-
-       memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
-
-       if (!rtw_set_802_11_add_wep(padapter, &wep)) {
-               if (rf_on == pwrpriv->rf_pwrstate)
-                       ret = -EOPNOTSUPP;
-               goto exit;
-       }
-
-exit:
-
-
-
-       return ret;
-}
-
-static int rtw_wx_get_enc(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu, char *keybuf)
-{
-       uint key;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct iw_point *erq = &wrqu->encoding;
-       struct  mlme_priv       *pmlmepriv = &padapter->mlmepriv;
-
-
-
-       if (check_fwstate(pmlmepriv, _FW_LINKED) != true) {
-               if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
-                       erq->length = 0;
-                       erq->flags |= IW_ENCODE_DISABLED;
-                       return 0;
-               }
-       }
-
-       key = erq->flags & IW_ENCODE_INDEX;
-
-       if (key) {
-               if (key > WEP_KEYS)
-                       return -EINVAL;
-               key--;
-       } else {
-               key = padapter->securitypriv.dot11PrivacyKeyIndex;
-       }
-
-       erq->flags = key + 1;
-
-       switch (padapter->securitypriv.ndisencryptstatus) {
-       case Ndis802_11EncryptionNotSupported:
-       case Ndis802_11EncryptionDisabled:
-               erq->length = 0;
-               erq->flags |= IW_ENCODE_DISABLED;
-               break;
-       case Ndis802_11Encryption1Enabled:
-               erq->length = padapter->securitypriv.dot11DefKeylen[key];
-               if (erq->length) {
-                       memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
-
-                       erq->flags |= IW_ENCODE_ENABLED;
-
-                       if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
-                               erq->flags |= IW_ENCODE_OPEN;
-                       else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
-                               erq->flags |= IW_ENCODE_RESTRICTED;
-               } else {
-                       erq->length = 0;
-                       erq->flags |= IW_ENCODE_DISABLED;
-               }
-               break;
-       case Ndis802_11Encryption2Enabled:
-       case Ndis802_11Encryption3Enabled:
-               erq->length = 16;
-               erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);
-               break;
-       default:
-               erq->length = 0;
-               erq->flags |= IW_ENCODE_DISABLED;
-               break;
-       }
-
-
-       return 0;
-}
-
-static int rtw_wx_get_power(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
-{
-       wrqu->power.value = 0;
-       wrqu->power.fixed = 0;  /* no auto select */
-       wrqu->power.disabled = 1;
-
-       return 0;
-}
-
-static int rtw_wx_set_gen_ie(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
-{
-       int ret;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-
-       ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length);
-       return ret;
-}
-
-static int rtw_wx_set_auth(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct iw_param *param = (struct iw_param *)&wrqu->param;
-       int ret = 0;
-
-       switch (param->flags & IW_AUTH_INDEX) {
-       case IW_AUTH_WPA_VERSION:
-               break;
-       case IW_AUTH_CIPHER_PAIRWISE:
-
-               break;
-       case IW_AUTH_CIPHER_GROUP:
-
-               break;
-       case IW_AUTH_KEY_MGMT:
-               /*
-                *  ??? does not use these parameters
-                */
-               break;
-       case IW_AUTH_TKIP_COUNTERMEASURES:
-               if (param->value) {
-                       /*  wpa_supplicant is enabling the tkip countermeasure. */
-                       padapter->securitypriv.btkip_countermeasure = true;
-               } else {
-                       /*  wpa_supplicant is disabling the tkip countermeasure. */
-                       padapter->securitypriv.btkip_countermeasure = false;
-               }
-               break;
-       case IW_AUTH_DROP_UNENCRYPTED:
-               /* HACK:
-                *
-                * wpa_supplicant calls set_wpa_enabled when the driver
-                * is loaded and unloaded, regardless of if WPA is being
-                * used.  No other calls are made which can be used to
-                * determine if encryption will be used or not prior to
-                * association being expected.  If encryption is not being
-                * used, drop_unencrypted is set to false, else true -- we
-                * can use this to determine if the CAP_PRIVACY_ON bit should
-                * be set.
-                */
-
-               if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled)
-                       break;/* it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, */
-                                       /*  then it needn't reset it; */
-
-               if (param->value) {
-                       padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
-                       padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
-                       padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
-                       padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
-                       padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
-               }
-
-               break;
-       case IW_AUTH_80211_AUTH_ALG:
-               /*
-                *  It's the starting point of a link layer connection using wpa_supplicant
-               */
-               if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
-                       LeaveAllPowerSaveMode(padapter);
-                       rtw_disassoc_cmd(padapter, 500, false);
-                       rtw_indicate_disconnect(padapter);
-                       rtw_free_assoc_resources(padapter, 1);
-               }
-               ret = wpa_set_auth_algs(dev, (u32)param->value);
-               break;
-       case IW_AUTH_WPA_ENABLED:
-               break;
-       case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-               break;
-       case IW_AUTH_PRIVACY_INVOKED:
-               break;
-       default:
-               return -EOPNOTSUPP;
-       }
-
-       return ret;
-}
-
-static int rtw_wx_set_enc_ext(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
-{
-       char *alg_name;
-       u32 param_len;
-       struct ieee_param *param = NULL;
-       struct iw_point *pencoding = &wrqu->encoding;
-       struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
-       int ret = -1;
-
-       param_len = sizeof(struct ieee_param) + pext->key_len;
-       param = kzalloc(param_len, GFP_KERNEL);
-       if (!param)
-               return -ENOMEM;
-
-       param->cmd = IEEE_CMD_SET_ENCRYPTION;
-       memset(param->sta_addr, 0xff, ETH_ALEN);
-
-       switch (pext->alg) {
-       case IW_ENCODE_ALG_NONE:
-               /* todo: remove key */
-               /* remove = 1; */
-               alg_name = "none";
-               break;
-       case IW_ENCODE_ALG_WEP:
-               alg_name = "WEP";
-               break;
-       case IW_ENCODE_ALG_TKIP:
-               alg_name = "TKIP";
-               break;
-       case IW_ENCODE_ALG_CCMP:
-               alg_name = "CCMP";
-               break;
-       default:
-               goto out;
-       }
-
-       strscpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
-
-       if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
-               param->u.crypt.set_tx = 1;
-
-       /* cliW: WEP does not have group key
-        * just not checking GROUP key setting
-        */
-       if ((pext->alg != IW_ENCODE_ALG_WEP) &&
-           (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY))
-               param->u.crypt.set_tx = 0;
-
-       param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
-
-       if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
-               memcpy(param->u.crypt.seq, pext->rx_seq, 8);
-
-       if (pext->key_len) {
-               param->u.crypt.key_len = pext->key_len;
-               memcpy(param->u.crypt.key, pext + 1, pext->key_len);
-       }
-
-       ret =  wpa_set_encryption(dev, param, param_len);
-
-out:
-       kfree(param);
-       return ret;
-}
-
-static int rtw_wx_get_nick(struct net_device *dev,
-                          struct iw_request_info *info,
-                          union iwreq_data *wrqu, char *extra)
-{
-       if (extra) {
-               wrqu->data.length = 14;
-               wrqu->data.flags = 1;
-               memcpy(extra, "<WIFI@REALTEK>", 14);
-       }
-
-       /* dump debug info here */
-       return 0;
-}
-
-static int rtw_wx_read_rf(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       u32 path, addr, data32;
-
-       path = *(u32 *)extra;
-       if (path != RF_PATH_A)
-               return -EINVAL;
-
-       addr = *((u32 *)extra + 1);
-       data32 = rtl8188e_PHY_QueryRFReg(padapter, addr, 0xFFFFF);
-       /*
-        * IMPORTANT!!
-        * Only when wireless private ioctl is at odd order,
-        * "extra" would be copied to user space.
-        */
-       sprintf(extra, "0x%05x", data32);
-
-       return 0;
-}
-
-static int rtw_wx_write_rf(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       u32 path, addr, data32;
-
-       path = *(u32 *)extra;
-       if (path != RF_PATH_A)
-               return -EINVAL;
-
-       addr = *((u32 *)extra + 1);
-       data32 = *((u32 *)extra + 2);
-       rtl8188e_PHY_SetRFReg(padapter, addr, 0xFFFFF, data32);
-
-       return 0;
-}
-
-static int rtw_wx_set_channel_plan(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       u8 channel_plan_req = (u8)(*((int *)wrqu));
-
-       if (rtw_set_chplan_cmd(padapter, channel_plan_req) != _SUCCESS)
-               return -EPERM;
-
-       return 0;
-}
-
-static int rtw_get_ap_info(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       int ret = 0;
-       u32 cnt = 0, wpa_ielen;
-       struct list_head *plist, *phead;
-       unsigned char *pbuf;
-       u8 bssid[ETH_ALEN];
-       char data[32];
-       struct wlan_network *pnetwork = NULL;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct __queue *queue = &pmlmepriv->scanned_queue;
-       struct iw_point *pdata = &wrqu->data;
-
-       if (padapter->bDriverStopped || !pdata) {
-               ret = -EINVAL;
-               goto exit;
-       }
-
-       while ((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY | _FW_UNDER_LINKING)))) {
-               msleep(30);
-               cnt++;
-               if (cnt > 100)
-                       break;
-       }
-       pdata->flags = 0;
-       if (pdata->length >= 32) {
-               if (copy_from_user(data, pdata->pointer, 32)) {
-                       ret = -EINVAL;
-                       goto exit;
-               }
-       } else {
-               ret = -EINVAL;
-               goto exit;
-       }
-
-       spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-
-       phead = get_list_head(queue);
-       plist = phead->next;
-
-       while (phead != plist) {
-               pnetwork = container_of(plist, struct wlan_network, list);
-
-               if (!mac_pton(data, bssid)) {
-                       spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-                       return -EINVAL;
-               }
-
-               if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) {
-                       /* BSSID match, then check if supporting wpa/wpa2 */
-                       pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
-                       if (pbuf && (wpa_ielen > 0)) {
-                               pdata->flags = 1;
-                               break;
-                       }
-
-                       pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
-                       if (pbuf && (wpa_ielen > 0)) {
-                               pdata->flags = 2;
-                               break;
-                       }
-               }
-
-               plist = plist->next;
-       }
-
-       spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
-       if (pdata->length >= 34) {
-               if (copy_to_user(pdata->pointer + 32, (u8 *)&pdata->flags, 1)) {
-                       ret = -EINVAL;
-                       goto exit;
-               }
-       }
-
-exit:
-
-       return ret;
-}
-
-static int rtw_set_pid(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       int ret = 0;
-       struct adapter *padapter = rtw_netdev_priv(dev);
-       int *pdata = (int *)wrqu;
-       int selector;
-
-       if (padapter->bDriverStopped || !pdata) {
-               ret = -EINVAL;
-               goto exit;
-       }
-
-       selector = *pdata;
-       if (selector < 3 && selector >= 0) {
-               padapter->pid[selector] = *(pdata + 1);
-               ui_pid[selector] = *(pdata + 1);
-       }
-exit:
-       return ret;
-}
-
-static int rtw_wps_start(struct net_device *dev,
-                        struct iw_request_info *info,
-                        union iwreq_data *wrqu, char *extra)
-{
-       int ret = 0;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct iw_point *pdata = &wrqu->data;
-       u32   u32wps_start = 0;
-
-       if (!pdata)
-               return -EINVAL;
-       ret = copy_from_user((void *)&u32wps_start, pdata->pointer, 4);
-       if (ret) {
-               ret = -EINVAL;
-               goto exit;
-       }
-
-       if (padapter->bDriverStopped) {
-               ret = -EINVAL;
-               goto exit;
-       }
-
-       if (u32wps_start == 0)
-               u32wps_start = *extra;
-
-       if (u32wps_start == 1) /*  WPS Start */
-               rtw_led_control(padapter, LED_CTL_START_WPS);
-       else if (u32wps_start == 2) /*  WPS Stop because of wps success */
-               rtw_led_control(padapter, LED_CTL_STOP_WPS);
-       else if (u32wps_start == 3) /*  WPS Stop because of wps fail */
-               rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL);
-
-exit:
-       return ret;
-}
-
-static int rtw_wext_p2p_enable(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       int ret;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       enum P2P_ROLE init_role = P2P_ROLE_DISABLE;
-
-       if (*extra == '0')
-               init_role = P2P_ROLE_DISABLE;
-       else if (*extra == '1')
-               init_role = P2P_ROLE_DEVICE;
-       else if (*extra == '2')
-               init_role = P2P_ROLE_CLIENT;
-       else if (*extra == '3')
-               init_role = P2P_ROLE_GO;
-
-       ret = rtw_p2p_enable(padapter, init_role);
-       if (ret)
-               return ret;
-
-       /* set channel/bandwidth */
-       if (init_role != P2P_ROLE_DISABLE) {
-               u8 channel, ch_offset;
-               u16 bwmode;
-
-               if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN)) {
-                       /*      Stay at the listen state and wait for discovery. */
-                       channel = pwdinfo->listen_channel;
-                       pwdinfo->operating_channel = pwdinfo->listen_channel;
-                       ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-                       bwmode = HT_CHANNEL_WIDTH_20;
-               } else {
-                       pwdinfo->operating_channel = pmlmeext->cur_channel;
-
-                       channel = pwdinfo->operating_channel;
-                       ch_offset = pmlmeext->cur_ch_offset;
-                       bwmode = pmlmeext->cur_bwmode;
-               }
-
-               set_channel_bwmode(padapter, channel, ch_offset, bwmode);
-       }
-
-       return 0;
-}
-
-static void rtw_p2p_set_go_nego_ssid(struct net_device *dev,
-                                    struct iw_request_info *info,
-                                    union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       memcpy(pwdinfo->nego_ssid, extra, strlen(extra));
-       pwdinfo->nego_ssidlen = strlen(extra);
-}
-
-static int rtw_p2p_set_intent(struct net_device *dev,
-                             struct iw_request_info *info,
-                             union iwreq_data *wrqu, char *extra)
-{
-       int ret = 0;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-       u8 intent = pwdinfo->intent;
-
-       switch (wrqu->data.length) {
-       case 1:
-               intent = extra[0] - '0';
-               break;
-       case 2:
-               intent = str_2char2num(extra[0], extra[1]);
-               break;
-       }
-       if (intent <= 15)
-               pwdinfo->intent = intent;
-       else
-               ret = -1;
-       return ret;
-}
-
-static int rtw_p2p_set_listen_ch(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       int ret = 0;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-       u8 listen_ch = pwdinfo->listen_channel; /*      Listen channel number */
-
-       switch (wrqu->data.length) {
-       case 1:
-               listen_ch = extra[0] - '0';
-               break;
-       case 2:
-               listen_ch = str_2char2num(extra[0], extra[1]);
-               break;
-       }
-
-       if ((listen_ch == 1) || (listen_ch == 6) || (listen_ch == 11)) {
-               pwdinfo->listen_channel = listen_ch;
-               set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
-       } else {
-               ret = -1;
-       }
-
-       return ret;
-}
-
-static int rtw_p2p_set_op_ch(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-/*     Commented by Albert 20110524 */
-/*     This function is used to set the operating channel if the driver will become the group owner */
-
-       int ret = 0;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-       u8 op_ch = pwdinfo->operating_channel;  /*      Operating channel number */
-
-       switch (wrqu->data.length) {
-       case 1:
-               op_ch = extra[0] - '0';
-               break;
-       case 2:
-               op_ch = str_2char2num(extra[0], extra[1]);
-               break;
-       }
-
-       if (op_ch > 0)
-               pwdinfo->operating_channel = op_ch;
-       else
-               ret = -1;
-
-       return ret;
-}
-
-static int rtw_p2p_profilefound(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       int ret = 0;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       /*      Comment by Albert 2010/10/13 */
-       /*      Input data format: */
-       /*      Ex:  0 */
-       /*      Ex:  1XX:XX:XX:XX:XX:XXYYSSID */
-       /*      0 => Reflush the profile record list. */
-       /*      1 => Add the profile list */
-       /*      XX:XX:XX:XX:XX:XX => peer's MAC Address (ex: 00:E0:4C:00:00:01) */
-       /*      YY => SSID Length */
-       /*      SSID => SSID for persistence group */
-
-       /*      The upper application should pass the SSID to driver by using this rtw_p2p_profilefound function. */
-       if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
-               if (extra[0] == '0') {
-                       /*      Remove all the profile information of wifidirect_info structure. */
-                       memset(&pwdinfo->profileinfo[0], 0x00, sizeof(struct profile_info) * P2P_MAX_PERSISTENT_GROUP_NUM);
-                       pwdinfo->profileindex = 0;
-               } else {
-                       if (pwdinfo->profileindex >= P2P_MAX_PERSISTENT_GROUP_NUM) {
-                               ret = -1;
-                       } else {
-                               int jj, kk;
-
-                               /*      Add this profile information into pwdinfo->profileinfo */
-                               /*      Ex:  1XX:XX:XX:XX:XX:XXYYSSID */
-                               for (jj = 0, kk = 1; jj < ETH_ALEN; jj++, kk += 3)
-                                       pwdinfo->profileinfo[pwdinfo->profileindex].peermac[jj] = key_2char2num(extra[kk], extra[kk + 1]);
-
-                               pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen = (extra[18] - '0') * 10 + (extra[19] - '0');
-                               memcpy(pwdinfo->profileinfo[pwdinfo->profileindex].ssid, &extra[20], pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen);
-                               pwdinfo->profileindex++;
-                       }
-               }
-       }
-
-       return ret;
-}
-
-static void rtw_p2p_setDN(struct net_device *dev,
-                         struct iw_request_info *info,
-                         union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       memset(pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN);
-       memcpy(pwdinfo->device_name, extra, wrqu->data.length - 1);
-       pwdinfo->device_name_len = wrqu->data.length - 1;
-}
-
-static int rtw_p2p_get_wps_configmethod(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       u8 peerMAC[ETH_ALEN] = {0x00};
-       int jj, kk;
-       u8 peerMACStr[17] = {0x00};
-       struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
-       struct list_head *plist, *phead;
-       struct __queue *queue   = &pmlmepriv->scanned_queue;
-       struct  wlan_network    *pnetwork = NULL;
-       u8 blnMatch = 0;
-       u16     attr_content = 0;
-       uint attr_contentlen = 0;
-       /* 6 is the string "wpsCM =", 17 is the MAC addr, we have to clear it at wrqu->data.pointer */
-       u8 attr_content_str[6 + 17] = {0x00};
-
-       /*      Commented by Albert 20110727 */
-       /*      The input data is the MAC address which the application wants to know its WPS config method. */
-       /*      After knowing its WPS config method, the application can decide the config method for provisioning discovery. */
-       /*      Format: iwpriv wlanx p2p_get_wpsCM 00:E0:4C:00:00:05 */
-
-       if (copy_from_user(peerMACStr, wrqu->data.pointer + 6, 17))
-               return -EFAULT;
-
-       for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
-               peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
-
-       spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-
-       phead = get_list_head(queue);
-       plist = phead->next;
-
-       while (phead != plist) {
-               pnetwork = container_of(plist, struct wlan_network, list);
-               if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
-                       u8 *wpsie;
-                       uint wpsie_len = 0;
-                       __be16 be_tmp;
-
-                       /*  The mac address is matched. */
-                       wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len);
-                       if (wpsie) {
-                               rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *)&be_tmp, &attr_contentlen);
-                               if (attr_contentlen) {
-                                       attr_content = be16_to_cpu(be_tmp);
-                                       sprintf(attr_content_str, "\n\nM =%.4d", attr_content);
-                                       blnMatch = 1;
-                               }
-                       }
-                       break;
-               }
-               plist = plist->next;
-       }
-
-       spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
-       if (!blnMatch)
-               sprintf(attr_content_str, "\n\nM = 0000");
-
-       if (copy_to_user(wrqu->data.pointer, attr_content_str, 6 + 17))
-               return -EFAULT;
-       return 0;
-}
-
-static int rtw_p2p_get_go_device_address(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       u8 peerMAC[ETH_ALEN] = {0x00};
-       int jj, kk;
-       u8 peerMACStr[17] = {0x00};
-       struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
-       struct list_head *plist, *phead;
-       struct __queue *queue   = &pmlmepriv->scanned_queue;
-       struct  wlan_network    *pnetwork = NULL;
-       u8 blnMatch = 0;
-       u8 *p2pie;
-       uint p2pielen = 0, attr_contentlen = 0;
-       u8 attr_content[100] = {0x00};
-
-       u8 go_devadd_str[100 + 10] = {0x00};
-       /*  +10 is for the str "go_devadd =", we have to clear it at wrqu->data.pointer */
-
-       /*      Commented by Albert 20121209 */
-       /*      The input data is the GO's interface address which the application wants to know its device address. */
-       /*      Format: iwpriv wlanx p2p_get2 go_devadd = 00:E0:4C:00:00:05 */
-
-       if (copy_from_user(peerMACStr, wrqu->data.pointer + 10, 17))
-               return -EFAULT;
-
-       for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
-               peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
-
-       spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-
-       phead = get_list_head(queue);
-       plist = phead->next;
-
-       while (phead != plist) {
-               pnetwork = container_of(plist, struct wlan_network, list);
-               if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
-                       /*      Commented by Albert 2011/05/18 */
-                       /*      Match the device address located in the P2P IE */
-                       /*      This is for the case that the P2P device address is not the same as the P2P interface address. */
-
-                       p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
-                       if (p2pie) {
-                               while (p2pie) {
-                                       /*      The P2P Device ID attribute is included in the Beacon frame. */
-                                       /*      The P2P Device Info attribute is included in the probe response frame. */
-
-                                       memset(attr_content, 0x00, 100);
-                                       if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
-                                               /*      Handle the P2P Device ID attribute of Beacon first */
-                                               blnMatch = 1;
-                                               break;
-                                       } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
-                                               /*      Handle the P2P Device Info attribute of probe response */
-                                               blnMatch = 1;
-                                               break;
-                                       }
-
-                                       /* Get the next P2P IE */
-                                       p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
-                               }
-                       }
-            }
-
-               plist = plist->next;
-       }
-
-       spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
-       if (!blnMatch)
-               sprintf(go_devadd_str, "\n\ndev_add = NULL");
-       else
-               sprintf(go_devadd_str, "\ndev_add =%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
-                       attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]);
-
-       if (copy_to_user(wrqu->data.pointer, go_devadd_str, 10 + 17))
-               return -EFAULT;
-       return 0;
-}
-
-static int rtw_p2p_get_device_type(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       u8 peerMAC[ETH_ALEN] = {0x00};
-       int jj, kk;
-       u8 peerMACStr[17] = {0x00};
-       struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
-       struct list_head *plist, *phead;
-       struct __queue *queue   = &pmlmepriv->scanned_queue;
-       struct  wlan_network    *pnetwork = NULL;
-       u8 blnMatch = 0;
-       u8 dev_type[8] = {0x00};
-       uint dev_type_len = 0;
-       u8 dev_type_str[17 + 9] = {0x00};       /*  +9 is for the str "dev_type =", we have to clear it at wrqu->data.pointer */
-
-       /*      Commented by Albert 20121209 */
-       /*      The input data is the MAC address which the application wants to know its device type. */
-       /*      Such user interface could know the device type. */
-       /*      Format: iwpriv wlanx p2p_get2 dev_type = 00:E0:4C:00:00:05 */
-
-       if (copy_from_user(peerMACStr, wrqu->data.pointer + 9, 17))
-               return -EFAULT;
-
-       for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
-               peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
-
-       spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-
-       phead = get_list_head(queue);
-       plist = phead->next;
-
-       while (phead != plist) {
-               pnetwork = container_of(plist, struct wlan_network, list);
-               if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
-                       u8 *wpsie;
-                       uint wpsie_len = 0;
-
-               /*      The mac address is matched. */
-
-                       wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12],
-                                              pnetwork->network.IELength - 12,
-                                              NULL, &wpsie_len);
-                       if (wpsie) {
-                               rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len);
-                               if (dev_type_len) {
-                                       u16     type = 0;
-                                       __be16 be_tmp;
-
-                                       memcpy(&be_tmp, dev_type, 2);
-                                       type = be16_to_cpu(be_tmp);
-                                       sprintf(dev_type_str, "\n\nN =%.2d", type);
-                                       blnMatch = 1;
-                               }
-                       }
-                       break;
-            }
-
-               plist = plist->next;
-       }
-
-       spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
-       if (!blnMatch)
-               sprintf(dev_type_str, "\n\nN = 00");
-
-       if (copy_to_user(wrqu->data.pointer, dev_type_str, 9 + 17)) {
-               return -EFAULT;
-       }
-
-       return 0;
-}
-
-static int rtw_p2p_get_device_name(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       u8 peerMAC[ETH_ALEN] = {0x00};
-       int jj, kk;
-       u8 peerMACStr[17] = {0x00};
-       struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
-       struct list_head *plist, *phead;
-       struct __queue *queue   = &pmlmepriv->scanned_queue;
-       struct  wlan_network    *pnetwork = NULL;
-       u8 blnMatch = 0;
-       u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = {0x00};
-       uint dev_len = 0;
-       u8 dev_name_str[WPS_MAX_DEVICE_NAME_LEN + 5] = {0x00};  /*  +5 is for the str "devN =", we have to clear it at wrqu->data.pointer */
-
-       /*      Commented by Albert 20121225 */
-       /*      The input data is the MAC address which the application wants to know its device name. */
-       /*      Such user interface could show peer device's device name instead of ssid. */
-       /*      Format: iwpriv wlanx p2p_get2 devN = 00:E0:4C:00:00:05 */
-
-       if (copy_from_user(peerMACStr, wrqu->data.pointer + 5, 17))
-               return -EFAULT;
-
-       for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
-               peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
-
-       spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-
-       phead = get_list_head(queue);
-       plist = phead->next;
-
-       while (phead != plist) {
-               pnetwork = container_of(plist, struct wlan_network, list);
-               if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
-                       u8 *wpsie;
-                       uint wpsie_len = 0;
-
-                       /*      The mac address is matched. */
-                       wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len);
-                       if (wpsie) {
-                               rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len);
-                               if (dev_len) {
-                                       sprintf(dev_name_str, "\n\nN =%s", dev_name);
-                                       blnMatch = 1;
-                               }
-                       }
-                       break;
-               }
-
-               plist = plist->next;
-       }
-
-       spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
-       if (!blnMatch)
-               sprintf(dev_name_str, "\n\nN = 0000");
-
-       if (copy_to_user(wrqu->data.pointer, dev_name_str, 5 + ((dev_len > 17) ? dev_len : 17)))
-               return -EFAULT;
-       return 0;
-}
-
-static int rtw_p2p_get_invitation_procedure(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       u8 peerMAC[ETH_ALEN] = {0x00};
-       int jj, kk;
-       u8 peerMACStr[17] = {0x00};
-       struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
-       struct list_head *plist, *phead;
-       struct __queue *queue   = &pmlmepriv->scanned_queue;
-       struct  wlan_network    *pnetwork = NULL;
-       u8 blnMatch = 0;
-       u8 *p2pie;
-       uint p2pielen = 0, attr_contentlen = 0;
-       u8 attr_content[2] = {0x00};
-
-       u8 inv_proc_str[17 + 8] = {0x00};
-       /*  +8 is for the str "InvProc =", we have to clear it at wrqu->data.pointer */
-
-       /*      Commented by Ouden 20121226 */
-       /*      The application wants to know P2P initiation procedure is supported or not. */
-       /*      Format: iwpriv wlanx p2p_get2 InvProc = 00:E0:4C:00:00:05 */
-
-       if (copy_from_user(peerMACStr, wrqu->data.pointer + 8, 17))
-               return -EFAULT;
-
-       for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
-               peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
-
-       spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-
-       phead = get_list_head(queue);
-       plist = phead->next;
-
-       while (phead != plist) {
-               pnetwork = container_of(plist, struct wlan_network, list);
-               if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
-                       /*      Commented by Albert 20121226 */
-                       /*      Match the device address located in the P2P IE */
-                       /*      This is for the case that the P2P device address is not the same as the P2P interface address. */
-
-                       p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
-                       if (p2pie) {
-                               while (p2pie) {
-                                       if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_CAPABILITY, attr_content, &attr_contentlen)) {
-                                               /*      Handle the P2P capability attribute */
-                                               blnMatch = 1;
-                                               break;
-                                       }
-
-                                       /* Get the next P2P IE */
-                                       p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
-                               }
-                       }
-               }
-               plist = plist->next;
-       }
-
-       spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
-       if (!blnMatch) {
-               sprintf(inv_proc_str, "\nIP =-1");
-       } else {
-               if (attr_content[0] & 0x20)
-                       sprintf(inv_proc_str, "\nIP = 1");
-               else
-                       sprintf(inv_proc_str, "\nIP = 0");
-       }
-       if (copy_to_user(wrqu->data.pointer, inv_proc_str, 8 + 17))
-               return -EFAULT;
-       return 0;
-}
-
-static int rtw_p2p_connect(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       int ret = 0;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-       u8 peerMAC[ETH_ALEN] = {0x00};
-       int jj, kk;
-       struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
-       struct list_head *plist, *phead;
-       struct __queue *queue   = &pmlmepriv->scanned_queue;
-       struct  wlan_network    *pnetwork = NULL;
-       u32 peer_channel = 0;
-
-       /*      Commented by Albert 20110304 */
-       /*      The input data contains two information. */
-       /*      1. First information is the MAC address which wants to formate with */
-       /*      2. Second information is the WPS PINCode or "pbc" string for push button method */
-       /*      Format: 00:E0:4C:00:00:05 */
-       /*      Format: 00:E0:4C:00:00:05 */
-
-       if (pwdinfo->p2p_state == P2P_STATE_NONE)
-               return ret;
-
-       if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO)
-               return -1;
-
-       for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
-               peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
-
-       spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-
-       phead = get_list_head(queue);
-       plist = phead->next;
-
-       while (phead != plist) {
-               pnetwork = container_of(plist, struct wlan_network, list);
-               if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
-                       peer_channel = pnetwork->network.Configuration.DSConfig;
-                       break;
-               }
-
-               plist = plist->next;
-       }
-
-       spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
-       if (peer_channel) {
-               memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info));
-               memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
-
-               pwdinfo->nego_req_info.peer_channel_num[0] = peer_channel;
-               memcpy(pwdinfo->nego_req_info.peerDevAddr, pnetwork->network.MacAddress, ETH_ALEN);
-               pwdinfo->nego_req_info.benable = true;
-
-               _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
-               if (rtw_p2p_state(pwdinfo) != P2P_STATE_GONEGO_OK) {
-                       /*      Restore to the listen state if the current p2p state is not nego OK */
-                       rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
-               }
-
-               rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
-               rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
-
-               _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
-               _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT);
-       } else {
-               ret = -1;
-       }
-       return ret;
-}
-
-static void rtw_p2p_invite_req(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-       int jj, kk;
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-       struct list_head *plist, *phead;
-       struct __queue *queue   = &pmlmepriv->scanned_queue;
-       struct  wlan_network    *pnetwork = NULL;
-       uint peer_channel = 0;
-       u8 attr_content[50] = {0x00};
-       u8 *p2pie;
-       uint p2pielen = 0, attr_contentlen = 0;
-       struct tx_invite_req_info *pinvite_req_info = &pwdinfo->invitereq_info;
-
-       /*      The input data contains two information items. */
-       /*      1. First information is the P2P device address which you want to send to. */
-       /*      2. Second information is the group id which combines with GO's mac address, space and GO's ssid. */
-       /*      Command line sample: iwpriv wlan0 p2p_set invite ="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" */
-       /*      Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy */
-
-       if (wrqu->data.length <=  37)
-               return;
-
-       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
-               return;
-       } else {
-               /*      Reset the content of struct tx_invite_req_info */
-               pinvite_req_info->benable = false;
-               memset(pinvite_req_info->go_bssid, 0x00, ETH_ALEN);
-               memset(pinvite_req_info->go_ssid, 0x00, WLAN_SSID_MAXLEN);
-               pinvite_req_info->ssidlen = 0x00;
-               pinvite_req_info->operating_ch = pwdinfo->operating_channel;
-               memset(pinvite_req_info->peer_macaddr, 0x00, ETH_ALEN);
-               pinvite_req_info->token = 3;
-       }
-
-       for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
-               pinvite_req_info->peer_macaddr[jj] = key_2char2num(extra[kk], extra[kk + 1]);
-
-       spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-
-       phead = get_list_head(queue);
-       plist = phead->next;
-
-       while (phead != plist) {
-               pnetwork = container_of(plist, struct wlan_network, list);
-
-               /*      Commented by Albert 2011/05/18 */
-               /*      Match the device address located in the P2P IE */
-               /*      This is for the case that the P2P device address is not the same as the P2P interface address. */
-
-               p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
-               if (p2pie) {
-                       /*      The P2P Device ID attribute is included in the Beacon frame. */
-                       /*      The P2P Device Info attribute is included in the probe response frame. */
-
-                       if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
-                               /*      Handle the P2P Device ID attribute of Beacon first */
-                               if (!memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) {
-                                       peer_channel = pnetwork->network.Configuration.DSConfig;
-                                       break;
-                               }
-                       } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
-                               /*      Handle the P2P Device Info attribute of probe response */
-                               if (!memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) {
-                                       peer_channel = pnetwork->network.Configuration.DSConfig;
-                                       break;
-                               }
-                       }
-               }
-               plist = plist->next;
-       }
-
-       spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
-       if (peer_channel) {
-               /*      Store the GO's bssid */
-               for (jj = 0, kk = 18; jj < ETH_ALEN; jj++, kk += 3)
-                       pinvite_req_info->go_bssid[jj] = key_2char2num(extra[kk], extra[kk + 1]);
-
-               /*      Store the GO's ssid */
-               pinvite_req_info->ssidlen = wrqu->data.length - 36;
-               memcpy(pinvite_req_info->go_ssid, &extra[36], (u32)pinvite_req_info->ssidlen);
-               pinvite_req_info->benable = true;
-               pinvite_req_info->peer_ch = peer_channel;
-
-               rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
-               rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INVITE_REQ);
-
-               set_channel_bwmode(padapter, peer_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
-
-               _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
-
-               _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT);
-       }
-}
-
-static void rtw_p2p_set_persistent(struct net_device *dev,
-                                  struct iw_request_info *info,
-                                  union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       /*      The input data is 0 or 1 */
-       /*      0: disable persistent group functionality */
-       /*      1: enable persistent group founctionality */
-
-       if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
-               return;
-       } else {
-               if (extra[0] == '0')    /*      Disable the persistent group function. */
-                       pwdinfo->persistent_supported = false;
-               else if (extra[0] == '1')       /*      Enable the persistent group function. */
-                       pwdinfo->persistent_supported = true;
-               else
-                       pwdinfo->persistent_supported = false;
-       }
-       pr_info("[%s] persistent_supported = %d\n", __func__, pwdinfo->persistent_supported);
-}
-
-static void rtw_p2p_prov_disc(struct net_device *dev,
-                             struct iw_request_info *info,
-                             union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-       u8 peerMAC[ETH_ALEN] = {0x00};
-       int jj, kk;
-       struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
-       struct list_head *plist, *phead;
-       struct __queue *queue   = &pmlmepriv->scanned_queue;
-       struct  wlan_network    *pnetwork = NULL;
-       uint peer_channel = 0;
-       u8 attr_content[100] = {0x00};
-       u8 *p2pie;
-       uint p2pielen = 0, attr_contentlen = 0;
-
-       /*      The input data contains two information items. */
-       /*      1. First information is the MAC address which wants to issue the provisioning discovery request frame. */
-       /*      2. Second information is the WPS configuration method which wants to discovery */
-       /*      Format: 00:E0:4C:00:00:05_display */
-       /*      Format: 00:E0:4C:00:00:05_keypad */
-       /*      Format: 00:E0:4C:00:00:05_pbc */
-       /*      Format: 00:E0:4C:00:00:05_label */
-
-       if (pwdinfo->p2p_state == P2P_STATE_NONE) {
-               return;
-       } else {
-               /*      Reset the content of struct tx_provdisc_req_info excluded the wps_config_method_request. */
-               memset(pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN);
-               memset(pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN);
-               memset(&pwdinfo->tx_prov_disc_info.ssid, 0x00, sizeof(struct ndis_802_11_ssid));
-               pwdinfo->tx_prov_disc_info.peer_channel_num[0] = 0;
-               pwdinfo->tx_prov_disc_info.peer_channel_num[1] = 0;
-               pwdinfo->tx_prov_disc_info.benable = false;
-       }
-
-       for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
-               peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
-
-       if (!memcmp(&extra[18], "display", 7))
-               pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
-       else if (!memcmp(&extra[18], "keypad", 7))
-               pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
-       else if (!memcmp(&extra[18], "pbc", 3))
-               pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
-       else if (!memcmp(&extra[18], "label", 5))
-               pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
-       else
-               return;
-
-       spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-
-       phead = get_list_head(queue);
-       plist = phead->next;
-
-       while (phead != plist) {
-               if (peer_channel != 0)
-                       break;
-
-               pnetwork = container_of(plist, struct wlan_network, list);
-
-               /*      Commented by Albert 2011/05/18 */
-               /*      Match the device address located in the P2P IE */
-               /*      This is for the case that the P2P device address is not the same as the P2P interface address. */
-
-               p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
-               if (p2pie) {
-                       while (p2pie) {
-                               /*      The P2P Device ID attribute is included in the Beacon frame. */
-                               /*      The P2P Device Info attribute is included in the probe response frame. */
-
-                               if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
-                                       /*      Handle the P2P Device ID attribute of Beacon first */
-                                       if (!memcmp(attr_content, peerMAC, ETH_ALEN)) {
-                                               peer_channel = pnetwork->network.Configuration.DSConfig;
-                                               break;
-                                       }
-                               } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
-                                       /*      Handle the P2P Device Info attribute of probe response */
-                                       if (!memcmp(attr_content, peerMAC, ETH_ALEN)) {
-                                               peer_channel = pnetwork->network.Configuration.DSConfig;
-                                               break;
-                                       }
-                               }
-
-                               /* Get the next P2P IE */
-                               p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
-                       }
-               }
-
-               plist = plist->next;
-       }
-
-       spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
-       if (peer_channel) {
-               memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN);
-               memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN);
-               pwdinfo->tx_prov_disc_info.peer_channel_num[0] = (u16)peer_channel;
-               pwdinfo->tx_prov_disc_info.benable = true;
-               rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
-               rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ);
-
-               if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
-                       memcpy(&pwdinfo->tx_prov_disc_info.ssid, &pnetwork->network.Ssid, sizeof(struct ndis_802_11_ssid));
-               } else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
-                       memcpy(pwdinfo->tx_prov_disc_info.ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN);
-                       pwdinfo->tx_prov_disc_info.ssid.SsidLength = P2P_WILDCARD_SSID_LEN;
-               }
-
-               set_channel_bwmode(padapter, peer_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
-
-               _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
-
-               _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
-       }
-}
-
-/*     This function is used to inform the driver the user had specified the pin code value or pbc */
-/*     to application. */
-
-static void rtw_p2p_got_wpsinfo(struct net_device *dev,
-                               struct iw_request_info *info,
-                               union iwreq_data *wrqu, char *extra)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-       /*      Added by Albert 20110328 */
-       /*      if the input data is P2P_NO_WPSINFO -> reset the wpsinfo */
-       /*      if the input data is P2P_GOT_WPSINFO_PEER_DISPLAY_PIN -> the utility just input the PIN code got from the peer P2P device. */
-       /*      if the input data is P2P_GOT_WPSINFO_SELF_DISPLAY_PIN -> the utility just got the PIN code from itself. */
-       /*      if the input data is P2P_GOT_WPSINFO_PBC -> the utility just determine to use the PBC */
-
-       if (*extra == '0')
-               pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
-       else if (*extra == '1')
-               pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN;
-       else if (*extra == '2')
-               pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN;
-       else if (*extra == '3')
-               pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PBC;
-       else
-               pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
-}
-
-static int rtw_p2p_set(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       if (!memcmp(extra, "enable =", 7)) {
-               rtw_wext_p2p_enable(dev, info, wrqu, &extra[7]);
-       } else if (!memcmp(extra, "setDN =", 6)) {
-               wrqu->data.length -= 6;
-               rtw_p2p_setDN(dev, info, wrqu, &extra[6]);
-       } else if (!memcmp(extra, "profilefound =", 13)) {
-               wrqu->data.length -= 13;
-               rtw_p2p_profilefound(dev, info, wrqu, &extra[13]);
-       } else if (!memcmp(extra, "prov_disc =", 10)) {
-               wrqu->data.length -= 10;
-               rtw_p2p_prov_disc(dev, info, wrqu, &extra[10]);
-       } else if (!memcmp(extra, "nego =", 5)) {
-               wrqu->data.length -= 5;
-               rtw_p2p_connect(dev, info, wrqu, &extra[5]);
-       } else if (!memcmp(extra, "intent =", 7)) {
-               /*      Commented by Albert 2011/03/23 */
-               /*      The wrqu->data.length will include the null character */
-               /*      So, we will decrease 7 + 1 */
-               wrqu->data.length -= 8;
-               rtw_p2p_set_intent(dev, info, wrqu, &extra[7]);
-       } else if (!memcmp(extra, "ssid =", 5)) {
-               wrqu->data.length -= 5;
-               rtw_p2p_set_go_nego_ssid(dev, info, wrqu, &extra[5]);
-       } else if (!memcmp(extra, "got_wpsinfo =", 12)) {
-               wrqu->data.length -= 12;
-               rtw_p2p_got_wpsinfo(dev, info, wrqu, &extra[12]);
-       } else if (!memcmp(extra, "listen_ch =", 10)) {
-               /*      Commented by Albert 2011/05/24 */
-               /*      The wrqu->data.length will include the null character */
-               /*      So, we will decrease (10 + 1) */
-               wrqu->data.length -= 11;
-               rtw_p2p_set_listen_ch(dev, info, wrqu, &extra[10]);
-       } else if (!memcmp(extra, "op_ch =", 6)) {
-               /*      Commented by Albert 2011/05/24 */
-               /*      The wrqu->data.length will include the null character */
-               /*      So, we will decrease (6 + 1) */
-               wrqu->data.length -= 7;
-               rtw_p2p_set_op_ch(dev, info, wrqu, &extra[6]);
-       } else if (!memcmp(extra, "invite =", 7)) {
-               wrqu->data.length -= 8;
-               rtw_p2p_invite_req(dev, info, wrqu, &extra[7]);
-       } else if (!memcmp(extra, "persistent =", 11)) {
-               wrqu->data.length -= 11;
-               rtw_p2p_set_persistent(dev, info, wrqu, &extra[11]);
-       }
-
-       return 0;
-}
-
-static int rtw_p2p_get2(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       int ret = 0;
-
-       if (!memcmp(extra, "wpsCM =", 6)) {
-               wrqu->data.length -= 6;
-               ret = rtw_p2p_get_wps_configmethod(dev, info, wrqu,  &extra[6]);
-       } else if (!memcmp(extra, "devN =", 5)) {
-               wrqu->data.length -= 5;
-               ret = rtw_p2p_get_device_name(dev, info, wrqu, &extra[5]);
-       } else if (!memcmp(extra, "dev_type =", 9)) {
-               wrqu->data.length -= 9;
-               ret = rtw_p2p_get_device_type(dev, info, wrqu, &extra[9]);
-       } else if (!memcmp(extra, "go_devadd =", 10)) {
-               wrqu->data.length -= 10;
-               ret = rtw_p2p_get_go_device_address(dev, info, wrqu, &extra[10]);
-       } else if (!memcmp(extra, "InvProc =", 8)) {
-               wrqu->data.length -= 8;
-               ret = rtw_p2p_get_invitation_procedure(dev, info, wrqu, &extra[8]);
-       }
-
-       return ret;
-}
-
-static int rtw_rereg_nd_name(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       int ret = 0;
-       struct adapter *padapter = rtw_netdev_priv(dev);
-       struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv;
-       char new_ifname[IFNAMSIZ];
-
-       if (rereg_priv->old_ifname[0] == 0) {
-               char *reg_ifname;
-               reg_ifname = padapter->registrypriv.if2name;
-
-               strscpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ);
-       }
-
-       if (wrqu->data.length > IFNAMSIZ)
-               return -EFAULT;
-
-       if (copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ))
-               return -EFAULT;
-
-       if (0 == strcmp(rereg_priv->old_ifname, new_ifname))
-               return ret;
-
-       ret = rtw_change_ifname(padapter, new_ifname);
-       if (0 != ret)
-               goto exit;
-
-       if (!memcmp(rereg_priv->old_ifname, "disable%d", 9)) {
-               padapter->ledpriv.bRegUseLed = rereg_priv->old_bRegUseLed;
-               rtl8188eu_InitSwLeds(padapter);
-               rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode);
-       }
-
-       strscpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ);
-
-       if (!memcmp(new_ifname, "disable%d", 9)) {
-               /*  free network queue for Android's timming issue */
-               rtw_free_network_queue(padapter, true);
-
-               /*  close led */
-               rtw_led_control(padapter, LED_CTL_POWER_OFF);
-               rereg_priv->old_bRegUseLed = padapter->ledpriv.bRegUseLed;
-               padapter->ledpriv.bRegUseLed = false;
-               rtl8188eu_DeInitSwLeds(padapter);
-
-               /*  the interface is being "disabled", we can do deeper IPS */
-               rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv);
-               rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL);
-       }
-exit:
-       return ret;
-}
-
-static void mac_reg_dump(struct adapter *padapter)
-{
-       int i, j = 1;
-       u32 reg;
-       int res;
-
-       pr_info("\n ======= MAC REG =======\n");
-       for (i = 0x0; i < 0x300; i += 4) {
-               if (j % 4 == 1)
-                       pr_info("0x%02x", i);
-
-               res = rtw_read32(padapter, i, &reg);
-               if (!res)
-                       pr_info(" 0x%08x ", reg);
-
-               if ((j++) % 4 == 0)
-                       pr_info("\n");
-       }
-       for (i = 0x400; i < 0x800; i += 4) {
-               if (j % 4 == 1)
-                       pr_info("0x%02x", i);
-
-               res = rtw_read32(padapter, i, &reg);
-               if (!res)
-                       pr_info(" 0x%08x ", reg);
-
-               if ((j++) % 4 == 0)
-                       pr_info("\n");
-       }
-}
-
-static void bb_reg_dump(struct adapter *padapter)
-{
-       int i, j = 1, res;
-       u32 reg;
-
-       pr_info("\n ======= BB REG =======\n");
-       for (i = 0x800; i < 0x1000; i += 4) {
-               if (j % 4 == 1)
-                       pr_info("0x%02x", i);
-
-               res = rtw_read32(padapter, i, &reg);
-               if (!res)
-                       pr_info(" 0x%08x ", reg);
-
-               if ((j++) % 4 == 0)
-                       pr_info("\n");
-       }
-}
-
-static void rf_reg_dump(struct adapter *padapter)
-{
-       int i, j = 1;
-       u32 value;
-
-       pr_info("\n ======= RF REG =======\n");
-       pr_info("\nRF_Path(%x)\n", RF_PATH_A);
-       for (i = 0; i < 0x100; i++) {
-               value = rtl8188e_PHY_QueryRFReg(padapter, i, 0xffffffff);
-               if (j % 4 == 1)
-                       pr_info("0x%02x ", i);
-               pr_info(" 0x%08x ", value);
-               if ((j++) % 4 == 0)
-                       pr_info("\n");
-       }
-}
-
-static void rtw_set_dynamic_functions(struct adapter *adapter, u8 dm_func)
-{
-       struct hal_data_8188e *haldata = &adapter->haldata;
-       struct odm_dm_struct *odmpriv = &haldata->odmpriv;
-       int res;
-
-       switch (dm_func) {
-       case 0:
-               /* disable all dynamic func */
-               odmpriv->SupportAbility = DYNAMIC_FUNC_DISABLE;
-               break;
-       case 1:
-               /* disable DIG */
-               odmpriv->SupportAbility &= (~DYNAMIC_BB_DIG);
-               break;
-       case 6:
-               /* turn on all dynamic func */
-               if (!(odmpriv->SupportAbility & DYNAMIC_BB_DIG)) {
-                       struct rtw_dig *digtable = &odmpriv->DM_DigTable;
-
-                       res = rtw_read8(adapter, 0xc50, &digtable->CurIGValue);
-                       (void)res;
-                       /* FIXME: return an error to caller */
-               }
-               odmpriv->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE;
-               break;
-       default:
-               break;
-       }
-}
-
-static void rtw_set_dm_func_flag(struct adapter *adapter, u32 odm_flag)
-{
-       struct hal_data_8188e *haldata = &adapter->haldata;
-       struct odm_dm_struct *odmpriv = &haldata->odmpriv;
-
-       odmpriv->SupportAbility = odm_flag;
-}
-
-static int rtw_dbg_port(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       int ret = 0;
-       u8 major_cmd, minor_cmd;
-       u16 arg;
-       s32 extra_arg;
-       u32 *pdata, val32;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-       struct wlan_network *cur_network = &pmlmepriv->cur_network;
-       struct sta_priv *pstapriv = &padapter->stapriv;
-
-       pdata = (u32 *)&wrqu->data;
-
-       val32 = *pdata;
-       arg = (u16)(val32 & 0x0000ffff);
-       major_cmd = (u8)(val32 >> 24);
-       minor_cmd = (u8)((val32 >> 16) & 0x00ff);
-
-       extra_arg = *(pdata + 1);
-
-       switch (major_cmd) {
-       case 0x70:/* read_reg */
-               switch (minor_cmd) {
-               case 1:
-                       break;
-               case 2:
-                       break;
-               case 4:
-                       break;
-               }
-               break;
-       case 0x71:/* write_reg */
-               switch (minor_cmd) {
-               case 1:
-                       rtw_write8(padapter, arg, extra_arg);
-                       break;
-               case 2:
-                       rtw_write16(padapter, arg, extra_arg);
-                       break;
-               case 4:
-                       rtw_write32(padapter, arg, extra_arg);
-                       break;
-               }
-               break;
-       case 0x72:/* read_bb */
-               break;
-       case 0x73:/* write_bb */
-               rtl8188e_PHY_SetBBReg(padapter, arg, 0xffffffff, extra_arg);
-               break;
-       case 0x74:/* read_rf */
-               if (minor_cmd != RF_PATH_A) {
-                       ret = -EINVAL;
-                       break;
-               }
-               break;
-       case 0x75:/* write_rf */
-               if (minor_cmd != RF_PATH_A) {
-                       ret = -EINVAL;
-                       break;
-               }
-               rtl8188e_PHY_SetRFReg(padapter, arg, 0xffffffff, extra_arg);
-               break;
-
-       case 0x76:
-               switch (minor_cmd) {
-               case 0x00: /* normal mode, */
-                       padapter->recvpriv.is_signal_dbg = 0;
-                       break;
-               case 0x01: /* dbg mode */
-                       padapter->recvpriv.is_signal_dbg = 1;
-                       extra_arg = extra_arg > 100 ? 100 : extra_arg;
-                       extra_arg = extra_arg < 0 ? 0 : extra_arg;
-                       padapter->recvpriv.signal_strength_dbg = extra_arg;
-                       break;
-               }
-               break;
-       case 0x78: /* IOL test */
-               switch (minor_cmd) {
-               case 0x04: /* LLT table initialization test */
-               {
-                       struct xmit_frame       *xmit_frame;
-
-                       xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
-                       if (!xmit_frame) {
-                               ret = -ENOMEM;
-                               break;
-                       }
-
-                       if (rtl8188e_IOL_exec_cmds_sync(padapter, xmit_frame, 500, 0) != _SUCCESS)
-                               ret = -EPERM;
-               }
-                       break;
-               case 0x05: /* blink LED test */
-               {
-                       u16 reg = 0x4c;
-                       u32 blink_num = 50;
-                       u32 blink_delay_ms = 200;
-                       int i;
-                       struct xmit_frame       *xmit_frame;
-
-                       xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
-                       if (!xmit_frame) {
-                               ret = -ENOMEM;
-                               break;
-                       }
-
-                       for (i = 0; i < blink_num; i++) {
-                               rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00, 0xff);
-                               rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
-                               rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08, 0xff);
-                               rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
-                       }
-                       if (rtl8188e_IOL_exec_cmds_sync(padapter, xmit_frame, (blink_delay_ms * blink_num * 2) + 200, 0) != _SUCCESS)
-                               ret = -EPERM;
-               }
-                       break;
-
-               case 0x06: /* continuous write byte test */
-               {
-                       u16 reg = arg;
-                       u16 start_value = 0;
-                       u32 write_num = extra_arg;
-                       int i, res;
-                       struct xmit_frame       *xmit_frame;
-                       u8 val8;
-
-                       xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
-                       if (!xmit_frame) {
-                               ret = -ENOMEM;
-                               break;
-                       }
-
-                       for (i = 0; i < write_num; i++)
-                               rtw_IOL_append_WB_cmd(xmit_frame, reg, i + start_value, 0xFF);
-                       if (rtl8188e_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0) != _SUCCESS)
-                               ret = -EPERM;
-
-                       /* FIXME: is this read necessary? */
-                       res = rtw_read8(padapter, reg, &val8);
-                       (void)res;
-               }
-                       break;
-
-               case 0x07: /* continuous write word test */
-               {
-                       u16 reg = arg;
-                       u16 start_value = 200;
-                       u32 write_num = extra_arg;
-                       u16 val16;
-                       int i, res;
-                       struct xmit_frame       *xmit_frame;
-
-                       xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
-                       if (!xmit_frame) {
-                               ret = -ENOMEM;
-                               break;
-                       }
-
-                       for (i = 0; i < write_num; i++)
-                               rtw_IOL_append_WW_cmd(xmit_frame, reg, i + start_value, 0xFFFF);
-                       if (rtl8188e_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0) != _SUCCESS)
-                               ret = -EPERM;
-
-                       /* FIXME: is this read necessary? */
-                       res = rtw_read16(padapter, reg, &val16);
-                       (void)res;
-               }
-                       break;
-               case 0x08: /* continuous write dword test */
-               {
-                       u16 reg = arg;
-                       u32 start_value = 0x110000c7;
-                       u32 write_num = extra_arg;
-
-                       int i;
-                       struct xmit_frame       *xmit_frame;
-
-                       xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
-                       if (!xmit_frame) {
-                               ret = -ENOMEM;
-                               break;
-                       }
-
-                       for (i = 0; i < write_num; i++)
-                               rtw_IOL_append_WD_cmd(xmit_frame, reg, i + start_value, 0xFFFFFFFF);
-                       if (rtl8188e_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0) != _SUCCESS)
-                               ret = -EPERM;
-
-                       /* FIXME: is this read necessary? */
-                       ret = rtw_read32(padapter, reg, &write_num);
-               }
-                       break;
-               }
-               break;
-       case 0x79:
-               {
-                       /*
-                       * dbg 0x79000000 [value], set RESP_TXAGC to + value, value:0~15
-                       * dbg 0x79010000 [value], set RESP_TXAGC to - value, value:0~15
-                       */
-                       u8 value =  extra_arg & 0x0f;
-                       u8 sign = minor_cmd;
-                       u16 write_value = 0;
-
-                       if (sign)
-                               value = value | 0x10;
-
-                       write_value = value | (value << 5);
-                       rtw_write16(padapter, 0x6d9, write_value);
-               }
-               break;
-       case 0x7a:
-               receive_disconnect(padapter, pmlmeinfo->network.MacAddress
-                       , WLAN_REASON_EXPIRATION_CHK);
-               break;
-       case 0x7F:
-               switch (minor_cmd) {
-               case 0x0:
-                       break;
-               case 0x01:
-                       break;
-               case 0x02:
-                       break;
-               case 0x03:
-                       break;
-               case 0x04:
-                       break;
-               case 0x05:
-                       rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
-                       break;
-               case 0x06:
-                       {
-                               u32 ODMFlag = (u32)(0x0f & arg);
-                               rtw_set_dm_func_flag(padapter, ODMFlag);
-                       }
-                       break;
-               case 0x07:
-                       break;
-               case 0x08:
-                       break;
-               case 0x09:
-                       break;
-               case 0x15:
-                       break;
-               case 0x10:/*  driver version display */
-                       break;
-               case 0x11:
-                       padapter->bRxRSSIDisplay = extra_arg;
-                       break;
-               case 0x12: /* set rx_stbc */
-               {
-                       struct registry_priv    *pregpriv = &padapter->registrypriv;
-                       /*  0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g */
-                       /* default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ */
-                       if (extra_arg == 0 ||
-                           extra_arg == 1 ||
-                           extra_arg == 2 ||
-                           extra_arg == 3)
-                               pregpriv->rx_stbc = extra_arg;
-               }
-                       break;
-               case 0x13: /* set ampdu_enable */
-               {
-                       struct registry_priv    *pregpriv = &padapter->registrypriv;
-                       /*  0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec) */
-                       if (extra_arg >= 0 && extra_arg < 3)
-                               pregpriv->ampdu_enable = extra_arg;
-               }
-                       break;
-               case 0x14: /* get wifi_spec */
-                       break;
-               case 0x23:
-                       padapter->bNotifyChannelChange = extra_arg;
-                       break;
-               case 0x24:
-                       padapter->bShowGetP2PState = extra_arg;
-                       break;
-               case 0xdd:/* registers dump, 0 for mac reg, 1 for bb reg, 2 for rf reg */
-                       if (extra_arg == 0)
-                               mac_reg_dump(padapter);
-                       else if (extra_arg == 1)
-                               bb_reg_dump(padapter);
-                       else if (extra_arg == 2)
-                               rf_reg_dump(padapter);
-                       break;
-               case 0xee:/* turn on/off dynamic funcs */
-                       if (extra_arg != 0xf) {
-                               /* extra_arg = 0  - disable all dynamic func
-                                * extra_arg = 1  - disable DIG
-                                * extra_arg = 6  - turn on all dynamic func
-                                */
-                               rtw_set_dynamic_functions(padapter, extra_arg);
-                       }
-                       break;
-               case 0xfd:
-                       rtw_write8(padapter, 0xc50, arg);
-                       rtw_write8(padapter, 0xc58, arg);
-                       break;
-               case 0xfe:
-                       break;
-               case 0xff:
-                       break;
-               }
-               break;
-       default:
-               break;
-       }
-       return ret;
-}
-
-static int rtw_wx_set_priv(struct net_device *dev,
-                               struct iw_request_info *info,
-                               union iwreq_data *awrq,
-                               char *extra)
-{
-       int ret = 0;
-       int len = 0;
-       char *ext;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct iw_point *dwrq = (struct iw_point *)awrq;
-
-       if (dwrq->length == 0)
-               return -EFAULT;
-
-       len = dwrq->length;
-       ext = vmalloc(len);
-       if (!ext)
-               return -ENOMEM;
-
-       if (copy_from_user(ext, dwrq->pointer, len)) {
-               vfree(ext);
-               return -EFAULT;
-       }
-
-       /* added for wps2.0 @20110524 */
-       if (dwrq->flags == 0x8766 && len > 8) {
-               u32 cp_sz;
-               struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-               u8 *probereq_wpsie = ext;
-               int probereq_wpsie_len = len;
-               u8 wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
-
-               if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) &&
-                   (!memcmp(&probereq_wpsie[2], wps_oui, 4))) {
-                       cp_sz = min(probereq_wpsie_len, MAX_WPS_IE_LEN);
-
-                       pmlmepriv->wps_probe_req_ie_len = 0;
-                       kfree(pmlmepriv->wps_probe_req_ie);
-                       pmlmepriv->wps_probe_req_ie = NULL;
-
-                       pmlmepriv->wps_probe_req_ie = kmemdup(probereq_wpsie, cp_sz, GFP_KERNEL);
-                       if (!pmlmepriv->wps_probe_req_ie) {
-                               ret =  -EINVAL;
-                               goto FREE_EXT;
-                       }
-                       pmlmepriv->wps_probe_req_ie_len = cp_sz;
-               }
-               goto FREE_EXT;
-       }
-
-       if (len >= WEXT_CSCAN_HEADER_SIZE &&
-           !memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
-               ret = rtw_wx_set_scan(dev, info, awrq, ext);
-               goto FREE_EXT;
-       }
-
-FREE_EXT:
-
-       vfree(ext);
-
-       return ret;
-}
-
-static int rtw_pm_set(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       int ret = 0;
-       unsigned        mode = 0;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-
-       if (!memcmp(extra, "lps =", 4)) {
-               sscanf(extra + 4, "%u", &mode);
-               ret = rtw_pm_set_lps(padapter, mode);
-       } else if (!memcmp(extra, "ips =", 4)) {
-               sscanf(extra + 4, "%u", &mode);
-               ret = rtw_pm_set_ips(padapter, mode);
-       } else {
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-static iw_handler rtw_handlers[] = {
-       IW_HANDLER(SIOCGIWNAME, rtw_wx_get_name),
-       IW_HANDLER(SIOCGIWFREQ, rtw_wx_get_freq),
-       IW_HANDLER(SIOCSIWMODE, rtw_wx_set_mode),
-       IW_HANDLER(SIOCGIWMODE, rtw_wx_get_mode),
-       IW_HANDLER(SIOCGIWSENS, rtw_wx_get_sens),
-       IW_HANDLER(SIOCGIWRANGE, rtw_wx_get_range),
-       IW_HANDLER(SIOCSIWPRIV, rtw_wx_set_priv),
-       IW_HANDLER(SIOCSIWAP, rtw_wx_set_wap),
-       IW_HANDLER(SIOCGIWAP, rtw_wx_get_wap),
-       IW_HANDLER(SIOCSIWMLME, rtw_wx_set_mlme),
-       IW_HANDLER(SIOCSIWSCAN, rtw_wx_set_scan),
-       IW_HANDLER(SIOCGIWSCAN, rtw_wx_get_scan),
-       IW_HANDLER(SIOCSIWESSID, rtw_wx_set_essid),
-       IW_HANDLER(SIOCGIWESSID, rtw_wx_get_essid),
-       IW_HANDLER(SIOCGIWNICKN, rtw_wx_get_nick),
-       IW_HANDLER(SIOCSIWRATE, rtw_wx_set_rate),
-       IW_HANDLER(SIOCGIWRATE, rtw_wx_get_rate),
-       IW_HANDLER(SIOCSIWRTS, rtw_wx_set_rts),
-       IW_HANDLER(SIOCGIWRTS, rtw_wx_get_rts),
-       IW_HANDLER(SIOCSIWFRAG, rtw_wx_set_frag),
-       IW_HANDLER(SIOCGIWFRAG, rtw_wx_get_frag),
-       IW_HANDLER(SIOCGIWRETRY, rtw_wx_get_retry),
-       IW_HANDLER(SIOCSIWENCODE, rtw_wx_set_enc),
-       IW_HANDLER(SIOCGIWENCODE, rtw_wx_get_enc),
-       IW_HANDLER(SIOCGIWPOWER, rtw_wx_get_power),
-       IW_HANDLER(SIOCSIWGENIE, rtw_wx_set_gen_ie),
-       IW_HANDLER(SIOCSIWAUTH, rtw_wx_set_auth),
-       IW_HANDLER(SIOCSIWENCODEEXT, rtw_wx_set_enc_ext),
-       IW_HANDLER(SIOCSIWPMKSA, rtw_wx_set_pmkid),
-};
-
-static const struct iw_priv_args rtw_private_args[] = {
-       {
-               SIOCIWFIRSTPRIV + 0x0,
-               IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write"
-       },
-       {
-               SIOCIWFIRSTPRIV + 0x1,
-               IW_PRIV_TYPE_CHAR | 0x7FF,
-               IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read"
-       },
-       {
-               SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
-       },
-       {
-               SIOCIWFIRSTPRIV + 0x4,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
-       },
-       {
-               SIOCIWFIRSTPRIV + 0x5,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid"
-       },
-       {
-               SIOCIWFIRSTPRIV + 0x6,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
-       },
-       {
-               SIOCIWFIRSTPRIV + 0xA,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan"
-       },
-
-       {
-               SIOCIWFIRSTPRIV + 0xB,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg"
-       },
-       {
-               SIOCIWFIRSTPRIV + 0xC,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw"
-       },
-       {
-               SIOCIWFIRSTPRIV + 0xD,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr"
-       },
-       {
-               SIOCIWFIRSTPRIV + 0x10,
-               IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, 0, "p2p_set"
-       },
-       {
-               SIOCIWFIRSTPRIV + 0x11,
-               IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | P2P_PRIVATE_IOCTL_SET_LEN, "p2p_get"
-       },
-       {
-               SIOCIWFIRSTPRIV + 0x12,
-               IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IFNAMSIZ, "p2p_get2"
-       },
-       {
-               SIOCIWFIRSTPRIV + 0x16,
-               IW_PRIV_TYPE_CHAR | 64, 0, "pm_set"
-       },
-
-       {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ, 0, "rereg_nd_name"},
-};
-
-static iw_handler rtw_private_handler[] = {
-       NULL,                           /* 0x00 */
-       NULL,                           /* 0x01 */
-       NULL,                           /* 0x02 */
-NULL,                                  /* 0x03 */
-/*  for MM DTV platform */
-       rtw_get_ap_info,                /* 0x04 */
-
-       rtw_set_pid,                    /* 0x05 */
-       rtw_wps_start,                  /* 0x06 */
-
-       NULL,                           /* 0x07 */
-       NULL,                           /* 0x08 */
-       NULL,                           /* 0x09 */
-
-/*  Set Channel depend on the country code */
-       rtw_wx_set_channel_plan,        /* 0x0A */
-
-       rtw_dbg_port,                   /* 0x0B */
-       rtw_wx_write_rf,                /* 0x0C */
-       rtw_wx_read_rf,                 /* 0x0D */
-       NULL,                           /* 0x0E */
-       NULL,                           /* 0x0F */
-
-       rtw_p2p_set,                    /* 0x10 */
-       NULL,                           /* 0x11 */
-       rtw_p2p_get2,                   /* 0x12 */
-
-       NULL,                           /* 0x13 */
-       NULL,                           /* 0x14 */
-       NULL,                           /* 0x15 */
-
-       rtw_pm_set,                     /* 0x16 */
-       NULL,                           /* 0x17 */
-       rtw_rereg_nd_name,              /* 0x18 */
-};
-
-static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct iw_statistics *piwstats = &padapter->iwstats;
-       int tmp_noise = 0;
-       int tmp;
-
-       if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
-               piwstats->qual.qual = 0;
-               piwstats->qual.level = 0;
-               piwstats->qual.noise = 0;
-       } else {
-               tmp_noise = padapter->recvpriv.noise;
-
-               piwstats->qual.level = padapter->signal_strength;
-               tmp = 219 + 3 * padapter->signal_strength;
-               tmp = min(100, tmp);
-               tmp = max(0, tmp);
-               piwstats->qual.qual = tmp;
-               piwstats->qual.noise = tmp_noise;
-       }
-       piwstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
-       return &padapter->iwstats;
-}
-
-struct iw_handler_def rtw_handlers_def = {
-       .standard = rtw_handlers,
-       .num_standard = ARRAY_SIZE(rtw_handlers),
-       .private = rtw_private_handler,
-       .private_args = (struct iw_priv_args *)rtw_private_args,
-       .num_private = ARRAY_SIZE(rtw_private_handler),
-       .num_private_args = ARRAY_SIZE(rtw_private_args),
-       .get_wireless_stats = rtw_get_wireless_stats,
-};
diff --git a/drivers/staging/r8188eu/os_dep/os_intfs.c b/drivers/staging/r8188eu/os_dep/os_intfs.c
deleted file mode 100644 (file)
index dc419fd..0000000
+++ /dev/null
@@ -1,807 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#define _OS_INTFS_C_
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/hal_intf.h"
-#include "../include/rtw_ioctl.h"
-#include "../include/usb_osintf.h"
-#include "../include/rtw_br_ext.h"
-#include "../include/rtw_led.h"
-#include "../include/rtl8188e_dm.h"
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Realtek Wireless Lan Driver");
-MODULE_AUTHOR("Realtek Semiconductor Corp.");
-MODULE_FIRMWARE(FW_RTL8188EU);
-
-#define CONFIG_BR_EXT_BRNAME "br0"
-#define RTW_NOTCH_FILTER 0 /* 0:Disable, 1:Enable, */
-
-/* module param defaults */
-static int rtw_rfintfs = HWPI;
-static int rtw_lbkmode;/* RTL8712_AIR_TRX; */
-static int rtw_network_mode = Ndis802_11IBSS;/* Ndis802_11Infrastructure; infra, ad-hoc, auto */
-static int rtw_channel = 1;/* ad-hoc support requirement */
-static int rtw_wireless_mode = WIRELESS_11BG_24N;
-static int rtw_vrtl_carrier_sense = AUTO_VCS;
-static int rtw_vcs_type = RTS_CTS;/*  */
-static int rtw_rts_thresh = 2347;/*  */
-static int rtw_frag_thresh = 2346;/*  */
-static int rtw_preamble = PREAMBLE_LONG;/* long, short, auto */
-static int rtw_scan_mode = 1;/* active, passive */
-static int rtw_adhoc_tx_pwr = 1;
-static int rtw_soft_ap;
-static int rtw_power_mgnt = 1;
-static int rtw_ips_mode = IPS_NORMAL;
-
-static int rtw_smart_ps = 2;
-
-module_param(rtw_ips_mode, int, 0644);
-MODULE_PARM_DESC(rtw_ips_mode, "The default IPS mode");
-
-static int rtw_radio_enable = 1;
-static int rtw_long_retry_lmt = 7;
-static int rtw_short_retry_lmt = 7;
-static int rtw_busy_thresh = 40;
-static int rtw_ack_policy = NORMAL_ACK;
-
-static int rtw_software_encrypt;
-static int rtw_software_decrypt;
-
-static int rtw_acm_method;/*  0:By SW 1:By HW. */
-
-static int rtw_wmm_enable = 1;/*  default is set to enable the wmm. */
-static int rtw_uapsd_enable;
-static int rtw_uapsd_max_sp = NO_LIMIT;
-static int rtw_uapsd_acbk_en;
-static int rtw_uapsd_acbe_en;
-static int rtw_uapsd_acvi_en;
-static int rtw_uapsd_acvo_en;
-
-static int rtw_led_enable = 1;
-
-static int rtw_ht_enable = 1;
-static int rtw_cbw40_enable = 3; /*  0 :disable, bit(0): enable 2.4g, bit(1): enable 5g */
-static int rtw_ampdu_enable = 1;/* for enable tx_ampdu */
-static int rtw_rx_stbc = 1;/*  0: disable, bit(0):enable 2.4g, bit(1):enable 5g, default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ */
-static int rtw_ampdu_amsdu;/*  0: disabled, 1:enabled, 2:auto */
-
-static int rtw_lowrate_two_xmit = 1;/* Use 2 path Tx to transmit MCS0~7 and legacy mode */
-
-static int rtw_low_power;
-static int rtw_wifi_spec;
-static int rtw_channel_plan = RT_CHANNEL_DOMAIN_MAX;
-static int rtw_AcceptAddbaReq = true;/*  0:Reject AP's Add BA req, 1:Accept AP's Add BA req. */
-
-static int rtw_antdiv_cfg = 2; /*  0:OFF , 1:ON, 2:decide by Efuse config */
-static int rtw_antdiv_type; /* 0:decide by efuse  1: for 88EE, 1Tx and 1RxCG are diversity.(2 Ant with SPDT), 2:  for 88EE, 1Tx and 2Rx are diversity.(2 Ant, Tx and RxCG are both on aux port, RxCS is on main port), 3: for 88EE, 1Tx and 1RxCG are fixed.(1Ant, Tx and RxCG are both on aux port) */
-
-
-static int rtw_hwpdn_mode = 2;/* 0:disable, 1:enable, 2: by EFUSE config */
-
-static int rtw_hwpwrp_detect; /* HW power  ping detect 0:disable , 1:enable */
-
-static int rtw_hw_wps_pbc = 1;
-
-int rtw_mc2u_disable;
-
-static int rtw_80211d;
-
-static char *ifname = "wlan%d";
-module_param(ifname, charp, 0644);
-MODULE_PARM_DESC(ifname, "The default name to allocate for first interface");
-
-static char *if2name = "wlan%d";
-module_param(if2name, charp, 0644);
-MODULE_PARM_DESC(if2name, "The default name to allocate for second interface");
-
-char *rtw_initmac;  /*  temp mac address if users want to use instead of the mac address in Efuse */
-
-module_param(rtw_initmac, charp, 0644);
-module_param(rtw_channel_plan, int, 0644);
-module_param(rtw_rfintfs, int, 0644);
-module_param(rtw_lbkmode, int, 0644);
-module_param(rtw_network_mode, int, 0644);
-module_param(rtw_channel, int, 0644);
-module_param(rtw_wmm_enable, int, 0644);
-module_param(rtw_vrtl_carrier_sense, int, 0644);
-module_param(rtw_vcs_type, int, 0644);
-module_param(rtw_busy_thresh, int, 0644);
-module_param(rtw_led_enable, int, 0644);
-module_param(rtw_ht_enable, int, 0644);
-module_param(rtw_cbw40_enable, int, 0644);
-module_param(rtw_ampdu_enable, int, 0644);
-module_param(rtw_rx_stbc, int, 0644);
-module_param(rtw_ampdu_amsdu, int, 0644);
-module_param(rtw_lowrate_two_xmit, int, 0644);
-module_param(rtw_power_mgnt, int, 0644);
-module_param(rtw_smart_ps, int, 0644);
-module_param(rtw_low_power, int, 0644);
-module_param(rtw_wifi_spec, int, 0644);
-module_param(rtw_antdiv_cfg, int, 0644);
-module_param(rtw_antdiv_type, int, 0644);
-module_param(rtw_hwpdn_mode, int, 0644);
-module_param(rtw_hwpwrp_detect, int, 0644);
-module_param(rtw_hw_wps_pbc, int, 0644);
-
-static uint rtw_max_roaming_times = 2;
-module_param(rtw_max_roaming_times, uint, 0644);
-MODULE_PARM_DESC(rtw_max_roaming_times, "The max roaming times to try");
-
-static int rtw_fw_iol = 1;/*  0:Disable, 1:enable, 2:by usb speed */
-module_param(rtw_fw_iol, int, 0644);
-MODULE_PARM_DESC(rtw_fw_iol, "FW IOL");
-
-module_param(rtw_mc2u_disable, int, 0644);
-
-module_param(rtw_80211d, int, 0644);
-MODULE_PARM_DESC(rtw_80211d, "Enable 802.11d mechanism");
-
-static uint rtw_notch_filter = RTW_NOTCH_FILTER;
-module_param(rtw_notch_filter, uint, 0644);
-MODULE_PARM_DESC(rtw_notch_filter, "0:Disable, 1:Enable, 2:Enable only for P2P");
-
-static uint loadparam(struct adapter *padapter)
-{
-       struct registry_priv  *registry_par = &padapter->registrypriv;
-
-       registry_par->rfintfs = (u8)rtw_rfintfs;
-       registry_par->lbkmode = (u8)rtw_lbkmode;
-       registry_par->network_mode  = (u8)rtw_network_mode;
-
-       memcpy(registry_par->ssid.Ssid, "ANY", 3);
-       registry_par->ssid.SsidLength = 3;
-
-       registry_par->channel = (u8)rtw_channel;
-       registry_par->wireless_mode = (u8)rtw_wireless_mode;
-       registry_par->vrtl_carrier_sense = (u8)rtw_vrtl_carrier_sense;
-       registry_par->vcs_type = (u8)rtw_vcs_type;
-       registry_par->rts_thresh = (u16)rtw_rts_thresh;
-       registry_par->frag_thresh = (u16)rtw_frag_thresh;
-       registry_par->preamble = (u8)rtw_preamble;
-       registry_par->scan_mode = (u8)rtw_scan_mode;
-       registry_par->adhoc_tx_pwr = (u8)rtw_adhoc_tx_pwr;
-       registry_par->soft_ap =  (u8)rtw_soft_ap;
-       registry_par->smart_ps =  (u8)rtw_smart_ps;
-       registry_par->power_mgnt = (u8)rtw_power_mgnt;
-       registry_par->ips_mode = (u8)rtw_ips_mode;
-       registry_par->radio_enable = (u8)rtw_radio_enable;
-       registry_par->long_retry_lmt = (u8)rtw_long_retry_lmt;
-       registry_par->short_retry_lmt = (u8)rtw_short_retry_lmt;
-       registry_par->busy_thresh = (u16)rtw_busy_thresh;
-       registry_par->ack_policy = (u8)rtw_ack_policy;
-       registry_par->software_encrypt = (u8)rtw_software_encrypt;
-       registry_par->software_decrypt = (u8)rtw_software_decrypt;
-       registry_par->acm_method = (u8)rtw_acm_method;
-
-        /* UAPSD */
-       registry_par->wmm_enable = (u8)rtw_wmm_enable;
-       registry_par->uapsd_enable = (u8)rtw_uapsd_enable;
-       registry_par->uapsd_max_sp = (u8)rtw_uapsd_max_sp;
-       registry_par->uapsd_acbk_en = (u8)rtw_uapsd_acbk_en;
-       registry_par->uapsd_acbe_en = (u8)rtw_uapsd_acbe_en;
-       registry_par->uapsd_acvi_en = (u8)rtw_uapsd_acvi_en;
-       registry_par->uapsd_acvo_en = (u8)rtw_uapsd_acvo_en;
-
-       registry_par->led_enable = (u8)rtw_led_enable;
-
-       registry_par->ht_enable = (u8)rtw_ht_enable;
-       registry_par->cbw40_enable = (u8)rtw_cbw40_enable;
-       registry_par->ampdu_enable = (u8)rtw_ampdu_enable;
-       registry_par->rx_stbc = (u8)rtw_rx_stbc;
-       registry_par->ampdu_amsdu = (u8)rtw_ampdu_amsdu;
-       registry_par->lowrate_two_xmit = (u8)rtw_lowrate_two_xmit;
-       registry_par->low_power = (u8)rtw_low_power;
-       registry_par->wifi_spec = (u8)rtw_wifi_spec;
-       registry_par->channel_plan = (u8)rtw_channel_plan;
-       registry_par->bAcceptAddbaReq = (u8)rtw_AcceptAddbaReq;
-       registry_par->antdiv_cfg = (u8)rtw_antdiv_cfg;
-       registry_par->antdiv_type = (u8)rtw_antdiv_type;
-       registry_par->hwpdn_mode = (u8)rtw_hwpdn_mode;/* 0:disable, 1:enable, 2:by EFUSE config */
-       registry_par->hwpwrp_detect = (u8)rtw_hwpwrp_detect;/* 0:disable, 1:enable */
-       registry_par->hw_wps_pbc = (u8)rtw_hw_wps_pbc;
-
-       registry_par->max_roaming_times = (u8)rtw_max_roaming_times;
-
-       registry_par->fw_iol = rtw_fw_iol;
-
-       registry_par->enable80211d = (u8)rtw_80211d;
-       snprintf(registry_par->ifname, 16, "%s", ifname);
-       snprintf(registry_par->if2name, 16, "%s", if2name);
-       registry_par->notch_filter = (u8)rtw_notch_filter;
-
-       return _SUCCESS;
-}
-
-static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev);
-       struct sockaddr *addr = p;
-
-       if (!padapter->bup)
-               memcpy(padapter->eeprompriv.mac_addr, addr->sa_data, ETH_ALEN);
-
-       return 0;
-}
-
-static struct net_device_stats *rtw_net_get_stats(struct net_device *pnetdev)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev);
-       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-       struct recv_priv *precvpriv = &padapter->recvpriv;
-
-       padapter->stats.tx_packets = pxmitpriv->tx_pkts;/* pxmitpriv->tx_pkts++; */
-       padapter->stats.rx_packets = precvpriv->rx_pkts;/* precvpriv->rx_pkts++; */
-       padapter->stats.tx_dropped = pxmitpriv->tx_drop;
-       padapter->stats.rx_dropped = precvpriv->rx_drop;
-       padapter->stats.tx_bytes = pxmitpriv->tx_bytes;
-       padapter->stats.rx_bytes = precvpriv->rx_bytes;
-       return &padapter->stats;
-}
-
-/*
- * AC to queue mapping
- *
- * AC_VO -> queue 0
- * AC_VI -> queue 1
- * AC_BE -> queue 2
- * AC_BK -> queue 3
- */
-static const u16 rtw_1d_to_queue[8] = { 2, 3, 3, 2, 1, 1, 0, 0 };
-
-/* Given a data frame determine the 802.1p/1d tag to use. */
-static unsigned int rtw_classify8021d(struct sk_buff *skb)
-{
-       unsigned int dscp;
-
-       /* skb->priority values from 256->263 are magic values to
-        * directly indicate a specific 802.1d priority.  This is used
-        * to allow 802.1d priority to be passed directly in from VLAN
-        * tags, etc.
-        */
-       if (skb->priority >= 256 && skb->priority <= 263)
-               return skb->priority - 256;
-
-       switch (skb->protocol) {
-       case htons(ETH_P_IP):
-               dscp = ip_hdr(skb)->tos & 0xfc;
-               break;
-       default:
-               return 0;
-       }
-
-       return dscp >> 5;
-}
-
-static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb, struct net_device *sb_dev)
-{
-       struct adapter  *padapter = rtw_netdev_priv(dev);
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
-       skb->priority = rtw_classify8021d(skb);
-
-       if (pmlmepriv->acm_mask != 0)
-               skb->priority = qos_acm(pmlmepriv->acm_mask, skb->priority);
-
-       return rtw_1d_to_queue[skb->priority];
-}
-
-u16 rtw_recv_select_queue(struct sk_buff *skb)
-{
-       struct iphdr *piphdr;
-       unsigned int dscp;
-       __be16  eth_type;
-       u32 priority;
-       u8 *pdata = skb->data;
-
-       memcpy(&eth_type, pdata + (ETH_ALEN << 1), 2);
-
-       switch (eth_type) {
-       case htons(ETH_P_IP):
-               piphdr = (struct iphdr *)(pdata + ETH_HLEN);
-               dscp = piphdr->tos & 0xfc;
-               priority = dscp >> 5;
-               break;
-       default:
-               priority = 0;
-       }
-
-       return rtw_1d_to_queue[priority];
-}
-
-static const struct net_device_ops rtw_netdev_ops = {
-       .ndo_open = netdev_open,
-       .ndo_stop = netdev_close,
-       .ndo_start_xmit = rtw_xmit_entry,
-       .ndo_select_queue       = rtw_select_queue,
-       .ndo_set_mac_address = rtw_net_set_mac_address,
-       .ndo_get_stats = rtw_net_get_stats,
-};
-
-int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname)
-{
-       int err;
-
-       err = dev_alloc_name(pnetdev, ifname);
-       if (err < 0)
-               return err;
-
-       netif_carrier_off(pnetdev);
-       return 0;
-}
-
-static const struct device_type wlan_type = {
-       .name = "wlan",
-};
-
-struct net_device *rtw_init_netdev(struct adapter *old_padapter)
-{
-       struct adapter *padapter;
-       struct net_device *pnetdev;
-
-       if (old_padapter)
-               pnetdev = rtw_alloc_etherdev_with_old_priv(sizeof(struct adapter), (void *)old_padapter);
-       else
-               pnetdev = rtw_alloc_etherdev(sizeof(struct adapter));
-
-       if (!pnetdev)
-               return NULL;
-
-       pnetdev->dev.type = &wlan_type;
-       padapter = rtw_netdev_priv(pnetdev);
-       padapter->pnetdev = pnetdev;
-       pnetdev->netdev_ops = &rtw_netdev_ops;
-       pnetdev->watchdog_timeo = HZ * 3; /* 3 second timeout */
-       pnetdev->wireless_handlers = (struct iw_handler_def *)&rtw_handlers_def;
-
-       /* step 2. */
-       loadparam(padapter);
-
-       return pnetdev;
-}
-
-int rtw_start_drv_threads(struct adapter *padapter)
-{
-       padapter->cmdThread = kthread_run(rtw_cmd_thread, padapter, "RTW_CMD_THREAD");
-       if (IS_ERR(padapter->cmdThread))
-               return PTR_ERR(padapter->cmdThread);
-
-       /* wait for rtw_cmd_thread() to start running */
-       wait_for_completion(&padapter->cmdpriv.start_cmd_thread);
-
-       return 0;
-}
-
-void rtw_stop_drv_threads(struct adapter *padapter)
-{
-       /* Below is to termindate rtw_cmd_thread & event_thread... */
-       complete(&padapter->cmdpriv.enqueue_cmd);
-       if (padapter->cmdThread)
-               /* wait for rtw_cmd_thread() to stop running */
-               wait_for_completion(&padapter->cmdpriv.stop_cmd_thread);
-}
-
-static void rtw_init_default_value(struct adapter *padapter)
-{
-       struct registry_priv *pregistrypriv = &padapter->registrypriv;
-       struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct security_priv *psecuritypriv = &padapter->securitypriv;
-
-       /* xmit_priv */
-       pxmitpriv->frag_len = pregistrypriv->frag_thresh;
-
-       /* mlme_priv */
-       pmlmepriv->scan_interval = SCAN_INTERVAL;/*  30*2 sec = 60sec */
-       pmlmepriv->scan_mode = SCAN_ACTIVE;
-
-       /* ht_priv */
-       pmlmepriv->htpriv.ampdu_enable = false;/* set to disabled */
-
-       /* security_priv */
-       psecuritypriv->binstallGrpkey = false;
-       psecuritypriv->sw_encrypt = pregistrypriv->software_encrypt;
-       psecuritypriv->sw_decrypt = pregistrypriv->software_decrypt;
-       psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
-       psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
-       psecuritypriv->dot11PrivacyKeyIndex = 0;
-       psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
-       psecuritypriv->dot118021XGrpKeyid = 1;
-       psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
-       psecuritypriv->ndisencryptstatus = Ndis802_11WEPDisabled;
-
-       /* registry_priv */
-       rtw_init_registrypriv_dev_network(padapter);
-       rtw_update_registrypriv_dev_network(padapter);
-
-       /* hal_priv */
-       rtl8188eu_init_default_value(padapter);
-
-       /* misc. */
-       padapter->bReadPortCancel = false;
-       padapter->bWritePortCancel = false;
-       padapter->bRxRSSIDisplay = 0;
-       padapter->bNotifyChannelChange = 0;
-       padapter->bShowGetP2PState = 1;
-}
-
-void rtw_reset_drv_sw(struct adapter *padapter)
-{
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
-       /* hal_priv */
-       rtl8188eu_init_default_value(padapter);
-       padapter->bReadPortCancel = false;
-       padapter->bWritePortCancel = false;
-       padapter->bRxRSSIDisplay = 0;
-       pmlmepriv->scan_interval = SCAN_INTERVAL;/*  30*2 sec = 60sec */
-
-       padapter->xmitpriv.tx_pkts = 0;
-       padapter->recvpriv.rx_pkts = 0;
-
-       pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
-
-       _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING);
-
-       /* mlmeextpriv */
-       padapter->mlmeextpriv.sitesurvey_res.state = SCAN_DISABLE;
-
-       rtw_set_signal_stat_timer(&padapter->recvpriv);
-}
-
-u8 rtw_init_drv_sw(struct adapter *padapter)
-{
-       if (rtw_init_cmd_priv(&padapter->cmdpriv)) {
-               dev_err(dvobj_to_dev(padapter->dvobj), "rtw_init_cmd_priv failed\n");
-               return _FAIL;
-       }
-
-       padapter->cmdpriv.padapter = padapter;
-
-       if (rtw_init_evt_priv(&padapter->evtpriv)) {
-               dev_err(dvobj_to_dev(padapter->dvobj), "rtw_init_evt_priv failed\n");
-               goto free_cmd_priv;
-       }
-
-       if (rtw_init_mlme_priv(padapter)) {
-               dev_err(dvobj_to_dev(padapter->dvobj), "rtw_init_mlme_priv failed\n");
-               goto free_evt_priv;
-       }
-
-       rtw_init_wifidirect_timers(padapter);
-       init_wifidirect_info(padapter, P2P_ROLE_DISABLE);
-       reset_global_wifidirect_info(padapter);
-
-       init_mlme_ext_priv(padapter);
-
-       if (_rtw_init_xmit_priv(&padapter->xmitpriv, padapter)) {
-               dev_err(dvobj_to_dev(padapter->dvobj), "_rtw_init_xmit_priv failed\n");
-               goto free_mlme_ext;
-       }
-
-       if (_rtw_init_recv_priv(&padapter->recvpriv, padapter)) {
-               dev_err(dvobj_to_dev(padapter->dvobj), "_rtw_init_recv_priv failed\n");
-               goto free_xmit_priv;
-       }
-
-       if (_rtw_init_sta_priv(&padapter->stapriv)) {
-               dev_err(dvobj_to_dev(padapter->dvobj), "_rtw_init_sta_priv failed\n");
-               goto free_recv_priv;
-       }
-
-       padapter->stapriv.padapter = padapter;
-
-       rtw_init_bcmc_stainfo(padapter);
-
-       rtw_init_pwrctrl_priv(padapter);
-
-       rtw_init_default_value(padapter);
-
-       rtl8188e_init_dm_priv(padapter);
-       rtl8188eu_InitSwLeds(padapter);
-
-       spin_lock_init(&padapter->br_ext_lock);
-
-       return _SUCCESS;
-
-free_recv_priv:
-       _rtw_free_recv_priv(&padapter->recvpriv);
-
-free_xmit_priv:
-       _rtw_free_xmit_priv(&padapter->xmitpriv);
-
-free_mlme_ext:
-       free_mlme_ext_priv(&padapter->mlmeextpriv);
-
-       rtw_free_mlme_priv(&padapter->mlmepriv);
-
-free_evt_priv:
-       rtw_free_evt_priv(&padapter->evtpriv);
-
-free_cmd_priv:
-       rtw_free_cmd_priv(&padapter->cmdpriv);
-
-       return _FAIL;
-}
-
-void rtw_cancel_all_timer(struct adapter *padapter)
-{
-       _cancel_timer_ex(&padapter->mlmepriv.assoc_timer);
-
-       _cancel_timer_ex(&padapter->mlmepriv.scan_to_timer);
-
-       _cancel_timer_ex(&padapter->mlmepriv.dynamic_chk_timer);
-
-       /*  cancel sw led timer */
-       rtl8188eu_DeInitSwLeds(padapter);
-
-       _cancel_timer_ex(&padapter->pwrctrlpriv.pwr_state_check_timer);
-
-       _cancel_timer_ex(&padapter->recvpriv.signal_stat_timer);
-}
-
-void rtw_free_drv_sw(struct adapter *padapter)
-{
-       /* we can call rtw_p2p_enable here, but: */
-       /*  1. rtw_p2p_enable may have IO operation */
-       /*  2. rtw_p2p_enable is bundled with wext interface */
-       {
-               struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-               if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
-                       _cancel_timer_ex(&pwdinfo->find_phase_timer);
-                       _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
-                       _cancel_timer_ex(&pwdinfo->pre_tx_scan_timer);
-                       rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
-               }
-       }
-
-       free_mlme_ext_priv(&padapter->mlmeextpriv);
-
-       rtw_free_cmd_priv(&padapter->cmdpriv);
-
-       rtw_free_evt_priv(&padapter->evtpriv);
-
-       rtw_free_mlme_priv(&padapter->mlmepriv);
-       _rtw_free_xmit_priv(&padapter->xmitpriv);
-
-       _rtw_free_sta_priv(&padapter->stapriv); /* will free bcmc_stainfo here */
-
-       _rtw_free_recv_priv(&padapter->recvpriv);
-
-       /* free the old_pnetdev */
-       if (padapter->rereg_nd_name_priv.old_pnetdev) {
-               free_netdev(padapter->rereg_nd_name_priv.old_pnetdev);
-               padapter->rereg_nd_name_priv.old_pnetdev = NULL;
-       }
-
-       /*  clear pbuddystruct adapter to avoid access wrong pointer. */
-       if (padapter->pbuddy_adapter)
-               padapter->pbuddy_adapter->pbuddy_adapter = NULL;
-}
-
-void netdev_br_init(struct net_device *netdev)
-{
-       struct adapter *adapter = (struct adapter *)rtw_netdev_priv(netdev);
-
-       rcu_read_lock();
-
-       if (rcu_dereference(adapter->pnetdev->rx_handler_data)) {
-               struct net_device *br_netdev;
-               struct net *devnet = NULL;
-
-               devnet = dev_net(netdev);
-               br_netdev = dev_get_by_name(devnet, CONFIG_BR_EXT_BRNAME);
-               if (br_netdev) {
-                       memcpy(adapter->br_mac, br_netdev->dev_addr, ETH_ALEN);
-                       dev_put(br_netdev);
-               } else {
-                       pr_info("%s()-%d: dev_get_by_name(%s) failed!",
-                               __func__, __LINE__, CONFIG_BR_EXT_BRNAME);
-               }
-       }
-       adapter->ethBrExtInfo.addPPPoETag = 1;
-
-       rcu_read_unlock();
-}
-
-static int _netdev_open(struct net_device *pnetdev)
-{
-       uint status;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev);
-
-       if (!padapter->bup) {
-               padapter->bDriverStopped = false;
-               padapter->bSurpriseRemoved = false;
-
-               status = rtw_hal_init(padapter);
-               if (status == _FAIL)
-                       goto netdev_open_error;
-
-               netdev_dbg(pnetdev, "MAC Address = %pM\n", pnetdev->dev_addr);
-
-               if (rtw_start_drv_threads(padapter)) {
-                       pr_info("Initialize driver software resource Failed!\n");
-                       goto netdev_open_error;
-               }
-
-               if (init_hw_mlme_ext(padapter) == _FAIL) {
-                       pr_info("can't init mlme_ext_priv\n");
-                       goto netdev_open_error;
-               }
-               if (rtl8188eu_inirp_init(padapter))
-                       goto netdev_open_error;
-
-               rtw_led_control(padapter, LED_CTL_NO_LINK);
-
-               padapter->bup = true;
-       }
-       padapter->net_closed = false;
-
-       _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000);
-
-       padapter->pwrctrlpriv.bips_processing = false;
-       rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv);
-
-       if (!rtw_netif_queue_stopped(pnetdev))
-               netif_tx_start_all_queues(pnetdev);
-       else
-               netif_tx_wake_all_queues(pnetdev);
-
-       netdev_br_init(pnetdev);
-
-       return 0;
-
-netdev_open_error:
-       padapter->bup = false;
-       netif_carrier_off(pnetdev);
-       netif_tx_stop_all_queues(pnetdev);
-       return -1;
-}
-
-int netdev_open(struct net_device *pnetdev)
-{
-       int ret;
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev);
-
-       mutex_lock(padapter->hw_init_mutex);
-       ret = _netdev_open(pnetdev);
-       mutex_unlock(padapter->hw_init_mutex);
-       return ret;
-}
-
-static int  ips_netdrv_open(struct adapter *padapter)
-{
-       int status = _SUCCESS;
-       padapter->net_closed = false;
-
-       padapter->bDriverStopped = false;
-       padapter->bSurpriseRemoved = false;
-
-       status = rtw_hal_init(padapter);
-       if (status == _FAIL)
-               goto netdev_open_error;
-
-       if (rtl8188eu_inirp_init(padapter))
-               goto netdev_open_error;
-
-       rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv);
-       _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 5000);
-
-       return _SUCCESS;
-
-netdev_open_error:
-       return _FAIL;
-}
-
-int rtw_ips_pwr_up(struct adapter *padapter)
-{
-       int result;
-       rtw_reset_drv_sw(padapter);
-
-       result = ips_netdrv_open(padapter);
-
-       rtw_led_control(padapter, LED_CTL_NO_LINK);
-
-       return result;
-}
-
-void rtw_ips_pwr_down(struct adapter *padapter)
-{
-       padapter->net_closed = true;
-
-       rtw_led_control(padapter, LED_CTL_POWER_OFF);
-
-       rtw_ips_dev_unload(padapter);
-}
-
-static void rtw_fifo_cleanup(struct adapter *adapter)
-{
-       struct pwrctrl_priv *pwrpriv = &adapter->pwrctrlpriv;
-       u8 trycnt = 100;
-       int res;
-       u32 reg;
-
-       /* pause tx */
-       rtw_write8(adapter, REG_TXPAUSE, 0xff);
-
-       /* keep sn */
-       /* FIXME: return an error to caller */
-       res = rtw_read16(adapter, REG_NQOS_SEQ, &adapter->xmitpriv.nqos_ssn);
-       if (res)
-               return;
-
-       if (!pwrpriv->bkeepfwalive) {
-               /* RX DMA stop */
-               res = rtw_read32(adapter, REG_RXPKT_NUM, &reg);
-               if (res)
-                       return;
-
-               rtw_write32(adapter, REG_RXPKT_NUM,
-                           (reg | RW_RELEASE_EN));
-               do {
-                       res = rtw_read32(adapter, REG_RXPKT_NUM, &reg);
-                       if (res)
-                               continue;
-
-                       if (!(reg & RXDMA_IDLE))
-                               break;
-               } while (trycnt--);
-
-               /* RQPN Load 0 */
-               rtw_write16(adapter, REG_RQPN_NPQ, 0x0);
-               rtw_write32(adapter, REG_RQPN, 0x80000000);
-               mdelay(10);
-       }
-}
-
-void rtw_ips_dev_unload(struct adapter *padapter)
-{
-       rtw_fifo_cleanup(padapter);
-
-       rtw_read_port_cancel(padapter);
-       rtw_write_port_cancel(padapter);
-
-       /* s5. */
-       if (!padapter->bSurpriseRemoved)
-               rtw_hal_deinit(padapter);
-}
-
-int netdev_close(struct net_device *pnetdev)
-{
-       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev);
-       struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
-
-       padapter->net_closed = true;
-
-       if (padapter->pwrctrlpriv.rf_pwrstate == rf_on) {
-               /* s1. */
-               if (pnetdev) {
-                       if (!rtw_netif_queue_stopped(pnetdev))
-                               netif_tx_stop_all_queues(pnetdev);
-               }
-
-               /* s2. */
-               LeaveAllPowerSaveMode(padapter);
-               rtw_disassoc_cmd(padapter, 500, false);
-               /* s2-2.  indicate disconnect to os */
-               rtw_indicate_disconnect(padapter);
-               /* s2-3. */
-               rtw_free_assoc_resources(padapter, 1);
-               /* s2-4. */
-               rtw_free_network_queue(padapter, true);
-               /*  Close LED */
-               rtw_led_control(padapter, LED_CTL_POWER_OFF);
-       }
-
-       nat25_db_cleanup(padapter);
-
-       rtw_p2p_enable(padapter, P2P_ROLE_DISABLE);
-
-       kfree(dvobj->firmware.data);
-       dvobj->firmware.data = NULL;
-
-       return 0;
-}
diff --git a/drivers/staging/r8188eu/os_dep/osdep_service.c b/drivers/staging/r8188eu/os_dep/osdep_service.c
deleted file mode 100644 (file)
index 88271f9..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-#define _OSDEP_SERVICE_C_
-
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/rtw_ioctl_set.h"
-
-/*
-* Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE
-* @return: one of RTW_STATUS_CODE
-*/
-inline int RTW_STATUS_CODE(int error_code)
-{
-       if (error_code >= 0)
-               return _SUCCESS;
-       return _FAIL;
-}
-
-void *rtw_malloc2d(int h, int w, int size)
-{
-       int j;
-
-       void **a = kzalloc(h * sizeof(void *) + h * w * size, GFP_KERNEL);
-       if (!a)
-               return NULL;
-
-       for (j = 0; j < h; j++)
-               a[j] = ((char *)(a + h)) + j * w * size;
-
-       return a;
-}
-
-/*
-For the following list_xxx operations,
-caller must guarantee the atomic context.
-Otherwise, there will be racing condition.
-*/
-/*
-Caller must check if the list is empty before calling rtw_list_delete
-*/
-
-static const struct device_type wlan_type = {
-       .name = "wlan",
-};
-
-struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv,
-                                                   void *old_priv)
-{
-       struct net_device *pnetdev;
-       struct rtw_netdev_priv_indicator *pnpi;
-
-       pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
-       if (!pnetdev)
-               return NULL;
-
-       pnetdev->dev.type = &wlan_type;
-       pnpi = netdev_priv(pnetdev);
-       pnpi->priv = old_priv;
-       pnpi->sizeof_priv = sizeof_priv;
-
-       return pnetdev;
-}
-
-struct net_device *rtw_alloc_etherdev(int sizeof_priv)
-{
-       struct net_device *pnetdev;
-       struct rtw_netdev_priv_indicator *pnpi;
-
-       pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
-       if (!pnetdev)
-               return NULL;
-
-       pnpi = netdev_priv(pnetdev);
-
-       pnpi->priv = vzalloc(sizeof_priv);
-       if (!pnpi->priv) {
-               free_netdev(pnetdev);
-               return NULL;
-       }
-
-       pnpi->sizeof_priv = sizeof_priv;
-
-       return pnetdev;
-}
-
-void rtw_free_netdev(struct net_device *netdev)
-{
-       struct rtw_netdev_priv_indicator *pnpi;
-
-       pnpi = netdev_priv(netdev);
-
-       vfree(pnpi->priv);
-       free_netdev(netdev);
-}
-
-int rtw_change_ifname(struct adapter *padapter, const char *ifname)
-{
-       struct net_device *pnetdev;
-       struct net_device *cur_pnetdev;
-       struct rereg_nd_name_data *rereg_priv;
-       int ret;
-
-       if (!padapter)
-               goto error;
-
-       cur_pnetdev = padapter->pnetdev;
-       rereg_priv = &padapter->rereg_nd_name_priv;
-
-       /* free the old_pnetdev */
-       if (rereg_priv->old_pnetdev) {
-               free_netdev(rereg_priv->old_pnetdev);
-               rereg_priv->old_pnetdev = NULL;
-       }
-
-       if (!rtnl_is_locked())
-               unregister_netdev(cur_pnetdev);
-       else
-               unregister_netdevice(cur_pnetdev);
-
-       rereg_priv->old_pnetdev = cur_pnetdev;
-
-       pnetdev = rtw_init_netdev(padapter);
-       if (!pnetdev)  {
-               ret = -1;
-               goto error;
-       }
-
-       SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter)));
-
-       rtw_init_netdev_name(pnetdev, ifname);
-
-       eth_hw_addr_set(pnetdev, padapter->eeprompriv.mac_addr);
-
-       if (!rtnl_is_locked())
-               ret = register_netdev(pnetdev);
-       else
-               ret = register_netdevice(pnetdev);
-       if (ret != 0)
-               goto error;
-
-       return 0;
-error:
-       return -1;
-}
-
-void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len)
-{
-       u32 dup_len = 0;
-       u8 *ori = NULL;
-       u8 *dup = NULL;
-
-       if (!buf || !buf_len)
-               return;
-
-       if (!src || !src_len)
-               goto keep_ori;
-
-       /* duplicate src */
-       dup = kmalloc(src_len, GFP_ATOMIC);
-       if (dup) {
-               dup_len = src_len;
-               memcpy(dup, src, dup_len);
-       }
-
-keep_ori:
-       ori = *buf;
-
-       /* replace buf with dup */
-       *buf_len = 0;
-       *buf = dup;
-       *buf_len = dup_len;
-
-       /* free ori */
-       kfree(ori);
-}
-
-/**
- * rtw_cbuf_empty - test if cbuf is empty
- * @cbuf: pointer of struct rtw_cbuf
- *
- * Returns: true if cbuf is empty
- */
-inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf)
-{
-       return cbuf->write == cbuf->read;
-}
-
-/**
- * rtw_cbuf_pop - pop a pointer from cbuf
- * @cbuf: pointer of struct rtw_cbuf
- *
- * Lock free operation, be careful of the use scheme
- * Returns: pointer popped out
- */
-void *rtw_cbuf_pop(struct rtw_cbuf *cbuf)
-{
-       void *buf;
-       if (rtw_cbuf_empty(cbuf))
-               return NULL;
-
-       buf = cbuf->bufs[cbuf->read];
-       cbuf->read = (cbuf->read + 1) % cbuf->size;
-
-       return buf;
-}
-
-/**
- * rtw_cbuf_alloc - allocate a rtw_cbuf with given size and do initialization
- * @size: size of pointer
- *
- * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure
- */
-struct rtw_cbuf *rtw_cbuf_alloc(u32 size)
-{
-       struct rtw_cbuf *cbuf;
-
-       cbuf = kmalloc(struct_size(cbuf, bufs, size), GFP_KERNEL);
-
-       if (cbuf) {
-               cbuf->write = 0;
-               cbuf->read = 0;
-               cbuf->size = size;
-       }
-       return cbuf;
-}
diff --git a/drivers/staging/r8188eu/os_dep/usb_intf.c b/drivers/staging/r8188eu/os_dep/usb_intf.c
deleted file mode 100644 (file)
index 74a16d1..0000000
+++ /dev/null
@@ -1,445 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#include <linux/usb.h>
-#include "../include/osdep_service.h"
-#include "../include/drv_types.h"
-#include "../include/hal_intf.h"
-#include "../include/osdep_intf.h"
-#include "../include/usb_ops.h"
-#include "../include/usb_osintf.h"
-#include "../include/rtw_ioctl.h"
-#include "../include/rtl8188e_hal.h"
-
-int ui_pid[3] = {0, 0, 0};
-
-static int rtw_suspend(struct usb_interface *intf, pm_message_t message);
-static int rtw_resume(struct usb_interface *intf);
-
-static int rtw_drv_init(struct usb_interface *pusb_intf, const struct usb_device_id *pdid);
-static void rtw_dev_remove(struct usb_interface *pusb_intf);
-
-#define USB_VENDER_ID_REALTEK          0x0bda
-
-/* DID_USB_v916_20130116 */
-static struct usb_device_id rtw_usb_id_tbl[] = {
-       /*=== Realtek demoboard ===*/
-       {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8179)}, /* 8188EUS */
-       {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0179)}, /* 8188ETV */
-       {USB_DEVICE(USB_VENDER_ID_REALTEK, 0xffef)}, /* Rosewill USB-N150 Nano */
-       /*=== Customer ID ===*/
-       /****** 8188EUS ********/
-       {USB_DEVICE(0x07B8, 0x8179)}, /* Abocom - Abocom */
-       {USB_DEVICE(0x0DF6, 0x0076)}, /* Sitecom N150 v2 */
-       {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */
-       {USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */
-       {USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */
-       {USB_DEVICE(0x2001, 0x331B)}, /* D-Link DWA-121 rev B1 */
-       {USB_DEVICE(0x056E, 0x4008)}, /* Elecom WDC-150SU2M */
-       {USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */
-       {USB_DEVICE(0x2357, 0x0111)}, /* TP-Link TL-WN727N v5.21 */
-       {USB_DEVICE(0x2C4E, 0x0102)}, /* MERCUSYS MW150US v2 */
-       {USB_DEVICE(0x0B05, 0x18F0)}, /* ASUS USB-N10 Nano B1 */
-       {USB_DEVICE(0x7392, 0xb811)}, /* Edimax EW-7811Un V2 */
-       {}      /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, rtw_usb_id_tbl);
-
-struct rtw_usb_drv {
-       struct usb_driver usbdrv;
-       int drv_registered;
-       struct mutex hw_init_mutex;
-};
-
-static struct rtw_usb_drv rtl8188e_usb_drv = {
-       .usbdrv.name = KBUILD_MODNAME,
-       .usbdrv.probe = rtw_drv_init,
-       .usbdrv.disconnect = rtw_dev_remove,
-       .usbdrv.id_table = rtw_usb_id_tbl,
-       .usbdrv.suspend =  rtw_suspend,
-       .usbdrv.resume = rtw_resume,
-       .usbdrv.reset_resume   = rtw_resume,
-};
-
-static struct rtw_usb_drv *usb_drv = &rtl8188e_usb_drv;
-
-static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
-{
-       int     i;
-       u8      rt_num_in_pipes = 0;
-       struct dvobj_priv *pdvobjpriv;
-       struct usb_host_config          *phost_conf;
-       struct usb_config_descriptor    *pconf_desc;
-       struct usb_host_interface       *phost_iface;
-       struct usb_interface_descriptor *piface_desc;
-       struct usb_endpoint_descriptor  *pendp_desc;
-       struct usb_device       *pusbd;
-
-       pdvobjpriv = kzalloc(sizeof(*pdvobjpriv), GFP_KERNEL);
-       if (!pdvobjpriv)
-               goto err;
-
-       pdvobjpriv->pusbintf = usb_intf;
-       pusbd = interface_to_usbdev(usb_intf);
-       pdvobjpriv->pusbdev = pusbd;
-       usb_set_intfdata(usb_intf, pdvobjpriv);
-
-       pdvobjpriv->RtNumOutPipes = 0;
-
-       phost_conf = pusbd->actconfig;
-       pconf_desc = &phost_conf->desc;
-
-       phost_iface = &usb_intf->altsetting[0];
-       piface_desc = &phost_iface->desc;
-
-       pdvobjpriv->NumInterfaces = pconf_desc->bNumInterfaces;
-       pdvobjpriv->InterfaceNumber = piface_desc->bInterfaceNumber;
-
-       for (i = 0; i < piface_desc->bNumEndpoints; i++) {
-               int ep_num;
-               pendp_desc = &phost_iface->endpoint[i].desc;
-
-               ep_num = usb_endpoint_num(pendp_desc);
-
-               if (usb_endpoint_is_bulk_in(pendp_desc)) {
-                       pdvobjpriv->RtInPipe = ep_num;
-                       rt_num_in_pipes++;
-               } else if (usb_endpoint_is_bulk_out(pendp_desc)) {
-                       pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] =
-                               ep_num;
-                       pdvobjpriv->RtNumOutPipes++;
-               }
-       }
-
-       if (rt_num_in_pipes != 1)
-               goto err;
-
-       /* 3 misc */
-       rtw_reset_continual_urb_error(pdvobjpriv);
-
-       usb_get_dev(pusbd);
-       return pdvobjpriv;
-
-err:
-       kfree(pdvobjpriv);
-       return NULL;
-}
-
-static void usb_dvobj_deinit(struct usb_interface *usb_intf)
-{
-       struct dvobj_priv *dvobj = usb_get_intfdata(usb_intf);
-
-       usb_set_intfdata(usb_intf, NULL);
-       if (dvobj) {
-               /* Modify condition for 92DU DMDP 2010.11.18, by Thomas */
-               if ((dvobj->NumInterfaces != 2 &&
-                   dvobj->NumInterfaces != 3) ||
-           (dvobj->InterfaceNumber == 1)) {
-                       if (interface_to_usbdev(usb_intf)->state !=
-                           USB_STATE_NOTATTACHED)
-                               /* If we didn't unplug usb dongle and
-                                * remove/insert module, driver fails
-                                * on sitesurvey for the first time when
-                                * device is up . Reset usb port for sitesurvey
-                                * fail issue. */
-                               usb_reset_device(interface_to_usbdev(usb_intf));
-               }
-               kfree(dvobj);
-       }
-
-       usb_put_dev(interface_to_usbdev(usb_intf));
-
-}
-
-static void rtw_dev_unload(struct adapter *padapter)
-{
-       if (padapter->bup) {
-               padapter->bDriverStopped = true;
-               if (padapter->xmitpriv.ack_tx)
-                       rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP);
-               /* s3. */
-               rtw_read_port_cancel(padapter);
-               rtw_write_port_cancel(padapter);
-
-               /* s4. */
-               rtw_stop_drv_threads(padapter);
-
-               /* s5. */
-               if (!padapter->bSurpriseRemoved) {
-                       rtw_hal_deinit(padapter);
-                       padapter->bSurpriseRemoved = true;
-               }
-
-               padapter->bup = false;
-       }
-}
-
-static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message)
-{
-       struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
-       struct adapter *padapter = dvobj->if1;
-       struct net_device *pnetdev = padapter->pnetdev;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
-
-       if ((!padapter->bup) || (padapter->bDriverStopped) ||
-           (padapter->bSurpriseRemoved))
-               goto exit;
-
-       pwrpriv->bInSuspend = true;
-       rtw_cancel_all_timer(padapter);
-       LeaveAllPowerSaveMode(padapter);
-
-       mutex_lock(&pwrpriv->lock);
-       /* s1. */
-       if (pnetdev) {
-               netif_carrier_off(pnetdev);
-               netif_tx_stop_all_queues(pnetdev);
-       }
-
-       /* s2. */
-       rtw_disassoc_cmd(padapter, 0, false);
-
-       if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
-           check_fwstate(pmlmepriv, _FW_LINKED))
-               pmlmepriv->to_roaming = 1;
-       /* s2-2.  indicate disconnect to os */
-       rtw_indicate_disconnect(padapter);
-       /* s2-3. */
-       rtw_free_assoc_resources(padapter, 1);
-       /* s2-4. */
-       rtw_free_network_queue(padapter, true);
-
-       rtw_dev_unload(padapter);
-       mutex_unlock(&pwrpriv->lock);
-
-       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
-               rtw_indicate_scan_done(padapter);
-
-       if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
-               rtw_indicate_disconnect(padapter);
-
-exit:
-               return 0;
-}
-
-static int rtw_resume(struct usb_interface *pusb_intf)
-{
-       struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
-       struct adapter *padapter = dvobj->if1;
-       struct net_device *pnetdev;
-       struct pwrctrl_priv *pwrpriv = NULL;
-       int ret = -1;
-
-       pnetdev = padapter->pnetdev;
-       pwrpriv = &padapter->pwrctrlpriv;
-
-       mutex_lock(&pwrpriv->lock);
-       rtw_reset_drv_sw(padapter);
-       if (pwrpriv)
-               pwrpriv->bkeepfwalive = false;
-
-       if (netdev_open(pnetdev) != 0) {
-               mutex_unlock(&pwrpriv->lock);
-               goto exit;
-       }
-
-       netif_device_attach(pnetdev);
-       netif_carrier_on(pnetdev);
-
-       mutex_unlock(&pwrpriv->lock);
-
-       if (padapter->pid[1] != 0)
-               rtw_signal_process(padapter->pid[1], SIGUSR2);
-
-       rtw_roaming(padapter, NULL);
-
-       ret = 0;
-exit:
-       if (pwrpriv)
-               pwrpriv->bInSuspend = false;
-
-       return ret;
-}
-
-/*
- * drv_init() - a device potentially for us
- *
- * notes: drv_init() is called when the bus driver has located
- * a card for us to support.
- *        We accept the new device by returning 0.
- */
-
-static int rtw_usb_if1_init(struct dvobj_priv *dvobj, struct usb_interface *pusb_intf)
-{
-       struct adapter *padapter = NULL;
-       struct net_device *pnetdev = NULL;
-       int ret;
-
-       padapter = vzalloc(sizeof(*padapter));
-       if (!padapter)
-               return -ENOMEM;
-
-       padapter->dvobj = dvobj;
-       dvobj->if1 = padapter;
-
-       padapter->bDriverStopped = true;
-
-       padapter->hw_init_mutex = &usb_drv->hw_init_mutex;
-
-       rtw_handle_dualmac(padapter, 1);
-
-       pnetdev = rtw_init_netdev(padapter);
-       if (!pnetdev) {
-               ret = -ENODEV;
-               goto handle_dualmac;
-       }
-       SET_NETDEV_DEV(pnetdev, dvobj_to_dev(dvobj));
-       padapter = rtw_netdev_priv(pnetdev);
-
-       /* step read_chip_version */
-       rtl8188e_read_chip_version(padapter);
-
-       /* step usb endpoint mapping */
-       ret = rtl8188eu_interface_configure(padapter);
-       if (ret)
-               goto handle_dualmac;
-
-       /* step read efuse/eeprom data and get mac_addr */
-       ret = ReadAdapterInfo8188EU(padapter);
-       if (ret)
-               goto handle_dualmac;
-
-       /* step 5. */
-       if (rtw_init_drv_sw(padapter) == _FAIL) {
-               ret = -ENODEV;
-               goto handle_dualmac;
-       }
-
-#ifdef CONFIG_PM
-       if (padapter->pwrctrlpriv.bSupportRemoteWakeup) {
-               dvobj->pusbdev->do_remote_wakeup = 1;
-               pusb_intf->needs_remote_wakeup = 1;
-               device_init_wakeup(&pusb_intf->dev, 1);
-       }
-#endif
-
-       /* 2012-07-11 Move here to prevent the 8723AS-VAU BT auto
-        * suspend influence */
-       usb_autopm_get_interface(pusb_intf);
-
-       /*  alloc dev name after read efuse. */
-       ret = rtw_init_netdev_name(pnetdev, padapter->registrypriv.ifname);
-       if (ret)
-               goto free_drv_sw;
-       rtw_macaddr_cfg(padapter->eeprompriv.mac_addr);
-       rtw_init_wifidirect_addrs(padapter, padapter->eeprompriv.mac_addr,
-                                 padapter->eeprompriv.mac_addr);
-       eth_hw_addr_set(pnetdev, padapter->eeprompriv.mac_addr);
-
-       /* step 6. Tell the network stack we exist */
-       ret = register_netdev(pnetdev);
-       if (ret)
-               goto free_drv_sw;
-
-       return 0;
-
-free_drv_sw:
-       rtw_cancel_all_timer(padapter);
-       rtw_free_drv_sw(padapter);
-handle_dualmac:
-       rtw_handle_dualmac(padapter, 0);
-       if (pnetdev)
-               rtw_free_netdev(pnetdev);
-       else
-               vfree(padapter);
-
-       return ret;
-}
-
-static void rtw_usb_if1_deinit(struct adapter *if1)
-{
-       struct net_device *pnetdev = if1->pnetdev;
-       struct mlme_priv *pmlmepriv = &if1->mlmepriv;
-
-       if (check_fwstate(pmlmepriv, _FW_LINKED))
-               rtw_disassoc_cmd(if1, 0, false);
-
-       free_mlme_ap_info(if1);
-
-       if (pnetdev) {
-               /* will call netdev_close() */
-               unregister_netdev(pnetdev);
-       }
-       rtw_cancel_all_timer(if1);
-
-       rtw_dev_unload(if1);
-       rtw_handle_dualmac(if1, 0);
-       rtw_free_drv_sw(if1);
-       if (pnetdev)
-               rtw_free_netdev(pnetdev);
-}
-
-static int rtw_drv_init(struct usb_interface *pusb_intf, const struct usb_device_id *pdid)
-{
-       struct dvobj_priv *dvobj;
-       int ret;
-
-       /* Initialize dvobj_priv */
-       dvobj = usb_dvobj_init(pusb_intf);
-       if (!dvobj)
-               return -ENODEV;
-
-       ret = rtw_usb_if1_init(dvobj, pusb_intf);
-       if (ret) {
-               usb_dvobj_deinit(pusb_intf);
-               return ret;
-       }
-
-       if (ui_pid[1] != 0)
-               rtw_signal_process(ui_pid[1], SIGUSR2);
-
-       return 0;
-}
-
-/*
- * dev_remove() - our device is being removed
-*/
-/* rmmod module & unplug(SurpriseRemoved) will call r871xu_dev_remove() => how to recognize both */
-static void rtw_dev_remove(struct usb_interface *pusb_intf)
-{
-       struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
-       struct adapter *padapter = dvobj->if1;
-
-       if (usb_drv->drv_registered)
-               padapter->bSurpriseRemoved = true;
-
-       rtw_pm_set_ips(padapter, IPS_NONE);
-       rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
-
-       LeaveAllPowerSaveMode(padapter);
-
-       rtw_usb_if1_deinit(padapter);
-
-       usb_dvobj_deinit(pusb_intf);
-}
-
-static int __init rtw_drv_entry(void)
-{
-       mutex_init(&usb_drv->hw_init_mutex);
-
-       usb_drv->drv_registered = true;
-       return usb_register(&usb_drv->usbdrv);
-}
-
-static void __exit rtw_drv_halt(void)
-{
-       usb_drv->drv_registered = false;
-       usb_deregister(&usb_drv->usbdrv);
-
-       mutex_destroy(&usb_drv->hw_init_mutex);
-}
-
-module_init(rtw_drv_entry);
-module_exit(rtw_drv_halt);
diff --git a/drivers/staging/r8188eu/os_dep/usb_ops_linux.c b/drivers/staging/r8188eu/os_dep/usb_ops_linux.c
deleted file mode 100644 (file)
index ca09f7e..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2012 Realtek Corporation. */
-
-#define _USB_OPS_LINUX_C_
-
-#include "../include/drv_types.h"
-#include "../include/rtl8188e_recv.h"
-
-static unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr)
-{
-       unsigned int pipe = 0, ep_num = 0;
-       struct usb_device *pusbd = pdvobj->pusbdev;
-
-       if (addr < HW_QUEUE_ENTRY) {
-               ep_num = pdvobj->Queue2Pipe[addr];
-               pipe = usb_sndbulkpipe(pusbd, ep_num);
-       }
-
-       return pipe;
-}
-
-void rtw_read_port_cancel(struct adapter *padapter)
-{
-       int i;
-       struct recv_buf *precvbuf = (struct recv_buf *)padapter->recvpriv.precv_buf;
-
-       padapter->bReadPortCancel = true;
-
-       for (i = 0; i < NR_RECVBUFF; i++) {
-               precvbuf->reuse = true;
-               usb_kill_urb(precvbuf->purb);
-               precvbuf++;
-       }
-}
-
-static void usb_write_port_complete(struct urb *purb)
-{
-       struct xmit_buf *pxmitbuf = (struct xmit_buf *)purb->context;
-       struct adapter *padapter = pxmitbuf->padapter;
-       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
-       if (pxmitbuf->high_queue)
-               rtw_chk_hi_queue_cmd(padapter);
-
-       switch (purb->status) {
-       case 0:
-       case -EINPROGRESS:
-       case -ENOENT:
-       case -ECONNRESET:
-       case -EPIPE:
-       case -EPROTO:
-               break;
-       case -ESHUTDOWN:
-               padapter->bDriverStopped = true;
-               break;
-       default:
-               padapter->bSurpriseRemoved = true;
-               break;
-       }
-
-       rtw_sctx_done_err(&pxmitbuf->sctx,
-                         purb->status ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS);
-       rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
-       tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
-}
-
-u32 rtw_write_port(struct adapter *padapter, u32 addr, u32 cnt, u8 *wmem)
-{
-       unsigned long irqL;
-       unsigned int pipe;
-       int status;
-       u32 ret = _FAIL;
-       struct urb *purb = NULL;
-       struct dvobj_priv       *pdvobj = adapter_to_dvobj(padapter);
-       struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
-       struct xmit_buf *pxmitbuf = (struct xmit_buf *)wmem;
-       struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data;
-       struct usb_device *pusbd = pdvobj->pusbdev;
-
-       if (padapter->bDriverStopped || padapter->bSurpriseRemoved) {
-               rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_TX_DENY);
-               goto exit;
-       }
-
-       spin_lock_irqsave(&pxmitpriv->lock, irqL);
-       pxmitbuf->high_queue = (addr == HIGH_QUEUE_INX);
-       spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
-
-       purb    = pxmitbuf->pxmit_urb;
-
-       /* translate DMA FIFO addr to pipehandle */
-       pipe = ffaddr2pipehdl(pdvobj, addr);
-
-       usb_fill_bulk_urb(purb, pusbd, pipe,
-                         pxmitframe->buf_addr, /*  pxmitbuf->pbuf */
-                         cnt,
-                         usb_write_port_complete,
-                         pxmitbuf);/* context is pxmitbuf */
-
-       status = usb_submit_urb(purb, GFP_ATOMIC);
-       if (status) {
-               rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR);
-               if (status == -ENODEV)
-                       padapter->bDriverStopped = true;
-               goto exit;
-       }
-
-       ret = _SUCCESS;
-
-/*    We add the URB_ZERO_PACKET flag to urb so that the host will send the zero packet automatically. */
-
-exit:
-       if (ret != _SUCCESS)
-               rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
-
-       return ret;
-}
-
-void rtw_write_port_cancel(struct adapter *padapter)
-{
-       int i;
-       struct xmit_buf *pxmitbuf = (struct xmit_buf *)padapter->xmitpriv.pxmitbuf;
-
-       padapter->bWritePortCancel = true;
-
-       for (i = 0; i < NR_XMITBUFF; i++) {
-               usb_kill_urb(pxmitbuf->pxmit_urb);
-               pxmitbuf++;
-       }
-
-       pxmitbuf = (struct xmit_buf *)padapter->xmitpriv.pxmit_extbuf;
-       for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
-               usb_kill_urb(pxmitbuf->pxmit_urb);
-               pxmitbuf++;
-       }
-}
index d8455b23e555441a071cbad3085aebda6b9ebed9..d8408acfc763f3199e73a84f25211da9d08706a9 100644 (file)
@@ -185,7 +185,6 @@ static void _rtl92e_dm_init_fsync(struct net_device *dev);
 static void _rtl92e_dm_deinit_fsync(struct net_device *dev);
 
 static void _rtl92e_dm_check_txrateandretrycount(struct net_device *dev);
-static  void _rtl92e_dm_check_ac_dc_power(struct net_device *dev);
 static void _rtl92e_dm_check_fsync(struct net_device *dev);
 static void _rtl92e_dm_check_rf_ctrl_gpio(void *data);
 static void _rtl92e_dm_fsync_timer_callback(struct timer_list *t);
@@ -236,8 +235,6 @@ void rtl92e_dm_watchdog(struct net_device *dev)
        if (priv->being_init_adapter)
                return;
 
-       _rtl92e_dm_check_ac_dc_power(dev);
-
        _rtl92e_dm_check_txrateandretrycount(dev);
        _rtl92e_dm_check_edca_turbo(dev);
 
@@ -255,26 +252,6 @@ void rtl92e_dm_watchdog(struct net_device *dev)
        _rtl92e_dm_cts_to_self(dev);
 }
 
-static void _rtl92e_dm_check_ac_dc_power(struct net_device *dev)
-{
-       struct r8192_priv *priv = rtllib_priv(dev);
-       static const char ac_dc_script[] = "/etc/acpi/wireless-rtl-ac-dc-power.sh";
-       char *argv[] = {(char *)ac_dc_script, DRV_NAME, NULL};
-       static char *envp[] = {"HOME=/",
-                       "TERM=linux",
-                       "PATH=/usr/bin:/bin",
-                        NULL};
-
-       if (priv->rst_progress == RESET_TYPE_SILENT)
-               return;
-       if (priv->rtllib->state != RTLLIB_LINKED)
-               return;
-       call_usermodehelper(ac_dc_script, argv, envp, UMH_WAIT_PROC);
-
-       return;
-};
-
-
 void rtl92e_init_adaptive_rate(struct net_device *dev)
 {
 
@@ -1660,10 +1637,6 @@ static void _rtl92e_dm_check_rf_ctrl_gpio(void *data)
        u8 tmp1byte;
        enum rt_rf_power_state rf_power_state_to_set;
        bool bActuallySet = false;
-       char *argv[3];
-       static const char RadioPowerPath[] = "/etc/acpi/events/RadioPower.sh";
-       static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin",
-                              NULL};
 
        bActuallySet = false;
 
@@ -1693,14 +1666,6 @@ static void _rtl92e_dm_check_rf_ctrl_gpio(void *data)
                mdelay(1000);
                priv->hw_rf_off_action = 1;
                rtl92e_set_rf_state(dev, rf_power_state_to_set, RF_CHANGE_BY_HW);
-               if (priv->hw_radio_off)
-                       argv[1] = "RFOFF";
-               else
-                       argv[1] = "RFON";
-
-               argv[0] = (char *)RadioPowerPath;
-               argv[2] = NULL;
-               call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC);
        }
 }
 
index a68b7385846235faf11c79dd6930c8a86af95ed3..7587fa88852741bc1262691324ef43ed9aab3fbb 100644 (file)
@@ -107,13 +107,13 @@ struct security_priv {
 
        u32 dot118021XGrpPrivacy;       /*  This specify the privacy algthm. used for Grp key */
        u32 dot118021XGrpKeyid;         /*  key id used for Grp Key (tx key index) */
-       union Keytype   dot118021XGrpKey[BIP_MAX_KEYID];        /*  802.1x Group Key, for inx0 and inx1 */
-       union Keytype   dot118021XGrptxmickey[BIP_MAX_KEYID];
-       union Keytype   dot118021XGrprxmickey[BIP_MAX_KEYID];
+       union Keytype   dot118021XGrpKey[BIP_MAX_KEYID + 1];    /*  802.1x Group Key, for inx0 and inx1 */
+       union Keytype   dot118021XGrptxmickey[BIP_MAX_KEYID + 1];
+       union Keytype   dot118021XGrprxmickey[BIP_MAX_KEYID + 1];
        union pn48              dot11Grptxpn;                   /*  PN48 used for Grp Key xmit. */
        union pn48              dot11Grprxpn;                   /*  PN48 used for Grp Key recv. */
        u32 dot11wBIPKeyid;                                             /*  key id used for BIP Key (tx key index) */
-       union Keytype   dot11wBIPKey[6];                /*  BIP Key, for index4 and index5 */
+       union Keytype   dot11wBIPKey[BIP_MAX_KEYID + 1];        /*  BIP Key, for index4 and index5 */
        union pn48              dot11wBIPtxpn;                  /*  PN48 used for Grp Key xmit. */
        union pn48              dot11wBIPrxpn;                  /*  PN48 used for Grp Key recv. */
 
index 54004f846cf0fd25b940c40b169c08d54eebe24d..84a9f4dd8f95456e2abfec04674f146788b4647b 100644 (file)
@@ -350,7 +350,7 @@ int rtw_cfg80211_check_bss(struct adapter *padapter)
        bss = cfg80211_get_bss(padapter->rtw_wdev->wiphy, notify_channel,
                        pnetwork->mac_address, pnetwork->ssid.ssid,
                        pnetwork->ssid.ssid_length,
-                       WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
+                       IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
 
        cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
 
@@ -711,6 +711,7 @@ exit:
 static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
 {
        int ret = 0;
+       u8 max_idx;
        u32 wep_key_idx, wep_key_len;
        struct adapter *padapter = rtw_netdev_priv(dev);
        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
@@ -724,26 +725,29 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
                goto exit;
        }
 
-       if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
-           param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
-           param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
-               if (param->u.crypt.idx >= WEP_KEYS
-                       || param->u.crypt.idx >= BIP_MAX_KEYID) {
-                       ret = -EINVAL;
-                       goto exit;
-               }
-       } else {
-               {
+       if (param->sta_addr[0] != 0xff || param->sta_addr[1] != 0xff ||
+           param->sta_addr[2] != 0xff || param->sta_addr[3] != 0xff ||
+           param->sta_addr[4] != 0xff || param->sta_addr[5] != 0xff) {
                ret = -EINVAL;
                goto exit;
        }
+
+       if (strcmp(param->u.crypt.alg, "WEP") == 0)
+               max_idx = WEP_KEYS - 1;
+       else
+               max_idx = BIP_MAX_KEYID;
+
+       if (param->u.crypt.idx > max_idx) {
+               netdev_err(dev, "Error crypt.idx %d > %d\n", param->u.crypt.idx, max_idx);
+               ret = -EINVAL;
+               goto exit;
        }
 
        if (strcmp(param->u.crypt.alg, "WEP") == 0) {
                wep_key_idx = param->u.crypt.idx;
                wep_key_len = param->u.crypt.key_len;
 
-               if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
+               if (wep_key_len <= 0) {
                        ret = -EINVAL;
                        goto exit;
                }
@@ -1135,8 +1139,8 @@ void rtw_cfg80211_unlink_bss(struct adapter *padapter, struct wlan_network *pnet
 
        bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
                select_network->mac_address, select_network->ssid.ssid,
-               select_network->ssid.ssid_length, 0/*WLAN_CAPABILITY_ESS*/,
-               0/*WLAN_CAPABILITY_ESS*/);
+               select_network->ssid.ssid_length, IEEE80211_BSS_TYPE_ANY,
+               IEEE80211_PRIVACY_ANY);
 
        if (bss) {
                cfg80211_unlink_bss(wiphy, bss);
index 30374a820496e6a137f934f5d53d5e9ad8b41988..40a3157fb73597cfde38a0bb6ae84745155ce32d 100644 (file)
@@ -46,6 +46,7 @@ static int wpa_set_auth_algs(struct net_device *dev, u32 value)
 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
 {
        int ret = 0;
+       u8 max_idx;
        u32 wep_key_idx, wep_key_len, wep_total_len;
        struct ndis_802_11_wep   *pwep = NULL;
        struct adapter *padapter = rtw_netdev_priv(dev);
@@ -60,19 +61,22 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
                goto exit;
        }
 
-       if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
-           param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
-           param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
-               if (param->u.crypt.idx >= WEP_KEYS ||
-                   param->u.crypt.idx >= BIP_MAX_KEYID) {
-                       ret = -EINVAL;
-                       goto exit;
-               }
-       } else {
-               {
-                       ret = -EINVAL;
-                       goto exit;
-               }
+       if (param->sta_addr[0] != 0xff || param->sta_addr[1] != 0xff ||
+           param->sta_addr[2] != 0xff || param->sta_addr[3] != 0xff ||
+           param->sta_addr[4] != 0xff || param->sta_addr[5] != 0xff) {
+               ret = -EINVAL;
+               goto exit;
+       }
+
+       if (strcmp(param->u.crypt.alg, "WEP") == 0)
+               max_idx = WEP_KEYS - 1;
+       else
+               max_idx = BIP_MAX_KEYID;
+
+       if (param->u.crypt.idx > max_idx) {
+               netdev_err(dev, "Error crypt.idx %d > %d\n", param->u.crypt.idx, max_idx);
+               ret = -EINVAL;
+               goto exit;
        }
 
        if (strcmp(param->u.crypt.alg, "WEP") == 0) {
@@ -84,9 +88,6 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
                wep_key_idx = param->u.crypt.idx;
                wep_key_len = param->u.crypt.key_len;
 
-               if (wep_key_idx > WEP_KEYS)
-                       return -EINVAL;
-
                if (wep_key_len > 0) {
                        wep_key_len = wep_key_len <= 5 ? 5 : 13;
                        wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, key_material);
index 2317fb077db0eb70e59b619d7ede6337b7bc919b..557516c642c3b037e8ffd04393c24b0b37e4a27e 100644 (file)
@@ -1262,18 +1262,20 @@ static struct iscsi_param *iscsi_check_key(
                return param;
 
        if (!(param->phase & phase)) {
-               pr_err("Key \"%s\" may not be negotiated during ",
-                               param->name);
+               char *phase_name;
+
                switch (phase) {
                case PHASE_SECURITY:
-                       pr_debug("Security phase.\n");
+                       phase_name = "Security";
                        break;
                case PHASE_OPERATIONAL:
-                       pr_debug("Operational phase.\n");
+                       phase_name = "Operational";
                        break;
                default:
-                       pr_debug("Unknown phase.\n");
+                       phase_name = "Unknown";
                }
+               pr_err("Key \"%s\" may not be negotiated during %s phase.\n",
+                               param->name, phase_name);
                return NULL;
        }
 
index 297dc62bca2986f014c4b4060c95d112a807fe7d..372d64756ed64b10c3dd9096aa20886320837ff9 100644 (file)
@@ -267,35 +267,34 @@ int amdtee_open_session(struct tee_context *ctx,
                goto out;
        }
 
+       /* Open session with loaded TA */
+       handle_open_session(arg, &session_info, param);
+       if (arg->ret != TEEC_SUCCESS) {
+               pr_err("open_session failed %d\n", arg->ret);
+               handle_unload_ta(ta_handle);
+               kref_put(&sess->refcount, destroy_session);
+               goto out;
+       }
+
        /* Find an empty session index for the given TA */
        spin_lock(&sess->lock);
        i = find_first_zero_bit(sess->sess_mask, TEE_NUM_SESSIONS);
-       if (i < TEE_NUM_SESSIONS)
+       if (i < TEE_NUM_SESSIONS) {
+               sess->session_info[i] = session_info;
+               set_session_id(ta_handle, i, &arg->session);
                set_bit(i, sess->sess_mask);
+       }
        spin_unlock(&sess->lock);
 
        if (i >= TEE_NUM_SESSIONS) {
                pr_err("reached maximum session count %d\n", TEE_NUM_SESSIONS);
+               handle_close_session(ta_handle, session_info);
                handle_unload_ta(ta_handle);
                kref_put(&sess->refcount, destroy_session);
                rc = -ENOMEM;
                goto out;
        }
 
-       /* Open session with loaded TA */
-       handle_open_session(arg, &session_info, param);
-       if (arg->ret != TEEC_SUCCESS) {
-               pr_err("open_session failed %d\n", arg->ret);
-               spin_lock(&sess->lock);
-               clear_bit(i, sess->sess_mask);
-               spin_unlock(&sess->lock);
-               handle_unload_ta(ta_handle);
-               kref_put(&sess->refcount, destroy_session);
-               goto out;
-       }
-
-       sess->session_info[i] = session_info;
-       set_session_id(ta_handle, i, &arg->session);
 out:
        free_pages((u64)ta, get_order(ta_size));
        return rc;
index 290b1bb0e9cd724fe51188154aef53da808cfbd1..df5fb5410b722a1be0f50996bbbb1582806c50c2 100644 (file)
@@ -488,7 +488,7 @@ static bool is_normal_memory(pgprot_t p)
 #elif defined(CONFIG_ARM64)
        return (pgprot_val(p) & PTE_ATTRINDX_MASK) == PTE_ATTRINDX(MT_NORMAL);
 #else
-#error "Unuspported architecture"
+#error "Unsupported architecture"
 #endif
 }
 
index b1c6231defad7a5ebf939e44466717f7e5645f6e..673cf035949483eba11bc9067d4303fd7eced52f 100644 (file)
@@ -32,7 +32,7 @@ static int shm_get_kernel_pages(unsigned long start, size_t page_count,
                         is_kmap_addr((void *)start)))
                return -EINVAL;
 
-       page = virt_to_page(start);
+       page = virt_to_page((void *)start);
        for (n = 0; n < page_count; n++) {
                pages[n] = page + n;
                get_page(pages[n]);
index 40725cbc6eb0cdcf1381ad71644085d00656bd5e..d71ee50e7878f6c2dbb0b9ac84c1dd631f1b9c8c 100644 (file)
@@ -153,7 +153,6 @@ static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp
                cancel_delayed_work_sync(&pci_info->work);
                proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 0);
                proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_THRES_0, 0);
-               thermal_zone_device_disable(tzd);
                pci_info->stored_thres = 0;
                return 0;
        }
@@ -166,7 +165,6 @@ static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp
        proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_THRES_0, _temp);
        proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 1);
 
-       thermal_zone_device_enable(tzd);
        pci_info->stored_thres = temp;
 
        return 0;
@@ -268,6 +266,10 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
                goto err_free_vectors;
        }
 
+       ret = thermal_zone_device_enable(pci_info->tzone);
+       if (ret)
+               goto err_free_vectors;
+
        return 0;
 
 err_free_vectors:
index c7ba5680cd483abd5c3196b7db2ca68abcb6f644..91fc7e239497165d6cf5a91eed20f8810d9c4903 100644 (file)
@@ -235,6 +235,12 @@ static int max_idle_set(const char *arg, const struct kernel_param *kp)
                goto skip_limit_set;
        }
 
+       if (!cpumask_available(idle_injection_cpu_mask)) {
+               ret = allocate_copy_idle_injection_mask(cpu_present_mask);
+               if (ret)
+                       goto skip_limit_set;
+       }
+
        if (check_invalid(idle_injection_cpu_mask, new_max_idle)) {
                ret = -EINVAL;
                goto skip_limit_set;
@@ -791,7 +797,8 @@ static int __init powerclamp_init(void)
                return retval;
 
        mutex_lock(&powerclamp_lock);
-       retval = allocate_copy_idle_injection_mask(cpu_present_mask);
+       if (!cpumask_available(idle_injection_cpu_mask))
+               retval = allocate_copy_idle_injection_mask(cpu_present_mask);
        mutex_unlock(&powerclamp_lock);
 
        if (retval)
index 2e22bb82b7389e740c70dc66de24351372861bf0..e69868e868eb9e9abd0a2e826dbf75913605b4bc 100644 (file)
@@ -193,8 +193,67 @@ static const struct attribute_group thermal_attr_group = {
 #define THERM_THROT_POLL_INTERVAL      HZ
 #define THERM_STATUS_PROCHOT_LOG       BIT(1)
 
-#define THERM_STATUS_CLEAR_CORE_MASK (BIT(1) | BIT(3) | BIT(5) | BIT(7) | BIT(9) | BIT(11) | BIT(13) | BIT(15))
-#define THERM_STATUS_CLEAR_PKG_MASK  (BIT(1) | BIT(3) | BIT(5) | BIT(7) | BIT(9) | BIT(11))
+static u64 therm_intr_core_clear_mask;
+static u64 therm_intr_pkg_clear_mask;
+
+static void thermal_intr_init_core_clear_mask(void)
+{
+       if (therm_intr_core_clear_mask)
+               return;
+
+       /*
+        * Reference: Intel SDM  Volume 4
+        * "Table 2-2. IA-32 Architectural MSRs", MSR 0x19C
+        * IA32_THERM_STATUS.
+        */
+
+       /*
+        * Bit 1, 3, 5: CPUID.01H:EDX[22] = 1. This driver will not
+        * enable interrupts, when 0 as it checks for X86_FEATURE_ACPI.
+        */
+       therm_intr_core_clear_mask = (BIT(1) | BIT(3) | BIT(5));
+
+       /*
+        * Bit 7 and 9: Thermal Threshold #1 and #2 log
+        * If CPUID.01H:ECX[8] = 1
+        */
+       if (boot_cpu_has(X86_FEATURE_TM2))
+               therm_intr_core_clear_mask |= (BIT(7) | BIT(9));
+
+       /* Bit 11: Power Limitation log (R/WC0) If CPUID.06H:EAX[4] = 1 */
+       if (boot_cpu_has(X86_FEATURE_PLN))
+               therm_intr_core_clear_mask |= BIT(11);
+
+       /*
+        * Bit 13: Current Limit log (R/WC0) If CPUID.06H:EAX[7] = 1
+        * Bit 15: Cross Domain Limit log (R/WC0) If CPUID.06H:EAX[7] = 1
+        */
+       if (boot_cpu_has(X86_FEATURE_HWP))
+               therm_intr_core_clear_mask |= (BIT(13) | BIT(15));
+}
+
+static void thermal_intr_init_pkg_clear_mask(void)
+{
+       if (therm_intr_pkg_clear_mask)
+               return;
+
+       /*
+        * Reference: Intel SDM  Volume 4
+        * "Table 2-2. IA-32 Architectural MSRs", MSR 0x1B1
+        * IA32_PACKAGE_THERM_STATUS.
+        */
+
+       /* All bits except BIT 26 depend on CPUID.06H: EAX[6] = 1 */
+       if (boot_cpu_has(X86_FEATURE_PTS))
+               therm_intr_pkg_clear_mask = (BIT(1) | BIT(3) | BIT(5) | BIT(7) | BIT(9) | BIT(11));
+
+       /*
+        * Intel SDM Volume 2A: Thermal and Power Management Leaf
+        * Bit 26: CPUID.06H: EAX[19] = 1
+        */
+       if (boot_cpu_has(X86_FEATURE_HFI))
+               therm_intr_pkg_clear_mask |= BIT(26);
+}
 
 /*
  * Clear the bits in package thermal status register for bit = 1
@@ -207,13 +266,10 @@ void thermal_clear_package_intr_status(int level, u64 bit_mask)
 
        if (level == CORE_LEVEL) {
                msr  = MSR_IA32_THERM_STATUS;
-               msr_val = THERM_STATUS_CLEAR_CORE_MASK;
+               msr_val = therm_intr_core_clear_mask;
        } else {
                msr  = MSR_IA32_PACKAGE_THERM_STATUS;
-               msr_val = THERM_STATUS_CLEAR_PKG_MASK;
-               if (boot_cpu_has(X86_FEATURE_HFI))
-                       msr_val |= BIT(26);
-
+               msr_val = therm_intr_pkg_clear_mask;
        }
 
        msr_val &= ~bit_mask;
@@ -708,6 +764,9 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
        h = THERMAL_APIC_VECTOR | APIC_DM_FIXED | APIC_LVT_MASKED;
        apic_write(APIC_LVTTHMR, h);
 
+       thermal_intr_init_core_clear_mask();
+       thermal_intr_init_pkg_clear_mask();
+
        rdmsr(MSR_IA32_THERM_INTERRUPT, l, h);
        if (cpu_has(c, X86_FEATURE_PLN) && !int_pln_enable)
                wrmsr(MSR_IA32_THERM_INTERRUPT,
index 55679fd86505d762ea05ec68028e1a500aec0b5d..566df4522b8853fb89d965d994353c6c0d603671 100644 (file)
@@ -613,6 +613,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
        struct thermal_instance *pos;
        struct thermal_zone_device *pos1;
        struct thermal_cooling_device *pos2;
+       bool upper_no_limit;
        int result;
 
        if (trip >= tz->num_trips || trip < 0)
@@ -632,7 +633,13 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
 
        /* lower default 0, upper default max_state */
        lower = lower == THERMAL_NO_LIMIT ? 0 : lower;
-       upper = upper == THERMAL_NO_LIMIT ? cdev->max_state : upper;
+
+       if (upper == THERMAL_NO_LIMIT) {
+               upper = cdev->max_state;
+               upper_no_limit = true;
+       } else {
+               upper_no_limit = false;
+       }
 
        if (lower > upper || upper > cdev->max_state)
                return -EINVAL;
@@ -644,6 +651,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
        dev->cdev = cdev;
        dev->trip = trip;
        dev->upper = upper;
+       dev->upper_no_limit = upper_no_limit;
        dev->lower = lower;
        dev->target = THERMAL_NO_TARGET;
        dev->weight = weight;
@@ -1045,6 +1053,91 @@ devm_thermal_of_cooling_device_register(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_thermal_of_cooling_device_register);
 
+static bool thermal_cooling_device_present(struct thermal_cooling_device *cdev)
+{
+       struct thermal_cooling_device *pos = NULL;
+
+       list_for_each_entry(pos, &thermal_cdev_list, node) {
+               if (pos == cdev)
+                       return true;
+       }
+
+       return false;
+}
+
+/**
+ * thermal_cooling_device_update - Update a cooling device object
+ * @cdev: Target cooling device.
+ *
+ * Update @cdev to reflect a change of the underlying hardware or platform.
+ *
+ * Must be called when the maximum cooling state of @cdev becomes invalid and so
+ * its .get_max_state() callback needs to be run to produce the new maximum
+ * cooling state value.
+ */
+void thermal_cooling_device_update(struct thermal_cooling_device *cdev)
+{
+       struct thermal_instance *ti;
+       unsigned long state;
+
+       if (IS_ERR_OR_NULL(cdev))
+               return;
+
+       /*
+        * Hold thermal_list_lock throughout the update to prevent the device
+        * from going away while being updated.
+        */
+       mutex_lock(&thermal_list_lock);
+
+       if (!thermal_cooling_device_present(cdev))
+               goto unlock_list;
+
+       /*
+        * Update under the cdev lock to prevent the state from being set beyond
+        * the new limit concurrently.
+        */
+       mutex_lock(&cdev->lock);
+
+       if (cdev->ops->get_max_state(cdev, &cdev->max_state))
+               goto unlock;
+
+       thermal_cooling_device_stats_reinit(cdev);
+
+       list_for_each_entry(ti, &cdev->thermal_instances, cdev_node) {
+               if (ti->upper == cdev->max_state)
+                       continue;
+
+               if (ti->upper < cdev->max_state) {
+                       if (ti->upper_no_limit)
+                               ti->upper = cdev->max_state;
+
+                       continue;
+               }
+
+               ti->upper = cdev->max_state;
+               if (ti->lower > ti->upper)
+                       ti->lower = ti->upper;
+
+               if (ti->target == THERMAL_NO_TARGET)
+                       continue;
+
+               if (ti->target > ti->upper)
+                       ti->target = ti->upper;
+       }
+
+       if (cdev->ops->get_cur_state(cdev, &state) || state > cdev->max_state)
+               goto unlock;
+
+       thermal_cooling_device_stats_update(cdev, state);
+
+unlock:
+       mutex_unlock(&cdev->lock);
+
+unlock_list:
+       mutex_unlock(&thermal_list_lock);
+}
+EXPORT_SYMBOL_GPL(thermal_cooling_device_update);
+
 static void __unbind(struct thermal_zone_device *tz, int mask,
                     struct thermal_cooling_device *cdev)
 {
@@ -1067,20 +1160,17 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
        int i;
        const struct thermal_zone_params *tzp;
        struct thermal_zone_device *tz;
-       struct thermal_cooling_device *pos = NULL;
 
        if (!cdev)
                return;
 
        mutex_lock(&thermal_list_lock);
-       list_for_each_entry(pos, &thermal_cdev_list, node)
-               if (pos == cdev)
-                       break;
-       if (pos != cdev) {
-               /* thermal cooling device not found */
+
+       if (!thermal_cooling_device_present(cdev)) {
                mutex_unlock(&thermal_list_lock);
                return;
        }
+
        list_del(&cdev->node);
 
        /* Unbind all thermal zones associated with 'this' cdev */
@@ -1309,7 +1399,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
                struct thermal_trip trip;
 
                result = thermal_zone_get_trip(tz, count, &trip);
-               if (result)
+               if (result || !trip.temperature)
                        set_bit(count, &tz->trips_disabled);
        }
 
index 7af54382e915172975bd63079f3a5cf23de8d1fc..3d4a787c6b28a0baf7197726058708a5a7b830af 100644 (file)
@@ -101,6 +101,7 @@ struct thermal_instance {
        struct list_head tz_node; /* node in tz->thermal_instances */
        struct list_head cdev_node; /* node in cdev->thermal_instances */
        unsigned int weight; /* The weight of the cooling device */
+       bool upper_no_limit;
 };
 
 #define to_thermal_zone(_dev) \
@@ -127,6 +128,7 @@ int thermal_zone_create_device_groups(struct thermal_zone_device *, int);
 void thermal_zone_destroy_device_groups(struct thermal_zone_device *);
 void thermal_cooling_device_setup_sysfs(struct thermal_cooling_device *);
 void thermal_cooling_device_destroy_sysfs(struct thermal_cooling_device *cdev);
+void thermal_cooling_device_stats_reinit(struct thermal_cooling_device *cdev);
 /* used only at binding time */
 ssize_t trip_point_show(struct device *, struct device_attribute *, char *);
 ssize_t weight_show(struct device *, struct device_attribute *, char *);
index cef860deaf912db0b264a14e71ffff0bff3eee52..6c20c9f90a05acb777b13019fa341fcb80e69320 100644 (file)
@@ -685,6 +685,8 @@ void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev,
 {
        struct cooling_dev_stats *stats = cdev->stats;
 
+       lockdep_assert_held(&cdev->lock);
+
        if (!stats)
                return;
 
@@ -706,13 +708,22 @@ static ssize_t total_trans_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
        struct thermal_cooling_device *cdev = to_cooling_device(dev);
-       struct cooling_dev_stats *stats = cdev->stats;
-       int ret;
+       struct cooling_dev_stats *stats;
+       int ret = 0;
+
+       mutex_lock(&cdev->lock);
+
+       stats = cdev->stats;
+       if (!stats)
+               goto unlock;
 
        spin_lock(&stats->lock);
        ret = sprintf(buf, "%u\n", stats->total_trans);
        spin_unlock(&stats->lock);
 
+unlock:
+       mutex_unlock(&cdev->lock);
+
        return ret;
 }
 
@@ -721,11 +732,18 @@ time_in_state_ms_show(struct device *dev, struct device_attribute *attr,
                      char *buf)
 {
        struct thermal_cooling_device *cdev = to_cooling_device(dev);
-       struct cooling_dev_stats *stats = cdev->stats;
+       struct cooling_dev_stats *stats;
        ssize_t len = 0;
        int i;
 
+       mutex_lock(&cdev->lock);
+
+       stats = cdev->stats;
+       if (!stats)
+               goto unlock;
+
        spin_lock(&stats->lock);
+
        update_time_in_state(stats);
 
        for (i = 0; i <= cdev->max_state; i++) {
@@ -734,6 +752,9 @@ time_in_state_ms_show(struct device *dev, struct device_attribute *attr,
        }
        spin_unlock(&stats->lock);
 
+unlock:
+       mutex_unlock(&cdev->lock);
+
        return len;
 }
 
@@ -742,8 +763,16 @@ reset_store(struct device *dev, struct device_attribute *attr, const char *buf,
            size_t count)
 {
        struct thermal_cooling_device *cdev = to_cooling_device(dev);
-       struct cooling_dev_stats *stats = cdev->stats;
-       int i, states = cdev->max_state + 1;
+       struct cooling_dev_stats *stats;
+       int i, states;
+
+       mutex_lock(&cdev->lock);
+
+       stats = cdev->stats;
+       if (!stats)
+               goto unlock;
+
+       states = cdev->max_state + 1;
 
        spin_lock(&stats->lock);
 
@@ -757,6 +786,9 @@ reset_store(struct device *dev, struct device_attribute *attr, const char *buf,
 
        spin_unlock(&stats->lock);
 
+unlock:
+       mutex_unlock(&cdev->lock);
+
        return count;
 }
 
@@ -764,10 +796,18 @@ static ssize_t trans_table_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
        struct thermal_cooling_device *cdev = to_cooling_device(dev);
-       struct cooling_dev_stats *stats = cdev->stats;
+       struct cooling_dev_stats *stats;
        ssize_t len = 0;
        int i, j;
 
+       mutex_lock(&cdev->lock);
+
+       stats = cdev->stats;
+       if (!stats) {
+               len = -ENODATA;
+               goto unlock;
+       }
+
        len += snprintf(buf + len, PAGE_SIZE - len, " From  :    To\n");
        len += snprintf(buf + len, PAGE_SIZE - len, "       : ");
        for (i = 0; i <= cdev->max_state; i++) {
@@ -775,8 +815,10 @@ static ssize_t trans_table_show(struct device *dev,
                        break;
                len += snprintf(buf + len, PAGE_SIZE - len, "state%2u  ", i);
        }
-       if (len >= PAGE_SIZE)
-               return PAGE_SIZE;
+       if (len >= PAGE_SIZE) {
+               len = PAGE_SIZE;
+               goto unlock;
+       }
 
        len += snprintf(buf + len, PAGE_SIZE - len, "\n");
 
@@ -799,8 +841,12 @@ static ssize_t trans_table_show(struct device *dev,
 
        if (len >= PAGE_SIZE) {
                pr_warn_once("Thermal transition table exceeds PAGE_SIZE. Disabling\n");
-               return -EFBIG;
+               len = -EFBIG;
        }
+
+unlock:
+       mutex_unlock(&cdev->lock);
+
        return len;
 }
 
@@ -879,6 +925,14 @@ void thermal_cooling_device_destroy_sysfs(struct thermal_cooling_device *cdev)
        cooling_device_stats_destroy(cdev);
 }
 
+void thermal_cooling_device_stats_reinit(struct thermal_cooling_device *cdev)
+{
+       lockdep_assert_held(&cdev->lock);
+
+       cooling_device_stats_destroy(cdev);
+       cooling_device_stats_setup(cdev);
+}
+
 /* these helper will be used only at the time of bindig */
 ssize_t
 trip_point_show(struct device *dev, struct device_attribute *attr, char *buf)
index 4339e706cc3a12ad455b01ab4a0e99898c06c9aa..f92ad71ef9831fa3611134c764af3af68b1c4582 100644 (file)
@@ -942,7 +942,8 @@ static void margining_port_remove(struct tb_port *port)
 
        snprintf(dir_name, sizeof(dir_name), "port%d", port->port);
        parent = debugfs_lookup(dir_name, port->sw->debugfs_dir);
-       debugfs_remove_recursive(debugfs_lookup("margining", parent));
+       if (parent)
+               debugfs_remove_recursive(debugfs_lookup("margining", parent));
 
        kfree(port->usb4->margining);
        port->usb4->margining = NULL;
@@ -967,19 +968,18 @@ static void margining_switch_init(struct tb_switch *sw)
 
 static void margining_switch_remove(struct tb_switch *sw)
 {
+       struct tb_port *upstream, *downstream;
        struct tb_switch *parent_sw;
-       struct tb_port *downstream;
        u64 route = tb_route(sw);
 
        if (!route)
                return;
 
-       /*
-        * Upstream is removed with the router itself but we need to
-        * remove the downstream port margining directory.
-        */
+       upstream = tb_upstream_port(sw);
        parent_sw = tb_switch_parent(sw);
        downstream = tb_port_at(route, parent_sw);
+
+       margining_port_remove(upstream);
        margining_port_remove(downstream);
 }
 
index 4dce2edd86ea0f9a4d223f2f6047e8a7db03d42e..cfebec107f3fc8a437718c376045cd4d8d734171 100644 (file)
@@ -46,7 +46,7 @@
 #define QUIRK_AUTO_CLEAR_INT   BIT(0)
 #define QUIRK_E2E              BIT(1)
 
-static int ring_interrupt_index(struct tb_ring *ring)
+static int ring_interrupt_index(const struct tb_ring *ring)
 {
        int bit = ring->hop;
        if (!ring->is_tx)
@@ -63,13 +63,14 @@ static void ring_interrupt_active(struct tb_ring *ring, bool active)
 {
        int reg = REG_RING_INTERRUPT_BASE +
                  ring_interrupt_index(ring) / 32 * 4;
-       int bit = ring_interrupt_index(ring) & 31;
-       int mask = 1 << bit;
+       int interrupt_bit = ring_interrupt_index(ring) & 31;
+       int mask = 1 << interrupt_bit;
        u32 old, new;
 
        if (ring->irq > 0) {
                u32 step, shift, ivr, misc;
                void __iomem *ivr_base;
+               int auto_clear_bit;
                int index;
 
                if (ring->is_tx)
@@ -77,18 +78,25 @@ static void ring_interrupt_active(struct tb_ring *ring, bool active)
                else
                        index = ring->hop + ring->nhi->hop_count;
 
-               if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT) {
-                       /*
-                        * Ask the hardware to clear interrupt status
-                        * bits automatically since we already know
-                        * which interrupt was triggered.
-                        */
-                       misc = ioread32(ring->nhi->iobase + REG_DMA_MISC);
-                       if (!(misc & REG_DMA_MISC_INT_AUTO_CLEAR)) {
-                               misc |= REG_DMA_MISC_INT_AUTO_CLEAR;
-                               iowrite32(misc, ring->nhi->iobase + REG_DMA_MISC);
-                       }
-               }
+               /*
+                * Intel routers support a bit that isn't part of
+                * the USB4 spec to ask the hardware to clear
+                * interrupt status bits automatically since
+                * we already know which interrupt was triggered.
+                *
+                * Other routers explicitly disable auto-clear
+                * to prevent conditions that may occur where two
+                * MSIX interrupts are simultaneously active and
+                * reading the register clears both of them.
+                */
+               misc = ioread32(ring->nhi->iobase + REG_DMA_MISC);
+               if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT)
+                       auto_clear_bit = REG_DMA_MISC_INT_AUTO_CLEAR;
+               else
+                       auto_clear_bit = REG_DMA_MISC_DISABLE_AUTO_CLEAR;
+               if (!(misc & auto_clear_bit))
+                       iowrite32(misc | auto_clear_bit,
+                                 ring->nhi->iobase + REG_DMA_MISC);
 
                ivr_base = ring->nhi->iobase + REG_INT_VEC_ALLOC_BASE;
                step = index / REG_INT_VEC_ALLOC_REGS * REG_INT_VEC_ALLOC_BITS;
@@ -108,7 +116,7 @@ static void ring_interrupt_active(struct tb_ring *ring, bool active)
 
        dev_dbg(&ring->nhi->pdev->dev,
                "%s interrupt at register %#x bit %d (%#x -> %#x)\n",
-               active ? "enabling" : "disabling", reg, bit, old, new);
+               active ? "enabling" : "disabling", reg, interrupt_bit, old, new);
 
        if (new == old)
                dev_WARN(&ring->nhi->pdev->dev,
@@ -393,14 +401,17 @@ EXPORT_SYMBOL_GPL(tb_ring_poll_complete);
 
 static void ring_clear_msix(const struct tb_ring *ring)
 {
+       int bit;
+
        if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT)
                return;
 
+       bit = ring_interrupt_index(ring) & 31;
        if (ring->is_tx)
-               ioread32(ring->nhi->iobase + REG_RING_NOTIFY_BASE);
+               iowrite32(BIT(bit), ring->nhi->iobase + REG_RING_INT_CLEAR);
        else
-               ioread32(ring->nhi->iobase + REG_RING_NOTIFY_BASE +
-                        4 * (ring->nhi->hop_count / 32));
+               iowrite32(BIT(bit), ring->nhi->iobase + REG_RING_INT_CLEAR +
+                         4 * (ring->nhi->hop_count / 32));
 }
 
 static irqreturn_t ring_msix(int irq, void *data)
index 0d4970dcef842f7c8841ad933ef36940c8d5ed24..faef165a919ccda93a00fea018151210f68aec1b 100644 (file)
@@ -77,12 +77,13 @@ struct ring_desc {
 
 /*
  * three bitfields: tx, rx, rx overflow
- * Every bitfield contains one bit for every hop (REG_HOP_COUNT). Registers are
- * cleared on read. New interrupts are fired only after ALL registers have been
+ * Every bitfield contains one bit for every hop (REG_HOP_COUNT).
+ * New interrupts are fired only after ALL registers have been
  * read (even those containing only disabled rings).
  */
 #define REG_RING_NOTIFY_BASE   0x37800
 #define RING_NOTIFY_REG_COUNT(nhi) ((31 + 3 * nhi->hop_count) / 32)
+#define REG_RING_INT_CLEAR     0x37808
 
 /*
  * two bitfields: rx, tx
@@ -105,6 +106,7 @@ struct ring_desc {
 
 #define REG_DMA_MISC                   0x39864
 #define REG_DMA_MISC_INT_AUTO_CLEAR     BIT(2)
+#define REG_DMA_MISC_DISABLE_AUTO_CLEAR        BIT(17)
 
 #define REG_INMAIL_DATA                        0x39900
 
index b5f2ec79c4d6e53e20266aff1ee7c57d9008669f..1157b8869bcca1da217285202b74b53bea2bf703 100644 (file)
@@ -20,6 +20,25 @@ static void quirk_dp_credit_allocation(struct tb_switch *sw)
        }
 }
 
+static void quirk_clx_disable(struct tb_switch *sw)
+{
+       sw->quirks |= QUIRK_NO_CLX;
+       tb_sw_dbg(sw, "disabling CL states\n");
+}
+
+static void quirk_usb3_maximum_bandwidth(struct tb_switch *sw)
+{
+       struct tb_port *port;
+
+       tb_switch_for_each_port(sw, port) {
+               if (!tb_port_is_usb3_down(port))
+                       continue;
+               port->max_bw = 16376;
+               tb_port_dbg(port, "USB3 maximum bandwidth limited to %u Mb/s\n",
+                           port->max_bw);
+       }
+}
+
 struct tb_quirk {
        u16 hw_vendor_id;
        u16 hw_device_id;
@@ -37,6 +56,31 @@ static const struct tb_quirk tb_quirks[] = {
         * DP buffers.
         */
        { 0x8087, 0x0b26, 0x0000, 0x0000, quirk_dp_credit_allocation },
+       /*
+        * Limit the maximum USB3 bandwidth for the following Intel USB4
+        * host routers due to a hardware issue.
+        */
+       { 0x8087, PCI_DEVICE_ID_INTEL_ADL_NHI0, 0x0000, 0x0000,
+                 quirk_usb3_maximum_bandwidth },
+       { 0x8087, PCI_DEVICE_ID_INTEL_ADL_NHI1, 0x0000, 0x0000,
+                 quirk_usb3_maximum_bandwidth },
+       { 0x8087, PCI_DEVICE_ID_INTEL_RPL_NHI0, 0x0000, 0x0000,
+                 quirk_usb3_maximum_bandwidth },
+       { 0x8087, PCI_DEVICE_ID_INTEL_RPL_NHI1, 0x0000, 0x0000,
+                 quirk_usb3_maximum_bandwidth },
+       { 0x8087, PCI_DEVICE_ID_INTEL_MTL_M_NHI0, 0x0000, 0x0000,
+                 quirk_usb3_maximum_bandwidth },
+       { 0x8087, PCI_DEVICE_ID_INTEL_MTL_P_NHI0, 0x0000, 0x0000,
+                 quirk_usb3_maximum_bandwidth },
+       { 0x8087, PCI_DEVICE_ID_INTEL_MTL_P_NHI1, 0x0000, 0x0000,
+                 quirk_usb3_maximum_bandwidth },
+       /*
+        * CLx is not supported on AMD USB4 Yellow Carp and Pink Sardine platforms.
+        */
+       { 0x0438, 0x0208, 0x0000, 0x0000, quirk_clx_disable },
+       { 0x0438, 0x0209, 0x0000, 0x0000, quirk_clx_disable },
+       { 0x0438, 0x020a, 0x0000, 0x0000, quirk_clx_disable },
+       { 0x0438, 0x020b, 0x0000, 0x0000, quirk_clx_disable },
 };
 
 /**
index 56008eb91e2e448b9d584c318d6bc55c9af00a5b..9cc28197dbc45f7e6912ac43fc01d40fe5a80027 100644 (file)
@@ -187,6 +187,22 @@ static ssize_t nvm_authenticate_show(struct device *dev,
        return ret;
 }
 
+static void tb_retimer_set_inbound_sbtx(struct tb_port *port)
+{
+       int i;
+
+       for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++)
+               usb4_port_retimer_set_inbound_sbtx(port, i);
+}
+
+static void tb_retimer_unset_inbound_sbtx(struct tb_port *port)
+{
+       int i;
+
+       for (i = TB_MAX_RETIMER_INDEX; i >= 1; i--)
+               usb4_port_retimer_unset_inbound_sbtx(port, i);
+}
+
 static ssize_t nvm_authenticate_store(struct device *dev,
        struct device_attribute *attr, const char *buf, size_t count)
 {
@@ -213,6 +229,7 @@ static ssize_t nvm_authenticate_store(struct device *dev,
        rt->auth_status = 0;
 
        if (val) {
+               tb_retimer_set_inbound_sbtx(rt->port);
                if (val == AUTHENTICATE_ONLY) {
                        ret = tb_retimer_nvm_authenticate(rt, true);
                } else {
@@ -232,6 +249,7 @@ static ssize_t nvm_authenticate_store(struct device *dev,
        }
 
 exit_unlock:
+       tb_retimer_unset_inbound_sbtx(rt->port);
        mutex_unlock(&rt->tb->lock);
 exit_rpm:
        pm_runtime_mark_last_busy(&rt->dev);
@@ -440,8 +458,7 @@ int tb_retimer_scan(struct tb_port *port, bool add)
         * Enable sideband channel for each retimer. We can do this
         * regardless whether there is device connected or not.
         */
-       for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++)
-               usb4_port_retimer_set_inbound_sbtx(port, i);
+       tb_retimer_set_inbound_sbtx(port);
 
        /*
         * Before doing anything else, read the authentication status.
@@ -464,6 +481,8 @@ int tb_retimer_scan(struct tb_port *port, bool add)
                        break;
        }
 
+       tb_retimer_unset_inbound_sbtx(port);
+
        if (!last_idx)
                return 0;
 
index 5185cf3e4d978f0216ea8f8cd3327c3fc0be32ef..f37a4320f10a528393b8a10f320103b8565b124d 100644 (file)
@@ -20,6 +20,7 @@ enum usb4_sb_opcode {
        USB4_SB_OPCODE_ROUTER_OFFLINE = 0x4e45534c,             /* "LSEN" */
        USB4_SB_OPCODE_ENUMERATE_RETIMERS = 0x4d554e45,         /* "ENUM" */
        USB4_SB_OPCODE_SET_INBOUND_SBTX = 0x5055534c,           /* "LSUP" */
+       USB4_SB_OPCODE_UNSET_INBOUND_SBTX = 0x50555355,         /* "USUP" */
        USB4_SB_OPCODE_QUERY_LAST_RETIMER = 0x5453414c,         /* "LAST" */
        USB4_SB_OPCODE_GET_NVM_SECTOR_SIZE = 0x53534e47,        /* "GNSS" */
        USB4_SB_OPCODE_NVM_SET_OFFSET = 0x53504f42,             /* "BOPS" */
index 3370e18ba05f9348c37ec526bbd7641f2673225b..da373ac38285c6a1b35c8ed035689306fc9c045c 100644 (file)
@@ -2968,8 +2968,6 @@ int tb_switch_add(struct tb_switch *sw)
                        dev_warn(&sw->dev, "reading DROM failed: %d\n", ret);
                tb_sw_dbg(sw, "uid: %#llx\n", sw->uid);
 
-               tb_check_quirks(sw);
-
                ret = tb_switch_set_uuid(sw);
                if (ret) {
                        dev_err(&sw->dev, "failed to set UUID\n");
@@ -2988,6 +2986,8 @@ int tb_switch_add(struct tb_switch *sw)
                        }
                }
 
+               tb_check_quirks(sw);
+
                tb_switch_default_link_ports(sw);
 
                ret = tb_switch_update_link_attributes(sw);
index cbb20a2773462ab892c2e4e242becbe3085dc0bf..275ff5219a3a3ae79a69b0548aab891bc1824aa1 100644 (file)
 #define NVM_MAX_SIZE           SZ_512K
 #define NVM_DATA_DWORDS                16
 
+/* Keep link controller awake during update */
+#define QUIRK_FORCE_POWER_LINK_CONTROLLER              BIT(0)
+/* Disable CLx if not supported */
+#define QUIRK_NO_CLX                                   BIT(1)
+
 /**
  * struct tb_nvm - Structure holding NVM information
  * @dev: Owner of the NVM
@@ -267,6 +272,8 @@ struct tb_bandwidth_group {
  * @group: Bandwidth allocation group the adapter is assigned to. Only
  *        used for DP IN adapters for now.
  * @group_list: The adapter is linked to the group's list of ports through this
+ * @max_bw: Maximum possible bandwidth through this adapter if set to
+ *         non-zero.
  *
  * In USB4 terminology this structure represents an adapter (protocol or
  * lane adapter).
@@ -294,6 +301,7 @@ struct tb_port {
        unsigned int dma_credits;
        struct tb_bandwidth_group *group;
        struct list_head group_list;
+       unsigned int max_bw;
 };
 
 /**
@@ -1019,6 +1027,9 @@ static inline bool tb_switch_is_clx_enabled(const struct tb_switch *sw,
  */
 static inline bool tb_switch_is_clx_supported(const struct tb_switch *sw)
 {
+       if (sw->quirks & QUIRK_NO_CLX)
+               return false;
+
        return tb_switch_is_usb4(sw) || tb_switch_is_titan_ridge(sw);
 }
 
@@ -1234,6 +1245,7 @@ int usb4_port_sw_margin(struct tb_port *port, unsigned int lanes, bool timing,
 int usb4_port_sw_margin_errors(struct tb_port *port, u32 *errors);
 
 int usb4_port_retimer_set_inbound_sbtx(struct tb_port *port, u8 index);
+int usb4_port_retimer_unset_inbound_sbtx(struct tb_port *port, u8 index);
 int usb4_port_retimer_read(struct tb_port *port, u8 index, u8 reg, void *buf,
                           u8 size);
 int usb4_port_retimer_write(struct tb_port *port, u8 index, u8 reg,
@@ -1291,9 +1303,6 @@ struct usb4_port *usb4_port_device_add(struct tb_port *port);
 void usb4_port_device_remove(struct usb4_port *usb4);
 int usb4_port_device_resume(struct usb4_port *usb4);
 
-/* Keep link controller awake during update */
-#define QUIRK_FORCE_POWER_LINK_CONTROLLER              BIT(0)
-
 void tb_check_quirks(struct tb_switch *sw);
 
 #ifdef CONFIG_ACPI
index 1e5e9c147a310da3627f38f11296d0345e7f529c..a0996cb2893c8693cfc08fd2e0bf71966b04a34a 100644 (file)
@@ -1578,6 +1578,20 @@ int usb4_port_retimer_set_inbound_sbtx(struct tb_port *port, u8 index)
                                    500);
 }
 
+/**
+ * usb4_port_retimer_unset_inbound_sbtx() - Disable sideband channel transactions
+ * @port: USB4 port
+ * @index: Retimer index
+ *
+ * Disables sideband channel transations on SBTX. The reverse of
+ * usb4_port_retimer_set_inbound_sbtx().
+ */
+int usb4_port_retimer_unset_inbound_sbtx(struct tb_port *port, u8 index)
+{
+       return usb4_port_retimer_op(port, index,
+                                   USB4_SB_OPCODE_UNSET_INBOUND_SBTX, 500);
+}
+
 /**
  * usb4_port_retimer_read() - Read from retimer sideband registers
  * @port: USB4 port
@@ -1868,6 +1882,15 @@ int usb4_port_retimer_nvm_read(struct tb_port *port, u8 index,
                                usb4_port_retimer_nvm_read_block, &info);
 }
 
+static inline unsigned int
+usb4_usb3_port_max_bandwidth(const struct tb_port *port, unsigned int bw)
+{
+       /* Take the possible bandwidth limitation into account */
+       if (port->max_bw)
+               return min(bw, port->max_bw);
+       return bw;
+}
+
 /**
  * usb4_usb3_port_max_link_rate() - Maximum support USB3 link rate
  * @port: USB3 adapter port
@@ -1889,7 +1912,9 @@ int usb4_usb3_port_max_link_rate(struct tb_port *port)
                return ret;
 
        lr = (val & ADP_USB3_CS_4_MSLR_MASK) >> ADP_USB3_CS_4_MSLR_SHIFT;
-       return lr == ADP_USB3_CS_4_MSLR_20G ? 20000 : 10000;
+       ret = lr == ADP_USB3_CS_4_MSLR_20G ? 20000 : 10000;
+
+       return usb4_usb3_port_max_bandwidth(port, ret);
 }
 
 /**
@@ -1916,7 +1941,9 @@ int usb4_usb3_port_actual_link_rate(struct tb_port *port)
                return 0;
 
        lr = val & ADP_USB3_CS_4_ALR_MASK;
-       return lr == ADP_USB3_CS_4_ALR_20G ? 20000 : 10000;
+       ret = lr == ADP_USB3_CS_4_ALR_20G ? 20000 : 10000;
+
+       return usb4_usb3_port_max_bandwidth(port, ret);
 }
 
 static int usb4_usb3_port_cm_request(struct tb_port *port, bool request)
@@ -2067,18 +2094,30 @@ static int usb4_usb3_port_write_allocated_bandwidth(struct tb_port *port,
                                                    int downstream_bw)
 {
        u32 val, ubw, dbw, scale;
-       int ret;
+       int ret, max_bw;
 
-       /* Read the used scale, hardware default is 0 */
-       ret = tb_port_read(port, &scale, TB_CFG_PORT,
-                          port->cap_adap + ADP_USB3_CS_3, 1);
+       /* Figure out suitable scale */
+       scale = 0;
+       max_bw = max(upstream_bw, downstream_bw);
+       while (scale < 64) {
+               if (mbps_to_usb3_bw(max_bw, scale) < 4096)
+                       break;
+               scale++;
+       }
+
+       if (WARN_ON(scale >= 64))
+               return -EINVAL;
+
+       ret = tb_port_write(port, &scale, TB_CFG_PORT,
+                           port->cap_adap + ADP_USB3_CS_3, 1);
        if (ret)
                return ret;
 
-       scale &= ADP_USB3_CS_3_SCALE_MASK;
        ubw = mbps_to_usb3_bw(upstream_bw, scale);
        dbw = mbps_to_usb3_bw(downstream_bw, scale);
 
+       tb_port_dbg(port, "scaled bandwidth %u/%u, scale %u\n", ubw, dbw, scale);
+
        ret = tb_port_read(port, &val, TB_CFG_PORT,
                           port->cap_adap + ADP_USB3_CS_2, 1);
        if (ret)
index 5bddb2f5e93185eca993595dd0c44f7cc7d1ec46..98764e740c07830495dc5d3532e08d3b40a9ee7b 100644 (file)
@@ -43,6 +43,7 @@ struct xencons_info {
        int irq;
        int vtermno;
        grant_ref_t gntref;
+       spinlock_t ring_lock;
 };
 
 static LIST_HEAD(xenconsoles);
@@ -89,12 +90,15 @@ static int __write_console(struct xencons_info *xencons,
        XENCONS_RING_IDX cons, prod;
        struct xencons_interface *intf = xencons->intf;
        int sent = 0;
+       unsigned long flags;
 
+       spin_lock_irqsave(&xencons->ring_lock, flags);
        cons = intf->out_cons;
        prod = intf->out_prod;
        mb();                   /* update queue values before going on */
 
        if ((prod - cons) > sizeof(intf->out)) {
+               spin_unlock_irqrestore(&xencons->ring_lock, flags);
                pr_err_once("xencons: Illegal ring page indices");
                return -EINVAL;
        }
@@ -104,6 +108,7 @@ static int __write_console(struct xencons_info *xencons,
 
        wmb();                  /* write ring before updating pointer */
        intf->out_prod = prod;
+       spin_unlock_irqrestore(&xencons->ring_lock, flags);
 
        if (sent)
                notify_daemon(xencons);
@@ -146,16 +151,19 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len)
        int recv = 0;
        struct xencons_info *xencons = vtermno_to_xencons(vtermno);
        unsigned int eoiflag = 0;
+       unsigned long flags;
 
        if (xencons == NULL)
                return -EINVAL;
        intf = xencons->intf;
 
+       spin_lock_irqsave(&xencons->ring_lock, flags);
        cons = intf->in_cons;
        prod = intf->in_prod;
        mb();                   /* get pointers before reading ring */
 
        if ((prod - cons) > sizeof(intf->in)) {
+               spin_unlock_irqrestore(&xencons->ring_lock, flags);
                pr_err_once("xencons: Illegal ring page indices");
                return -EINVAL;
        }
@@ -179,10 +187,13 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len)
                xencons->out_cons = intf->out_cons;
                xencons->out_cons_same = 0;
        }
+       if (!recv && xencons->out_cons_same++ > 1) {
+               eoiflag = XEN_EOI_FLAG_SPURIOUS;
+       }
+       spin_unlock_irqrestore(&xencons->ring_lock, flags);
+
        if (recv) {
                notify_daemon(xencons);
-       } else if (xencons->out_cons_same++ > 1) {
-               eoiflag = XEN_EOI_FLAG_SPURIOUS;
        }
 
        xen_irq_lateeoi(xencons->irq, eoiflag);
@@ -239,6 +250,7 @@ static int xen_hvm_console_init(void)
                info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL);
                if (!info)
                        return -ENOMEM;
+               spin_lock_init(&info->ring_lock);
        } else if (info->intf != NULL) {
                /* already configured */
                return 0;
@@ -275,6 +287,7 @@ err:
 
 static int xencons_info_pv_init(struct xencons_info *info, int vtermno)
 {
+       spin_lock_init(&info->ring_lock);
        info->evtchn = xen_start_info->console.domU.evtchn;
        /* GFN == MFN for PV guest */
        info->intf = gfn_to_virt(xen_start_info->console.domU.mfn);
@@ -325,6 +338,7 @@ static int xen_initial_domain_console_init(void)
                info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL);
                if (!info)
                        return -ENOMEM;
+               spin_lock_init(&info->ring_lock);
        }
 
        info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0, false);
@@ -482,6 +496,7 @@ static int xencons_probe(struct xenbus_device *dev,
        info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL);
        if (!info)
                return -ENOMEM;
+       spin_lock_init(&info->ring_lock);
        dev_set_drvdata(&dev->dev, info);
        info->xbdev = dev;
        info->vtermno = xenbus_devid_to_vtermno(devid);
index aa80de3a819478e83b20839bce704c615afcf9b4..678014253b7b2642147d5ffe5b6367d0727f1a59 100644 (file)
@@ -534,7 +534,7 @@ static int of_serdev_register_devices(struct serdev_controller *ctrl)
                if (!serdev)
                        continue;
 
-               serdev->dev.of_node = node;
+               device_set_node(&serdev->dev, of_fwnode_handle(node));
 
                err = serdev_device_add(serdev);
                if (err) {
index f8e99995eee911de69ceb5eb8d95dec876cb1acd..d94c3811a8f7af310528a36df2dd99fd28256c69 100644 (file)
@@ -106,8 +106,8 @@ static int serial8250_em_probe(struct platform_device *pdev)
        memset(&up, 0, sizeof(up));
        up.port.mapbase = regs->start;
        up.port.irq = irq;
-       up.port.type = PORT_UNKNOWN;
-       up.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_IOREMAP;
+       up.port.type = PORT_16750;
+       up.port.flags = UPF_FIXED_PORT | UPF_IOREMAP | UPF_FIXED_TYPE;
        up.port.dev = &pdev->dev;
        up.port.private_data = priv;
 
index 8aad15622a2e5c869b94dfec762f98185e1d785e..8adfaa183f778d4a6f8cf21098025b2dac886691 100644 (file)
@@ -34,7 +34,7 @@ int fsl8250_handle_irq(struct uart_port *port)
 
        iir = port->serial_in(port, UART_IIR);
        if (iir & UART_IIR_NO_INT) {
-               spin_unlock(&up->port.lock);
+               spin_unlock_irqrestore(&up->port.lock, flags);
                return 0;
        }
 
@@ -42,7 +42,7 @@ int fsl8250_handle_irq(struct uart_port *port)
        if (unlikely(up->lsr_saved_flags & UART_LSR_BI)) {
                up->lsr_saved_flags &= ~UART_LSR_BI;
                port->serial_in(port, UART_RX);
-               spin_unlock(&up->port.lock);
+               spin_unlock_irqrestore(&up->port.lock, flags);
                return 1;
        }
 
index fa43df05342bd5f72741c93172aa16659039c206..3ba9c8b93ae6c56510af4ee3bb07ec6e3e0bd6f3 100644 (file)
@@ -1903,6 +1903,17 @@ EXPORT_SYMBOL_GPL(serial8250_modem_status);
 static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir)
 {
        switch (iir & 0x3f) {
+       case UART_IIR_THRI:
+               /*
+                * Postpone DMA or not decision to IIR_RDI or IIR_RX_TIMEOUT
+                * because it's impossible to do an informed decision about
+                * that with IIR_THRI.
+                *
+                * This also fixes one known DMA Rx corruption issue where
+                * DR is asserted but DMA Rx only gets a corrupted zero byte
+                * (too early DR?).
+                */
+               return false;
        case UART_IIR_RDI:
                if (!up->dma->rx_running)
                        break;
index 978dc196c29bea32ca85477337667f2449ec4fde..5313aa31930f4ec4ea8f798a03f8c08066b86b36 100644 (file)
@@ -257,8 +257,9 @@ config SERIAL_8250_ASPEED_VUART
        tristate "Aspeed Virtual UART"
        depends on SERIAL_8250
        depends on OF
-       depends on REGMAP && MFD_SYSCON
+       depends on MFD_SYSCON
        depends on ARCH_ASPEED || COMPILE_TEST
+       select REGMAP
        help
          If you want to use the virtual UART (VUART) device on Aspeed
          BMC platforms, enable this option. This enables the 16550A-
@@ -299,7 +300,6 @@ config SERIAL_8250_PCI1XXXX
        tristate "Microchip 8250 based serial port"
        depends on SERIAL_8250 && PCI
        select SERIAL_8250_PCILIB
-       default SERIAL_8250
        help
         Select this option if you have a setup with Microchip PCIe
         Switch with serial port enabled and wish to enable 8250
index 625358f44419743ffbc3d1663d1aae455df119b6..0072892ca7fc9df89a104270d1e35924cbe00746 100644 (file)
@@ -1313,7 +1313,7 @@ config SERIAL_FSL_LPUART
 
 config SERIAL_FSL_LPUART_CONSOLE
        bool "Console on Freescale lpuart serial port"
-       depends on SERIAL_FSL_LPUART
+       depends on SERIAL_FSL_LPUART=y
        select SERIAL_CORE_CONSOLE
        select SERIAL_EARLYCON
        help
index e945f41b93d4384b573c0ffe279da5c50c187ba1..074bfed57fc9e26c9c6db931ee89468d77f37a19 100644 (file)
@@ -858,11 +858,17 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port)
                        struct lpuart_port, port);
        unsigned long stat = lpuart32_read(port, UARTSTAT);
        unsigned long sfifo = lpuart32_read(port, UARTFIFO);
+       unsigned long ctrl = lpuart32_read(port, UARTCTRL);
 
        if (sport->dma_tx_in_progress)
                return 0;
 
-       if (stat & UARTSTAT_TC && sfifo & UARTFIFO_TXEMPT)
+       /*
+        * LPUART Transmission Complete Flag may never be set while queuing a break
+        * character, so avoid checking for transmission complete when UARTCTRL_SBK
+        * is asserted.
+        */
+       if ((stat & UARTSTAT_TC && sfifo & UARTFIFO_TXEMPT) || ctrl & UARTCTRL_SBK)
                return TIOCSER_TEMT;
 
        return 0;
@@ -1354,6 +1360,7 @@ static void lpuart_dma_rx_free(struct uart_port *port)
        struct dma_chan *chan = sport->dma_rx_chan;
 
        dmaengine_terminate_sync(chan);
+       del_timer_sync(&sport->lpuart_timer);
        dma_unmap_sg(chan->device->dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE);
        kfree(sport->rx_ring.buf);
        sport->rx_ring.tail = 0;
@@ -1813,7 +1820,6 @@ static int lpuart32_startup(struct uart_port *port)
 static void lpuart_dma_shutdown(struct lpuart_port *sport)
 {
        if (sport->lpuart_dma_rx_use) {
-               del_timer_sync(&sport->lpuart_timer);
                lpuart_dma_rx_free(&sport->port);
                sport->lpuart_dma_rx_use = false;
        }
@@ -1973,10 +1979,8 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
         * Since timer function acqures sport->port.lock, need to stop before
         * acquring same lock because otherwise del_timer_sync() can deadlock.
         */
-       if (old && sport->lpuart_dma_rx_use) {
-               del_timer_sync(&sport->lpuart_timer);
+       if (old && sport->lpuart_dma_rx_use)
                lpuart_dma_rx_free(&sport->port);
-       }
 
        spin_lock_irqsave(&sport->port.lock, flags);
 
@@ -2210,10 +2214,8 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
         * Since timer function acqures sport->port.lock, need to stop before
         * acquring same lock because otherwise del_timer_sync() can deadlock.
         */
-       if (old && sport->lpuart_dma_rx_use) {
-               del_timer_sync(&sport->lpuart_timer);
+       if (old && sport->lpuart_dma_rx_use)
                lpuart_dma_rx_free(&sport->port);
-       }
 
        spin_lock_irqsave(&sport->port.lock, flags);
 
@@ -2240,9 +2242,15 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
        /* update the per-port timeout */
        uart_update_timeout(port, termios->c_cflag, baud);
 
-       /* wait transmit engin complete */
-       lpuart32_write(&sport->port, 0, UARTMODIR);
-       lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC);
+       /*
+        * LPUART Transmission Complete Flag may never be set while queuing a break
+        * character, so skip waiting for transmission complete when UARTCTRL_SBK is
+        * asserted.
+        */
+       if (!(old_ctrl & UARTCTRL_SBK)) {
+               lpuart32_write(&sport->port, 0, UARTMODIR);
+               lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC);
+       }
 
        /* disable transmit and receive */
        lpuart32_write(&sport->port, old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE),
@@ -2940,7 +2948,7 @@ static bool lpuart_uport_is_active(struct lpuart_port *sport)
        tty = tty_port_tty_get(port);
        if (tty) {
                tty_dev = tty->dev;
-               may_wake = device_may_wakeup(tty_dev);
+               may_wake = tty_dev && device_may_wakeup(tty_dev);
                tty_kref_put(tty);
        }
 
@@ -3014,7 +3022,6 @@ static int lpuart_suspend(struct device *dev)
                         * cannot resume as expected, hence gracefully release the
                         * Rx DMA path before suspend and start Rx DMA path on resume.
                         */
-                       del_timer_sync(&sport->lpuart_timer);
                        lpuart_dma_rx_free(&sport->port);
 
                        /* Disable Rx DMA to use UART port as wakeup source */
index d69592e5e2ec581743d1c155c8ad469453a701d4..28fbc927a546574e6d4559063034f629caffd9ed 100644 (file)
@@ -596,7 +596,7 @@ static void qcom_geni_serial_stop_tx_dma(struct uart_port *uport)
        if (!qcom_geni_serial_main_active(uport))
                return;
 
-       if (port->rx_dma_addr) {
+       if (port->tx_dma_addr) {
                geni_se_tx_dma_unprep(&port->se, port->tx_dma_addr,
                                      port->tx_remaining);
                port->tx_dma_addr = 0;
@@ -631,9 +631,8 @@ static void qcom_geni_serial_start_tx_dma(struct uart_port *uport)
        if (port->tx_dma_addr)
                return;
 
-       xmit_size = uart_circ_chars_pending(xmit);
-       if (xmit_size < WAKEUP_CHARS)
-               uart_write_wakeup(uport);
+       if (uart_circ_empty(xmit))
+               return;
 
        xmit_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
 
@@ -1070,6 +1069,10 @@ static int setup_fifos(struct qcom_geni_serial_port *port)
 static void qcom_geni_serial_shutdown(struct uart_port *uport)
 {
        disable_irq(uport->irq);
+
+       if (uart_console(uport))
+               return;
+
        qcom_geni_serial_stop_tx(uport);
        qcom_geni_serial_stop_rx(uport);
 }
index 29c94be0915962b2184829be6d83418bc4fbcce6..abad091baeeaef273d3e923bd168f51a1f9435ac 100644 (file)
@@ -1666,9 +1666,9 @@ MODULE_ALIAS("spi:sc16is7xx");
 #endif
 
 #ifdef CONFIG_SERIAL_SC16IS7XX_I2C
-static int sc16is7xx_i2c_probe(struct i2c_client *i2c,
-                              const struct i2c_device_id *id)
+static int sc16is7xx_i2c_probe(struct i2c_client *i2c)
 {
+       const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
        const struct sc16is7xx_devtype *devtype;
        struct regmap *regmap;
 
@@ -1709,7 +1709,7 @@ static struct i2c_driver sc16is7xx_i2c_uart_driver = {
                .name           = SC16IS7XX_NAME,
                .of_match_table = sc16is7xx_dt_ids,
        },
-       .probe          = sc16is7xx_i2c_probe,
+       .probe_new      = sc16is7xx_i2c_probe,
        .remove         = sc16is7xx_i2c_remove,
        .id_table       = sc16is7xx_i2c_id_table,
 };
index 7bd0807209299bba3f6c7af65a8d7f492d71e7de..caa09a0c48f45d0c72d99e8d22b04aa30b2af317 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/ioport.h>
 #include <linux/ktime.h>
 #include <linux/major.h>
+#include <linux/minmax.h>
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/of.h>
@@ -2864,6 +2865,13 @@ static int sci_init_single(struct platform_device *dev,
                        sci_port->irqs[i] = platform_get_irq(dev, i);
        }
 
+       /*
+        * The fourth interrupt on SCI port is transmit end interrupt, so
+        * shuffle the interrupts.
+        */
+       if (p->type == PORT_SCI)
+               swap(sci_port->irqs[SCIx_BRI_IRQ], sci_port->irqs[SCIx_TEI_IRQ]);
+
        /* The SCI generates several interrupts. They can be muxed together or
         * connected to different interrupt lines. In the muxed case only one
         * interrupt resource is specified as there is only one interrupt ID.
@@ -2929,7 +2937,7 @@ static int sci_init_single(struct platform_device *dev,
        port->flags             = UPF_FIXED_PORT | UPF_BOOT_AUTOCONF | p->flags;
        port->fifosize          = sci_port->params->fifosize;
 
-       if (port->type == PORT_SCI) {
+       if (port->type == PORT_SCI && !dev->dev.of_node) {
                if (sci_port->reg_size >= 0x20)
                        port->regshift = 2;
                else
index 57a5c23b51d47429c4c1d2d5a7a80d16beb2b75b..3c2ea9c098f7c4b36f1687f1b4834fe7de0a3e28 100644 (file)
@@ -4545,6 +4545,9 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op)
        int c;
        unsigned int vpitch = op->op == KD_FONT_OP_GET_TALL ? op->height : 32;
 
+       if (vpitch > max_font_height)
+               return -EINVAL;
+
        if (op->data) {
                font.data = kvmalloc(max_font_size, GFP_KERNEL);
                if (!font.data)
index 172d25fef740d354a73f156acdbc37a1febb9b00..70b112038792aed022a9d3441ca862e3e42fdff3 100644 (file)
@@ -1409,13 +1409,6 @@ static int ufshcd_devfreq_target(struct device *dev,
        struct ufs_clk_info *clki;
        unsigned long irq_flags;
 
-       /*
-        * Skip devfreq if UFS initialization is not finished.
-        * Otherwise ufs could be in a inconsistent state.
-        */
-       if (!smp_load_acquire(&hba->logical_unit_scan_finished))
-               return 0;
-
        if (!ufshcd_is_clkscaling_supported(hba))
                return -EINVAL;
 
@@ -1500,7 +1493,7 @@ start_window:
        scaling->window_start_t = curr_t;
        scaling->tot_busy_t = 0;
 
-       if (hba->outstanding_reqs) {
+       if (scaling->active_reqs) {
                scaling->busy_start_t = curr_t;
                scaling->is_busy_started = true;
        } else {
@@ -2118,7 +2111,7 @@ static void ufshcd_clk_scaling_update_busy(struct ufs_hba *hba)
 
        spin_lock_irqsave(hba->host->host_lock, flags);
        hba->clk_scaling.active_reqs--;
-       if (!hba->outstanding_reqs && scaling->is_busy_started) {
+       if (!scaling->active_reqs && scaling->is_busy_started) {
                scaling->tot_busy_t += ktime_to_us(ktime_sub(ktime_get(),
                                        scaling->busy_start_t));
                scaling->busy_start_t = 0;
@@ -8399,6 +8392,22 @@ static int ufshcd_add_lus(struct ufs_hba *hba)
        if (ret)
                goto out;
 
+       /* Initialize devfreq after UFS device is detected */
+       if (ufshcd_is_clkscaling_supported(hba)) {
+               memcpy(&hba->clk_scaling.saved_pwr_info.info,
+                       &hba->pwr_info,
+                       sizeof(struct ufs_pa_layer_attr));
+               hba->clk_scaling.saved_pwr_info.is_valid = true;
+               hba->clk_scaling.is_allowed = true;
+
+               ret = ufshcd_devfreq_init(hba);
+               if (ret)
+                       goto out;
+
+               hba->clk_scaling.is_enabled = true;
+               ufshcd_init_clk_scaling_sysfs(hba);
+       }
+
        ufs_bsg_probe(hba);
        ufshpb_init(hba);
        scsi_scan_host(hba->host);
@@ -8670,12 +8679,6 @@ out:
        if (ret) {
                pm_runtime_put_sync(hba->dev);
                ufshcd_hba_exit(hba);
-       } else {
-               /*
-                * Make sure that when reader code sees UFS initialization has finished,
-                * all initialization steps have really been executed.
-                */
-               smp_store_release(&hba->logical_unit_scan_finished, true);
        }
 }
 
@@ -10316,30 +10319,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
         */
        ufshcd_set_ufs_dev_active(hba);
 
-       /* Initialize devfreq */
-       if (ufshcd_is_clkscaling_supported(hba)) {
-               memcpy(&hba->clk_scaling.saved_pwr_info.info,
-                       &hba->pwr_info,
-                       sizeof(struct ufs_pa_layer_attr));
-               hba->clk_scaling.saved_pwr_info.is_valid = true;
-               hba->clk_scaling.is_allowed = true;
-
-               err = ufshcd_devfreq_init(hba);
-               if (err)
-                       goto rpm_put_sync;
-
-               hba->clk_scaling.is_enabled = true;
-               ufshcd_init_clk_scaling_sysfs(hba);
-       }
-
        async_schedule(ufshcd_async_scan, hba);
        ufs_sysfs_add_nodes(hba->dev);
 
        device_enable_async_suspend(dev);
        return 0;
 
-rpm_put_sync:
-       pm_runtime_put_sync(dev);
 free_tmf_queue:
        blk_mq_destroy_queue(hba->tmf_queue);
        blk_put_queue(hba->tmf_queue);
@@ -10512,4 +10497,5 @@ module_exit(ufshcd_core_exit);
 MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>");
 MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>");
 MODULE_DESCRIPTION("Generic UFS host controller driver Core");
+MODULE_SOFTDEP("pre: governor_simpleondemand");
 MODULE_LICENSE("GPL");
index 34fc453f3eb1f23c39bebb6695e12641de95edf1..a02cd866e2f8a0940d1a036e2b3623815619c8f3 100644 (file)
@@ -1177,7 +1177,7 @@ static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba,
                        err = ufs_qcom_clk_scale_down_post_change(hba);
 
 
-               if (err || !dev_req_params) {
+               if (err) {
                        ufshcd_uic_hibern8_exit(hba);
                        return err;
                }
@@ -1451,8 +1451,8 @@ static int ufs_qcom_mcq_config_resource(struct ufs_hba *hba)
                if (IS_ERR(res->base)) {
                        dev_err(hba->dev, "Failed to map res %s, err=%d\n",
                                         res->name, (int)PTR_ERR(res->base));
-                       res->base = NULL;
                        ret = PTR_ERR(res->base);
+                       res->base = NULL;
                        return ret;
                }
        }
@@ -1466,7 +1466,7 @@ static int ufs_qcom_mcq_config_resource(struct ufs_hba *hba)
        /* Explicitly allocate MCQ resource from ufs_mem */
        res_mcq = devm_kzalloc(hba->dev, sizeof(*res_mcq), GFP_KERNEL);
        if (!res_mcq)
-               return ret;
+               return -ENOMEM;
 
        res_mcq->start = res_mem->start +
                         MCQ_SQATTR_OFFSET(hba->mcq_capabilities);
@@ -1478,7 +1478,7 @@ static int ufs_qcom_mcq_config_resource(struct ufs_hba *hba)
        if (ret) {
                dev_err(hba->dev, "Failed to insert MCQ resource, err=%d\n",
                        ret);
-               goto insert_res_err;
+               return ret;
        }
 
        res->base = devm_ioremap_resource(hba->dev, res_mcq);
@@ -1495,8 +1495,6 @@ out:
 ioremap_err:
        res->base = NULL;
        remove_resource(res_mcq);
-insert_res_err:
-       devm_kfree(hba->dev, res_mcq);
        return ret;
 }
 
index deeea618ba33beccc840169a2ae85d1f6a8445d8..1f6320d98a76ba37b03e928c9ae965c9d5a01272 100644 (file)
@@ -60,6 +60,11 @@ static struct pci_dev *cdns3_get_second_fun(struct pci_dev *pdev)
                        return NULL;
        }
 
+       if (func->devfn != PCI_DEV_FN_HOST_DEVICE &&
+           func->devfn != PCI_DEV_FN_OTG) {
+               return NULL;
+       }
+
        return func;
 }
 
index 9b8325f824992ad7829a12bb880304dcffe0e024..f317d3c84781082d00d27f13481a5f759e7d1515 100644 (file)
@@ -403,20 +403,6 @@ static int cdnsp_ep0_std_request(struct cdnsp_device *pdev,
        case USB_REQ_SET_ISOCH_DELAY:
                ret = cdnsp_ep0_set_isoch_delay(pdev, ctrl);
                break;
-       case USB_REQ_SET_INTERFACE:
-               /*
-                * Add request into pending list to block sending status stage
-                * by libcomposite.
-                */
-               list_add_tail(&pdev->ep0_preq.list,
-                             &pdev->ep0_preq.pep->pending_list);
-
-               ret = cdnsp_ep0_delegate_req(pdev, ctrl);
-               if (ret == -EBUSY)
-                       ret = 0;
-
-               list_del(&pdev->ep0_preq.list);
-               break;
        default:
                ret = cdnsp_ep0_delegate_req(pdev, ctrl);
                break;
@@ -428,7 +414,7 @@ static int cdnsp_ep0_std_request(struct cdnsp_device *pdev,
 void cdnsp_setup_analyze(struct cdnsp_device *pdev)
 {
        struct usb_ctrlrequest *ctrl = &pdev->setup;
-       int ret = 0;
+       int ret = -EINVAL;
        u16 len;
 
        trace_cdnsp_ctrl_req(ctrl);
@@ -438,7 +424,6 @@ void cdnsp_setup_analyze(struct cdnsp_device *pdev)
 
        if (pdev->gadget.state == USB_STATE_NOTATTACHED) {
                dev_err(pdev->dev, "ERR: Setup detected in unattached state\n");
-               ret = -EINVAL;
                goto out;
        }
 
@@ -474,9 +459,6 @@ void cdnsp_setup_analyze(struct cdnsp_device *pdev)
        else
                ret = cdnsp_ep0_delegate_req(pdev, ctrl);
 
-       if (!len)
-               pdev->ep0_stage = CDNSP_STATUS_STAGE;
-
        if (ret == USB_GADGET_DELAYED_STATUS) {
                trace_cdnsp_ep0_status_stage("delayed");
                return;
@@ -484,6 +466,6 @@ void cdnsp_setup_analyze(struct cdnsp_device *pdev)
 out:
        if (ret < 0)
                cdnsp_ep0_stall(pdev);
-       else if (pdev->ep0_stage == CDNSP_STATUS_STAGE)
+       else if (!len && pdev->ep0_stage != CDNSP_STATUS_STAGE)
                cdnsp_status_stage(pdev);
 }
index efd54ed918b9701e6f765408f298391219ffca3e..7b151f5af3ccb82ceb37c0a71a7c63da677d3d7b 100644 (file)
 #define PLAT_DRIVER_NAME       "cdns-usbssp"
 
 #define CDNS_VENDOR_ID         0x17cd
-#define CDNS_DEVICE_ID         0x0100
+#define CDNS_DEVICE_ID         0x0200
+#define CDNS_DRD_ID            0x0100
 #define CDNS_DRD_IF            (PCI_CLASS_SERIAL_USB << 8 | 0x80)
 
 static struct pci_dev *cdnsp_get_second_fun(struct pci_dev *pdev)
 {
-       struct pci_dev *func;
-
        /*
         * Gets the second function.
-        * It's little tricky, but this platform has two function.
-        * The fist keeps resources for Host/Device while the second
-        * keeps resources for DRD/OTG.
+        * Platform has two function. The fist keeps resources for
+        * Host/Device while the secon keeps resources for DRD/OTG.
         */
-       func = pci_get_device(pdev->vendor, pdev->device, NULL);
-       if (!func)
-               return NULL;
+       if (pdev->device == CDNS_DEVICE_ID)
+               return  pci_get_device(pdev->vendor, CDNS_DRD_ID, NULL);
+       else if (pdev->device == CDNS_DRD_ID)
+               return pci_get_device(pdev->vendor, CDNS_DEVICE_ID, NULL);
 
-       if (func->devfn == pdev->devfn) {
-               func = pci_get_device(pdev->vendor, pdev->device, func);
-               if (!func)
-                       return NULL;
-       }
-
-       return func;
+       return NULL;
 }
 
 static int cdnsp_pci_probe(struct pci_dev *pdev,
@@ -230,6 +223,8 @@ static const struct pci_device_id cdnsp_pci_ids[] = {
          PCI_CLASS_SERIAL_USB_DEVICE, PCI_ANY_ID },
        { PCI_VENDOR_ID_CDNS, CDNS_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,
          CDNS_DRD_IF, PCI_ANY_ID },
+       { PCI_VENDOR_ID_CDNS, CDNS_DRD_ID, PCI_ANY_ID, PCI_ANY_ID,
+         CDNS_DRD_IF, PCI_ANY_ID },
        { 0, }
 };
 
index 005c67cb3afb72cadc171d73cc5c25887a7939b3..f210b7489fd5b8ff825905da38c87674ce5a87a0 100644 (file)
@@ -208,6 +208,7 @@ struct hw_bank {
  * @in_lpm: if the core in low power mode
  * @wakeup_int: if wakeup interrupt occur
  * @rev: The revision number for controller
+ * @mutex: protect code from concorrent running when doing role switch
  */
 struct ci_hdrc {
        struct device                   *dev;
@@ -260,6 +261,7 @@ struct ci_hdrc {
        bool                            in_lpm;
        bool                            wakeup_int;
        enum ci_revision                rev;
+       struct mutex                    mutex;
 };
 
 static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci)
index 27c601296130e23f5b3d740d2b2944ccb2bbe586..281fc51720cea2ab9d0d63b486fb38c6c4f4ebfc 100644 (file)
@@ -984,9 +984,16 @@ static ssize_t role_store(struct device *dev,
                             strlen(ci->roles[role]->name)))
                        break;
 
-       if (role == CI_ROLE_END || role == ci->role)
+       if (role == CI_ROLE_END)
                return -EINVAL;
 
+       mutex_lock(&ci->mutex);
+
+       if (role == ci->role) {
+               mutex_unlock(&ci->mutex);
+               return n;
+       }
+
        pm_runtime_get_sync(dev);
        disable_irq(ci->irq);
        ci_role_stop(ci);
@@ -995,6 +1002,7 @@ static ssize_t role_store(struct device *dev,
                ci_handle_vbus_change(ci);
        enable_irq(ci->irq);
        pm_runtime_put_sync(dev);
+       mutex_unlock(&ci->mutex);
 
        return (ret == 0) ? n : ret;
 }
@@ -1030,6 +1038,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        spin_lock_init(&ci->lock);
+       mutex_init(&ci->mutex);
        ci->dev = dev;
        ci->platdata = dev_get_platdata(dev);
        ci->imx28_write_fix = !!(ci->platdata->flags &
index 622c3b68aa1e6a4bf55370d42ab4d3768eb478d8..f5490f2a5b6bca6b725c596d7536c2b548547d4b 100644 (file)
@@ -167,8 +167,10 @@ static int hw_wait_vbus_lower_bsv(struct ci_hdrc *ci)
 
 void ci_handle_id_switch(struct ci_hdrc *ci)
 {
-       enum ci_role role = ci_otg_role(ci);
+       enum ci_role role;
 
+       mutex_lock(&ci->mutex);
+       role = ci_otg_role(ci);
        if (role != ci->role) {
                dev_dbg(ci->dev, "switching from %s to %s\n",
                        ci_role(ci)->name, ci->roles[role]->name);
@@ -198,6 +200,7 @@ void ci_handle_id_switch(struct ci_hdrc *ci)
                if (role == CI_ROLE_GADGET)
                        ci_handle_vbus_change(ci);
        }
+       mutex_unlock(&ci->mutex);
 }
 /**
  * ci_otg_work - perform otg (vbus/id) event handle
index d8d6493bc4576ba767d0c13b0255592cbece1595..a8605b02115b1c3d0c6038c1dbb72e0e9ab3bac9 100644 (file)
@@ -35,7 +35,8 @@ static void dwc2_ovr_init(struct dwc2_hsotg *hsotg)
 
        spin_unlock_irqrestore(&hsotg->lock, flags);
 
-       dwc2_force_mode(hsotg, (hsotg->dr_mode == USB_DR_MODE_HOST));
+       dwc2_force_mode(hsotg, (hsotg->dr_mode == USB_DR_MODE_HOST) ||
+                               (hsotg->role_sw_default_mode == USB_DR_MODE_HOST));
 }
 
 static int dwc2_ovr_avalid(struct dwc2_hsotg *hsotg, bool valid)
index 62fa6378d2d73c63365e22ef0ea916517372a589..8b15742d9e8aa03301c41a7192207b33dd1a7293 100644 (file)
@@ -4549,8 +4549,7 @@ static int dwc2_hsotg_udc_start(struct usb_gadget *gadget,
        hsotg->gadget.dev.of_node = hsotg->dev->of_node;
        hsotg->gadget.speed = USB_SPEED_UNKNOWN;
 
-       if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL ||
-           (hsotg->dr_mode == USB_DR_MODE_OTG && dwc2_is_device_mode(hsotg))) {
+       if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) {
                ret = dwc2_lowlevel_hw_enable(hsotg);
                if (ret)
                        goto err;
@@ -4612,8 +4611,7 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget)
        if (!IS_ERR_OR_NULL(hsotg->uphy))
                otg_set_peripheral(hsotg->uphy->otg, NULL);
 
-       if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL ||
-           (hsotg->dr_mode == USB_DR_MODE_OTG && dwc2_is_device_mode(hsotg)))
+       if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
                dwc2_lowlevel_hw_disable(hsotg);
 
        return 0;
index 23ef759968231a80bab5e78cdf3217d7771298fc..d1589ba7d322dc6ccf8427ab29c131059c4ee80a 100644 (file)
@@ -91,13 +91,6 @@ static int dwc2_get_dr_mode(struct dwc2_hsotg *hsotg)
        return 0;
 }
 
-static void __dwc2_disable_regulators(void *data)
-{
-       struct dwc2_hsotg *hsotg = data;
-
-       regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
-}
-
 static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
 {
        struct platform_device *pdev = to_platform_device(hsotg->dev);
@@ -108,11 +101,6 @@ static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
        if (ret)
                return ret;
 
-       ret = devm_add_action_or_reset(&pdev->dev,
-                                      __dwc2_disable_regulators, hsotg);
-       if (ret)
-               return ret;
-
        if (hsotg->clk) {
                ret = clk_prepare_enable(hsotg->clk);
                if (ret)
@@ -168,7 +156,7 @@ static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
        if (hsotg->clk)
                clk_disable_unprepare(hsotg->clk);
 
-       return 0;
+       return regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
 }
 
 /**
@@ -576,8 +564,7 @@ static int dwc2_driver_probe(struct platform_device *dev)
        dwc2_debugfs_init(hsotg);
 
        /* Gadget code manages lowlevel hw on its own */
-       if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL ||
-           (hsotg->dr_mode == USB_DR_MODE_OTG && dwc2_is_device_mode(hsotg)))
+       if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
                dwc2_lowlevel_hw_disable(hsotg);
 
 #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \
@@ -608,7 +595,7 @@ error_init:
        if (hsotg->params.activate_stm_id_vb_detection)
                regulator_disable(hsotg->usb33d);
 error:
-       if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL)
+       if (hsotg->ll_hw_enabled)
                dwc2_lowlevel_hw_disable(hsotg);
        return retval;
 }
index 582ebd9cf9c2e1ed4867404203efe8c9a0e11254..4743e918dcafa96aea30b238ca24d44c36745448 100644 (file)
@@ -1098,7 +1098,7 @@ struct dwc3_scratchpad_array {
  *                     change quirk.
  * @dis_tx_ipgap_linecheck_quirk: set if we disable u2mac linestate
  *                     check during HS transmit.
- * @resume-hs-terminations: Set if we enable quirk for fixing improper crc
+ * @resume_hs_terminations: Set if we enable quirk for fixing improper crc
  *                     generation after resume from suspend.
  * @parkmode_disable_ss_quirk: set if we need to disable all SuperSpeed
  *                     instances in park mode.
index a23ddbb81979502ace7b66e93ea3b0c5f269ec5e..560793545362afc0ee105f54a086a87b003fbe46 100644 (file)
@@ -49,6 +49,7 @@
 #define PCI_DEVICE_ID_INTEL_RPLS               0x7a61
 #define PCI_DEVICE_ID_INTEL_MTLM               0x7eb1
 #define PCI_DEVICE_ID_INTEL_MTLP               0x7ec1
+#define PCI_DEVICE_ID_INTEL_MTLS               0x7f6f
 #define PCI_DEVICE_ID_INTEL_MTL                        0x7e7e
 #define PCI_DEVICE_ID_INTEL_TGL                        0x9a15
 #define PCI_DEVICE_ID_AMD_MR                   0x163a
@@ -474,6 +475,9 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MTLP),
          (kernel_ulong_t) &dwc3_pci_intel_swnode, },
 
+       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MTLS),
+         (kernel_ulong_t) &dwc3_pci_intel_swnode, },
+
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MTL),
          (kernel_ulong_t) &dwc3_pci_intel_swnode, },
 
index 3c63fa97a680041f7345b1f6aadddda4e6207a2b..cf5b4f49c3ed8241fdf34d5ebd9ae15d78c14e89 100644 (file)
@@ -1699,6 +1699,7 @@ static int __dwc3_gadget_get_frame(struct dwc3 *dwc)
  */
 static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt)
 {
+       struct dwc3 *dwc = dep->dwc;
        struct dwc3_gadget_ep_cmd_params params;
        u32 cmd;
        int ret;
@@ -1722,10 +1723,13 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool int
        WARN_ON_ONCE(ret);
        dep->resource_index = 0;
 
-       if (!interrupt)
+       if (!interrupt) {
+               if (!DWC3_IP_IS(DWC3) || DWC3_VER_IS_PRIOR(DWC3, 310A))
+                       mdelay(1);
                dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
-       else if (!ret)
+       } else if (!ret) {
                dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
+       }
 
        dep->flags &= ~DWC3_EP_DELAY_STOP;
        return ret;
@@ -3774,7 +3778,11 @@ void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
         * enabled, the EndTransfer command will have completed upon
         * returning from this function.
         *
-        * This mode is NOT available on the DWC_usb31 IP.
+        * This mode is NOT available on the DWC_usb31 IP.  In this
+        * case, if the IOC bit is not set, then delay by 1ms
+        * after issuing the EndTransfer command.  This allows for the
+        * controller to handle the command completely before DWC3
+        * remove requests attempts to unmap USB request buffers.
         */
 
        __dwc3_stop_active_transfer(dep, force, interrupt);
index fa7dd6cf014d7b093da3fea48aee1a6981e9157e..5377d873c08eb6fb57895e1fe127f8b0fa16b68e 100644 (file)
@@ -2079,10 +2079,9 @@ unknown:
                                sizeof(url_descriptor->URL)
                                - WEBUSB_URL_DESCRIPTOR_HEADER_LENGTH + landing_page_offset);
 
-                       if (ctrl->wLength < WEBUSB_URL_DESCRIPTOR_HEADER_LENGTH
-                                           + landing_page_length)
-                               landing_page_length = ctrl->wLength
-                                       - WEBUSB_URL_DESCRIPTOR_HEADER_LENGTH + landing_page_offset;
+                       if (w_length < WEBUSB_URL_DESCRIPTOR_HEADER_LENGTH + landing_page_length)
+                               landing_page_length = w_length
+                               - WEBUSB_URL_DESCRIPTOR_HEADER_LENGTH + landing_page_offset;
 
                        memcpy(url_descriptor->URL,
                                cdev->landing_page + landing_page_offset,
index ddfc537c7526b2256dd4a17f85daab0d8b1f739d..56cdfb2e42113eb27b29e2f675a104d84503c737 100644 (file)
@@ -1251,7 +1251,7 @@ static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to)
        p->kiocb = kiocb;
        if (p->aio) {
                p->to_free = dup_iter(&p->data, to, GFP_KERNEL);
-               if (!p->to_free) {
+               if (!iter_is_ubuf(&p->data) && !p->to_free) {
                        kfree(p);
                        return -ENOMEM;
                }
index c1f62e91b012634498bb7b299e59a018c28076d6..4a42574b4a7feb9ecc230889fe66f85e3c5ab8ea 100644 (file)
@@ -1422,7 +1422,7 @@ void g_audio_cleanup(struct g_audio *g_audio)
        uac = g_audio->uac;
        card = uac->card;
        if (card)
-               snd_card_free(card);
+               snd_card_free_when_closed(card);
 
        kfree(uac->p_prm.reqs);
        kfree(uac->c_prm.reqs);
index d605bc2e7e8fd43dd0725e221e22786d96e22bfd..28249d0bf0629fa73acb9c8b9c963fad52b0b619 100644 (file)
@@ -614,7 +614,7 @@ ep_read_iter(struct kiocb *iocb, struct iov_iter *to)
                if (!priv)
                        goto fail;
                priv->to_free = dup_iter(&priv->to, to, GFP_KERNEL);
-               if (!priv->to_free) {
+               if (!iter_is_ubuf(&priv->to) && !priv->to_free) {
                        kfree(priv);
                        goto fail;
                }
index fb988e4ea9244e160e7b2af6aabf01901b9b4d63..6db07ca419c317488e4c0918a39d2d3e6f6a5865 100644 (file)
@@ -771,12 +771,11 @@ static struct pci_driver xhci_pci_driver = {
        /* suspend and resume implemented later */
 
        .shutdown =     usb_hcd_pci_shutdown,
-       .driver = {
 #ifdef CONFIG_PM
-               .pm = &usb_hcd_pci_pm_ops,
-#endif
-               .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+       .driver = {
+               .pm = &usb_hcd_pci_pm_ops
        },
+#endif
 };
 
 static int __init xhci_pci_init(void)
index 1ff22f675930c41c7eb4383d5430441455ce9063..a88c39e525c235521d1583ca2807aced1bc96259 100644 (file)
@@ -1360,6 +1360,9 @@ static void tegra_xhci_id_work(struct work_struct *work)
 
        mutex_unlock(&tegra->lock);
 
+       tegra->otg_usb3_port = tegra_xusb_padctl_get_usb3_companion(tegra->padctl,
+                                                                   tegra->otg_usb2_port);
+
        if (tegra->host_mode) {
                /* switch to host mode */
                if (tegra->otg_usb3_port >= 0) {
@@ -1474,9 +1477,6 @@ static int tegra_xhci_id_notify(struct notifier_block *nb,
        }
 
        tegra->otg_usb2_port = tegra_xusb_get_usb2_port(tegra, usbphy);
-       tegra->otg_usb3_port = tegra_xusb_padctl_get_usb3_companion(
-                                                       tegra->padctl,
-                                                       tegra->otg_usb2_port);
 
        tegra->host_mode = (usbphy->last_event == USB_EVENT_ID) ? true : false;
 
index 6183ce8574b1abcec88b35a5261601af8a72fc58..6307bae9cddffdf775786d976b28b7eadd8d0078 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/iommu.h>
 #include <linux/iopoll.h>
 #include <linux/irq.h>
 #include <linux/log2.h>
@@ -228,6 +229,7 @@ int xhci_reset(struct xhci_hcd *xhci, u64 timeout_us)
 static void xhci_zero_64b_regs(struct xhci_hcd *xhci)
 {
        struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
+       struct iommu_domain *domain;
        int err, i;
        u64 val;
        u32 intrs;
@@ -246,7 +248,9 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci)
         * an iommu. Doing anything when there is no iommu is definitely
         * unsafe...
         */
-       if (!(xhci->quirks & XHCI_ZERO_64B_REGS) || !device_iommu_mapped(dev))
+       domain = iommu_get_domain_for_dev(dev);
+       if (!(xhci->quirks & XHCI_ZERO_64B_REGS) || !domain ||
+           domain->type == IOMMU_DOMAIN_IDENTITY)
                return;
 
        xhci_info(xhci, "Zeroing 64bit base registers, expecting fault\n");
@@ -4438,6 +4442,7 @@ static int __maybe_unused xhci_change_max_exit_latency(struct xhci_hcd *xhci,
 
        if (!virt_dev || max_exit_latency == virt_dev->current_mel) {
                spin_unlock_irqrestore(&xhci->lock, flags);
+               xhci_free_command(xhci, command);
                return 0;
        }
 
index 5402e4b7267b9957f0f6300099f20ccc50398944..12fc6eb67c3bf23a253ee1f48667499021d830d7 100644 (file)
@@ -410,6 +410,7 @@ static const struct usb_device_id onboard_hub_id_table[] = {
        { USB_DEVICE(VENDOR_ID_GENESYS, 0x0608) }, /* Genesys Logic GL850G USB 2.0 */
        { USB_DEVICE(VENDOR_ID_GENESYS, 0x0610) }, /* Genesys Logic GL852G USB 2.0 */
        { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2514) }, /* USB2514B USB 2.0 */
+       { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2517) }, /* USB2517 USB 2.0 */
        { USB_DEVICE(VENDOR_ID_REALTEK, 0x0411) }, /* RTS5411 USB 3.1 */
        { USB_DEVICE(VENDOR_ID_REALTEK, 0x5411) }, /* RTS5411 USB 2.1 */
        { USB_DEVICE(VENDOR_ID_REALTEK, 0x0414) }, /* RTS5414 USB 3.2 */
index 0a943a1546490293c3342609dd960f71cf046b50..aca5f50eb0da77f471816219d1e0d37ad57589cc 100644 (file)
@@ -36,6 +36,7 @@ static const struct onboard_hub_pdata vialab_vl817_data = {
 
 static const struct of_device_id onboard_hub_match[] = {
        { .compatible = "usb424,2514", .data = &microchip_usb424_data, },
+       { .compatible = "usb424,2517", .data = &microchip_usb424_data, },
        { .compatible = "usb451,8140", .data = &ti_tusb8041_data, },
        { .compatible = "usb451,8142", .data = &ti_tusb8041_data, },
        { .compatible = "usb5e3,608", .data = &genesys_gl850g_data, },
index 832ad592b7ef3bed8411922c9fec294591ea0756..cdea1bff3b708b819d58be6265fd0d8f617bd8b3 100644 (file)
@@ -120,6 +120,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */
        { USB_DEVICE(0x10C4, 0x8281) }, /* Nanotec Plug & Drive */
        { USB_DEVICE(0x10C4, 0x8293) }, /* Telegesis ETRX2USB */
+       { USB_DEVICE(0x10C4, 0x82AA) }, /* Silicon Labs IFS-USB-DATACABLE used with Quint UPS */
        { USB_DEVICE(0x10C4, 0x82EF) }, /* CESINEL FALCO 6105 AC Power Supply */
        { USB_DEVICE(0x10C4, 0x82F1) }, /* CESINEL MEDCAL EFD Earth Fault Detector */
        { USB_DEVICE(0x10C4, 0x82F2) }, /* CESINEL MEDCAL ST Network Analyzer */
index e6d8d9b35ad0e2186a961746d9eaaed736d96a31..f31cc3c763299d4dc7affd31e7aa94c025841029 100644 (file)
@@ -1198,6 +1198,8 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0xff, 0x30) },
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0x40) },
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0) },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0900, 0xff, 0, 0), /* RM500U-CN */
+         .driver_info = ZLP },
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200U, 0xff, 0, 0) },
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) },
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) },
@@ -1300,6 +1302,14 @@ static const struct usb_device_id option_ids[] = {
          .driver_info = NCTRL(0) | RSVD(1) },
        { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff),    /* Telit FN990 (PCIe) */
          .driver_info = RSVD(0) },
+       { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1080, 0xff),    /* Telit FE990 (rmnet) */
+         .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
+       { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1081, 0xff),    /* Telit FE990 (MBIM) */
+         .driver_info = NCTRL(0) | RSVD(1) },
+       { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1082, 0xff),    /* Telit FE990 (RNDIS) */
+         .driver_info = NCTRL(2) | RSVD(3) },
+       { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1083, 0xff),    /* Telit FE990 (ECM) */
+         .driver_info = NCTRL(0) | RSVD(1) },
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
          .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
index c7b763d6d102394aba9080cfc104db9cb2b3c9c3..1f8c9b16a0fb850de066b2d1c071ff933fa4f4bf 100644 (file)
@@ -111,6 +111,13 @@ UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_BROKEN_FUA),
 
+/* Reported by: Yaroslav Furman <yaro330@gmail.com> */
+UNUSUAL_DEV(0x152d, 0x0583, 0x0000, 0x9999,
+               "JMicron",
+               "JMS583Gen 2",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_NO_REPORT_OPCODES),
+
 /* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */
 UNUSUAL_DEV(0x154b, 0xf00b, 0x0000, 0x9999,
                "PNY",
index 662cd043b50ea68468b7c5fc672364848ed2e749..8f3e884222adef512a424e16623ad3cad8565143 100644 (file)
@@ -112,8 +112,12 @@ static int dp_altmode_configure(struct dp_altmode *dp, u8 con)
                if (dp->data.status & DP_STATUS_PREFER_MULTI_FUNC &&
                    pin_assign & DP_PIN_ASSIGN_MULTI_FUNC_MASK)
                        pin_assign &= DP_PIN_ASSIGN_MULTI_FUNC_MASK;
-               else if (pin_assign & DP_PIN_ASSIGN_DP_ONLY_MASK)
+               else if (pin_assign & DP_PIN_ASSIGN_DP_ONLY_MASK) {
                        pin_assign &= DP_PIN_ASSIGN_DP_ONLY_MASK;
+                       /* Default to pin assign C if available */
+                       if (pin_assign & BIT(DP_PIN_ASSIGN_C))
+                               pin_assign = BIT(DP_PIN_ASSIGN_C);
+               }
 
                if (!pin_assign)
                        return -EINVAL;
index a0d943d785800fbbdb36a2cc5f206b5841697d64..1ee774c263f08c06ea87f28dcca1a83ef614e279 100644 (file)
@@ -1445,10 +1445,18 @@ static int tcpm_ams_start(struct tcpm_port *port, enum tcpm_ams ams)
 static void tcpm_queue_vdm(struct tcpm_port *port, const u32 header,
                           const u32 *data, int cnt)
 {
+       u32 vdo_hdr = port->vdo_data[0];
+
        WARN_ON(!mutex_is_locked(&port->lock));
 
-       /* Make sure we are not still processing a previous VDM packet */
-       WARN_ON(port->vdm_state > VDM_STATE_DONE);
+       /* If is sending discover_identity, handle received message first */
+       if (PD_VDO_SVDM(vdo_hdr) && PD_VDO_CMD(vdo_hdr) == CMD_DISCOVER_IDENT) {
+               port->send_discover = true;
+               mod_send_discover_delayed_work(port, SEND_DISCOVER_RETRY_MS);
+       } else {
+               /* Make sure we are not still processing a previous VDM packet */
+               WARN_ON(port->vdm_state > VDM_STATE_DONE);
+       }
 
        port->vdo_count = cnt + 1;
        port->vdo_data[0] = header;
@@ -1948,11 +1956,13 @@ static void vdm_run_state_machine(struct tcpm_port *port)
                        switch (PD_VDO_CMD(vdo_hdr)) {
                        case CMD_DISCOVER_IDENT:
                                res = tcpm_ams_start(port, DISCOVER_IDENTITY);
-                               if (res == 0)
+                               if (res == 0) {
                                        port->send_discover = false;
-                               else if (res == -EAGAIN)
+                               } else if (res == -EAGAIN) {
+                                       port->vdo_data[0] = 0;
                                        mod_send_discover_delayed_work(port,
                                                                       SEND_DISCOVER_RETRY_MS);
+                               }
                                break;
                        case CMD_DISCOVER_SVID:
                                res = tcpm_ams_start(port, DISCOVER_SVIDS);
@@ -2035,6 +2045,7 @@ static void vdm_run_state_machine(struct tcpm_port *port)
                        unsigned long timeout;
 
                        port->vdm_retries = 0;
+                       port->vdo_data[0] = 0;
                        port->vdm_state = VDM_STATE_BUSY;
                        timeout = vdm_ready_timeout(vdo_hdr);
                        mod_vdm_delayed_work(port, timeout);
@@ -4570,6 +4581,9 @@ static void run_state_machine(struct tcpm_port *port)
        case SOFT_RESET:
                port->message_id = 0;
                port->rx_msgid = -1;
+               /* remove existing capabilities */
+               usb_power_delivery_unregister_capabilities(port->partner_source_caps);
+               port->partner_source_caps = NULL;
                tcpm_pd_send_control(port, PD_CTRL_ACCEPT);
                tcpm_ams_finish(port);
                if (port->pwr_role == TYPEC_SOURCE) {
@@ -4589,6 +4603,9 @@ static void run_state_machine(struct tcpm_port *port)
        case SOFT_RESET_SEND:
                port->message_id = 0;
                port->rx_msgid = -1;
+               /* remove existing capabilities */
+               usb_power_delivery_unregister_capabilities(port->partner_source_caps);
+               port->partner_source_caps = NULL;
                if (tcpm_pd_send_control(port, PD_CTRL_SOFT_RESET))
                        tcpm_set_state_cond(port, hard_reset_state(port), 0);
                else
@@ -4718,6 +4735,9 @@ static void run_state_machine(struct tcpm_port *port)
                tcpm_set_state(port, SNK_STARTUP, 0);
                break;
        case PR_SWAP_SNK_SRC_SINK_OFF:
+               /* will be source, remove existing capabilities */
+               usb_power_delivery_unregister_capabilities(port->partner_source_caps);
+               port->partner_source_caps = NULL;
                /*
                 * Prevent vbus discharge circuit from turning on during PR_SWAP
                 * as this is not a disconnect.
index f632350f6dcb2ad43bf4faa6509ce1d917c654b4..8d1baf28df55c90e3f3bf2078ee6373134ddcfc6 100644 (file)
@@ -1125,12 +1125,11 @@ static struct fwnode_handle *ucsi_find_fwnode(struct ucsi_connector *con)
        return NULL;
 }
 
-static int ucsi_register_port(struct ucsi *ucsi, int index)
+static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
 {
        struct usb_power_delivery_desc desc = { ucsi->cap.pd_version};
        struct usb_power_delivery_capabilities_desc pd_caps;
        struct usb_power_delivery_capabilities *pd_cap;
-       struct ucsi_connector *con = &ucsi->connector[index];
        struct typec_capability *cap = &con->typec_cap;
        enum typec_accessory *accessory = cap->accessory;
        enum usb_role u_role = USB_ROLE_NONE;
@@ -1151,7 +1150,6 @@ static int ucsi_register_port(struct ucsi *ucsi, int index)
        init_completion(&con->complete);
        mutex_init(&con->lock);
        INIT_LIST_HEAD(&con->partner_tasks);
-       con->num = index + 1;
        con->ucsi = ucsi;
 
        cap->fwnode = ucsi_find_fwnode(con);
@@ -1328,8 +1326,8 @@ out_unlock:
  */
 static int ucsi_init(struct ucsi *ucsi)
 {
-       struct ucsi_connector *con;
-       u64 command;
+       struct ucsi_connector *con, *connector;
+       u64 command, ntfy;
        int ret;
        int i;
 
@@ -1341,8 +1339,8 @@ static int ucsi_init(struct ucsi *ucsi)
        }
 
        /* Enable basic notifications */
-       ucsi->ntfy = UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR;
-       command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
+       ntfy = UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR;
+       command = UCSI_SET_NOTIFICATION_ENABLE | ntfy;
        ret = ucsi_send_command(ucsi, command, NULL, 0);
        if (ret < 0)
                goto err_reset;
@@ -1359,31 +1357,33 @@ static int ucsi_init(struct ucsi *ucsi)
        }
 
        /* Allocate the connectors. Released in ucsi_unregister() */
-       ucsi->connector = kcalloc(ucsi->cap.num_connectors + 1,
-                                 sizeof(*ucsi->connector), GFP_KERNEL);
-       if (!ucsi->connector) {
+       connector = kcalloc(ucsi->cap.num_connectors + 1, sizeof(*connector), GFP_KERNEL);
+       if (!connector) {
                ret = -ENOMEM;
                goto err_reset;
        }
 
        /* Register all connectors */
        for (i = 0; i < ucsi->cap.num_connectors; i++) {
-               ret = ucsi_register_port(ucsi, i);
+               connector[i].num = i + 1;
+               ret = ucsi_register_port(ucsi, &connector[i]);
                if (ret)
                        goto err_unregister;
        }
 
        /* Enable all notifications */
-       ucsi->ntfy = UCSI_ENABLE_NTFY_ALL;
-       command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
+       ntfy = UCSI_ENABLE_NTFY_ALL;
+       command = UCSI_SET_NOTIFICATION_ENABLE | ntfy;
        ret = ucsi_send_command(ucsi, command, NULL, 0);
        if (ret < 0)
                goto err_unregister;
 
+       ucsi->connector = connector;
+       ucsi->ntfy = ntfy;
        return 0;
 
 err_unregister:
-       for (con = ucsi->connector; con->port; con++) {
+       for (con = connector; con->port; con++) {
                ucsi_unregister_partner(con);
                ucsi_unregister_altmodes(con, UCSI_RECIPIENT_CON);
                ucsi_unregister_port_psy(con);
@@ -1399,10 +1399,7 @@ err_unregister:
                typec_unregister_port(con->port);
                con->port = NULL;
        }
-
-       kfree(ucsi->connector);
-       ucsi->connector = NULL;
-
+       kfree(connector);
 err_reset:
        memset(&ucsi->cap, 0, sizeof(ucsi->cap));
        ucsi_reset_ppm(ucsi);
index ce0c8ef80c04343d2d674579283cddfc567c3e85..62206a6b8ea75019e1ec767146a1a1d35e5e5b90 100644 (file)
@@ -78,7 +78,7 @@ static int ucsi_acpi_sync_write(struct ucsi *ucsi, unsigned int offset,
        if (ret)
                goto out_clear_bit;
 
-       if (!wait_for_completion_timeout(&ua->complete, HZ))
+       if (!wait_for_completion_timeout(&ua->complete, 5 * HZ))
                ret = -ETIMEDOUT;
 
 out_clear_bit:
index 058fbe28107e9e2740c698ad862a1b1b747c8cc1..25fc4120b618de16483ae2bd89af9bb866206bcd 100644 (file)
@@ -96,6 +96,7 @@ struct mlx5_vdpa_dev {
        struct mlx5_control_vq cvq;
        struct workqueue_struct *wq;
        unsigned int group2asid[MLX5_VDPA_NUMVQ_GROUPS];
+       bool suspended;
 };
 
 int mlx5_vdpa_alloc_pd(struct mlx5_vdpa_dev *dev, u32 *pdn, u16 uid);
index 3a0e721aef05fb419ca84c604ed29c79f8e84da8..195963b82b636340d4a1b73e15e25a6c5face806 100644 (file)
@@ -2438,7 +2438,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev,
        if (err)
                goto err_mr;
 
-       if (!(mvdev->status & VIRTIO_CONFIG_S_DRIVER_OK))
+       if (!(mvdev->status & VIRTIO_CONFIG_S_DRIVER_OK) || mvdev->suspended)
                goto err_mr;
 
        restore_channels_info(ndev);
@@ -2467,10 +2467,11 @@ static int setup_driver(struct mlx5_vdpa_dev *mvdev)
                err = 0;
                goto out;
        }
+       mlx5_vdpa_add_debugfs(ndev);
        err = setup_virtqueues(mvdev);
        if (err) {
                mlx5_vdpa_warn(mvdev, "setup_virtqueues\n");
-               goto out;
+               goto err_setup;
        }
 
        err = create_rqt(ndev);
@@ -2500,6 +2501,8 @@ err_tir:
        destroy_rqt(ndev);
 err_rqt:
        teardown_virtqueues(ndev);
+err_setup:
+       mlx5_vdpa_remove_debugfs(ndev->debugfs);
 out:
        return err;
 }
@@ -2513,6 +2516,8 @@ static void teardown_driver(struct mlx5_vdpa_net *ndev)
        if (!ndev->setup)
                return;
 
+       mlx5_vdpa_remove_debugfs(ndev->debugfs);
+       ndev->debugfs = NULL;
        teardown_steering(ndev);
        destroy_tir(ndev);
        destroy_rqt(ndev);
@@ -2606,6 +2611,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)
        clear_vqs_ready(ndev);
        mlx5_vdpa_destroy_mr(&ndev->mvdev);
        ndev->mvdev.status = 0;
+       ndev->mvdev.suspended = false;
        ndev->cur_num_vqs = 0;
        ndev->mvdev.cvq.received_desc = 0;
        ndev->mvdev.cvq.completed_desc = 0;
@@ -2852,6 +2858,8 @@ static int mlx5_vdpa_suspend(struct vdpa_device *vdev)
        struct mlx5_vdpa_virtqueue *mvq;
        int i;
 
+       mlx5_vdpa_info(mvdev, "suspending device\n");
+
        down_write(&ndev->reslock);
        ndev->nb_registered = false;
        mlx5_notifier_unregister(mvdev->mdev, &ndev->nb);
@@ -2861,6 +2869,7 @@ static int mlx5_vdpa_suspend(struct vdpa_device *vdev)
                suspend_vq(ndev, mvq);
        }
        mlx5_vdpa_cvq_suspend(mvdev);
+       mvdev->suspended = true;
        up_write(&ndev->reslock);
        return 0;
 }
@@ -3257,7 +3266,6 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,
        if (err)
                goto err_reg;
 
-       mlx5_vdpa_add_debugfs(ndev);
        mgtdev->ndev = ndev;
        return 0;
 
index 6a0a658146269a5d1c218d88747f4a6186060869..eea23c630f7c08d3abc33ef463529bde775e64b8 100644 (file)
@@ -68,6 +68,17 @@ static void vdpasim_queue_ready(struct vdpasim *vdpasim, unsigned int idx)
                          (uintptr_t)vq->device_addr);
 
        vq->vring.last_avail_idx = last_avail_idx;
+
+       /*
+        * Since vdpa_sim does not support receive inflight descriptors as a
+        * destination of a migration, let's set both avail_idx and used_idx
+        * the same at vq start.  This is how vhost-user works in a
+        * VHOST_SET_VRING_BASE call.
+        *
+        * Although the simple fix is to set last_used_idx at
+        * vdpasim_set_vq_state, it would be reset at vdpasim_queue_ready.
+        */
+       vq->vring.last_used_idx = last_avail_idx;
        vq->vring.notify = vdpasim_vq_notify;
 }
 
index 862f405362de27dc3ca88eefa3d3ac334a154fa5..dfe2ce34180356e408cb129a9ce0be77461bd64d 100644 (file)
@@ -466,16 +466,21 @@ static int vdpasim_net_dev_add(struct vdpa_mgmt_dev *mdev, const char *name,
 
        vdpasim_net_setup_config(simdev, config);
 
-       ret = _vdpa_register_device(&simdev->vdpa, VDPASIM_NET_VQ_NUM);
-       if (ret)
-               goto reg_err;
-
        net = sim_to_net(simdev);
 
        u64_stats_init(&net->tx_stats.syncp);
        u64_stats_init(&net->rx_stats.syncp);
        u64_stats_init(&net->cq_stats.syncp);
 
+       /*
+        * Initialization must be completed before this call, since it can
+        * connect the device to the vDPA bus, so requests can arrive after
+        * this call.
+        */
+       ret = _vdpa_register_device(&simdev->vdpa, VDPASIM_NET_VQ_NUM);
+       if (ret)
+               goto reg_err;
+
        return 0;
 
 reg_err:
index 8fe267ca3e76f2483501030aa838b9773321bac6..281287fae89f137e18e09d5c259115f3af1fcb4f 100644 (file)
@@ -645,8 +645,8 @@ static void vp_vdpa_remove(struct pci_dev *pdev)
        struct virtio_pci_modern_device *mdev = NULL;
 
        mdev = vp_vdpa_mgtdev->mdev;
-       vp_modern_remove(mdev);
        vdpa_mgmtdev_unregister(&vp_vdpa_mgtdev->mgtdev);
+       vp_modern_remove(mdev);
        kfree(vp_vdpa_mgtdev->mgtdev.id_table);
        kfree(mdev);
        kfree(vp_vdpa_mgtdev);
index e897537a9e8ad7e26238eee6c8bd90ab3fbaf6b6..d95fd382814c8f28ba4db8d78170e97441992cc9 100644 (file)
@@ -442,16 +442,10 @@ static long mlx5vf_precopy_ioctl(struct file *filp, unsigned int cmd,
        if (migf->pre_copy_initial_bytes > *pos) {
                info.initial_bytes = migf->pre_copy_initial_bytes - *pos;
        } else {
-               buf = mlx5vf_get_data_buff_from_pos(migf, *pos, &end_of_data);
-               if (buf) {
-                       info.dirty_bytes = buf->start_pos + buf->length - *pos;
-               } else {
-                       if (!end_of_data) {
-                               ret = -EINVAL;
-                               goto err_migf_unlock;
-                       }
-                       info.dirty_bytes = inc_length;
-               }
+               info.dirty_bytes = migf->max_pos - *pos;
+               if (!info.dirty_bytes)
+                       end_of_data = true;
+               info.dirty_bytes += inc_length;
        }
 
        if (!end_of_data || !inc_length) {
index 587fbae0618213ea5399a2cf0bf7f55cd8ed558b..b455d9ab6f3d9c989ca10f37efd1fbebbcae665b 100644 (file)
@@ -13,9 +13,14 @@ config VHOST_RING
          This option is selected by any driver which needs to access
          the host side of a virtio ring.
 
+config VHOST_TASK
+       bool
+       default n
+
 config VHOST
        tristate
        select VHOST_IOTLB
+       select VHOST_TASK
        help
          This option is selected by any driver which needs to access
          the core of vhost.
index b244e7c0f514ca3efdb676b771a4457780a2b7a2..e68f7d226bc9ff9482a8842c7e32dc5ba598236e 100644 (file)
@@ -125,7 +125,6 @@ struct vhost_scsi_tpg {
        struct se_portal_group se_tpg;
        /* Pointer back to vhost_scsi, protected by tv_tpg_mutex */
        struct vhost_scsi *vhost_scsi;
-       struct list_head tmf_queue;
 };
 
 struct vhost_scsi_tport {
@@ -206,10 +205,8 @@ struct vhost_scsi {
 
 struct vhost_scsi_tmf {
        struct vhost_work vwork;
-       struct vhost_scsi_tpg *tpg;
        struct vhost_scsi *vhost;
        struct vhost_scsi_virtqueue *svq;
-       struct list_head queue_entry;
 
        struct se_cmd se_cmd;
        u8 scsi_resp;
@@ -352,12 +349,9 @@ static void vhost_scsi_release_cmd_res(struct se_cmd *se_cmd)
 
 static void vhost_scsi_release_tmf_res(struct vhost_scsi_tmf *tmf)
 {
-       struct vhost_scsi_tpg *tpg = tmf->tpg;
        struct vhost_scsi_inflight *inflight = tmf->inflight;
 
-       mutex_lock(&tpg->tv_tpg_mutex);
-       list_add_tail(&tpg->tmf_queue, &tmf->queue_entry);
-       mutex_unlock(&tpg->tv_tpg_mutex);
+       kfree(tmf);
        vhost_scsi_put_inflight(inflight);
 }
 
@@ -671,7 +665,7 @@ vhost_scsi_calc_sgls(struct iov_iter *iter, size_t bytes, int max_sgls)
 {
        int sgl_count = 0;
 
-       if (!iter || !iter->iov) {
+       if (!iter || !iter_iov(iter)) {
                pr_err("%s: iter->iov is NULL, but expected bytes: %zu"
                       " present\n", __func__, bytes);
                return -EINVAL;
@@ -1194,19 +1188,11 @@ vhost_scsi_handle_tmf(struct vhost_scsi *vs, struct vhost_scsi_tpg *tpg,
                goto send_reject;
        }
 
-       mutex_lock(&tpg->tv_tpg_mutex);
-       if (list_empty(&tpg->tmf_queue)) {
-               pr_err("Missing reserve TMF. Could not handle LUN RESET.\n");
-               mutex_unlock(&tpg->tv_tpg_mutex);
+       tmf = kzalloc(sizeof(*tmf), GFP_KERNEL);
+       if (!tmf)
                goto send_reject;
-       }
-
-       tmf = list_first_entry(&tpg->tmf_queue, struct vhost_scsi_tmf,
-                              queue_entry);
-       list_del_init(&tmf->queue_entry);
-       mutex_unlock(&tpg->tv_tpg_mutex);
 
-       tmf->tpg = tpg;
+       vhost_work_init(&tmf->vwork, vhost_scsi_tmf_resp_work);
        tmf->vhost = vs;
        tmf->svq = svq;
        tmf->resp_iov = vq->iov[vc->out];
@@ -1658,7 +1644,10 @@ undepend:
        for (i = 0; i < VHOST_SCSI_MAX_TARGET; i++) {
                tpg = vs_tpg[i];
                if (tpg) {
+                       mutex_lock(&tpg->tv_tpg_mutex);
+                       tpg->vhost_scsi = NULL;
                        tpg->tv_tpg_vhost_count--;
+                       mutex_unlock(&tpg->tv_tpg_mutex);
                        target_undepend_item(&tpg->se_tpg.tpg_group.cg_item);
                }
        }
@@ -2032,19 +2021,11 @@ static int vhost_scsi_port_link(struct se_portal_group *se_tpg,
 {
        struct vhost_scsi_tpg *tpg = container_of(se_tpg,
                                struct vhost_scsi_tpg, se_tpg);
-       struct vhost_scsi_tmf *tmf;
-
-       tmf = kzalloc(sizeof(*tmf), GFP_KERNEL);
-       if (!tmf)
-               return -ENOMEM;
-       INIT_LIST_HEAD(&tmf->queue_entry);
-       vhost_work_init(&tmf->vwork, vhost_scsi_tmf_resp_work);
 
        mutex_lock(&vhost_scsi_mutex);
 
        mutex_lock(&tpg->tv_tpg_mutex);
        tpg->tv_tpg_port_count++;
-       list_add_tail(&tmf->queue_entry, &tpg->tmf_queue);
        mutex_unlock(&tpg->tv_tpg_mutex);
 
        vhost_scsi_hotplug(tpg, lun);
@@ -2059,16 +2040,11 @@ static void vhost_scsi_port_unlink(struct se_portal_group *se_tpg,
 {
        struct vhost_scsi_tpg *tpg = container_of(se_tpg,
                                struct vhost_scsi_tpg, se_tpg);
-       struct vhost_scsi_tmf *tmf;
 
        mutex_lock(&vhost_scsi_mutex);
 
        mutex_lock(&tpg->tv_tpg_mutex);
        tpg->tv_tpg_port_count--;
-       tmf = list_first_entry(&tpg->tmf_queue, struct vhost_scsi_tmf,
-                              queue_entry);
-       list_del(&tmf->queue_entry);
-       kfree(tmf);
        mutex_unlock(&tpg->tv_tpg_mutex);
 
        vhost_scsi_hotunplug(tpg, lun);
@@ -2329,7 +2305,6 @@ vhost_scsi_make_tpg(struct se_wwn *wwn, const char *name)
        }
        mutex_init(&tpg->tv_tpg_mutex);
        INIT_LIST_HEAD(&tpg->tv_tpg_list);
-       INIT_LIST_HEAD(&tpg->tmf_queue);
        tpg->tport = tport;
        tpg->tport_tpgt = tpgt;
 
index dc12dbd5b43ba6045078e621afd035e0b7946e8c..7be9d9d8f01c819d60e309ec1d6a83e46e03bf21 100644 (file)
@@ -1169,6 +1169,7 @@ static int vhost_vdpa_alloc_domain(struct vhost_vdpa *v)
 
 err_attach:
        iommu_domain_free(v->domain);
+       v->domain = NULL;
        return ret;
 }
 
@@ -1213,6 +1214,7 @@ static void vhost_vdpa_cleanup(struct vhost_vdpa *v)
                        vhost_vdpa_remove_as(v, asid);
        }
 
+       vhost_vdpa_free_domain(v);
        vhost_dev_cleanup(&v->vdev);
        kfree(v->vdev.vqs);
 }
@@ -1285,7 +1287,6 @@ static int vhost_vdpa_release(struct inode *inode, struct file *filep)
        vhost_vdpa_clean_irq(v);
        vhost_vdpa_reset(v);
        vhost_dev_stop(&v->vdev);
-       vhost_vdpa_free_domain(v);
        vhost_vdpa_config_put(v);
        vhost_vdpa_cleanup(v);
        mutex_unlock(&d->mutex);
index f11bdbe4c2c5ff712bd4fa929e77e8723a63c239..6d07b42833be4093b7c6a6f4b738e1b4ef800db9 100644 (file)
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/kthread.h>
-#include <linux/cgroup.h>
 #include <linux/module.h>
 #include <linux/sort.h>
 #include <linux/sched/mm.h>
 #include <linux/sched/signal.h>
+#include <linux/sched/vhost_task.h>
 #include <linux/interval_tree_generic.h>
 #include <linux/nospec.h>
 #include <linux/kcov.h>
@@ -255,8 +255,8 @@ void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work)
                 * sure it was not in the list.
                 * test_and_set_bit() implies a memory barrier.
                 */
-               llist_add(&work->node, &dev->work_list);
-               wake_up_process(dev->worker);
+               llist_add(&work->node, &dev->worker->work_list);
+               wake_up_process(dev->worker->vtsk->task);
        }
 }
 EXPORT_SYMBOL_GPL(vhost_work_queue);
@@ -264,7 +264,7 @@ EXPORT_SYMBOL_GPL(vhost_work_queue);
 /* A lockless hint for busy polling code to exit the loop */
 bool vhost_has_work(struct vhost_dev *dev)
 {
-       return !llist_empty(&dev->work_list);
+       return dev->worker && !llist_empty(&dev->worker->work_list);
 }
 EXPORT_SYMBOL_GPL(vhost_has_work);
 
@@ -335,22 +335,20 @@ static void vhost_vq_reset(struct vhost_dev *dev,
 
 static int vhost_worker(void *data)
 {
-       struct vhost_dev *dev = data;
+       struct vhost_worker *worker = data;
        struct vhost_work *work, *work_next;
        struct llist_node *node;
 
-       kthread_use_mm(dev->mm);
-
        for (;;) {
                /* mb paired w/ kthread_stop */
                set_current_state(TASK_INTERRUPTIBLE);
 
-               if (kthread_should_stop()) {
+               if (vhost_task_should_stop(worker->vtsk)) {
                        __set_current_state(TASK_RUNNING);
                        break;
                }
 
-               node = llist_del_all(&dev->work_list);
+               node = llist_del_all(&worker->work_list);
                if (!node)
                        schedule();
 
@@ -360,14 +358,14 @@ static int vhost_worker(void *data)
                llist_for_each_entry_safe(work, work_next, node, node) {
                        clear_bit(VHOST_WORK_QUEUED, &work->flags);
                        __set_current_state(TASK_RUNNING);
-                       kcov_remote_start_common(dev->kcov_handle);
+                       kcov_remote_start_common(worker->kcov_handle);
                        work->fn(work);
                        kcov_remote_stop();
                        if (need_resched())
                                schedule();
                }
        }
-       kthread_unuse_mm(dev->mm);
+
        return 0;
 }
 
@@ -479,7 +477,6 @@ void vhost_dev_init(struct vhost_dev *dev,
        dev->byte_weight = byte_weight;
        dev->use_worker = use_worker;
        dev->msg_handler = msg_handler;
-       init_llist_head(&dev->work_list);
        init_waitqueue_head(&dev->wait);
        INIT_LIST_HEAD(&dev->read_list);
        INIT_LIST_HEAD(&dev->pending_list);
@@ -509,31 +506,6 @@ long vhost_dev_check_owner(struct vhost_dev *dev)
 }
 EXPORT_SYMBOL_GPL(vhost_dev_check_owner);
 
-struct vhost_attach_cgroups_struct {
-       struct vhost_work work;
-       struct task_struct *owner;
-       int ret;
-};
-
-static void vhost_attach_cgroups_work(struct vhost_work *work)
-{
-       struct vhost_attach_cgroups_struct *s;
-
-       s = container_of(work, struct vhost_attach_cgroups_struct, work);
-       s->ret = cgroup_attach_task_all(s->owner, current);
-}
-
-static int vhost_attach_cgroups(struct vhost_dev *dev)
-{
-       struct vhost_attach_cgroups_struct attach;
-
-       attach.owner = current;
-       vhost_work_init(&attach.work, vhost_attach_cgroups_work);
-       vhost_work_queue(dev, &attach.work);
-       vhost_dev_flush(dev);
-       return attach.ret;
-}
-
 /* Caller should have device mutex */
 bool vhost_dev_has_owner(struct vhost_dev *dev)
 {
@@ -571,10 +543,54 @@ static void vhost_detach_mm(struct vhost_dev *dev)
        dev->mm = NULL;
 }
 
+static void vhost_worker_free(struct vhost_dev *dev)
+{
+       struct vhost_worker *worker = dev->worker;
+
+       if (!worker)
+               return;
+
+       dev->worker = NULL;
+       WARN_ON(!llist_empty(&worker->work_list));
+       vhost_task_stop(worker->vtsk);
+       kfree(worker);
+}
+
+static int vhost_worker_create(struct vhost_dev *dev)
+{
+       struct vhost_worker *worker;
+       struct vhost_task *vtsk;
+       char name[TASK_COMM_LEN];
+       int ret;
+
+       worker = kzalloc(sizeof(*worker), GFP_KERNEL_ACCOUNT);
+       if (!worker)
+               return -ENOMEM;
+
+       dev->worker = worker;
+       worker->kcov_handle = kcov_common_handle();
+       init_llist_head(&worker->work_list);
+       snprintf(name, sizeof(name), "vhost-%d", current->pid);
+
+       vtsk = vhost_task_create(vhost_worker, worker, name);
+       if (!vtsk) {
+               ret = -ENOMEM;
+               goto free_worker;
+       }
+
+       worker->vtsk = vtsk;
+       vhost_task_start(vtsk);
+       return 0;
+
+free_worker:
+       kfree(worker);
+       dev->worker = NULL;
+       return ret;
+}
+
 /* Caller should have device mutex */
 long vhost_dev_set_owner(struct vhost_dev *dev)
 {
-       struct task_struct *worker;
        int err;
 
        /* Is there an owner already? */
@@ -585,36 +601,21 @@ long vhost_dev_set_owner(struct vhost_dev *dev)
 
        vhost_attach_mm(dev);
 
-       dev->kcov_handle = kcov_common_handle();
        if (dev->use_worker) {
-               worker = kthread_create(vhost_worker, dev,
-                                       "vhost-%d", current->pid);
-               if (IS_ERR(worker)) {
-                       err = PTR_ERR(worker);
-                       goto err_worker;
-               }
-
-               dev->worker = worker;
-               wake_up_process(worker); /* avoid contributing to loadavg */
-
-               err = vhost_attach_cgroups(dev);
+               err = vhost_worker_create(dev);
                if (err)
-                       goto err_cgroup;
+                       goto err_worker;
        }
 
        err = vhost_dev_alloc_iovecs(dev);
        if (err)
-               goto err_cgroup;
+               goto err_iovecs;
 
        return 0;
-err_cgroup:
-       if (dev->worker) {
-               kthread_stop(dev->worker);
-               dev->worker = NULL;
-       }
+err_iovecs:
+       vhost_worker_free(dev);
 err_worker:
        vhost_detach_mm(dev);
-       dev->kcov_handle = 0;
 err_mm:
        return err;
 }
@@ -705,12 +706,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev)
        dev->iotlb = NULL;
        vhost_clear_msg(dev);
        wake_up_interruptible_poll(&dev->wait, EPOLLIN | EPOLLRDNORM);
-       WARN_ON(!llist_empty(&dev->work_list));
-       if (dev->worker) {
-               kthread_stop(dev->worker);
-               dev->worker = NULL;
-               dev->kcov_handle = 0;
-       }
+       vhost_worker_free(dev);
        vhost_detach_mm(dev);
 }
 EXPORT_SYMBOL_GPL(vhost_dev_cleanup);
@@ -1831,7 +1827,7 @@ EXPORT_SYMBOL_GPL(vhost_dev_ioctl);
 
 /* TODO: This is really inefficient.  We need something like get_user()
  * (instruction directly accesses the data, with an exception table entry
- * returning -EFAULT). See Documentation/x86/exception-tables.rst.
+ * returning -EFAULT). See Documentation/arch/x86/exception-tables.rst.
  */
 static int set_bit_to_user(int nr, void __user *addr)
 {
index 1647b750169c79363b8e9ea3ac9c667d0af6af69..0308638cdeeebef46ca0ad98994eb8c6edd803f4 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/irqbypass.h>
 
 struct vhost_work;
+struct vhost_task;
 typedef void (*vhost_work_fn_t)(struct vhost_work *work);
 
 #define VHOST_WORK_QUEUED 1
@@ -25,6 +26,12 @@ struct vhost_work {
        unsigned long           flags;
 };
 
+struct vhost_worker {
+       struct vhost_task       *vtsk;
+       struct llist_head       work_list;
+       u64                     kcov_handle;
+};
+
 /* Poll a file (eventfd or socket) */
 /* Note: there's nothing vhost specific about this structure. */
 struct vhost_poll {
@@ -147,8 +154,7 @@ struct vhost_dev {
        struct vhost_virtqueue **vqs;
        int nvqs;
        struct eventfd_ctx *log_ctx;
-       struct llist_head work_list;
-       struct task_struct *worker;
+       struct vhost_worker *worker;
        struct vhost_iotlb *umem;
        struct vhost_iotlb *iotlb;
        spinlock_t iotlb_lock;
@@ -158,7 +164,6 @@ struct vhost_dev {
        int iov_limit;
        int weight;
        int byte_weight;
-       u64 kcov_handle;
        bool use_worker;
        int (*msg_handler)(struct vhost_dev *dev, u32 asid,
                           struct vhost_iotlb_msg *msg);
index f65c96d1394d3257a93dfc1b1ad82bb3432cf4ed..e45338227be6e03e102b2cf06a95d5afffa21d13 100644 (file)
@@ -854,7 +854,7 @@ static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev)
        board->caps = CLCD_CAP_ALL;
        board->check = clcdfb_check;
        board->decode = clcdfb_decode;
-       if (of_find_property(node, "memory-region", NULL)) {
+       if (of_property_present(node, "memory-region")) {
                board->setup = clcdfb_of_vram_setup;
                board->mmap = clcdfb_of_vram_mmap;
                board->remove = clcdfb_of_vram_remove;
index 81c3154544287763a30ff522e05bdc6305e51f21..b6b22fa4a8a01360095c3549dc63800f6dd0ddf9 100644 (file)
@@ -1040,6 +1040,9 @@ static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
        u32 pixclock;
        int screen_size, plane;
 
+       if (!var->pixclock)
+               return -EINVAL;
+
        plane = fbdev->plane;
 
        /* Make sure that the mode respect all LCD controller and
index 6403ae07970d6cbd7110f7b781627d628e69fd83..9cbadcd18b256c4ff0e525f7d09867d377d1028f 100644 (file)
@@ -306,7 +306,7 @@ static int bw2_probe(struct platform_device *op)
        if (!par->regs)
                goto out_release_fb;
 
-       if (!of_find_property(dp, "width", NULL)) {
+       if (!of_property_present(dp, "width")) {
                err = bw2_do_default_mode(par, info, &linebytes);
                if (err)
                        goto out_unmap_regs;
index bdcc3f6ab6665b6b31984f0e05b0c0bf4e594695..3a37fff4df3664df0ddf608f2908298a7bd3aa84 100644 (file)
@@ -393,7 +393,7 @@ static int cg3_probe(struct platform_device *op)
 
        cg3_blank(FB_BLANK_UNBLANK, info);
 
-       if (!of_find_property(dp, "width", NULL)) {
+       if (!of_property_present(dp, "width")) {
                err = cg3_do_default_mode(par);
                if (err)
                        goto out_unmap_screen;
index cc37ec3f8fc1f466af20402ff1254f1e780fcaff..7799d52a651f3273a8280f36e1c9174d15c50d52 100644 (file)
@@ -358,16 +358,21 @@ static int chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
        if (rc)
                return rc;
 
-       if (pci_enable_device(dp) < 0) {
+       rc = pci_enable_device(dp);
+       if (rc < 0) {
                dev_err(&dp->dev, "Cannot enable PCI device\n");
                goto err_out;
        }
 
-       if ((dp->resource[0].flags & IORESOURCE_MEM) == 0)
+       if ((dp->resource[0].flags & IORESOURCE_MEM) == 0) {
+               rc = -ENODEV;
                goto err_disable;
+       }
        addr = pci_resource_start(dp, 0);
-       if (addr == 0)
+       if (addr == 0) {
+               rc = -ENODEV;
                goto err_disable;
+       }
 
        p = framebuffer_alloc(0, &dp->dev);
        if (p == NULL) {
@@ -417,7 +422,8 @@ static int chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
 
        init_chips(p, addr);
 
-       if (register_framebuffer(p) < 0) {
+       rc = register_framebuffer(p);
+       if (rc < 0) {
                dev_err(&dp->dev,"C&T 65550 framebuffer failed to register\n");
                goto err_unmap;
        }
index 45c75ff01eca4d938a496f0d37cc46d165aa717e..c8bfc608bd9c11ea61d48d3373abaa61e669d5b4 100644 (file)
@@ -238,8 +238,7 @@ static int clps711x_fb_probe(struct platform_device *pdev)
        info->fix.mmio_start = res->start;
        info->fix.mmio_len = resource_size(res);
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-       info->screen_base = devm_ioremap_resource(dev, res);
+       info->screen_base = devm_platform_get_and_ioremap_resource(pdev, 1, &res);
        if (IS_ERR(info->screen_base)) {
                ret = PTR_ERR(info->screen_base);
                goto out_fb_release;
index aa5f059d022271c3ffe879edbd2d5027b51c710a..274f5d0fa24714ab31a7a6fcb1aa1667bda78c8a 100644 (file)
@@ -305,17 +305,18 @@ void fb_deferred_io_open(struct fb_info *info,
                         struct inode *inode,
                         struct file *file)
 {
+       struct fb_deferred_io *fbdefio = info->fbdefio;
+
        file->f_mapping->a_ops = &fb_deferred_io_aops;
+       fbdefio->open_count++;
 }
 EXPORT_SYMBOL_GPL(fb_deferred_io_open);
 
-void fb_deferred_io_release(struct fb_info *info)
+static void fb_deferred_io_lastclose(struct fb_info *info)
 {
-       struct fb_deferred_io *fbdefio = info->fbdefio;
        struct page *page;
        int i;
 
-       BUG_ON(!fbdefio);
        cancel_delayed_work_sync(&info->deferred_work);
 
        /* clear out the mapping that we setup */
@@ -324,13 +325,21 @@ void fb_deferred_io_release(struct fb_info *info)
                page->mapping = NULL;
        }
 }
+
+void fb_deferred_io_release(struct fb_info *info)
+{
+       struct fb_deferred_io *fbdefio = info->fbdefio;
+
+       if (!--fbdefio->open_count)
+               fb_deferred_io_lastclose(info);
+}
 EXPORT_SYMBOL_GPL(fb_deferred_io_release);
 
 void fb_deferred_io_cleanup(struct fb_info *info)
 {
        struct fb_deferred_io *fbdefio = info->fbdefio;
 
-       fb_deferred_io_release(info);
+       fb_deferred_io_lastclose(info);
 
        kvfree(info->pagerefs);
        mutex_destroy(&fbdefio->lock);
index 0a2c47df01f402b2221777a2d5ba78e748ceb43c..eb565a10e5cda306fb3f12b837d57a311599fb95 100644 (file)
@@ -823,7 +823,7 @@ static int set_con2fb_map(int unit, int newidx, int user)
        int oldidx = con2fb_map[unit];
        struct fb_info *info = fbcon_registered_fb[newidx];
        struct fb_info *oldinfo = NULL;
-       int found, err = 0, show_logo;
+       int err = 0, show_logo;
 
        WARN_CONSOLE_UNLOCKED();
 
@@ -841,26 +841,26 @@ static int set_con2fb_map(int unit, int newidx, int user)
        if (oldidx != -1)
                oldinfo = fbcon_registered_fb[oldidx];
 
-       found = search_fb_in_map(newidx);
-
-       if (!err && !found) {
+       if (!search_fb_in_map(newidx)) {
                err = con2fb_acquire_newinfo(vc, info, unit);
-               if (!err)
-                       con2fb_map[unit] = newidx;
+               if (err)
+                       return err;
+
+               fbcon_add_cursor_work(info);
        }
 
+       con2fb_map[unit] = newidx;
+
        /*
         * If old fb is not mapped to any of the consoles,
         * fbcon should release it.
         */
-       if (!err && oldinfo && !search_fb_in_map(oldidx))
+       if (oldinfo && !search_fb_in_map(oldidx))
                con2fb_release_oldinfo(vc, oldinfo, info);
 
        show_logo = (fg_console == 0 && !user &&
                         logo_shown != FBCON_LOGO_DONTSHOW);
 
-       if (!found)
-               fbcon_add_cursor_work(info);
        con2fb_map_boot[unit] = newidx;
        con2fb_init_display(vc, info, unit, show_logo);
 
index 875541ff185bf365f2a046e55c2421d50790649a..3fd95a79e4c334674e2bd6fdcecda747cdcd6c8c 100644 (file)
@@ -1116,6 +1116,8 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
        case FBIOPUT_VSCREENINFO:
                if (copy_from_user(&var, argp, sizeof(var)))
                        return -EFAULT;
+               /* only for kernel-internal use */
+               var.activate &= ~FB_ACTIVATE_KD_TEXT;
                console_lock();
                lock_fb_info(info);
                ret = fbcon_modechange_possible(info, &var);
index 8130e9eee2b4b4151a202358d0ce9d69964530de..556d8b1a9e06aefd6ec34796d9a60963c733f956 100644 (file)
@@ -235,6 +235,9 @@ static void get_modedb(struct fb_videomode **modedb, unsigned int *size)
 
 static int lxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
+       if (!var->pixclock)
+               return -EINVAL;
+
        if (var->xres > 1920 || var->yres > 1440)
                return -EINVAL;
 
index 0a9e5067b201083be2b74654b7c60ea89b575d43..a81095b2b1ea592e6eaabc03f0f880d459e9e1fd 100644 (file)
@@ -1222,6 +1222,9 @@ static int intelfb_check_var(struct fb_var_screeninfo *var,
 
        dinfo = GET_DINFO(info);
 
+       if (!var->pixclock)
+               return -EINVAL;
+
        /* update the pitch */
        if (intelfbhw_validate_mode(dinfo, var) != 0)
                return -EINVAL;
index e60a276b4855dcddd06a6ffbe46220b161bba7d5..ea4ba3dfb96bb51d149c0e288286269bc1a1ad0f 100644 (file)
@@ -764,6 +764,8 @@ static int nvidiafb_check_var(struct fb_var_screeninfo *var,
        int pitch, err = 0;
 
        NVTRACE_ENTER();
+       if (!var->pixclock)
+               return -EINVAL;
 
        var->transp.offset = 0;
        var->transp.length = 0;
index f7ad6bc9d02d718e3c10818000554005f3978e49..b97d251d894b7a9100f76b1f0eff7d2f20694e69 100644 (file)
@@ -549,10 +549,10 @@ static void offb_init_nodriver(struct platform_device *parent, struct device_nod
        int foreign_endian = 0;
 
 #ifdef __BIG_ENDIAN
-       if (of_get_property(dp, "little-endian", NULL))
+       if (of_property_read_bool(dp, "little-endian"))
                foreign_endian = FBINFO_FOREIGN_ENDIAN;
 #else
-       if (of_get_property(dp, "big-endian", NULL))
+       if (of_property_read_bool(dp, "big-endian"))
                foreign_endian = FBINFO_FOREIGN_ENDIAN;
 #endif
 
index 504edb9c09dd832dbe097581f903196ddc668faf..6d5082c76919d9ba26e168c1c2ef99622e143e7d 100644 (file)
@@ -18,7 +18,6 @@ objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o
 
 lcds-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o
 lcds-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o
-lcds-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o
 
 lcds-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o
 
diff --git a/drivers/video/fbdev/omap/lcd_osk.c b/drivers/video/fbdev/omap/lcd_osk.c
deleted file mode 100644 (file)
index 8168ba0..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * LCD panel support for the TI OMAP OSK board
- *
- * Copyright (C) 2004 Nokia Corporation
- * Author: Imre Deak <imre.deak@nokia.com>
- * Adapted for OSK by <dirk.behme@de.bosch.com>
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-
-#include <linux/soc/ti/omap1-io.h>
-#include <linux/soc/ti/omap1-mux.h>
-
-#include "omapfb.h"
-
-static int osk_panel_enable(struct lcd_panel *panel)
-{
-       /* configure PWL pin */
-       omap_cfg_reg(PWL);
-
-       /* Enable PWL unit */
-       omap_writeb(0x01, OMAP_PWL_CLK_ENABLE);
-
-       /* Set PWL level */
-       omap_writeb(0xFF, OMAP_PWL_ENABLE);
-
-       /* set GPIO2 high (lcd power enabled) */
-       gpio_set_value(2, 1);
-
-       return 0;
-}
-
-static void osk_panel_disable(struct lcd_panel *panel)
-{
-       /* Set PWL level to zero */
-       omap_writeb(0x00, OMAP_PWL_ENABLE);
-
-       /* Disable PWL unit */
-       omap_writeb(0x00, OMAP_PWL_CLK_ENABLE);
-
-       /* set GPIO2 low */
-       gpio_set_value(2, 0);
-}
-
-static struct lcd_panel osk_panel = {
-       .name           = "osk",
-       .config         = OMAP_LCDC_PANEL_TFT,
-
-       .bpp            = 16,
-       .data_lines     = 16,
-       .x_res          = 240,
-       .y_res          = 320,
-       .pixel_clock    = 12500,
-       .hsw            = 40,
-       .hfp            = 40,
-       .hbp            = 72,
-       .vsw            = 1,
-       .vfp            = 1,
-       .vbp            = 0,
-       .pcd            = 12,
-
-       .enable         = osk_panel_enable,
-       .disable        = osk_panel_disable,
-};
-
-static int osk_panel_probe(struct platform_device *pdev)
-{
-       omapfb_register_panel(&osk_panel);
-       return 0;
-}
-
-static struct platform_driver osk_panel_driver = {
-       .probe          = osk_panel_probe,
-       .driver         = {
-               .name   = "lcd_osk",
-       },
-};
-
-module_platform_driver(osk_panel_driver);
-
-MODULE_AUTHOR("Imre Deak");
-MODULE_DESCRIPTION("LCD panel support for the TI OMAP OSK board");
-MODULE_LICENSE("GPL");
index 1f3df2055ff0d5670cc8b1b79a25937413f79a88..18736079843dca4b6fd92a4b46b9db7388abfa41 100644 (file)
@@ -544,19 +544,25 @@ static int set_fb_var(struct fb_info *fbi,
                var->yoffset = var->yres_virtual - var->yres;
 
        if (plane->color_mode == OMAPFB_COLOR_RGB444) {
-               var->red.offset   = 8; var->red.length   = 4;
-                                               var->red.msb_right   = 0;
-               var->green.offset = 4; var->green.length = 4;
-                                               var->green.msb_right = 0;
-               var->blue.offset  = 0; var->blue.length  = 4;
-                                               var->blue.msb_right  = 0;
+               var->red.offset         = 8;
+               var->red.length         = 4;
+               var->red.msb_right      = 0;
+               var->green.offset       = 4;
+               var->green.length       = 4;
+               var->green.msb_right    = 0;
+               var->blue.offset        = 0;
+               var->blue.length        = 4;
+               var->blue.msb_right     = 0;
        } else {
-               var->red.offset  = 11; var->red.length   = 5;
-                                               var->red.msb_right   = 0;
-               var->green.offset = 5;  var->green.length = 6;
-                                               var->green.msb_right = 0;
-               var->blue.offset = 0;  var->blue.length  = 5;
-                                               var->blue.msb_right  = 0;
+               var->red.offset         = 11;
+               var->red.length         = 5;
+               var->red.msb_right      = 0;
+               var->green.offset       = 5;
+               var->green.length       = 6;
+               var->green.msb_right    = 0;
+               var->blue.offset        = 0;
+               var->blue.length        = 5;
+               var->blue.msb_right     = 0;
        }
 
        var->height             = -1;
index 0ae0cab252d3d0460e8b713f37496a3235872357..09f719af0d0c914c9b62b52b3549fb2b98037101 100644 (file)
@@ -192,7 +192,7 @@ static int __init omapdss_boot_init(void)
        omapdss_walk_device(dss, true);
 
        for_each_available_child_of_node(dss, child) {
-               if (!of_find_property(child, "compatible", NULL))
+               if (!of_property_present(child, "compatible"))
                        continue;
 
                omapdss_walk_device(child, true);
index c3cd1e1cc01b497fe2eaf8b0d5f368790a4e76a9..d16729215423d0909620d72b39b036452304743b 100644 (file)
@@ -599,8 +599,7 @@ static int pxa3xx_gcu_probe(struct platform_device *pdev)
        priv->misc_dev.fops     = &pxa3xx_gcu_miscdev_fops;
 
        /* handle IO resources */
-       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       priv->mmio_base = devm_ioremap_resource(dev, r);
+       priv->mmio_base = devm_platform_get_and_ioremap_resource(pdev, 0, &r);
        if (IS_ERR(priv->mmio_base))
                return PTR_ERR(priv->mmio_base);
 
index f743bfbde2a6cb02e98fde4bbee27ddb2cf7b452..1f3cbe723def139e1f5cea1614d6e09c72c82028 100644 (file)
@@ -1737,10 +1737,10 @@ static int sm501fb_init_fb(struct fb_info *fb, enum sm501_controller head,
 
 #if defined(CONFIG_OF)
 #ifdef __BIG_ENDIAN
-       if (of_get_property(info->dev->parent->of_node, "little-endian", NULL))
+       if (of_property_read_bool(info->dev->parent->of_node, "little-endian"))
                fb->flags |= FBINFO_FOREIGN_ENDIAN;
 #else
-       if (of_get_property(info->dev->parent->of_node, "big-endian", NULL))
+       if (of_property_read_bool(info->dev->parent->of_node, "big-endian"))
                fb->flags |= FBINFO_FOREIGN_ENDIAN;
 #endif
 #endif
index 3feb6e40d56d8c8db1ba4699dde09465050e1ec8..ef8a4c5fc6875c55e180eea152e84e72c55c39d0 100644 (file)
@@ -921,6 +921,28 @@ SETUP_HCRX(struct stifb_info *fb)
 
 /* ------------------- driver specific functions --------------------------- */
 
+static int
+stifb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+       struct stifb_info *fb = container_of(info, struct stifb_info, info);
+
+       if (var->xres != fb->info.var.xres ||
+           var->yres != fb->info.var.yres ||
+           var->bits_per_pixel != fb->info.var.bits_per_pixel)
+               return -EINVAL;
+
+       var->xres_virtual = var->xres;
+       var->yres_virtual = var->yres;
+       var->xoffset = 0;
+       var->yoffset = 0;
+       var->grayscale = fb->info.var.grayscale;
+       var->red.length = fb->info.var.red.length;
+       var->green.length = fb->info.var.green.length;
+       var->blue.length = fb->info.var.blue.length;
+
+       return 0;
+}
+
 static int
 stifb_setcolreg(u_int regno, u_int red, u_int green,
              u_int blue, u_int transp, struct fb_info *info)
@@ -1145,6 +1167,7 @@ stifb_init_display(struct stifb_info *fb)
 
 static const struct fb_ops stifb_ops = {
        .owner          = THIS_MODULE,
+       .fb_check_var   = stifb_check_var,
        .fb_setcolreg   = stifb_setcolreg,
        .fb_blank       = stifb_blank,
        .fb_fillrect    = stifb_fillrect,
@@ -1164,6 +1187,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
        struct stifb_info *fb;
        struct fb_info *info;
        unsigned long sti_rom_address;
+       char modestr[32];
        char *dev_name;
        int bpp, xres, yres;
 
@@ -1342,6 +1366,9 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
        info->flags = FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT;
        info->pseudo_palette = &fb->pseudo_palette;
 
+       scnprintf(modestr, sizeof(modestr), "%dx%d-%d", xres, yres, bpp);
+       fb_find_mode(&info->var, info, modestr, NULL, 0, NULL, bpp);
+
        /* This has to be done !!! */
        if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0))
                goto out_err1;
index 01d87f53324d985452afb511f343d16ab67ec0dd..f2eaf6e7fff604de0a191939d53120a182e5c3b5 100644 (file)
@@ -379,8 +379,7 @@ static int tcx_probe(struct platform_device *op)
 
        spin_lock_init(&par->lock);
 
-       par->lowdepth =
-               (of_find_property(dp, "tcx-8-bit", NULL) != NULL);
+       par->lowdepth = of_property_read_bool(dp, "tcx-8-bit");
 
        sbusfb_fill_var(&info->var, dp, 8);
        info->var.red.length = 8;
index 14d37c49633c6b36819bda002333b4d63b199795..b44004880f0d1e25119ab9028aafc9acd0c61177 100644 (file)
@@ -173,6 +173,9 @@ tgafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
        struct tga_par *par = (struct tga_par *)info->par;
 
+       if (!var->pixclock)
+               return -EINVAL;
+
        if (par->tga_type == TGA_TYPE_8PLANE) {
                if (var->bits_per_pixel != 8)
                        return -EINVAL;
index 8f4d674fa0d03892ea22bf3ecb8bd8f355890b03..96a6f7623e197396ed7231215df7df3d9ff1d8e7 100644 (file)
@@ -261,7 +261,6 @@ static const struct fb_ops wm8505fb_ops = {
 static int wm8505fb_probe(struct platform_device *pdev)
 {
        struct wm8505fb_info    *fbi;
-       struct resource *res;
        struct display_timings *disp_timing;
        void                    *addr;
        int ret;
@@ -299,8 +298,7 @@ static int wm8505fb_probe(struct platform_device *pdev)
        addr = addr + sizeof(struct wm8505fb_info);
        fbi->fb.pseudo_palette  = addr;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       fbi->regbase = devm_ioremap_resource(&pdev->dev, res);
+       fbi->regbase = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(fbi->regbase))
                return PTR_ERR(fbi->regbase);
 
index 1ac83900a21ccef301d2a0557549b610bbe46127..7911354827dc25042720884f408c11a98ae373bd 100644 (file)
@@ -273,8 +273,7 @@ static int xilinxfb_assign(struct platform_device *pdev,
        if (drvdata->flags & BUS_ACCESS_FLAG) {
                struct resource *res;
 
-               res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-               drvdata->regs = devm_ioremap_resource(&pdev->dev, res);
+               drvdata->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
                if (IS_ERR(drvdata->regs))
                        return PTR_ERR(drvdata->regs);
 
@@ -469,8 +468,7 @@ static int xilinxfb_of_probe(struct platform_device *pdev)
                pdata.yvirt = prop[1];
        }
 
-       if (of_find_property(pdev->dev.of_node, "rotate-display", NULL))
-               pdata.rotate_screen = 1;
+       pdata.rotate_screen = of_property_read_bool(pdev->dev.of_node, "rotate-display");
 
        platform_set_drvdata(pdev, drvdata);
        return xilinxfb_assign(pdev, drvdata, &pdata);
index 4718d7895f0b451e4a529a4e1fcce6a85ec5a4c5..ada5ef6e51b7a9f61159101b39e5c299b010e61a 100644 (file)
@@ -1,15 +1,9 @@
-
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  *  Convert a logo in ASCII PNM format to C source suitable for inclusion in
  *  the Linux kernel
  *
  *  (C) Copyright 2001-2003 by Geert Uytterhoeven <geert@linux-m68k.org>
- *
- *  --------------------------------------------------------------------------
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License. See the file COPYING in the main directory of the Linux
- *  distribution for more details.
  */
 
 #include <ctype.h>
@@ -34,37 +28,37 @@ static FILE *out;
 #define LINUX_LOGO_GRAY256     4       /* 256 levels grayscale */
 
 static const char *logo_types[LINUX_LOGO_GRAY256+1] = {
-    [LINUX_LOGO_MONO] = "LINUX_LOGO_MONO",
-    [LINUX_LOGO_VGA16] = "LINUX_LOGO_VGA16",
-    [LINUX_LOGO_CLUT224] = "LINUX_LOGO_CLUT224",
-    [LINUX_LOGO_GRAY256] = "LINUX_LOGO_GRAY256"
+       [LINUX_LOGO_MONO] = "LINUX_LOGO_MONO",
+       [LINUX_LOGO_VGA16] = "LINUX_LOGO_VGA16",
+       [LINUX_LOGO_CLUT224] = "LINUX_LOGO_CLUT224",
+       [LINUX_LOGO_GRAY256] = "LINUX_LOGO_GRAY256"
 };
 
 #define MAX_LINUX_LOGO_COLORS  224
 
 struct color {
-    unsigned char red;
-    unsigned char green;
-    unsigned char blue;
+       unsigned char red;
+       unsigned char green;
+       unsigned char blue;
 };
 
 static const struct color clut_vga16[16] = {
-    { 0x00, 0x00, 0x00 },
-    { 0x00, 0x00, 0xaa },
-    { 0x00, 0xaa, 0x00 },
-    { 0x00, 0xaa, 0xaa },
-    { 0xaa, 0x00, 0x00 },
-    { 0xaa, 0x00, 0xaa },
-    { 0xaa, 0x55, 0x00 },
-    { 0xaa, 0xaa, 0xaa },
-    { 0x55, 0x55, 0x55 },
-    { 0x55, 0x55, 0xff },
-    { 0x55, 0xff, 0x55 },
-    { 0x55, 0xff, 0xff },
-    { 0xff, 0x55, 0x55 },
-    { 0xff, 0x55, 0xff },
-    { 0xff, 0xff, 0x55 },
-    { 0xff, 0xff, 0xff },
+       { 0x00, 0x00, 0x00 },
+       { 0x00, 0x00, 0xaa },
+       { 0x00, 0xaa, 0x00 },
+       { 0x00, 0xaa, 0xaa },
+       { 0xaa, 0x00, 0x00 },
+       { 0xaa, 0x00, 0xaa },
+       { 0xaa, 0x55, 0x00 },
+       { 0xaa, 0xaa, 0xaa },
+       { 0x55, 0x55, 0x55 },
+       { 0x55, 0x55, 0xff },
+       { 0x55, 0xff, 0x55 },
+       { 0x55, 0xff, 0xff },
+       { 0xff, 0x55, 0x55 },
+       { 0xff, 0x55, 0xff },
+       { 0xff, 0xff, 0x55 },
+       { 0xff, 0xff, 0xff },
 };
 
 
@@ -77,438 +71,440 @@ static unsigned int logo_clutsize;
 static int is_plain_pbm = 0;
 
 static void die(const char *fmt, ...)
-    __attribute__ ((noreturn)) __attribute ((format (printf, 1, 2)));
-static void usage(void) __attribute ((noreturn));
+__attribute__((noreturn)) __attribute((format (printf, 1, 2)));
+static void usage(void) __attribute((noreturn));
 
 
 static unsigned int get_number(FILE *fp)
 {
-    int c, val;
-
-    /* Skip leading whitespace */
-    do {
-       c = fgetc(fp);
-       if (c == EOF)
-           die("%s: end of file\n", filename);
-       if (c == '#') {
-           /* Ignore comments 'till end of line */
-           do {
+       int c, val;
+
+       /* Skip leading whitespace */
+       do {
                c = fgetc(fp);
                if (c == EOF)
-                   die("%s: end of file\n", filename);
-           } while (c != '\n');
+                       die("%s: end of file\n", filename);
+               if (c == '#') {
+                       /* Ignore comments 'till end of line */
+                       do {
+                               c = fgetc(fp);
+                               if (c == EOF)
+                                       die("%s: end of file\n", filename);
+                       } while (c != '\n');
+               }
+       } while (isspace(c));
+
+       /* Parse decimal number */
+       val = 0;
+       while (isdigit(c)) {
+               val = 10*val+c-'0';
+               /* some PBM are 'broken'; GiMP for example exports a PBM without space
+                * between the digits. This is Ok cause we know a PBM can only have a '1'
+                * or a '0' for the digit.
+                */
+               if (is_plain_pbm)
+                       break;
+               c = fgetc(fp);
+               if (c == EOF)
+                       die("%s: end of file\n", filename);
        }
-    } while (isspace(c));
-
-    /* Parse decimal number */
-    val = 0;
-    while (isdigit(c)) {
-       val = 10*val+c-'0';
-       /* some PBM are 'broken'; GiMP for example exports a PBM without space
-        * between the digits. This is Ok cause we know a PBM can only have a '1'
-        * or a '0' for the digit. */
-       if (is_plain_pbm)
-               break;
-       c = fgetc(fp);
-       if (c == EOF)
-           die("%s: end of file\n", filename);
-    }
-    return val;
+       return val;
 }
 
 static unsigned int get_number255(FILE *fp, unsigned int maxval)
 {
-    unsigned int val = get_number(fp);
-    return (255*val+maxval/2)/maxval;
+       unsigned int val = get_number(fp);
+
+       return (255*val+maxval/2)/maxval;
 }
 
 static void read_image(void)
 {
-    FILE *fp;
-    unsigned int i, j;
-    int magic;
-    unsigned int maxval;
-
-    /* open image file */
-    fp = fopen(filename, "r");
-    if (!fp)
-       die("Cannot open file %s: %s\n", filename, strerror(errno));
-
-    /* check file type and read file header */
-    magic = fgetc(fp);
-    if (magic != 'P')
-       die("%s is not a PNM file\n", filename);
-    magic = fgetc(fp);
-    switch (magic) {
+       FILE *fp;
+       unsigned int i, j;
+       int magic;
+       unsigned int maxval;
+
+       /* open image file */
+       fp = fopen(filename, "r");
+       if (!fp)
+               die("Cannot open file %s: %s\n", filename, strerror(errno));
+
+       /* check file type and read file header */
+       magic = fgetc(fp);
+       if (magic != 'P')
+               die("%s is not a PNM file\n", filename);
+       magic = fgetc(fp);
+       switch (magic) {
        case '1':
        case '2':
        case '3':
-           /* Plain PBM/PGM/PPM */
-           break;
+               /* Plain PBM/PGM/PPM */
+               break;
 
        case '4':
        case '5':
        case '6':
-           /* Binary PBM/PGM/PPM */
-           die("%s: Binary PNM is not supported\n"
+               /* Binary PBM/PGM/PPM */
+               die("%s: Binary PNM is not supported\n"
                "Use pnmnoraw(1) to convert it to ASCII PNM\n", filename);
 
        default:
-           die("%s is not a PNM file\n", filename);
-    }
-    logo_width = get_number(fp);
-    logo_height = get_number(fp);
-
-    /* allocate image data */
-    logo_data = (struct color **)malloc(logo_height*sizeof(struct color *));
-    if (!logo_data)
-       die("%s\n", strerror(errno));
-    for (i = 0; i < logo_height; i++) {
-       logo_data[i] = malloc(logo_width*sizeof(struct color));
+               die("%s is not a PNM file\n", filename);
+       }
+       logo_width = get_number(fp);
+       logo_height = get_number(fp);
+
+       /* allocate image data */
+       logo_data = (struct color **)malloc(logo_height*sizeof(struct color *));
+       if (!logo_data)
+               die("%s\n", strerror(errno));
+       for (i = 0; i < logo_height; i++) {
+               logo_data[i] = malloc(logo_width*sizeof(struct color));
        if (!logo_data[i])
-           die("%s\n", strerror(errno));
-    }
+               die("%s\n", strerror(errno));
+       }
 
-    /* read image data */
-    switch (magic) {
+       /* read image data */
+       switch (magic) {
        case '1':
-           /* Plain PBM */
-           is_plain_pbm = 1;
-           for (i = 0; i < logo_height; i++)
-               for (j = 0; j < logo_width; j++)
-                   logo_data[i][j].red = logo_data[i][j].green =
-                       logo_data[i][j].blue = 255*(1-get_number(fp));
-           break;
+               /* Plain PBM */
+               is_plain_pbm = 1;
+               for (i = 0; i < logo_height; i++)
+                       for (j = 0; j < logo_width; j++)
+                               logo_data[i][j].red = logo_data[i][j].green =
+                                       logo_data[i][j].blue = 255*(1-get_number(fp));
+               break;
 
        case '2':
-           /* Plain PGM */
-           maxval = get_number(fp);
-           for (i = 0; i < logo_height; i++)
-               for (j = 0; j < logo_width; j++)
-                   logo_data[i][j].red = logo_data[i][j].green =
-                       logo_data[i][j].blue = get_number255(fp, maxval);
-           break;
+               /* Plain PGM */
+               maxval = get_number(fp);
+               for (i = 0; i < logo_height; i++)
+                       for (j = 0; j < logo_width; j++)
+                               logo_data[i][j].red = logo_data[i][j].green =
+                                       logo_data[i][j].blue = get_number255(fp, maxval);
+               break;
 
        case '3':
-           /* Plain PPM */
-           maxval = get_number(fp);
-           for (i = 0; i < logo_height; i++)
-               for (j = 0; j < logo_width; j++) {
-                   logo_data[i][j].red = get_number255(fp, maxval);
-                   logo_data[i][j].green = get_number255(fp, maxval);
-                   logo_data[i][j].blue = get_number255(fp, maxval);
-               }
-           break;
-    }
+               /* Plain PPM */
+               maxval = get_number(fp);
+               for (i = 0; i < logo_height; i++)
+                       for (j = 0; j < logo_width; j++) {
+                               logo_data[i][j].red = get_number255(fp, maxval);
+                               logo_data[i][j].green = get_number255(fp, maxval);
+                               logo_data[i][j].blue = get_number255(fp, maxval);
+                       }
+               break;
+       }
 
-    /* close file */
-    fclose(fp);
+       /* close file */
+       fclose(fp);
 }
 
 static inline int is_black(struct color c)
 {
-    return c.red == 0 && c.green == 0 && c.blue == 0;
+       return c.red == 0 && c.green == 0 && c.blue == 0;
 }
 
 static inline int is_white(struct color c)
 {
-    return c.red == 255 && c.green == 255 && c.blue == 255;
+       return c.red == 255 && c.green == 255 && c.blue == 255;
 }
 
 static inline int is_gray(struct color c)
 {
-    return c.red == c.green && c.red == c.blue;
+       return c.red == c.green && c.red == c.blue;
 }
 
 static inline int is_equal(struct color c1, struct color c2)
 {
-    return c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue;
+       return c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue;
 }
 
 static void write_header(void)
 {
-    /* open logo file */
-    if (outputname) {
-       out = fopen(outputname, "w");
-       if (!out)
-           die("Cannot create file %s: %s\n", outputname, strerror(errno));
-    } else {
-       out = stdout;
-    }
-
-    fputs("/*\n", out);
-    fputs(" *  DO NOT EDIT THIS FILE!\n", out);
-    fputs(" *\n", out);
-    fprintf(out, " *  It was automatically generated from %s\n", filename);
-    fputs(" *\n", out);
-    fprintf(out, " *  Linux logo %s\n", logoname);
-    fputs(" */\n\n", out);
-    fputs("#include <linux/linux_logo.h>\n\n", out);
-    fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
-           logoname);
+       /* open logo file */
+       if (outputname) {
+               out = fopen(outputname, "w");
+               if (!out)
+                       die("Cannot create file %s: %s\n", outputname, strerror(errno));
+       } else {
+               out = stdout;
+       }
+
+       fputs("/*\n", out);
+       fputs(" *  DO NOT EDIT THIS FILE!\n", out);
+       fputs(" *\n", out);
+       fprintf(out, " *  It was automatically generated from %s\n", filename);
+       fputs(" *\n", out);
+       fprintf(out, " *  Linux logo %s\n", logoname);
+       fputs(" */\n\n", out);
+       fputs("#include <linux/linux_logo.h>\n\n", out);
+       fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
+               logoname);
 }
 
 static void write_footer(void)
 {
-    fputs("\n};\n\n", out);
-    fprintf(out, "const struct linux_logo %s __initconst = {\n", logoname);
-    fprintf(out, "\t.type\t\t= %s,\n", logo_types[logo_type]);
-    fprintf(out, "\t.width\t\t= %d,\n", logo_width);
-    fprintf(out, "\t.height\t\t= %d,\n", logo_height);
-    if (logo_type == LINUX_LOGO_CLUT224) {
-       fprintf(out, "\t.clutsize\t= %d,\n", logo_clutsize);
-       fprintf(out, "\t.clut\t\t= %s_clut,\n", logoname);
-    }
-    fprintf(out, "\t.data\t\t= %s_data\n", logoname);
-    fputs("};\n\n", out);
-
-    /* close logo file */
-    if (outputname)
-       fclose(out);
+       fputs("\n};\n\n", out);
+       fprintf(out, "const struct linux_logo %s __initconst = {\n", logoname);
+       fprintf(out, "\t.type\t\t= %s,\n", logo_types[logo_type]);
+       fprintf(out, "\t.width\t\t= %d,\n", logo_width);
+       fprintf(out, "\t.height\t\t= %d,\n", logo_height);
+       if (logo_type == LINUX_LOGO_CLUT224) {
+               fprintf(out, "\t.clutsize\t= %d,\n", logo_clutsize);
+               fprintf(out, "\t.clut\t\t= %s_clut,\n", logoname);
+       }
+       fprintf(out, "\t.data\t\t= %s_data\n", logoname);
+       fputs("};\n\n", out);
+
+       /* close logo file */
+       if (outputname)
+               fclose(out);
 }
 
 static int write_hex_cnt;
 
 static void write_hex(unsigned char byte)
 {
-    if (write_hex_cnt % 12)
-       fprintf(out, ", 0x%02x", byte);
-    else if (write_hex_cnt)
-       fprintf(out, ",\n\t0x%02x", byte);
-    else
-       fprintf(out, "\t0x%02x", byte);
-    write_hex_cnt++;
+       if (write_hex_cnt % 12)
+               fprintf(out, ", 0x%02x", byte);
+       else if (write_hex_cnt)
+               fprintf(out, ",\n\t0x%02x", byte);
+       else
+               fprintf(out, "\t0x%02x", byte);
+       write_hex_cnt++;
 }
 
 static void write_logo_mono(void)
 {
-    unsigned int i, j;
-    unsigned char val, bit;
-
-    /* validate image */
-    for (i = 0; i < logo_height; i++)
-       for (j = 0; j < logo_width; j++)
-           if (!is_black(logo_data[i][j]) && !is_white(logo_data[i][j]))
-               die("Image must be monochrome\n");
-
-    /* write file header */
-    write_header();
-
-    /* write logo data */
-    for (i = 0; i < logo_height; i++) {
-       for (j = 0; j < logo_width;) {
-           for (val = 0, bit = 0x80; bit && j < logo_width; j++, bit >>= 1)
-               if (logo_data[i][j].red)
-                   val |= bit;
-           write_hex(val);
+       unsigned int i, j;
+       unsigned char val, bit;
+
+       /* validate image */
+       for (i = 0; i < logo_height; i++)
+               for (j = 0; j < logo_width; j++)
+                       if (!is_black(logo_data[i][j]) && !is_white(logo_data[i][j]))
+                               die("Image must be monochrome\n");
+
+       /* write file header */
+       write_header();
+
+       /* write logo data */
+       for (i = 0; i < logo_height; i++) {
+               for (j = 0; j < logo_width;) {
+                       for (val = 0, bit = 0x80; bit && j < logo_width; j++, bit >>= 1)
+                               if (logo_data[i][j].red)
+                                       val |= bit;
+                       write_hex(val);
+               }
        }
-    }
 
-    /* write logo structure and file footer */
-    write_footer();
+       /* write logo structure and file footer */
+       write_footer();
 }
 
 static void write_logo_vga16(void)
 {
-    unsigned int i, j, k;
-    unsigned char val;
-
-    /* validate image */
-    for (i = 0; i < logo_height; i++)
-       for (j = 0; j < logo_width; j++) {
-           for (k = 0; k < 16; k++)
-               if (is_equal(logo_data[i][j], clut_vga16[k]))
-                   break;
-           if (k == 16)
-               die("Image must use the 16 console colors only\n"
-                   "Use ppmquant(1) -map clut_vga16.ppm to reduce the number "
-                   "of colors\n");
-       }
+       unsigned int i, j, k;
+       unsigned char val;
 
-    /* write file header */
-    write_header();
-
-    /* write logo data */
-    for (i = 0; i < logo_height; i++)
-       for (j = 0; j < logo_width; j++) {
-           for (k = 0; k < 16; k++)
-               if (is_equal(logo_data[i][j], clut_vga16[k]))
-                   break;
-           val = k<<4;
-           if (++j < logo_width) {
-               for (k = 0; k < 16; k++)
-                   if (is_equal(logo_data[i][j], clut_vga16[k]))
-                       break;
-               val |= k;
-           }
-           write_hex(val);
-       }
+       /* validate image */
+       for (i = 0; i < logo_height; i++)
+               for (j = 0; j < logo_width; j++) {
+                       for (k = 0; k < 16; k++)
+                               if (is_equal(logo_data[i][j], clut_vga16[k]))
+                                       break;
+                       if (k == 16)
+                               die("Image must use the 16 console colors only\n"
+                                   "Use ppmquant(1) -map clut_vga16.ppm to reduce the number "
+                                   "of colors\n");
+               }
 
-    /* write logo structure and file footer */
-    write_footer();
+       /* write file header */
+       write_header();
+
+       /* write logo data */
+       for (i = 0; i < logo_height; i++)
+               for (j = 0; j < logo_width; j++) {
+                       for (k = 0; k < 16; k++)
+                               if (is_equal(logo_data[i][j], clut_vga16[k]))
+                                       break;
+                       val = k<<4;
+                       if (++j < logo_width) {
+                               for (k = 0; k < 16; k++)
+                                       if (is_equal(logo_data[i][j], clut_vga16[k]))
+                                               break;
+                               val |= k;
+                       }
+                       write_hex(val);
+               }
+
+       /* write logo structure and file footer */
+       write_footer();
 }
 
 static void write_logo_clut224(void)
 {
-    unsigned int i, j, k;
-
-    /* validate image */
-    for (i = 0; i < logo_height; i++)
-       for (j = 0; j < logo_width; j++) {
-           for (k = 0; k < logo_clutsize; k++)
-               if (is_equal(logo_data[i][j], logo_clut[k]))
-                   break;
-           if (k == logo_clutsize) {
-               if (logo_clutsize == MAX_LINUX_LOGO_COLORS)
-                   die("Image has more than %d colors\n"
-                       "Use ppmquant(1) to reduce the number of colors\n",
-                       MAX_LINUX_LOGO_COLORS);
-               logo_clut[logo_clutsize++] = logo_data[i][j];
-           }
-       }
+       unsigned int i, j, k;
 
-    /* write file header */
-    write_header();
+       /* validate image */
+       for (i = 0; i < logo_height; i++)
+               for (j = 0; j < logo_width; j++) {
+                       for (k = 0; k < logo_clutsize; k++)
+                               if (is_equal(logo_data[i][j], logo_clut[k]))
+                                       break;
+                       if (k == logo_clutsize) {
+                               if (logo_clutsize == MAX_LINUX_LOGO_COLORS)
+                                       die("Image has more than %d colors\n"
+                                           "Use ppmquant(1) to reduce the number of colors\n",
+                                           MAX_LINUX_LOGO_COLORS);
+                               logo_clut[logo_clutsize++] = logo_data[i][j];
+                       }
+               }
 
-    /* write logo data */
-    for (i = 0; i < logo_height; i++)
-       for (j = 0; j < logo_width; j++) {
-           for (k = 0; k < logo_clutsize; k++)
-               if (is_equal(logo_data[i][j], logo_clut[k]))
-                   break;
-           write_hex(k+32);
+       /* write file header */
+       write_header();
+
+       /* write logo data */
+       for (i = 0; i < logo_height; i++)
+               for (j = 0; j < logo_width; j++) {
+                       for (k = 0; k < logo_clutsize; k++)
+                               if (is_equal(logo_data[i][j], logo_clut[k]))
+                                       break;
+                       write_hex(k+32);
+               }
+       fputs("\n};\n\n", out);
+
+       /* write logo clut */
+       fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
+               logoname);
+       write_hex_cnt = 0;
+       for (i = 0; i < logo_clutsize; i++) {
+               write_hex(logo_clut[i].red);
+               write_hex(logo_clut[i].green);
+               write_hex(logo_clut[i].blue);
        }
-    fputs("\n};\n\n", out);
-
-    /* write logo clut */
-    fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
-           logoname);
-    write_hex_cnt = 0;
-    for (i = 0; i < logo_clutsize; i++) {
-       write_hex(logo_clut[i].red);
-       write_hex(logo_clut[i].green);
-       write_hex(logo_clut[i].blue);
-    }
-
-    /* write logo structure and file footer */
-    write_footer();
+
+       /* write logo structure and file footer */
+       write_footer();
 }
 
 static void write_logo_gray256(void)
 {
-    unsigned int i, j;
+       unsigned int i, j;
 
-    /* validate image */
-    for (i = 0; i < logo_height; i++)
-       for (j = 0; j < logo_width; j++)
-           if (!is_gray(logo_data[i][j]))
-               die("Image must be grayscale\n");
+       /* validate image */
+       for (i = 0; i < logo_height; i++)
+               for (j = 0; j < logo_width; j++)
+                       if (!is_gray(logo_data[i][j]))
+                               die("Image must be grayscale\n");
 
-    /* write file header */
-    write_header();
+       /* write file header */
+       write_header();
 
-    /* write logo data */
-    for (i = 0; i < logo_height; i++)
-       for (j = 0; j < logo_width; j++)
-           write_hex(logo_data[i][j].red);
+       /* write logo data */
+       for (i = 0; i < logo_height; i++)
+               for (j = 0; j < logo_width; j++)
+                       write_hex(logo_data[i][j].red);
 
-    /* write logo structure and file footer */
-    write_footer();
+       /* write logo structure and file footer */
+       write_footer();
 }
 
 static void die(const char *fmt, ...)
 {
-    va_list ap;
+       va_list ap;
 
-    va_start(ap, fmt);
-    vfprintf(stderr, fmt, ap);
-    va_end(ap);
+       va_start(ap, fmt);
+       vfprintf(stderr, fmt, ap);
+       va_end(ap);
 
-    exit(1);
+       exit(1);
 }
 
 static void usage(void)
 {
-    die("\n"
+       die("\n"
        "Usage: %s [options] <filename>\n"
        "\n"
        "Valid options:\n"
-       "    -h          : display this usage information\n"
-       "    -n <name>   : specify logo name (default: linux_logo)\n"
-       "    -o <output> : output to file <output> instead of stdout\n"
-       "    -t <type>   : specify logo type, one of\n"
-       "                      mono    : monochrome black/white\n"
-       "                      vga16   : 16 colors VGA text palette\n"
-       "                      clut224 : 224 colors (default)\n"
-       "                      gray256 : 256 levels grayscale\n"
+       "       -h                : display this usage information\n"
+       "       -n <name>   : specify logo name (default: linux_logo)\n"
+       "       -o <output> : output to file <output> instead of stdout\n"
+       "       -t <type>   : specify logo type, one of\n"
+       "                                         mono  : monochrome black/white\n"
+       "                                         vga16   : 16 colors VGA text palette\n"
+       "                                         clut224 : 224 colors (default)\n"
+       "                                         gray256 : 256 levels grayscale\n"
        "\n", programname);
 }
 
 int main(int argc, char *argv[])
 {
-    int opt;
+       int opt;
 
-    programname = argv[0];
+       programname = argv[0];
 
-    opterr = 0;
-    while (1) {
-       opt = getopt(argc, argv, "hn:o:t:");
-       if (opt == -1)
-           break;
+       opterr = 0;
+       while (1) {
+               opt = getopt(argc, argv, "hn:o:t:");
+               if (opt == -1)
+                       break;
 
-       switch (opt) {
-           case 'h':
-               usage();
-               break;
+               switch (opt) {
+               case 'h':
+                       usage();
+                       break;
 
-           case 'n':
-               logoname = optarg;
-               break;
+               case 'n':
+                       logoname = optarg;
+                       break;
 
-           case 'o':
-               outputname = optarg;
-               break;
+               case 'o':
+                       outputname = optarg;
+                       break;
 
-           case 't':
-               if (!strcmp(optarg, "mono"))
-                   logo_type = LINUX_LOGO_MONO;
-               else if (!strcmp(optarg, "vga16"))
-                   logo_type = LINUX_LOGO_VGA16;
-               else if (!strcmp(optarg, "clut224"))
-                   logo_type = LINUX_LOGO_CLUT224;
-               else if (!strcmp(optarg, "gray256"))
-                   logo_type = LINUX_LOGO_GRAY256;
-               else
-                   usage();
-               break;
+               case 't':
+                       if (!strcmp(optarg, "mono"))
+                               logo_type = LINUX_LOGO_MONO;
+                       else if (!strcmp(optarg, "vga16"))
+                               logo_type = LINUX_LOGO_VGA16;
+                       else if (!strcmp(optarg, "clut224"))
+                               logo_type = LINUX_LOGO_CLUT224;
+                       else if (!strcmp(optarg, "gray256"))
+                               logo_type = LINUX_LOGO_GRAY256;
+                       else
+                               usage();
+                       break;
 
-           default:
-               usage();
-               break;
+               default:
+                       usage();
+                       break;
+               }
        }
-    }
-    if (optind != argc-1)
-       usage();
+       if (optind != argc-1)
+               usage();
 
-    filename = argv[optind];
+       filename = argv[optind];
 
-    read_image();
-    switch (logo_type) {
+       read_image();
+       switch (logo_type) {
        case LINUX_LOGO_MONO:
-           write_logo_mono();
-           break;
+               write_logo_mono();
+               break;
 
        case LINUX_LOGO_VGA16:
-           write_logo_vga16();
-           break;
+               write_logo_vga16();
+               break;
 
        case LINUX_LOGO_CLUT224:
-           write_logo_clut224();
-           break;
+               write_logo_clut224();
+               break;
 
        case LINUX_LOGO_GRAY256:
-           write_logo_gray256();
-           break;
-    }
-    exit(0);
+               write_logo_gray256();
+               break;
+       }
+       exit(0);
 }
index 7b4e9009f33559fe04a11c17af5433715b625893..46f1a8d558b0b28321b1f9312dd415df25f4f504 100644 (file)
@@ -31,6 +31,9 @@
 #define AAD_LEN                48
 #define MSG_HDR_VER    1
 
+#define SNP_REQ_MAX_RETRY_DURATION     (60*HZ)
+#define SNP_REQ_RETRY_DELAY            (2*HZ)
+
 struct snp_guest_crypto {
        struct crypto_aead *tfm;
        u8 *iv, *authtag;
@@ -318,26 +321,14 @@ static int enc_payload(struct snp_guest_dev *snp_dev, u64 seqno, int version, u8
        return __enc_payload(snp_dev, req, payload, sz);
 }
 
-static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, int msg_ver,
-                               u8 type, void *req_buf, size_t req_sz, void *resp_buf,
-                               u32 resp_sz, __u64 *fw_err)
+static int __handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, __u64 *fw_err)
 {
-       unsigned long err;
-       u64 seqno;
+       unsigned long err = 0xff, override_err = 0;
+       unsigned long req_start = jiffies;
+       unsigned int override_npages = 0;
        int rc;
 
-       /* Get message sequence and verify that its a non-zero */
-       seqno = snp_get_msg_seqno(snp_dev);
-       if (!seqno)
-               return -EIO;
-
-       memset(snp_dev->response, 0, sizeof(struct snp_guest_msg));
-
-       /* Encrypt the userspace provided payload */
-       rc = enc_payload(snp_dev, seqno, msg_ver, type, req_buf, req_sz);
-       if (rc)
-               return rc;
-
+retry_request:
        /*
         * Call firmware to process the request. In this function the encrypted
         * message enters shared memory with the host. So after this call the
@@ -345,18 +336,24 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in
         * prevent reuse of the IV.
         */
        rc = snp_issue_guest_request(exit_code, &snp_dev->input, &err);
+       switch (rc) {
+       case -ENOSPC:
+               /*
+                * If the extended guest request fails due to having too
+                * small of a certificate data buffer, retry the same
+                * guest request without the extended data request in
+                * order to increment the sequence number and thus avoid
+                * IV reuse.
+                */
+               override_npages = snp_dev->input.data_npages;
+               exit_code       = SVM_VMGEXIT_GUEST_REQUEST;
 
-       /*
-        * If the extended guest request fails due to having too small of a
-        * certificate data buffer, retry the same guest request without the
-        * extended data request in order to increment the sequence number
-        * and thus avoid IV reuse.
-        */
-       if (exit_code == SVM_VMGEXIT_EXT_GUEST_REQUEST &&
-           err == SNP_GUEST_REQ_INVALID_LEN) {
-               const unsigned int certs_npages = snp_dev->input.data_npages;
-
-               exit_code = SVM_VMGEXIT_GUEST_REQUEST;
+               /*
+                * Override the error to inform callers the given extended
+                * request buffer size was too small and give the caller the
+                * required buffer size.
+                */
+               override_err    = SNP_GUEST_REQ_INVALID_LEN;
 
                /*
                 * If this call to the firmware succeeds, the sequence number can
@@ -366,15 +363,20 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in
                 * of the VMPCK and the error code being propagated back to the
                 * user as an ioctl() return code.
                 */
-               rc = snp_issue_guest_request(exit_code, &snp_dev->input, &err);
+               goto retry_request;
 
-               /*
-                * Override the error to inform callers the given extended
-                * request buffer size was too small and give the caller the
-                * required buffer size.
-                */
-               err = SNP_GUEST_REQ_INVALID_LEN;
-               snp_dev->input.data_npages = certs_npages;
+       /*
+        * The host may return SNP_GUEST_REQ_ERR_EBUSY if the request has been
+        * throttled. Retry in the driver to avoid returning and reusing the
+        * message sequence number on a different message.
+        */
+       case -EAGAIN:
+               if (jiffies - req_start > SNP_REQ_MAX_RETRY_DURATION) {
+                       rc = -ETIMEDOUT;
+                       break;
+               }
+               schedule_timeout_killable(SNP_REQ_RETRY_DELAY);
+               goto retry_request;
        }
 
        /*
@@ -386,7 +388,10 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in
        snp_inc_msg_seqno(snp_dev);
 
        if (fw_err)
-               *fw_err = err;
+               *fw_err = override_err ?: err;
+
+       if (override_npages)
+               snp_dev->input.data_npages = override_npages;
 
        /*
         * If an extended guest request was issued and the supplied certificate
@@ -394,29 +399,49 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in
         * prevent IV reuse. If the standard request was successful, return -EIO
         * back to the caller as would have originally been returned.
         */
-       if (!rc && err == SNP_GUEST_REQ_INVALID_LEN)
+       if (!rc && override_err == SNP_GUEST_REQ_INVALID_LEN)
+               return -EIO;
+
+       return rc;
+}
+
+static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, int msg_ver,
+                               u8 type, void *req_buf, size_t req_sz, void *resp_buf,
+                               u32 resp_sz, __u64 *fw_err)
+{
+       u64 seqno;
+       int rc;
+
+       /* Get message sequence and verify that its a non-zero */
+       seqno = snp_get_msg_seqno(snp_dev);
+       if (!seqno)
                return -EIO;
 
+       memset(snp_dev->response, 0, sizeof(struct snp_guest_msg));
+
+       /* Encrypt the userspace provided payload */
+       rc = enc_payload(snp_dev, seqno, msg_ver, type, req_buf, req_sz);
+       if (rc)
+               return rc;
+
+       rc = __handle_guest_request(snp_dev, exit_code, fw_err);
        if (rc) {
-               dev_alert(snp_dev->dev,
-                         "Detected error from ASP request. rc: %d, fw_err: %llu\n",
-                         rc, *fw_err);
-               goto disable_vmpck;
+               if (rc == -EIO && *fw_err == SNP_GUEST_REQ_INVALID_LEN)
+                       return rc;
+
+               dev_alert(snp_dev->dev, "Detected error from ASP request. rc: %d, fw_err: %llu\n", rc, *fw_err);
+               snp_disable_vmpck(snp_dev);
+               return rc;
        }
 
        rc = verify_and_dec_payload(snp_dev, resp_buf, resp_sz);
        if (rc) {
-               dev_alert(snp_dev->dev,
-                         "Detected unexpected decode failure from ASP. rc: %d\n",
-                         rc);
-               goto disable_vmpck;
+               dev_alert(snp_dev->dev, "Detected unexpected decode failure from ASP. rc: %d\n", rc);
+               snp_disable_vmpck(snp_dev);
+               return rc;
        }
 
        return 0;
-
-disable_vmpck:
-       snp_disable_vmpck(snp_dev);
-       return rc;
 }
 
 static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg)
@@ -703,6 +728,9 @@ static int __init sev_guest_probe(struct platform_device *pdev)
        void __iomem *mapping;
        int ret;
 
+       if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
+               return -ENODEV;
+
        if (!dev->platform_data)
                return -ENODEV;
 
index 62c44616d8a922637e92f89d79d0fd7f8a8858ea..3d8b51316bef0fad53d5607be7bec3fac9850e60 100644 (file)
@@ -442,8 +442,7 @@ static u8 ds2482_w1_set_pullup(void *data, int delay)
 }
 
 
-static int ds2482_probe(struct i2c_client *client,
-                       const struct i2c_device_id *id)
+static int ds2482_probe(struct i2c_client *client)
 {
        struct ds2482_data *data;
        int err = -ENODEV;
@@ -553,7 +552,7 @@ static struct i2c_driver ds2482_driver = {
        .driver = {
                .name   = "ds2482",
        },
-       .probe          = ds2482_probe,
+       .probe_new      = ds2482_probe,
        .remove         = ds2482_remove,
        .id_table       = ds2482_id,
 };
index c6c73a33c44d556c0ac5ebf53d6b5e078bfb6dc5..b799bc759c15f4e988a858ed1f41c1d3b3b6d934 100644 (file)
@@ -64,7 +64,7 @@ static int xensyms_next_sym(struct xensyms *xs)
 
 static void *xensyms_start(struct seq_file *m, loff_t *pos)
 {
-       struct xensyms *xs = (struct xensyms *)m->private;
+       struct xensyms *xs = m->private;
 
        xs->op.u.symdata.symnum = *pos;
 
@@ -76,7 +76,7 @@ static void *xensyms_start(struct seq_file *m, loff_t *pos)
 
 static void *xensyms_next(struct seq_file *m, void *p, loff_t *pos)
 {
-       struct xensyms *xs = (struct xensyms *)m->private;
+       struct xensyms *xs = m->private;
 
        xs->op.u.symdata.symnum = ++(*pos);
 
@@ -88,7 +88,7 @@ static void *xensyms_next(struct seq_file *m, void *p, loff_t *pos)
 
 static int xensyms_show(struct seq_file *m, void *p)
 {
-       struct xensyms *xs = (struct xensyms *)m->private;
+       struct xensyms *xs = m->private;
        struct xenpf_symdata *symdata = &xs->op.u.symdata;
 
        seq_printf(m, "%016llx %c %s\n", symdata->address,
@@ -120,7 +120,7 @@ static int xensyms_open(struct inode *inode, struct file *file)
                return ret;
 
        m = file->private_data;
-       xs = (struct xensyms *)m->private;
+       xs = m->private;
 
        xs->namelen = XEN_KSYM_NAME_LEN + 1;
        xs->name = kzalloc(xs->namelen, GFP_KERNEL);
@@ -138,7 +138,7 @@ static int xensyms_open(struct inode *inode, struct file *file)
 static int xensyms_release(struct inode *inode, struct file *file)
 {
        struct seq_file *m = file->private_data;
-       struct xensyms *xs = (struct xensyms *)m->private;
+       struct xensyms *xs = m->private;
 
        kfree(xs->name);
        return seq_release_private(inode, file);
index 50f7f3f6b55e9a7853cc1f6e4d8d14238274379a..e00cf8109b3f31cb77ffb900b56ca67df480a791 100644 (file)
@@ -35,10 +35,12 @@ ssize_t v9fs_fid_xattr_get(struct p9_fid *fid, const char *name,
                return retval;
        }
        if (attr_size > buffer_size) {
-               if (!buffer_size) /* request to get the attr_size */
-                       retval = attr_size;
-               else
+               if (buffer_size)
                        retval = -ERANGE;
+               else if (attr_size > SSIZE_MAX)
+                       retval = -EOVERFLOW;
+               else /* request to get the attr_size */
+                       retval = attr_size;
        } else {
                iov_iter_truncate(&to, attr_size);
                retval = p9_client_read(attr_fid, 0, &to, &err);
@@ -183,10 +185,6 @@ static struct xattr_handler v9fs_xattr_security_handler = {
 const struct xattr_handler *v9fs_xattr_handlers[] = {
        &v9fs_xattr_user_handler,
        &v9fs_xattr_trusted_handler,
-#ifdef CONFIG_FS_POSIX_ACL
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
-#endif
 #ifdef CONFIG_9P_FS_SECURITY
        &v9fs_xattr_security_handler,
 #endif
index aca9ff7aed3331c31848cf6bf7480bd4b9e27187..d60dc1edb526885584bf62b74da1542e271a8f7d 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -47,6 +47,7 @@ int setattr_should_drop_sgid(struct mnt_idmap *idmap,
                return ATTR_KILL_SGID;
        return 0;
 }
+EXPORT_SYMBOL(setattr_should_drop_sgid);
 
 /**
  * setattr_should_drop_suidgid - determine whether the set{g,u}id bit needs to
index 90e40d5ceccd15bca4b4c388d2dcc97d88f34b4c..e54f0884802a0cb2ac3592a71d348e80e5e01e62 100644 (file)
@@ -1921,8 +1921,7 @@ int btrfs_is_data_extent_shared(struct btrfs_inode *inode, u64 bytenr,
        level = -1;
        ULIST_ITER_INIT(&uiter);
        while (1) {
-               bool is_shared;
-               bool cached;
+               const unsigned long prev_ref_count = ctx->refs.nnodes;
 
                walk_ctx.bytenr = bytenr;
                ret = find_parent_nodes(&walk_ctx, &shared);
@@ -1940,21 +1939,36 @@ int btrfs_is_data_extent_shared(struct btrfs_inode *inode, u64 bytenr,
                ret = 0;
 
                /*
-                * If our data extent was not directly shared (without multiple
-                * reference items), than it might have a single reference item
-                * with a count > 1 for the same offset, which means there are 2
-                * (or more) file extent items that point to the data extent -
-                * this happens when a file extent item needs to be split and
-                * then one item gets moved to another leaf due to a b+tree leaf
-                * split when inserting some item. In this case the file extent
-                * items may be located in different leaves and therefore some
-                * of the leaves may be referenced through shared subtrees while
-                * others are not. Since our extent buffer cache only works for
-                * a single path (by far the most common case and simpler to
-                * deal with), we can not use it if we have multiple leaves
-                * (which implies multiple paths).
+                * More than one extent buffer (bytenr) may have been added to
+                * the ctx->refs ulist, in which case we have to check multiple
+                * tree paths in case the first one is not shared, so we can not
+                * use the path cache which is made for a single path. Multiple
+                * extent buffers at the current level happen when:
+                *
+                * 1) level -1, the data extent: If our data extent was not
+                *    directly shared (without multiple reference items), then
+                *    it might have a single reference item with a count > 1 for
+                *    the same offset, which means there are 2 (or more) file
+                *    extent items that point to the data extent - this happens
+                *    when a file extent item needs to be split and then one
+                *    item gets moved to another leaf due to a b+tree leaf split
+                *    when inserting some item. In this case the file extent
+                *    items may be located in different leaves and therefore
+                *    some of the leaves may be referenced through shared
+                *    subtrees while others are not. Since our extent buffer
+                *    cache only works for a single path (by far the most common
+                *    case and simpler to deal with), we can not use it if we
+                *    have multiple leaves (which implies multiple paths).
+                *
+                * 2) level >= 0, a tree node/leaf: We can have a mix of direct
+                *    and indirect references on a b+tree node/leaf, so we have
+                *    to check multiple paths, and the extent buffer (the
+                *    current bytenr) may be shared or not. One example is
+                *    during relocation as we may get a shared tree block ref
+                *    (direct ref) and a non-shared tree block ref (indirect
+                *    ref) for the same node/leaf.
                 */
-               if (level == -1 && ctx->refs.nnodes > 1)
+               if ((ctx->refs.nnodes - prev_ref_count) > 1)
                        ctx->use_path_cache = false;
 
                if (level >= 0)
@@ -1964,18 +1978,45 @@ int btrfs_is_data_extent_shared(struct btrfs_inode *inode, u64 bytenr,
                if (!node)
                        break;
                bytenr = node->val;
-               level++;
-               cached = lookup_backref_shared_cache(ctx, root, bytenr, level,
-                                                    &is_shared);
-               if (cached) {
-                       ret = (is_shared ? 1 : 0);
-                       break;
+               if (ctx->use_path_cache) {
+                       bool is_shared;
+                       bool cached;
+
+                       level++;
+                       cached = lookup_backref_shared_cache(ctx, root, bytenr,
+                                                            level, &is_shared);
+                       if (cached) {
+                               ret = (is_shared ? 1 : 0);
+                               break;
+                       }
                }
                shared.share_count = 0;
                shared.have_delayed_delete_refs = false;
                cond_resched();
        }
 
+       /*
+        * If the path cache is disabled, then it means at some tree level we
+        * got multiple parents due to a mix of direct and indirect backrefs or
+        * multiple leaves with file extent items pointing to the same data
+        * extent. We have to invalidate the cache and cache only the sharedness
+        * result for the levels where we got only one node/reference.
+        */
+       if (!ctx->use_path_cache) {
+               int i = 0;
+
+               level--;
+               if (ret >= 0 && level >= 0) {
+                       bytenr = ctx->path_cache_entries[level].bytenr;
+                       ctx->use_path_cache = true;
+                       store_backref_shared_cache(ctx, root, bytenr, level, ret);
+                       i = level + 1;
+               }
+
+               for ( ; i < BTRFS_MAX_LEVEL; i++)
+                       ctx->path_cache_entries[i].bytenr = 0;
+       }
+
        /*
         * Cache the sharedness result for the data extent if we know our inode
         * has more than 1 file extent item that refers to the data extent.
index d8b90f95b1575c31359ad16d9b9d70287a2b4164..726592868e9c5ced71af2a4ade91b965634de882 100644 (file)
@@ -287,7 +287,7 @@ static void btrfs_log_dev_io_error(struct bio *bio, struct btrfs_device *dev)
 
        if (btrfs_op(bio) == BTRFS_MAP_WRITE)
                btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_WRITE_ERRS);
-       if (!(bio->bi_opf & REQ_RAHEAD))
+       else if (!(bio->bi_opf & REQ_RAHEAD))
                btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_READ_ERRS);
        if (bio->bi_opf & REQ_PREFLUSH)
                btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_FLUSH_ERRS);
index 5b10401d803b3d5dd563b271ec46ad33922d6c8a..5fc670c27f8648d996016fe8da3f6fae658fdc78 100644 (file)
@@ -558,14 +558,15 @@ u64 add_new_free_space(struct btrfs_block_group *block_group, u64 start, u64 end
 static int sample_block_group_extent_item(struct btrfs_caching_control *caching_ctl,
                                          struct btrfs_block_group *block_group,
                                          int index, int max_index,
-                                         struct btrfs_key *key)
+                                         struct btrfs_key *found_key)
 {
        struct btrfs_fs_info *fs_info = block_group->fs_info;
        struct btrfs_root *extent_root;
-       int ret = 0;
        u64 search_offset;
        u64 search_end = block_group->start + block_group->length;
        struct btrfs_path *path;
+       struct btrfs_key search_key;
+       int ret = 0;
 
        ASSERT(index >= 0);
        ASSERT(index <= max_index);
@@ -585,37 +586,24 @@ static int sample_block_group_extent_item(struct btrfs_caching_control *caching_
        path->reada = READA_FORWARD;
 
        search_offset = index * div_u64(block_group->length, max_index);
-       key->objectid = block_group->start + search_offset;
-       key->type = BTRFS_EXTENT_ITEM_KEY;
-       key->offset = 0;
+       search_key.objectid = block_group->start + search_offset;
+       search_key.type = BTRFS_EXTENT_ITEM_KEY;
+       search_key.offset = 0;
 
-       while (1) {
-               ret = btrfs_search_forward(extent_root, key, path, 0);
-               if (ret != 0)
-                       goto out;
+       btrfs_for_each_slot(extent_root, &search_key, found_key, path, ret) {
                /* Success; sampled an extent item in the block group */
-               if (key->type == BTRFS_EXTENT_ITEM_KEY &&
-                   key->objectid >= block_group->start &&
-                   key->objectid + key->offset <= search_end)
-                       goto out;
+               if (found_key->type == BTRFS_EXTENT_ITEM_KEY &&
+                   found_key->objectid >= block_group->start &&
+                   found_key->objectid + found_key->offset <= search_end)
+                       break;
 
                /* We can't possibly find a valid extent item anymore */
-               if (key->objectid >= search_end) {
+               if (found_key->objectid >= search_end) {
                        ret = 1;
                        break;
                }
-               if (key->type < BTRFS_EXTENT_ITEM_KEY)
-                       key->type = BTRFS_EXTENT_ITEM_KEY;
-               else
-                       key->objectid++;
-               btrfs_release_path(path);
-               up_read(&fs_info->commit_root_sem);
-               mutex_unlock(&caching_ctl->mutex);
-               cond_resched();
-               mutex_lock(&caching_ctl->mutex);
-               down_read(&fs_info->commit_root_sem);
        }
-out:
+
        lockdep_assert_held(&caching_ctl->mutex);
        lockdep_assert_held_read(&fs_info->commit_root_sem);
        btrfs_free_path(path);
@@ -659,6 +647,7 @@ out:
 static int load_block_group_size_class(struct btrfs_caching_control *caching_ctl,
                                       struct btrfs_block_group *block_group)
 {
+       struct btrfs_fs_info *fs_info = block_group->fs_info;
        struct btrfs_key key;
        int i;
        u64 min_size = block_group->length;
@@ -668,6 +657,8 @@ static int load_block_group_size_class(struct btrfs_caching_control *caching_ctl
        if (!btrfs_block_group_should_use_size_class(block_group))
                return 0;
 
+       lockdep_assert_held(&caching_ctl->mutex);
+       lockdep_assert_held_read(&fs_info->commit_root_sem);
        for (i = 0; i < 5; ++i) {
                ret = sample_block_group_extent_item(caching_ctl, block_group, i, 5, &key);
                if (ret < 0)
@@ -682,7 +673,6 @@ static int load_block_group_size_class(struct btrfs_caching_control *caching_ctl
                block_group->size_class = size_class;
                spin_unlock(&block_group->lock);
        }
-
 out:
        return ret;
 }
@@ -1185,14 +1175,8 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
                        < block_group->zone_unusable);
                WARN_ON(block_group->space_info->disk_total
                        < block_group->length * factor);
-               WARN_ON(test_bit(BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE,
-                                &block_group->runtime_flags) &&
-                       block_group->space_info->active_total_bytes
-                       < block_group->length);
        }
        block_group->space_info->total_bytes -= block_group->length;
-       if (test_bit(BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE, &block_group->runtime_flags))
-               block_group->space_info->active_total_bytes -= block_group->length;
        block_group->space_info->bytes_readonly -=
                (block_group->length - block_group->zone_unusable);
        block_group->space_info->bytes_zone_unusable -=
@@ -1836,7 +1820,8 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
 
                btrfs_info(fs_info,
                        "reclaiming chunk %llu with %llu%% used %llu%% unusable",
-                               bg->start, div_u64(bg->used * 100, bg->length),
+                               bg->start,
+                               div64_u64(bg->used * 100, bg->length),
                                div64_u64(zone_unusable * 100, bg->length));
                trace_btrfs_reclaim_block_group(bg);
                ret = btrfs_relocate_chunk(fs_info, bg->start);
@@ -2493,18 +2478,29 @@ static int insert_block_group_item(struct btrfs_trans_handle *trans,
        struct btrfs_block_group_item bgi;
        struct btrfs_root *root = btrfs_block_group_root(fs_info);
        struct btrfs_key key;
+       u64 old_commit_used;
+       int ret;
 
        spin_lock(&block_group->lock);
        btrfs_set_stack_block_group_used(&bgi, block_group->used);
        btrfs_set_stack_block_group_chunk_objectid(&bgi,
                                                   block_group->global_root_id);
        btrfs_set_stack_block_group_flags(&bgi, block_group->flags);
+       old_commit_used = block_group->commit_used;
+       block_group->commit_used = block_group->used;
        key.objectid = block_group->start;
        key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
        key.offset = block_group->length;
        spin_unlock(&block_group->lock);
 
-       return btrfs_insert_item(trans, root, &key, &bgi, sizeof(bgi));
+       ret = btrfs_insert_item(trans, root, &key, &bgi, sizeof(bgi));
+       if (ret < 0) {
+               spin_lock(&block_group->lock);
+               block_group->commit_used = old_commit_used;
+               spin_unlock(&block_group->lock);
+       }
+
+       return ret;
 }
 
 static int insert_dev_extent(struct btrfs_trans_handle *trans,
@@ -3474,6 +3470,7 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans,
        spin_unlock(&info->delalloc_root_lock);
 
        while (total) {
+               struct btrfs_space_info *space_info;
                bool reclaim = false;
 
                cache = btrfs_lookup_block_group(info, bytenr);
@@ -3481,6 +3478,7 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans,
                        ret = -ENOENT;
                        break;
                }
+               space_info = cache->space_info;
                factor = btrfs_bg_type_to_factor(cache->flags);
 
                /*
@@ -3495,7 +3493,7 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans,
                byte_in_group = bytenr - cache->start;
                WARN_ON(byte_in_group > cache->length);
 
-               spin_lock(&cache->space_info->lock);
+               spin_lock(&space_info->lock);
                spin_lock(&cache->lock);
 
                if (btrfs_test_opt(info, SPACE_CACHE) &&
@@ -3508,24 +3506,24 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans,
                        old_val += num_bytes;
                        cache->used = old_val;
                        cache->reserved -= num_bytes;
-                       cache->space_info->bytes_reserved -= num_bytes;
-                       cache->space_info->bytes_used += num_bytes;
-                       cache->space_info->disk_used += num_bytes * factor;
+                       space_info->bytes_reserved -= num_bytes;
+                       space_info->bytes_used += num_bytes;
+                       space_info->disk_used += num_bytes * factor;
                        spin_unlock(&cache->lock);
-                       spin_unlock(&cache->space_info->lock);
+                       spin_unlock(&space_info->lock);
                } else {
                        old_val -= num_bytes;
                        cache->used = old_val;
                        cache->pinned += num_bytes;
-                       btrfs_space_info_update_bytes_pinned(info,
-                                       cache->space_info, num_bytes);
-                       cache->space_info->bytes_used -= num_bytes;
-                       cache->space_info->disk_used -= num_bytes * factor;
+                       btrfs_space_info_update_bytes_pinned(info, space_info,
+                                                            num_bytes);
+                       space_info->bytes_used -= num_bytes;
+                       space_info->disk_used -= num_bytes * factor;
 
                        reclaim = should_reclaim_block_group(cache, num_bytes);
 
                        spin_unlock(&cache->lock);
-                       spin_unlock(&cache->space_info->lock);
+                       spin_unlock(&space_info->lock);
 
                        set_extent_dirty(&trans->transaction->pinned_extents,
                                         bytenr, bytenr + num_bytes - 1,
index 0095c6e4c3d1cebb3b4cf752b723daa2ad811d8e..6b457b010cbc4ae204bc211c521f389ad46ded4c 100644 (file)
@@ -1048,7 +1048,7 @@ again:
         * so there is only one iref. The case that several irefs are
         * in the same item doesn't exist.
         */
-       btrfs_del_item(trans, root, path);
+       ret = btrfs_del_item(trans, root, path);
 out:
        btrfs_release_delayed_iref(node);
        btrfs_release_path(path);
index 317aeff6c1dacce2b3432cf91bfdb7261da883a8..a6d77fe41e1a9eeb367322c03b26c5edef50e453 100644 (file)
 #define BTRFS_DISCARD_DELAY            (120ULL * NSEC_PER_SEC)
 #define BTRFS_DISCARD_UNUSED_DELAY     (10ULL * NSEC_PER_SEC)
 
-/* Target completion latency of discarding all discardable extents */
-#define BTRFS_DISCARD_TARGET_MSEC      (6 * 60 * 60UL * MSEC_PER_SEC)
 #define BTRFS_DISCARD_MIN_DELAY_MSEC   (1UL)
 #define BTRFS_DISCARD_MAX_DELAY_MSEC   (1000UL)
-#define BTRFS_DISCARD_MAX_IOPS         (10U)
+#define BTRFS_DISCARD_MAX_IOPS         (1000U)
 
 /* Monotonically decreasing minimum length filters after index 0 */
 static int discard_minlen[BTRFS_NR_DISCARD_LISTS] = {
@@ -577,6 +575,7 @@ void btrfs_discard_calc_delay(struct btrfs_discard_ctl *discard_ctl)
        s32 discardable_extents;
        s64 discardable_bytes;
        u32 iops_limit;
+       unsigned long min_delay = BTRFS_DISCARD_MIN_DELAY_MSEC;
        unsigned long delay;
 
        discardable_extents = atomic_read(&discard_ctl->discardable_extents);
@@ -607,13 +606,19 @@ void btrfs_discard_calc_delay(struct btrfs_discard_ctl *discard_ctl)
        }
 
        iops_limit = READ_ONCE(discard_ctl->iops_limit);
-       if (iops_limit)
+
+       if (iops_limit) {
                delay = MSEC_PER_SEC / iops_limit;
-       else
-               delay = BTRFS_DISCARD_TARGET_MSEC / discardable_extents;
+       } else {
+               /*
+                * Unset iops_limit means go as fast as possible, so allow a
+                * delay of 0.
+                */
+               delay = 0;
+               min_delay = 0;
+       }
 
-       delay = clamp(delay, BTRFS_DISCARD_MIN_DELAY_MSEC,
-                     BTRFS_DISCARD_MAX_DELAY_MSEC);
+       delay = clamp(delay, min_delay, BTRFS_DISCARD_MAX_DELAY_MSEC);
        discard_ctl->delay_ms = delay;
 
        spin_unlock(&discard_ctl->lock);
index b53f0e30ce2b3bbb2e40baa1163ee57e29e942b7..9e1596bb208db09ff69d441c9ca3330ea7b940c2 100644 (file)
@@ -2250,6 +2250,20 @@ static int btrfs_init_csum_hash(struct btrfs_fs_info *fs_info, u16 csum_type)
 
        fs_info->csum_shash = csum_shash;
 
+       /*
+        * Check if the checksum implementation is a fast accelerated one.
+        * As-is this is a bit of a hack and should be replaced once the csum
+        * implementations provide that information themselves.
+        */
+       switch (csum_type) {
+       case BTRFS_CSUM_TYPE_CRC32:
+               if (!strstr(crypto_shash_driver_name(csum_shash), "generic"))
+                       set_bit(BTRFS_FS_CSUM_IMPL_FAST, &fs_info->flags);
+               break;
+       default:
+               break;
+       }
+
        btrfs_info(fs_info, "using %s (%s) checksum algorithm",
                        btrfs_super_csum_name(csum_type),
                        crypto_shash_driver_name(csum_shash));
index be94030e1dfbf34a356326c4812206be711073f3..138afa955370bc6dd651cd7c2ada6388a6a2f7f9 100644 (file)
@@ -763,7 +763,13 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
                        goto next;
                }
 
+               flags = em->flags;
                clear_bit(EXTENT_FLAG_PINNED, &em->flags);
+               /*
+                * In case we split the extent map, we want to preserve the
+                * EXTENT_FLAG_LOGGING flag on our extent map, but we don't want
+                * it on the new extent maps.
+                */
                clear_bit(EXTENT_FLAG_LOGGING, &flags);
                modified = !list_empty(&em->list);
 
@@ -774,7 +780,6 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
                if (em->start >= start && em_end <= end)
                        goto remove_em;
 
-               flags = em->flags;
                gen = em->generation;
                compressed = test_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
 
index 5cc5a1faaef5b571e81322b7b3699bf2017a591b..f649647392e0e47c62f030d5c59c74cf633e4fac 100644 (file)
@@ -3730,10 +3730,15 @@ static int check_direct_read(struct btrfs_fs_info *fs_info,
        if (!iter_is_iovec(iter))
                return 0;
 
-       for (seg = 0; seg < iter->nr_segs; seg++)
-               for (i = seg + 1; i < iter->nr_segs; i++)
-                       if (iter->iov[seg].iov_base == iter->iov[i].iov_base)
+       for (seg = 0; seg < iter->nr_segs; seg++) {
+               for (i = seg + 1; i < iter->nr_segs; i++) {
+                       const struct iovec *iov1 = iter_iov(iter) + seg;
+                       const struct iovec *iov2 = iter_iov(iter) + i;
+
+                       if (iov1->iov_base == iov2->iov_base)
                                return -EINVAL;
+               }
+       }
        return 0;
 }
 
index 0d250d052487cf04085e5b059e10be1810e7d654..d84cef89cdff522ab64931da108498d00637ea53 100644 (file)
@@ -2693,8 +2693,13 @@ static int __btrfs_add_free_space_zoned(struct btrfs_block_group *block_group,
                bg_reclaim_threshold = READ_ONCE(sinfo->bg_reclaim_threshold);
 
        spin_lock(&ctl->tree_lock);
+       /* Count initial region as zone_unusable until it gets activated. */
        if (!used)
                to_free = size;
+       else if (initial &&
+                test_bit(BTRFS_FS_ACTIVE_ZONE_TRACKING, &block_group->fs_info->flags) &&
+                (block_group->flags & (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_SYSTEM)))
+               to_free = 0;
        else if (initial)
                to_free = block_group->zone_capacity;
        else if (offset >= block_group->alloc_offset)
@@ -2722,7 +2727,8 @@ static int __btrfs_add_free_space_zoned(struct btrfs_block_group *block_group,
        reclaimable_unusable = block_group->zone_unusable -
                               (block_group->length - block_group->zone_capacity);
        /* All the region is now unusable. Mark it as unused and reclaim */
-       if (block_group->zone_unusable == block_group->length) {
+       if (block_group->zone_unusable == block_group->length &&
+           block_group->alloc_offset) {
                btrfs_mark_bg_unused(block_group);
        } else if (bg_reclaim_threshold &&
                   reclaimable_unusable >=
index 4c477eae689148dd59c45514eb2069a073d08155..24cd492294086c1dfa02b59e61d5f4d311e99c30 100644 (file)
@@ -120,11 +120,8 @@ enum {
        /* Indicate that we want to commit the transaction. */
        BTRFS_FS_NEED_TRANS_COMMIT,
 
-       /*
-        * Indicate metadata over-commit is disabled. This is set when active
-        * zone tracking is needed.
-        */
-       BTRFS_FS_NO_OVERCOMMIT,
+       /* This is set when active zone tracking is needed. */
+       BTRFS_FS_ACTIVE_ZONE_TRACKING,
 
        /*
         * Indicate if we have some features changed, this is mostly for
index 6c18dc9a1831d03b7ec04c13ac6efc19a28d7a67..957e4d76a7b6578d59fd8f0b7d887e30d02c4e2b 100644 (file)
@@ -5421,8 +5421,13 @@ static int btrfs_inode_by_name(struct btrfs_inode *dir, struct dentry *dentry,
                return -ENOMEM;
 
        ret = fscrypt_setup_filename(&dir->vfs_inode, &dentry->d_name, 1, &fname);
-       if (ret)
+       if (ret < 0)
                goto out;
+       /*
+        * fscrypt_setup_filename() should never return a positive value, but
+        * gcc on sparc/parisc thinks it can, so assert that doesn't happen.
+        */
+       ASSERT(ret == 0);
 
        /* This needs to handle no-key deletions later on */
 
index 84626c8ad5bf55a97d1a5265436934c100bd8493..ba769a1eb87ab24e535576b37db26e50be58b02b 100644 (file)
@@ -2859,6 +2859,7 @@ static long btrfs_ioctl_dev_info(struct btrfs_fs_info *fs_info,
        di_args->bytes_used = btrfs_device_get_bytes_used(dev);
        di_args->total_bytes = btrfs_device_get_total_bytes(dev);
        memcpy(di_args->uuid, dev->uuid, sizeof(di_args->uuid));
+       memcpy(di_args->fsid, dev->fs_devices->fsid, BTRFS_UUID_SIZE);
        if (dev->name)
                strscpy(di_args->path, btrfs_dev_name(dev), sizeof(di_args->path));
        else
@@ -3731,7 +3732,9 @@ static long btrfs_ioctl_qgroup_assign(struct file *file, void __user *arg)
        }
 
        /* update qgroup status and info */
+       mutex_lock(&fs_info->qgroup_ioctl_lock);
        err = btrfs_run_qgroups(trans);
+       mutex_unlock(&fs_info->qgroup_ioctl_lock);
        if (err < 0)
                btrfs_handle_fs_error(fs_info, err,
                                      "failed to update qgroup status and info");
index 52a7d2fa2284f89ae063ee436578337abdae2ee8..f41da7ac360d86767bd120900d89c1e1d3b82ab5 100644 (file)
@@ -2828,13 +2828,22 @@ cleanup:
 }
 
 /*
- * called from commit_transaction. Writes all changed qgroups to disk.
+ * Writes all changed qgroups to disk.
+ * Called by the transaction commit path and the qgroup assign ioctl.
  */
 int btrfs_run_qgroups(struct btrfs_trans_handle *trans)
 {
        struct btrfs_fs_info *fs_info = trans->fs_info;
        int ret = 0;
 
+       /*
+        * In case we are called from the qgroup assign ioctl, assert that we
+        * are holding the qgroup_ioctl_lock, otherwise we can race with a quota
+        * disable operation (ioctl) and access a freed quota root.
+        */
+       if (trans->transaction->state != TRANS_STATE_COMMIT_DOING)
+               lockdep_assert_held(&fs_info->qgroup_ioctl_lock);
+
        if (!fs_info->quota_root)
                return ret;
 
index 69c09508afb506ac8121caeae39fb2e7071362c0..3eecce86f63fc4e8d1cc96c6c7b09d84db076d1e 100644 (file)
@@ -308,8 +308,6 @@ void btrfs_add_bg_to_space_info(struct btrfs_fs_info *info,
        ASSERT(found);
        spin_lock(&found->lock);
        found->total_bytes += block_group->length;
-       if (test_bit(BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE, &block_group->runtime_flags))
-               found->active_total_bytes += block_group->length;
        found->disk_total += block_group->length * factor;
        found->bytes_used += block_group->used;
        found->disk_used += block_group->used * factor;
@@ -379,22 +377,6 @@ static u64 calc_available_free_space(struct btrfs_fs_info *fs_info,
        return avail;
 }
 
-static inline u64 writable_total_bytes(struct btrfs_fs_info *fs_info,
-                                      struct btrfs_space_info *space_info)
-{
-       /*
-        * On regular filesystem, all total_bytes are always writable. On zoned
-        * filesystem, there may be a limitation imposed by max_active_zones.
-        * For metadata allocation, we cannot finish an existing active block
-        * group to avoid a deadlock. Thus, we need to consider only the active
-        * groups to be writable for metadata space.
-        */
-       if (!btrfs_is_zoned(fs_info) || (space_info->flags & BTRFS_BLOCK_GROUP_DATA))
-               return space_info->total_bytes;
-
-       return space_info->active_total_bytes;
-}
-
 int btrfs_can_overcommit(struct btrfs_fs_info *fs_info,
                         struct btrfs_space_info *space_info, u64 bytes,
                         enum btrfs_reserve_flush_enum flush)
@@ -407,13 +389,13 @@ int btrfs_can_overcommit(struct btrfs_fs_info *fs_info,
                return 0;
 
        used = btrfs_space_info_used(space_info, true);
-       if (test_bit(BTRFS_FS_NO_OVERCOMMIT, &fs_info->flags) &&
+       if (test_bit(BTRFS_FS_ACTIVE_ZONE_TRACKING, &fs_info->flags) &&
            (space_info->flags & BTRFS_BLOCK_GROUP_METADATA))
                avail = 0;
        else
                avail = calc_available_free_space(fs_info, space_info, flush);
 
-       if (used + bytes < writable_total_bytes(fs_info, space_info) + avail)
+       if (used + bytes < space_info->total_bytes + avail)
                return 1;
        return 0;
 }
@@ -449,7 +431,7 @@ again:
                ticket = list_first_entry(head, struct reserve_ticket, list);
 
                /* Check and see if our ticket can be satisfied now. */
-               if ((used + ticket->bytes <= writable_total_bytes(fs_info, space_info)) ||
+               if ((used + ticket->bytes <= space_info->total_bytes) ||
                    btrfs_can_overcommit(fs_info, space_info, ticket->bytes,
                                         flush)) {
                        btrfs_space_info_update_bytes_may_use(fs_info,
@@ -829,7 +811,6 @@ btrfs_calc_reclaim_metadata_size(struct btrfs_fs_info *fs_info,
 {
        u64 used;
        u64 avail;
-       u64 total;
        u64 to_reclaim = space_info->reclaim_size;
 
        lockdep_assert_held(&space_info->lock);
@@ -844,9 +825,8 @@ btrfs_calc_reclaim_metadata_size(struct btrfs_fs_info *fs_info,
         * space.  If that's the case add in our overage so we make sure to put
         * appropriate pressure on the flushing state machine.
         */
-       total = writable_total_bytes(fs_info, space_info);
-       if (total + avail < used)
-               to_reclaim += used - (total + avail);
+       if (space_info->total_bytes + avail < used)
+               to_reclaim += used - (space_info->total_bytes + avail);
 
        return to_reclaim;
 }
@@ -856,11 +836,10 @@ static bool need_preemptive_reclaim(struct btrfs_fs_info *fs_info,
 {
        u64 global_rsv_size = fs_info->global_block_rsv.reserved;
        u64 ordered, delalloc;
-       u64 total = writable_total_bytes(fs_info, space_info);
        u64 thresh;
        u64 used;
 
-       thresh = mult_perc(total, 90);
+       thresh = mult_perc(space_info->total_bytes, 90);
 
        lockdep_assert_held(&space_info->lock);
 
@@ -923,8 +902,8 @@ static bool need_preemptive_reclaim(struct btrfs_fs_info *fs_info,
                                           BTRFS_RESERVE_FLUSH_ALL);
        used = space_info->bytes_used + space_info->bytes_reserved +
               space_info->bytes_readonly + global_rsv_size;
-       if (used < total)
-               thresh += total - used;
+       if (used < space_info->total_bytes)
+               thresh += space_info->total_bytes - used;
        thresh >>= space_info->clamp;
 
        used = space_info->bytes_pinned;
@@ -1651,7 +1630,7 @@ static int __reserve_bytes(struct btrfs_fs_info *fs_info,
         * can_overcommit() to ensure we can overcommit to continue.
         */
        if (!pending_tickets &&
-           ((used + orig_bytes <= writable_total_bytes(fs_info, space_info)) ||
+           ((used + orig_bytes <= space_info->total_bytes) ||
             btrfs_can_overcommit(fs_info, space_info, orig_bytes, flush))) {
                btrfs_space_info_update_bytes_may_use(fs_info, space_info,
                                                      orig_bytes);
@@ -1665,8 +1644,7 @@ static int __reserve_bytes(struct btrfs_fs_info *fs_info,
         */
        if (ret && unlikely(flush == BTRFS_RESERVE_FLUSH_EMERGENCY)) {
                used = btrfs_space_info_used(space_info, false);
-               if (used + orig_bytes <=
-                   writable_total_bytes(fs_info, space_info)) {
+               if (used + orig_bytes <= space_info->total_bytes) {
                        btrfs_space_info_update_bytes_may_use(fs_info, space_info,
                                                              orig_bytes);
                        ret = 0;
index fc99ea2b0c34fc2187813dffc2a206577e65ee22..2033b71b18cece2b5ee1e35877d184e1d3ced1b2 100644 (file)
@@ -96,8 +96,6 @@ struct btrfs_space_info {
        u64 bytes_may_use;      /* number of bytes that may be used for
                                   delalloc/allocations */
        u64 bytes_readonly;     /* total bytes that are read only */
-       /* Total bytes in the space, but only accounts active block groups. */
-       u64 active_total_bytes;
        u64 bytes_zone_unusable;        /* total bytes that are unusable until
                                           resetting the device zone */
 
index 581845bc206ad28b403d52f7b8dc421982078222..366fb4cde14584b5c1477869c064364c4a1c03fa 100644 (file)
@@ -1516,8 +1516,6 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
                shrinker_debugfs_rename(&s->s_shrink, "sb-%s:%s", fs_type->name,
                                        s->s_id);
                btrfs_sb(s)->bdev_holder = fs_type;
-               if (!strstr(crc32c_impl(), "generic"))
-                       set_bit(BTRFS_FS_CSUM_IMPL_FAST, &fs_info->flags);
                error = btrfs_fill_super(s, fs_devices, data);
        }
        if (!error)
@@ -1631,6 +1629,8 @@ static void btrfs_resize_thread_pool(struct btrfs_fs_info *fs_info,
        btrfs_workqueue_set_max(fs_info->hipri_workers, new_pool_size);
        btrfs_workqueue_set_max(fs_info->delalloc_workers, new_pool_size);
        btrfs_workqueue_set_max(fs_info->caching_workers, new_pool_size);
+       workqueue_set_max_active(fs_info->endio_workers, new_pool_size);
+       workqueue_set_max_active(fs_info->endio_meta_workers, new_pool_size);
        btrfs_workqueue_set_max(fs_info->endio_write_workers, new_pool_size);
        btrfs_workqueue_set_max(fs_info->endio_freespace_worker, new_pool_size);
        btrfs_workqueue_set_max(fs_info->delayed_workers, new_pool_size);
index 8c5efa5813b3779552fcffbf23bcad2c0ed9e7b6..37fc58a7f27edf789143f9b97323f36f6cdb6138 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/spinlock.h>
 #include <linux/completion.h>
 #include <linux/bug.h>
+#include <linux/list.h>
 #include <crypto/hash.h>
 #include "messages.h"
 #include "ctree.h"
@@ -778,6 +779,45 @@ static ssize_t btrfs_chunk_size_store(struct kobject *kobj,
        return len;
 }
 
+static ssize_t btrfs_size_classes_show(struct kobject *kobj,
+                                      struct kobj_attribute *a, char *buf)
+{
+       struct btrfs_space_info *sinfo = to_space_info(kobj);
+       struct btrfs_block_group *bg;
+       u32 none = 0;
+       u32 small = 0;
+       u32 medium = 0;
+       u32 large = 0;
+
+       for (int i = 0; i < BTRFS_NR_RAID_TYPES; ++i) {
+               down_read(&sinfo->groups_sem);
+               list_for_each_entry(bg, &sinfo->block_groups[i], list) {
+                       if (!btrfs_block_group_should_use_size_class(bg))
+                               continue;
+                       switch (bg->size_class) {
+                       case BTRFS_BG_SZ_NONE:
+                               none++;
+                               break;
+                       case BTRFS_BG_SZ_SMALL:
+                               small++;
+                               break;
+                       case BTRFS_BG_SZ_MEDIUM:
+                               medium++;
+                               break;
+                       case BTRFS_BG_SZ_LARGE:
+                               large++;
+                               break;
+                       }
+               }
+               up_read(&sinfo->groups_sem);
+       }
+       return sysfs_emit(buf, "none %u\n"
+                              "small %u\n"
+                              "medium %u\n"
+                              "large %u\n",
+                              none, small, medium, large);
+}
+
 #ifdef CONFIG_BTRFS_DEBUG
 /*
  * Request chunk allocation with current chunk size.
@@ -835,6 +875,7 @@ SPACE_INFO_ATTR(bytes_zone_unusable);
 SPACE_INFO_ATTR(disk_used);
 SPACE_INFO_ATTR(disk_total);
 BTRFS_ATTR_RW(space_info, chunk_size, btrfs_chunk_size_show, btrfs_chunk_size_store);
+BTRFS_ATTR(space_info, size_classes, btrfs_size_classes_show);
 
 static ssize_t btrfs_sinfo_bg_reclaim_threshold_show(struct kobject *kobj,
                                                     struct kobj_attribute *a,
@@ -887,6 +928,7 @@ static struct attribute *space_info_attrs[] = {
        BTRFS_ATTR_PTR(space_info, disk_total),
        BTRFS_ATTR_PTR(space_info, bg_reclaim_threshold),
        BTRFS_ATTR_PTR(space_info, chunk_size),
+       BTRFS_ATTR_PTR(space_info, size_classes),
 #ifdef CONFIG_BTRFS_DEBUG
        BTRFS_ATTR_PTR(space_info, force_chunk_alloc),
 #endif
index 18329ebcb1cbffa0e3c98b9eaea654ec39529662..b8d5b1fa9a03b447b579d50a19c15810f231c79e 100644 (file)
@@ -2035,7 +2035,20 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans, int err)
 
        if (current->journal_info == trans)
                current->journal_info = NULL;
-       btrfs_scrub_cancel(fs_info);
+
+       /*
+        * If relocation is running, we can't cancel scrub because that will
+        * result in a deadlock. Before relocating a block group, relocation
+        * pauses scrub, then starts and commits a transaction before unpausing
+        * scrub. If the transaction commit is being done by the relocation
+        * task or triggered by another task and the relocation task is waiting
+        * for the commit, and we end up here due to an error in the commit
+        * path, then calling btrfs_scrub_cancel() will deadlock, as we are
+        * asking for scrub to stop while having it asked to be paused higher
+        * above in relocation code.
+        */
+       if (!test_bit(BTRFS_FS_RELOC_RUNNING, &fs_info->flags))
+               btrfs_scrub_cancel(fs_info);
 
        kmem_cache_free(btrfs_trans_handle_cachep, trans);
 }
index 7823168c08a6aa22466addc1472f0c4f3732529c..c6d59287040019a17ac4796f1f69f105a316178e 100644 (file)
@@ -1366,8 +1366,17 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, fmode_t flags,
         * So, we need to add a special mount option to scan for
         * later supers, using BTRFS_SUPER_MIRROR_MAX instead
         */
-       flags |= FMODE_EXCL;
 
+       /*
+        * Avoid using flag |= FMODE_EXCL here, as the systemd-udev may
+        * initiate the device scan which may race with the user's mount
+        * or mkfs command, resulting in failure.
+        * Since the device scan is solely for reading purposes, there is
+        * no need for FMODE_EXCL. Additionally, the devices are read again
+        * during the mount process. It is ok to get some inconsistent
+        * values temporarily, as the device paths of the fsid are the only
+        * required information for assembling the volume.
+        */
        bdev = blkdev_get_by_path(path, flags, holder);
        if (IS_ERR(bdev))
                return ERR_CAST(bdev);
@@ -3266,8 +3275,15 @@ int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset)
        btrfs_scrub_pause(fs_info);
        ret = btrfs_relocate_block_group(fs_info, chunk_offset);
        btrfs_scrub_continue(fs_info);
-       if (ret)
+       if (ret) {
+               /*
+                * If we had a transaction abort, stop all running scrubs.
+                * See transaction.c:cleanup_transaction() why we do it here.
+                */
+               if (BTRFS_FS_ERROR(fs_info))
+                       btrfs_scrub_cancel(fs_info);
                return ret;
+       }
 
        block_group = btrfs_lookup_block_group(fs_info, chunk_offset);
        if (!block_group)
@@ -6363,7 +6379,8 @@ int __btrfs_map_block(struct btrfs_fs_info *fs_info, enum btrfs_map_op op,
        ASSERT(op != BTRFS_MAP_DISCARD);
 
        em = btrfs_get_chunk_map(fs_info, logical, *length);
-       ASSERT(!IS_ERR(em));
+       if (IS_ERR(em))
+               return PTR_ERR(em);
 
        map = em->map_lookup;
        data_stripes = nr_data_stripes(map);
index 0ebeaf4e81f9329541f7e6b29457a69923d6e5d2..fc4b20c2688a060b38a9afee1f10d002f2489818 100644 (file)
@@ -444,10 +444,6 @@ static const struct xattr_handler btrfs_btrfs_xattr_handler = {
 
 const struct xattr_handler *btrfs_xattr_handlers[] = {
        &btrfs_security_xattr_handler,
-#ifdef CONFIG_BTRFS_FS_POSIX_ACL
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
-#endif
        &btrfs_trusted_xattr_handler,
        &btrfs_user_xattr_handler,
        &btrfs_btrfs_xattr_handler,
index f95b2c94d6199a62194d785ffa3d427c0a3fa79b..45d04092f2f8cdadded5570b677738c9de74197a 100644 (file)
@@ -524,8 +524,7 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache)
                }
                atomic_set(&zone_info->active_zones_left,
                           max_active_zones - nactive);
-               /* Overcommit does not work well with active zone tacking. */
-               set_bit(BTRFS_FS_NO_OVERCOMMIT, &fs_info->flags);
+               set_bit(BTRFS_FS_ACTIVE_ZONE_TRACKING, &fs_info->flags);
        }
 
        /* Validate superblock log */
@@ -1581,9 +1580,19 @@ void btrfs_calc_zone_unusable(struct btrfs_block_group *cache)
                return;
 
        WARN_ON(cache->bytes_super != 0);
-       unusable = (cache->alloc_offset - cache->used) +
-                  (cache->length - cache->zone_capacity);
-       free = cache->zone_capacity - cache->alloc_offset;
+
+       /* Check for block groups never get activated */
+       if (test_bit(BTRFS_FS_ACTIVE_ZONE_TRACKING, &cache->fs_info->flags) &&
+           cache->flags & (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_SYSTEM) &&
+           !test_bit(BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE, &cache->runtime_flags) &&
+           cache->alloc_offset == 0) {
+               unusable = cache->length;
+               free = 0;
+       } else {
+               unusable = (cache->alloc_offset - cache->used) +
+                          (cache->length - cache->zone_capacity);
+               free = cache->zone_capacity - cache->alloc_offset;
+       }
 
        /* We only need ->free_space in ALLOC_SEQ block groups */
        cache->cached = BTRFS_CACHE_FINISHED;
@@ -1902,7 +1911,11 @@ bool btrfs_zone_activate(struct btrfs_block_group *block_group)
 
        /* Successfully activated all the zones */
        set_bit(BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE, &block_group->runtime_flags);
-       space_info->active_total_bytes += block_group->length;
+       WARN_ON(block_group->alloc_offset != 0);
+       if (block_group->zone_unusable == block_group->length) {
+               block_group->zone_unusable = block_group->length - block_group->zone_capacity;
+               space_info->bytes_zone_unusable -= block_group->zone_capacity;
+       }
        spin_unlock(&block_group->lock);
        btrfs_try_granting_tickets(fs_info, space_info);
        spin_unlock(&space_info->lock);
@@ -2086,11 +2099,21 @@ bool btrfs_can_activate_zone(struct btrfs_fs_devices *fs_devices, u64 flags)
                if (!device->bdev)
                        continue;
 
-               if (!zinfo->max_active_zones ||
-                   atomic_read(&zinfo->active_zones_left)) {
+               if (!zinfo->max_active_zones) {
                        ret = true;
                        break;
                }
+
+               switch (flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) {
+               case 0: /* single */
+                       ret = (atomic_read(&zinfo->active_zones_left) >= 1);
+                       break;
+               case BTRFS_BLOCK_GROUP_DUP:
+                       ret = (atomic_read(&zinfo->active_zones_left) >= 2);
+                       break;
+               }
+               if (ret)
+                       break;
        }
        mutex_unlock(&fs_info->chunk_mutex);
 
@@ -2256,7 +2279,7 @@ int btrfs_zone_finish_one_bg(struct btrfs_fs_info *fs_info)
                u64 avail;
 
                spin_lock(&block_group->lock);
-               if (block_group->reserved ||
+               if (block_group->reserved || block_group->alloc_offset == 0 ||
                    (block_group->flags & BTRFS_BLOCK_GROUP_SYSTEM)) {
                        spin_unlock(&block_group->lock);
                        continue;
@@ -2293,10 +2316,6 @@ int btrfs_zoned_activate_one_bg(struct btrfs_fs_info *fs_info,
        if (!btrfs_is_zoned(fs_info) || (space_info->flags & BTRFS_BLOCK_GROUP_DATA))
                return 0;
 
-       /* No more block groups to activate */
-       if (space_info->active_total_bytes == space_info->total_bytes)
-               return 0;
-
        for (;;) {
                int ret;
                bool need_finish = false;
index 9e1e2add541e07a593bcc743d73eb05ed51bfbd9..10390f53f3f529321dada7eec6593a27d0054ca4 100644 (file)
@@ -2581,7 +2581,7 @@ int block_truncate_page(struct address_space *mapping,
        struct inode *inode = mapping->host;
        struct page *page;
        struct buffer_head *bh;
-       int err;
+       int err = 0;
 
        blocksize = i_blocksize(inode);
        length = offset & (blocksize - 1);
@@ -2594,9 +2594,8 @@ int block_truncate_page(struct address_space *mapping,
        iblock = (sector_t)index << (PAGE_SHIFT - inode->i_blkbits);
        
        page = grab_cache_page(mapping, index);
-       err = -ENOMEM;
        if (!page)
-               goto out;
+               return -ENOMEM;
 
        if (!page_has_buffers(page))
                create_empty_buffers(page, blocksize, 0);
@@ -2610,7 +2609,6 @@ int block_truncate_page(struct address_space *mapping,
                pos += blocksize;
        }
 
-       err = 0;
        if (!buffer_mapped(bh)) {
                WARN_ON(bh->b_size != blocksize);
                err = get_block(inode, iblock, bh, 0);
@@ -2634,12 +2632,11 @@ int block_truncate_page(struct address_space *mapping,
 
        zero_user(page, offset, length);
        mark_buffer_dirty(bh);
-       err = 0;
 
 unlock:
        unlock_page(page);
        put_page(page);
-out:
+
        return err;
 }
 EXPORT_SYMBOL(block_truncate_page);
index f65b07cc33a2471d196d7c2e5bb650db822299e0..1fe1b62abebd135befe3ee67b2f1060ed30286f8 100644 (file)
@@ -1411,10 +1411,6 @@ void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx)
  * attributes are handled directly.
  */
 const struct xattr_handler *ceph_xattr_handlers[] = {
-#ifdef CONFIG_CEPH_FS_POSIX_ACL
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
-#endif
        &ceph_other_xattr_handler,
        NULL,
 };
index 75d5e06306ea52d30038ffa4f2d7760bbcf346e0..bfc964b36c72ecaa9da088892be7349731b327dc 100644 (file)
@@ -99,6 +99,23 @@ path_to_dentry(struct cifs_sb_info *cifs_sb, const char *path)
        return dentry;
 }
 
+static const char *path_no_prefix(struct cifs_sb_info *cifs_sb,
+                                 const char *path)
+{
+       size_t len = 0;
+
+       if (!*path)
+               return path;
+
+       if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
+           cifs_sb->prepath) {
+               len = strlen(cifs_sb->prepath) + 1;
+               if (unlikely(len > strlen(path)))
+                       return ERR_PTR(-EINVAL);
+       }
+       return path + len;
+}
+
 /*
  * Open the and cache a directory handle.
  * If error then *cfid is not initialized.
@@ -125,6 +142,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
        struct dentry *dentry = NULL;
        struct cached_fid *cfid;
        struct cached_fids *cfids;
+       const char *npath;
 
        if (tcon == NULL || tcon->cfids == NULL || tcon->nohandlecache ||
            is_smb1_server(tcon->ses->server))
@@ -160,6 +178,20 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
                return 0;
        }
 
+       /*
+        * Skip any prefix paths in @path as lookup_positive_unlocked() ends up
+        * calling ->lookup() which already adds those through
+        * build_path_from_dentry().  Also, do it earlier as we might reconnect
+        * below when trying to send compounded request and then potentially
+        * having a different prefix path (e.g. after DFS failover).
+        */
+       npath = path_no_prefix(cifs_sb, path);
+       if (IS_ERR(npath)) {
+               rc = PTR_ERR(npath);
+               kfree(utf16_path);
+               return rc;
+       }
+
        /*
         * We do not hold the lock for the open because in case
         * SMB2_open needs to reconnect.
@@ -184,6 +216,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 
        oparms = (struct cifs_open_parms) {
                .tcon = tcon,
+               .path = path,
                .create_options = cifs_create_options(cifs_sb, CREATE_NOT_FILE),
                .desired_access = FILE_READ_ATTRIBUTES,
                .disposition = FILE_OPEN,
@@ -251,10 +284,10 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
                                (char *)&cfid->file_all_info))
                cfid->file_all_info_is_valid = true;
 
-       if (!path[0])
+       if (!npath[0])
                dentry = dget(cifs_sb->root);
        else {
-               dentry = path_to_dentry(cifs_sb, path);
+               dentry = path_to_dentry(cifs_sb, npath);
                if (IS_ERR(dentry)) {
                        rc = -ENOENT;
                        goto oshr_free;
index 1911f7016fa1d5e747681f6df06e75a27a6db199..e9c8c088d948ccb44fa110f64ab99729a50d1e2f 100644 (file)
@@ -176,7 +176,7 @@ static int cifs_debug_files_proc_show(struct seq_file *m, void *v)
 
        seq_puts(m, "# Version:1\n");
        seq_puts(m, "# Format:\n");
-       seq_puts(m, "# <tree id> <persistent fid> <flags> <count> <pid> <uid>");
+       seq_puts(m, "# <tree id> <ses id> <persistent fid> <flags> <count> <pid> <uid>");
 #ifdef CONFIG_CIFS_DEBUG2
        seq_printf(m, " <filename> <mid>\n");
 #else
@@ -189,8 +189,9 @@ static int cifs_debug_files_proc_show(struct seq_file *m, void *v)
                                spin_lock(&tcon->open_file_lock);
                                list_for_each_entry(cfile, &tcon->openFileList, tlist) {
                                        seq_printf(m,
-                                               "0x%x 0x%llx 0x%x %d %d %d %pd",
+                                               "0x%x 0x%llx 0x%llx 0x%x %d %d %d %pd",
                                                tcon->tid,
+                                               ses->Suid,
                                                cfile->fid.persistent_fid,
                                                cfile->f_flags,
                                                cfile->count,
@@ -216,6 +217,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
 {
        struct mid_q_entry *mid_entry;
        struct TCP_Server_Info *server;
+       struct TCP_Server_Info *chan_server;
        struct cifs_ses *ses;
        struct cifs_tcon *tcon;
        struct cifs_server_iface *iface;
@@ -420,6 +422,11 @@ skip_rdma:
                                   from_kuid(&init_user_ns, ses->linux_uid),
                                   from_kuid(&init_user_ns, ses->cred_uid));
 
+                       if (ses->dfs_root_ses) {
+                               seq_printf(m, "\n\tDFS root session id: 0x%llx",
+                                          ses->dfs_root_ses->Suid);
+                       }
+
                        spin_lock(&ses->chan_lock);
                        if (CIFS_CHAN_NEEDS_RECONNECT(ses, 0))
                                seq_puts(m, "\tPrimary channel: DISCONNECTED ");
@@ -469,23 +476,35 @@ skip_rdma:
                                        seq_puts(m, "\t\t[CONNECTED]\n");
                        }
                        spin_unlock(&ses->iface_lock);
+
+                       seq_puts(m, "\n\n\tMIDs: ");
+                       spin_lock(&ses->chan_lock);
+                       for (j = 0; j < ses->chan_count; j++) {
+                               chan_server = ses->chans[j].server;
+                               if (!chan_server)
+                                       continue;
+
+                               if (list_empty(&chan_server->pending_mid_q))
+                                       continue;
+
+                               seq_printf(m, "\n\tServer ConnectionId: 0x%llx",
+                                          chan_server->conn_id);
+                               spin_lock(&chan_server->mid_lock);
+                               list_for_each_entry(mid_entry, &chan_server->pending_mid_q, qhead) {
+                                       seq_printf(m, "\n\t\tState: %d com: %d pid: %d cbdata: %p mid %llu",
+                                                  mid_entry->mid_state,
+                                                  le16_to_cpu(mid_entry->command),
+                                                  mid_entry->pid,
+                                                  mid_entry->callback_data,
+                                                  mid_entry->mid);
+                               }
+                               spin_unlock(&chan_server->mid_lock);
+                       }
+                       spin_unlock(&ses->chan_lock);
+                       seq_puts(m, "\n--\n");
                }
                if (i == 0)
                        seq_printf(m, "\n\t\t[NONE]");
-
-               seq_puts(m, "\n\n\tMIDs: ");
-               spin_lock(&server->mid_lock);
-               list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) {
-                       seq_printf(m, "\n\tState: %d com: %d pid:"
-                                       " %d cbdata: %p mid %llu\n",
-                                       mid_entry->mid_state,
-                                       le16_to_cpu(mid_entry->command),
-                                       mid_entry->pid,
-                                       mid_entry->callback_data,
-                                       mid_entry->mid);
-               }
-               spin_unlock(&server->mid_lock);
-               seq_printf(m, "\n--\n");
        }
        if (c == 0)
                seq_printf(m, "\n\t[NONE]");
index 2b1a8d55b4ec427dcd25ddad2439bd9a65f79c93..0329a907bdfe8acc709069d5bb165ddd1fdcdb72 100644 (file)
@@ -171,14 +171,13 @@ static struct vfsmount *cifs_dfs_do_automount(struct path *path)
                mnt = ERR_CAST(full_path);
                goto out;
        }
-
-       convert_delimiter(full_path, '/');
        cifs_dbg(FYI, "%s: full_path: %s\n", __func__, full_path);
 
        tmp = *cur_ctx;
        tmp.source = full_path;
        tmp.leaf_fullpath = NULL;
        tmp.UNC = tmp.prepath = NULL;
+       tmp.dfs_root_ses = NULL;
 
        rc = smb3_fs_context_dup(ctx, &tmp);
        if (rc) {
index 013a4bd65280ce9d7341796e456f189eff255367..65175919228014001a7b5c0b0acc4df8c72ed8b2 100644 (file)
@@ -61,8 +61,6 @@ struct cifs_sb_info {
        /* only used when CIFS_MOUNT_USE_PREFIX_PATH is set */
        char *prepath;
 
-       /* randomly generated 128-bit number for indexing dfs mount groups in referral cache */
-       uuid_t dfs_mount_id;
        /*
         * Indicate whether serverino option was turned off later
         * (cifs_autodisable_serverino) in order to match new mounts.
index cbcf210d56e4863d705597175ee952100cb4c51e..ac9034fce409d27be6640a1fd1dbcea66c3abf32 100644 (file)
@@ -731,13 +731,16 @@ static void cifs_umount_begin(struct super_block *sb)
        spin_lock(&tcon->tc_lock);
        if ((tcon->tc_count > 1) || (tcon->status == TID_EXITING)) {
                /* we have other mounts to same share or we have
-                  already tried to force umount this and woken up
+                  already tried to umount this and woken up
                   all waiting network requests, nothing to do */
                spin_unlock(&tcon->tc_lock);
                spin_unlock(&cifs_tcp_ses_lock);
                return;
-       } else if (tcon->tc_count == 1)
-               tcon->status = TID_EXITING;
+       }
+       /*
+        * can not set tcon->status to TID_EXITING yet since we don't know if umount -f will
+        * fail later (e.g. due to open files).  TID_EXITING will be set just before tdis req sent
+        */
        spin_unlock(&tcon->tc_lock);
        spin_unlock(&cifs_tcp_ses_lock);
 
index 71fe0a0a799265b677bb8d874de1f29d73ed105b..415176b2cf321ff2c270d410f47b04a310938a82 100644 (file)
@@ -124,7 +124,10 @@ extern const struct dentry_operations cifs_ci_dentry_ops;
 #ifdef CONFIG_CIFS_DFS_UPCALL
 extern struct vfsmount *cifs_dfs_d_automount(struct path *path);
 #else
-#define cifs_dfs_d_automount NULL
+static inline struct vfsmount *cifs_dfs_d_automount(struct path *path)
+{
+       return ERR_PTR(-EREMOTE);
+}
 #endif
 
 /* Functions related to symlinks */
index a99883f16d9467d75dd167ada1d32b5a951a617d..08a73dcb778641bc4d313d34632bf06d9d3ed621 100644 (file)
@@ -1233,6 +1233,7 @@ struct cifs_tcon {
        /* BB add field for back pointer to sb struct(s)? */
 #ifdef CONFIG_CIFS_DFS_UPCALL
        struct list_head ulist; /* cache update list */
+       struct list_head dfs_ses_list;
 #endif
        struct delayed_work     query_interfaces; /* query interfaces workqueue job */
 };
@@ -1749,9 +1750,8 @@ struct cifs_mount_ctx {
        struct TCP_Server_Info *server;
        struct cifs_ses *ses;
        struct cifs_tcon *tcon;
-       struct cifs_ses *root_ses;
-       uuid_t mount_id;
        char *origin_fullpath, *leaf_fullpath;
+       struct list_head dfs_ses_list;
 };
 
 static inline void free_dfs_info_param(struct dfs_info3_param *param)
index a43c78396dd8815a9b972814bb599dafd2c4c456..9d963caec35c8d07f671aefca26ae1ee9a63a82d 100644 (file)
@@ -71,7 +71,7 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
        int rc;
        struct cifs_ses *ses;
        struct TCP_Server_Info *server;
-       struct nls_table *nls_codepage;
+       struct nls_table *nls_codepage = NULL;
 
        /*
         * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
@@ -86,13 +86,11 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
 
        /*
         * only tree disconnect, open, and write, (and ulogoff which does not
-        * have tcon) are allowed as we start force umount
+        * have tcon) are allowed as we start umount
         */
        spin_lock(&tcon->tc_lock);
        if (tcon->status == TID_EXITING) {
-               if (smb_command != SMB_COM_WRITE_ANDX &&
-                   smb_command != SMB_COM_OPEN_ANDX &&
-                   smb_command != SMB_COM_TREE_DISCONNECT) {
+               if (smb_command != SMB_COM_TREE_DISCONNECT) {
                        spin_unlock(&tcon->tc_lock);
                        cifs_dbg(FYI, "can not send cmd %d while umounting\n",
                                 smb_command);
@@ -101,6 +99,7 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
        }
        spin_unlock(&tcon->tc_lock);
 
+again:
        rc = cifs_wait_for_server_reconnect(server, tcon->retry);
        if (rc)
                return rc;
@@ -112,8 +111,7 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
        }
        spin_unlock(&ses->chan_lock);
 
-       nls_codepage = load_nls_default();
-
+       mutex_lock(&ses->session_mutex);
        /*
         * Recheck after acquire mutex. If another thread is negotiating
         * and the server never sends an answer the socket will be closed
@@ -122,29 +120,38 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
        spin_lock(&server->srv_lock);
        if (server->tcpStatus == CifsNeedReconnect) {
                spin_unlock(&server->srv_lock);
+               mutex_unlock(&ses->session_mutex);
+
+               if (tcon->retry)
+                       goto again;
                rc = -EHOSTDOWN;
                goto out;
        }
        spin_unlock(&server->srv_lock);
 
+       nls_codepage = load_nls_default();
+
        /*
         * need to prevent multiple threads trying to simultaneously
         * reconnect the same SMB session
         */
+       spin_lock(&ses->ses_lock);
        spin_lock(&ses->chan_lock);
-       if (!cifs_chan_needs_reconnect(ses, server)) {
+       if (!cifs_chan_needs_reconnect(ses, server) &&
+           ses->ses_status == SES_GOOD) {
                spin_unlock(&ses->chan_lock);
+               spin_unlock(&ses->ses_lock);
 
                /* this means that we only need to tree connect */
                if (tcon->need_reconnect)
                        goto skip_sess_setup;
 
-               rc = -EHOSTDOWN;
+               mutex_unlock(&ses->session_mutex);
                goto out;
        }
        spin_unlock(&ses->chan_lock);
+       spin_unlock(&ses->ses_lock);
 
-       mutex_lock(&ses->session_mutex);
        rc = cifs_negotiate_protocol(0, ses, server);
        if (!rc)
                rc = cifs_setup_session(0, ses, server, nls_codepage);
@@ -4375,8 +4382,13 @@ CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
                return -ENODEV;
 
 getDFSRetry:
-       rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
-                     (void **) &pSMBr);
+       /*
+        * Use smb_init_no_reconnect() instead of smb_init() as
+        * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus
+        * causing an infinite recursion.
+        */
+       rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
+                                  (void **)&pSMB, (void **)&pSMBr);
        if (rc)
                return rc;
 
index 5233f14f0636ac0fa65ff1d1b058d186543ffada..1cbb9058799572686193dfa84925d0b03601d5ad 100644 (file)
@@ -212,31 +212,42 @@ cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server,
                        cifs_chan_update_iface(ses, server);
 
                spin_lock(&ses->chan_lock);
-               if (!mark_smb_session && cifs_chan_needs_reconnect(ses, server))
-                       goto next_session;
+               if (!mark_smb_session && cifs_chan_needs_reconnect(ses, server)) {
+                       spin_unlock(&ses->chan_lock);
+                       continue;
+               }
 
                if (mark_smb_session)
                        CIFS_SET_ALL_CHANS_NEED_RECONNECT(ses);
                else
                        cifs_chan_set_need_reconnect(ses, server);
 
+               cifs_dbg(FYI, "%s: channel connect bitmap: 0x%lx\n",
+                        __func__, ses->chans_need_reconnect);
+
                /* If all channels need reconnect, then tcon needs reconnect */
-               if (!mark_smb_session && !CIFS_ALL_CHANS_NEED_RECONNECT(ses))
-                       goto next_session;
+               if (!mark_smb_session && !CIFS_ALL_CHANS_NEED_RECONNECT(ses)) {
+                       spin_unlock(&ses->chan_lock);
+                       continue;
+               }
+               spin_unlock(&ses->chan_lock);
 
+               spin_lock(&ses->ses_lock);
                ses->ses_status = SES_NEED_RECON;
+               spin_unlock(&ses->ses_lock);
 
                list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
                        tcon->need_reconnect = true;
+                       spin_lock(&tcon->tc_lock);
                        tcon->status = TID_NEED_RECON;
+                       spin_unlock(&tcon->tc_lock);
                }
                if (ses->tcon_ipc) {
                        ses->tcon_ipc->need_reconnect = true;
+                       spin_lock(&ses->tcon_ipc->tc_lock);
                        ses->tcon_ipc->status = TID_NEED_RECON;
+                       spin_unlock(&ses->tcon_ipc->tc_lock);
                }
-
-next_session:
-               spin_unlock(&ses->chan_lock);
        }
        spin_unlock(&cifs_tcp_ses_lock);
 }
@@ -1721,7 +1732,7 @@ out_err:
        return ERR_PTR(rc);
 }
 
-/* this function must be called with ses_lock held */
+/* this function must be called with ses_lock and chan_lock held */
 static int match_session(struct cifs_ses *ses, struct smb3_fs_context *ctx)
 {
        if (ctx->sectype != Unspecified &&
@@ -1732,12 +1743,8 @@ static int match_session(struct cifs_ses *ses, struct smb3_fs_context *ctx)
         * If an existing session is limited to less channels than
         * requested, it should not be reused
         */
-       spin_lock(&ses->chan_lock);
-       if (ses->chan_max < ctx->max_channels) {
-               spin_unlock(&ses->chan_lock);
+       if (ses->chan_max < ctx->max_channels)
                return 0;
-       }
-       spin_unlock(&ses->chan_lock);
 
        switch (ses->sectype) {
        case Kerberos:
@@ -1865,10 +1872,13 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
                        spin_unlock(&ses->ses_lock);
                        continue;
                }
+               spin_lock(&ses->chan_lock);
                if (!match_session(ses, ctx)) {
+                       spin_unlock(&ses->chan_lock);
                        spin_unlock(&ses->ses_lock);
                        continue;
                }
+               spin_unlock(&ses->chan_lock);
                spin_unlock(&ses->ses_lock);
 
                ++ses->ses_count;
@@ -2229,6 +2239,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
         * need to lock before changing something in the session.
         */
        spin_lock(&cifs_tcp_ses_lock);
+       ses->dfs_root_ses = ctx->dfs_root_ses;
        list_add(&ses->smb_ses_list, &server->smb_ses_list);
        spin_unlock(&cifs_tcp_ses_lock);
 
@@ -2313,6 +2324,7 @@ cifs_put_tcon(struct cifs_tcon *tcon)
        WARN_ON(tcon->tc_count < 0);
 
        list_del_init(&tcon->tcon_list);
+       tcon->status = TID_EXITING;
        spin_unlock(&tcon->tc_lock);
        spin_unlock(&cifs_tcp_ses_lock);
 
@@ -2692,6 +2704,7 @@ cifs_match_super(struct super_block *sb, void *data)
 
        spin_lock(&tcp_srv->srv_lock);
        spin_lock(&ses->ses_lock);
+       spin_lock(&ses->chan_lock);
        spin_lock(&tcon->tc_lock);
        if (!match_server(tcp_srv, ctx, dfs_super_cmp) ||
            !match_session(ses, ctx) ||
@@ -2704,6 +2717,7 @@ cifs_match_super(struct super_block *sb, void *data)
        rc = compare_mount_options(sb, mnt_data);
 out:
        spin_unlock(&tcon->tc_lock);
+       spin_unlock(&ses->chan_lock);
        spin_unlock(&ses->ses_lock);
        spin_unlock(&tcp_srv->srv_lock);
 
@@ -3407,7 +3421,8 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
        bool isdfs;
        int rc;
 
-       uuid_gen(&mnt_ctx.mount_id);
+       INIT_LIST_HEAD(&mnt_ctx.dfs_ses_list);
+
        rc = dfs_mount_share(&mnt_ctx, &isdfs);
        if (rc)
                goto error;
@@ -3427,7 +3442,6 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
        kfree(cifs_sb->prepath);
        cifs_sb->prepath = ctx->prepath;
        ctx->prepath = NULL;
-       uuid_copy(&cifs_sb->dfs_mount_id, &mnt_ctx.mount_id);
 
 out:
        cifs_try_adding_channels(cifs_sb, mnt_ctx.ses);
@@ -3439,7 +3453,7 @@ out:
        return rc;
 
 error:
-       dfs_cache_put_refsrv_sessions(&mnt_ctx.mount_id);
+       dfs_put_root_smb_sessions(&mnt_ctx.dfs_ses_list);
        kfree(mnt_ctx.origin_fullpath);
        kfree(mnt_ctx.leaf_fullpath);
        cifs_mount_put_conns(&mnt_ctx);
@@ -3637,9 +3651,6 @@ cifs_umount(struct cifs_sb_info *cifs_sb)
        spin_unlock(&cifs_sb->tlink_tree_lock);
 
        kfree(cifs_sb->prepath);
-#ifdef CONFIG_CIFS_DFS_UPCALL
-       dfs_cache_put_refsrv_sessions(&cifs_sb->dfs_mount_id);
-#endif
        call_rcu(&cifs_sb->rcu, delayed_free);
 }
 
@@ -3654,11 +3665,19 @@ cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses,
 
        /* only send once per connect */
        spin_lock(&server->srv_lock);
-       if (!server->ops->need_neg(server) ||
+       if (server->tcpStatus != CifsGood &&
+           server->tcpStatus != CifsNew &&
            server->tcpStatus != CifsNeedNegotiate) {
+               spin_unlock(&server->srv_lock);
+               return -EHOSTDOWN;
+       }
+
+       if (!server->ops->need_neg(server) &&
+           server->tcpStatus == CifsGood) {
                spin_unlock(&server->srv_lock);
                return 0;
        }
+
        server->tcpStatus = CifsInNegotiate;
        spin_unlock(&server->srv_lock);
 
@@ -3692,23 +3711,28 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
        bool is_binding = false;
 
        spin_lock(&ses->ses_lock);
+       cifs_dbg(FYI, "%s: channel connect bitmap: 0x%lx\n",
+                __func__, ses->chans_need_reconnect);
+
        if (ses->ses_status != SES_GOOD &&
            ses->ses_status != SES_NEW &&
            ses->ses_status != SES_NEED_RECON) {
                spin_unlock(&ses->ses_lock);
-               return 0;
+               return -EHOSTDOWN;
        }
 
        /* only send once per connect */
        spin_lock(&ses->chan_lock);
-       if (CIFS_ALL_CHANS_GOOD(ses) ||
-           cifs_chan_in_reconnect(ses, server)) {
+       if (CIFS_ALL_CHANS_GOOD(ses)) {
+               if (ses->ses_status == SES_NEED_RECON)
+                       ses->ses_status = SES_GOOD;
                spin_unlock(&ses->chan_lock);
                spin_unlock(&ses->ses_lock);
                return 0;
        }
-       is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses);
+
        cifs_chan_set_in_reconnect(ses, server);
+       is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses);
        spin_unlock(&ses->chan_lock);
 
        if (!is_binding)
@@ -4038,9 +4062,13 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
 
        /* only send once per connect */
        spin_lock(&tcon->tc_lock);
-       if (tcon->ses->ses_status != SES_GOOD ||
-           (tcon->status != TID_NEW &&
-           tcon->status != TID_NEED_TCON)) {
+       if (tcon->status != TID_NEW &&
+           tcon->status != TID_NEED_TCON) {
+               spin_unlock(&tcon->tc_lock);
+               return -EHOSTDOWN;
+       }
+
+       if (tcon->status == TID_GOOD) {
                spin_unlock(&tcon->tc_lock);
                return 0;
        }
index b64d20374b9c853d4402ef3f8617dbfa57921d94..3a11716b6e13eb4b724177265a343981b26143a4 100644 (file)
@@ -95,25 +95,31 @@ static int get_session(struct cifs_mount_ctx *mnt_ctx, const char *full_path)
        ctx->leaf_fullpath = (char *)full_path;
        rc = cifs_mount_get_session(mnt_ctx);
        ctx->leaf_fullpath = NULL;
-       if (!rc) {
-               struct cifs_ses *ses = mnt_ctx->ses;
 
-               mutex_lock(&ses->session_mutex);
-               ses->dfs_root_ses = mnt_ctx->root_ses;
-               mutex_unlock(&ses->session_mutex);
-       }
        return rc;
 }
 
-static void set_root_ses(struct cifs_mount_ctx *mnt_ctx)
+static int get_root_smb_session(struct cifs_mount_ctx *mnt_ctx)
 {
-       if (mnt_ctx->ses) {
+       struct smb3_fs_context *ctx = mnt_ctx->fs_ctx;
+       struct dfs_root_ses *root_ses;
+       struct cifs_ses *ses = mnt_ctx->ses;
+
+       if (ses) {
+               root_ses = kmalloc(sizeof(*root_ses), GFP_KERNEL);
+               if (!root_ses)
+                       return -ENOMEM;
+
+               INIT_LIST_HEAD(&root_ses->list);
+
                spin_lock(&cifs_tcp_ses_lock);
-               mnt_ctx->ses->ses_count++;
+               ses->ses_count++;
                spin_unlock(&cifs_tcp_ses_lock);
-               dfs_cache_add_refsrv_session(&mnt_ctx->mount_id, mnt_ctx->ses);
+               root_ses->ses = ses;
+               list_add_tail(&root_ses->list, &mnt_ctx->dfs_ses_list);
        }
-       mnt_ctx->root_ses = mnt_ctx->ses;
+       ctx->dfs_root_ses = ses;
+       return 0;
 }
 
 static int get_dfs_conn(struct cifs_mount_ctx *mnt_ctx, const char *ref_path, const char *full_path,
@@ -121,7 +127,8 @@ static int get_dfs_conn(struct cifs_mount_ctx *mnt_ctx, const char *ref_path, co
 {
        struct smb3_fs_context *ctx = mnt_ctx->fs_ctx;
        struct dfs_info3_param ref = {};
-       int rc;
+       bool is_refsrv = false;
+       int rc, rc2;
 
        rc = dfs_cache_get_tgt_referral(ref_path + 1, tit, &ref);
        if (rc)
@@ -136,8 +143,7 @@ static int get_dfs_conn(struct cifs_mount_ctx *mnt_ctx, const char *ref_path, co
        if (rc)
                goto out;
 
-       if (ref.flags & DFSREF_REFERRAL_SERVER)
-               set_root_ses(mnt_ctx);
+       is_refsrv = !!(ref.flags & DFSREF_REFERRAL_SERVER);
 
        rc = -EREMOTE;
        if (ref.flags & DFSREF_STORAGE_SERVER) {
@@ -146,13 +152,17 @@ static int get_dfs_conn(struct cifs_mount_ctx *mnt_ctx, const char *ref_path, co
                        goto out;
 
                /* some servers may not advertise referral capability under ref.flags */
-               if (!(ref.flags & DFSREF_REFERRAL_SERVER) &&
-                   is_tcon_dfs(mnt_ctx->tcon))
-                       set_root_ses(mnt_ctx);
+               is_refsrv |= is_tcon_dfs(mnt_ctx->tcon);
 
                rc = cifs_is_path_remote(mnt_ctx);
        }
 
+       if (rc == -EREMOTE && is_refsrv) {
+               rc2 = get_root_smb_session(mnt_ctx);
+               if (rc2)
+                       rc = rc2;
+       }
+
 out:
        free_dfs_info_param(&ref);
        return rc;
@@ -165,6 +175,7 @@ static int __dfs_mount_share(struct cifs_mount_ctx *mnt_ctx)
        char *ref_path = NULL, *full_path = NULL;
        struct dfs_cache_tgt_iterator *tit;
        struct TCP_Server_Info *server;
+       struct cifs_tcon *tcon;
        char *origin_fullpath = NULL;
        int num_links = 0;
        int rc;
@@ -234,12 +245,22 @@ static int __dfs_mount_share(struct cifs_mount_ctx *mnt_ctx)
 
        if (!rc) {
                server = mnt_ctx->server;
+               tcon = mnt_ctx->tcon;
 
                mutex_lock(&server->refpath_lock);
-               server->origin_fullpath = origin_fullpath;
-               server->current_fullpath = server->leaf_fullpath;
+               if (!server->origin_fullpath) {
+                       server->origin_fullpath = origin_fullpath;
+                       server->current_fullpath = server->leaf_fullpath;
+                       origin_fullpath = NULL;
+               }
                mutex_unlock(&server->refpath_lock);
-               origin_fullpath = NULL;
+
+               if (list_empty(&tcon->dfs_ses_list)) {
+                       list_replace_init(&mnt_ctx->dfs_ses_list,
+                                         &tcon->dfs_ses_list);
+               } else {
+                       dfs_put_root_smb_sessions(&mnt_ctx->dfs_ses_list);
+               }
        }
 
 out:
@@ -260,7 +281,7 @@ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs)
        rc = get_session(mnt_ctx, NULL);
        if (rc)
                return rc;
-       mnt_ctx->root_ses = mnt_ctx->ses;
+       ctx->dfs_root_ses = mnt_ctx->ses;
        /*
         * If called with 'nodfs' mount option, then skip DFS resolving.  Otherwise unconditionally
         * try to get an DFS referral (even cached) to determine whether it is an DFS mount.
@@ -280,7 +301,9 @@ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs)
        }
 
        *isdfs = true;
-       set_root_ses(mnt_ctx);
+       rc = get_root_smb_session(mnt_ctx);
+       if (rc)
+               return rc;
 
        return __dfs_mount_share(mnt_ctx);
 }
@@ -479,9 +502,13 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
 
        /* only send once per connect */
        spin_lock(&tcon->tc_lock);
-       if (tcon->ses->ses_status != SES_GOOD ||
-           (tcon->status != TID_NEW &&
-           tcon->status != TID_NEED_TCON)) {
+       if (tcon->status != TID_NEW &&
+           tcon->status != TID_NEED_TCON) {
+               spin_unlock(&tcon->tc_lock);
+               return -EHOSTDOWN;
+       }
+
+       if (tcon->status == TID_GOOD) {
                spin_unlock(&tcon->tc_lock);
                return 0;
        }
index 344bea6d8bab1e471444131b1841c4442e5ca657..0b8cbf721fff6ed6e9aac7c4f01239f039acefdf 100644 (file)
 #include "fs_context.h"
 #include "cifs_unicode.h"
 
+struct dfs_root_ses {
+       struct list_head list;
+       struct cifs_ses *ses;
+};
+
 int dfs_parse_target_referral(const char *full_path, const struct dfs_info3_param *ref,
                              struct smb3_fs_context *ctx);
 int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs);
@@ -22,25 +27,51 @@ static inline char *dfs_get_path(struct cifs_sb_info *cifs_sb, const char *path)
 static inline int dfs_get_referral(struct cifs_mount_ctx *mnt_ctx, const char *path,
                                   struct dfs_info3_param *ref, struct dfs_cache_tgt_list *tl)
 {
+       struct smb3_fs_context *ctx = mnt_ctx->fs_ctx;
        struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb;
 
-       return dfs_cache_find(mnt_ctx->xid, mnt_ctx->root_ses, cifs_sb->local_nls,
+       return dfs_cache_find(mnt_ctx->xid, ctx->dfs_root_ses, cifs_sb->local_nls,
                              cifs_remap(cifs_sb), path, ref, tl);
 }
 
+/* Return DFS full path out of a dentry set for automount */
 static inline char *dfs_get_automount_devname(struct dentry *dentry, void *page)
 {
        struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
        struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
        struct TCP_Server_Info *server = tcon->ses->server;
+       size_t len;
+       char *s;
 
        if (unlikely(!server->origin_fullpath))
                return ERR_PTR(-EREMOTE);
 
-       return __build_path_from_dentry_optional_prefix(dentry, page,
-                                                       server->origin_fullpath,
-                                                       strlen(server->origin_fullpath),
-                                                       true);
+       s = dentry_path_raw(dentry, page, PATH_MAX);
+       if (IS_ERR(s))
+               return s;
+       /* for root, we want "" */
+       if (!s[1])
+               s++;
+
+       len = strlen(server->origin_fullpath);
+       if (s < (char *)page + len)
+               return ERR_PTR(-ENAMETOOLONG);
+
+       s -= len;
+       memcpy(s, server->origin_fullpath, len);
+       convert_delimiter(s, '/');
+       return s;
+}
+
+static inline void dfs_put_root_smb_sessions(struct list_head *head)
+{
+       struct dfs_root_ses *root, *tmp;
+
+       list_for_each_entry_safe(root, tmp, head, list) {
+               list_del_init(&root->list);
+               cifs_put_smb_ses(root->ses);
+               kfree(root);
+       }
 }
 
 #endif /* _CIFS_DFS_H */
index ac86bd0ebd637bc2d1440c3f2858489ed27b5364..30cbdf8514a5969c8a2b862277b0544405d2a151 100644 (file)
@@ -49,17 +49,6 @@ struct cache_entry {
        struct cache_dfs_tgt *tgthint;
 };
 
-/* List of referral server sessions per dfs mount */
-struct mount_group {
-       struct list_head list;
-       uuid_t id;
-       struct cifs_ses *sessions[CACHE_MAX_ENTRIES];
-       int num_sessions;
-       spinlock_t lock;
-       struct list_head refresh_list;
-       struct kref refcount;
-};
-
 static struct kmem_cache *cache_slab __read_mostly;
 static struct workqueue_struct *dfscache_wq __read_mostly;
 
@@ -76,85 +65,10 @@ static atomic_t cache_count;
 static struct hlist_head cache_htable[CACHE_HTABLE_SIZE];
 static DECLARE_RWSEM(htable_rw_lock);
 
-static LIST_HEAD(mount_group_list);
-static DEFINE_MUTEX(mount_group_list_lock);
-
 static void refresh_cache_worker(struct work_struct *work);
 
 static DECLARE_DELAYED_WORK(refresh_task, refresh_cache_worker);
 
-static void __mount_group_release(struct mount_group *mg)
-{
-       int i;
-
-       for (i = 0; i < mg->num_sessions; i++)
-               cifs_put_smb_ses(mg->sessions[i]);
-       kfree(mg);
-}
-
-static void mount_group_release(struct kref *kref)
-{
-       struct mount_group *mg = container_of(kref, struct mount_group, refcount);
-
-       mutex_lock(&mount_group_list_lock);
-       list_del(&mg->list);
-       mutex_unlock(&mount_group_list_lock);
-       __mount_group_release(mg);
-}
-
-static struct mount_group *find_mount_group_locked(const uuid_t *id)
-{
-       struct mount_group *mg;
-
-       list_for_each_entry(mg, &mount_group_list, list) {
-               if (uuid_equal(&mg->id, id))
-                       return mg;
-       }
-       return ERR_PTR(-ENOENT);
-}
-
-static struct mount_group *__get_mount_group_locked(const uuid_t *id)
-{
-       struct mount_group *mg;
-
-       mg = find_mount_group_locked(id);
-       if (!IS_ERR(mg))
-               return mg;
-
-       mg = kmalloc(sizeof(*mg), GFP_KERNEL);
-       if (!mg)
-               return ERR_PTR(-ENOMEM);
-       kref_init(&mg->refcount);
-       uuid_copy(&mg->id, id);
-       mg->num_sessions = 0;
-       spin_lock_init(&mg->lock);
-       list_add(&mg->list, &mount_group_list);
-       return mg;
-}
-
-static struct mount_group *get_mount_group(const uuid_t *id)
-{
-       struct mount_group *mg;
-
-       mutex_lock(&mount_group_list_lock);
-       mg = __get_mount_group_locked(id);
-       if (!IS_ERR(mg))
-               kref_get(&mg->refcount);
-       mutex_unlock(&mount_group_list_lock);
-
-       return mg;
-}
-
-static void free_mount_group_list(void)
-{
-       struct mount_group *mg, *tmp_mg;
-
-       list_for_each_entry_safe(mg, tmp_mg, &mount_group_list, list) {
-               list_del_init(&mg->list);
-               __mount_group_release(mg);
-       }
-}
-
 /**
  * dfs_cache_canonical_path - get a canonical DFS path
  *
@@ -704,7 +618,6 @@ void dfs_cache_destroy(void)
 {
        cancel_delayed_work_sync(&refresh_task);
        unload_nls(cache_cp);
-       free_mount_group_list();
        flush_cache_ents();
        kmem_cache_destroy(cache_slab);
        destroy_workqueue(dfscache_wq);
@@ -1111,54 +1024,6 @@ out_unlock:
        return rc;
 }
 
-/**
- * dfs_cache_add_refsrv_session - add SMB session of referral server
- *
- * @mount_id: mount group uuid to lookup.
- * @ses: reference counted SMB session of referral server.
- */
-void dfs_cache_add_refsrv_session(const uuid_t *mount_id, struct cifs_ses *ses)
-{
-       struct mount_group *mg;
-
-       if (WARN_ON_ONCE(!mount_id || uuid_is_null(mount_id) || !ses))
-               return;
-
-       mg = get_mount_group(mount_id);
-       if (WARN_ON_ONCE(IS_ERR(mg)))
-               return;
-
-       spin_lock(&mg->lock);
-       if (mg->num_sessions < ARRAY_SIZE(mg->sessions))
-               mg->sessions[mg->num_sessions++] = ses;
-       spin_unlock(&mg->lock);
-       kref_put(&mg->refcount, mount_group_release);
-}
-
-/**
- * dfs_cache_put_refsrv_sessions - put all referral server sessions
- *
- * Put all SMB sessions from the given mount group id.
- *
- * @mount_id: mount group uuid to lookup.
- */
-void dfs_cache_put_refsrv_sessions(const uuid_t *mount_id)
-{
-       struct mount_group *mg;
-
-       if (!mount_id || uuid_is_null(mount_id))
-               return;
-
-       mutex_lock(&mount_group_list_lock);
-       mg = find_mount_group_locked(mount_id);
-       if (IS_ERR(mg)) {
-               mutex_unlock(&mount_group_list_lock);
-               return;
-       }
-       mutex_unlock(&mount_group_list_lock);
-       kref_put(&mg->refcount, mount_group_release);
-}
-
 /* Extract share from DFS target and return a pointer to prefix path or NULL */
 static const char *parse_target_share(const char *target, char **share)
 {
@@ -1326,7 +1191,7 @@ static int __refresh_tcon(const char *path, struct cifs_tcon *tcon, bool force_r
        }
 
        spin_lock(&ipc->tc_lock);
-       if (ses->ses_status != SES_GOOD || ipc->status != TID_GOOD) {
+       if (ipc->status != TID_GOOD) {
                spin_unlock(&ipc->tc_lock);
                cifs_dbg(FYI, "%s: skip cache refresh due to disconnected ipc\n", __func__);
                goto out;
@@ -1384,11 +1249,6 @@ int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb)
                cifs_dbg(FYI, "%s: not a dfs mount\n", __func__);
                return 0;
        }
-
-       if (uuid_is_null(&cifs_sb->dfs_mount_id)) {
-               cifs_dbg(FYI, "%s: no dfs mount group id\n", __func__);
-               return -EINVAL;
-       }
        /*
         * After reconnecting to a different server, unique ids won't match anymore, so we disable
         * serverino. This prevents dentry revalidation to think the dentry are stale (ESTALE).
index be3b5a44cf82711a575e8efe70934f7e07109131..e0d39393035a99086c875324d8440f8fe03436ca 100644 (file)
@@ -40,8 +40,6 @@ int dfs_cache_get_tgt_referral(const char *path, const struct dfs_cache_tgt_iter
                               struct dfs_info3_param *ref);
 int dfs_cache_get_tgt_share(char *path, const struct dfs_cache_tgt_iterator *it, char **share,
                            char **prefix);
-void dfs_cache_put_refsrv_sessions(const uuid_t *mount_id);
-void dfs_cache_add_refsrv_session(const uuid_t *mount_id, struct cifs_ses *ses);
 char *dfs_cache_canonical_path(const char *path, const struct nls_table *cp, int remap);
 int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb);
 
index 4d4a2d82636d2a359f785c41c5efca5ba5aa8504..b33d2e7b0f984490e9db987a535201de0fe79e1e 100644 (file)
@@ -174,13 +174,13 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
        struct list_head *tmp1;
 
        /* only send once per connect */
-       spin_lock(&tcon->ses->ses_lock);
-       if ((tcon->ses->ses_status != SES_GOOD) || (tcon->status != TID_NEED_RECON)) {
-               spin_unlock(&tcon->ses->ses_lock);
+       spin_lock(&tcon->tc_lock);
+       if (tcon->status != TID_NEED_RECON) {
+               spin_unlock(&tcon->tc_lock);
                return;
        }
        tcon->status = TID_IN_FILES_INVALIDATE;
-       spin_unlock(&tcon->ses->ses_lock);
+       spin_unlock(&tcon->tc_lock);
 
        /* list all files open on tree connection and mark them invalid */
        spin_lock(&tcon->open_file_lock);
@@ -4010,7 +4010,6 @@ static void
 collect_uncached_read_data(struct cifs_aio_ctx *ctx)
 {
        struct cifs_readdata *rdata, *tmp;
-       struct iov_iter *to = &ctx->iter;
        struct cifs_sb_info *cifs_sb;
        int rc;
 
@@ -4076,9 +4075,6 @@ again:
                kref_put(&rdata->refcount, cifs_readdata_release);
        }
 
-       if (!ctx->direct_io)
-               ctx->total_len = ctx->len - iov_iter_count(to);
-
        /* mask nodata case */
        if (rc == -ENODATA)
                rc = 0;
index 6d13f8207e96a146a44860538cfaf1045924b4b2..ace11a1a7c8abc07e9df9ec7e9fbf2bd61455e1c 100644 (file)
@@ -441,13 +441,14 @@ out:
  * but there are some bugs that prevent rename from working if there are
  * multiple delimiters.
  *
- * Returns a sanitized duplicate of @path. The caller is responsible for
- * cleaning up the original.
+ * Returns a sanitized duplicate of @path. @gfp indicates the GFP_* flags
+ * for kstrdup.
+ * The caller is responsible for freeing the original.
  */
 #define IS_DELIM(c) ((c) == '/' || (c) == '\\')
-static char *sanitize_path(char *path)
+char *cifs_sanitize_prepath(char *prepath, gfp_t gfp)
 {
-       char *cursor1 = path, *cursor2 = path;
+       char *cursor1 = prepath, *cursor2 = prepath;
 
        /* skip all prepended delimiters */
        while (IS_DELIM(*cursor1))
@@ -469,7 +470,7 @@ static char *sanitize_path(char *path)
                cursor2--;
 
        *(cursor2) = '\0';
-       return kstrdup(path, GFP_KERNEL);
+       return kstrdup(prepath, gfp);
 }
 
 /*
@@ -531,7 +532,7 @@ smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx)
        if (!*pos)
                return 0;
 
-       ctx->prepath = sanitize_path(pos);
+       ctx->prepath = cifs_sanitize_prepath(pos, GFP_KERNEL);
        if (!ctx->prepath)
                return -ENOMEM;
 
index 44cb5639ed3ba3502db464c887526c3c0b0ec58a..f4eaf855890222924c99a92f693f131b0c69cde7 100644 (file)
@@ -265,6 +265,7 @@ struct smb3_fs_context {
        bool rootfs:1; /* if it's a SMB root file system */
        bool witness:1; /* use witness protocol */
        char *leaf_fullpath;
+       struct cifs_ses *dfs_root_ses;
 };
 
 extern const struct fs_parameter_spec smb3_fs_parameters[];
@@ -285,5 +286,8 @@ extern void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb);
  * max deferred close timeout (jiffies) - 2^30
  */
 #define SMB3_MAX_DCLOSETIMEO (1 << 30)
-#define SMB3_DEF_DCLOSETIMEO (5 * HZ) /* Can increase later, other clients use larger */
+#define SMB3_DEF_DCLOSETIMEO (1 * HZ) /* even 1 sec enough to help eg open/write/close/open/read */
+
+extern char *cifs_sanitize_prepath(char *prepath, gfp_t gfp);
+
 #endif
index 7d97c10f24535016a0ad447f1854274a7c853df7..c66be4904e1fa0db7277571e5163f0dfe6359b1b 100644 (file)
@@ -360,6 +360,7 @@ smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
        oparms = (struct cifs_open_parms) {
                .tcon = tcon,
                .cifs_sb = cifs_sb,
+               .path = path,
                .desired_access = GENERIC_READ,
                .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),
                .disposition = FILE_OPEN,
@@ -427,6 +428,7 @@ smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
        oparms = (struct cifs_open_parms) {
                .tcon = tcon,
                .cifs_sb = cifs_sb,
+               .path = path,
                .desired_access = GENERIC_WRITE,
                .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),
                .disposition = FILE_CREATE,
index a0d286ee723dda465cecbe9d9e0c4f20c3887e3e..7f085ed2d866bb751270176120e0fc26d5d60d11 100644 (file)
@@ -22,6 +22,7 @@
 #ifdef CONFIG_CIFS_DFS_UPCALL
 #include "dns_resolve.h"
 #include "dfs_cache.h"
+#include "dfs.h"
 #endif
 #include "fs_context.h"
 #include "cached_dir.h"
@@ -134,6 +135,9 @@ tconInfoAlloc(void)
        spin_lock_init(&ret_buf->stat_lock);
        atomic_set(&ret_buf->num_local_opens, 0);
        atomic_set(&ret_buf->num_remote_opens, 0);
+#ifdef CONFIG_CIFS_DFS_UPCALL
+       INIT_LIST_HEAD(&ret_buf->dfs_ses_list);
+#endif
 
        return ret_buf;
 }
@@ -149,6 +153,9 @@ tconInfoFree(struct cifs_tcon *tcon)
        atomic_dec(&tconInfoAllocCount);
        kfree(tcon->nativeFileSystem);
        kfree_sensitive(tcon->password);
+#ifdef CONFIG_CIFS_DFS_UPCALL
+       dfs_put_root_smb_sessions(&tcon->dfs_ses_list);
+#endif
        kfree(tcon);
 }
 
@@ -1188,7 +1195,7 @@ int cifs_update_super_prepath(struct cifs_sb_info *cifs_sb, char *prefix)
        kfree(cifs_sb->prepath);
 
        if (prefix && *prefix) {
-               cifs_sb->prepath = kstrdup(prefix, GFP_ATOMIC);
+               cifs_sb->prepath = cifs_sanitize_prepath(prefix, GFP_ATOMIC);
                if (!cifs_sb->prepath)
                        return -ENOMEM;
 
@@ -1255,6 +1262,7 @@ int cifs_inval_name_dfs_link_error(const unsigned int xid,
                 * removing cached DFS targets that the client would eventually
                 * need during failover.
                 */
+               ses = CIFS_DFS_ROOT_SES(ses);
                if (ses->server->ops->get_dfs_refer &&
                    !ses->server->ops->get_dfs_refer(xid, ses, ref_path, &refs,
                                                     &num_refs, cifs_sb->local_nls,
index 9b956294e8643dfe57772699436ffab2bd0bcc85..163a03298430d08304647d3c137903f8afbef0bc 100644 (file)
@@ -107,6 +107,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
 
        vars->oparms = (struct cifs_open_parms) {
                .tcon = tcon,
+               .path = full_path,
                .desired_access = desired_access,
                .disposition = create_disposition,
                .create_options = cifs_create_options(cifs_sb, create_options),
@@ -234,15 +235,32 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
                size[0] = 8; /* sizeof __le64 */
                data[0] = ptr;
 
-               rc = SMB2_set_info_init(tcon, server,
-                                       &rqst[num_rqst], COMPOUND_FID,
-                                       COMPOUND_FID, current->tgid,
-                                       FILE_END_OF_FILE_INFORMATION,
-                                       SMB2_O_INFO_FILE, 0, data, size);
+               if (cfile) {
+                       rc = SMB2_set_info_init(tcon, server,
+                                               &rqst[num_rqst],
+                                               cfile->fid.persistent_fid,
+                                               cfile->fid.volatile_fid,
+                                               current->tgid,
+                                               FILE_END_OF_FILE_INFORMATION,
+                                               SMB2_O_INFO_FILE, 0,
+                                               data, size);
+               } else {
+                       rc = SMB2_set_info_init(tcon, server,
+                                               &rqst[num_rqst],
+                                               COMPOUND_FID,
+                                               COMPOUND_FID,
+                                               current->tgid,
+                                               FILE_END_OF_FILE_INFORMATION,
+                                               SMB2_O_INFO_FILE, 0,
+                                               data, size);
+                       if (!rc) {
+                               smb2_set_next_command(tcon, &rqst[num_rqst]);
+                               smb2_set_related(&rqst[num_rqst]);
+                       }
+               }
                if (rc)
                        goto finished;
-               smb2_set_next_command(tcon, &rqst[num_rqst]);
-               smb2_set_related(&rqst[num_rqst++]);
+               num_rqst++;
                trace_smb3_set_eof_enter(xid, ses->Suid, tcon->tid, full_path);
                break;
        case SMB2_OP_SET_INFO:
index 6dfb865ee9d75155f1421b0a41677e32da15eb98..a81758225fcdc7b24b8921bf37ef95c79fde2ba3 100644 (file)
@@ -530,6 +530,14 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
        p = buf;
 
        spin_lock(&ses->iface_lock);
+       /* do not query too frequently, this time with lock held */
+       if (ses->iface_last_update &&
+           time_before(jiffies, ses->iface_last_update +
+                       (SMB_INTERFACE_POLL_INTERVAL * HZ))) {
+               spin_unlock(&ses->iface_lock);
+               return 0;
+       }
+
        /*
         * Go through iface_list and do kref_put to remove
         * any unused ifaces. ifaces in use will be removed
@@ -696,6 +704,12 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_
        struct network_interface_info_ioctl_rsp *out_buf = NULL;
        struct cifs_ses *ses = tcon->ses;
 
+       /* do not query too frequently */
+       if (ses->iface_last_update &&
+           time_before(jiffies, ses->iface_last_update +
+                       (SMB_INTERFACE_POLL_INTERVAL * HZ)))
+               return 0;
+
        rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
                        FSCTL_QUERY_NETWORK_INTERFACE_INFO,
                        NULL /* no data input */, 0 /* no data input */,
@@ -703,7 +717,7 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_
        if (rc == -EOPNOTSUPP) {
                cifs_dbg(FYI,
                         "server does not support query network interfaces\n");
-               goto out;
+               ret_data_len = 0;
        } else if (rc != 0) {
                cifs_tcon_dbg(VFS, "error %d on ioctl to get interface list\n", rc);
                goto out;
@@ -731,6 +745,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
 
        oparms = (struct cifs_open_parms) {
                .tcon = tcon,
+               .path = "",
                .desired_access = FILE_READ_ATTRIBUTES,
                .disposition = FILE_OPEN,
                .create_options = cifs_create_options(cifs_sb, 0),
@@ -774,6 +789,7 @@ smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
 
        oparms = (struct cifs_open_parms) {
                .tcon = tcon,
+               .path = "",
                .desired_access = FILE_READ_ATTRIBUTES,
                .disposition = FILE_OPEN,
                .create_options = cifs_create_options(cifs_sb, 0),
@@ -821,6 +837,7 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
 
        oparms = (struct cifs_open_parms) {
                .tcon = tcon,
+               .path = full_path,
                .desired_access = FILE_READ_ATTRIBUTES,
                .disposition = FILE_OPEN,
                .create_options = cifs_create_options(cifs_sb, 0),
@@ -1105,6 +1122,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
 
        oparms = (struct cifs_open_parms) {
                .tcon = tcon,
+               .path = path,
                .desired_access = FILE_WRITE_EA,
                .disposition = FILE_OPEN,
                .create_options = cifs_create_options(cifs_sb, 0),
@@ -2096,6 +2114,7 @@ smb3_notify(const unsigned int xid, struct file *pfile,
        tcon = cifs_sb_master_tcon(cifs_sb);
        oparms = (struct cifs_open_parms) {
                .tcon = tcon,
+               .path = path,
                .desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA,
                .disposition = FILE_OPEN,
                .create_options = cifs_create_options(cifs_sb, 0),
@@ -2168,6 +2187,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
 
        oparms = (struct cifs_open_parms) {
                .tcon = tcon,
+               .path = path,
                .desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA,
                .disposition = FILE_OPEN,
                .create_options = cifs_create_options(cifs_sb, 0),
@@ -2500,6 +2520,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
 
        oparms = (struct cifs_open_parms) {
                .tcon = tcon,
+               .path = path,
                .desired_access = desired_access,
                .disposition = FILE_OPEN,
                .create_options = cifs_create_options(cifs_sb, 0),
@@ -2634,6 +2655,7 @@ smb311_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
 
        oparms = (struct cifs_open_parms) {
                .tcon = tcon,
+               .path = "",
                .desired_access = FILE_READ_ATTRIBUTES,
                .disposition = FILE_OPEN,
                .create_options = cifs_create_options(cifs_sb, 0),
@@ -2928,6 +2950,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
 
        oparms = (struct cifs_open_parms) {
                .tcon = tcon,
+               .path = full_path,
                .desired_access = FILE_READ_ATTRIBUTES,
                .disposition = FILE_OPEN,
                .create_options = cifs_create_options(cifs_sb, create_options),
@@ -3068,6 +3091,7 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
 
        oparms = (struct cifs_open_parms) {
                .tcon = tcon,
+               .path = full_path,
                .desired_access = FILE_READ_ATTRIBUTES,
                .disposition = FILE_OPEN,
                .create_options = cifs_create_options(cifs_sb, OPEN_REPARSE_POINT),
@@ -3208,6 +3232,7 @@ get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb,
 
        oparms = (struct cifs_open_parms) {
                .tcon = tcon,
+               .path = path,
                .desired_access = READ_CONTROL,
                .disposition = FILE_OPEN,
                /*
index 0e53265e1462a350d5c8bbde41893b50f3dac3ae..366f0c3b799b66368f79bd662b03c0d4f9852fd3 100644 (file)
@@ -144,7 +144,7 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
               struct TCP_Server_Info *server)
 {
        int rc = 0;
-       struct nls_table *nls_codepage;
+       struct nls_table *nls_codepage = NULL;
        struct cifs_ses *ses;
 
        /*
@@ -165,13 +165,9 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
        spin_lock(&tcon->tc_lock);
        if (tcon->status == TID_EXITING) {
                /*
-                * only tree disconnect, open, and write,
-                * (and ulogoff which does not have tcon)
-                * are allowed as we start force umount.
+                * only tree disconnect allowed when disconnecting ...
                 */
-               if ((smb2_command != SMB2_WRITE) &&
-                  (smb2_command != SMB2_CREATE) &&
-                  (smb2_command != SMB2_TREE_DISCONNECT)) {
+               if (smb2_command != SMB2_TREE_DISCONNECT) {
                        spin_unlock(&tcon->tc_lock);
                        cifs_dbg(FYI, "can not send cmd %d while umounting\n",
                                 smb2_command);
@@ -203,6 +199,7 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
        }
        spin_unlock(&server->srv_lock);
 
+again:
        rc = cifs_wait_for_server_reconnect(server, tcon->retry);
        if (rc)
                return rc;
@@ -219,8 +216,7 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
                 tcon->ses->chans_need_reconnect,
                 tcon->need_reconnect);
 
-       nls_codepage = load_nls_default();
-
+       mutex_lock(&ses->session_mutex);
        /*
         * Recheck after acquire mutex. If another thread is negotiating
         * and the server never sends an answer the socket will be closed
@@ -229,28 +225,38 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
        spin_lock(&server->srv_lock);
        if (server->tcpStatus == CifsNeedReconnect) {
                spin_unlock(&server->srv_lock);
+               mutex_unlock(&ses->session_mutex);
+
+               if (tcon->retry)
+                       goto again;
+
                rc = -EHOSTDOWN;
                goto out;
        }
        spin_unlock(&server->srv_lock);
 
+       nls_codepage = load_nls_default();
+
        /*
         * need to prevent multiple threads trying to simultaneously
         * reconnect the same SMB session
         */
+       spin_lock(&ses->ses_lock);
        spin_lock(&ses->chan_lock);
-       if (!cifs_chan_needs_reconnect(ses, server)) {
+       if (!cifs_chan_needs_reconnect(ses, server) &&
+           ses->ses_status == SES_GOOD) {
                spin_unlock(&ses->chan_lock);
-
+               spin_unlock(&ses->ses_lock);
                /* this means that we only need to tree connect */
                if (tcon->need_reconnect)
                        goto skip_sess_setup;
 
+               mutex_unlock(&ses->session_mutex);
                goto out;
        }
        spin_unlock(&ses->chan_lock);
+       spin_unlock(&ses->ses_lock);
 
-       mutex_lock(&ses->session_mutex);
        rc = cifs_negotiate_protocol(0, ses, server);
        if (!rc) {
                rc = cifs_setup_session(0, ses, server, nls_codepage);
@@ -266,10 +272,8 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
                mutex_unlock(&ses->session_mutex);
                goto out;
        }
-       mutex_unlock(&ses->session_mutex);
 
 skip_sess_setup:
-       mutex_lock(&ses->session_mutex);
        if (!tcon->need_reconnect) {
                mutex_unlock(&ses->session_mutex);
                goto out;
@@ -284,7 +288,7 @@ skip_sess_setup:
        cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
        if (rc) {
                /* If sess reconnected but tcon didn't, something strange ... */
-               pr_warn_once("reconnect tcon failed rc = %d\n", rc);
+               cifs_dbg(VFS, "reconnect tcon failed rc = %d\n", rc);
                goto out;
        }
 
@@ -306,7 +310,6 @@ out:
        case SMB2_READ:
        case SMB2_WRITE:
        case SMB2_LOCK:
-       case SMB2_IOCTL:
        case SMB2_QUERY_DIRECTORY:
        case SMB2_CHANGE_NOTIFY:
        case SMB2_QUERY_INFO:
@@ -584,11 +587,15 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
 
 }
 
+/* If invalid preauth context warn but use what we requested, SHA-512 */
 static void decode_preauth_context(struct smb2_preauth_neg_context *ctxt)
 {
        unsigned int len = le16_to_cpu(ctxt->DataLength);
 
-       /* If invalid preauth context warn but use what we requested, SHA-512 */
+       /*
+        * Caller checked that DataLength remains within SMB boundary. We still
+        * need to confirm that one HashAlgorithms member is accounted for.
+        */
        if (len < MIN_PREAUTH_CTXT_DATA_LEN) {
                pr_warn_once("server sent bad preauth context\n");
                return;
@@ -607,7 +614,11 @@ static void decode_compress_ctx(struct TCP_Server_Info *server,
 {
        unsigned int len = le16_to_cpu(ctxt->DataLength);
 
-       /* sizeof compress context is a one element compression capbility struct */
+       /*
+        * Caller checked that DataLength remains within SMB boundary. We still
+        * need to confirm that one CompressionAlgorithms member is accounted
+        * for.
+        */
        if (len < 10) {
                pr_warn_once("server sent bad compression cntxt\n");
                return;
@@ -629,6 +640,11 @@ static int decode_encrypt_ctx(struct TCP_Server_Info *server,
        unsigned int len = le16_to_cpu(ctxt->DataLength);
 
        cifs_dbg(FYI, "decode SMB3.11 encryption neg context of len %d\n", len);
+       /*
+        * Caller checked that DataLength remains within SMB boundary. We still
+        * need to confirm that one Cipher flexible array member is accounted
+        * for.
+        */
        if (len < MIN_ENCRYPT_CTXT_DATA_LEN) {
                pr_warn_once("server sent bad crypto ctxt len\n");
                return -EINVAL;
@@ -675,6 +691,11 @@ static void decode_signing_ctx(struct TCP_Server_Info *server,
 {
        unsigned int len = le16_to_cpu(pctxt->DataLength);
 
+       /*
+        * Caller checked that DataLength remains within SMB boundary. We still
+        * need to confirm that one SigningAlgorithms flexible array member is
+        * accounted for.
+        */
        if ((len < 4) || (len > 16)) {
                pr_warn_once("server sent bad signing negcontext\n");
                return;
@@ -716,14 +737,19 @@ static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp,
        for (i = 0; i < ctxt_cnt; i++) {
                int clen;
                /* check that offset is not beyond end of SMB */
-               if (len_of_ctxts == 0)
-                       break;
-
                if (len_of_ctxts < sizeof(struct smb2_neg_context))
                        break;
 
                pctx = (struct smb2_neg_context *)(offset + (char *)rsp);
-               clen = le16_to_cpu(pctx->DataLength);
+               clen = sizeof(struct smb2_neg_context)
+                       + le16_to_cpu(pctx->DataLength);
+               /*
+                * 2.2.4 SMB2 NEGOTIATE Response
+                * Subsequent negotiate contexts MUST appear at the first 8-byte
+                * aligned offset following the previous negotiate context.
+                */
+               if (i + 1 != ctxt_cnt)
+                       clen = ALIGN(clen, 8);
                if (clen > len_of_ctxts)
                        break;
 
@@ -744,12 +770,10 @@ static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp,
                else
                        cifs_server_dbg(VFS, "unknown negcontext of type %d ignored\n",
                                le16_to_cpu(pctx->ContextType));
-
                if (rc)
                        break;
-               /* offsets must be 8 byte aligned */
-               clen = ALIGN(clen, 8);
-               offset += clen + sizeof(struct smb2_neg_context);
+
+               offset += clen;
                len_of_ctxts -= clen;
        }
        return rc;
@@ -1256,9 +1280,9 @@ SMB2_sess_alloc_buffer(struct SMB2_sess_data *sess_data)
        if (rc)
                return rc;
 
-       spin_lock(&ses->chan_lock);
-       is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses);
-       spin_unlock(&ses->chan_lock);
+       spin_lock(&ses->ses_lock);
+       is_binding = (ses->ses_status == SES_GOOD);
+       spin_unlock(&ses->ses_lock);
 
        if (is_binding) {
                req->hdr.SessionId = cpu_to_le64(ses->Suid);
@@ -1416,9 +1440,9 @@ SMB2_auth_kerberos(struct SMB2_sess_data *sess_data)
                goto out_put_spnego_key;
        }
 
-       spin_lock(&ses->chan_lock);
-       is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses);
-       spin_unlock(&ses->chan_lock);
+       spin_lock(&ses->ses_lock);
+       is_binding = (ses->ses_status == SES_GOOD);
+       spin_unlock(&ses->ses_lock);
 
        /* keep session key if binding */
        if (!is_binding) {
@@ -1542,9 +1566,9 @@ SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_sess_data *sess_data)
 
        cifs_dbg(FYI, "rawntlmssp session setup challenge phase\n");
 
-       spin_lock(&ses->chan_lock);
-       is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses);
-       spin_unlock(&ses->chan_lock);
+       spin_lock(&ses->ses_lock);
+       is_binding = (ses->ses_status == SES_GOOD);
+       spin_unlock(&ses->ses_lock);
 
        /* keep existing ses id and flags if binding */
        if (!is_binding) {
@@ -1610,9 +1634,9 @@ SMB2_sess_auth_rawntlmssp_authenticate(struct SMB2_sess_data *sess_data)
 
        rsp = (struct smb2_sess_setup_rsp *)sess_data->iov[0].iov_base;
 
-       spin_lock(&ses->chan_lock);
-       is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses);
-       spin_unlock(&ses->chan_lock);
+       spin_lock(&ses->ses_lock);
+       is_binding = (ses->ses_status == SES_GOOD);
+       spin_unlock(&ses->ses_lock);
 
        /* keep existing ses id and flags if binding */
        if (!is_binding) {
@@ -2705,7 +2729,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
        rqst.rq_nvec = n_iov;
 
        /* no need to inc num_remote_opens because we close it just below */
-       trace_smb3_posix_mkdir_enter(xid, tcon->tid, ses->Suid, CREATE_NOT_FILE,
+       trace_smb3_posix_mkdir_enter(xid, tcon->tid, ses->Suid, full_path, CREATE_NOT_FILE,
                                    FILE_WRITE_ATTRIBUTES);
        /* resource #4: response buffer */
        rc = cifs_send_recv(xid, ses, server,
@@ -2973,7 +2997,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
        if (rc)
                goto creat_exit;
 
-       trace_smb3_open_enter(xid, tcon->tid, tcon->ses->Suid,
+       trace_smb3_open_enter(xid, tcon->tid, tcon->ses->Suid, oparms->path,
                oparms->create_options, oparms->desired_access);
 
        rc = cifs_send_recv(xid, ses, server,
@@ -4156,10 +4180,12 @@ smb2_readv_callback(struct mid_q_entry *mid)
        struct smb2_hdr *shdr =
                                (struct smb2_hdr *)rdata->iov[0].iov_base;
        struct cifs_credits credits = { .value = 0, .instance = 0 };
-       struct smb_rqst rqst = { .rq_iov = &rdata->iov[1],
-                                .rq_nvec = 1,
-                                .rq_iter = rdata->iter,
-                                .rq_iter_size = iov_iter_count(&rdata->iter), };
+       struct smb_rqst rqst = { .rq_iov = &rdata->iov[1], .rq_nvec = 1 };
+
+       if (rdata->got_bytes) {
+               rqst.rq_iter      = rdata->iter;
+               rqst.rq_iter_size = iov_iter_count(&rdata->iter);
+       };
 
        WARN_ONCE(rdata->server != mid->server,
                  "rdata server %p != mid server %p",
index 381babc1212c9e8a95911e6382e5ba4ff5c3cc80..790acf65a0926cbe3316d591a3bc7a1b97120974 100644 (file)
@@ -81,6 +81,7 @@ int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
        struct cifs_ses *ses = NULL;
        int i;
        int rc = 0;
+       bool is_binding = false;
 
        spin_lock(&cifs_tcp_ses_lock);
 
@@ -97,9 +98,12 @@ int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
        goto out;
 
 found:
+       spin_lock(&ses->ses_lock);
        spin_lock(&ses->chan_lock);
-       if (cifs_chan_needs_reconnect(ses, server) &&
-           !CIFS_ALL_CHANS_NEED_RECONNECT(ses)) {
+
+       is_binding = (cifs_chan_needs_reconnect(ses, server) &&
+                     ses->ses_status == SES_GOOD);
+       if (is_binding) {
                /*
                 * If we are in the process of binding a new channel
                 * to an existing session, use the master connection
@@ -107,6 +111,7 @@ found:
                 */
                memcpy(key, ses->smb3signingkey, SMB3_SIGN_KEY_SIZE);
                spin_unlock(&ses->chan_lock);
+               spin_unlock(&ses->ses_lock);
                goto out;
        }
 
@@ -119,10 +124,12 @@ found:
                if (chan->server == server) {
                        memcpy(key, chan->signkey, SMB3_SIGN_KEY_SIZE);
                        spin_unlock(&ses->chan_lock);
+                       spin_unlock(&ses->ses_lock);
                        goto out;
                }
        }
        spin_unlock(&ses->chan_lock);
+       spin_unlock(&ses->ses_lock);
 
        cifs_dbg(VFS,
                 "%s: Could not find channel signing key for session 0x%llx\n",
@@ -392,11 +399,15 @@ generate_smb3signingkey(struct cifs_ses *ses,
        bool is_binding = false;
        int chan_index = 0;
 
+       spin_lock(&ses->ses_lock);
        spin_lock(&ses->chan_lock);
-       is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses);
+       is_binding = (cifs_chan_needs_reconnect(ses, server) &&
+                     ses->ses_status == SES_GOOD);
+
        chan_index = cifs_ses_get_chan_index(ses, server);
        /* TODO: introduce ref counting for channels when the can be freed */
        spin_unlock(&ses->chan_lock);
+       spin_unlock(&ses->ses_lock);
 
        /*
         * All channels use the same encryption/decryption keys but
@@ -425,7 +436,7 @@ generate_smb3signingkey(struct cifs_ses *ses,
 
                /* safe to access primary channel, since it will never go away */
                spin_lock(&ses->chan_lock);
-               memcpy(ses->chans[0].signkey, ses->smb3signingkey,
+               memcpy(ses->chans[chan_index].signkey, ses->smb3signingkey,
                       SMB3_SIGN_KEY_SIZE);
                spin_unlock(&ses->chan_lock);
 
index 110070ba8b04e3b3e4aa2315d1cfce1c933ea809..d3053bd8ae7312656b04fe97063f50c7c8938a24 100644 (file)
@@ -701,13 +701,15 @@ DECLARE_EVENT_CLASS(smb3_open_enter_class,
        TP_PROTO(unsigned int xid,
                __u32   tid,
                __u64   sesid,
+               const char *full_path,
                int     create_options,
                int     desired_access),
-       TP_ARGS(xid, tid, sesid, create_options, desired_access),
+       TP_ARGS(xid, tid, sesid, full_path, create_options, desired_access),
        TP_STRUCT__entry(
                __field(unsigned int, xid)
                __field(__u32, tid)
                __field(__u64, sesid)
+               __string(path, full_path)
                __field(int, create_options)
                __field(int, desired_access)
        ),
@@ -715,11 +717,12 @@ DECLARE_EVENT_CLASS(smb3_open_enter_class,
                __entry->xid = xid;
                __entry->tid = tid;
                __entry->sesid = sesid;
+               __assign_str(path, full_path);
                __entry->create_options = create_options;
                __entry->desired_access = desired_access;
        ),
-       TP_printk("xid=%u sid=0x%llx tid=0x%x cr_opts=0x%x des_access=0x%x",
-               __entry->xid, __entry->sesid, __entry->tid,
+       TP_printk("xid=%u sid=0x%llx tid=0x%x path=%s cr_opts=0x%x des_access=0x%x",
+               __entry->xid, __entry->sesid, __entry->tid, __get_str(path),
                __entry->create_options, __entry->desired_access)
 )
 
@@ -728,9 +731,10 @@ DEFINE_EVENT(smb3_open_enter_class, smb3_##name,  \
        TP_PROTO(unsigned int xid,              \
                __u32   tid,                    \
                __u64   sesid,                  \
+               const char *full_path,          \
                int     create_options,         \
                int     desired_access),        \
-       TP_ARGS(xid, tid, sesid, create_options, desired_access))
+       TP_ARGS(xid, tid, sesid, full_path, create_options, desired_access))
 
 DEFINE_SMB3_OPEN_ENTER_EVENT(open_enter);
 DEFINE_SMB3_OPEN_ENTER_EVENT(posix_mkdir_enter);
index b42050c68e6c95a1420dfc3e5ccecff75dee6cd6..24bdd5f4d3bcc725a9763266270a790f03d00a49 100644 (file)
@@ -278,7 +278,7 @@ static int
 __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
                struct smb_rqst *rqst)
 {
-       int rc = 0;
+       int rc;
        struct kvec *iov;
        int n_vec;
        unsigned int send_length = 0;
@@ -289,6 +289,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
        struct msghdr smb_msg = {};
        __be32 rfc1002_marker;
 
+       cifs_in_send_inc(server);
        if (cifs_rdma_enabled(server)) {
                /* return -EAGAIN when connecting or reconnecting */
                rc = -EAGAIN;
@@ -297,14 +298,17 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
                goto smbd_done;
        }
 
+       rc = -EAGAIN;
        if (ssocket == NULL)
-               return -EAGAIN;
+               goto out;
 
+       rc = -ERESTARTSYS;
        if (fatal_signal_pending(current)) {
                cifs_dbg(FYI, "signal pending before send request\n");
-               return -ERESTARTSYS;
+               goto out;
        }
 
+       rc = 0;
        /* cork the socket */
        tcp_sock_set_cork(ssocket->sk, true);
 
@@ -407,7 +411,8 @@ smbd_done:
                         rc);
        else if (rc > 0)
                rc = 0;
-
+out:
+       cifs_in_send_dec(server);
        return rc;
 }
 
@@ -826,9 +831,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
         * I/O response may come back and free the mid entry on another thread.
         */
        cifs_save_when_sent(mid);
-       cifs_in_send_inc(server);
        rc = smb_send_rqst(server, 1, rqst, flags);
-       cifs_in_send_dec(server);
 
        if (rc < 0) {
                revert_current_mid(server, mid->credits);
@@ -1144,9 +1147,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
                else
                        midQ[i]->callback = cifs_compound_last_callback;
        }
-       cifs_in_send_inc(server);
        rc = smb_send_rqst(server, num_rqst, rqst, flags);
-       cifs_in_send_dec(server);
 
        for (i = 0; i < num_rqst; i++)
                cifs_save_when_sent(midQ[i]);
@@ -1396,9 +1397,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
 
        midQ->mid_state = MID_REQUEST_SUBMITTED;
 
-       cifs_in_send_inc(server);
        rc = smb_send(server, in_buf, len);
-       cifs_in_send_dec(server);
        cifs_save_when_sent(midQ);
 
        if (rc < 0)
@@ -1539,9 +1538,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
        }
 
        midQ->mid_state = MID_REQUEST_SUBMITTED;
-       cifs_in_send_inc(server);
        rc = smb_send(server, in_buf, len);
-       cifs_in_send_dec(server);
        cifs_save_when_sent(midQ);
 
        if (rc < 0)
index 50e762fa1a148beb53e4c437177ced731c8afd03..4ad5531686d81aa4e9395f58ceb04be13520b5a2 100644 (file)
@@ -487,9 +487,5 @@ const struct xattr_handler *cifs_xattr_handlers[] = {
        &smb3_ntsd_xattr_handler, /* alias for above since avoiding "cifs" */
        &cifs_cifs_ntsd_full_xattr_handler,
        &smb3_ntsd_full_xattr_handler, /* alias for above since avoiding "cifs" */
-#ifdef CONFIG_FS_POSIX_ACL
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
-#endif
        NULL
 };
index 4afcbbe63e685f8b4e2d225e3f86360b55bda4ac..18677cd4e62f543187966501bb52364b5f6b3a55 100644 (file)
@@ -1599,12 +1599,6 @@ static int configfs_dir_close(struct inode *inode, struct file *file)
        return 0;
 }
 
-/* Relationship between s_mode and the DT_xxx types */
-static inline unsigned char dt_type(struct configfs_dirent *sd)
-{
-       return (sd->s_mode >> 12) & 15;
-}
-
 static int configfs_readdir(struct file *file, struct dir_context *ctx)
 {
        struct dentry *dentry = file->f_path.dentry;
@@ -1654,7 +1648,8 @@ static int configfs_readdir(struct file *file, struct dir_context *ctx)
                name = configfs_get_name(next);
                len = strlen(name);
 
-               if (!dir_emit(ctx, name, len, ino, dt_type(next)))
+               if (!dir_emit(ctx, name, len, ino,
+                             fs_umode_to_dtype(next->s_mode)))
                        return 0;
 
                spin_lock(&configfs_dirent_lock);
index 78086f8dbda5261f6b36a9fe8523debe81c97faa..13d336a6cc5da5675fa322d3d793c13a56291848 100644 (file)
@@ -92,6 +92,8 @@ void fscrypt_put_master_key_activeref(struct super_block *sb,
         * destroying any subkeys embedded in it.
         */
 
+       if (WARN_ON(!sb->s_master_keys))
+               return;
        spin_lock(&sb->s_master_keys->lock);
        hlist_del_rcu(&mk->mk_node);
        spin_unlock(&sb->s_master_keys->lock);
@@ -207,10 +209,11 @@ static int allocate_filesystem_keyring(struct super_block *sb)
  * Release all encryption keys that have been added to the filesystem, along
  * with the keyring that contains them.
  *
- * This is called at unmount time.  The filesystem's underlying block device(s)
- * are still available at this time; this is important because after user file
- * accesses have been allowed, this function may need to evict keys from the
- * keyslots of an inline crypto engine, which requires the block device(s).
+ * This is called at unmount time, after all potentially-encrypted inodes have
+ * been evicted.  The filesystem's underlying block device(s) are still
+ * available at this time; this is important because after user file accesses
+ * have been allowed, this function may need to evict keys from the keyslots of
+ * an inline crypto engine, which requires the block device(s).
  */
 void fscrypt_destroy_keyring(struct super_block *sb)
 {
@@ -227,12 +230,12 @@ void fscrypt_destroy_keyring(struct super_block *sb)
 
                hlist_for_each_entry_safe(mk, tmp, bucket, mk_node) {
                        /*
-                        * Since all inodes were already evicted, every key
-                        * remaining in the keyring should have an empty inode
-                        * list, and should only still be in the keyring due to
-                        * the single active ref associated with ->mk_secret.
-                        * There should be no structural refs beyond the one
-                        * associated with the active ref.
+                        * Since all potentially-encrypted inodes were already
+                        * evicted, every key remaining in the keyring should
+                        * have an empty inode list, and should only still be in
+                        * the keyring due to the single active ref associated
+                        * with ->mk_secret.  There should be no structural refs
+                        * beyond the one associated with the active ref.
                         */
                        WARN_ON(refcount_read(&mk->mk_active_refs) != 1);
                        WARN_ON(refcount_read(&mk->mk_struct_refs) != 1);
index 3e457a16c7d1828f5a70c8c9f5dcad4a422cd2ad..2ababb89918de64e2b299492ad6099792b5486a0 100644 (file)
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -781,6 +781,33 @@ out:
        return ret;
 }
 
+static int __dax_clear_dirty_range(struct address_space *mapping,
+               pgoff_t start, pgoff_t end)
+{
+       XA_STATE(xas, &mapping->i_pages, start);
+       unsigned int scanned = 0;
+       void *entry;
+
+       xas_lock_irq(&xas);
+       xas_for_each(&xas, entry, end) {
+               entry = get_unlocked_entry(&xas, 0);
+               xas_clear_mark(&xas, PAGECACHE_TAG_DIRTY);
+               xas_clear_mark(&xas, PAGECACHE_TAG_TOWRITE);
+               put_unlocked_entry(&xas, entry, WAKE_NEXT);
+
+               if (++scanned % XA_CHECK_SCHED)
+                       continue;
+
+               xas_pause(&xas);
+               xas_unlock_irq(&xas);
+               cond_resched();
+               xas_lock_irq(&xas);
+       }
+       xas_unlock_irq(&xas);
+
+       return 0;
+}
+
 /*
  * Delete DAX entry at @index from @mapping.  Wait for it
  * to be unlocked before deleting it.
@@ -1258,15 +1285,20 @@ static s64 dax_unshare_iter(struct iomap_iter *iter)
        /* don't bother with blocks that are not shared to start with */
        if (!(iomap->flags & IOMAP_F_SHARED))
                return length;
-       /* don't bother with holes or unwritten extents */
-       if (srcmap->type == IOMAP_HOLE || srcmap->type == IOMAP_UNWRITTEN)
-               return length;
 
        id = dax_read_lock();
        ret = dax_iomap_direct_access(iomap, pos, length, &daddr, NULL);
        if (ret < 0)
                goto out_unlock;
 
+       /* zero the distance if srcmap is HOLE or UNWRITTEN */
+       if (srcmap->flags & IOMAP_F_SHARED || srcmap->type == IOMAP_UNWRITTEN) {
+               memset(daddr, 0, length);
+               dax_flush(iomap->dax_dev, daddr, length);
+               ret = length;
+               goto out_unlock;
+       }
+
        ret = dax_iomap_direct_access(srcmap, pos, length, &saddr, NULL);
        if (ret < 0)
                goto out_unlock;
@@ -1435,6 +1467,16 @@ static loff_t dax_iomap_iter(const struct iomap_iter *iomi,
         * written by write(2) is visible in mmap.
         */
        if (iomap->flags & IOMAP_F_NEW || cow) {
+               /*
+                * Filesystem allows CoW on non-shared extents. The src extents
+                * may have been mmapped with dirty mark before. To be able to
+                * invalidate its dax entries, we need to clear the dirty mark
+                * in advance.
+                */
+               if (cow)
+                       __dax_clear_dirty_range(iomi->inode->i_mapping,
+                                               pos >> PAGE_SHIFT,
+                                               (end - 1) >> PAGE_SHIFT);
                invalidate_inode_pages2_range(iomi->inode->i_mapping,
                                              pos >> PAGE_SHIFT,
                                              (end - 1) >> PAGE_SHIFT);
@@ -2022,8 +2064,8 @@ int dax_dedupe_file_range_compare(struct inode *src, loff_t srcoff,
 
        while ((ret = iomap_iter(&src_iter, ops)) > 0 &&
               (ret = iomap_iter(&dst_iter, ops)) > 0) {
-               compared = dax_range_compare_iter(&src_iter, &dst_iter, len,
-                                                 same);
+               compared = dax_range_compare_iter(&src_iter, &dst_iter,
+                               min(src_iter.len, dst_iter.len), same);
                if (compared < 0)
                        return ret;
                src_iter.processed = dst_iter.processed = compared;
index 4f25015aa5342a332c76ad7d931a507784eea764..fe3db0eda8e47e00384ad352a97c9df360175a9a 100644 (file)
@@ -72,24 +72,6 @@ static struct ctl_table pty_table[] = {
        {}
 };
 
-static struct ctl_table pty_kern_table[] = {
-       {
-               .procname       = "pty",
-               .mode           = 0555,
-               .child          = pty_table,
-       },
-       {}
-};
-
-static struct ctl_table pty_root_table[] = {
-       {
-               .procname       = "kernel",
-               .mode           = 0555,
-               .child          = pty_kern_table,
-       },
-       {}
-};
-
 struct pts_mount_opts {
        int setuid;
        int setgid;
@@ -630,7 +612,7 @@ static int __init init_devpts_fs(void)
 {
        int err = register_filesystem(&devpts_fs_type);
        if (!err) {
-               register_sysctl_table(pty_root_table);
+               register_sysctl("kernel/pty", pty_table);
        }
        return err;
 }
index ab0d7ea89813a6c99e77da8381c7e4b8dfec3bd2..0b380bb8a81e11532d4488782d61fb5420198057 100644 (file)
@@ -86,7 +86,6 @@ struct dio_submit {
        sector_t final_block_in_request;/* doesn't change */
        int boundary;                   /* prev block is at a boundary */
        get_block_t *get_block;         /* block mapping function */
-       dio_submit_t *submit_io;        /* IO submition function */
 
        loff_t logical_offset_in_bio;   /* current first logical block in bio */
        sector_t final_block_in_bio;    /* current final block in bio + 1 */
@@ -431,10 +430,7 @@ static inline void dio_bio_submit(struct dio *dio, struct dio_submit *sdio)
 
        dio->bio_disk = bio->bi_bdev->bd_disk;
 
-       if (sdio->submit_io)
-               sdio->submit_io(bio, dio->inode, sdio->logical_offset_in_bio);
-       else
-               submit_bio(bio);
+       submit_bio(bio);
 
        sdio->bio = NULL;
        sdio->boundary = 0;
@@ -1098,7 +1094,7 @@ static inline int drop_refcount(struct dio *dio)
 ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
                struct block_device *bdev, struct iov_iter *iter,
                get_block_t get_block, dio_iodone_t end_io,
-               dio_submit_t submit_io, int flags)
+               int flags)
 {
        unsigned i_blkbits = READ_ONCE(inode->i_blkbits);
        unsigned blkbits = i_blkbits;
@@ -1215,7 +1211,6 @@ ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
 
        sdio.get_block = get_block;
        dio->end_io = end_io;
-       sdio.submit_io = submit_io;
        sdio.final_block_in_bio = -1;
        sdio.next_block_for_io = -1;
 
index 144ace9e0dd9116e928c2b77884b46c7c2adb1ea..83274915ba6dca20e263a868b6a60efb9670323d 100644 (file)
@@ -1210,10 +1210,6 @@ static const struct xattr_handler ecryptfs_xattr_handler = {
 };
 
 const struct xattr_handler *ecryptfs_xattr_handlers[] = {
-#ifdef CONFIG_FS_POSIX_ACL
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
-#endif
        &ecryptfs_xattr_handler,
        NULL
 };
index e16545849ea7f3e6c49718479918e218b0e47411..6fe9a779fa91643430ede2c84a4a7c1ff4899f66 100644 (file)
@@ -27,11 +27,15 @@ void erofs_put_metabuf(struct erofs_buf *buf)
        buf->page = NULL;
 }
 
-void *erofs_bread(struct erofs_buf *buf, struct inode *inode,
-                 erofs_blk_t blkaddr, enum erofs_kmap_type type)
+/*
+ * Derive the block size from inode->i_blkbits to make compatible with
+ * anonymous inode in fscache mode.
+ */
+void *erofs_bread(struct erofs_buf *buf, erofs_blk_t blkaddr,
+                 enum erofs_kmap_type type)
 {
-       struct address_space *const mapping = inode->i_mapping;
-       erofs_off_t offset = blknr_to_addr(blkaddr);
+       struct inode *inode = buf->inode;
+       erofs_off_t offset = (erofs_off_t)blkaddr << inode->i_blkbits;
        pgoff_t index = offset >> PAGE_SHIFT;
        struct page *page = buf->page;
        struct folio *folio;
@@ -41,7 +45,7 @@ void *erofs_bread(struct erofs_buf *buf, struct inode *inode,
                erofs_put_metabuf(buf);
 
                nofs_flag = memalloc_nofs_save();
-               folio = read_cache_folio(mapping, index, NULL, NULL);
+               folio = read_cache_folio(inode->i_mapping, index, NULL, NULL);
                memalloc_nofs_restore(nofs_flag);
                if (IS_ERR(folio))
                        return folio;
@@ -63,14 +67,19 @@ void *erofs_bread(struct erofs_buf *buf, struct inode *inode,
        return buf->base + (offset & ~PAGE_MASK);
 }
 
-void *erofs_read_metabuf(struct erofs_buf *buf, struct super_block *sb,
-                        erofs_blk_t blkaddr, enum erofs_kmap_type type)
+void erofs_init_metabuf(struct erofs_buf *buf, struct super_block *sb)
 {
        if (erofs_is_fscache_mode(sb))
-               return erofs_bread(buf, EROFS_SB(sb)->s_fscache->inode,
-                                  blkaddr, type);
+               buf->inode = EROFS_SB(sb)->s_fscache->inode;
+       else
+               buf->inode = sb->s_bdev->bd_inode;
+}
 
-       return erofs_bread(buf, sb->s_bdev->bd_inode, blkaddr, type);
+void *erofs_read_metabuf(struct erofs_buf *buf, struct super_block *sb,
+                        erofs_blk_t blkaddr, enum erofs_kmap_type type)
+{
+       erofs_init_metabuf(buf, sb);
+       return erofs_bread(buf, blkaddr, type);
 }
 
 static int erofs_map_blocks_flatmode(struct inode *inode,
@@ -79,33 +88,32 @@ static int erofs_map_blocks_flatmode(struct inode *inode,
        erofs_blk_t nblocks, lastblk;
        u64 offset = map->m_la;
        struct erofs_inode *vi = EROFS_I(inode);
+       struct super_block *sb = inode->i_sb;
        bool tailendpacking = (vi->datalayout == EROFS_INODE_FLAT_INLINE);
 
-       nblocks = DIV_ROUND_UP(inode->i_size, EROFS_BLKSIZ);
+       nblocks = erofs_iblks(inode);
        lastblk = nblocks - tailendpacking;
 
        /* there is no hole in flatmode */
        map->m_flags = EROFS_MAP_MAPPED;
-       if (offset < blknr_to_addr(lastblk)) {
-               map->m_pa = blknr_to_addr(vi->raw_blkaddr) + map->m_la;
-               map->m_plen = blknr_to_addr(lastblk) - offset;
+       if (offset < erofs_pos(sb, lastblk)) {
+               map->m_pa = erofs_pos(sb, vi->raw_blkaddr) + map->m_la;
+               map->m_plen = erofs_pos(sb, lastblk) - offset;
        } else if (tailendpacking) {
                map->m_pa = erofs_iloc(inode) + vi->inode_isize +
-                       vi->xattr_isize + erofs_blkoff(offset);
+                       vi->xattr_isize + erofs_blkoff(sb, offset);
                map->m_plen = inode->i_size - offset;
 
                /* inline data should be located in the same meta block */
-               if (erofs_blkoff(map->m_pa) + map->m_plen > EROFS_BLKSIZ) {
-                       erofs_err(inode->i_sb,
-                                 "inline data cross block boundary @ nid %llu",
+               if (erofs_blkoff(sb, map->m_pa) + map->m_plen > sb->s_blocksize) {
+                       erofs_err(sb, "inline data cross block boundary @ nid %llu",
                                  vi->nid);
                        DBG_BUGON(1);
                        return -EFSCORRUPTED;
                }
                map->m_flags |= EROFS_MAP_META;
        } else {
-               erofs_err(inode->i_sb,
-                         "internal error @ nid: %llu (size %llu), m_la 0x%llx",
+               erofs_err(sb, "internal error @ nid: %llu (size %llu), m_la 0x%llx",
                          vi->nid, inode->i_size, map->m_la);
                DBG_BUGON(1);
                return -EIO;
@@ -148,29 +156,29 @@ int erofs_map_blocks(struct inode *inode, struct erofs_map_blocks *map)
        pos = ALIGN(erofs_iloc(inode) + vi->inode_isize +
                    vi->xattr_isize, unit) + unit * chunknr;
 
-       kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos), EROFS_KMAP);
+       kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(sb, pos), EROFS_KMAP);
        if (IS_ERR(kaddr)) {
                err = PTR_ERR(kaddr);
                goto out;
        }
        map->m_la = chunknr << vi->chunkbits;
        map->m_plen = min_t(erofs_off_t, 1UL << vi->chunkbits,
-                           roundup(inode->i_size - map->m_la, EROFS_BLKSIZ));
+                       round_up(inode->i_size - map->m_la, sb->s_blocksize));
 
        /* handle block map */
        if (!(vi->chunkformat & EROFS_CHUNK_FORMAT_INDEXES)) {
-               __le32 *blkaddr = kaddr + erofs_blkoff(pos);
+               __le32 *blkaddr = kaddr + erofs_blkoff(sb, pos);
 
                if (le32_to_cpu(*blkaddr) == EROFS_NULL_ADDR) {
                        map->m_flags = 0;
                } else {
-                       map->m_pa = blknr_to_addr(le32_to_cpu(*blkaddr));
+                       map->m_pa = erofs_pos(sb, le32_to_cpu(*blkaddr));
                        map->m_flags = EROFS_MAP_MAPPED;
                }
                goto out_unlock;
        }
        /* parse chunk indexes */
-       idx = kaddr + erofs_blkoff(pos);
+       idx = kaddr + erofs_blkoff(sb, pos);
        switch (le32_to_cpu(idx->blkaddr)) {
        case EROFS_NULL_ADDR:
                map->m_flags = 0;
@@ -178,7 +186,7 @@ int erofs_map_blocks(struct inode *inode, struct erofs_map_blocks *map)
        default:
                map->m_deviceid = le16_to_cpu(idx->device_id) &
                        EROFS_SB(sb)->device_id_mask;
-               map->m_pa = blknr_to_addr(le32_to_cpu(idx->blkaddr));
+               map->m_pa = erofs_pos(sb, le32_to_cpu(idx->blkaddr));
                map->m_flags = EROFS_MAP_MAPPED;
                break;
        }
@@ -197,7 +205,6 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map)
        struct erofs_device_info *dif;
        int id;
 
-       /* primary device by default */
        map->m_bdev = sb->s_bdev;
        map->m_daxdev = EROFS_SB(sb)->dax_dev;
        map->m_dax_part_off = EROFS_SB(sb)->dax_part_off;
@@ -210,20 +217,25 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map)
                        up_read(&devs->rwsem);
                        return -ENODEV;
                }
+               if (devs->flatdev) {
+                       map->m_pa += erofs_pos(sb, dif->mapped_blkaddr);
+                       up_read(&devs->rwsem);
+                       return 0;
+               }
                map->m_bdev = dif->bdev;
                map->m_daxdev = dif->dax_dev;
                map->m_dax_part_off = dif->dax_part_off;
                map->m_fscache = dif->fscache;
                up_read(&devs->rwsem);
-       } else if (devs->extra_devices) {
+       } else if (devs->extra_devices && !devs->flatdev) {
                down_read(&devs->rwsem);
                idr_for_each_entry(&devs->tree, dif, id) {
                        erofs_off_t startoff, length;
 
                        if (!dif->mapped_blkaddr)
                                continue;
-                       startoff = blknr_to_addr(dif->mapped_blkaddr);
-                       length = blknr_to_addr(dif->blocks);
+                       startoff = erofs_pos(sb, dif->mapped_blkaddr);
+                       length = erofs_pos(sb, dif->blocks);
 
                        if (map->m_pa >= startoff &&
                            map->m_pa < startoff + length) {
@@ -244,6 +256,7 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
                unsigned int flags, struct iomap *iomap, struct iomap *srcmap)
 {
        int ret;
+       struct super_block *sb = inode->i_sb;
        struct erofs_map_blocks map;
        struct erofs_map_dev mdev;
 
@@ -258,7 +271,7 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
                .m_deviceid = map.m_deviceid,
                .m_pa = map.m_pa,
        };
-       ret = erofs_map_dev(inode->i_sb, &mdev);
+       ret = erofs_map_dev(sb, &mdev);
        if (ret)
                return ret;
 
@@ -284,11 +297,11 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
                struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
 
                iomap->type = IOMAP_INLINE;
-               ptr = erofs_read_metabuf(&buf, inode->i_sb,
-                                        erofs_blknr(mdev.m_pa), EROFS_KMAP);
+               ptr = erofs_read_metabuf(&buf, sb,
+                               erofs_blknr(sb, mdev.m_pa), EROFS_KMAP);
                if (IS_ERR(ptr))
                        return PTR_ERR(ptr);
-               iomap->inline_data = ptr + erofs_blkoff(mdev.m_pa);
+               iomap->inline_data = ptr + erofs_blkoff(sb, mdev.m_pa);
                iomap->private = buf.base;
        } else {
                iomap->type = IOMAP_MAPPED;
@@ -376,7 +389,7 @@ static ssize_t erofs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
                if (bdev)
                        blksize_mask = bdev_logical_block_size(bdev) - 1;
                else
-                       blksize_mask = (1 << inode->i_blkbits) - 1;
+                       blksize_mask = i_blocksize(inode) - 1;
 
                if ((iocb->ki_pos | iov_iter_count(to) |
                     iov_iter_alignment(to)) & blksize_mask)
index 51b7ac7166d9656c05ef437e680f92a57b09d0ba..7021e2cf6146338459ba40f41fa3cca57ccd9849 100644 (file)
@@ -42,7 +42,7 @@ int z_erofs_load_lz4_config(struct super_block *sb,
                if (!sbi->lz4.max_pclusterblks) {
                        sbi->lz4.max_pclusterblks = 1;  /* reserved case */
                } else if (sbi->lz4.max_pclusterblks >
-                          Z_EROFS_PCLUSTER_MAX_SIZE / EROFS_BLKSIZ) {
+                          erofs_blknr(sb, Z_EROFS_PCLUSTER_MAX_SIZE)) {
                        erofs_err(sb, "too large lz4 pclusterblks %u",
                                  sbi->lz4.max_pclusterblks);
                        return -EINVAL;
@@ -221,13 +221,13 @@ static int z_erofs_lz4_decompress_mem(struct z_erofs_lz4_decompress_ctx *ctx,
                support_0padding = true;
                ret = z_erofs_fixup_insize(rq, headpage + rq->pageofs_in,
                                min_t(unsigned int, rq->inputsize,
-                                     EROFS_BLKSIZ - rq->pageofs_in));
+                                     rq->sb->s_blocksize - rq->pageofs_in));
                if (ret) {
                        kunmap_atomic(headpage);
                        return ret;
                }
                may_inplace = !((rq->pageofs_in + rq->inputsize) &
-                               (EROFS_BLKSIZ - 1));
+                               (rq->sb->s_blocksize - 1));
        }
 
        inputmargin = rq->pageofs_in;
index 091fd5adf818f0026f67f70e323fe7b2a7531062..73091fbe3ea453d377f20bc4cfc0c2de5f76c1e5 100644 (file)
@@ -47,7 +47,7 @@ void z_erofs_lzma_exit(void)
        }
 }
 
-int z_erofs_lzma_init(void)
+int __init z_erofs_lzma_init(void)
 {
        unsigned int i;
 
@@ -166,8 +166,8 @@ int z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
        /* 1. get the exact LZMA compressed size */
        kin = kmap(*rq->in);
        err = z_erofs_fixup_insize(rq, kin + rq->pageofs_in,
-                                  min_t(unsigned int, rq->inputsize,
-                                        EROFS_BLKSIZ - rq->pageofs_in));
+                       min_t(unsigned int, rq->inputsize,
+                             rq->sb->s_blocksize - rq->pageofs_in));
        if (err) {
                kunmap(*rq->in);
                return err;
@@ -278,7 +278,7 @@ again:
                }
        }
        if (no < nrpages_out && strm->buf.out)
-               kunmap(rq->in[no]);
+               kunmap(rq->out[no]);
        if (ni < nrpages_in)
                kunmap(rq->in[ni]);
        /* 4. push back LZMA stream context to the global list */
index 6970b09b83079cd6630458a19bb9246f875ca939..b80abec0531aadc10d0e0ba9a6a4db94d81061d5 100644 (file)
@@ -50,44 +50,43 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx)
 {
        struct inode *dir = file_inode(f);
        struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
+       struct super_block *sb = dir->i_sb;
+       unsigned long bsz = sb->s_blocksize;
        const size_t dirsize = i_size_read(dir);
-       unsigned int i = ctx->pos / EROFS_BLKSIZ;
-       unsigned int ofs = ctx->pos % EROFS_BLKSIZ;
+       unsigned int i = erofs_blknr(sb, ctx->pos);
+       unsigned int ofs = erofs_blkoff(sb, ctx->pos);
        int err = 0;
        bool initial = true;
 
+       buf.inode = dir;
        while (ctx->pos < dirsize) {
                struct erofs_dirent *de;
                unsigned int nameoff, maxsize;
 
-               de = erofs_bread(&buf, dir, i, EROFS_KMAP);
+               de = erofs_bread(&buf, i, EROFS_KMAP);
                if (IS_ERR(de)) {
-                       erofs_err(dir->i_sb,
-                                 "fail to readdir of logical block %u of nid %llu",
+                       erofs_err(sb, "fail to readdir of logical block %u of nid %llu",
                                  i, EROFS_I(dir)->nid);
                        err = PTR_ERR(de);
                        break;
                }
 
                nameoff = le16_to_cpu(de->nameoff);
-               if (nameoff < sizeof(struct erofs_dirent) ||
-                   nameoff >= EROFS_BLKSIZ) {
-                       erofs_err(dir->i_sb,
-                                 "invalid de[0].nameoff %u @ nid %llu",
+               if (nameoff < sizeof(struct erofs_dirent) || nameoff >= bsz) {
+                       erofs_err(sb, "invalid de[0].nameoff %u @ nid %llu",
                                  nameoff, EROFS_I(dir)->nid);
                        err = -EFSCORRUPTED;
                        break;
                }
 
-               maxsize = min_t(unsigned int,
-                               dirsize - ctx->pos + ofs, EROFS_BLKSIZ);
+               maxsize = min_t(unsigned int, dirsize - ctx->pos + ofs, bsz);
 
                /* search dirents at the arbitrary position */
                if (initial) {
                        initial = false;
 
                        ofs = roundup(ofs, sizeof(struct erofs_dirent));
-                       ctx->pos = blknr_to_addr(i) + ofs;
+                       ctx->pos = erofs_pos(sb, i) + ofs;
                        if (ofs >= nameoff)
                                goto skip_this;
                }
@@ -97,7 +96,7 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx)
                if (err)
                        break;
 skip_this:
-               ctx->pos = blknr_to_addr(i) + maxsize;
+               ctx->pos = erofs_pos(sb, i) + maxsize;
                ++i;
                ofs = 0;
        }
index dbcd24371002bbebefed025ba15415e3193101ed..2c7b16e340fef3358f598355234c1dc5441d14ad 100644 (file)
@@ -27,6 +27,7 @@
 #define EROFS_FEATURE_INCOMPAT_ZTAILPACKING    0x00000010
 #define EROFS_FEATURE_INCOMPAT_FRAGMENTS       0x00000020
 #define EROFS_FEATURE_INCOMPAT_DEDUPE          0x00000020
+#define EROFS_FEATURE_INCOMPAT_XATTR_PREFIXES  0x00000040
 #define EROFS_ALL_FEATURE_INCOMPAT             \
        (EROFS_FEATURE_INCOMPAT_ZERO_PADDING | \
         EROFS_FEATURE_INCOMPAT_COMPR_CFGS | \
@@ -36,7 +37,8 @@
         EROFS_FEATURE_INCOMPAT_COMPR_HEAD2 | \
         EROFS_FEATURE_INCOMPAT_ZTAILPACKING | \
         EROFS_FEATURE_INCOMPAT_FRAGMENTS | \
-        EROFS_FEATURE_INCOMPAT_DEDUPE)
+        EROFS_FEATURE_INCOMPAT_DEDUPE | \
+        EROFS_FEATURE_INCOMPAT_XATTR_PREFIXES)
 
 #define EROFS_SB_EXTSLOT_SIZE  16
 
@@ -53,7 +55,7 @@ struct erofs_super_block {
        __le32 magic;           /* file system magic number */
        __le32 checksum;        /* crc32c(super_block) */
        __le32 feature_compat;
-       __u8 blkszbits;         /* support block_size == PAGE_SIZE only */
+       __u8 blkszbits;         /* filesystem block size in bit shift */
        __u8 sb_extslots;       /* superblock size = 128 + sb_extslots * 16 */
 
        __le16 root_nid;        /* nid of root directory */
@@ -75,49 +77,46 @@ struct erofs_super_block {
        } __packed u1;
        __le16 extra_devices;   /* # of devices besides the primary device */
        __le16 devt_slotoff;    /* startoff = devt_slotoff * devt_slotsize */
-       __u8 reserved[6];
+       __u8 dirblkbits;        /* directory block size in bit shift */
+       __u8 xattr_prefix_count;        /* # of long xattr name prefixes */
+       __le32 xattr_prefix_start;      /* start of long xattr prefixes */
        __le64 packed_nid;      /* nid of the special packed inode */
        __u8 reserved2[24];
 };
 
 /*
- * erofs inode datalayout (i_format in on-disk inode):
+ * EROFS inode datalayout (i_format in on-disk inode):
  * 0 - uncompressed flat inode without tail-packing inline data:
- * inode, [xattrs], ... | ... | no-holed data
  * 1 - compressed inode with non-compact indexes:
- * inode, [xattrs], [map_header], extents ... | ...
  * 2 - uncompressed flat inode with tail-packing inline data:
- * inode, [xattrs], tailpacking data, ... | ... | no-holed data
  * 3 - compressed inode with compact indexes:
- * inode, [xattrs], map_header, extents ... | ...
  * 4 - chunk-based inode with (optional) multi-device support:
- * inode, [xattrs], chunk indexes ... | ...
  * 5~7 - reserved
  */
 enum {
        EROFS_INODE_FLAT_PLAIN                  = 0,
-       EROFS_INODE_FLAT_COMPRESSION_LEGACY     = 1,
+       EROFS_INODE_COMPRESSED_FULL             = 1,
        EROFS_INODE_FLAT_INLINE                 = 2,
-       EROFS_INODE_FLAT_COMPRESSION            = 3,
+       EROFS_INODE_COMPRESSED_COMPACT          = 3,
        EROFS_INODE_CHUNK_BASED                 = 4,
        EROFS_INODE_DATALAYOUT_MAX
 };
 
 static inline bool erofs_inode_is_data_compressed(unsigned int datamode)
 {
-       return datamode == EROFS_INODE_FLAT_COMPRESSION ||
-               datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY;
+       return datamode == EROFS_INODE_COMPRESSED_COMPACT ||
+               datamode == EROFS_INODE_COMPRESSED_FULL;
 }
 
 /* bit definitions of inode i_format */
-#define EROFS_I_VERSION_BITS            1
-#define EROFS_I_DATALAYOUT_BITS         3
+#define EROFS_I_VERSION_MASK            0x01
+#define EROFS_I_DATALAYOUT_MASK         0x07
 
 #define EROFS_I_VERSION_BIT             0
 #define EROFS_I_DATALAYOUT_BIT          1
+#define EROFS_I_ALL_BIT                        4
 
-#define EROFS_I_ALL    \
-       ((1 << (EROFS_I_DATALAYOUT_BIT + EROFS_I_DATALAYOUT_BITS)) - 1)
+#define EROFS_I_ALL    ((1 << EROFS_I_ALL_BIT) - 1)
 
 /* indicate chunk blkbits, thus 'chunksize = blocksize << chunk blkbits' */
 #define EROFS_CHUNK_FORMAT_BLKBITS_MASK                0x001F
@@ -127,11 +126,30 @@ static inline bool erofs_inode_is_data_compressed(unsigned int datamode)
 #define EROFS_CHUNK_FORMAT_ALL \
        (EROFS_CHUNK_FORMAT_BLKBITS_MASK | EROFS_CHUNK_FORMAT_INDEXES)
 
+/* 32-byte on-disk inode */
+#define EROFS_INODE_LAYOUT_COMPACT     0
+/* 64-byte on-disk inode */
+#define EROFS_INODE_LAYOUT_EXTENDED    1
+
 struct erofs_inode_chunk_info {
        __le16 format;          /* chunk blkbits, etc. */
        __le16 reserved;
 };
 
+union erofs_inode_i_u {
+       /* total compressed blocks for compressed inodes */
+       __le32 compressed_blocks;
+
+       /* block address for uncompressed flat inodes */
+       __le32 raw_blkaddr;
+
+       /* for device files, used to indicate old/new device # */
+       __le32 rdev;
+
+       /* for chunk-based files, it contains the summary info */
+       struct erofs_inode_chunk_info c;
+};
+
 /* 32-byte reduced form of an ondisk inode */
 struct erofs_inode_compact {
        __le16 i_format;        /* inode format hints */
@@ -142,29 +160,14 @@ struct erofs_inode_compact {
        __le16 i_nlink;
        __le32 i_size;
        __le32 i_reserved;
-       union {
-               /* total compressed blocks for compressed inodes */
-               __le32 compressed_blocks;
-               /* block address for uncompressed flat inodes */
-               __le32 raw_blkaddr;
-
-               /* for device files, used to indicate old/new device # */
-               __le32 rdev;
-
-               /* for chunk-based files, it contains the summary info */
-               struct erofs_inode_chunk_info c;
-       } i_u;
-       __le32 i_ino;           /* only used for 32-bit stat compatibility */
+       union erofs_inode_i_u i_u;
+
+       __le32 i_ino;           /* only used for 32-bit stat compatibility */
        __le16 i_uid;
        __le16 i_gid;
        __le32 i_reserved2;
 };
 
-/* 32-byte on-disk inode */
-#define EROFS_INODE_LAYOUT_COMPACT     0
-/* 64-byte on-disk inode */
-#define EROFS_INODE_LAYOUT_EXTENDED    1
-
 /* 64-byte complete form of an ondisk inode */
 struct erofs_inode_extended {
        __le16 i_format;        /* inode format hints */
@@ -174,22 +177,9 @@ struct erofs_inode_extended {
        __le16 i_mode;
        __le16 i_reserved;
        __le64 i_size;
-       union {
-               /* total compressed blocks for compressed inodes */
-               __le32 compressed_blocks;
-               /* block address for uncompressed flat inodes */
-               __le32 raw_blkaddr;
-
-               /* for device files, used to indicate old/new device # */
-               __le32 rdev;
-
-               /* for chunk-based files, it contains the summary info */
-               struct erofs_inode_chunk_info c;
-       } i_u;
-
-       /* only used for 32-bit stat compatibility */
-       __le32 i_ino;
+       union erofs_inode_i_u i_u;
 
+       __le32 i_ino;           /* only used for 32-bit stat compatibility */
        __le32 i_uid;
        __le32 i_gid;
        __le64 i_mtime;
@@ -198,10 +188,6 @@ struct erofs_inode_extended {
        __u8   i_reserved2[16];
 };
 
-#define EROFS_MAX_SHARED_XATTRS         (128)
-/* h_shared_count between 129 ... 255 are special # */
-#define EROFS_SHARED_XATTR_EXTENT       (255)
-
 /*
  * inline xattrs (n == i_xattr_icount):
  * erofs_xattr_ibody_header(1) + (n - 1) * 4 bytes
@@ -228,6 +214,13 @@ struct erofs_xattr_ibody_header {
 #define EROFS_XATTR_INDEX_LUSTRE            5
 #define EROFS_XATTR_INDEX_SECURITY          6
 
+/*
+ * bit 7 of e_name_index is set when it refers to a long xattr name prefix,
+ * while the remained lower bits represent the index of the prefix.
+ */
+#define EROFS_XATTR_LONG_PREFIX                0x80
+#define EROFS_XATTR_LONG_PREFIX_MASK   0x7f
+
 /* xattr entry (for both inline & shared xattrs) */
 struct erofs_xattr_entry {
        __u8   e_name_len;      /* length of name */
@@ -237,6 +230,12 @@ struct erofs_xattr_entry {
        char   e_name[];        /* attribute name */
 };
 
+/* long xattr name prefix */
+struct erofs_xattr_long_prefix {
+       __u8   base_index;      /* short xattr name prefix index */
+       char   infix[];         /* infix apart from short prefix */
+};
+
 static inline unsigned int erofs_xattr_ibody_size(__le16 i_xattr_icount)
 {
        if (!i_xattr_icount)
@@ -267,6 +266,22 @@ struct erofs_inode_chunk_index {
        __le32 blkaddr;         /* start block address of this inode chunk */
 };
 
+/* dirent sorts in alphabet order, thus we can do binary search */
+struct erofs_dirent {
+       __le64 nid;     /* node number */
+       __le16 nameoff; /* start offset of file name */
+       __u8 file_type; /* file type */
+       __u8 reserved;  /* reserved */
+} __packed;
+
+/*
+ * EROFS file types should match generic FT_* types and
+ * it seems no need to add BUILD_BUG_ONs since potential
+ * unmatchness will break other fses as well...
+ */
+
+#define EROFS_NAME_LEN      255
+
 /* maximum supported size of a physical compression cluster */
 #define Z_EROFS_PCLUSTER_MAX_SIZE      (1024 * 1024)
 
@@ -336,10 +351,8 @@ struct z_erofs_map_header {
        __u8    h_clusterbits;
 };
 
-#define Z_EROFS_VLE_LEGACY_HEADER_PADDING       8
-
 /*
- * Fixed-sized output compression on-disk logical cluster type:
+ * On-disk logical cluster type:
  *    0   - literal (uncompressed) lcluster
  *    1,3 - compressed lcluster (for HEAD lclusters)
  *    2   - compressed lcluster (for NONHEAD lclusters)
@@ -363,27 +376,27 @@ struct z_erofs_map_header {
  *        di_u.delta[1] = distance to the next HEAD lcluster
  */
 enum {
-       Z_EROFS_VLE_CLUSTER_TYPE_PLAIN          = 0,
-       Z_EROFS_VLE_CLUSTER_TYPE_HEAD1          = 1,
-       Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD        = 2,
-       Z_EROFS_VLE_CLUSTER_TYPE_HEAD2          = 3,
-       Z_EROFS_VLE_CLUSTER_TYPE_MAX
+       Z_EROFS_LCLUSTER_TYPE_PLAIN     = 0,
+       Z_EROFS_LCLUSTER_TYPE_HEAD1     = 1,
+       Z_EROFS_LCLUSTER_TYPE_NONHEAD   = 2,
+       Z_EROFS_LCLUSTER_TYPE_HEAD2     = 3,
+       Z_EROFS_LCLUSTER_TYPE_MAX
 };
 
-#define Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS        2
-#define Z_EROFS_VLE_DI_CLUSTER_TYPE_BIT         0
+#define Z_EROFS_LI_LCLUSTER_TYPE_BITS        2
+#define Z_EROFS_LI_LCLUSTER_TYPE_BIT         0
 
 /* (noncompact only, HEAD) This pcluster refers to partial decompressed data */
-#define Z_EROFS_VLE_DI_PARTIAL_REF             (1 << 15)
+#define Z_EROFS_LI_PARTIAL_REF         (1 << 15)
 
 /*
  * D0_CBLKCNT will be marked _only_ at the 1st non-head lcluster to store the
  * compressed block count of a compressed extent (in logical clusters, aka.
  * block count of a pcluster).
  */
-#define Z_EROFS_VLE_DI_D0_CBLKCNT              (1 << 11)
+#define Z_EROFS_LI_D0_CBLKCNT          (1 << 11)
 
-struct z_erofs_vle_decompressed_index {
+struct z_erofs_lcluster_index {
        __le16 di_advise;
        /* where to decompress in the head lcluster */
        __le16 di_clusterofs;
@@ -400,25 +413,8 @@ struct z_erofs_vle_decompressed_index {
        } di_u;
 };
 
-#define Z_EROFS_VLE_LEGACY_INDEX_ALIGN(size) \
-       (round_up(size, sizeof(struct z_erofs_vle_decompressed_index)) + \
-        sizeof(struct z_erofs_map_header) + Z_EROFS_VLE_LEGACY_HEADER_PADDING)
-
-/* dirent sorts in alphabet order, thus we can do binary search */
-struct erofs_dirent {
-       __le64 nid;     /* node number */
-       __le16 nameoff; /* start offset of file name */
-       __u8 file_type; /* file type */
-       __u8 reserved;  /* reserved */
-} __packed;
-
-/*
- * EROFS file types should match generic FT_* types and
- * it seems no need to add BUILD_BUG_ONs since potential
- * unmatchness will break other fses as well...
- */
-
-#define EROFS_NAME_LEN      255
+#define Z_EROFS_FULL_INDEX_ALIGN(end)  \
+       (ALIGN(end, 8) + sizeof(struct z_erofs_map_header) + 8)
 
 /* check the EROFS on-disk layout strictly at compile time */
 static inline void erofs_check_ondisk_layout_definitions(void)
@@ -435,15 +431,15 @@ static inline void erofs_check_ondisk_layout_definitions(void)
        BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_info) != 4);
        BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_index) != 8);
        BUILD_BUG_ON(sizeof(struct z_erofs_map_header) != 8);
-       BUILD_BUG_ON(sizeof(struct z_erofs_vle_decompressed_index) != 8);
+       BUILD_BUG_ON(sizeof(struct z_erofs_lcluster_index) != 8);
        BUILD_BUG_ON(sizeof(struct erofs_dirent) != 12);
        /* keep in sync between 2 index structures for better extendibility */
        BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_index) !=
-                    sizeof(struct z_erofs_vle_decompressed_index));
+                    sizeof(struct z_erofs_lcluster_index));
        BUILD_BUG_ON(sizeof(struct erofs_deviceslot) != 128);
 
-       BUILD_BUG_ON(BIT(Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS) <
-                    Z_EROFS_VLE_CLUSTER_TYPE_MAX - 1);
+       BUILD_BUG_ON(BIT(Z_EROFS_LI_LCLUSTER_TYPE_BITS) <
+                    Z_EROFS_LCLUSTER_TYPE_MAX - 1);
        /* exclude old compiler versions like gcc 7.5.0 */
        BUILD_BUG_ON(__builtin_constant_p(fmh) ?
                     fmh != cpu_to_le64(1ULL << 63) : 0);
index 96a87c023128e0ddd18c9f06f9256239cf49126e..87ff35bff8d5bb3acb8dbc4d79c07d1d018cba56 100644 (file)
@@ -209,8 +209,8 @@ static int erofs_fscache_data_read_slice(struct erofs_fscache_request *primary)
                void *src;
 
                /* For tail packing layout, the offset may be non-zero. */
-               offset = erofs_blkoff(map.m_pa);
-               blknr = erofs_blknr(map.m_pa);
+               offset = erofs_blkoff(sb, map.m_pa);
+               blknr = erofs_blknr(sb, map.m_pa);
                size = map.m_llen;
 
                src = erofs_read_metabuf(&buf, sb, blknr, EROFS_KMAP);
@@ -460,6 +460,7 @@ static struct erofs_fscache *erofs_fscache_acquire_cookie(struct super_block *sb
        inode->i_size = OFFSET_MAX;
        inode->i_mapping->a_ops = &erofs_fscache_meta_aops;
        mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
+       inode->i_blkbits = EROFS_SB(sb)->blkszbits;
        inode->i_private = ctx;
 
        ctx->cookie = cookie;
index 4be7dda3cd24dfddaf3c9b28f5035432d1f59cf4..d70b12b81507fad3d601744b3fa55a6fd2212ead 100644 (file)
@@ -23,11 +23,8 @@ static void *erofs_read_inode(struct erofs_buf *buf,
        unsigned int ifmt;
        int err;
 
-       blkaddr = erofs_blknr(inode_loc);
-       *ofs = erofs_blkoff(inode_loc);
-
-       erofs_dbg("%s, reading inode nid %llu at %u of blkaddr %u",
-                 __func__, vi->nid, *ofs, blkaddr);
+       blkaddr = erofs_blknr(sb, inode_loc);
+       *ofs = erofs_blkoff(sb, inode_loc);
 
        kaddr = erofs_read_metabuf(buf, sb, blkaddr, EROFS_KMAP);
        if (IS_ERR(kaddr)) {
@@ -58,11 +55,11 @@ static void *erofs_read_inode(struct erofs_buf *buf,
        case EROFS_INODE_LAYOUT_EXTENDED:
                vi->inode_isize = sizeof(struct erofs_inode_extended);
                /* check if the extended inode acrosses block boundary */
-               if (*ofs + vi->inode_isize <= EROFS_BLKSIZ) {
+               if (*ofs + vi->inode_isize <= sb->s_blocksize) {
                        *ofs += vi->inode_isize;
                        die = (struct erofs_inode_extended *)dic;
                } else {
-                       const unsigned int gotten = EROFS_BLKSIZ - *ofs;
+                       const unsigned int gotten = sb->s_blocksize - *ofs;
 
                        copied = kmalloc(vi->inode_isize, GFP_NOFS);
                        if (!copied) {
@@ -176,7 +173,7 @@ static void *erofs_read_inode(struct erofs_buf *buf,
                        err = -EOPNOTSUPP;
                        goto err_out;
                }
-               vi->chunkbits = LOG_BLOCK_SIZE +
+               vi->chunkbits = sb->s_blocksize_bits +
                        (vi->chunkformat & EROFS_CHUNK_FORMAT_BLKBITS_MASK);
        }
        inode->i_mtime.tv_sec = inode->i_ctime.tv_sec;
@@ -188,11 +185,12 @@ static void *erofs_read_inode(struct erofs_buf *buf,
        if (test_opt(&sbi->opt, DAX_ALWAYS) && S_ISREG(inode->i_mode) &&
            vi->datalayout == EROFS_INODE_FLAT_PLAIN)
                inode->i_flags |= S_DAX;
+
        if (!nblks)
                /* measure inode.i_blocks as generic filesystems */
-               inode->i_blocks = roundup(inode->i_size, EROFS_BLKSIZ) >> 9;
+               inode->i_blocks = round_up(inode->i_size, sb->s_blocksize) >> 9;
        else
-               inode->i_blocks = nblks << LOG_SECTORS_PER_BLOCK;
+               inode->i_blocks = nblks << (sb->s_blocksize_bits - 9);
        return kaddr;
 
 bogusimode:
@@ -210,11 +208,12 @@ static int erofs_fill_symlink(struct inode *inode, void *kaddr,
                              unsigned int m_pofs)
 {
        struct erofs_inode *vi = EROFS_I(inode);
+       unsigned int bsz = i_blocksize(inode);
        char *lnk;
 
        /* if it cannot be handled with fast symlink scheme */
        if (vi->datalayout != EROFS_INODE_FLAT_INLINE ||
-           inode->i_size >= EROFS_BLKSIZ || inode->i_size < 0) {
+           inode->i_size >= bsz || inode->i_size < 0) {
                inode->i_op = &erofs_symlink_iops;
                return 0;
        }
@@ -225,7 +224,7 @@ static int erofs_fill_symlink(struct inode *inode, void *kaddr,
 
        m_pofs += vi->xattr_isize;
        /* inline symlink data shouldn't cross block boundary */
-       if (m_pofs + inode->i_size > EROFS_BLKSIZ) {
+       if (m_pofs + inode->i_size > bsz) {
                kfree(lnk);
                erofs_err(inode->i_sb,
                          "inline data cross block boundary @ nid %llu",
@@ -289,10 +288,15 @@ static int erofs_fill_inode(struct inode *inode)
        }
 
        if (erofs_inode_is_data_compressed(vi->datalayout)) {
-               if (!erofs_is_fscache_mode(inode->i_sb))
-                       err = z_erofs_fill_inode(inode);
-               else
-                       err = -EOPNOTSUPP;
+#ifdef CONFIG_EROFS_FS_ZIP
+               if (!erofs_is_fscache_mode(inode->i_sb) &&
+                   inode->i_sb->s_blocksize_bits == PAGE_SHIFT) {
+                       inode->i_mapping->a_ops = &z_erofs_aops;
+                       err = 0;
+                       goto out_unlock;
+               }
+#endif
+               err = -EOPNOTSUPP;
                goto out_unlock;
        }
        inode->i_mapping->a_ops = &erofs_raw_access_aops;
index 3f3561d37d1b2469c70c2fa697a014cca9274dcb..af0431a40647905738e2d2533d02d644f2a49c8d 100644 (file)
@@ -31,10 +31,8 @@ __printf(3, 4) void _erofs_info(struct super_block *sb,
 #define erofs_info(sb, fmt, ...) \
        _erofs_info(sb, __func__, fmt "\n", ##__VA_ARGS__)
 #ifdef CONFIG_EROFS_FS_DEBUG
-#define erofs_dbg(x, ...)       pr_debug(x "\n", ##__VA_ARGS__)
 #define DBG_BUGON               BUG_ON
 #else
-#define erofs_dbg(x, ...)       ((void)0)
 #define DBG_BUGON(x)            ((void)(x))
 #endif /* !CONFIG_EROFS_FS_DEBUG */
 
@@ -81,6 +79,7 @@ struct erofs_dev_context {
        struct rw_semaphore rwsem;
 
        unsigned int extra_devices;
+       bool flatdev;
 };
 
 struct erofs_fs_context {
@@ -116,6 +115,11 @@ struct erofs_fscache {
        char *name;
 };
 
+struct erofs_xattr_prefix_item {
+       struct erofs_xattr_long_prefix *prefix;
+       u8 infix_len;
+};
+
 struct erofs_sb_info {
        struct erofs_mount_opts opt;    /* options */
 #ifdef CONFIG_EROFS_FS_ZIP
@@ -133,8 +137,8 @@ struct erofs_sb_info {
        struct inode *managed_cache;
 
        struct erofs_sb_lz4_info lz4;
-       struct inode *packed_inode;
 #endif /* CONFIG_EROFS_FS_ZIP */
+       struct inode *packed_inode;
        struct erofs_dev_context *devs;
        struct dax_device *dax_dev;
        u64 dax_part_off;
@@ -144,11 +148,14 @@ struct erofs_sb_info {
        u32 meta_blkaddr;
 #ifdef CONFIG_EROFS_FS_XATTR
        u32 xattr_blkaddr;
+       u32 xattr_prefix_start;
+       u8 xattr_prefix_count;
+       struct erofs_xattr_prefix_item *xattr_prefixes;
 #endif
        u16 device_id_mask;     /* valid bits of device id to be used */
 
-       /* inode slot unit size in bit shift */
-       unsigned char islotbits;
+       unsigned char islotbits;        /* inode slot unit size in bit shift */
+       unsigned char blkszbits;        /* filesystem block size in bit shift */
 
        u32 sb_size;                    /* total superblock size */
        u32 build_time_nsec;
@@ -156,6 +163,7 @@ struct erofs_sb_info {
 
        /* what we really care is nid, rather than ino.. */
        erofs_nid_t root_nid;
+       erofs_nid_t packed_nid;
        /* used for statfs, f_files - f_favail */
        u64 inos;
 
@@ -240,27 +248,13 @@ static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup *grp)
                                        VAL != EROFS_LOCKED_MAGIC);
 }
 
-/* we strictly follow PAGE_SIZE and no buffer head yet */
-#define LOG_BLOCK_SIZE         PAGE_SHIFT
-
-#undef LOG_SECTORS_PER_BLOCK
-#define LOG_SECTORS_PER_BLOCK  (PAGE_SHIFT - 9)
-
-#undef SECTORS_PER_BLOCK
-#define SECTORS_PER_BLOCK      (1 << SECTORS_PER_BLOCK)
-
-#define EROFS_BLKSIZ           (1 << LOG_BLOCK_SIZE)
-
-#if (EROFS_BLKSIZ % 4096 || !EROFS_BLKSIZ)
-#error erofs cannot be used in this platform
-#endif
-
 enum erofs_kmap_type {
        EROFS_NO_KMAP,          /* don't map the buffer */
        EROFS_KMAP,             /* use kmap_local_page() to map the buffer */
 };
 
 struct erofs_buf {
+       struct inode *inode;
        struct page *page;
        void *base;
        enum erofs_kmap_type kmap_type;
@@ -269,9 +263,10 @@ struct erofs_buf {
 
 #define ROOT_NID(sb)           ((sb)->root_nid)
 
-#define erofs_blknr(addr)       ((addr) / EROFS_BLKSIZ)
-#define erofs_blkoff(addr)      ((addr) % EROFS_BLKSIZ)
-#define blknr_to_addr(nr)       ((erofs_off_t)(nr) * EROFS_BLKSIZ)
+#define erofs_blknr(sb, addr)  ((addr) >> (sb)->s_blocksize_bits)
+#define erofs_blkoff(sb, addr) ((addr) & ((sb)->s_blocksize - 1))
+#define erofs_pos(sb, blk)     ((erofs_off_t)(blk) << (sb)->s_blocksize_bits)
+#define erofs_iblks(i) (round_up((i)->i_size, i_blocksize(i)) >> (i)->i_blkbits)
 
 #define EROFS_FEATURE_FUNCS(name, compat, feature) \
 static inline bool erofs_sb_has_##name(struct erofs_sb_info *sbi) \
@@ -288,6 +283,7 @@ EROFS_FEATURE_FUNCS(compr_head2, incompat, INCOMPAT_COMPR_HEAD2)
 EROFS_FEATURE_FUNCS(ztailpacking, incompat, INCOMPAT_ZTAILPACKING)
 EROFS_FEATURE_FUNCS(fragments, incompat, INCOMPAT_FRAGMENTS)
 EROFS_FEATURE_FUNCS(dedupe, incompat, INCOMPAT_DEDUPE)
+EROFS_FEATURE_FUNCS(xattr_prefixes, incompat, INCOMPAT_XATTR_PREFIXES)
 EROFS_FEATURE_FUNCS(sb_chksum, compat, COMPAT_SB_CHKSUM)
 
 /* atomic flag definitions */
@@ -306,7 +302,7 @@ struct erofs_inode {
 
        unsigned char datalayout;
        unsigned char inode_isize;
-       unsigned short xattr_isize;
+       unsigned int xattr_isize;
 
        unsigned int xattr_shared_count;
        unsigned int *xattr_shared_xattrs;
@@ -343,28 +339,18 @@ static inline erofs_off_t erofs_iloc(struct inode *inode)
 {
        struct erofs_sb_info *sbi = EROFS_I_SB(inode);
 
-       return blknr_to_addr(sbi->meta_blkaddr) +
+       return erofs_pos(inode->i_sb, sbi->meta_blkaddr) +
                (EROFS_I(inode)->nid << sbi->islotbits);
 }
 
-static inline unsigned int erofs_bitrange(unsigned int value, unsigned int bit,
-                                         unsigned int bits)
-{
-
-       return (value >> bit) & ((1 << bits) - 1);
-}
-
-
-static inline unsigned int erofs_inode_version(unsigned int value)
+static inline unsigned int erofs_inode_version(unsigned int ifmt)
 {
-       return erofs_bitrange(value, EROFS_I_VERSION_BIT,
-                             EROFS_I_VERSION_BITS);
+       return (ifmt >> EROFS_I_VERSION_BIT) & EROFS_I_VERSION_MASK;
 }
 
-static inline unsigned int erofs_inode_datalayout(unsigned int value)
+static inline unsigned int erofs_inode_datalayout(unsigned int ifmt)
 {
-       return erofs_bitrange(value, EROFS_I_DATALAYOUT_BIT,
-                             EROFS_I_DATALAYOUT_BITS);
+       return (ifmt >> EROFS_I_DATALAYOUT_BIT) & EROFS_I_DATALAYOUT_MASK;
 }
 
 /*
@@ -451,10 +437,13 @@ extern const struct iomap_ops z_erofs_iomap_report_ops;
 #define EROFS_REG_COOKIE_SHARE         0x0001
 #define EROFS_REG_COOKIE_NEED_NOEXIST  0x0002
 
+void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
+                         erofs_off_t *offset, int *lengthp);
 void erofs_unmap_metabuf(struct erofs_buf *buf);
 void erofs_put_metabuf(struct erofs_buf *buf);
-void *erofs_bread(struct erofs_buf *buf, struct inode *inode,
-                 erofs_blk_t blkaddr, enum erofs_kmap_type type);
+void *erofs_bread(struct erofs_buf *buf, erofs_blk_t blkaddr,
+                 enum erofs_kmap_type type);
+void erofs_init_metabuf(struct erofs_buf *buf, struct super_block *sb);
 void *erofs_read_metabuf(struct erofs_buf *buf, struct super_block *sb,
                         erofs_blk_t blkaddr, enum erofs_kmap_type type);
 int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *dev);
@@ -486,7 +475,7 @@ static inline void *erofs_vm_map_ram(struct page **pages, unsigned int count)
 void *erofs_get_pcpubuf(unsigned int requiredpages);
 void erofs_put_pcpubuf(void *ptr);
 int erofs_pcpubuf_growsize(unsigned int nrpages);
-void erofs_pcpubuf_init(void);
+void __init erofs_pcpubuf_init(void);
 void erofs_pcpubuf_exit(void);
 
 int erofs_register_sysfs(struct super_block *sb);
@@ -521,7 +510,6 @@ int erofs_try_to_free_cached_page(struct page *page);
 int z_erofs_load_lz4_config(struct super_block *sb,
                            struct erofs_super_block *dsb,
                            struct z_erofs_lz4_cfgs *lz4, int len);
-int z_erofs_fill_inode(struct inode *inode);
 int z_erofs_map_blocks_iter(struct inode *inode, struct erofs_map_blocks *map,
                            int flags);
 #else
@@ -541,11 +529,10 @@ static inline int z_erofs_load_lz4_config(struct super_block *sb,
        }
        return 0;
 }
-static inline int z_erofs_fill_inode(struct inode *inode) { return -EOPNOTSUPP; }
 #endif /* !CONFIG_EROFS_FS_ZIP */
 
 #ifdef CONFIG_EROFS_FS_ZIP_LZMA
-int z_erofs_lzma_init(void);
+int __init z_erofs_lzma_init(void);
 void z_erofs_lzma_exit(void);
 int z_erofs_load_lzma_config(struct super_block *sb,
                             struct erofs_super_block *dsb,
index 966eabc61c1378bc5f79770b67e6fb77a1e14547..d4f631d39f0fa83141eafcb13951bb3fd36598bd 100644 (file)
@@ -89,7 +89,8 @@ static struct erofs_dirent *find_target_dirent(struct erofs_qstr *name,
 static void *erofs_find_target_block(struct erofs_buf *target,
                struct inode *dir, struct erofs_qstr *name, int *_ndirents)
 {
-       int head = 0, back = DIV_ROUND_UP(dir->i_size, EROFS_BLKSIZ) - 1;
+       unsigned int bsz = i_blocksize(dir);
+       int head = 0, back = erofs_iblks(dir) - 1;
        unsigned int startprfx = 0, endprfx = 0;
        void *candidate = ERR_PTR(-ENOENT);
 
@@ -98,10 +99,10 @@ static void *erofs_find_target_block(struct erofs_buf *target,
                struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
                struct erofs_dirent *de;
 
-               de = erofs_bread(&buf, dir, mid, EROFS_KMAP);
+               buf.inode = dir;
+               de = erofs_bread(&buf, mid, EROFS_KMAP);
                if (!IS_ERR(de)) {
-                       const int nameoff = nameoff_from_disk(de->nameoff,
-                                                             EROFS_BLKSIZ);
+                       const int nameoff = nameoff_from_disk(de->nameoff, bsz);
                        const int ndirents = nameoff / sizeof(*de);
                        int diff;
                        unsigned int matched;
@@ -121,11 +122,10 @@ static void *erofs_find_target_block(struct erofs_buf *target,
 
                        dname.name = (u8 *)de + nameoff;
                        if (ndirents == 1)
-                               dname.end = (u8 *)de + EROFS_BLKSIZ;
+                               dname.end = (u8 *)de + bsz;
                        else
                                dname.end = (u8 *)de +
-                                       nameoff_from_disk(de[1].nameoff,
-                                                         EROFS_BLKSIZ);
+                                       nameoff_from_disk(de[1].nameoff, bsz);
 
                        /* string comparison without already matched prefix */
                        diff = erofs_dirnamecmp(name, &dname, &matched);
@@ -171,6 +171,7 @@ int erofs_namei(struct inode *dir, const struct qstr *name, erofs_nid_t *nid,
 
        qn.name = name->name;
        qn.end = name->name + name->len;
+       buf.inode = dir;
 
        ndirents = 0;
        de = erofs_find_target_block(&buf, dir, &qn, &ndirents);
@@ -178,7 +179,8 @@ int erofs_namei(struct inode *dir, const struct qstr *name, erofs_nid_t *nid,
                return PTR_ERR(de);
 
        if (ndirents)
-               de = find_target_dirent(&qn, (u8 *)de, EROFS_BLKSIZ, ndirents);
+               de = find_target_dirent(&qn, (u8 *)de, i_blocksize(dir),
+                                       ndirents);
 
        if (!IS_ERR(de)) {
                *nid = le64_to_cpu(de->nid);
@@ -203,16 +205,13 @@ static struct dentry *erofs_lookup(struct inode *dir, struct dentry *dentry,
 
        err = erofs_namei(dir, &dentry->d_name, &nid, &d_type);
 
-       if (err == -ENOENT) {
+       if (err == -ENOENT)
                /* negative dentry */
                inode = NULL;
-       } else if (err) {
+       else if (err)
                inode = ERR_PTR(err);
-       } else {
-               erofs_dbg("%s, %pd (nid %llu) found, d_type %u", __func__,
-                         dentry, nid, d_type);
+       else
                inode = erofs_iget(dir->i_sb, nid);
-       }
        return d_splice_alias(inode, dentry);
 }
 
index a2efd833d1b6c32791c3ed380d5792361160fd05..c7a4b1d77069d9e7b749a08aec36988e7fa92d3f 100644 (file)
@@ -114,7 +114,7 @@ out:
        return ret;
 }
 
-void erofs_pcpubuf_init(void)
+void __init erofs_pcpubuf_init(void)
 {
        int cpu;
 
index 19b1ae79cec4169800e308014add7466f7916b23..811ab66d805ede335ab7f84aff510ba1fbdd549c 100644 (file)
@@ -52,18 +52,21 @@ void _erofs_info(struct super_block *sb, const char *function,
 
 static int erofs_superblock_csum_verify(struct super_block *sb, void *sbdata)
 {
+       size_t len = 1 << EROFS_SB(sb)->blkszbits;
        struct erofs_super_block *dsb;
        u32 expected_crc, crc;
 
-       dsb = kmemdup(sbdata + EROFS_SUPER_OFFSET,
-                     EROFS_BLKSIZ - EROFS_SUPER_OFFSET, GFP_KERNEL);
+       if (len > EROFS_SUPER_OFFSET)
+               len -= EROFS_SUPER_OFFSET;
+
+       dsb = kmemdup(sbdata + EROFS_SUPER_OFFSET, len, GFP_KERNEL);
        if (!dsb)
                return -ENOMEM;
 
        expected_crc = le32_to_cpu(dsb->checksum);
        dsb->checksum = 0;
        /* to allow for x86 boot sectors and other oddities. */
-       crc = crc32c(~0, dsb, EROFS_BLKSIZ - EROFS_SUPER_OFFSET);
+       crc = crc32c(~0, dsb, len);
        kfree(dsb);
 
        if (crc != expected_crc) {
@@ -123,20 +126,19 @@ static bool check_layout_compatibility(struct super_block *sb,
        return true;
 }
 
-#ifdef CONFIG_EROFS_FS_ZIP
 /* read variable-sized metadata, offset will be aligned by 4-byte */
-static void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
-                                erofs_off_t *offset, int *lengthp)
+void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
+                         erofs_off_t *offset, int *lengthp)
 {
        u8 *buffer, *ptr;
        int len, i, cnt;
 
        *offset = round_up(*offset, 4);
-       ptr = erofs_read_metabuf(buf, sb, erofs_blknr(*offset), EROFS_KMAP);
+       ptr = erofs_bread(buf, erofs_blknr(sb, *offset), EROFS_KMAP);
        if (IS_ERR(ptr))
                return ptr;
 
-       len = le16_to_cpu(*(__le16 *)&ptr[erofs_blkoff(*offset)]);
+       len = le16_to_cpu(*(__le16 *)&ptr[erofs_blkoff(sb, *offset)]);
        if (!len)
                len = U16_MAX + 1;
        buffer = kmalloc(len, GFP_KERNEL);
@@ -146,19 +148,20 @@ static void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
        *lengthp = len;
 
        for (i = 0; i < len; i += cnt) {
-               cnt = min(EROFS_BLKSIZ - (int)erofs_blkoff(*offset), len - i);
-               ptr = erofs_read_metabuf(buf, sb, erofs_blknr(*offset),
-                                        EROFS_KMAP);
+               cnt = min_t(int, sb->s_blocksize - erofs_blkoff(sb, *offset),
+                           len - i);
+               ptr = erofs_bread(buf, erofs_blknr(sb, *offset), EROFS_KMAP);
                if (IS_ERR(ptr)) {
                        kfree(buffer);
                        return ptr;
                }
-               memcpy(buffer + i, ptr + erofs_blkoff(*offset), cnt);
+               memcpy(buffer + i, ptr + erofs_blkoff(sb, *offset), cnt);
                *offset += cnt;
        }
        return buffer;
 }
 
+#ifdef CONFIG_EROFS_FS_ZIP
 static int erofs_load_compr_cfgs(struct super_block *sb,
                                 struct erofs_super_block *dsb)
 {
@@ -175,6 +178,7 @@ static int erofs_load_compr_cfgs(struct super_block *sb,
                return -EINVAL;
        }
 
+       erofs_init_metabuf(&buf, sb);
        offset = EROFS_SUPER_OFFSET + sbi->sb_size;
        alg = 0;
        for (algs = sbi->available_compr_algs; algs; algs >>= 1, ++alg) {
@@ -228,10 +232,10 @@ static int erofs_init_device(struct erofs_buf *buf, struct super_block *sb,
        struct block_device *bdev;
        void *ptr;
 
-       ptr = erofs_read_metabuf(buf, sb, erofs_blknr(*pos), EROFS_KMAP);
+       ptr = erofs_read_metabuf(buf, sb, erofs_blknr(sb, *pos), EROFS_KMAP);
        if (IS_ERR(ptr))
                return PTR_ERR(ptr);
-       dis = ptr + erofs_blkoff(*pos);
+       dis = ptr + erofs_blkoff(sb, *pos);
 
        if (!dif->path) {
                if (!dis->tag[0]) {
@@ -248,7 +252,7 @@ static int erofs_init_device(struct erofs_buf *buf, struct super_block *sb,
                if (IS_ERR(fscache))
                        return PTR_ERR(fscache);
                dif->fscache = fscache;
-       } else {
+       } else if (!sbi->devs->flatdev) {
                bdev = blkdev_get_by_path(dif->path, FMODE_READ | FMODE_EXCL,
                                          sb->s_type);
                if (IS_ERR(bdev))
@@ -290,6 +294,9 @@ static int erofs_scan_devices(struct super_block *sb,
        if (!ondisk_extradevs)
                return 0;
 
+       if (!sbi->devs->extra_devices && !erofs_is_fscache_mode(sb))
+               sbi->devs->flatdev = true;
+
        sbi->device_id_mask = roundup_pow_of_two(ondisk_extradevs + 1) - 1;
        pos = le16_to_cpu(dsb->devt_slotoff) * EROFS_DEVT_SLOT_SIZE;
        down_read(&sbi->devs->rwsem);
@@ -329,7 +336,6 @@ static int erofs_read_superblock(struct super_block *sb)
        struct erofs_sb_info *sbi;
        struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
        struct erofs_super_block *dsb;
-       unsigned int blkszbits;
        void *data;
        int ret;
 
@@ -348,6 +354,16 @@ static int erofs_read_superblock(struct super_block *sb)
                goto out;
        }
 
+       sbi->blkszbits  = dsb->blkszbits;
+       if (sbi->blkszbits < 9 || sbi->blkszbits > PAGE_SHIFT) {
+               erofs_err(sb, "blkszbits %u isn't supported", sbi->blkszbits);
+               goto out;
+       }
+       if (dsb->dirblkbits) {
+               erofs_err(sb, "dirblkbits %u isn't supported", dsb->dirblkbits);
+               goto out;
+       }
+
        sbi->feature_compat = le32_to_cpu(dsb->feature_compat);
        if (erofs_sb_has_sb_chksum(sbi)) {
                ret = erofs_superblock_csum_verify(sb, data);
@@ -356,19 +372,11 @@ static int erofs_read_superblock(struct super_block *sb)
        }
 
        ret = -EINVAL;
-       blkszbits = dsb->blkszbits;
-       /* 9(512 bytes) + LOG_SECTORS_PER_BLOCK == LOG_BLOCK_SIZE */
-       if (blkszbits != LOG_BLOCK_SIZE) {
-               erofs_err(sb, "blkszbits %u isn't supported on this platform",
-                         blkszbits);
-               goto out;
-       }
-
        if (!check_layout_compatibility(sb, dsb))
                goto out;
 
        sbi->sb_size = 128 + dsb->sb_extslots * EROFS_SB_EXTSLOT_SIZE;
-       if (sbi->sb_size > EROFS_BLKSIZ) {
+       if (sbi->sb_size > PAGE_SIZE - EROFS_SUPER_OFFSET) {
                erofs_err(sb, "invalid sb_extslots %u (more than a fs block)",
                          sbi->sb_size);
                goto out;
@@ -377,20 +385,12 @@ static int erofs_read_superblock(struct super_block *sb)
        sbi->meta_blkaddr = le32_to_cpu(dsb->meta_blkaddr);
 #ifdef CONFIG_EROFS_FS_XATTR
        sbi->xattr_blkaddr = le32_to_cpu(dsb->xattr_blkaddr);
+       sbi->xattr_prefix_start = le32_to_cpu(dsb->xattr_prefix_start);
+       sbi->xattr_prefix_count = dsb->xattr_prefix_count;
 #endif
        sbi->islotbits = ilog2(sizeof(struct erofs_inode_compact));
        sbi->root_nid = le16_to_cpu(dsb->root_nid);
-#ifdef CONFIG_EROFS_FS_ZIP
-       sbi->packed_inode = NULL;
-       if (erofs_sb_has_fragments(sbi) && dsb->packed_nid) {
-               sbi->packed_inode =
-                       erofs_iget(sb, le64_to_cpu(dsb->packed_nid));
-               if (IS_ERR(sbi->packed_inode)) {
-                       ret = PTR_ERR(sbi->packed_inode);
-                       goto out;
-               }
-       }
-#endif
+       sbi->packed_nid = le64_to_cpu(dsb->packed_nid);
        sbi->inos = le64_to_cpu(dsb->inos);
 
        sbi->build_time = le64_to_cpu(dsb->build_time);
@@ -417,8 +417,6 @@ static int erofs_read_superblock(struct super_block *sb)
        /* handle multiple devices */
        ret = erofs_scan_devices(sb, dsb);
 
-       if (erofs_sb_has_ztailpacking(sbi))
-               erofs_info(sb, "EXPERIMENTAL compressed inline data feature in use. Use at your own risk!");
        if (erofs_is_fscache_mode(sb))
                erofs_info(sb, "EXPERIMENTAL fscache-based on-demand read feature in use. Use at your own risk!");
        if (erofs_sb_has_fragments(sbi))
@@ -733,9 +731,10 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
        sbi->domain_id = ctx->domain_id;
        ctx->domain_id = NULL;
 
+       sbi->blkszbits = PAGE_SHIFT;
        if (erofs_is_fscache_mode(sb)) {
-               sb->s_blocksize = EROFS_BLKSIZ;
-               sb->s_blocksize_bits = LOG_BLOCK_SIZE;
+               sb->s_blocksize = PAGE_SIZE;
+               sb->s_blocksize_bits = PAGE_SHIFT;
 
                err = erofs_fscache_register_fs(sb);
                if (err)
@@ -745,8 +744,8 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
                if (err)
                        return err;
        } else {
-               if (!sb_set_blocksize(sb, EROFS_BLKSIZ)) {
-                       erofs_err(sb, "failed to set erofs blksize");
+               if (!sb_set_blocksize(sb, PAGE_SIZE)) {
+                       errorfc(fc, "failed to set initial blksize");
                        return -EINVAL;
                }
 
@@ -759,12 +758,24 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
        if (err)
                return err;
 
-       if (test_opt(&sbi->opt, DAX_ALWAYS)) {
-               BUILD_BUG_ON(EROFS_BLKSIZ != PAGE_SIZE);
+       if (sb->s_blocksize_bits != sbi->blkszbits) {
+               if (erofs_is_fscache_mode(sb)) {
+                       errorfc(fc, "unsupported blksize for fscache mode");
+                       return -EINVAL;
+               }
+               if (!sb_set_blocksize(sb, 1 << sbi->blkszbits)) {
+                       errorfc(fc, "failed to set erofs blksize");
+                       return -EINVAL;
+               }
+       }
 
+       if (test_opt(&sbi->opt, DAX_ALWAYS)) {
                if (!sbi->dax_dev) {
                        errorfc(fc, "DAX unsupported by block device. Turning off DAX.");
                        clear_opt(&sbi->opt, DAX_ALWAYS);
+               } else if (sbi->blkszbits != PAGE_SHIFT) {
+                       errorfc(fc, "unsupported blocksize for DAX");
+                       clear_opt(&sbi->opt, DAX_ALWAYS);
                }
        }
 
@@ -799,10 +810,22 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
 
        erofs_shrinker_register(sb);
        /* sb->s_umount is already locked, SB_ACTIVE and SB_BORN are not set */
+       if (erofs_sb_has_fragments(sbi) && sbi->packed_nid) {
+               sbi->packed_inode = erofs_iget(sb, sbi->packed_nid);
+               if (IS_ERR(sbi->packed_inode)) {
+                       err = PTR_ERR(sbi->packed_inode);
+                       sbi->packed_inode = NULL;
+                       return err;
+               }
+       }
        err = erofs_init_managed_cache(sb);
        if (err)
                return err;
 
+       err = erofs_xattr_prefixes_init(sb);
+       if (err)
+               return err;
+
        err = erofs_register_sysfs(sb);
        if (err)
                return err;
@@ -962,12 +985,13 @@ static void erofs_put_super(struct super_block *sb)
 
        erofs_unregister_sysfs(sb);
        erofs_shrinker_unregister(sb);
+       erofs_xattr_prefixes_cleanup(sb);
 #ifdef CONFIG_EROFS_FS_ZIP
        iput(sbi->managed_cache);
        sbi->managed_cache = NULL;
+#endif
        iput(sbi->packed_inode);
        sbi->packed_inode = NULL;
-#endif
        erofs_free_dev_context(sbi->devs);
        sbi->devs = NULL;
        erofs_fscache_unregister_fs(sb);
@@ -1060,7 +1084,7 @@ static int erofs_statfs(struct dentry *dentry, struct kstatfs *buf)
                id = huge_encode_dev(sb->s_bdev->bd_dev);
 
        buf->f_type = sb->s_magic;
-       buf->f_bsize = EROFS_BLKSIZ;
+       buf->f_bsize = sb->s_blocksize;
        buf->f_blocks = sbi->total_blocks;
        buf->f_bfree = buf->f_bavail = 0;
 
index 60729b1220b6bbdb1a5e3dc01058538689b96545..cd80499351e05c1e3900a71f468b51eaa8d009ad 100644 (file)
@@ -7,6 +7,19 @@
 #include <linux/security.h>
 #include "xattr.h"
 
+static inline erofs_blk_t erofs_xattr_blkaddr(struct super_block *sb,
+                                             unsigned int xattr_id)
+{
+       return EROFS_SB(sb)->xattr_blkaddr +
+              erofs_blknr(sb, xattr_id * sizeof(__u32));
+}
+
+static inline unsigned int erofs_xattr_blkoff(struct super_block *sb,
+                                             unsigned int xattr_id)
+{
+       return erofs_blkoff(sb, xattr_id * sizeof(__u32));
+}
+
 struct xattr_iter {
        struct super_block *sb;
        struct erofs_buf buf;
@@ -16,7 +29,7 @@ struct xattr_iter {
        unsigned int ofs;
 };
 
-static int init_inode_xattrs(struct inode *inode)
+static int erofs_init_inode_xattrs(struct inode *inode)
 {
        struct erofs_inode *const vi = EROFS_I(inode);
        struct xattr_iter it;
@@ -68,8 +81,8 @@ static int init_inode_xattrs(struct inode *inode)
        }
 
        it.buf = __EROFS_BUF_INITIALIZER;
-       it.blkaddr = erofs_blknr(erofs_iloc(inode) + vi->inode_isize);
-       it.ofs = erofs_blkoff(erofs_iloc(inode) + vi->inode_isize);
+       it.blkaddr = erofs_blknr(sb, erofs_iloc(inode) + vi->inode_isize);
+       it.ofs = erofs_blkoff(sb, erofs_iloc(inode) + vi->inode_isize);
 
        /* read in shared xattr array (non-atomic, see kmalloc below) */
        it.kaddr = erofs_read_metabuf(&it.buf, sb, it.blkaddr, EROFS_KMAP);
@@ -92,9 +105,9 @@ static int init_inode_xattrs(struct inode *inode)
        it.ofs += sizeof(struct erofs_xattr_ibody_header);
 
        for (i = 0; i < vi->xattr_shared_count; ++i) {
-               if (it.ofs >= EROFS_BLKSIZ) {
+               if (it.ofs >= sb->s_blocksize) {
                        /* cannot be unaligned */
-                       DBG_BUGON(it.ofs != EROFS_BLKSIZ);
+                       DBG_BUGON(it.ofs != sb->s_blocksize);
 
                        it.kaddr = erofs_read_metabuf(&it.buf, sb, ++it.blkaddr,
                                                      EROFS_KMAP);
@@ -139,15 +152,15 @@ struct xattr_iter_handlers {
 
 static inline int xattr_iter_fixup(struct xattr_iter *it)
 {
-       if (it->ofs < EROFS_BLKSIZ)
+       if (it->ofs < it->sb->s_blocksize)
                return 0;
 
-       it->blkaddr += erofs_blknr(it->ofs);
+       it->blkaddr += erofs_blknr(it->sb, it->ofs);
        it->kaddr = erofs_read_metabuf(&it->buf, it->sb, it->blkaddr,
                                       EROFS_KMAP);
        if (IS_ERR(it->kaddr))
                return PTR_ERR(it->kaddr);
-       it->ofs = erofs_blkoff(it->ofs);
+       it->ofs = erofs_blkoff(it->sb, it->ofs);
        return 0;
 }
 
@@ -157,7 +170,8 @@ static int inline_xattr_iter_begin(struct xattr_iter *it,
        struct erofs_inode *const vi = EROFS_I(inode);
        unsigned int xattr_header_sz, inline_xattr_ofs;
 
-       xattr_header_sz = inlinexattr_header_size(inode);
+       xattr_header_sz = sizeof(struct erofs_xattr_ibody_header) +
+                         sizeof(u32) * vi->xattr_shared_count;
        if (xattr_header_sz >= vi->xattr_isize) {
                DBG_BUGON(xattr_header_sz > vi->xattr_isize);
                return -ENOATTR;
@@ -165,8 +179,8 @@ static int inline_xattr_iter_begin(struct xattr_iter *it,
 
        inline_xattr_ofs = vi->inode_isize + xattr_header_sz;
 
-       it->blkaddr = erofs_blknr(erofs_iloc(inode) + inline_xattr_ofs);
-       it->ofs = erofs_blkoff(erofs_iloc(inode) + inline_xattr_ofs);
+       it->blkaddr = erofs_blknr(it->sb, erofs_iloc(inode) + inline_xattr_ofs);
+       it->ofs = erofs_blkoff(it->sb, erofs_iloc(inode) + inline_xattr_ofs);
        it->kaddr = erofs_read_metabuf(&it->buf, inode->i_sb, it->blkaddr,
                                       EROFS_KMAP);
        if (IS_ERR(it->kaddr))
@@ -222,8 +236,8 @@ static int xattr_foreach(struct xattr_iter *it,
        processed = 0;
 
        while (processed < entry.e_name_len) {
-               if (it->ofs >= EROFS_BLKSIZ) {
-                       DBG_BUGON(it->ofs > EROFS_BLKSIZ);
+               if (it->ofs >= it->sb->s_blocksize) {
+                       DBG_BUGON(it->ofs > it->sb->s_blocksize);
 
                        err = xattr_iter_fixup(it);
                        if (err)
@@ -231,7 +245,7 @@ static int xattr_foreach(struct xattr_iter *it,
                        it->ofs = 0;
                }
 
-               slice = min_t(unsigned int, EROFS_BLKSIZ - it->ofs,
+               slice = min_t(unsigned int, it->sb->s_blocksize - it->ofs,
                              entry.e_name_len - processed);
 
                /* handle name */
@@ -257,8 +271,8 @@ static int xattr_foreach(struct xattr_iter *it,
        }
 
        while (processed < value_sz) {
-               if (it->ofs >= EROFS_BLKSIZ) {
-                       DBG_BUGON(it->ofs > EROFS_BLKSIZ);
+               if (it->ofs >= it->sb->s_blocksize) {
+                       DBG_BUGON(it->ofs > it->sb->s_blocksize);
 
                        err = xattr_iter_fixup(it);
                        if (err)
@@ -266,7 +280,7 @@ static int xattr_foreach(struct xattr_iter *it,
                        it->ofs = 0;
                }
 
-               slice = min_t(unsigned int, EROFS_BLKSIZ - it->ofs,
+               slice = min_t(unsigned int, it->sb->s_blocksize - it->ofs,
                              value_sz - processed);
                op->value(it, processed, it->kaddr + it->ofs, slice);
                it->ofs += slice;
@@ -283,17 +297,45 @@ struct getxattr_iter {
        struct xattr_iter it;
 
        char *buffer;
-       int buffer_size, index;
+       int buffer_size, index, infix_len;
        struct qstr name;
 };
 
+static int erofs_xattr_long_entrymatch(struct getxattr_iter *it,
+                                      struct erofs_xattr_entry *entry)
+{
+       struct erofs_sb_info *sbi = EROFS_SB(it->it.sb);
+       struct erofs_xattr_prefix_item *pf = sbi->xattr_prefixes +
+               (entry->e_name_index & EROFS_XATTR_LONG_PREFIX_MASK);
+
+       if (pf >= sbi->xattr_prefixes + sbi->xattr_prefix_count)
+               return -ENOATTR;
+
+       if (it->index != pf->prefix->base_index ||
+           it->name.len != entry->e_name_len + pf->infix_len)
+               return -ENOATTR;
+
+       if (memcmp(it->name.name, pf->prefix->infix, pf->infix_len))
+               return -ENOATTR;
+
+       it->infix_len = pf->infix_len;
+       return 0;
+}
+
 static int xattr_entrymatch(struct xattr_iter *_it,
                            struct erofs_xattr_entry *entry)
 {
        struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it);
 
-       return (it->index != entry->e_name_index ||
-               it->name.len != entry->e_name_len) ? -ENOATTR : 0;
+       /* should also match the infix for long name prefixes */
+       if (entry->e_name_index & EROFS_XATTR_LONG_PREFIX)
+               return erofs_xattr_long_entrymatch(it, entry);
+
+       if (it->index != entry->e_name_index ||
+           it->name.len != entry->e_name_len)
+               return -ENOATTR;
+       it->infix_len = 0;
+       return 0;
 }
 
 static int xattr_namematch(struct xattr_iter *_it,
@@ -301,7 +343,9 @@ static int xattr_namematch(struct xattr_iter *_it,
 {
        struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it);
 
-       return memcmp(buf, it->name.name + processed, len) ? -ENOATTR : 0;
+       if (memcmp(buf, it->name.name + it->infix_len + processed, len))
+               return -ENOATTR;
+       return 0;
 }
 
 static int xattr_checkbuffer(struct xattr_iter *_it,
@@ -351,21 +395,18 @@ static int inline_getxattr(struct inode *inode, struct getxattr_iter *it)
 static int shared_getxattr(struct inode *inode, struct getxattr_iter *it)
 {
        struct erofs_inode *const vi = EROFS_I(inode);
-       struct super_block *const sb = inode->i_sb;
-       struct erofs_sb_info *const sbi = EROFS_SB(sb);
-       unsigned int i;
+       struct super_block *const sb = it->it.sb;
+       unsigned int i, xsid;
        int ret = -ENOATTR;
 
        for (i = 0; i < vi->xattr_shared_count; ++i) {
-               erofs_blk_t blkaddr =
-                       xattrblock_addr(sbi, vi->xattr_shared_xattrs[i]);
-
-               it->it.ofs = xattrblock_offset(sbi, vi->xattr_shared_xattrs[i]);
-               it->it.kaddr = erofs_read_metabuf(&it->it.buf, sb, blkaddr,
-                                                 EROFS_KMAP);
+               xsid = vi->xattr_shared_xattrs[i];
+               it->it.blkaddr = erofs_xattr_blkaddr(sb, xsid);
+               it->it.ofs = erofs_xattr_blkoff(sb, xsid);
+               it->it.kaddr = erofs_read_metabuf(&it->it.buf, sb,
+                                                 it->it.blkaddr, EROFS_KMAP);
                if (IS_ERR(it->it.kaddr))
                        return PTR_ERR(it->it.kaddr);
-               it->it.blkaddr = blkaddr;
 
                ret = xattr_foreach(&it->it, &find_xattr_handlers, NULL);
                if (ret != -ENOATTR)
@@ -394,7 +435,7 @@ int erofs_getxattr(struct inode *inode, int index,
        if (!name)
                return -EINVAL;
 
-       ret = init_inode_xattrs(inode);
+       ret = erofs_init_inode_xattrs(inode);
        if (ret)
                return ret;
 
@@ -421,20 +462,9 @@ static int erofs_xattr_generic_get(const struct xattr_handler *handler,
                                   struct dentry *unused, struct inode *inode,
                                   const char *name, void *buffer, size_t size)
 {
-       struct erofs_sb_info *const sbi = EROFS_I_SB(inode);
-
-       switch (handler->flags) {
-       case EROFS_XATTR_INDEX_USER:
-               if (!test_opt(&sbi->opt, XATTR_USER))
-                       return -EOPNOTSUPP;
-               break;
-       case EROFS_XATTR_INDEX_TRUSTED:
-               break;
-       case EROFS_XATTR_INDEX_SECURITY:
-               break;
-       default:
-               return -EINVAL;
-       }
+       if (handler->flags == EROFS_XATTR_INDEX_USER &&
+           !test_opt(&EROFS_I_SB(inode)->opt, XATTR_USER))
+               return -EOPNOTSUPP;
 
        return erofs_getxattr(inode, handler->flags, name, buffer, size);
 }
@@ -463,10 +493,6 @@ const struct xattr_handler __maybe_unused erofs_xattr_security_handler = {
 
 const struct xattr_handler *erofs_xattr_handlers[] = {
        &erofs_xattr_user_handler,
-#ifdef CONFIG_EROFS_FS_POSIX_ACL
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
-#endif
        &erofs_xattr_trusted_handler,
 #ifdef CONFIG_EROFS_FS_SECURITY
        &erofs_xattr_security_handler,
@@ -487,29 +513,40 @@ static int xattr_entrylist(struct xattr_iter *_it,
 {
        struct listxattr_iter *it =
                container_of(_it, struct listxattr_iter, it);
-       unsigned int prefix_len;
-       const char *prefix;
-
-       const struct xattr_handler *h =
-               erofs_xattr_handler(entry->e_name_index);
+       unsigned int base_index = entry->e_name_index;
+       unsigned int prefix_len, infix_len = 0;
+       const char *prefix, *infix = NULL;
+
+       if (entry->e_name_index & EROFS_XATTR_LONG_PREFIX) {
+               struct erofs_sb_info *sbi = EROFS_SB(_it->sb);
+               struct erofs_xattr_prefix_item *pf = sbi->xattr_prefixes +
+                       (entry->e_name_index & EROFS_XATTR_LONG_PREFIX_MASK);
+
+               if (pf >= sbi->xattr_prefixes + sbi->xattr_prefix_count)
+                       return 1;
+               infix = pf->prefix->infix;
+               infix_len = pf->infix_len;
+               base_index = pf->prefix->base_index;
+       }
 
-       if (!h || (h->list && !h->list(it->dentry)))
+       prefix = erofs_xattr_prefix(base_index, it->dentry);
+       if (!prefix)
                return 1;
-
-       prefix = xattr_prefix(h);
        prefix_len = strlen(prefix);
 
        if (!it->buffer) {
-               it->buffer_ofs += prefix_len + entry->e_name_len + 1;
+               it->buffer_ofs += prefix_len + infix_len +
+                                       entry->e_name_len + 1;
                return 1;
        }
 
-       if (it->buffer_ofs + prefix_len
+       if (it->buffer_ofs + prefix_len + infix_len +
                + entry->e_name_len + 1 > it->buffer_size)
                return -ERANGE;
 
        memcpy(it->buffer + it->buffer_ofs, prefix, prefix_len);
-       it->buffer_ofs += prefix_len;
+       memcpy(it->buffer + it->buffer_ofs + prefix_len, infix, infix_len);
+       it->buffer_ofs += prefix_len + infix_len;
        return 0;
 }
 
@@ -563,21 +600,18 @@ static int shared_listxattr(struct listxattr_iter *it)
 {
        struct inode *const inode = d_inode(it->dentry);
        struct erofs_inode *const vi = EROFS_I(inode);
-       struct super_block *const sb = inode->i_sb;
-       struct erofs_sb_info *const sbi = EROFS_SB(sb);
-       unsigned int i;
+       struct super_block *const sb = it->it.sb;
+       unsigned int i, xsid;
        int ret = 0;
 
        for (i = 0; i < vi->xattr_shared_count; ++i) {
-               erofs_blk_t blkaddr =
-                       xattrblock_addr(sbi, vi->xattr_shared_xattrs[i]);
-
-               it->it.ofs = xattrblock_offset(sbi, vi->xattr_shared_xattrs[i]);
-               it->it.kaddr = erofs_read_metabuf(&it->it.buf, sb, blkaddr,
-                                                 EROFS_KMAP);
+               xsid = vi->xattr_shared_xattrs[i];
+               it->it.blkaddr = erofs_xattr_blkaddr(sb, xsid);
+               it->it.ofs = erofs_xattr_blkoff(sb, xsid);
+               it->it.kaddr = erofs_read_metabuf(&it->it.buf, sb,
+                                                 it->it.blkaddr, EROFS_KMAP);
                if (IS_ERR(it->it.kaddr))
                        return PTR_ERR(it->it.kaddr);
-               it->it.blkaddr = blkaddr;
 
                ret = xattr_foreach(&it->it, &list_xattr_handlers, NULL);
                if (ret)
@@ -592,7 +626,7 @@ ssize_t erofs_listxattr(struct dentry *dentry,
        int ret;
        struct listxattr_iter it;
 
-       ret = init_inode_xattrs(d_inode(dentry));
+       ret = erofs_init_inode_xattrs(d_inode(dentry));
        if (ret == -ENOATTR)
                return 0;
        if (ret)
@@ -613,6 +647,62 @@ ssize_t erofs_listxattr(struct dentry *dentry,
        return ret;
 }
 
+void erofs_xattr_prefixes_cleanup(struct super_block *sb)
+{
+       struct erofs_sb_info *sbi = EROFS_SB(sb);
+       int i;
+
+       if (sbi->xattr_prefixes) {
+               for (i = 0; i < sbi->xattr_prefix_count; i++)
+                       kfree(sbi->xattr_prefixes[i].prefix);
+               kfree(sbi->xattr_prefixes);
+               sbi->xattr_prefixes = NULL;
+       }
+}
+
+int erofs_xattr_prefixes_init(struct super_block *sb)
+{
+       struct erofs_sb_info *sbi = EROFS_SB(sb);
+       struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
+       erofs_off_t pos = (erofs_off_t)sbi->xattr_prefix_start << 2;
+       struct erofs_xattr_prefix_item *pfs;
+       int ret = 0, i, len;
+
+       if (!sbi->xattr_prefix_count)
+               return 0;
+
+       pfs = kzalloc(sbi->xattr_prefix_count * sizeof(*pfs), GFP_KERNEL);
+       if (!pfs)
+               return -ENOMEM;
+
+       if (erofs_sb_has_fragments(sbi))
+               buf.inode = sbi->packed_inode;
+       else
+               erofs_init_metabuf(&buf, sb);
+
+       for (i = 0; i < sbi->xattr_prefix_count; i++) {
+               void *ptr = erofs_read_metadata(sb, &buf, &pos, &len);
+
+               if (IS_ERR(ptr)) {
+                       ret = PTR_ERR(ptr);
+                       break;
+               } else if (len < sizeof(*pfs->prefix) ||
+                          len > EROFS_NAME_LEN + sizeof(*pfs->prefix)) {
+                       kfree(ptr);
+                       ret = -EFSCORRUPTED;
+                       break;
+               }
+               pfs[i].prefix = ptr;
+               pfs[i].infix_len = len - sizeof(struct erofs_xattr_long_prefix);
+       }
+
+       erofs_put_metabuf(&buf);
+       sbi->xattr_prefixes = pfs;
+       if (ret)
+               erofs_xattr_prefixes_cleanup(sb);
+       return ret;
+}
+
 #ifdef CONFIG_EROFS_FS_POSIX_ACL
 struct posix_acl *erofs_get_acl(struct inode *inode, int type, bool rcu)
 {
index 0a43c9ee9f8f3ba8d7cf999d90d39f435c78cfbf..f16283cb8c9301c1f0ce81d5bd321ca4c04d8c72 100644 (file)
 /* Attribute not found */
 #define ENOATTR         ENODATA
 
-static inline unsigned int inlinexattr_header_size(struct inode *inode)
-{
-       return sizeof(struct erofs_xattr_ibody_header) +
-               sizeof(u32) * EROFS_I(inode)->xattr_shared_count;
-}
-
-static inline erofs_blk_t xattrblock_addr(struct erofs_sb_info *sbi,
-                                         unsigned int xattr_id)
-{
-#ifdef CONFIG_EROFS_FS_XATTR
-       return sbi->xattr_blkaddr +
-               xattr_id * sizeof(__u32) / EROFS_BLKSIZ;
-#else
-       return 0;
-#endif
-}
-
-static inline unsigned int xattrblock_offset(struct erofs_sb_info *sbi,
-                                            unsigned int xattr_id)
-{
-       return (xattr_id * sizeof(__u32)) % EROFS_BLKSIZ;
-}
-
 #ifdef CONFIG_EROFS_FS_XATTR
 extern const struct xattr_handler erofs_xattr_user_handler;
 extern const struct xattr_handler erofs_xattr_trusted_handler;
 extern const struct xattr_handler erofs_xattr_security_handler;
 
-static inline const struct xattr_handler *erofs_xattr_handler(unsigned int idx)
+static inline const char *erofs_xattr_prefix(unsigned int idx,
+                                            struct dentry *dentry)
 {
+       const struct xattr_handler *handler = NULL;
+
        static const struct xattr_handler *xattr_handler_map[] = {
                [EROFS_XATTR_INDEX_USER] = &erofs_xattr_user_handler,
 #ifdef CONFIG_EROFS_FS_POSIX_ACL
-               [EROFS_XATTR_INDEX_POSIX_ACL_ACCESS] =
-                       &posix_acl_access_xattr_handler,
-               [EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT] =
-                       &posix_acl_default_xattr_handler,
+               [EROFS_XATTR_INDEX_POSIX_ACL_ACCESS] = &nop_posix_acl_access,
+               [EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &nop_posix_acl_default,
 #endif
                [EROFS_XATTR_INDEX_TRUSTED] = &erofs_xattr_trusted_handler,
 #ifdef CONFIG_EROFS_FS_SECURITY
@@ -57,15 +35,24 @@ static inline const struct xattr_handler *erofs_xattr_handler(unsigned int idx)
 #endif
        };
 
-       return idx && idx < ARRAY_SIZE(xattr_handler_map) ?
-               xattr_handler_map[idx] : NULL;
+       if (idx && idx < ARRAY_SIZE(xattr_handler_map))
+               handler = xattr_handler_map[idx];
+
+       if (!xattr_handler_can_list(handler, dentry))
+               return NULL;
+
+       return xattr_prefix(handler);
 }
 
 extern const struct xattr_handler *erofs_xattr_handlers[];
 
+int erofs_xattr_prefixes_init(struct super_block *sb);
+void erofs_xattr_prefixes_cleanup(struct super_block *sb);
 int erofs_getxattr(struct inode *, int, const char *, void *, size_t);
 ssize_t erofs_listxattr(struct dentry *, char *, size_t);
 #else
+static inline int erofs_xattr_prefixes_init(struct super_block *sb) { return 0; }
+static inline void erofs_xattr_prefixes_cleanup(struct super_block *sb) {}
 static inline int erofs_getxattr(struct inode *inode, int index,
                                 const char *name, void *buffer,
                                 size_t buffer_size)
index 3247d2422beae75d71d95345287d78135e5bc50f..45f21db2303a9d72b606c92d5783cb724b5d5705 100644 (file)
@@ -807,7 +807,7 @@ static int z_erofs_register_pcluster(struct z_erofs_decompress_frontend *fe)
 
        if (ztailpacking) {
                pcl->obj.index = 0;     /* which indicates ztailpacking */
-               pcl->pageofs_in = erofs_blkoff(map->m_pa);
+               pcl->pageofs_in = erofs_blkoff(fe->inode->i_sb, map->m_pa);
                pcl->tailpacking_size = map->m_plen;
        } else {
                pcl->obj.index = map->m_pa >> PAGE_SHIFT;
@@ -930,6 +930,7 @@ static int z_erofs_read_fragment(struct inode *inode, erofs_off_t pos,
                                 struct page *page, unsigned int pageofs,
                                 unsigned int len)
 {
+       struct super_block *sb = inode->i_sb;
        struct inode *packed_inode = EROFS_I_SB(inode)->packed_inode;
        struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
        u8 *src, *dst;
@@ -938,19 +939,19 @@ static int z_erofs_read_fragment(struct inode *inode, erofs_off_t pos,
        if (!packed_inode)
                return -EFSCORRUPTED;
 
+       buf.inode = packed_inode;
        pos += EROFS_I(inode)->z_fragmentoff;
        for (i = 0; i < len; i += cnt) {
                cnt = min_t(unsigned int, len - i,
-                           EROFS_BLKSIZ - erofs_blkoff(pos));
-               src = erofs_bread(&buf, packed_inode,
-                                 erofs_blknr(pos), EROFS_KMAP);
+                           sb->s_blocksize - erofs_blkoff(sb, pos));
+               src = erofs_bread(&buf, erofs_blknr(sb, pos), EROFS_KMAP);
                if (IS_ERR(src)) {
                        erofs_put_metabuf(&buf);
                        return PTR_ERR(src);
                }
 
                dst = kmap_local_page(page);
-               memcpy(dst + pageofs + i, src + erofs_blkoff(pos), cnt);
+               memcpy(dst + pageofs + i, src + erofs_blkoff(sb, pos), cnt);
                kunmap_local(dst);
                pos += cnt;
        }
@@ -978,8 +979,6 @@ repeat:
 
        if (offset + cur < map->m_la ||
            offset + cur >= map->m_la + map->m_llen) {
-               erofs_dbg("out-of-range map @ pos %llu", offset + cur);
-
                if (z_erofs_collector_end(fe))
                        fe->backmost = false;
                map->m_la = offset + cur;
@@ -1005,7 +1004,8 @@ repeat:
                void *mp;
 
                mp = erofs_read_metabuf(&fe->map.buf, inode->i_sb,
-                                       erofs_blknr(map->m_pa), EROFS_NO_KMAP);
+                                       erofs_blknr(inode->i_sb, map->m_pa),
+                                       EROFS_NO_KMAP);
                if (IS_ERR(mp)) {
                        err = PTR_ERR(mp);
                        erofs_err(inode->i_sb,
@@ -1103,9 +1103,6 @@ out:
        if (err)
                z_erofs_page_mark_eio(page);
        z_erofs_onlinepage_endio(page);
-
-       erofs_dbg("%s, finish page: %pK spiltted: %u map->m_llen %llu",
-                 __func__, page, spiltted, map->m_llen);
        return err;
 }
 
@@ -1312,12 +1309,12 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be,
 
        if (!be->decompressed_pages)
                be->decompressed_pages =
-                       kcalloc(be->nr_pages, sizeof(struct page *),
-                               GFP_KERNEL | __GFP_NOFAIL);
+                       kvcalloc(be->nr_pages, sizeof(struct page *),
+                                GFP_KERNEL | __GFP_NOFAIL);
        if (!be->compressed_pages)
                be->compressed_pages =
-                       kcalloc(pclusterpages, sizeof(struct page *),
-                               GFP_KERNEL | __GFP_NOFAIL);
+                       kvcalloc(pclusterpages, sizeof(struct page *),
+                                GFP_KERNEL | __GFP_NOFAIL);
 
        z_erofs_parse_out_bvecs(be);
        err2 = z_erofs_parse_in_bvecs(be, &overlapped);
@@ -1365,7 +1362,7 @@ out:
        }
        if (be->compressed_pages < be->onstack_pages ||
            be->compressed_pages >= be->onstack_pages + Z_EROFS_ONSTACK_PAGES)
-               kfree(be->compressed_pages);
+               kvfree(be->compressed_pages);
        z_erofs_fill_other_copies(be, err);
 
        for (i = 0; i < be->nr_pages; ++i) {
@@ -1384,7 +1381,7 @@ out:
        }
 
        if (be->decompressed_pages != be->onstack_pages)
-               kfree(be->decompressed_pages);
+               kvfree(be->decompressed_pages);
 
        pcl->length = 0;
        pcl->partial = true;
@@ -1726,11 +1723,11 @@ static void z_erofs_submit_queue(struct z_erofs_decompress_frontend *f,
 
                /* no device id here, thus it will always succeed */
                mdev = (struct erofs_map_dev) {
-                       .m_pa = blknr_to_addr(pcl->obj.index),
+                       .m_pa = erofs_pos(sb, pcl->obj.index),
                };
                (void)erofs_map_dev(sb, &mdev);
 
-               cur = erofs_blknr(mdev.m_pa);
+               cur = erofs_blknr(sb, mdev.m_pa);
                end = cur + pcl->pclusterpages;
 
                do {
@@ -1764,7 +1761,7 @@ submit_bio_retry:
 
                                last_bdev = mdev.m_bdev;
                                bio->bi_iter.bi_sector = (sector_t)cur <<
-                                       LOG_SECTORS_PER_BLOCK;
+                                       (sb->s_blocksize_bits - 9);
                                bio->bi_private = q[JQ_SUBMIT];
                                if (f->readahead)
                                        bio->bi_opf |= REQ_RAHEAD;
index 8bf6d30518b64834de5e3c859825f3680efc675d..d37c5c89c72878b416159e8680e58831ad9fd3d9 100644 (file)
@@ -7,24 +7,6 @@
 #include <asm/unaligned.h>
 #include <trace/events/erofs.h>
 
-int z_erofs_fill_inode(struct inode *inode)
-{
-       struct erofs_inode *const vi = EROFS_I(inode);
-       struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb);
-
-       if (!erofs_sb_has_big_pcluster(sbi) &&
-           !erofs_sb_has_ztailpacking(sbi) && !erofs_sb_has_fragments(sbi) &&
-           vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY) {
-               vi->z_advise = 0;
-               vi->z_algorithmtype[0] = 0;
-               vi->z_algorithmtype[1] = 0;
-               vi->z_logical_clusterbits = LOG_BLOCK_SIZE;
-               set_bit(EROFS_I_Z_INITED_BIT, &vi->flags);
-       }
-       inode->i_mapping->a_ops = &z_erofs_aops;
-       return 0;
-}
-
 struct z_erofs_maprecorder {
        struct inode *inode;
        struct erofs_map_blocks *map;
@@ -45,47 +27,50 @@ static int legacy_load_cluster_from_disk(struct z_erofs_maprecorder *m,
 {
        struct inode *const inode = m->inode;
        struct erofs_inode *const vi = EROFS_I(inode);
-       const erofs_off_t pos =
-               Z_EROFS_VLE_LEGACY_INDEX_ALIGN(erofs_iloc(inode) +
-                               vi->inode_isize + vi->xattr_isize) +
-               lcn * sizeof(struct z_erofs_vle_decompressed_index);
-       struct z_erofs_vle_decompressed_index *di;
+       const erofs_off_t pos = Z_EROFS_FULL_INDEX_ALIGN(erofs_iloc(inode) +
+                       vi->inode_isize + vi->xattr_isize) +
+                       lcn * sizeof(struct z_erofs_lcluster_index);
+       struct z_erofs_lcluster_index *di;
        unsigned int advise, type;
 
        m->kaddr = erofs_read_metabuf(&m->map->buf, inode->i_sb,
-                                     erofs_blknr(pos), EROFS_KMAP);
+                                     erofs_blknr(inode->i_sb, pos), EROFS_KMAP);
        if (IS_ERR(m->kaddr))
                return PTR_ERR(m->kaddr);
 
-       m->nextpackoff = pos + sizeof(struct z_erofs_vle_decompressed_index);
+       m->nextpackoff = pos + sizeof(struct z_erofs_lcluster_index);
        m->lcn = lcn;
-       di = m->kaddr + erofs_blkoff(pos);
+       di = m->kaddr + erofs_blkoff(inode->i_sb, pos);
 
        advise = le16_to_cpu(di->di_advise);
-       type = (advise >> Z_EROFS_VLE_DI_CLUSTER_TYPE_BIT) &
-               ((1 << Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS) - 1);
+       type = (advise >> Z_EROFS_LI_LCLUSTER_TYPE_BIT) &
+               ((1 << Z_EROFS_LI_LCLUSTER_TYPE_BITS) - 1);
        switch (type) {
-       case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
+       case Z_EROFS_LCLUSTER_TYPE_NONHEAD:
                m->clusterofs = 1 << vi->z_logical_clusterbits;
                m->delta[0] = le16_to_cpu(di->di_u.delta[0]);
-               if (m->delta[0] & Z_EROFS_VLE_DI_D0_CBLKCNT) {
+               if (m->delta[0] & Z_EROFS_LI_D0_CBLKCNT) {
                        if (!(vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 |
                                        Z_EROFS_ADVISE_BIG_PCLUSTER_2))) {
                                DBG_BUGON(1);
                                return -EFSCORRUPTED;
                        }
                        m->compressedblks = m->delta[0] &
-                               ~Z_EROFS_VLE_DI_D0_CBLKCNT;
+                               ~Z_EROFS_LI_D0_CBLKCNT;
                        m->delta[0] = 1;
                }
                m->delta[1] = le16_to_cpu(di->di_u.delta[1]);
                break;
-       case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
-       case Z_EROFS_VLE_CLUSTER_TYPE_HEAD1:
-       case Z_EROFS_VLE_CLUSTER_TYPE_HEAD2:
-               if (advise & Z_EROFS_VLE_DI_PARTIAL_REF)
+       case Z_EROFS_LCLUSTER_TYPE_PLAIN:
+       case Z_EROFS_LCLUSTER_TYPE_HEAD1:
+       case Z_EROFS_LCLUSTER_TYPE_HEAD2:
+               if (advise & Z_EROFS_LI_PARTIAL_REF)
                        m->partialref = true;
                m->clusterofs = le16_to_cpu(di->di_clusterofs);
+               if (m->clusterofs >= 1 << vi->z_logical_clusterbits) {
+                       DBG_BUGON(1);
+                       return -EFSCORRUPTED;
+               }
                m->pblk = le32_to_cpu(di->di_u.blkaddr);
                break;
        default:
@@ -121,13 +106,13 @@ static int get_compacted_la_distance(unsigned int lclusterbits,
                lo = decode_compactedbits(lclusterbits, lomask,
                                          in, encodebits * i, &type);
 
-               if (type != Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD)
+               if (type != Z_EROFS_LCLUSTER_TYPE_NONHEAD)
                        return d1;
                ++d1;
        } while (++i < vcnt);
 
-       /* vcnt - 1 (Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) item */
-       if (!(lo & Z_EROFS_VLE_DI_D0_CBLKCNT))
+       /* vcnt - 1 (Z_EROFS_LCLUSTER_TYPE_NONHEAD) item */
+       if (!(lo & Z_EROFS_LI_D0_CBLKCNT))
                d1 += lo - 1;
        return d1;
 }
@@ -156,7 +141,7 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
                         (vcnt << amortizedshift);
        big_pcluster = vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1;
        encodebits = ((vcnt << amortizedshift) - sizeof(__le32)) * 8 / vcnt;
-       eofs = erofs_blkoff(pos);
+       eofs = erofs_blkoff(m->inode->i_sb, pos);
        base = round_down(eofs, vcnt << amortizedshift);
        in = m->kaddr + base;
 
@@ -165,19 +150,19 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
        lo = decode_compactedbits(lclusterbits, lomask,
                                  in, encodebits * i, &type);
        m->type = type;
-       if (type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) {
+       if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
                m->clusterofs = 1 << lclusterbits;
 
                /* figure out lookahead_distance: delta[1] if needed */
                if (lookahead)
                        m->delta[1] = get_compacted_la_distance(lclusterbits,
                                                encodebits, vcnt, in, i);
-               if (lo & Z_EROFS_VLE_DI_D0_CBLKCNT) {
+               if (lo & Z_EROFS_LI_D0_CBLKCNT) {
                        if (!big_pcluster) {
                                DBG_BUGON(1);
                                return -EFSCORRUPTED;
                        }
-                       m->compressedblks = lo & ~Z_EROFS_VLE_DI_D0_CBLKCNT;
+                       m->compressedblks = lo & ~Z_EROFS_LI_D0_CBLKCNT;
                        m->delta[0] = 1;
                        return 0;
                } else if (i + 1 != (int)vcnt) {
@@ -191,9 +176,9 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
                 */
                lo = decode_compactedbits(lclusterbits, lomask,
                                          in, encodebits * (i - 1), &type);
-               if (type != Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD)
+               if (type != Z_EROFS_LCLUSTER_TYPE_NONHEAD)
                        lo = 0;
-               else if (lo & Z_EROFS_VLE_DI_D0_CBLKCNT)
+               else if (lo & Z_EROFS_LI_D0_CBLKCNT)
                        lo = 1;
                m->delta[0] = lo + 1;
                return 0;
@@ -207,7 +192,7 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
                        --i;
                        lo = decode_compactedbits(lclusterbits, lomask,
                                                  in, encodebits * i, &type);
-                       if (type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD)
+                       if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD)
                                i -= lo;
 
                        if (i >= 0)
@@ -219,10 +204,10 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
                        --i;
                        lo = decode_compactedbits(lclusterbits, lomask,
                                                  in, encodebits * i, &type);
-                       if (type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) {
-                               if (lo & Z_EROFS_VLE_DI_D0_CBLKCNT) {
+                       if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
+                               if (lo & Z_EROFS_LI_D0_CBLKCNT) {
                                        --i;
-                                       nblk += lo & ~Z_EROFS_VLE_DI_D0_CBLKCNT;
+                                       nblk += lo & ~Z_EROFS_LI_D0_CBLKCNT;
                                        continue;
                                }
                                /* bigpcluster shouldn't have plain d0 == 1 */
@@ -249,7 +234,7 @@ static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m,
        const unsigned int lclusterbits = vi->z_logical_clusterbits;
        const erofs_off_t ebase = sizeof(struct z_erofs_map_header) +
                ALIGN(erofs_iloc(inode) + vi->inode_isize + vi->xattr_isize, 8);
-       const unsigned int totalidx = DIV_ROUND_UP(inode->i_size, EROFS_BLKSIZ);
+       unsigned int totalidx = erofs_iblks(inode);
        unsigned int compacted_4b_initial, compacted_2b;
        unsigned int amortizedshift;
        erofs_off_t pos;
@@ -290,7 +275,7 @@ static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m,
 out:
        pos += lcn * (1 << amortizedshift);
        m->kaddr = erofs_read_metabuf(&m->map->buf, inode->i_sb,
-                                     erofs_blknr(pos), EROFS_KMAP);
+                                     erofs_blknr(inode->i_sb, pos), EROFS_KMAP);
        if (IS_ERR(m->kaddr))
                return PTR_ERR(m->kaddr);
        return unpack_compacted_index(m, amortizedshift, pos, lookahead);
@@ -301,10 +286,10 @@ static int z_erofs_load_cluster_from_disk(struct z_erofs_maprecorder *m,
 {
        const unsigned int datamode = EROFS_I(m->inode)->datalayout;
 
-       if (datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY)
+       if (datamode == EROFS_INODE_COMPRESSED_FULL)
                return legacy_load_cluster_from_disk(m, lcn);
 
-       if (datamode == EROFS_INODE_FLAT_COMPRESSION)
+       if (datamode == EROFS_INODE_COMPRESSED_COMPACT)
                return compacted_load_cluster_from_disk(m, lcn, lookahead);
 
        return -EINVAL;
@@ -326,7 +311,7 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
                        return err;
 
                switch (m->type) {
-               case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
+               case Z_EROFS_LCLUSTER_TYPE_NONHEAD:
                        if (!m->delta[0]) {
                                erofs_err(m->inode->i_sb,
                                          "invalid lookback distance 0 @ nid %llu",
@@ -336,9 +321,9 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
                        }
                        lookback_distance = m->delta[0];
                        continue;
-               case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
-               case Z_EROFS_VLE_CLUSTER_TYPE_HEAD1:
-               case Z_EROFS_VLE_CLUSTER_TYPE_HEAD2:
+               case Z_EROFS_LCLUSTER_TYPE_PLAIN:
+               case Z_EROFS_LCLUSTER_TYPE_HEAD1:
+               case Z_EROFS_LCLUSTER_TYPE_HEAD2:
                        m->headtype = m->type;
                        m->map->m_la = (lcn << lclusterbits) | m->clusterofs;
                        return 0;
@@ -360,21 +345,22 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
 static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
                                            unsigned int initial_lcn)
 {
+       struct super_block *sb = m->inode->i_sb;
        struct erofs_inode *const vi = EROFS_I(m->inode);
        struct erofs_map_blocks *const map = m->map;
        const unsigned int lclusterbits = vi->z_logical_clusterbits;
        unsigned long lcn;
        int err;
 
-       DBG_BUGON(m->type != Z_EROFS_VLE_CLUSTER_TYPE_PLAIN &&
-                 m->type != Z_EROFS_VLE_CLUSTER_TYPE_HEAD1 &&
-                 m->type != Z_EROFS_VLE_CLUSTER_TYPE_HEAD2);
+       DBG_BUGON(m->type != Z_EROFS_LCLUSTER_TYPE_PLAIN &&
+                 m->type != Z_EROFS_LCLUSTER_TYPE_HEAD1 &&
+                 m->type != Z_EROFS_LCLUSTER_TYPE_HEAD2);
        DBG_BUGON(m->type != m->headtype);
 
-       if (m->headtype == Z_EROFS_VLE_CLUSTER_TYPE_PLAIN ||
-           ((m->headtype == Z_EROFS_VLE_CLUSTER_TYPE_HEAD1) &&
+       if (m->headtype == Z_EROFS_LCLUSTER_TYPE_PLAIN ||
+           ((m->headtype == Z_EROFS_LCLUSTER_TYPE_HEAD1) &&
             !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1)) ||
-           ((m->headtype == Z_EROFS_VLE_CLUSTER_TYPE_HEAD2) &&
+           ((m->headtype == Z_EROFS_LCLUSTER_TYPE_HEAD2) &&
             !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2))) {
                map->m_plen = 1ULL << lclusterbits;
                return 0;
@@ -396,19 +382,19 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
         * BUG_ON in the debugging mode only for developers to notice that.
         */
        DBG_BUGON(lcn == initial_lcn &&
-                 m->type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD);
+                 m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD);
 
        switch (m->type) {
-       case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
-       case Z_EROFS_VLE_CLUSTER_TYPE_HEAD1:
-       case Z_EROFS_VLE_CLUSTER_TYPE_HEAD2:
+       case Z_EROFS_LCLUSTER_TYPE_PLAIN:
+       case Z_EROFS_LCLUSTER_TYPE_HEAD1:
+       case Z_EROFS_LCLUSTER_TYPE_HEAD2:
                /*
                 * if the 1st NONHEAD lcluster is actually PLAIN or HEAD type
                 * rather than CBLKCNT, it's a 1 lcluster-sized pcluster.
                 */
-               m->compressedblks = 1 << (lclusterbits - LOG_BLOCK_SIZE);
+               m->compressedblks = 1 << (lclusterbits - sb->s_blocksize_bits);
                break;
-       case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
+       case Z_EROFS_LCLUSTER_TYPE_NONHEAD:
                if (m->delta[0] != 1)
                        goto err_bonus_cblkcnt;
                if (m->compressedblks)
@@ -422,7 +408,7 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
                return -EFSCORRUPTED;
        }
 out:
-       map->m_plen = (u64)m->compressedblks << LOG_BLOCK_SIZE;
+       map->m_plen = erofs_pos(sb, m->compressedblks);
        return 0;
 err_bonus_cblkcnt:
        erofs_err(m->inode->i_sb,
@@ -452,12 +438,12 @@ static int z_erofs_get_extent_decompressedlen(struct z_erofs_maprecorder *m)
                if (err)
                        return err;
 
-               if (m->type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) {
+               if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
                        DBG_BUGON(!m->delta[1] &&
                                  m->clusterofs != 1 << lclusterbits);
-               } else if (m->type == Z_EROFS_VLE_CLUSTER_TYPE_PLAIN ||
-                          m->type == Z_EROFS_VLE_CLUSTER_TYPE_HEAD1 ||
-                          m->type == Z_EROFS_VLE_CLUSTER_TYPE_HEAD2) {
+               } else if (m->type == Z_EROFS_LCLUSTER_TYPE_PLAIN ||
+                          m->type == Z_EROFS_LCLUSTER_TYPE_HEAD1 ||
+                          m->type == Z_EROFS_LCLUSTER_TYPE_HEAD2) {
                        /* go on until the next HEAD lcluster */
                        if (lcn != headlcn)
                                break;
@@ -476,8 +462,7 @@ static int z_erofs_get_extent_decompressedlen(struct z_erofs_maprecorder *m)
 }
 
 static int z_erofs_do_map_blocks(struct inode *inode,
-                                struct erofs_map_blocks *map,
-                                int flags)
+                                struct erofs_map_blocks *map, int flags)
 {
        struct erofs_inode *const vi = EROFS_I(inode);
        bool ztailpacking = vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER;
@@ -507,9 +492,9 @@ static int z_erofs_do_map_blocks(struct inode *inode,
        end = (m.lcn + 1ULL) << lclusterbits;
 
        switch (m.type) {
-       case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
-       case Z_EROFS_VLE_CLUSTER_TYPE_HEAD1:
-       case Z_EROFS_VLE_CLUSTER_TYPE_HEAD2:
+       case Z_EROFS_LCLUSTER_TYPE_PLAIN:
+       case Z_EROFS_LCLUSTER_TYPE_HEAD1:
+       case Z_EROFS_LCLUSTER_TYPE_HEAD2:
                if (endoff >= m.clusterofs) {
                        m.headtype = m.type;
                        map->m_la = (m.lcn << lclusterbits) | m.clusterofs;
@@ -534,7 +519,7 @@ static int z_erofs_do_map_blocks(struct inode *inode,
                map->m_flags |= EROFS_MAP_FULL_MAPPED;
                m.delta[0] = 1;
                fallthrough;
-       case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
+       case Z_EROFS_LCLUSTER_TYPE_NONHEAD:
                /* get the corresponding first chunk */
                err = z_erofs_extent_lookback(&m, m.delta[0]);
                if (err)
@@ -555,7 +540,7 @@ static int z_erofs_do_map_blocks(struct inode *inode,
                vi->z_tailextent_headlcn = m.lcn;
                /* for non-compact indexes, fragmentoff is 64 bits */
                if (fragment &&
-                   vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY)
+                   vi->datalayout == EROFS_INODE_COMPRESSED_FULL)
                        vi->z_fragmentoff |= (u64)m.pblk << 32;
        }
        if (ztailpacking && m.lcn == vi->z_tailextent_headlcn) {
@@ -565,13 +550,13 @@ static int z_erofs_do_map_blocks(struct inode *inode,
        } else if (fragment && m.lcn == vi->z_tailextent_headlcn) {
                map->m_flags |= EROFS_MAP_FRAGMENT;
        } else {
-               map->m_pa = blknr_to_addr(m.pblk);
+               map->m_pa = erofs_pos(inode->i_sb, m.pblk);
                err = z_erofs_get_extent_compressedlen(&m, initial_lcn);
                if (err)
                        goto unmap_out;
        }
 
-       if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_PLAIN) {
+       if (m.headtype == Z_EROFS_LCLUSTER_TYPE_PLAIN) {
                if (map->m_llen > map->m_plen) {
                        DBG_BUGON(1);
                        err = -EFSCORRUPTED;
@@ -583,7 +568,7 @@ static int z_erofs_do_map_blocks(struct inode *inode,
                else
                        map->m_algorithmformat =
                                Z_EROFS_COMPRESSION_SHIFTED;
-       } else if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_HEAD2) {
+       } else if (m.headtype == Z_EROFS_LCLUSTER_TYPE_HEAD2) {
                map->m_algorithmformat = vi->z_algorithmtype[1];
        } else {
                map->m_algorithmformat = vi->z_algorithmtype[0];
@@ -592,7 +577,7 @@ static int z_erofs_do_map_blocks(struct inode *inode,
        if ((flags & EROFS_GET_BLOCKS_FIEMAP) ||
            ((flags & EROFS_GET_BLOCKS_READMORE) &&
             map->m_algorithmformat == Z_EROFS_COMPRESSION_LZMA &&
-            map->m_llen >= EROFS_BLKSIZ)) {
+            map->m_llen >= i_blocksize(inode))) {
                err = z_erofs_get_extent_decompressedlen(&m);
                if (!err)
                        map->m_flags |= EROFS_MAP_FULL_MAPPED;
@@ -600,9 +585,6 @@ static int z_erofs_do_map_blocks(struct inode *inode,
 
 unmap_out:
        erofs_unmap_metabuf(&m.map->buf);
-       erofs_dbg("%s, m_la %llu m_pa %llu m_llen %llu m_plen %llu m_flags 0%o",
-                 __func__, map->m_la, map->m_pa,
-                 map->m_llen, map->m_plen, map->m_flags);
        return err;
 }
 
@@ -633,13 +615,13 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
                goto out_unlock;
 
        pos = ALIGN(erofs_iloc(inode) + vi->inode_isize + vi->xattr_isize, 8);
-       kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos), EROFS_KMAP);
+       kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(sb, pos), EROFS_KMAP);
        if (IS_ERR(kaddr)) {
                err = PTR_ERR(kaddr);
                goto out_unlock;
        }
 
-       h = kaddr + erofs_blkoff(pos);
+       h = kaddr + erofs_blkoff(sb, pos);
        /*
         * if the highest bit of the 8-byte map header is set, the whole file
         * is stored in the packed inode. The rest bits keeps z_fragmentoff.
@@ -663,7 +645,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
                goto out_put_metabuf;
        }
 
-       vi->z_logical_clusterbits = LOG_BLOCK_SIZE + (h->h_clusterbits & 7);
+       vi->z_logical_clusterbits = sb->s_blocksize_bits + (h->h_clusterbits & 7);
        if (!erofs_sb_has_big_pcluster(EROFS_SB(sb)) &&
            vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 |
                            Z_EROFS_ADVISE_BIG_PCLUSTER_2)) {
@@ -672,7 +654,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
                err = -EFSCORRUPTED;
                goto out_put_metabuf;
        }
-       if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION &&
+       if (vi->datalayout == EROFS_INODE_COMPRESSED_COMPACT &&
            !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^
            !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2)) {
                erofs_err(sb, "big pcluster head1/2 of compact indexes should be consistent for nid %llu",
@@ -692,7 +674,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
                erofs_put_metabuf(&map.buf);
 
                if (!map.m_plen ||
-                   erofs_blkoff(map.m_pa) + map.m_plen > EROFS_BLKSIZ) {
+                   erofs_blkoff(sb, map.m_pa) + map.m_plen > sb->s_blocksize) {
                        erofs_err(sb, "invalid tail-packing pclustersize %llu",
                                  map.m_plen);
                        err = -EFSCORRUPTED;
@@ -757,9 +739,6 @@ int z_erofs_map_blocks_iter(struct inode *inode, struct erofs_map_blocks *map,
        err = z_erofs_do_map_blocks(inode, map, flags);
 out:
        trace_z_erofs_map_blocks_iter_exit(inode, map, flags, err);
-
-       /* aggressively BUG_ON iff CONFIG_EROFS_FS_DEBUG is on */
-       DBG_BUGON(err < 0 && err != -ENOMEM);
        return err;
 }
 
index 249ca6c0b7843ff1fa9d102ad14c15e54c0ad578..95850a13ce8d01a79658a7c04748f12914d6a199 100644 (file)
@@ -228,7 +228,6 @@ static ssize_t eventfd_read(struct kiocb *iocb, struct iov_iter *to)
        struct file *file = iocb->ki_filp;
        struct eventfd_ctx *ctx = file->private_data;
        __u64 ucnt = 0;
-       DECLARE_WAITQUEUE(wait, current);
 
        if (iov_iter_count(to) < sizeof(ucnt))
                return -EINVAL;
@@ -239,23 +238,11 @@ static ssize_t eventfd_read(struct kiocb *iocb, struct iov_iter *to)
                        spin_unlock_irq(&ctx->wqh.lock);
                        return -EAGAIN;
                }
-               __add_wait_queue(&ctx->wqh, &wait);
-               for (;;) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       if (ctx->count)
-                               break;
-                       if (signal_pending(current)) {
-                               __remove_wait_queue(&ctx->wqh, &wait);
-                               __set_current_state(TASK_RUNNING);
-                               spin_unlock_irq(&ctx->wqh.lock);
-                               return -ERESTARTSYS;
-                       }
+
+               if (wait_event_interruptible_locked_irq(ctx->wqh, ctx->count)) {
                        spin_unlock_irq(&ctx->wqh.lock);
-                       schedule();
-                       spin_lock_irq(&ctx->wqh.lock);
+                       return -ERESTARTSYS;
                }
-               __remove_wait_queue(&ctx->wqh, &wait);
-               __set_current_state(TASK_RUNNING);
        }
        eventfd_ctx_do_read(ctx, &ucnt);
        current->in_eventfd = 1;
@@ -275,7 +262,6 @@ static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t c
        struct eventfd_ctx *ctx = file->private_data;
        ssize_t res;
        __u64 ucnt;
-       DECLARE_WAITQUEUE(wait, current);
 
        if (count < sizeof(ucnt))
                return -EINVAL;
@@ -288,23 +274,10 @@ static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t c
        if (ULLONG_MAX - ctx->count > ucnt)
                res = sizeof(ucnt);
        else if (!(file->f_flags & O_NONBLOCK)) {
-               __add_wait_queue(&ctx->wqh, &wait);
-               for (res = 0;;) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       if (ULLONG_MAX - ctx->count > ucnt) {
-                               res = sizeof(ucnt);
-                               break;
-                       }
-                       if (signal_pending(current)) {
-                               res = -ERESTARTSYS;
-                               break;
-                       }
-                       spin_unlock_irq(&ctx->wqh.lock);
-                       schedule();
-                       spin_lock_irq(&ctx->wqh.lock);
-               }
-               __remove_wait_queue(&ctx->wqh, &wait);
-               __set_current_state(TASK_RUNNING);
+               res = wait_event_interruptible_locked_irq(ctx->wqh,
+                               ULLONG_MAX - ctx->count > ucnt);
+               if (!res)
+                       res = sizeof(ucnt);
        }
        if (likely(res > 0)) {
                ctx->count += ucnt;
index 64659b110973339dbbbbf061a2107e3a7246916b..f6d25050dd7aac42ab1dd59799a05827f2fd7e37 100644 (file)
@@ -483,8 +483,8 @@ static inline void ep_set_busy_poll_napi_id(struct epitem *epi)
  * (efd1) notices that it may have some event ready, so it needs to wake up
  * the waiters on its poll wait list (efd2). So it calls ep_poll_safewake()
  * that ends up in another wake_up(), after having checked about the
- * recursion constraints. That are, no more than EP_MAX_POLLWAKE_NESTS, to
- * avoid stack blasting.
+ * recursion constraints. That are, no more than EP_MAX_NESTS, to avoid
+ * stack blasting.
  *
  * When CONFIG_DEBUG_LOCK_ALLOC is enabled, make sure lockdep can handle
  * this special case of epoll.
index 641abfa4b718a4c0f1b7fc06618f13201a35e36b..b126af5f8b15211a20f95c44561902d9a29ea2fd 100644 (file)
@@ -101,8 +101,8 @@ static void ext2_xattr_rehash(struct ext2_xattr_header *,
 static const struct xattr_handler *ext2_xattr_handler_map[] = {
        [EXT2_XATTR_INDEX_USER]              = &ext2_xattr_user_handler,
 #ifdef CONFIG_EXT2_FS_POSIX_ACL
-       [EXT2_XATTR_INDEX_POSIX_ACL_ACCESS]  = &posix_acl_access_xattr_handler,
-       [EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT] = &posix_acl_default_xattr_handler,
+       [EXT2_XATTR_INDEX_POSIX_ACL_ACCESS]  = &nop_posix_acl_access,
+       [EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT] = &nop_posix_acl_default,
 #endif
        [EXT2_XATTR_INDEX_TRUSTED]           = &ext2_xattr_trusted_handler,
 #ifdef CONFIG_EXT2_FS_SECURITY
@@ -113,10 +113,6 @@ static const struct xattr_handler *ext2_xattr_handler_map[] = {
 const struct xattr_handler *ext2_xattr_handlers[] = {
        &ext2_xattr_user_handler,
        &ext2_xattr_trusted_handler,
-#ifdef CONFIG_EXT2_FS_POSIX_ACL
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
-#endif
 #ifdef CONFIG_EXT2_FS_SECURITY
        &ext2_xattr_security_handler,
 #endif
@@ -125,14 +121,18 @@ const struct xattr_handler *ext2_xattr_handlers[] = {
 
 #define EA_BLOCK_CACHE(inode)  (EXT2_SB(inode->i_sb)->s_ea_block_cache)
 
-static inline const struct xattr_handler *
-ext2_xattr_handler(int name_index)
+static inline const char *ext2_xattr_prefix(int name_index,
+                                           struct dentry *dentry)
 {
        const struct xattr_handler *handler = NULL;
 
        if (name_index > 0 && name_index < ARRAY_SIZE(ext2_xattr_handler_map))
                handler = ext2_xattr_handler_map[name_index];
-       return handler;
+
+       if (!xattr_handler_can_list(handler, dentry))
+               return NULL;
+
+       return xattr_prefix(handler);
 }
 
 static bool
@@ -333,11 +333,10 @@ bad_block:
        /* list the attribute names */
        for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
             entry = EXT2_XATTR_NEXT(entry)) {
-               const struct xattr_handler *handler =
-                       ext2_xattr_handler(entry->e_name_index);
+               const char *prefix;
 
-               if (handler && (!handler->list || handler->list(dentry))) {
-                       const char *prefix = handler->prefix ?: handler->name;
+               prefix = ext2_xattr_prefix(entry->e_name_index, dentry);
+               if (prefix) {
                        size_t prefix_len = strlen(prefix);
                        size_t size = prefix_len + entry->e_name_len + 1;
 
index 4eeb02d456a958b7f8809e7d884378a23d0e4c0b..08b29c289da4d15bc7ac8b3ed9c17fc8574c4bc2 100644 (file)
@@ -1387,7 +1387,7 @@ struct ext4_super_block {
        __le32  s_first_meta_bg;        /* First metablock block group */
        __le32  s_mkfs_time;            /* When the filesystem was created */
        __le32  s_jnl_blocks[17];       /* Backup of the journal inode */
-       /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */
+       /* 64bit support valid if EXT4_FEATURE_INCOMPAT_64BIT */
 /*150*/        __le32  s_blocks_count_hi;      /* Blocks count */
        __le32  s_r_blocks_count_hi;    /* Reserved blocks count */
        __le32  s_free_blocks_count_hi; /* Free blocks count */
index 4493ef0c715e9d1a1e8166feefc0a532339f6dd0..cdf9bfe10137ff4804c49fc85a666478e9c937cd 100644 (file)
@@ -486,6 +486,8 @@ static int ext4_getfsmap_datadev(struct super_block *sb,
                keys[0].fmr_physical = bofs;
        if (keys[1].fmr_physical >= eofs)
                keys[1].fmr_physical = eofs - 1;
+       if (keys[1].fmr_physical < keys[0].fmr_physical)
+               return 0;
        start_fsb = keys[0].fmr_physical;
        end_fsb = keys[1].fmr_physical;
 
index 2b42ececa46d8fe5e0e621ee1845d7d3c2b4e39a..1602d74b5eeb35f0090afb0ec566ed5f00c21ecc 100644 (file)
@@ -159,7 +159,6 @@ int ext4_find_inline_data_nolock(struct inode *inode)
                                        (void *)ext4_raw_inode(&is.iloc));
                EXT4_I(inode)->i_inline_size = EXT4_MIN_INLINE_DATA_SIZE +
                                le32_to_cpu(is.s.here->e_value_size);
-               ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
        }
 out:
        brelse(is.iloc.bh);
index d251d705c2763ca82aea53e7f9ab41e8f743dbb0..bf0b7dea4900afed9d81496c47a7aa741a76c32b 100644 (file)
@@ -4797,8 +4797,13 @@ static inline int ext4_iget_extra_inode(struct inode *inode,
 
        if (EXT4_INODE_HAS_XATTR_SPACE(inode)  &&
            *magic == cpu_to_le32(EXT4_XATTR_MAGIC)) {
+               int err;
+
                ext4_set_inode_state(inode, EXT4_STATE_XATTR);
-               return ext4_find_inline_data_nolock(inode);
+               err = ext4_find_inline_data_nolock(inode);
+               if (!err && ext4_has_inline_data(inode))
+                       ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
+               return err;
        } else
                EXT4_I(inode)->i_inline_off = 0;
        return 0;
index 12435d61f09eff9d85e23907588d21fd3c0be734..f9a430152063238a8b18d24651a28556192f6ed7 100644 (file)
@@ -431,6 +431,7 @@ static long swap_inode_boot_loader(struct super_block *sb,
                ei_bl->i_flags = 0;
                inode_set_iversion(inode_bl, 1);
                i_size_write(inode_bl, 0);
+               EXT4_I(inode_bl)->i_disksize = inode_bl->i_size;
                inode_bl->i_mode = S_IFREG;
                if (ext4_has_feature_extents(sb)) {
                        ext4_set_inode_flag(inode_bl, EXT4_INODE_EXTENTS);
index 94608b7df7e8a0fb01e656ec1616244d72744758..a5010b5b8a8c11b5909c137b649fe5d04849d832 100644 (file)
@@ -1595,11 +1595,10 @@ static struct buffer_head *__ext4_find_entry(struct inode *dir,
                int has_inline_data = 1;
                ret = ext4_find_inline_entry(dir, fname, res_dir,
                                             &has_inline_data);
-               if (has_inline_data) {
-                       if (inlined)
-                               *inlined = 1;
+               if (inlined)
+                       *inlined = has_inline_data;
+               if (has_inline_data)
                        goto cleanup_and_exit;
-               }
        }
 
        if ((namelen <= 2) && (name[0] == '.') &&
@@ -3646,7 +3645,8 @@ static void ext4_resetent(handle_t *handle, struct ext4_renament *ent,
         * so the old->de may no longer valid and need to find it again
         * before reset old inode info.
         */
-       old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, NULL);
+       old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de,
+                                &old.inlined);
        if (IS_ERR(old.bh))
                retval = PTR_ERR(old.bh);
        if (!old.bh)
@@ -3813,9 +3813,20 @@ static int ext4_rename(struct mnt_idmap *idmap, struct inode *old_dir,
                        return retval;
        }
 
-       old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, NULL);
-       if (IS_ERR(old.bh))
-               return PTR_ERR(old.bh);
+       /*
+        * We need to protect against old.inode directory getting converted
+        * from inline directory format into a normal one.
+        */
+       if (S_ISDIR(old.inode->i_mode))
+               inode_lock_nested(old.inode, I_MUTEX_NONDIR2);
+
+       old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de,
+                                &old.inlined);
+       if (IS_ERR(old.bh)) {
+               retval = PTR_ERR(old.bh);
+               goto unlock_moved_dir;
+       }
+
        /*
         *  Check for inode number is _not_ due to possible IO errors.
         *  We might rmdir the source, keep it as pwd of some process
@@ -3872,16 +3883,9 @@ static int ext4_rename(struct mnt_idmap *idmap, struct inode *old_dir,
                        if (new.dir != old.dir && EXT4_DIR_LINK_MAX(new.dir))
                                goto end_rename;
                }
-               /*
-                * We need to protect against old.inode directory getting
-                * converted from inline directory format into a normal one.
-                */
-               inode_lock_nested(old.inode, I_MUTEX_NONDIR2);
                retval = ext4_rename_dir_prepare(handle, &old);
-               if (retval) {
-                       inode_unlock(old.inode);
+               if (retval)
                        goto end_rename;
-               }
        }
        /*
         * If we're renaming a file within an inline_data dir and adding or
@@ -4013,12 +4017,15 @@ end_rename:
        } else {
                ext4_journal_stop(handle);
        }
-       if (old.dir_bh)
-               inode_unlock(old.inode);
 release_bh:
        brelse(old.dir_bh);
        brelse(old.bh);
        brelse(new.bh);
+
+unlock_moved_dir:
+       if (S_ISDIR(old.inode->i_mode))
+               inode_unlock(old.inode);
+
        return retval;
 }
 
index beaec6d81074a7e21c5ea3123700bd8332859a58..1e4db96a04e630b9a118d34580fa5c23c2db14a6 100644 (file)
@@ -409,7 +409,8 @@ static void io_submit_init_bio(struct ext4_io_submit *io,
 
 static void io_submit_add_bh(struct ext4_io_submit *io,
                             struct inode *inode,
-                            struct page *page,
+                            struct page *pagecache_page,
+                            struct page *bounce_page,
                             struct buffer_head *bh)
 {
        int ret;
@@ -421,10 +422,11 @@ submit_and_retry:
        }
        if (io->io_bio == NULL)
                io_submit_init_bio(io, bh);
-       ret = bio_add_page(io->io_bio, page, bh->b_size, bh_offset(bh));
+       ret = bio_add_page(io->io_bio, bounce_page ?: pagecache_page,
+                          bh->b_size, bh_offset(bh));
        if (ret != bh->b_size)
                goto submit_and_retry;
-       wbc_account_cgroup_owner(io->io_wbc, page, bh->b_size);
+       wbc_account_cgroup_owner(io->io_wbc, pagecache_page, bh->b_size);
        io->io_next_block++;
 }
 
@@ -561,8 +563,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
        do {
                if (!buffer_async_write(bh))
                        continue;
-               io_submit_add_bh(io, inode,
-                                bounce_page ? bounce_page : page, bh);
+               io_submit_add_bh(io, inode, page, bounce_page, bh);
        } while ((bh = bh->b_this_page) != head);
 unlock:
        unlock_page(page);
index 88f7b8a88c76b6d5d34d9740d58ffe26136dc5dd..76d1ef0efbf4bb75161b25887588021d157839db 100644 (file)
@@ -2500,7 +2500,7 @@ static void ext4_apply_quota_options(struct fs_context *fc,
                        qname = rcu_replace_pointer(sbi->s_qf_names[i], qname,
                                                lockdep_is_held(&sb->s_umount));
                        if (qname)
-                               kfree_rcu(qname);
+                               kfree_rcu_mightsleep(qname);
                }
        }
 
@@ -5726,6 +5726,28 @@ static struct inode *ext4_get_journal_inode(struct super_block *sb,
        return journal_inode;
 }
 
+static int ext4_journal_bmap(journal_t *journal, sector_t *block)
+{
+       struct ext4_map_blocks map;
+       int ret;
+
+       if (journal->j_inode == NULL)
+               return 0;
+
+       map.m_lblk = *block;
+       map.m_len = 1;
+       ret = ext4_map_blocks(NULL, journal->j_inode, &map, 0);
+       if (ret <= 0) {
+               ext4_msg(journal->j_inode->i_sb, KERN_CRIT,
+                        "journal bmap failed: block %llu ret %d\n",
+                        *block, ret);
+               jbd2_journal_abort(journal, ret ? ret : -EIO);
+               return ret;
+       }
+       *block = map.m_pblk;
+       return 0;
+}
+
 static journal_t *ext4_get_journal(struct super_block *sb,
                                   unsigned int journal_inum)
 {
@@ -5746,6 +5768,7 @@ static journal_t *ext4_get_journal(struct super_block *sb,
                return NULL;
        }
        journal->j_private = sb;
+       journal->j_bmap = ext4_journal_bmap;
        ext4_init_journal_params(sb, journal);
        return journal;
 }
@@ -5920,6 +5943,7 @@ static int ext4_load_journal(struct super_block *sb,
                err = jbd2_journal_wipe(journal, !really_read_only);
        if (!err) {
                char *save = kmalloc(EXT4_S_ERR_LEN, GFP_KERNEL);
+
                if (save)
                        memcpy(save, ((char *) es) +
                               EXT4_S_ERR_START, EXT4_S_ERR_LEN);
@@ -5928,6 +5952,14 @@ static int ext4_load_journal(struct super_block *sb,
                        memcpy(((char *) es) + EXT4_S_ERR_START,
                               save, EXT4_S_ERR_LEN);
                kfree(save);
+               es->s_state |= cpu_to_le16(EXT4_SB(sb)->s_mount_state &
+                                          EXT4_ERROR_FS);
+               /* Write out restored error information to the superblock */
+               if (!bdev_read_only(sb->s_bdev)) {
+                       int err2;
+                       err2 = ext4_commit_super(sb);
+                       err = err ? : err2;
+               }
        }
 
        if (err) {
@@ -6157,11 +6189,13 @@ static int ext4_clear_journal_err(struct super_block *sb,
                errstr = ext4_decode_error(sb, j_errno, nbuf);
                ext4_warning(sb, "Filesystem error recorded "
                             "from previous mount: %s", errstr);
-               ext4_warning(sb, "Marking fs in need of filesystem check.");
 
                EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
                es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
-               ext4_commit_super(sb);
+               j_errno = ext4_commit_super(sb);
+               if (j_errno)
+                       return j_errno;
+               ext4_warning(sb, "Marked fs in need of filesystem check.");
 
                jbd2_journal_clear_err(journal);
                jbd2_journal_update_sb_errno(journal);
index e2b8b3437c589734553eb6abf73066b7cc8f347d..12d6252e3e226dfdf5ee2f61512b23b213c1b503 100644 (file)
@@ -501,13 +501,13 @@ static const struct sysfs_ops ext4_attr_ops = {
        .store  = ext4_attr_store,
 };
 
-static struct kobj_type ext4_sb_ktype = {
+static const struct kobj_type ext4_sb_ktype = {
        .default_groups = ext4_groups,
        .sysfs_ops      = &ext4_attr_ops,
        .release        = ext4_sb_release,
 };
 
-static struct kobj_type ext4_feat_ktype = {
+static const struct kobj_type ext4_feat_ktype = {
        .default_groups = ext4_feat_groups,
        .sysfs_ops      = &ext4_attr_ops,
        .release        = ext4_feat_release,
index 62f2ec599218354caf9ea8ef4600cb59a200a0a8..dadad29bd81bf0739273c1283592a246967b9234 100644 (file)
@@ -88,8 +88,8 @@ static void ext4_xattr_rehash(struct ext4_xattr_header *);
 static const struct xattr_handler * const ext4_xattr_handler_map[] = {
        [EXT4_XATTR_INDEX_USER]              = &ext4_xattr_user_handler,
 #ifdef CONFIG_EXT4_FS_POSIX_ACL
-       [EXT4_XATTR_INDEX_POSIX_ACL_ACCESS]  = &posix_acl_access_xattr_handler,
-       [EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT] = &posix_acl_default_xattr_handler,
+       [EXT4_XATTR_INDEX_POSIX_ACL_ACCESS]  = &nop_posix_acl_access,
+       [EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT] = &nop_posix_acl_default,
 #endif
        [EXT4_XATTR_INDEX_TRUSTED]           = &ext4_xattr_trusted_handler,
 #ifdef CONFIG_EXT4_FS_SECURITY
@@ -101,10 +101,6 @@ static const struct xattr_handler * const ext4_xattr_handler_map[] = {
 const struct xattr_handler *ext4_xattr_handlers[] = {
        &ext4_xattr_user_handler,
        &ext4_xattr_trusted_handler,
-#ifdef CONFIG_EXT4_FS_POSIX_ACL
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
-#endif
 #ifdef CONFIG_EXT4_FS_SECURITY
        &ext4_xattr_security_handler,
 #endif
@@ -173,14 +169,18 @@ static void ext4_xattr_block_csum_set(struct inode *inode,
                                                bh->b_blocknr, BHDR(bh));
 }
 
-static inline const struct xattr_handler *
-ext4_xattr_handler(int name_index)
+static inline const char *ext4_xattr_prefix(int name_index,
+                                           struct dentry *dentry)
 {
        const struct xattr_handler *handler = NULL;
 
        if (name_index > 0 && name_index < ARRAY_SIZE(ext4_xattr_handler_map))
                handler = ext4_xattr_handler_map[name_index];
-       return handler;
+
+       if (!xattr_handler_can_list(handler, dentry))
+               return NULL;
+
+       return xattr_prefix(handler);
 }
 
 static int
@@ -740,11 +740,10 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
        size_t rest = buffer_size;
 
        for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
-               const struct xattr_handler *handler =
-                       ext4_xattr_handler(entry->e_name_index);
+               const char *prefix;
 
-               if (handler && (!handler->list || handler->list(dentry))) {
-                       const char *prefix = handler->prefix ?: handler->name;
+               prefix = ext4_xattr_prefix(entry->e_name_index, dentry);
+               if (prefix) {
                        size_t prefix_len = strlen(prefix);
                        size_t size = prefix_len + entry->e_name_len + 1;
 
@@ -2852,6 +2851,9 @@ shift:
                        (void *)header, total_ino);
        EXT4_I(inode)->i_extra_isize = new_extra_isize;
 
+       if (ext4_has_inline_data(inode))
+               error = ext4_find_inline_data_nolock(inode);
+
 cleanup:
        if (error && (mnt_count != le16_to_cpu(sbi->s_es->s_mnt_count))) {
                ext4_warning(inode->i_sb, "Unable to expand inode %lu. Delete some EAs or run e2fsck.",
index d92edbbdc30e72f1bb1a9fe1e231d009c6d309c2..213805d3592cca4acc3cc3206b6ed7021ad6dc37 100644 (file)
@@ -192,8 +192,8 @@ const struct xattr_handler f2fs_xattr_security_handler = {
 static const struct xattr_handler *f2fs_xattr_handler_map[] = {
        [F2FS_XATTR_INDEX_USER] = &f2fs_xattr_user_handler,
 #ifdef CONFIG_F2FS_FS_POSIX_ACL
-       [F2FS_XATTR_INDEX_POSIX_ACL_ACCESS] = &posix_acl_access_xattr_handler,
-       [F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &posix_acl_default_xattr_handler,
+       [F2FS_XATTR_INDEX_POSIX_ACL_ACCESS] = &nop_posix_acl_access,
+       [F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &nop_posix_acl_default,
 #endif
        [F2FS_XATTR_INDEX_TRUSTED] = &f2fs_xattr_trusted_handler,
 #ifdef CONFIG_F2FS_FS_SECURITY
@@ -204,10 +204,6 @@ static const struct xattr_handler *f2fs_xattr_handler_map[] = {
 
 const struct xattr_handler *f2fs_xattr_handlers[] = {
        &f2fs_xattr_user_handler,
-#ifdef CONFIG_F2FS_FS_POSIX_ACL
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
-#endif
        &f2fs_xattr_trusted_handler,
 #ifdef CONFIG_F2FS_FS_SECURITY
        &f2fs_xattr_security_handler,
@@ -216,13 +212,18 @@ const struct xattr_handler *f2fs_xattr_handlers[] = {
        NULL,
 };
 
-static inline const struct xattr_handler *f2fs_xattr_handler(int index)
+static inline const char *f2fs_xattr_prefix(int index,
+                                           struct dentry *dentry)
 {
        const struct xattr_handler *handler = NULL;
 
        if (index > 0 && index < ARRAY_SIZE(f2fs_xattr_handler_map))
                handler = f2fs_xattr_handler_map[index];
-       return handler;
+
+       if (!xattr_handler_can_list(handler, dentry))
+               return NULL;
+
+       return xattr_prefix(handler);
 }
 
 static struct f2fs_xattr_entry *__find_xattr(void *base_addr,
@@ -573,12 +574,12 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
        last_base_addr = (void *)base_addr + XATTR_SIZE(inode);
 
        list_for_each_xattr(entry, base_addr) {
-               const struct xattr_handler *handler =
-                       f2fs_xattr_handler(entry->e_name_index);
                const char *prefix;
                size_t prefix_len;
                size_t size;
 
+               prefix = f2fs_xattr_prefix(entry->e_name_index, dentry);
+
                if ((void *)(entry) + sizeof(__u32) > last_base_addr ||
                        (void *)XATTR_NEXT_ENTRY(entry) > last_base_addr) {
                        f2fs_err(F2FS_I_SB(inode), "inode (%lu) has corrupted xattr",
@@ -590,10 +591,9 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
                        goto cleanup;
                }
 
-               if (!handler || (handler->list && !handler->list(dentry)))
+               if (!prefix)
                        continue;
 
-               prefix = xattr_prefix(handler);
                prefix_len = strlen(prefix);
                size = prefix_len + entry->e_name_len + 1;
                if (buffer) {
index c942c89ca4cda90b94eaf724a2dabd63853bb52e..7893ea161d77075ca0ab524d7c8021ab668c0978 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -642,6 +642,7 @@ static struct file *pick_file(struct files_struct *files, unsigned fd)
        if (fd >= fdt->max_fds)
                return NULL;
 
+       fd = array_index_nospec(fd, fdt->max_fds);
        file = fdt->fd[fd];
        if (file) {
                rcu_assign_pointer(fdt->fd[fd], NULL);
index 195dc23e0d83109df6cb3942813ecb0e4d8caf5d..1db3e3c24b43a0252756efc7720b4a8b3bf032d3 100644 (file)
@@ -978,6 +978,16 @@ restart:
                        continue;
                }
 
+               /*
+                * If wb_tryget fails, the wb has been shutdown, skip it.
+                *
+                * Pin @wb so that it stays on @bdi->wb_list.  This allows
+                * continuing iteration from @wb after dropping and
+                * regrabbing rcu read lock.
+                */
+               if (!wb_tryget(wb))
+                       continue;
+
                /* alloc failed, execute synchronously using on-stack fallback */
                work = &fallback_work;
                *work = *base_work;
@@ -986,13 +996,6 @@ restart:
                work->done = &fallback_work_done;
 
                wb_queue_work(wb, work);
-
-               /*
-                * Pin @wb so that it stays on @bdi->wb_list.  This allows
-                * continuing iteration from @wb after dropping and
-                * regrabbing rcu read lock.
-                */
-               wb_get(wb);
                last_wb = wb;
 
                rcu_read_unlock();
index eb4f88e3dc97fe101fcfe340837496c54cf614b8..1a8f82f478cb7aa4a01f7286ff2f1e939ee5caca 100644 (file)
@@ -2257,30 +2257,31 @@ static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
        int res;
        int oldfd;
        struct fuse_dev *fud = NULL;
+       struct fd f;
 
        switch (cmd) {
        case FUSE_DEV_IOC_CLONE:
-               res = -EFAULT;
-               if (!get_user(oldfd, (__u32 __user *)arg)) {
-                       struct file *old = fget(oldfd);
-
-                       res = -EINVAL;
-                       if (old) {
-                               /*
-                                * Check against file->f_op because CUSE
-                                * uses the same ioctl handler.
-                                */
-                               if (old->f_op == file->f_op)
-                                       fud = fuse_get_dev(old);
-
-                               if (fud) {
-                                       mutex_lock(&fuse_mutex);
-                                       res = fuse_device_clone(fud->fc, file);
-                                       mutex_unlock(&fuse_mutex);
-                               }
-                               fput(old);
-                       }
+               if (get_user(oldfd, (__u32 __user *)arg))
+                       return -EFAULT;
+
+               f = fdget(oldfd);
+               if (!f.file)
+                       return -EINVAL;
+
+               /*
+                * Check against file->f_op because CUSE
+                * uses the same ioctl handler.
+                */
+               if (f.file->f_op == file->f_op)
+                       fud = fuse_get_dev(f.file);
+
+               res = -EINVAL;
+               if (fud) {
+                       mutex_lock(&fuse_mutex);
+                       res = fuse_device_clone(fud->fc, file);
+                       mutex_unlock(&fuse_mutex);
                }
+               fdput(f);
                break;
        default:
                res = -ENOTTY;
index de37a3a06a7169c628de17abe08ed14b56335108..89d97f6188e05ee58a195c72a5e3936177ba2733 100644 (file)
@@ -1419,7 +1419,7 @@ out:
 
 static inline unsigned long fuse_get_user_addr(const struct iov_iter *ii)
 {
-       return (unsigned long)ii->iov->iov_base + ii->iov_offset;
+       return (unsigned long)iter_iov(ii)->iov_base + ii->iov_offset;
 }
 
 static inline size_t fuse_get_frag_size(const struct iov_iter *ii,
index 6fe9ca253b709e8b8c193ab9a038206cd1f6c069..2e215e8c3c88e57d6ed17ba6cc5cb22420e99af6 100644 (file)
@@ -83,8 +83,26 @@ static int gfs2_dhash(const struct dentry *dentry, struct qstr *str)
        return 0;
 }
 
+static int gfs2_dentry_delete(const struct dentry *dentry)
+{
+       struct gfs2_inode *ginode;
+
+       if (d_really_is_negative(dentry))
+               return 0;
+
+       ginode = GFS2_I(d_inode(dentry));
+       if (!gfs2_holder_initialized(&ginode->i_iopen_gh))
+               return 0;
+
+       if (test_bit(GLF_DEMOTE, &ginode->i_iopen_gh.gh_gl->gl_flags))
+               return 1;
+
+       return 0;
+}
+
 const struct dentry_operations gfs2_dops = {
        .d_revalidate = gfs2_drevalidate,
        .d_hash = gfs2_dhash,
+       .d_delete = gfs2_dentry_delete,
 };
 
index adf6d17cf03353872b4f74202d5dcc3594bb9326..93b36d026bb478b30b1b438e69313db28e16fa30 100644 (file)
@@ -1501,8 +1501,6 @@ const struct xattr_handler *gfs2_xattr_handlers_max[] = {
        /* GFS2_FS_FORMAT_MIN */
        &gfs2_xattr_user_handler,
        &gfs2_xattr_security_handler,
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
        NULL,
 };
 
index abb91f5fae9211b752914df35a96e50dff846301..b21660475ac1cc703428cabf1f953b1ea3fb095a 100644 (file)
@@ -511,7 +511,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
        if (type == HFSPLUS_FOLDER) {
                struct hfsplus_cat_folder *folder = &entry.folder;
 
-               WARN_ON(fd->entrylength < sizeof(struct hfsplus_cat_folder));
+               if (fd->entrylength < sizeof(struct hfsplus_cat_folder)) {
+                       pr_err("bad catalog folder entry\n");
+                       res = -EIO;
+                       goto out;
+               }
                hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
                                        sizeof(struct hfsplus_cat_folder));
                hfsplus_get_perms(inode, &folder->permissions, 1);
@@ -531,7 +535,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
        } else if (type == HFSPLUS_FILE) {
                struct hfsplus_cat_file *file = &entry.file;
 
-               WARN_ON(fd->entrylength < sizeof(struct hfsplus_cat_file));
+               if (fd->entrylength < sizeof(struct hfsplus_cat_file)) {
+                       pr_err("bad catalog file entry\n");
+                       res = -EIO;
+                       goto out;
+               }
                hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
                                        sizeof(struct hfsplus_cat_file));
 
@@ -562,6 +570,7 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
                pr_err("bad catalog entry used to create inode\n");
                res = -EIO;
        }
+out:
        return res;
 }
 
@@ -570,6 +579,7 @@ int hfsplus_cat_write_inode(struct inode *inode)
        struct inode *main_inode = inode;
        struct hfs_find_data fd;
        hfsplus_cat_entry entry;
+       int res = 0;
 
        if (HFSPLUS_IS_RSRC(inode))
                main_inode = HFSPLUS_I(inode)->rsrc_inode;
@@ -588,7 +598,11 @@ int hfsplus_cat_write_inode(struct inode *inode)
        if (S_ISDIR(main_inode->i_mode)) {
                struct hfsplus_cat_folder *folder = &entry.folder;
 
-               WARN_ON(fd.entrylength < sizeof(struct hfsplus_cat_folder));
+               if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) {
+                       pr_err("bad catalog folder entry\n");
+                       res = -EIO;
+                       goto out;
+               }
                hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
                                        sizeof(struct hfsplus_cat_folder));
                /* simple node checks? */
@@ -613,7 +627,11 @@ int hfsplus_cat_write_inode(struct inode *inode)
        } else {
                struct hfsplus_cat_file *file = &entry.file;
 
-               WARN_ON(fd.entrylength < sizeof(struct hfsplus_cat_file));
+               if (fd.entrylength < sizeof(struct hfsplus_cat_file)) {
+                       pr_err("bad catalog file entry\n");
+                       res = -EIO;
+                       goto out;
+               }
                hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
                                        sizeof(struct hfsplus_cat_file));
                hfsplus_inode_write_fork(inode, &file->data_fork);
@@ -634,7 +652,7 @@ int hfsplus_cat_write_inode(struct inode *inode)
        set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags);
 out:
        hfs_find_exit(&fd);
-       return 0;
+       return res;
 }
 
 int hfsplus_fileattr_get(struct dentry *dentry, struct fileattr *fa)
index 4558dc2f13557368fb0200d826fe2edba5de3f1e..3ec5a8f7b644d058ef23762f9a26fdfc137084ca 100644 (file)
@@ -1804,8 +1804,8 @@ EXPORT_SYMBOL(bmap);
 
 /*
  * With relative atime, only update atime if the previous atime is
- * earlier than either the ctime or mtime or if at least a day has
- * passed since the last atime update.
+ * earlier than or equal to either the ctime or mtime,
+ * or if at least a day has passed since the last atime update.
  */
 static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
                             struct timespec64 now)
@@ -1814,12 +1814,12 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
        if (!(mnt->mnt_flags & MNT_RELATIME))
                return 1;
        /*
-        * Is mtime younger than atime? If yes, update atime:
+        * Is mtime younger than or equal to atime? If yes, update atime:
         */
        if (timespec64_compare(&inode->i_mtime, &inode->i_atime) >= 0)
                return 1;
        /*
-        * Is ctime younger than atime? If yes, update atime:
+        * Is ctime younger than or equal to atime? If yes, update atime:
         */
        if (timespec64_compare(&inode->i_ctime, &inode->i_atime) >= 0)
                return 1;
index dc4eb91a577a80f16a3f49729e8c6f6dec2aeb3b..ab36ed8fa41caf2134cb5a1f0599a7f80590bf7c 100644 (file)
@@ -259,8 +259,6 @@ ssize_t __kernel_write_iter(struct file *file, struct iov_iter *from, loff_t *po
 /*
  * fs/attr.c
  */
-int setattr_should_drop_sgid(struct mnt_idmap *idmap,
-                            const struct inode *inode);
 struct mnt_idmap *alloc_mnt_idmap(struct user_namespace *mnt_userns);
 struct mnt_idmap *mnt_idmap_get(struct mnt_idmap *idmap);
 void mnt_idmap_put(struct mnt_idmap *idmap);
index e80c781731f82957b8ef0cea3ea3585915258200..8ae419152ff64f7b553c69ce7e8617a1d5d9fc24 100644 (file)
@@ -969,10 +969,13 @@ int jbd2_journal_bmap(journal_t *journal, unsigned long blocknr,
 {
        int err = 0;
        unsigned long long ret;
-       sector_t block = 0;
+       sector_t block = blocknr;
 
-       if (journal->j_inode) {
-               block = blocknr;
+       if (journal->j_bmap) {
+               err = journal->j_bmap(journal, &block);
+               if (err == 0)
+                       *retp = block;
+       } else if (journal->j_inode) {
                ret = bmap(journal->j_inode, &block);
 
                if (ret || !block) {
index da3e18503c6582074257e2714216bfb24b3a6f32..aa4048a27f31f1de95178d4cbedda3fe02f459d3 100644 (file)
@@ -919,17 +919,14 @@ const struct xattr_handler *jffs2_xattr_handlers[] = {
        &jffs2_user_xattr_handler,
 #ifdef CONFIG_JFFS2_FS_SECURITY
        &jffs2_security_xattr_handler,
-#endif
-#ifdef CONFIG_JFFS2_FS_POSIX_ACL
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
 #endif
        &jffs2_trusted_xattr_handler,
        NULL
 };
 
-static const struct xattr_handler *xprefix_to_handler(int xprefix) {
-       const struct xattr_handler *ret;
+static const char *jffs2_xattr_prefix(int xprefix, struct dentry *dentry)
+{
+       const struct xattr_handler *ret = NULL;
 
        switch (xprefix) {
        case JFFS2_XPREFIX_USER:
@@ -942,20 +939,23 @@ static const struct xattr_handler *xprefix_to_handler(int xprefix) {
 #endif
 #ifdef CONFIG_JFFS2_FS_POSIX_ACL
        case JFFS2_XPREFIX_ACL_ACCESS:
-               ret = &posix_acl_access_xattr_handler;
+               ret = &nop_posix_acl_access;
                break;
        case JFFS2_XPREFIX_ACL_DEFAULT:
-               ret = &posix_acl_default_xattr_handler;
+               ret = &nop_posix_acl_default;
                break;
 #endif
        case JFFS2_XPREFIX_TRUSTED:
                ret = &jffs2_trusted_xattr_handler;
                break;
        default:
-               ret = NULL;
-               break;
+               return NULL;
        }
-       return ret;
+
+       if (!xattr_handler_can_list(ret, dentry))
+               return NULL;
+
+       return xattr_prefix(ret);
 }
 
 ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
@@ -966,7 +966,6 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
        struct jffs2_inode_cache *ic = f->inocache;
        struct jffs2_xattr_ref *ref, **pref;
        struct jffs2_xattr_datum *xd;
-       const struct xattr_handler *xhandle;
        const char *prefix;
        ssize_t prefix_len, len, rc;
        int retry = 0;
@@ -998,10 +997,10 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
                                        goto out;
                        }
                }
-               xhandle = xprefix_to_handler(xd->xprefix);
-               if (!xhandle || (xhandle->list && !xhandle->list(dentry)))
+
+               prefix = jffs2_xattr_prefix(xd->xprefix, dentry);
+               if (!prefix)
                        continue;
-               prefix = xhandle->prefix ?: xhandle->name;
                prefix_len = strlen(prefix);
                rc = prefix_len + xd->name_len + 1;
 
index 2e8461ce74de697df24518f27e7e4cd99fcdd665..961569c1115901b84ec84cb58b93d53561dd5a96 100644 (file)
@@ -691,6 +691,35 @@ void grab_metapage(struct metapage * mp)
        unlock_page(mp->page);
 }
 
+static int metapage_write_one(struct page *page)
+{
+       struct folio *folio = page_folio(page);
+       struct address_space *mapping = folio->mapping;
+       struct writeback_control wbc = {
+               .sync_mode = WB_SYNC_ALL,
+               .nr_to_write = folio_nr_pages(folio),
+       };
+       int ret = 0;
+
+       BUG_ON(!folio_test_locked(folio));
+
+       folio_wait_writeback(folio);
+
+       if (folio_clear_dirty_for_io(folio)) {
+               folio_get(folio);
+               ret = metapage_writepage(page, &wbc);
+               if (ret == 0)
+                       folio_wait_writeback(folio);
+               folio_put(folio);
+       } else {
+               folio_unlock(folio);
+       }
+
+       if (!ret)
+               ret = filemap_check_errors(mapping);
+       return ret;
+}
+
 void force_metapage(struct metapage *mp)
 {
        struct page *page = mp->page;
@@ -700,8 +729,8 @@ void force_metapage(struct metapage *mp)
        get_page(page);
        lock_page(page);
        set_page_dirty(page);
-       if (write_one_page(page))
-               jfs_error(mp->sb, "write_one_page() failed\n");
+       if (metapage_write_one(page))
+               jfs_error(mp->sb, "metapage_write_one() failed\n");
        clear_bit(META_forcewrite, &mp->flag);
        put_page(page);
 }
@@ -746,9 +775,9 @@ void release_metapage(struct metapage * mp)
                set_page_dirty(page);
                if (test_bit(META_sync, &mp->flag)) {
                        clear_bit(META_sync, &mp->flag);
-                       if (write_one_page(page))
-                               jfs_error(mp->sb, "write_one_page() failed\n");
-                       lock_page(page); /* write_one_page unlocks the page */
+                       if (metapage_write_one(page))
+                               jfs_error(mp->sb, "metapage_write_one() failed\n");
+                       lock_page(page);
                }
        } else if (mp->lsn)     /* discard_metapage doesn't remove it */
                remove_from_logsync(mp);
index f817798fa1eb1e28a0608c02de1bda1609bdd8a3..931e50018f888a5c26a05a98e23966031c3ff70b 100644 (file)
@@ -986,10 +986,6 @@ static const struct xattr_handler jfs_trusted_xattr_handler = {
 };
 
 const struct xattr_handler *jfs_xattr_handlers[] = {
-#ifdef CONFIG_JFS_POSIX_ACL
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
-#endif
        &jfs_os2_xattr_handler,
        &jfs_user_xattr_handler,
        &jfs_security_xattr_handler,
index ef00b5fe8ceea9d9dd3c16a76d89c151dec282fd..90de0e498371119769759d0d1dbb9d30e50d2660 100644 (file)
@@ -1748,12 +1748,6 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
        return error;
 }
 
-/* Relationship between mode and the DT_xxx types */
-static inline unsigned char dt_type(struct kernfs_node *kn)
-{
-       return (kn->mode >> 12) & 15;
-}
-
 static int kernfs_dir_fop_release(struct inode *inode, struct file *filp)
 {
        kernfs_put(filp->private_data);
@@ -1831,7 +1825,7 @@ static int kernfs_fop_readdir(struct file *file, struct dir_context *ctx)
             pos;
             pos = kernfs_dir_next_pos(ns, parent, ctx->pos, pos)) {
                const char *name = pos->name;
-               unsigned int type = dt_type(pos);
+               unsigned int type = fs_umode_to_dtype(pos->mode);
                int len = strlen(name);
                ino_t ino = kernfs_ino(pos);
 
index 6e61b5bc7d86ed5add4e940a3972068a508c52a0..cead696b656a8cd2a39a3fa4598dd656f39515b0 100644 (file)
@@ -727,8 +727,9 @@ static int generate_key(struct ksmbd_conn *conn, struct ksmbd_session *sess,
                goto smb3signkey_ret;
        }
 
-       if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
-           conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
+       if (key_size == SMB3_ENC_DEC_KEY_SIZE &&
+           (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
+            conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
                rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L256, 4);
        else
                rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L128, 4);
index 5b10b03800c163fb7704ef3d56ba7b664874d932..365ac32af505804f270eadaabfba989dbd5e6bfb 100644 (file)
@@ -112,10 +112,8 @@ void ksmbd_conn_enqueue_request(struct ksmbd_work *work)
        struct ksmbd_conn *conn = work->conn;
        struct list_head *requests_queue = NULL;
 
-       if (conn->ops->get_cmd_val(work) != SMB2_CANCEL_HE) {
+       if (conn->ops->get_cmd_val(work) != SMB2_CANCEL_HE)
                requests_queue = &conn->requests;
-               work->synchronous = true;
-       }
 
        if (requests_queue) {
                atomic_inc(&conn->req_running);
@@ -136,14 +134,14 @@ int ksmbd_conn_try_dequeue_request(struct ksmbd_work *work)
 
        if (!work->multiRsp)
                atomic_dec(&conn->req_running);
-       spin_lock(&conn->request_lock);
        if (!work->multiRsp) {
+               spin_lock(&conn->request_lock);
                list_del_init(&work->request_entry);
-               if (!work->synchronous)
-                       list_del_init(&work->async_request_entry);
+               spin_unlock(&conn->request_lock);
+               if (work->asynchronous)
+                       release_async_work(work);
                ret = 0;
        }
-       spin_unlock(&conn->request_lock);
 
        wake_up_all(&conn->req_running_q);
        return ret;
@@ -298,7 +296,7 @@ int ksmbd_conn_handler_loop(void *p)
                kvfree(conn->request_buf);
                conn->request_buf = NULL;
 
-               size = t->ops->read(t, hdr_buf, sizeof(hdr_buf));
+               size = t->ops->read(t, hdr_buf, sizeof(hdr_buf), -1);
                if (size != sizeof(hdr_buf))
                        break;
 
@@ -319,20 +317,14 @@ int ksmbd_conn_handler_loop(void *p)
                }
 
                /*
-                * Check if pdu size is valid (min : smb header size,
-                * max : 0x00FFFFFF).
+                * Check maximum pdu size(0x00FFFFFF).
                 */
-               if (pdu_size < __SMB2_HEADER_STRUCTURE_SIZE ||
-                   pdu_size > MAX_STREAM_PROT_LEN) {
+               if (pdu_size > MAX_STREAM_PROT_LEN)
                        break;
-               }
 
                /* 4 for rfc1002 length field */
                size = pdu_size + 4;
-               conn->request_buf = kvmalloc(size,
-                                            GFP_KERNEL |
-                                            __GFP_NOWARN |
-                                            __GFP_NORETRY);
+               conn->request_buf = kvmalloc(size, GFP_KERNEL);
                if (!conn->request_buf)
                        break;
 
@@ -344,7 +336,7 @@ int ksmbd_conn_handler_loop(void *p)
                 * We already read 4 bytes to find out PDU size, now
                 * read in PDU
                 */
-               size = t->ops->read(t, conn->request_buf + 4, pdu_size);
+               size = t->ops->read(t, conn->request_buf + 4, pdu_size, 2);
                if (size < 0) {
                        pr_err("sock_read failed: %d\n", size);
                        break;
index 3643354a3fa79c2b351c581691eff7ee74fe761b..0e3a848defaf3214ed752deed6c51854890a4194 100644 (file)
@@ -114,7 +114,8 @@ struct ksmbd_transport_ops {
        int (*prepare)(struct ksmbd_transport *t);
        void (*disconnect)(struct ksmbd_transport *t);
        void (*shutdown)(struct ksmbd_transport *t);
-       int (*read)(struct ksmbd_transport *t, char *buf, unsigned int size);
+       int (*read)(struct ksmbd_transport *t, char *buf,
+                   unsigned int size, int max_retries);
        int (*writev)(struct ksmbd_transport *t, struct kvec *iovs, int niov,
                      int size, bool need_invalidate_rkey,
                      unsigned int remote_key);
index 3234f2cf6327cf22ac227c64e4be8afb376073ef..f8ae6144c0aea6ba8724fbed3b48f0d1e719d6a1 100644 (file)
@@ -68,7 +68,7 @@ struct ksmbd_work {
        /* Request is encrypted */
        bool                            encrypted:1;
        /* Is this SYNC or ASYNC ksmbd_work */
-       bool                            synchronous:1;
+       bool                            asynchronous:1;
        bool                            need_invalidate_rkey:1;
 
        unsigned int                    remote_key;
index 394b6ceac4312685ebbd57a6087de345b0c4111b..0d8242789dc8fd7a4e39d0ca52bd6e0263275dca 100644 (file)
@@ -289,10 +289,7 @@ static int queue_ksmbd_work(struct ksmbd_conn *conn)
        work->request_buf = conn->request_buf;
        conn->request_buf = NULL;
 
-       if (ksmbd_init_smb_server(work)) {
-               ksmbd_free_work_struct(work);
-               return -EINVAL;
-       }
+       ksmbd_init_smb_server(work);
 
        ksmbd_conn_enqueue_request(work);
        atomic_inc(&conn->r_count);
index 0685c1c77b9fc2b443866480ed7a7ae89dad7c18..67b7e766a06bace88ef65d2afdb7dff514f9f364 100644 (file)
@@ -229,9 +229,6 @@ int init_smb2_neg_rsp(struct ksmbd_work *work)
        struct smb2_negotiate_rsp *rsp;
        struct ksmbd_conn *conn = work->conn;
 
-       if (conn->need_neg == false)
-               return -EINVAL;
-
        *(__be32 *)work->response_buf =
                cpu_to_be32(conn->vals->header_size);
 
@@ -498,12 +495,6 @@ int init_smb2_rsp_hdr(struct ksmbd_work *work)
        rsp_hdr->SessionId = rcv_hdr->SessionId;
        memcpy(rsp_hdr->Signature, rcv_hdr->Signature, 16);
 
-       work->synchronous = true;
-       if (work->async_id) {
-               ksmbd_release_id(&conn->async_ida, work->async_id);
-               work->async_id = 0;
-       }
-
        return 0;
 }
 
@@ -644,7 +635,7 @@ int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg)
                pr_err("Failed to alloc async message id\n");
                return id;
        }
-       work->synchronous = false;
+       work->asynchronous = true;
        work->async_id = id;
        rsp_hdr->Id.AsyncId = cpu_to_le64(id);
 
@@ -664,6 +655,24 @@ int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg)
        return 0;
 }
 
+void release_async_work(struct ksmbd_work *work)
+{
+       struct ksmbd_conn *conn = work->conn;
+
+       spin_lock(&conn->request_lock);
+       list_del_init(&work->async_request_entry);
+       spin_unlock(&conn->request_lock);
+
+       work->asynchronous = 0;
+       work->cancel_fn = NULL;
+       kfree(work->cancel_argv);
+       work->cancel_argv = NULL;
+       if (work->async_id) {
+               ksmbd_release_id(&conn->async_ida, work->async_id);
+               work->async_id = 0;
+       }
+}
+
 void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status)
 {
        struct smb2_hdr *rsp_hdr;
@@ -867,17 +876,21 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn,
 }
 
 static __le32 decode_preauth_ctxt(struct ksmbd_conn *conn,
-                                 struct smb2_preauth_neg_context *pneg_ctxt)
+                                 struct smb2_preauth_neg_context *pneg_ctxt,
+                                 int len_of_ctxts)
 {
-       __le32 err = STATUS_NO_PREAUTH_INTEGRITY_HASH_OVERLAP;
+       /*
+        * sizeof(smb2_preauth_neg_context) assumes SMB311_SALT_SIZE Salt,
+        * which may not be present. Only check for used HashAlgorithms[1].
+        */
+       if (len_of_ctxts < MIN_PREAUTH_CTXT_DATA_LEN)
+               return STATUS_INVALID_PARAMETER;
 
-       if (pneg_ctxt->HashAlgorithms == SMB2_PREAUTH_INTEGRITY_SHA512) {
-               conn->preauth_info->Preauth_HashId =
-                       SMB2_PREAUTH_INTEGRITY_SHA512;
-               err = STATUS_SUCCESS;
-       }
+       if (pneg_ctxt->HashAlgorithms != SMB2_PREAUTH_INTEGRITY_SHA512)
+               return STATUS_NO_PREAUTH_INTEGRITY_HASH_OVERLAP;
 
-       return err;
+       conn->preauth_info->Preauth_HashId = SMB2_PREAUTH_INTEGRITY_SHA512;
+       return STATUS_SUCCESS;
 }
 
 static void decode_encrypt_ctxt(struct ksmbd_conn *conn,
@@ -1005,7 +1018,8 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
                                break;
 
                        status = decode_preauth_ctxt(conn,
-                                                    (struct smb2_preauth_neg_context *)pctx);
+                                                    (struct smb2_preauth_neg_context *)pctx,
+                                                    len_of_ctxts);
                        if (status != STATUS_SUCCESS)
                                break;
                } else if (pctx->ContextType == SMB2_ENCRYPTION_CAPABILITIES) {
@@ -2977,8 +2991,11 @@ int smb2_open(struct ksmbd_work *work)
                                                        sizeof(struct smb_acl) +
                                                        sizeof(struct smb_ace) * ace_num * 2,
                                                        GFP_KERNEL);
-                                       if (!pntsd)
+                                       if (!pntsd) {
+                                               posix_acl_release(fattr.cf_acls);
+                                               posix_acl_release(fattr.cf_dacls);
                                                goto err_out;
+                                       }
 
                                        rc = build_sec_desc(idmap,
                                                            pntsd, NULL, 0,
@@ -4934,6 +4951,10 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
 
                info->Attributes |= cpu_to_le32(server_conf.share_fake_fscaps);
 
+               if (test_share_config_flag(work->tcon->share_conf,
+                   KSMBD_SHARE_FLAG_STREAMS))
+                       info->Attributes |= cpu_to_le32(FILE_NAMED_STREAMS);
+
                info->MaxPathNameComponentLength = cpu_to_le32(stfs.f_namelen);
                len = smbConvertToUTF16((__le16 *)info->FileSystemName,
                                        "NTFS", PATH_MAX, conn->local_nls, 0);
@@ -7038,13 +7059,9 @@ skip:
 
                                ksmbd_vfs_posix_lock_wait(flock);
 
-                               spin_lock(&work->conn->request_lock);
                                spin_lock(&fp->f_lock);
                                list_del(&work->fp_entry);
-                               work->cancel_fn = NULL;
-                               kfree(argv);
                                spin_unlock(&fp->f_lock);
-                               spin_unlock(&work->conn->request_lock);
 
                                if (work->state != KSMBD_WORK_ACTIVE) {
                                        list_del(&smb_lock->llist);
@@ -7062,6 +7079,7 @@ skip:
                                                work->send_no_response = 1;
                                                goto out;
                                        }
+
                                        init_smb2_rsp_hdr(work);
                                        smb2_set_err_rsp(work);
                                        rsp->hdr.Status =
@@ -7074,7 +7092,7 @@ skip:
                                spin_lock(&work->conn->llist_lock);
                                list_del(&smb_lock->clist);
                                spin_unlock(&work->conn->llist_lock);
-
+                               release_async_work(work);
                                goto retry;
                        } else if (!rc) {
                                spin_lock(&work->conn->llist_lock);
@@ -7444,13 +7462,16 @@ static int fsctl_query_allocated_ranges(struct ksmbd_work *work, u64 id,
        if (in_count == 0)
                return -EINVAL;
 
+       start = le64_to_cpu(qar_req->file_offset);
+       length = le64_to_cpu(qar_req->length);
+
+       if (start < 0 || length < 0)
+               return -EINVAL;
+
        fp = ksmbd_lookup_fd_fast(work, id);
        if (!fp)
                return -ENOENT;
 
-       start = le64_to_cpu(qar_req->file_offset);
-       length = le64_to_cpu(qar_req->length);
-
        ret = ksmbd_vfs_fqar_lseek(fp, start, length,
                                   qar_rsp, in_count, out_count);
        if (ret && ret != -E2BIG)
@@ -7751,7 +7772,7 @@ int smb2_ioctl(struct ksmbd_work *work)
 
                off = le64_to_cpu(zero_data->FileOffset);
                bfz = le64_to_cpu(zero_data->BeyondFinalZero);
-               if (off > bfz) {
+               if (off < 0 || bfz < 0 || off > bfz) {
                        ret = -EINVAL;
                        goto out;
                }
index 0c8a770fe3189b0caeea15c6e04009f5864560c3..9420dd2813fb782157a0ae7ebc41c9fa83d2cb76 100644 (file)
@@ -486,6 +486,7 @@ int find_matching_smb2_dialect(int start_index, __le16 *cli_dialects,
 struct file_lock *smb_flock_init(struct file *f);
 int setup_async_work(struct ksmbd_work *work, void (*fn)(void **),
                     void **arg);
+void release_async_work(struct ksmbd_work *work);
 void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status);
 struct channel *lookup_chann_list(struct ksmbd_session *sess,
                                  struct ksmbd_conn *conn);
index fa2b54df6ee6ff2aad4da4f3090010b26a863c63..af0c2a9b85290de8201640dc2f45896453443fe5 100644 (file)
@@ -283,20 +283,121 @@ err_out:
        return BAD_PROT_ID;
 }
 
-int ksmbd_init_smb_server(struct ksmbd_work *work)
+#define SMB_COM_NEGOTIATE_EX   0x0
+
+/**
+ * get_smb1_cmd_val() - get smb command value from smb header
+ * @work:      smb work containing smb header
+ *
+ * Return:      smb command value
+ */
+static u16 get_smb1_cmd_val(struct ksmbd_work *work)
 {
-       struct ksmbd_conn *conn = work->conn;
+       return SMB_COM_NEGOTIATE_EX;
+}
 
-       if (conn->need_neg == false)
+/**
+ * init_smb1_rsp_hdr() - initialize smb negotiate response header
+ * @work:      smb work containing smb request
+ *
+ * Return:      0 on success, otherwise -EINVAL
+ */
+static int init_smb1_rsp_hdr(struct ksmbd_work *work)
+{
+       struct smb_hdr *rsp_hdr = (struct smb_hdr *)work->response_buf;
+       struct smb_hdr *rcv_hdr = (struct smb_hdr *)work->request_buf;
+
+       /*
+        * Remove 4 byte direct TCP header.
+        */
+       *(__be32 *)work->response_buf =
+               cpu_to_be32(sizeof(struct smb_hdr) - 4);
+
+       rsp_hdr->Command = SMB_COM_NEGOTIATE;
+       *(__le32 *)rsp_hdr->Protocol = SMB1_PROTO_NUMBER;
+       rsp_hdr->Flags = SMBFLG_RESPONSE;
+       rsp_hdr->Flags2 = SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS |
+               SMBFLG2_EXT_SEC | SMBFLG2_IS_LONG_NAME;
+       rsp_hdr->Pid = rcv_hdr->Pid;
+       rsp_hdr->Mid = rcv_hdr->Mid;
+       return 0;
+}
+
+/**
+ * smb1_check_user_session() - check for valid session for a user
+ * @work:      smb work containing smb request buffer
+ *
+ * Return:      0 on success, otherwise error
+ */
+static int smb1_check_user_session(struct ksmbd_work *work)
+{
+       unsigned int cmd = work->conn->ops->get_cmd_val(work);
+
+       if (cmd == SMB_COM_NEGOTIATE_EX)
                return 0;
 
-       init_smb3_11_server(conn);
+       return -EINVAL;
+}
+
+/**
+ * smb1_allocate_rsp_buf() - allocate response buffer for a command
+ * @work:      smb work containing smb request
+ *
+ * Return:      0 on success, otherwise -ENOMEM
+ */
+static int smb1_allocate_rsp_buf(struct ksmbd_work *work)
+{
+       work->response_buf = kmalloc(MAX_CIFS_SMALL_BUFFER_SIZE,
+                       GFP_KERNEL | __GFP_ZERO);
+       work->response_sz = MAX_CIFS_SMALL_BUFFER_SIZE;
+
+       if (!work->response_buf) {
+               pr_err("Failed to allocate %u bytes buffer\n",
+                               MAX_CIFS_SMALL_BUFFER_SIZE);
+               return -ENOMEM;
+       }
 
-       if (conn->ops->get_cmd_val(work) != SMB_COM_NEGOTIATE)
-               conn->need_neg = false;
        return 0;
 }
 
+static struct smb_version_ops smb1_server_ops = {
+       .get_cmd_val = get_smb1_cmd_val,
+       .init_rsp_hdr = init_smb1_rsp_hdr,
+       .allocate_rsp_buf = smb1_allocate_rsp_buf,
+       .check_user_session = smb1_check_user_session,
+};
+
+static int smb1_negotiate(struct ksmbd_work *work)
+{
+       return ksmbd_smb_negotiate_common(work, SMB_COM_NEGOTIATE);
+}
+
+static struct smb_version_cmds smb1_server_cmds[1] = {
+       [SMB_COM_NEGOTIATE_EX]  = { .proc = smb1_negotiate, },
+};
+
+static void init_smb1_server(struct ksmbd_conn *conn)
+{
+       conn->ops = &smb1_server_ops;
+       conn->cmds = smb1_server_cmds;
+       conn->max_cmds = ARRAY_SIZE(smb1_server_cmds);
+}
+
+void ksmbd_init_smb_server(struct ksmbd_work *work)
+{
+       struct ksmbd_conn *conn = work->conn;
+       __le32 proto;
+
+       if (conn->need_neg == false)
+               return;
+
+       proto = *(__le32 *)((struct smb_hdr *)work->request_buf)->Protocol;
+       if (proto == SMB1_PROTO_NUMBER)
+               init_smb1_server(conn);
+       else
+               init_smb3_11_server(conn);
+}
+
 int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level,
                                      struct ksmbd_file *dir,
                                      struct ksmbd_dir_info *d_info,
@@ -434,7 +535,7 @@ int ksmbd_extract_shortname(struct ksmbd_conn *conn, const char *longname,
 
 static int __smb2_negotiate(struct ksmbd_conn *conn)
 {
-       return (conn->dialect >= SMB21_PROT_ID &&
+       return (conn->dialect >= SMB20_PROT_ID &&
                conn->dialect <= SMB311_PROT_ID);
 }
 
@@ -442,9 +543,16 @@ static int smb_handle_negotiate(struct ksmbd_work *work)
 {
        struct smb_negotiate_rsp *neg_rsp = work->response_buf;
 
-       ksmbd_debug(SMB, "Unsupported SMB protocol\n");
-       neg_rsp->hdr.Status.CifsError = STATUS_INVALID_LOGON_TYPE;
-       return -EINVAL;
+       ksmbd_debug(SMB, "Unsupported SMB1 protocol\n");
+
+       /* Add 2 byte bcc and 2 byte DialectIndex. */
+       inc_rfc1001_len(work->response_buf, 4);
+       neg_rsp->hdr.Status.CifsError = STATUS_SUCCESS;
+
+       neg_rsp->hdr.WordCount = 1;
+       neg_rsp->DialectIndex = cpu_to_le16(work->conn->dialect);
+       neg_rsp->ByteCount = 0;
+       return 0;
 }
 
 int ksmbd_smb_negotiate_common(struct ksmbd_work *work, unsigned int command)
@@ -457,23 +565,12 @@ int ksmbd_smb_negotiate_common(struct ksmbd_work *work, unsigned int command)
        ksmbd_debug(SMB, "conn->dialect 0x%x\n", conn->dialect);
 
        if (command == SMB2_NEGOTIATE_HE) {
-               struct smb2_hdr *smb2_hdr = smb2_get_msg(work->request_buf);
-
-               if (smb2_hdr->ProtocolId != SMB2_PROTO_NUMBER) {
-                       ksmbd_debug(SMB, "Downgrade to SMB1 negotiation\n");
-                       command = SMB_COM_NEGOTIATE;
-               }
-       }
-
-       if (command == SMB2_NEGOTIATE_HE && __smb2_negotiate(conn)) {
                ret = smb2_handle_negotiate(work);
-               init_smb2_neg_rsp(work);
                return ret;
        }
 
        if (command == SMB_COM_NEGOTIATE) {
                if (__smb2_negotiate(conn)) {
-                       conn->need_neg = true;
                        init_smb3_11_server(conn);
                        init_smb2_neg_rsp(work);
                        ksmbd_debug(SMB, "Upgrade to SMB2 negotiation\n");
index e663ab9ea759092d9e1cb0282b76d0059490581c..9130d2e3cd78c0966d266f7bf72dfe390bd06462 100644 (file)
 
 #define SMB1_PROTO_NUMBER              cpu_to_le32(0x424d53ff)
 #define SMB_COM_NEGOTIATE              0x72
-
 #define SMB1_CLIENT_GUID_SIZE          (16)
+
+#define SMBFLG_RESPONSE 0x80   /* this PDU is a response from server */
+
+#define SMBFLG2_IS_LONG_NAME   cpu_to_le16(0x40)
+#define SMBFLG2_EXT_SEC                cpu_to_le16(0x800)
+#define SMBFLG2_ERR_STATUS     cpu_to_le16(0x4000)
+#define SMBFLG2_UNICODE                cpu_to_le16(0x8000)
+
 struct smb_hdr {
        __be32 smb_buf_length;
        __u8 Protocol[4];
@@ -199,28 +206,7 @@ struct smb_negotiate_req {
 struct smb_negotiate_rsp {
        struct smb_hdr hdr;     /* wct = 17 */
        __le16 DialectIndex; /* 0xFFFF = no dialect acceptable */
-       __u8 SecurityMode;
-       __le16 MaxMpxCount;
-       __le16 MaxNumberVcs;
-       __le32 MaxBufferSize;
-       __le32 MaxRawSize;
-       __le32 SessionKey;
-       __le32 Capabilities;    /* see below */
-       __le32 SystemTimeLow;
-       __le32 SystemTimeHigh;
-       __le16 ServerTimeZone;
-       __u8 EncryptionKeyLength;
        __le16 ByteCount;
-       union {
-               unsigned char EncryptionKey[8]; /* cap extended security off */
-               /* followed by Domain name - if extended security is off */
-               /* followed by 16 bytes of server GUID */
-               /* then security blob if cap_extended_security negotiated */
-               struct {
-                       unsigned char GUID[SMB1_CLIENT_GUID_SIZE];
-                       unsigned char SecurityBlob[1];
-               } __packed extended_response;
-       } __packed u;
 } __packed;
 
 struct filesystem_attribute_info {
@@ -441,7 +427,7 @@ bool ksmbd_smb_request(struct ksmbd_conn *conn);
 
 int ksmbd_lookup_dialect_by_id(__le16 *cli_dialects, __le16 dialects_count);
 
-int ksmbd_init_smb_server(struct ksmbd_work *work);
+void ksmbd_init_smb_server(struct ksmbd_work *work);
 
 struct ksmbd_kstat;
 int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work,
index 096eda9ef873b670b46e735178bccb15742c4268..c06efc020bd95475cfd83884fe79b11638c57f5a 100644 (file)
@@ -670,7 +670,7 @@ static int smb_direct_post_recv(struct smb_direct_transport *t,
 }
 
 static int smb_direct_read(struct ksmbd_transport *t, char *buf,
-                          unsigned int size)
+                          unsigned int size, int unused)
 {
        struct smb_direct_recvmsg *recvmsg;
        struct smb_direct_data_transfer *data_transfer;
index 603893fd87f57d632107258052df2b79407db3ae..20e85e2701f26cf38daac453a41cc5eee2c14245 100644 (file)
@@ -291,16 +291,18 @@ static int ksmbd_tcp_run_kthread(struct interface *iface)
 
 /**
  * ksmbd_tcp_readv() - read data from socket in given iovec
- * @t:         TCP transport instance
- * @iov_orig:  base IO vector
- * @nr_segs:   number of segments in base iov
- * @to_read:   number of bytes to read from socket
+ * @t:                 TCP transport instance
+ * @iov_orig:          base IO vector
+ * @nr_segs:           number of segments in base iov
+ * @to_read:           number of bytes to read from socket
+ * @max_retries:       maximum retry count
  *
  * Return:     on success return number of bytes read from socket,
  *             otherwise return error number
  */
 static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
-                          unsigned int nr_segs, unsigned int to_read)
+                          unsigned int nr_segs, unsigned int to_read,
+                          int max_retries)
 {
        int length = 0;
        int total_read;
@@ -308,7 +310,6 @@ static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
        struct msghdr ksmbd_msg;
        struct kvec *iov;
        struct ksmbd_conn *conn = KSMBD_TRANS(t)->conn;
-       int max_retry = 2;
 
        iov = get_conn_iovec(t, nr_segs);
        if (!iov)
@@ -335,14 +336,23 @@ static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
                } else if (conn->status == KSMBD_SESS_NEED_RECONNECT) {
                        total_read = -EAGAIN;
                        break;
-               } else if ((length == -ERESTARTSYS || length == -EAGAIN) &&
-                          max_retry) {
+               } else if (length == -ERESTARTSYS || length == -EAGAIN) {
+                       /*
+                        * If max_retries is negative, Allow unlimited
+                        * retries to keep connection with inactive sessions.
+                        */
+                       if (max_retries == 0) {
+                               total_read = length;
+                               break;
+                       } else if (max_retries > 0) {
+                               max_retries--;
+                       }
+
                        usleep_range(1000, 2000);
                        length = 0;
-                       max_retry--;
                        continue;
                } else if (length <= 0) {
-                       total_read = -EAGAIN;
+                       total_read = length;
                        break;
                }
        }
@@ -358,14 +368,15 @@ static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
  * Return:     on success return number of bytes read from socket,
  *             otherwise return error number
  */
-static int ksmbd_tcp_read(struct ksmbd_transport *t, char *buf, unsigned int to_read)
+static int ksmbd_tcp_read(struct ksmbd_transport *t, char *buf,
+                         unsigned int to_read, int max_retries)
 {
        struct kvec iov;
 
        iov.iov_base = buf;
        iov.iov_len = to_read;
 
-       return ksmbd_tcp_readv(TCP_TRANS(t), &iov, 1, to_read);
+       return ksmbd_tcp_readv(TCP_TRANS(t), &iov, 1, to_read, max_retries);
 }
 
 static int ksmbd_tcp_writev(struct ksmbd_transport *t, struct kvec *iov,
index a0db699ddafda5a51700cd1b30635a6dd5adf4a1..9ae676906ed394409eb4ba84a4d9a9113e73aea9 100644 (file)
@@ -113,24 +113,6 @@ cp_convert:
        goto out;
 }
 
-/*
- * is_char_allowed() - check for valid character
- * @ch:                input character to be checked
- *
- * Return:     1 if char is allowed, otherwise 0
- */
-static inline int is_char_allowed(char *ch)
-{
-       /* check for control chars, wildcards etc. */
-       if (!(*ch & 0x80) &&
-           (*ch <= 0x1f ||
-            *ch == '?' || *ch == '"' || *ch == '<' ||
-            *ch == '>' || *ch == '|'))
-               return 0;
-
-       return 1;
-}
-
 /*
  * smb_from_utf16() - convert utf16le string to local charset
  * @to:                destination buffer
index 4eda519c30022f1a676869053a4ecda36b24dd53..89cf614a32715877c9bc500bffff502383db9d97 100644 (file)
@@ -174,12 +174,6 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int whence)
 }
 EXPORT_SYMBOL(dcache_dir_lseek);
 
-/* Relationship between i_mode and the DT_xxx types */
-static inline unsigned char dt_type(struct inode *inode)
-{
-       return (inode->i_mode >> 12) & 15;
-}
-
 /*
  * Directory is locked and all positive dentries in it are safe, since
  * for ramfs-type trees they can't go away without unlink() or rmdir(),
@@ -206,7 +200,8 @@ int dcache_readdir(struct file *file, struct dir_context *ctx)
 
        while ((next = scan_positives(cursor, p, 1, next)) != NULL) {
                if (!dir_emit(ctx, next->d_name.name, next->d_name.len,
-                             d_inode(next)->i_ino, dt_type(d_inode(next))))
+                             d_inode(next)->i_ino,
+                             fs_umode_to_dtype(d_inode(next)->i_mode)))
                        break;
                ctx->pos++;
                p = &next->d_child;
index 7df6324ccb8ab33ac9e04de7cbcfb11bb4eb1413..8161667c976f8c487de84ba9fcba189ae29072d9 100644 (file)
@@ -261,7 +261,6 @@ static int decode_nlm4_holder(struct xdr_stream *xdr, struct nlm_res *result)
        u32 exclusive;
        int error;
        __be32 *p;
-       s32 end;
 
        memset(lock, 0, sizeof(*lock));
        locks_init_lock(fl);
@@ -285,13 +284,7 @@ static int decode_nlm4_holder(struct xdr_stream *xdr, struct nlm_res *result)
        fl->fl_type  = exclusive != 0 ? F_WRLCK : F_RDLCK;
        p = xdr_decode_hyper(p, &l_offset);
        xdr_decode_hyper(p, &l_len);
-       end = l_offset + l_len - 1;
-
-       fl->fl_start = (loff_t)l_offset;
-       if (l_len == 0 || end < 0)
-               fl->fl_end = OFFSET_MAX;
-       else
-               fl->fl_end = (loff_t)end;
+       nlm4svc_set_file_lock_range(fl, l_offset, l_len);
        error = 0;
 out:
        return error;
index 712fdfeb8ef063bd1ad12f80c3c2ddf30f75101e..5fcbf30cd275928d1d364cf63e4f39fb61cb2a5a 100644 (file)
@@ -33,6 +33,17 @@ loff_t_to_s64(loff_t offset)
        return res;
 }
 
+void nlm4svc_set_file_lock_range(struct file_lock *fl, u64 off, u64 len)
+{
+       s64 end = off + len - 1;
+
+       fl->fl_start = off;
+       if (len == 0 || end < 0)
+               fl->fl_end = OFFSET_MAX;
+       else
+               fl->fl_end = end;
+}
+
 /*
  * NLM file handles are defined by specification to be a variable-length
  * XDR opaque no longer than 1024 bytes. However, this implementation
@@ -80,7 +91,7 @@ svcxdr_decode_lock(struct xdr_stream *xdr, struct nlm_lock *lock)
        locks_init_lock(fl);
        fl->fl_flags = FL_POSIX;
        fl->fl_type  = F_RDLCK;
-
+       nlm4svc_set_file_lock_range(fl, lock->lock_start, lock->lock_len);
        return true;
 }
 
index 66b4eef09db57785b86c214e416660784081d1f7..df8b26a425248ac4aa87a4ef9772b9700b417209 100644 (file)
@@ -1863,9 +1863,10 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp,
                        void **priv)
 {
        struct inode *inode = file_inode(filp);
+       vfsuid_t vfsuid = i_uid_into_vfsuid(file_mnt_idmap(filp), inode);
        int error;
 
-       if ((!uid_eq(current_fsuid(), inode->i_uid)) && !capable(CAP_LEASE))
+       if ((!vfsuid_eq_kuid(vfsuid, current_fsuid())) && !capable(CAP_LEASE))
                return -EACCES;
        if (!S_ISREG(inode->i_mode))
                return -EINVAL;
@@ -2425,7 +2426,6 @@ int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock)
                if (flock->l_pid != 0)
                        goto out;
 
-               cmd = F_GETLK64;
                fl->fl_flags |= FL_OFDLCK;
                fl->fl_owner = filp;
        }
index edfedfbccaef471e9eb6fe02a20df58069d9b6dc..f04f7be589331992c794fe96296db96dbfba2e18 100644 (file)
@@ -3574,9 +3574,9 @@ static int do_open(struct nameidata *nd,
 /**
  * vfs_tmpfile - create tmpfile
  * @idmap:     idmap of the mount the inode was found from
- * @dentry:    pointer to dentry of the base directory
+ * @parentpath:        pointer to the path of the base directory
+ * @file:      file descriptor of the new tmpfile
  * @mode:      mode of the new tmpfile
- * @open_flag: flags
  *
  * Create a temporary file.
  *
index bc0f15257b49c2f00f76ba53df2af8f44c6519c0..54847db5b8195d1a698a3a0db3ad1fdb7cdf06c2 100644 (file)
@@ -2617,15 +2617,12 @@ static void mnt_warn_timestamp_expiry(struct path *mountpoint, struct vfsmount *
           (ktime_get_real_seconds() + TIME_UPTIME_SEC_MAX > sb->s_time_max)) {
                char *buf = (char *)__get_free_page(GFP_KERNEL);
                char *mntpath = buf ? d_path(mountpoint, buf, PAGE_SIZE) : ERR_PTR(-ENOMEM);
-               struct tm tm;
 
-               time64_to_tm(sb->s_time_max, 0, &tm);
-
-               pr_warn("%s filesystem being %s at %s supports timestamps until %04ld (0x%llx)\n",
+               pr_warn("%s filesystem being %s at %s supports timestamps until %ptTd (0x%llx)\n",
                        sb->s_type->name,
                        is_mounted(mnt) ? "remounted" : "mounted",
-                       mntpath,
-                       tm.tm_year+1900, (unsigned long long)sb->s_time_max);
+                       mntpath, &sb->s_time_max,
+                       (unsigned long long)sb->s_time_max);
 
                free_page((unsigned long)buf);
                sb->s_iflags |= SB_I_TS_EXPIRY_WARNED;
@@ -4183,9 +4180,9 @@ out:
        unlock_mount_hash();
 
        if (kattr->propagation) {
-               namespace_unlock();
                if (err)
                        cleanup_group_ids(mnt, NULL);
+               namespace_unlock();
        }
 
        return err;
@@ -4197,7 +4194,7 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
        int err = 0;
        struct ns_common *ns;
        struct user_namespace *mnt_userns;
-       struct file *file;
+       struct fd f;
 
        if (!((attr->attr_set | attr->attr_clr) & MOUNT_ATTR_IDMAP))
                return 0;
@@ -4213,16 +4210,16 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
        if (attr->userns_fd > INT_MAX)
                return -EINVAL;
 
-       file = fget(attr->userns_fd);
-       if (!file)
+       f = fdget(attr->userns_fd);
+       if (!f.file)
                return -EBADF;
 
-       if (!proc_ns_file(file)) {
+       if (!proc_ns_file(f.file)) {
                err = -EINVAL;
                goto out_fput;
        }
 
-       ns = get_proc_ns(file_inode(file));
+       ns = get_proc_ns(file_inode(f.file));
        if (ns->ops->type != CLONE_NEWUSER) {
                err = -EINVAL;
                goto out_fput;
@@ -4251,7 +4248,7 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
        kattr->mnt_userns = get_user_ns(mnt_userns);
 
 out_fput:
-       fput(file);
+       fdput(f);
        return err;
 }
 
index e9a45dea748a2494707e851735deeafa1b89fdd2..8a4c866874297c18bdf63ebcf878d8e5b313b586 100644 (file)
@@ -139,7 +139,7 @@ static ssize_t netfs_extract_user_to_sg(struct iov_iter *iter,
                        size_t seg = min_t(size_t, PAGE_SIZE - off, len);
 
                        *pages++ = NULL;
-                       sg_set_page(sg, page, len, off);
+                       sg_set_page(sg, page, seg, off);
                        sgtable->nents++;
                        sg++;
                        len -= seg;
index 14a72224b6571b9617d586f766e39dcb5f1772eb..c1c7ed2fd860e797b1c50430deb047931b5b0464 100644 (file)
@@ -75,7 +75,6 @@ config NFS_V3_ACL
 config NFS_V4
        tristate "NFS client support for NFS version 4"
        depends on NFS_FS
-       select SUNRPC_GSS
        select KEYS
        help
          This option enables support for version 4 of the NFS protocol
index a41c3ee4549c074fcdcbb91cbcfce463803fb78b..6fbcbb8d6587a2754b0d7283abf2a66ba4211056 100644 (file)
@@ -3089,7 +3089,6 @@ static void nfs_access_add_rbtree(struct inode *inode,
                else
                        goto found;
        }
-       set->timestamp = ktime_get_ns();
        rb_link_node(&set->rb_node, parent, p);
        rb_insert_color(&set->rb_node, root_node);
        list_add_tail(&set->lru, &nfsi->access_cache_entry_lru);
@@ -3114,6 +3113,7 @@ void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set,
        cache->fsgid = cred->fsgid;
        cache->group_info = get_group_info(cred->group_info);
        cache->mask = set->mask;
+       cache->timestamp = ktime_get_ns();
 
        /* The above field assignments must be visible
         * before this item appears on the lru.  We cannot easily
index 222a28320e1c211efd6c7898d26855931863cbab..97a76706fd542b9aa149a578a04aa8b42bbf2aad 100644 (file)
@@ -717,9 +717,7 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr,
                if ((attr->ia_valid & ATTR_KILL_SUID) != 0 &&
                    inode->i_mode & S_ISUID)
                        inode->i_mode &= ~S_ISUID;
-               if ((attr->ia_valid & ATTR_KILL_SGID) != 0 &&
-                   (inode->i_mode & (S_ISGID | S_IXGRP)) ==
-                    (S_ISGID | S_IXGRP))
+               if (setattr_should_drop_sgid(&nop_mnt_idmap, inode))
                        inode->i_mode &= ~S_ISGID;
                if ((attr->ia_valid & ATTR_MODE) != 0) {
                        int mode = attr->ia_mode & S_IALLUGO;
index 4fa37dc038b58f1038f0cdeac06823f85976e63e..b333ea119ef54986a0f166536a82c7578c160928 100644 (file)
@@ -17,7 +17,6 @@ extern int nfs3_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
 extern int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
                struct posix_acl *dfacl);
 extern ssize_t nfs3_listxattr(struct dentry *, char *, size_t);
-extern const struct xattr_handler *nfs3_xattr_handlers[];
 #else
 static inline int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
                struct posix_acl *dfacl)
index 1247f544a440e41303637a252d864eeb97b990fb..349cc4f60a28da8a32169916120c9383bd434363 100644 (file)
@@ -300,12 +300,6 @@ fail:
        goto out;
 }
 
-const struct xattr_handler *nfs3_xattr_handlers[] = {
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
-       NULL,
-};
-
 static int
 nfs3_list_one_acl(struct inode *inode, int type, const char *name, void *data,
                size_t size, ssize_t *result)
index 7c5809431e61b73771ddf047f860272690c0f038..8a9be9e47f7663a8b89b93e13cc4664553fd8ae6 100644 (file)
@@ -14,9 +14,6 @@ struct nfs_subversion nfs_v3 = {
        .rpc_vers = &nfs_version3,
        .rpc_ops  = &nfs_v3_clientops,
        .sops     = &nfs_sops,
-#ifdef CONFIG_NFS_V3_ACL
-       .xattr    = nfs3_xattr_handlers,
-#endif
 };
 
 static int __init init_nfs_v3(void)
index 22a93ae46cd72058db4a44eb760d6abb2f8c9576..5607b1e2b8212b661dc56490ef61019408dd6b01 100644 (file)
@@ -1980,8 +1980,7 @@ _nfs4_opendata_reclaim_to_nfs4_state(struct nfs4_opendata *data)
        if (!data->rpc_done) {
                if (data->rpc_status)
                        return ERR_PTR(data->rpc_status);
-               /* cached opens have already been processed */
-               goto update;
+               return nfs4_try_open_cached(data);
        }
 
        ret = nfs_refresh_inode(inode, &data->f_attr);
@@ -1990,7 +1989,7 @@ _nfs4_opendata_reclaim_to_nfs4_state(struct nfs4_opendata *data)
 
        if (data->o_res.delegation_type != 0)
                nfs4_opendata_check_deleg(data, state);
-update:
+
        if (!update_open_stateid(state, &data->o_res.stateid,
                                NULL, data->o_arg.fmode))
                return ERR_PTR(-EAGAIN);
index c380cff4108e0693bd04580c18b2da9747f486da..e90988591df4f253f130d5d10eb4a60e5d9843da 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/stat.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
+#include <linux/task_io_accounting_ops.h>
 #include <linux/pagemap.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/nfs_fs.h>
@@ -337,6 +338,7 @@ int nfs_read_folio(struct file *file, struct folio *folio)
 
        trace_nfs_aop_readpage(inode, folio);
        nfs_inc_stats(inode, NFSIOS_VFSREADPAGE);
+       task_io_account_read(folio_size(folio));
 
        /*
         * Try to flush any pending writes to the file..
@@ -393,6 +395,7 @@ void nfs_readahead(struct readahead_control *ractl)
 
        trace_nfs_aop_readahead(inode, readahead_pos(ractl), nr_pages);
        nfs_inc_stats(inode, NFSIOS_VFSREADPAGES);
+       task_io_account_read(readahead_length(ractl));
 
        ret = -ESTALE;
        if (NFS_STALE(inode))
index 05ae23657527da80dc0c66469df936dfff92c5eb..397c096d874eb8fa0aa1849134570962090e62e1 100644 (file)
@@ -1274,9 +1274,6 @@ int nfs_get_tree_common(struct fs_context *fc)
                if (ctx->clone_data.sb->s_flags & SB_SYNCHRONOUS)
                        fc->sb_flags |= SB_SYNCHRONOUS;
 
-       if (server->caps & NFS_CAP_SECURITY_LABEL)
-               fc->lsm_flags |= SECURITY_LSM_NATIVE_LABELS;
-
        /* Get a superblock - note that we may end up sharing one that already exists */
        fc->s_fs_info = server;
        s = sget_fc(fc, compare_super, nfs_set_super);
index 7c441f2bd4440c17bd1e5c59d172ff4595c8cb31..43b88eaf0673ab0bfda775646b40835d264e3748 100644 (file)
@@ -73,7 +73,7 @@ config NFSD_V4
        bool "NFS server support for NFS version 4"
        depends on NFSD && PROC_FS
        select FS_POSIX_ACL
-       select SUNRPC_GSS
+       select RPCSEC_GSS_KRB5
        select CRYPTO
        select CRYPTO_MD5
        select CRYPTO_SHA256
index 04697f8dc37d6a6d8e3e28a2f423d80619322759..01d7fd108cf3df6bd1abdd050c4a75c14b34fd3d 100644 (file)
@@ -297,6 +297,7 @@ nfsd4_block_get_device_info_scsi(struct super_block *sb,
 
 out_free_dev:
        kfree(dev);
+       gdp->gd_device = NULL;
        return ret;
 }
 
index 2a815f5a52c4bec59f08570da6dc47701532ef57..4039ffcf90ba5879bb38583b4a11efeb729f49e6 100644 (file)
@@ -946,8 +946,8 @@ static const struct cred *get_backchannel_cred(struct nfs4_client *clp, struct r
                if (!kcred)
                        return NULL;
 
-               kcred->uid = ses->se_cb_sec.uid;
-               kcred->gid = ses->se_cb_sec.gid;
+               kcred->fsuid = ses->se_cb_sec.uid;
+               kcred->fsgid = ses->se_cb_sec.gid;
                return kcred;
        }
 }
index e12e5a4ad5023de6fefac0b958f5b9b237b8e9a2..76db2fe296244366fd146490a5d1c9767e2c4961 100644 (file)
@@ -2476,10 +2476,12 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
        for (i = 0; i < argp->opcnt; i++) {
                op = &argp->ops[i];
                op->replay = NULL;
+               op->opdesc = NULL;
 
                if (xdr_stream_decode_u32(argp->xdr, &op->opnum) < 0)
                        return false;
                if (nfsd4_opnum_in_range(argp, op)) {
+                       op->opdesc = OPDESC(op);
                        op->status = nfsd4_dec_ops[op->opnum](argp, &op->u);
                        if (op->status != nfs_ok)
                                trace_nfsd_compound_decode_err(argp->rqstp,
@@ -2490,7 +2492,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
                        op->opnum = OP_ILLEGAL;
                        op->status = nfserr_op_illegal;
                }
-               op->opdesc = OPDESC(op);
+
                /*
                 * We'll try to cache the result in the DRC if any one
                 * op in the compound wants to be cached:
@@ -3444,8 +3446,7 @@ out_acl:
                p = xdr_reserve_space(xdr, 4);
                if (!p)
                        goto out_resource;
-               err = xattr_supported_namespace(d_inode(dentry),
-                                               XATTR_USER_PREFIX);
+               err = xattr_supports_user_prefix(d_inode(dentry));
                *p++ = cpu_to_be32(err == 0);
        }
 
@@ -5400,10 +5401,8 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
        __be32 *p;
 
        p = xdr_reserve_space(xdr, 8);
-       if (!p) {
-               WARN_ON_ONCE(1);
-               return;
-       }
+       if (!p)
+               goto release;
        *p++ = cpu_to_be32(op->opnum);
        post_err_offset = xdr->buf->len;
 
@@ -5418,8 +5417,6 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
        op->status = encoder(resp, op->status, &op->u);
        if (op->status)
                trace_nfsd_compound_encode_err(rqstp, op->opnum, op->status);
-       if (opdesc && opdesc->op_release)
-               opdesc->op_release(&op->u);
        xdr_commit_encode(xdr);
 
        /* nfsd4_check_resp_size guarantees enough room for error status */
@@ -5460,6 +5457,9 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
        }
 status:
        *p = op->status;
+release:
+       if (opdesc && opdesc->op_release)
+               opdesc->op_release(&op->u);
 }
 
 /* 
index e7462b5e5f1e2bacd845896c9f7a5635ccf74be0..5783209f17fc522a4c211149d5e55cd6184ff594 100644 (file)
@@ -941,8 +941,15 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
        struct page *last_page;
 
        last_page = page + (offset + sd->len - 1) / PAGE_SIZE;
-       for (page += offset / PAGE_SIZE; page <= last_page; page++)
+       for (page += offset / PAGE_SIZE; page <= last_page; page++) {
+               /*
+                * Skip page replacement when extending the contents
+                * of the current page.
+                */
+               if (page == *(rqstp->rq_next_page - 1))
+                       continue;
                svc_rqst_replace_page(rqstp, page);
+       }
        if (rqstp->rq_res.page_len == 0)        // first call
                rqstp->rq_res.page_base = offset % PAGE_SIZE;
        rqstp->rq_res.page_len += sd->len;
@@ -1104,7 +1111,9 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
        since = READ_ONCE(file->f_wb_err);
        if (verf)
                nfsd_copy_write_verifier(verf, nn);
+       file_start_write(file);
        host_err = vfs_iter_write(file, &iter, &pos, flags);
+       file_end_write(file);
        if (host_err < 0) {
                nfsd_reset_write_verifier(nn);
                trace_nfsd_writeverf_reset(nn, rqstp, host_err);
index 2681a449edc162da2adee43f78e4e53dc9a2aa95..13592e82eaf68b2d92851e0218a99bd7842af9c4 100644 (file)
@@ -2219,6 +2219,7 @@ static int nilfs_btree_assign_p(struct nilfs_bmap *btree,
        /* on-disk format */
        binfo->bi_dat.bi_blkoff = cpu_to_le64(key);
        binfo->bi_dat.bi_level = level;
+       memset(binfo->bi_dat.bi_pad, 0, sizeof(binfo->bi_dat.bi_pad));
 
        return 0;
 }
index a35f2795b2422ffefc8a22b1892a557b146b2fc6..4c85914f2abc37a7d2ccb66115072196d3f60427 100644 (file)
@@ -314,6 +314,7 @@ static int nilfs_direct_assign_p(struct nilfs_bmap *direct,
 
        binfo->bi_dat.bi_blkoff = cpu_to_le64(key);
        binfo->bi_dat.bi_level = 0;
+       memset(binfo->bi_dat.bi_pad, 0, sizeof(binfo->bi_dat.bi_pad));
 
        return 0;
 }
index 5ccc638ae92f7d2bf7cc7f3f9cad79e56dd20b2e..1dfbc0c34513fb022ff6b2c55f817cddea410dde 100644 (file)
@@ -71,7 +71,7 @@ static int nilfs_ioctl_wrap_copy(struct the_nilfs *nilfs,
        if (argv->v_index > ~(__u64)0 - argv->v_nmembs)
                return -EINVAL;
 
-       buf = (void *)__get_free_pages(GFP_NOFS, 0);
+       buf = (void *)get_zeroed_page(GFP_NOFS);
        if (unlikely(!buf))
                return -ENOMEM;
        maxmembs = PAGE_SIZE / argv->v_size;
index 19446a8243d79156940632def1d909c152d44ac2..228659612c0d76a67243755fc3512839c561e98c 100644 (file)
@@ -430,6 +430,23 @@ static int nilfs_segctor_reset_segment_buffer(struct nilfs_sc_info *sci)
        return 0;
 }
 
+/**
+ * nilfs_segctor_zeropad_segsum - zero pad the rest of the segment summary area
+ * @sci: segment constructor object
+ *
+ * nilfs_segctor_zeropad_segsum() zero-fills unallocated space at the end of
+ * the current segment summary block.
+ */
+static void nilfs_segctor_zeropad_segsum(struct nilfs_sc_info *sci)
+{
+       struct nilfs_segsum_pointer *ssp;
+
+       ssp = sci->sc_blk_cnt > 0 ? &sci->sc_binfo_ptr : &sci->sc_finfo_ptr;
+       if (ssp->offset < ssp->bh->b_size)
+               memset(ssp->bh->b_data + ssp->offset, 0,
+                      ssp->bh->b_size - ssp->offset);
+}
+
 static int nilfs_segctor_feed_segment(struct nilfs_sc_info *sci)
 {
        sci->sc_nblk_this_inc += sci->sc_curseg->sb_sum.nblocks;
@@ -438,6 +455,7 @@ static int nilfs_segctor_feed_segment(struct nilfs_sc_info *sci)
                                * The current segment is filled up
                                * (internal code)
                                */
+       nilfs_segctor_zeropad_segsum(sci);
        sci->sc_curseg = NILFS_NEXT_SEGBUF(sci->sc_curseg);
        return nilfs_segctor_reset_segment_buffer(sci);
 }
@@ -542,6 +560,7 @@ static int nilfs_segctor_add_file_block(struct nilfs_sc_info *sci,
                goto retry;
        }
        if (unlikely(required)) {
+               nilfs_segctor_zeropad_segsum(sci);
                err = nilfs_segbuf_extend_segsum(segbuf);
                if (unlikely(err))
                        goto failed;
@@ -1533,6 +1552,7 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci,
                nadd = min_t(int, nadd << 1, SC_MAX_SEGDELTA);
                sci->sc_stage = prev_stage;
        }
+       nilfs_segctor_zeropad_segsum(sci);
        nilfs_segctor_truncate_segments(sci, sci->sc_curseg, nilfs->ns_sufile);
        return 0;
 
@@ -2609,11 +2629,10 @@ static int nilfs_segctor_thread(void *arg)
        goto loop;
 
  end_thread:
-       spin_unlock(&sci->sc_state_lock);
-
        /* end sync. */
        sci->sc_task = NULL;
        wake_up(&sci->sc_wait_task); /* for nilfs_segctor_kill_thread() */
+       spin_unlock(&sci->sc_state_lock);
        return 0;
 }
 
index 1422b8ba24ed625ac9fe39b6fda522f3eb172774..77f1e5778d1c84504b14289e72ff89c52d6df9a8 100644 (file)
@@ -482,6 +482,7 @@ static void nilfs_put_super(struct super_block *sb)
                up_write(&nilfs->ns_sem);
        }
 
+       nilfs_sysfs_delete_device_group(nilfs);
        iput(nilfs->ns_sufile);
        iput(nilfs->ns_cpfile);
        iput(nilfs->ns_dat);
@@ -1105,6 +1106,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent)
        nilfs_put_root(fsroot);
 
  failed_unload:
+       nilfs_sysfs_delete_device_group(nilfs);
        iput(nilfs->ns_sufile);
        iput(nilfs->ns_cpfile);
        iput(nilfs->ns_dat);
index 3a4c9c150cbf575228f80ac67871ad4d1bd4efcf..2894152a6b25cf0f0183c8f20312fbb339200c59 100644 (file)
@@ -87,7 +87,6 @@ void destroy_nilfs(struct the_nilfs *nilfs)
 {
        might_sleep();
        if (nilfs_init(nilfs)) {
-               nilfs_sysfs_delete_device_group(nilfs);
                brelse(nilfs->ns_sbh[0]);
                brelse(nilfs->ns_sbh[1]);
        }
@@ -305,6 +304,10 @@ int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
                goto failed;
        }
 
+       err = nilfs_sysfs_create_device_group(sb);
+       if (unlikely(err))
+               goto sysfs_error;
+
        if (valid_fs)
                goto skip_recovery;
 
@@ -366,6 +369,9 @@ int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
        goto failed;
 
  failed_unload:
+       nilfs_sysfs_delete_device_group(nilfs);
+
+ sysfs_error:
        iput(nilfs->ns_cpfile);
        iput(nilfs->ns_sufile);
        iput(nilfs->ns_dat);
@@ -697,10 +703,6 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data)
        if (err)
                goto failed_sbh;
 
-       err = nilfs_sysfs_create_device_group(sb);
-       if (err)
-               goto failed_sbh;
-
        set_nilfs_init(nilfs);
        err = 0;
  out:
index 8f430bfad48746a39a1b428a2fed682baae49213..22fb1cf7e1fc5ba99ab232699a62b91edb676b22 100644 (file)
@@ -663,7 +663,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
        struct fanotify_info *info = fanotify_event_info(event);
        unsigned int info_mode = FAN_GROUP_FLAG(group, FANOTIFY_INFO_MODES);
        unsigned int pidfd_mode = info_mode & FAN_REPORT_PIDFD;
-       struct file *f = NULL;
+       struct file *f = NULL, *pidfd_file = NULL;
        int ret, pidfd = FAN_NOPIDFD, fd = FAN_NOFD;
 
        pr_debug("%s: group=%p event=%p\n", __func__, group, event);
@@ -718,7 +718,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
                    !pid_has_task(event->pid, PIDTYPE_TGID)) {
                        pidfd = FAN_NOPIDFD;
                } else {
-                       pidfd = pidfd_create(event->pid, 0);
+                       pidfd = pidfd_prepare(event->pid, 0, &pidfd_file);
                        if (pidfd < 0)
                                pidfd = FAN_EPIDFD;
                }
@@ -751,6 +751,9 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
        if (f)
                fd_install(fd, f);
 
+       if (pidfd_file)
+               fd_install(pidfd, pidfd_file);
+
        return metadata.event_len;
 
 out_close_fd:
@@ -759,8 +762,10 @@ out_close_fd:
                fput(f);
        }
 
-       if (pidfd >= 0)
-               close_fd(pidfd);
+       if (pidfd >= 0) {
+               put_unused_fd(pidfd);
+               fput(pidfd_file);
+       }
 
        return ret;
 }
index f8df60b3b901a37d401e7df24afdc4b56f59fb27..f602a96a1afec392fa8e2b31ff8f4d9c8f532284 100644 (file)
--- a/fs/nsfs.c
+++ b/fs/nsfs.c
@@ -235,24 +235,6 @@ bool proc_ns_file(const struct file *file)
        return file->f_op == &ns_file_operations;
 }
 
-struct file *proc_ns_fget(int fd)
-{
-       struct file *file;
-
-       file = fget(fd);
-       if (!file)
-               return ERR_PTR(-EBADF);
-
-       if (file->f_op != &ns_file_operations)
-               goto out_invalid;
-
-       return file;
-
-out_invalid:
-       fput(file);
-       return ERR_PTR(-EINVAL);
-}
-
 /**
  * ns_match() - Returns true if current namespace matches dev/ino provided.
  * @ns: current namespace
index ff64302e87e5846c6b26735f8d096df6403612ed..7324cf92493228795bf7934beb2fc6776f74d82f 100644 (file)
@@ -1033,10 +1033,6 @@ static const struct xattr_handler ntfs_other_xattr_handler = {
 };
 
 const struct xattr_handler *ntfs_xattr_handlers[] = {
-#ifdef CONFIG_NTFS3_FS_POSIX_ACL
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
-#endif
        &ntfs_other_xattr_handler,
        NULL,
 };
index 1d65f6ef00ca8ba7a42eae4c3e87ff885201c43b..8dfc284e85f0936da24ee4e28ed46460ab7f4e55 100644 (file)
@@ -1977,11 +1977,26 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
        }
 
        if (unlikely(copied < len) && wc->w_target_page) {
+               loff_t new_isize;
+
                if (!PageUptodate(wc->w_target_page))
                        copied = 0;
 
-               ocfs2_zero_new_buffers(wc->w_target_page, start+copied,
-                                      start+len);
+               new_isize = max_t(loff_t, i_size_read(inode), pos + copied);
+               if (new_isize > page_offset(wc->w_target_page))
+                       ocfs2_zero_new_buffers(wc->w_target_page, start+copied,
+                                              start+len);
+               else {
+                       /*
+                        * When page is fully beyond new isize (data copy
+                        * failed), do not bother zeroing the page. Invalidate
+                        * it instead so that writeback does not get confused
+                        * put page & buffer dirty bits into inconsistent
+                        * state.
+                        */
+                       block_invalidate_folio(page_folio(wc->w_target_page),
+                                               0, PAGE_SIZE);
+               }
        }
        if (wc->w_target_page)
                flush_dcache_page(wc->w_target_page);
@@ -2448,7 +2463,7 @@ static ssize_t ocfs2_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 
        return __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev,
                                    iter, get_block,
-                                   ocfs2_dio_end_io, NULL, 0);
+                                   ocfs2_dio_end_io, 0);
 }
 
 const struct address_space_operations ocfs2_aops = {
index 9175dbc472011ec1005863edeac6bb925fc64dee..17c52225b87d4bc4cfa1b2986120ee9ae6cc4b97 100644 (file)
@@ -242,6 +242,7 @@ static int ocfs2_mknod(struct mnt_idmap *idmap,
        int want_meta = 0;
        int xattr_credits = 0;
        struct ocfs2_security_xattr_info si = {
+               .name = NULL,
                .enable = 1,
        };
        int did_quota_inode = 0;
@@ -1805,6 +1806,7 @@ static int ocfs2_symlink(struct mnt_idmap *idmap,
        int want_clusters = 0;
        int xattr_credits = 0;
        struct ocfs2_security_xattr_info si = {
+               .name = NULL,
                .enable = 1,
        };
        int did_quota = 0, did_quota_inode = 0;
index 5a656dc683f10808becf926728e4ba155424a7f4..564ab48d03effaf6d24d0dd30531db7e5241f876 100644 (file)
@@ -2952,10 +2952,11 @@ retry:
                 */
                if (PAGE_SIZE <= OCFS2_SB(sb)->s_clustersize) {
                        if (PageDirty(page)) {
-                               /*
-                                * write_on_page will unlock the page on return
-                                */
-                               ret = write_one_page(page);
+                               unlock_page(page);
+                               put_page(page);
+
+                               ret = filemap_write_and_wait_range(mapping,
+                                               offset, map_end - 1);
                                goto retry;
                        }
                }
index 389308efe854f872648f2fafe08a9666e9e38c97..4ac77ff6e676aeeae585ea8806f488a7c964e10c 100644 (file)
@@ -89,21 +89,17 @@ static struct ocfs2_xattr_def_value_root def_xv = {
 
 const struct xattr_handler *ocfs2_xattr_handlers[] = {
        &ocfs2_xattr_user_handler,
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
        &ocfs2_xattr_trusted_handler,
        &ocfs2_xattr_security_handler,
        NULL
 };
 
 static const struct xattr_handler *ocfs2_xattr_handler_map[OCFS2_XATTR_MAX] = {
-       [OCFS2_XATTR_INDEX_USER]        = &ocfs2_xattr_user_handler,
-       [OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS]
-                                       = &posix_acl_access_xattr_handler,
-       [OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT]
-                                       = &posix_acl_default_xattr_handler,
-       [OCFS2_XATTR_INDEX_TRUSTED]     = &ocfs2_xattr_trusted_handler,
-       [OCFS2_XATTR_INDEX_SECURITY]    = &ocfs2_xattr_security_handler,
+       [OCFS2_XATTR_INDEX_USER]                = &ocfs2_xattr_user_handler,
+       [OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS]    = &nop_posix_acl_access,
+       [OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT]   = &nop_posix_acl_default,
+       [OCFS2_XATTR_INDEX_TRUSTED]             = &ocfs2_xattr_trusted_handler,
+       [OCFS2_XATTR_INDEX_SECURITY]            = &ocfs2_xattr_security_handler,
 };
 
 struct ocfs2_xattr_info {
@@ -7259,9 +7255,21 @@ static int ocfs2_xattr_security_set(const struct xattr_handler *handler,
 static int ocfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
                     void *fs_info)
 {
+       struct ocfs2_security_xattr_info *si = fs_info;
        const struct xattr *xattr;
        int err = 0;
 
+       if (si) {
+               si->value = kmemdup(xattr_array->value, xattr_array->value_len,
+                                   GFP_KERNEL);
+               if (!si->value)
+                       return -ENOMEM;
+
+               si->name = xattr_array->name;
+               si->value_len = xattr_array->value_len;
+               return 0;
+       }
+
        for (xattr = xattr_array; xattr->name != NULL; xattr++) {
                err = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,
                                      xattr->name, xattr->value,
@@ -7277,13 +7285,23 @@ int ocfs2_init_security_get(struct inode *inode,
                            const struct qstr *qstr,
                            struct ocfs2_security_xattr_info *si)
 {
+       int ret;
+
        /* check whether ocfs2 support feature xattr */
        if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb)))
                return -EOPNOTSUPP;
-       if (si)
-               return security_old_inode_init_security(inode, dir, qstr,
-                                                       &si->name, &si->value,
-                                                       &si->value_len);
+       if (si) {
+               ret = security_inode_init_security(inode, dir, qstr,
+                                                  &ocfs2_initxattrs, si);
+               /*
+                * security_inode_init_security() does not return -EOPNOTSUPP,
+                * we have to check the xattr ourselves.
+                */
+               if (!ret && !si->name)
+                       si->enable = 0;
+
+               return ret;
+       }
 
        return security_inode_init_security(inode, dir, qstr,
                                            &ocfs2_initxattrs, NULL);
index 4401a73d4032d856958a7164b9efa133466688a3..4478adcc4f3a0570a9c8c586fbfe8fe2c642ac12 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -1196,13 +1196,21 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
        }
 
        /*
-        * In order to ensure programs get explicit errors when trying to use
-        * O_TMPFILE on old kernels, O_TMPFILE is implemented such that it
-        * looks like (O_DIRECTORY|O_RDWR & ~O_CREAT) to old kernels. But we
-        * have to require userspace to explicitly set it.
+        * Block bugs where O_DIRECTORY | O_CREAT created regular files.
+        * Note, that blocking O_DIRECTORY | O_CREAT here also protects
+        * O_TMPFILE below which requires O_DIRECTORY being raised.
         */
+       if ((flags & (O_DIRECTORY | O_CREAT)) == (O_DIRECTORY | O_CREAT))
+               return -EINVAL;
+
+       /* Now handle the creative implementation of O_TMPFILE. */
        if (flags & __O_TMPFILE) {
-               if ((flags & O_TMPFILE_MASK) != O_TMPFILE)
+               /*
+                * In order to ensure programs get explicit errors when trying
+                * to use O_TMPFILE on old kernels we enforce that O_DIRECTORY
+                * is raised alongside __O_TMPFILE.
+                */
+               if (!(flags & O_DIRECTORY))
                        return -EINVAL;
                if (!(acc_mode & MAY_WRITE))
                        return -EINVAL;
index 6ecad4f94ae6ef504fb54714c04afdd0a7017782..68b62689a63e248f73881dffc7861e0ff1bc9335 100644 (file)
@@ -555,8 +555,6 @@ static const struct xattr_handler orangefs_xattr_default_handler = {
 };
 
 const struct xattr_handler *orangefs_xattr_handlers[] = {
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
        &orangefs_xattr_default_handler,
        NULL
 };
index c14e90764e356565cf25561ea92793526e760c47..f658cc8ea4920487810216c0e0d94086730debff 100644 (file)
@@ -81,8 +81,7 @@ int ovl_copy_xattr(struct super_block *sb, const struct path *oldpath, struct de
        int error = 0;
        size_t slen;
 
-       if (!(old->d_inode->i_opflags & IOP_XATTR) ||
-           !(new->d_inode->i_opflags & IOP_XATTR))
+       if (!old->d_inode->i_op->listxattr || !new->d_inode->i_op->listxattr)
                return 0;
 
        list_size = vfs_listxattr(old, NULL, 0);
index f1d9f75f8786ce51ae60723eff63dac5b59c9f7f..f97ad8b40dbbd27fd29e025371ee2b79f1866e69 100644 (file)
@@ -1055,20 +1055,12 @@ static const struct xattr_handler ovl_other_xattr_handler = {
 };
 
 static const struct xattr_handler *ovl_trusted_xattr_handlers[] = {
-#ifdef CONFIG_FS_POSIX_ACL
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
-#endif
        &ovl_own_trusted_xattr_handler,
        &ovl_other_xattr_handler,
        NULL
 };
 
 static const struct xattr_handler *ovl_user_xattr_handlers[] = {
-#ifdef CONFIG_FS_POSIX_ACL
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
-#endif
        &ovl_own_user_xattr_handler,
        &ovl_other_xattr_handler,
        NULL
index 468e4e65a615d770919e0d952e17d0f4f1a7c02f..3cede8b18c8b6ff385815ae51e911b6b6af81e56 100644 (file)
@@ -214,7 +214,6 @@ static struct mount *next_group(struct mount *m, struct mount *origin)
 
 /* all accesses are serialized by namespace_sem */
 static struct mount *last_dest, *first_source, *last_source, *dest_master;
-static struct mountpoint *mp;
 static struct hlist_head *list;
 
 static inline bool peers(struct mount *m1, struct mount *m2)
@@ -222,7 +221,7 @@ static inline bool peers(struct mount *m1, struct mount *m2)
        return m1->mnt_group_id == m2->mnt_group_id && m1->mnt_group_id;
 }
 
-static int propagate_one(struct mount *m)
+static int propagate_one(struct mount *m, struct mountpoint *dest_mp)
 {
        struct mount *child;
        int type;
@@ -230,7 +229,7 @@ static int propagate_one(struct mount *m)
        if (IS_MNT_NEW(m))
                return 0;
        /* skip if mountpoint isn't covered by it */
-       if (!is_subdir(mp->m_dentry, m->mnt.mnt_root))
+       if (!is_subdir(dest_mp->m_dentry, m->mnt.mnt_root))
                return 0;
        if (peers(m, last_dest)) {
                type = CL_MAKE_SHARED;
@@ -262,7 +261,7 @@ static int propagate_one(struct mount *m)
        if (IS_ERR(child))
                return PTR_ERR(child);
        read_seqlock_excl(&mount_lock);
-       mnt_set_mountpoint(m, mp, child);
+       mnt_set_mountpoint(m, dest_mp, child);
        if (m->mnt_master != dest_master)
                SET_MNT_MARK(m->mnt_master);
        read_sequnlock_excl(&mount_lock);
@@ -299,13 +298,12 @@ int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp,
        last_dest = dest_mnt;
        first_source = source_mnt;
        last_source = source_mnt;
-       mp = dest_mp;
        list = tree_list;
        dest_master = dest_mnt->mnt_master;
 
        /* all peers of dest_mnt, except dest_mnt itself */
        for (n = next_peer(dest_mnt); n != dest_mnt; n = next_peer(n)) {
-               ret = propagate_one(n);
+               ret = propagate_one(n, dest_mp);
                if (ret)
                        goto out;
        }
@@ -316,7 +314,7 @@ int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp,
                /* everything in that slave group */
                n = m;
                do {
-                       ret = propagate_one(n);
+                       ret = propagate_one(n, dest_mp);
                        if (ret)
                                goto out;
                        n = next_peer(n);
index 5a76fb35923a5de9c1e362cf1d849ee5d2650106..7fa1b738bbab07cf93453bfd4e4f52d62bb09ebe 100644 (file)
@@ -957,25 +957,62 @@ set_posix_acl(struct mnt_idmap *idmap, struct dentry *dentry,
 }
 EXPORT_SYMBOL(set_posix_acl);
 
+int posix_acl_listxattr(struct inode *inode, char **buffer,
+                       ssize_t *remaining_size)
+{
+       int err;
+
+       if (!IS_POSIXACL(inode))
+               return 0;
+
+       if (inode->i_acl) {
+               err = xattr_list_one(buffer, remaining_size,
+                                    XATTR_NAME_POSIX_ACL_ACCESS);
+               if (err)
+                       return err;
+       }
+
+       if (inode->i_default_acl) {
+               err = xattr_list_one(buffer, remaining_size,
+                                    XATTR_NAME_POSIX_ACL_DEFAULT);
+               if (err)
+                       return err;
+       }
+
+       return 0;
+}
+
 static bool
 posix_acl_xattr_list(struct dentry *dentry)
 {
        return IS_POSIXACL(d_backing_inode(dentry));
 }
 
-const struct xattr_handler posix_acl_access_xattr_handler = {
+/*
+ * nop_posix_acl_access - legacy xattr handler for access POSIX ACLs
+ *
+ * This is the legacy POSIX ACL access xattr handler. It is used by some
+ * filesystems to implement their ->listxattr() inode operation. New code
+ * should never use them.
+ */
+const struct xattr_handler nop_posix_acl_access = {
        .name = XATTR_NAME_POSIX_ACL_ACCESS,
-       .flags = ACL_TYPE_ACCESS,
        .list = posix_acl_xattr_list,
 };
-EXPORT_SYMBOL_GPL(posix_acl_access_xattr_handler);
+EXPORT_SYMBOL_GPL(nop_posix_acl_access);
 
-const struct xattr_handler posix_acl_default_xattr_handler = {
+/*
+ * nop_posix_acl_default - legacy xattr handler for default POSIX ACLs
+ *
+ * This is the legacy POSIX ACL default xattr handler. It is used by some
+ * filesystems to implement their ->listxattr() inode operation. New code
+ * should never use them.
+ */
+const struct xattr_handler nop_posix_acl_default = {
        .name = XATTR_NAME_POSIX_ACL_DEFAULT,
-       .flags = ACL_TYPE_DEFAULT,
        .list = posix_acl_xattr_list,
 };
-EXPORT_SYMBOL_GPL(posix_acl_default_xattr_handler);
+EXPORT_SYMBOL_GPL(nop_posix_acl_default);
 
 int simple_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
                   struct posix_acl *acl, int type)
@@ -1094,12 +1131,10 @@ retry_deleg:
        if (error)
                goto out_inode_unlock;
 
-       if (inode->i_opflags & IOP_XATTR)
+       if (likely(!is_bad_inode(inode)))
                error = set_posix_acl(idmap, dentry, acl_type, kacl);
-       else if (unlikely(is_bad_inode(inode)))
-               error = -EIO;
        else
-               error = -EOPNOTSUPP;
+               error = -EIO;
        if (!error) {
                fsnotify_xattr(dentry);
                evm_inode_post_set_acl(dentry, acl_name, kacl);
@@ -1204,12 +1239,10 @@ retry_deleg:
        if (error)
                goto out_inode_unlock;
 
-       if (inode->i_opflags & IOP_XATTR)
+       if (likely(!is_bad_inode(inode)))
                error = set_posix_acl(idmap, dentry, acl_type, NULL);
-       else if (unlikely(is_bad_inode(inode)))
-               error = -EIO;
        else
-               error = -EOPNOTSUPP;
+               error = -EIO;
        if (!error) {
                fsnotify_xattr(dentry);
                evm_inode_post_remove_acl(idmap, dentry, acl_name);
diff --git a/fs/qnx4/README b/fs/qnx4/README
deleted file mode 100644 (file)
index 1f1e320..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-
-  This is a snapshot of the QNX4 filesystem for Linux.
-  Please send diffs and remarks to <al@alarsen.net> .
-  
-Credits :
-
-Richard "Scuba" A. Frowijn     <scuba@wxs.nl>
-Frank "Jedi/Sector One" Denis  <j@pureftpd.org>
-Anders Larsen                  <al@alarsen.net> (Maintainer)
diff --git a/fs/qnx6/README b/fs/qnx6/README
deleted file mode 100644 (file)
index 116d622..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-
-  This is a snapshot of the QNX6 filesystem for Linux.
-  Please send diffs and remarks to <chaosman@ontika.net> .
-
-Credits :
-
-Al Viro                <viro@ZenIV.linux.org.uk> (endless patience with me & support ;))
-Kai Bankett    <chaosman@ontika.net> (Maintainer)
index 7a2ff6157eda4aadae53f3e8b8687988b1a8413c..a21ba3be7dbe73024125c2a4d619d65185456717 100644 (file)
@@ -749,15 +749,14 @@ static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter,
                return -EOPNOTSUPP;
 
        while (iov_iter_count(iter)) {
-               struct iovec iovec = iov_iter_iovec(iter);
                ssize_t nr;
 
                if (type == READ) {
-                       nr = filp->f_op->read(filp, iovec.iov_base,
-                                             iovec.iov_len, ppos);
+                       nr = filp->f_op->read(filp, iter_iov_addr(iter),
+                                               iter_iov_len(iter), ppos);
                } else {
-                       nr = filp->f_op->write(filp, iovec.iov_base,
-                                              iovec.iov_len, ppos);
+                       nr = filp->f_op->write(filp, iter_iov_addr(iter),
+                                               iter_iov_len(iter), ppos);
                }
 
                if (nr < 0) {
@@ -766,7 +765,7 @@ static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter,
                        break;
                }
                ret += nr;
-               if (nr != iovec.iov_len)
+               if (nr != iter_iov_len(iter))
                        break;
                iov_iter_advance(iter, nr);
        }
index 467d13da198f90cef5dd6ed5b29623916ecb3042..b54cc7048f0276dd1d2ac9e12f6bc4c2bcf5a87d 100644 (file)
@@ -261,3 +261,10 @@ const struct inode_operations reiserfs_file_inode_operations = {
        .fileattr_get = reiserfs_fileattr_get,
        .fileattr_set = reiserfs_fileattr_set,
 };
+
+const struct inode_operations reiserfs_priv_file_inode_operations = {
+       .setattr = reiserfs_setattr,
+       .permission = reiserfs_permission,
+       .fileattr_get = reiserfs_fileattr_get,
+       .fileattr_set = reiserfs_fileattr_set,
+};
index d54cab854f60d3401c5537a68fbd1d75aa54a93a..d8debbb6105f34e00f2b60e75c6278e92f625465 100644 (file)
@@ -2087,10 +2087,8 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
         * Mark it private if we're creating the privroot
         * or something under it.
         */
-       if (IS_PRIVATE(dir) || dentry == REISERFS_SB(sb)->priv_root) {
-               inode->i_flags |= S_PRIVATE;
-               inode->i_opflags &= ~IOP_XATTR;
-       }
+       if (IS_PRIVATE(dir) || dentry == REISERFS_SB(sb)->priv_root)
+               reiserfs_init_priv_inode(inode);
 
        if (reiserfs_posixacl(inode->i_sb)) {
                reiserfs_write_unlock(inode->i_sb);
index 42d2c20e13455a7ad86a7d87dc5c61fdda82ab63..52240cc891cf03090d686edfeeab0d5801b19a5c 100644 (file)
@@ -378,13 +378,11 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry,
 
                /*
                 * Propagate the private flag so we know we're
-                * in the priv tree.  Also clear IOP_XATTR
+                * in the priv tree.  Also clear xattr support
                 * since we don't have xattrs on xattr files.
                 */
-               if (IS_PRIVATE(dir)) {
-                       inode->i_flags |= S_PRIVATE;
-                       inode->i_opflags &= ~IOP_XATTR;
-               }
+               if (IS_PRIVATE(dir))
+                       reiserfs_init_priv_inode(inode);
        }
        reiserfs_write_unlock(dir->i_sb);
        if (retval == IO_ERROR) {
@@ -1649,6 +1647,48 @@ static int reiserfs_rename(struct mnt_idmap *idmap,
        return retval;
 }
 
+static const struct inode_operations reiserfs_priv_dir_inode_operations = {
+       .create = reiserfs_create,
+       .lookup = reiserfs_lookup,
+       .link = reiserfs_link,
+       .unlink = reiserfs_unlink,
+       .symlink = reiserfs_symlink,
+       .mkdir = reiserfs_mkdir,
+       .rmdir = reiserfs_rmdir,
+       .mknod = reiserfs_mknod,
+       .rename = reiserfs_rename,
+       .setattr = reiserfs_setattr,
+       .permission = reiserfs_permission,
+       .fileattr_get = reiserfs_fileattr_get,
+       .fileattr_set = reiserfs_fileattr_set,
+};
+
+static const struct inode_operations reiserfs_priv_symlink_inode_operations = {
+       .get_link       = page_get_link,
+       .setattr = reiserfs_setattr,
+       .permission = reiserfs_permission,
+};
+
+static const struct inode_operations reiserfs_priv_special_inode_operations = {
+       .setattr = reiserfs_setattr,
+       .permission = reiserfs_permission,
+};
+
+void reiserfs_init_priv_inode(struct inode *inode)
+{
+       inode->i_flags |= S_PRIVATE;
+       inode->i_opflags &= ~IOP_XATTR;
+
+       if (S_ISREG(inode->i_mode))
+               inode->i_op = &reiserfs_priv_file_inode_operations;
+       else if (S_ISDIR(inode->i_mode))
+               inode->i_op = &reiserfs_priv_dir_inode_operations;
+       else if (S_ISLNK(inode->i_mode))
+               inode->i_op = &reiserfs_priv_symlink_inode_operations;
+       else
+               inode->i_op = &reiserfs_priv_special_inode_operations;
+}
+
 /* directories can handle most operations...  */
 const struct inode_operations reiserfs_dir_inode_operations = {
        .create = reiserfs_create,
index 98e6f53c2fe0d00a78b3595ed3845b454c1f7508..1bccf6a2e908fbb2771b7cdbdba7a147bb92e351 100644 (file)
@@ -3106,6 +3106,7 @@ int reiserfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
 int __reiserfs_write_begin(struct page *page, unsigned from, unsigned len);
 
 /* namei.c */
+void reiserfs_init_priv_inode(struct inode *inode);
 void set_de_name_and_namelen(struct reiserfs_dir_entry *de);
 int search_by_entry_key(struct super_block *sb, const struct cpu_key *key,
                        struct treepath *path, struct reiserfs_dir_entry *de);
@@ -3175,6 +3176,7 @@ void reiserfs_unmap_buffer(struct buffer_head *);
 
 /* file.c */
 extern const struct inode_operations reiserfs_file_inode_operations;
+extern const struct inode_operations reiserfs_priv_file_inode_operations;
 extern const struct file_operations reiserfs_file_operations;
 extern const struct address_space_operations reiserfs_address_space_operations;
 
index 06d810c72c527d04c7116e2a36db1b705a16624f..6510279671596c4f5a666145b5f7be85d2d0ddea 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/quotaops.h>
 #include <linux/security.h>
 #include <linux/posix_acl_xattr.h>
+#include <linux/xattr.h>
 
 #define PRIVROOT_NAME ".reiserfs_priv"
 #define XAROOT_NAME   "xattrs"
@@ -770,23 +771,34 @@ out:
                        (handler) != NULL;                      \
                        (handler) = *(handlers)++)
 
+static inline bool reiserfs_posix_acl_list(const char *name,
+                                          struct dentry *dentry)
+{
+       return (posix_acl_type(name) >= 0) &&
+              IS_POSIXACL(d_backing_inode(dentry));
+}
+
 /* This is the implementation for the xattr plugin infrastructure */
-static inline const struct xattr_handler *
-find_xattr_handler_prefix(const struct xattr_handler **handlers,
-                          const char *name)
+static inline bool reiserfs_xattr_list(const struct xattr_handler **handlers,
+                                      const char *name, struct dentry *dentry)
 {
-       const struct xattr_handler *xah;
+       if (handlers) {
+               const struct xattr_handler *xah = NULL;
 
-       if (!handlers)
-               return NULL;
+               for_each_xattr_handler(handlers, xah) {
+                       const char *prefix = xattr_prefix(xah);
 
-       for_each_xattr_handler(handlers, xah) {
-               const char *prefix = xattr_prefix(xah);
-               if (strncmp(prefix, name, strlen(prefix)) == 0)
-                       break;
+                       if (strncmp(prefix, name, strlen(prefix)))
+                               continue;
+
+                       if (!xattr_handler_can_list(xah, dentry))
+                               return false;
+
+                       return true;
+               }
        }
 
-       return xah;
+       return reiserfs_posix_acl_list(name, dentry);
 }
 
 struct listxattr_buf {
@@ -807,12 +819,8 @@ static bool listxattr_filler(struct dir_context *ctx, const char *name,
 
        if (name[0] != '.' ||
            (namelen != 1 && (name[1] != '.' || namelen != 2))) {
-               const struct xattr_handler *handler;
-
-               handler = find_xattr_handler_prefix(b->dentry->d_sb->s_xattr,
-                                                   name);
-               if (!handler /* Unsupported xattr name */ ||
-                   (handler->list && !handler->list(b->dentry)))
+               if (!reiserfs_xattr_list(b->dentry->d_sb->s_xattr, name,
+                                        b->dentry))
                        return true;
                size = namelen + 1;
                if (b->buf) {
@@ -888,8 +896,7 @@ static int create_privroot(struct dentry *dentry)
                return -EOPNOTSUPP;
        }
 
-       d_inode(dentry)->i_flags |= S_PRIVATE;
-       d_inode(dentry)->i_opflags &= ~IOP_XATTR;
+       reiserfs_init_priv_inode(d_inode(dentry));
        reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr "
                      "storage.\n", PRIVROOT_NAME);
 
@@ -910,10 +917,6 @@ const struct xattr_handler *reiserfs_xattr_handlers[] = {
 #endif
 #ifdef CONFIG_REISERFS_FS_SECURITY
        &reiserfs_xattr_security_handler,
-#endif
-#ifdef CONFIG_REISERFS_FS_POSIX_ACL
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
 #endif
        NULL
 };
@@ -975,10 +978,8 @@ int reiserfs_lookup_privroot(struct super_block *s)
        if (!IS_ERR(dentry)) {
                REISERFS_SB(s)->priv_root = dentry;
                d_set_d_op(dentry, &xattr_lookup_poison_ops);
-               if (d_really_is_positive(dentry)) {
-                       d_inode(dentry)->i_flags |= S_PRIVATE;
-                       d_inode(dentry)->i_opflags &= ~IOP_XATTR;
-               }
+               if (d_really_is_positive(dentry))
+                       reiserfs_init_priv_inode(d_inode(dentry));
        } else
                err = PTR_ERR(dentry);
        inode_unlock(d_inode(s->s_root));
index 41c0ea84fbffcae46eef80b1580230c3dae289b2..6e0a099dd7886bd571aa4a4c56957de7a6f357ac 100644 (file)
@@ -39,6 +39,22 @@ static bool security_list(struct dentry *dentry)
        return !IS_PRIVATE(d_inode(dentry));
 }
 
+static int
+reiserfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
+                   void *fs_info)
+{
+       struct reiserfs_security_handle *sec = fs_info;
+
+       sec->value = kmemdup(xattr_array->value, xattr_array->value_len,
+                            GFP_KERNEL);
+       if (!sec->value)
+               return -ENOMEM;
+
+       sec->name = xattr_array->name;
+       sec->length = xattr_array->value_len;
+       return 0;
+}
+
 /* Initializes the security context for a new inode and returns the number
  * of blocks needed for the transaction. If successful, reiserfs_security
  * must be released using reiserfs_security_free when the caller is done. */
@@ -56,12 +72,9 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode,
        if (IS_PRIVATE(dir))
                return 0;
 
-       error = security_old_inode_init_security(inode, dir, qstr, &sec->name,
-                                                &sec->value, &sec->length);
+       error = security_inode_init_security(inode, dir, qstr,
+                                            &reiserfs_initxattrs, sec);
        if (error) {
-               if (error == -EOPNOTSUPP)
-                       error = 0;
-
                sec->name = NULL;
                sec->value = NULL;
                sec->length = 0;
@@ -82,11 +95,15 @@ int reiserfs_security_write(struct reiserfs_transaction_handle *th,
                            struct inode *inode,
                            struct reiserfs_security_handle *sec)
 {
+       char xattr_name[XATTR_NAME_MAX + 1] = XATTR_SECURITY_PREFIX;
        int error;
-       if (strlen(sec->name) < sizeof(XATTR_SECURITY_PREFIX))
+
+       if (XATTR_SECURITY_PREFIX_LEN + strlen(sec->name) > XATTR_NAME_MAX)
                return -EINVAL;
 
-       error = reiserfs_xattr_set_handle(th, inode, sec->name, sec->value,
+       strlcat(xattr_name, sec->name, sizeof(xattr_name));
+
+       error = reiserfs_xattr_set_handle(th, inode, xattr_name, sec->value,
                                          sec->length, XATTR_CREATE);
        if (error == -ENODATA || error == -EOPNOTSUPP)
                error = 0;
index 2e76dbb81a8fc193a1d2124748fc652265e0a5e2..0af8d150394f6a968ba37a7c2f88afad1b2914fa 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/export.h>
 #include <linux/syscalls.h>
 #include <linux/uio.h>
+#include <linux/fsnotify.h>
 #include <linux/security.h>
 #include <linux/gfp.h>
 #include <linux/socket.h>
@@ -937,7 +938,6 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
        /*
         * Do the splice.
         */
-       ret = 0;
        bytes = 0;
        len = sd->total_len;
        flags = sd->flags;
@@ -1166,6 +1166,9 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
                ret = do_splice_from(ipipe, out, &offset, len, flags);
                file_end_write(out);
 
+               if (ret > 0)
+                       fsnotify_modify(out);
+
                if (!off_out)
                        out->f_pos = offset;
                else
@@ -1189,6 +1192,10 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
                        flags |= SPLICE_F_NONBLOCK;
 
                ret = splice_file_to_pipe(in, opipe, &offset, len, flags);
+
+               if (ret > 0)
+                       fsnotify_access(in);
+
                if (!off_in)
                        in->f_pos = offset;
                else
index 84332d5cb817abbec2e206f7d25ce5db134a8fc8..04bc62ab7dfea9dde08c407fd4b5c04a7cbaedb0 100644 (file)
@@ -475,13 +475,22 @@ void generic_shutdown_super(struct super_block *sb)
 
                cgroup_writeback_umount();
 
-               /* evict all inodes with zero refcount */
+               /* Evict all inodes with zero refcount. */
                evict_inodes(sb);
-               /* only nonzero refcount inodes can have marks */
+
+               /*
+                * Clean up and evict any inodes that still have references due
+                * to fsnotify or the security policy.
+                */
                fsnotify_sb_delete(sb);
-               fscrypt_destroy_keyring(sb);
                security_sb_delete(sb);
 
+               /*
+                * Now that all potentially-encrypted inodes have been evicted,
+                * the fscrypt keyring can be destroyed.
+                */
+               fscrypt_destroy_keyring(sb);
+
                if (sb->s_dio_done_wq) {
                        destroy_workqueue(sb->s_dio_done_wq);
                        sb->s_dio_done_wq = NULL;
index 999bceb999742804f3b8cb3b5ededa5ffa724ea5..cdb3d632c63da878f83fff438267532ccebb8277 100644 (file)
@@ -28,12 +28,6 @@ const struct file_operations sysv_dir_operations = {
        .fsync          = generic_file_fsync,
 };
 
-inline void dir_put_page(struct page *page, void *page_addr)
-{
-       kunmap_local((void *)((unsigned long)page_addr & PAGE_MASK));
-       put_page(page);
-}
-
 static void dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
 {
        struct address_space *mapping = page->mapping;
@@ -58,7 +52,7 @@ static int sysv_handle_dirsync(struct inode *dir)
 }
 
 /*
- * Calls to dir_get_page()/dir_put_page() must be nested according to the
+ * Calls to dir_get_page()/put_and_unmap_page() must be nested according to the
  * rules documented in mm/highmem.rst.
  *
  * NOTE: sysv_find_entry() and sysv_dotdot() act as calls to dir_get_page()
@@ -109,11 +103,11 @@ static int sysv_readdir(struct file *file, struct dir_context *ctx)
                        if (!dir_emit(ctx, name, strnlen(name,SYSV_NAMELEN),
                                        fs16_to_cpu(SYSV_SB(sb), de->inode),
                                        DT_UNKNOWN)) {
-                               dir_put_page(page, kaddr);
+                               put_and_unmap_page(page, kaddr);
                                return 0;
                        }
                }
-               dir_put_page(page, kaddr);
+               put_and_unmap_page(page, kaddr);
        }
        return 0;
 }
@@ -137,7 +131,7 @@ static inline int namecompare(int len, int maxlen,
  * itself (as a parameter - res_dir). It does NOT read the inode of the
  * entry - you'll have to do that yourself if you want to.
  *
- * On Success dir_put_page() should be called on *res_page.
+ * On Success put_and_unmap_page() should be called on *res_page.
  *
  * sysv_find_entry() acts as a call to dir_get_page() and must be treated
  * accordingly for nesting purposes.
@@ -172,7 +166,7 @@ struct sysv_dir_entry *sysv_find_entry(struct dentry *dentry, struct page **res_
                                                        name, de->name))
                                        goto found;
                        }
-                       dir_put_page(page, kaddr);
+                       put_and_unmap_page(page, kaddr);
                }
 
                if (++n >= npages)
@@ -215,7 +209,7 @@ int sysv_add_link(struct dentry *dentry, struct inode *inode)
                                goto out_page;
                        de++;
                }
-               dir_put_page(page, kaddr);
+               put_and_unmap_page(page, kaddr);
        }
        BUG();
        return -EINVAL;
@@ -234,7 +228,7 @@ got_it:
        mark_inode_dirty(dir);
        err = sysv_handle_dirsync(dir);
 out_page:
-       dir_put_page(page, kaddr);
+       put_and_unmap_page(page, kaddr);
        return err;
 out_unlock:
        unlock_page(page);
@@ -327,12 +321,12 @@ int sysv_empty_dir(struct inode * inode)
                        if (de->name[1] != '.' || de->name[2])
                                goto not_empty;
                }
-               dir_put_page(page, kaddr);
+               put_and_unmap_page(page, kaddr);
        }
        return 1;
 
 not_empty:
-       dir_put_page(page, kaddr);
+       put_and_unmap_page(page, kaddr);
        return 0;
 }
 
@@ -358,7 +352,7 @@ int sysv_set_link(struct sysv_dir_entry *de, struct page *page,
 }
 
 /*
- * Calls to dir_get_page()/dir_put_page() must be nested according to the
+ * Calls to dir_get_page()/put_and_unmap_page() must be nested according to the
  * rules documented in mm/highmem.rst.
  *
  * sysv_dotdot() acts as a call to dir_get_page() and must be treated
@@ -382,7 +376,7 @@ ino_t sysv_inode_by_name(struct dentry *dentry)
        
        if (de) {
                res = fs16_to_cpu(SYSV_SB(dentry->d_sb), de->inode);
-               dir_put_page(page, de);
+               put_and_unmap_page(page, de);
        }
        return res;
 }
index a25862773d82cf53a7bb5b02200ff2f62f34f541..2b2dba4c4f56ec3e41a0e401d94ee627d09b08b7 100644 (file)
@@ -164,7 +164,7 @@ static int sysv_unlink(struct inode * dir, struct dentry * dentry)
                inode->i_ctime = dir->i_ctime;
                inode_dec_link_count(inode);
        }
-       dir_put_page(page, de);
+       put_and_unmap_page(page, de);
        return err;
 }
 
@@ -227,7 +227,7 @@ static int sysv_rename(struct mnt_idmap *idmap, struct inode *old_dir,
                if (!new_de)
                        goto out_dir;
                err = sysv_set_link(new_de, new_page, old_inode);
-               dir_put_page(new_page, new_de);
+               put_and_unmap_page(new_page, new_de);
                if (err)
                        goto out_dir;
                new_inode->i_ctime = current_time(new_inode);
@@ -256,9 +256,9 @@ static int sysv_rename(struct mnt_idmap *idmap, struct inode *old_dir,
 
 out_dir:
        if (dir_de)
-               dir_put_page(dir_page, dir_de);
+               put_and_unmap_page(dir_page, dir_de);
 out_old:
-       dir_put_page(old_page, old_de);
+       put_and_unmap_page(old_page, old_de);
 out:
        return err;
 }
index f2c36ea42df66d050cf45e1e50a2df1eaf333dfa..e3f988b469ee98d7451a7174e158c02adad91393 100644 (file)
@@ -148,7 +148,6 @@ extern void sysv_destroy_icache(void);
 
 
 /* dir.c */
-extern void dir_put_page(struct page *page, void *vaddr);
 extern struct sysv_dir_entry *sysv_find_entry(struct dentry *, struct page **);
 extern int sysv_add_link(struct dentry *, struct inode *);
 extern int sysv_delete_entry(struct sysv_dir_entry *, struct page *);
index f7a9607c2b9578ce459dee3ebc87360ea834f327..2210e5eb1ea06e9b16b824c0662f976f919e8d05 100644 (file)
@@ -193,7 +193,7 @@ static int udf_adinicb_writepage(struct folio *folio,
        struct udf_inode_info *iinfo = UDF_I(inode);
 
        BUG_ON(!PageLocked(page));
-       memcpy_to_page(page, 0, iinfo->i_data + iinfo->i_lenEAttr,
+       memcpy_from_page(iinfo->i_data + iinfo->i_lenEAttr, page, 0,
                       i_size_read(inode));
        unlock_page(page);
        mark_inode_dirty(inode);
@@ -241,6 +241,15 @@ static int udf_read_folio(struct file *file, struct folio *folio)
 
 static void udf_readahead(struct readahead_control *rac)
 {
+       struct udf_inode_info *iinfo = UDF_I(rac->mapping->host);
+
+       /*
+        * No readahead needed for in-ICB files and udf_get_block() would get
+        * confused for such file anyway.
+        */
+       if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
+               return;
+
        mpage_readahead(rac, udf_get_block);
 }
 
@@ -407,6 +416,9 @@ static int udf_map_block(struct inode *inode, struct udf_map_rq *map)
        int err;
        struct udf_inode_info *iinfo = UDF_I(inode);
 
+       if (WARN_ON_ONCE(iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB))
+               return -EFSCORRUPTED;
+
        map->oflags = 0;
        if (!(map->iflags & UDF_MAP_CREATE)) {
                struct kernel_lb_addr eloc;
index 391efaf1d528975256d9ac4cd3230daaaebb4702..379d75796a5ce305e2e2dcc2921153bbd6006f6b 100644 (file)
@@ -42,11 +42,10 @@ static inline int ufs_match(struct super_block *sb, int len,
        return !memcmp(name, de->d_name, len);
 }
 
-static int ufs_commit_chunk(struct page *page, loff_t pos, unsigned len)
+static void ufs_commit_chunk(struct page *page, loff_t pos, unsigned len)
 {
        struct address_space *mapping = page->mapping;
        struct inode *dir = mapping->host;
-       int err = 0;
 
        inode_inc_iversion(dir);
        block_write_end(NULL, mapping, pos, len, len, page, NULL);
@@ -54,10 +53,16 @@ static int ufs_commit_chunk(struct page *page, loff_t pos, unsigned len)
                i_size_write(dir, pos+len);
                mark_inode_dirty(dir);
        }
-       if (IS_DIRSYNC(dir))
-               err = write_one_page(page);
-       else
-               unlock_page(page);
+       unlock_page(page);
+}
+
+static int ufs_handle_dirsync(struct inode *dir)
+{
+       int err;
+
+       err = filemap_write_and_wait(dir->i_mapping);
+       if (!err)
+               err = sync_inode_metadata(dir, 1);
        return err;
 }
 
@@ -99,11 +104,12 @@ void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
        de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino);
        ufs_set_de_type(dir->i_sb, de, inode->i_mode);
 
-       err = ufs_commit_chunk(page, pos, len);
+       ufs_commit_chunk(page, pos, len);
        ufs_put_page(page);
        if (update_times)
                dir->i_mtime = dir->i_ctime = current_time(dir);
        mark_inode_dirty(dir);
+       ufs_handle_dirsync(dir);
 }
 
 
@@ -390,10 +396,11 @@ got_it:
        de->d_ino = cpu_to_fs32(sb, inode->i_ino);
        ufs_set_de_type(sb, de, inode->i_mode);
 
-       err = ufs_commit_chunk(page, pos, rec_len);
+       ufs_commit_chunk(page, pos, rec_len);
        dir->i_mtime = dir->i_ctime = current_time(dir);
 
        mark_inode_dirty(dir);
+       err = ufs_handle_dirsync(dir);
        /* OFFSET_CACHE */
 out_put:
        ufs_put_page(page);
@@ -531,9 +538,10 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
        if (pde)
                pde->d_reclen = cpu_to_fs16(sb, to - from);
        dir->d_ino = 0;
-       err = ufs_commit_chunk(page, pos, to - from);
+       ufs_commit_chunk(page, pos, to - from);
        inode->i_ctime = inode->i_mtime = current_time(inode);
        mark_inode_dirty(inode);
+       err = ufs_handle_dirsync(inode);
 out:
        ufs_put_page(page);
        UFSD("EXIT\n");
@@ -579,7 +587,8 @@ int ufs_make_empty(struct inode * inode, struct inode *dir)
        strcpy (de->d_name, "..");
        kunmap(page);
 
-       err = ufs_commit_chunk(page, 0, chunk_size);
+       ufs_commit_chunk(page, 0, chunk_size);
+       err = ufs_handle_dirsync(inode);
 fail:
        put_page(page);
        return err;
index 44d1ee429eb0c71d223cfe8364506dd636143d6f..40f9e1a2ebdd6d2d10a84167898af571ce2201e2 100644 (file)
@@ -1955,8 +1955,10 @@ static int userfaultfd_api(struct userfaultfd_ctx *ctx,
        ret = -EFAULT;
        if (copy_from_user(&uffdio_api, buf, sizeof(uffdio_api)))
                goto out;
-       /* Ignore unsupported features (userspace built against newer kernel) */
-       features = uffdio_api.features & UFFD_API_FEATURES;
+       features = uffdio_api.features;
+       ret = -EINVAL;
+       if (uffdio_api.api != UFFD_API || (features & ~UFFD_API_FEATURES))
+               goto err_out;
        ret = -EPERM;
        if ((features & UFFD_FEATURE_EVENT_FORK) && !capable(CAP_SYS_PTRACE))
                goto err_out;
index e13db6507b38b64b3c7e3acaff729831fc3daab2..7a0e3a84d370bc1d3a320762c7781fd4f752ec14 100644 (file)
@@ -8,7 +8,6 @@
 #include "fsverity_private.h"
 
 #include <linux/mount.h>
-#include <linux/pagemap.h>
 #include <linux/sched/signal.h>
 #include <linux/uaccess.h>
 
@@ -367,25 +366,27 @@ int fsverity_ioctl_enable(struct file *filp, const void __user *uarg)
                goto out_drop_write;
 
        err = enable_verity(filp, &arg);
-       if (err)
-               goto out_allow_write_access;
 
        /*
-        * Some pages of the file may have been evicted from pagecache after
-        * being used in the Merkle tree construction, then read into pagecache
-        * again by another process reading from the file concurrently.  Since
-        * these pages didn't undergo verification against the file digest which
-        * fs-verity now claims to be enforcing, we have to wipe the pagecache
-        * to ensure that all future reads are verified.
+        * We no longer drop the inode's pagecache after enabling verity.  This
+        * used to be done to try to avoid a race condition where pages could be
+        * evicted after being used in the Merkle tree construction, then
+        * re-instantiated by a concurrent read.  Such pages are unverified, and
+        * the backing storage could have filled them with different content, so
+        * they shouldn't be used to fulfill reads once verity is enabled.
+        *
+        * But, dropping the pagecache has a big performance impact, and it
+        * doesn't fully solve the race condition anyway.  So for those reasons,
+        * and also because this race condition isn't very important relatively
+        * speaking (especially for small-ish files, where the chance of a page
+        * being used, evicted, *and* re-instantiated all while enabling verity
+        * is quite small), we no longer drop the inode's pagecache.
         */
-       filemap_write_and_wait(inode->i_mapping);
-       invalidate_inode_pages2(inode->i_mapping);
 
        /*
         * allow_write_access() is needed to pair with deny_write_access().
         * Regardless, the filesystem won't allow writing to verity files.
         */
-out_allow_write_access:
        allow_write_access(filp);
 out_drop_write:
        mnt_drop_write_file(filp);
index f50e3b5b52c932eb3635a9fc146ba3aad6126270..e2508222750b35eabe154cf1d5609f95680bcc69 100644 (file)
@@ -387,15 +387,15 @@ EXPORT_SYMBOL_GPL(fsverity_enqueue_verify_work);
 int __init fsverity_init_workqueue(void)
 {
        /*
-        * Use an unbound workqueue to allow bios to be verified in parallel
-        * even when they happen to complete on the same CPU.  This sacrifices
-        * locality, but it's worthwhile since hashing is CPU-intensive.
+        * Use a high-priority workqueue to prioritize verification work, which
+        * blocks reads from completing, over regular application tasks.
         *
-        * Also use a high-priority workqueue to prioritize verification work,
-        * which blocks reads from completing, over regular application tasks.
+        * For performance reasons, don't use an unbound workqueue.  Using an
+        * unbound workqueue for crypto operations causes excessive scheduler
+        * latency on ARM64.
         */
        fsverity_read_workqueue = alloc_workqueue("fsverity_read_queue",
-                                                 WQ_UNBOUND | WQ_HIGHPRI,
+                                                 WQ_HIGHPRI,
                                                  num_online_cpus());
        if (!fsverity_read_workqueue)
                return -ENOMEM;
index 14a7eb3c8fa898ffb2a697968efb9eb70bd7bac2..fcf67d80d7f9cad3d3d8c3b6672f4100e87aed0e 100644 (file)
@@ -160,11 +160,10 @@ xattr_permission(struct mnt_idmap *idmap, struct inode *inode,
  * Look for any handler that deals with the specified namespace.
  */
 int
-xattr_supported_namespace(struct inode *inode, const char *prefix)
+xattr_supports_user_prefix(struct inode *inode)
 {
        const struct xattr_handler **handlers = inode->i_sb->s_xattr;
        const struct xattr_handler *handler;
-       size_t preflen;
 
        if (!(inode->i_opflags & IOP_XATTR)) {
                if (unlikely(is_bad_inode(inode)))
@@ -172,16 +171,15 @@ xattr_supported_namespace(struct inode *inode, const char *prefix)
                return -EOPNOTSUPP;
        }
 
-       preflen = strlen(prefix);
-
        for_each_xattr_handler(handlers, handler) {
-               if (!strncmp(xattr_prefix(handler), prefix, preflen))
+               if (!strncmp(xattr_prefix(handler), XATTR_USER_PREFIX,
+                            XATTR_USER_PREFIX_LEN))
                        return 0;
        }
 
        return -EOPNOTSUPP;
 }
-EXPORT_SYMBOL(xattr_supported_namespace);
+EXPORT_SYMBOL(xattr_supports_user_prefix);
 
 int
 __vfs_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
@@ -460,6 +458,28 @@ nolsm:
 }
 EXPORT_SYMBOL_GPL(vfs_getxattr);
 
+/**
+ * vfs_listxattr - retrieve \0 separated list of xattr names
+ * @dentry: the dentry from whose inode the xattr names are retrieved
+ * @list: buffer to store xattr names into
+ * @size: size of the buffer
+ *
+ * This function returns the names of all xattrs associated with the
+ * inode of @dentry.
+ *
+ * Note, for legacy reasons the vfs_listxattr() function lists POSIX
+ * ACLs as well. Since POSIX ACLs are decoupled from IOP_XATTR the
+ * vfs_listxattr() function doesn't check for this flag since a
+ * filesystem could implement POSIX ACLs without implementing any other
+ * xattrs.
+ *
+ * However, since all codepaths that remove IOP_XATTR also assign of
+ * inode operations that either don't implement or implement a stub
+ * ->listxattr() operation.
+ *
+ * Return: On success, the size of the buffer that was used. On error a
+ *         negative error code.
+ */
 ssize_t
 vfs_listxattr(struct dentry *dentry, char *list, size_t size)
 {
@@ -469,7 +489,8 @@ vfs_listxattr(struct dentry *dentry, char *list, size_t size)
        error = security_inode_listxattr(dentry);
        if (error)
                return error;
-       if (inode->i_op->listxattr && (inode->i_opflags & IOP_XATTR)) {
+
+       if (inode->i_op->listxattr) {
                error = inode->i_op->listxattr(dentry, list, size);
        } else {
                error = security_inode_listsecurity(inode, list, size);
@@ -949,6 +970,21 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)
        return error;
 }
 
+int xattr_list_one(char **buffer, ssize_t *remaining_size, const char *name)
+{
+       size_t len;
+
+       len = strlen(name) + 1;
+       if (*buffer) {
+               if (*remaining_size < len)
+                       return -ERANGE;
+               memcpy(*buffer, name, len);
+               *buffer += len;
+       }
+       *remaining_size -= len;
+       return 0;
+}
+
 /*
  * Combine the results of the list() operation from every xattr_handler in the
  * list.
@@ -957,33 +993,22 @@ ssize_t
 generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
 {
        const struct xattr_handler *handler, **handlers = dentry->d_sb->s_xattr;
-       unsigned int size = 0;
-
-       if (!buffer) {
-               for_each_xattr_handler(handlers, handler) {
-                       if (!handler->name ||
-                           (handler->list && !handler->list(dentry)))
-                               continue;
-                       size += strlen(handler->name) + 1;
-               }
-       } else {
-               char *buf = buffer;
-               size_t len;
-
-               for_each_xattr_handler(handlers, handler) {
-                       if (!handler->name ||
-                           (handler->list && !handler->list(dentry)))
-                               continue;
-                       len = strlen(handler->name);
-                       if (len + 1 > buffer_size)
-                               return -ERANGE;
-                       memcpy(buf, handler->name, len + 1);
-                       buf += len + 1;
-                       buffer_size -= len + 1;
-               }
-               size = buf - buffer;
+       ssize_t remaining_size = buffer_size;
+       int err = 0;
+
+       err = posix_acl_listxattr(d_inode(dentry), &buffer, &remaining_size);
+       if (err)
+               return err;
+
+       for_each_xattr_handler(handlers, handler) {
+               if (!handler->name || (handler->list && !handler->list(dentry)))
+                       continue;
+               err = xattr_list_one(&buffer, &remaining_size, handler->name);
+               if (err)
+                       return err;
        }
-       return size;
+
+       return err ? err : buffer_size - remaining_size;
 }
 EXPORT_SYMBOL(generic_listxattr);
 
@@ -1245,20 +1270,6 @@ static bool xattr_is_trusted(const char *name)
        return !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN);
 }
 
-static int xattr_list_one(char **buffer, ssize_t *remaining_size,
-                         const char *name)
-{
-       size_t len = strlen(name) + 1;
-       if (*buffer) {
-               if (*remaining_size < len)
-                       return -ERANGE;
-               memcpy(*buffer, name, len);
-               *buffer += len;
-       }
-       *remaining_size -= len;
-       return 0;
-}
-
 /**
  * simple_xattr_list - list all xattr objects
  * @inode: inode from which to get the xattrs
@@ -1287,22 +1298,9 @@ ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
        ssize_t remaining_size = size;
        int err = 0;
 
-#ifdef CONFIG_FS_POSIX_ACL
-       if (IS_POSIXACL(inode)) {
-               if (inode->i_acl) {
-                       err = xattr_list_one(&buffer, &remaining_size,
-                                            XATTR_NAME_POSIX_ACL_ACCESS);
-                       if (err)
-                               return err;
-               }
-               if (inode->i_default_acl) {
-                       err = xattr_list_one(&buffer, &remaining_size,
-                                            XATTR_NAME_POSIX_ACL_DEFAULT);
-                       if (err)
-                               return err;
-               }
-       }
-#endif
+       err = posix_acl_listxattr(inode, &buffer, &remaining_size);
+       if (err)
+               return err;
 
        read_lock(&xattrs->lock);
        for (rbp = rb_first(&xattrs->rb_root); rbp; rbp = rb_next(rbp)) {
index 03135a1c31b673fa435ed3853e83b166eb5e6b29..92d88dc3c9f71fad2424ddfba6692234ff57e16b 100644 (file)
@@ -63,6 +63,7 @@ xfs-y                         += xfs_aops.o \
                                   xfs_bmap_util.o \
                                   xfs_bio_io.o \
                                   xfs_buf.o \
+                                  xfs_dahash_test.o \
                                   xfs_dir2_readdir.o \
                                   xfs_discard.o \
                                   xfs_error.o \
index 6a037173d20d99e60239ad51e15c2a66822ae5df..203f16c48c19902e607b77250d41114d67205b97 100644 (file)
@@ -3045,6 +3045,8 @@ xfs_alloc_read_agf(
                pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level);
                if (xfs_agfl_needs_reset(pag->pag_mount, agf))
                        set_bit(XFS_AGSTATE_AGFL_NEEDS_RESET, &pag->pag_opstate);
+               else
+                       clear_bit(XFS_AGSTATE_AGFL_NEEDS_RESET, &pag->pag_opstate);
 
                /*
                 * Update the in-core allocbt counter. Filter out the rmapbt
@@ -3255,6 +3257,8 @@ xfs_alloc_vextent_finish(
        XFS_STATS_INC(mp, xs_allocx);
        XFS_STATS_ADD(mp, xs_allocb, args->len);
 
+       trace_xfs_alloc_vextent_finish(args);
+
 out_drop_perag:
        if (drop_perag && args->pag) {
                xfs_perag_rele(args->pag);
@@ -3279,8 +3283,14 @@ xfs_alloc_vextent_this_ag(
        xfs_agnumber_t          minimum_agno;
        int                     error;
 
+       ASSERT(args->pag != NULL);
+       ASSERT(args->pag->pag_agno == agno);
+
        args->agno = agno;
        args->agbno = 0;
+
+       trace_xfs_alloc_vextent_this_ag(args);
+
        error = xfs_alloc_vextent_check_args(args, XFS_AGB_TO_FSB(mp, agno, 0),
                        &minimum_agno);
        if (error) {
@@ -3323,11 +3333,14 @@ xfs_alloc_vextent_iterate_ags(
        uint32_t                flags)
 {
        struct xfs_mount        *mp = args->mp;
+       xfs_agnumber_t          restart_agno = minimum_agno;
        xfs_agnumber_t          agno;
        int                     error = 0;
 
+       if (flags & XFS_ALLOC_FLAG_TRYLOCK)
+               restart_agno = 0;
 restart:
-       for_each_perag_wrap_range(mp, start_agno, minimum_agno,
+       for_each_perag_wrap_range(mp, start_agno, restart_agno,
                        mp->m_sb.sb_agcount, agno, args->pag) {
                args->agno = agno;
                error = xfs_alloc_vextent_prepare_ag(args);
@@ -3366,6 +3379,7 @@ restart:
         */
        if (flags) {
                flags = 0;
+               restart_agno = minimum_agno;
                goto restart;
        }
 
@@ -3394,8 +3408,13 @@ xfs_alloc_vextent_start_ag(
        bool                    bump_rotor = false;
        int                     error;
 
+       ASSERT(args->pag == NULL);
+
        args->agno = NULLAGNUMBER;
        args->agbno = NULLAGBLOCK;
+
+       trace_xfs_alloc_vextent_start_ag(args);
+
        error = xfs_alloc_vextent_check_args(args, target, &minimum_agno);
        if (error) {
                if (error == -ENOSPC)
@@ -3442,8 +3461,13 @@ xfs_alloc_vextent_first_ag(
        xfs_agnumber_t          start_agno;
        int                     error;
 
+       ASSERT(args->pag == NULL);
+
        args->agno = NULLAGNUMBER;
        args->agbno = NULLAGBLOCK;
+
+       trace_xfs_alloc_vextent_first_ag(args);
+
        error = xfs_alloc_vextent_check_args(args, target, &minimum_agno);
        if (error) {
                if (error == -ENOSPC)
@@ -3470,8 +3494,14 @@ xfs_alloc_vextent_exact_bno(
        xfs_agnumber_t          minimum_agno;
        int                     error;
 
+       ASSERT(args->pag != NULL);
+       ASSERT(args->pag->pag_agno == XFS_FSB_TO_AGNO(mp, target));
+
        args->agno = XFS_FSB_TO_AGNO(mp, target);
        args->agbno = XFS_FSB_TO_AGBNO(mp, target);
+
+       trace_xfs_alloc_vextent_exact_bno(args);
+
        error = xfs_alloc_vextent_check_args(args, target, &minimum_agno);
        if (error) {
                if (error == -ENOSPC)
@@ -3502,8 +3532,14 @@ xfs_alloc_vextent_near_bno(
        bool                    needs_perag = args->pag == NULL;
        int                     error;
 
+       if (!needs_perag)
+               ASSERT(args->pag->pag_agno == XFS_FSB_TO_AGNO(mp, target));
+
        args->agno = XFS_FSB_TO_AGNO(mp, target);
        args->agbno = XFS_FSB_TO_AGBNO(mp, target);
+
+       trace_xfs_alloc_vextent_near_bno(args);
+
        error = xfs_alloc_vextent_check_args(args, target, &minimum_agno);
        if (error) {
                if (error == -ENOSPC)
index 41734202796f4ccb1bbee62ce5ccef0991073a9d..2ef78aa1d3f608713d934a07055d8f93b9ed6fa7 100644 (file)
@@ -449,15 +449,17 @@ xfs_prepare_ioend(
 }
 
 /*
- * If the page has delalloc blocks on it, we need to punch them out before we
- * invalidate the page.  If we don't, we leave a stale delalloc mapping on the
- * inode that can trip up a later direct I/O read operation on the same region.
+ * If the folio has delalloc blocks on it, the caller is asking us to punch them
+ * out. If we don't, we can leave a stale delalloc mapping covered by a clean
+ * page that needs to be dirtied again before the delalloc mapping can be
+ * converted. This stale delalloc mapping can trip up a later direct I/O read
+ * operation on the same region.
  *
- * We prevent this by truncating away the delalloc regions on the page.  Because
+ * We prevent this by truncating away the delalloc regions on the folio. Because
  * they are delalloc, we can do this without needing a transaction. Indeed - if
  * we get ENOSPC errors, we have to be able to do this truncation without a
- * transaction as there is no space left for block reservation (typically why we
- * see a ENOSPC in writeback).
+ * transaction as there is no space left for block reservation (typically why
+ * we see a ENOSPC in writeback).
  */
 static void
 xfs_discard_folio(
@@ -475,8 +477,13 @@ xfs_discard_folio(
                "page discard on page "PTR_FMT", inode 0x%llx, pos %llu.",
                        folio, ip->i_ino, pos);
 
+       /*
+        * The end of the punch range is always the offset of the the first
+        * byte of the next folio. Hence the end offset is only dependent on the
+        * folio itself and not the start offset that is passed in.
+        */
        error = xfs_bmap_punch_delalloc_range(ip, pos,
-                       round_up(pos, folio_size(folio)));
+                               folio_pos(folio) + folio_size(folio));
 
        if (error && !xfs_is_shutdown(mp))
                xfs_alert(mp, "page discard unable to remove delalloc mapping.");
diff --git a/fs/xfs/xfs_dahash_test.c b/fs/xfs/xfs_dahash_test.c
new file mode 100644 (file)
index 0000000..230651a
--- /dev/null
@@ -0,0 +1,662 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 Oracle.  All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#include "xfs.h"
+#include "xfs_fs.h"
+#include "xfs_shared.h"
+#include "xfs_format.h"
+#include "xfs_da_format.h"
+#include "xfs_da_btree.h"
+#include "xfs_dahash_test.h"
+
+/* 4096 random bytes */
+static uint8_t __initdata __attribute__((__aligned__(8))) test_buf[] =
+{
+       0x5b, 0x85, 0x21, 0xcb, 0x09, 0x68, 0x7d, 0x30,
+       0xc7, 0x69, 0xd7, 0x30, 0x92, 0xde, 0x59, 0xe4,
+       0xc9, 0x6e, 0x8b, 0xdb, 0x98, 0x6b, 0xaa, 0x60,
+       0xa8, 0xb5, 0xbc, 0x6c, 0xa9, 0xb1, 0x5b, 0x2c,
+       0xea, 0xb4, 0x92, 0x6a, 0x3f, 0x79, 0x91, 0xe4,
+       0xe9, 0x70, 0x51, 0x8c, 0x7f, 0x95, 0x6f, 0x1a,
+       0x56, 0xa1, 0x5c, 0x27, 0x03, 0x67, 0x9f, 0x3a,
+       0xe2, 0x31, 0x11, 0x29, 0x6b, 0x98, 0xfc, 0xc4,
+       0x53, 0x24, 0xc5, 0x8b, 0xce, 0x47, 0xb2, 0xb9,
+       0x32, 0xcb, 0xc1, 0xd0, 0x03, 0x57, 0x4e, 0xd4,
+       0xe9, 0x3c, 0xa1, 0x63, 0xcf, 0x12, 0x0e, 0xca,
+       0xe1, 0x13, 0xd1, 0x93, 0xa6, 0x88, 0x5c, 0x61,
+       0x5b, 0xbb, 0xf0, 0x19, 0x46, 0xb4, 0xcf, 0x9e,
+       0xb6, 0x6b, 0x4c, 0x3a, 0xcf, 0x60, 0xf9, 0x7a,
+       0x8d, 0x07, 0x63, 0xdb, 0x40, 0xe9, 0x0b, 0x6f,
+       0xad, 0x97, 0xf1, 0xed, 0xd0, 0x1e, 0x26, 0xfd,
+       0xbf, 0xb7, 0xc8, 0x04, 0x94, 0xf8, 0x8b, 0x8c,
+       0xf1, 0xab, 0x7a, 0xd4, 0xdd, 0xf3, 0xe8, 0x88,
+       0xc3, 0xed, 0x17, 0x8a, 0x9b, 0x40, 0x0d, 0x53,
+       0x62, 0x12, 0x03, 0x5f, 0x1b, 0x35, 0x32, 0x1f,
+       0xb4, 0x7b, 0x93, 0x78, 0x0d, 0xdb, 0xce, 0xa4,
+       0xc0, 0x47, 0xd5, 0xbf, 0x68, 0xe8, 0x5d, 0x74,
+       0x8f, 0x8e, 0x75, 0x1c, 0xb2, 0x4f, 0x9a, 0x60,
+       0xd1, 0xbe, 0x10, 0xf4, 0x5c, 0xa1, 0x53, 0x09,
+       0xa5, 0xe0, 0x09, 0x54, 0x85, 0x5c, 0xdc, 0x07,
+       0xe7, 0x21, 0x69, 0x7b, 0x8a, 0xfd, 0x90, 0xf1,
+       0x22, 0xd0, 0xb4, 0x36, 0x28, 0xe6, 0xb8, 0x0f,
+       0x39, 0xde, 0xc8, 0xf3, 0x86, 0x60, 0x34, 0xd2,
+       0x5e, 0xdf, 0xfd, 0xcf, 0x0f, 0xa9, 0x65, 0xf0,
+       0xd5, 0x4d, 0x96, 0x40, 0xe3, 0xdf, 0x3f, 0x95,
+       0x5a, 0x39, 0x19, 0x93, 0xf4, 0x75, 0xce, 0x22,
+       0x00, 0x1c, 0x93, 0xe2, 0x03, 0x66, 0xf4, 0x93,
+       0x73, 0x86, 0x81, 0x8e, 0x29, 0x44, 0x48, 0x86,
+       0x61, 0x7c, 0x48, 0xa3, 0x43, 0xd2, 0x9c, 0x8d,
+       0xd4, 0x95, 0xdd, 0xe1, 0x22, 0x89, 0x3a, 0x40,
+       0x4c, 0x1b, 0x8a, 0x04, 0xa8, 0x09, 0x69, 0x8b,
+       0xea, 0xc6, 0x55, 0x8e, 0x57, 0xe6, 0x64, 0x35,
+       0xf0, 0xc7, 0x16, 0x9f, 0x5d, 0x5e, 0x86, 0x40,
+       0x46, 0xbb, 0xe5, 0x45, 0x88, 0xfe, 0xc9, 0x63,
+       0x15, 0xfb, 0xf5, 0xbd, 0x71, 0x61, 0xeb, 0x7b,
+       0x78, 0x70, 0x07, 0x31, 0x03, 0x9f, 0xb2, 0xc8,
+       0xa7, 0xab, 0x47, 0xfd, 0xdf, 0xa0, 0x78, 0x72,
+       0xa4, 0x2a, 0xe4, 0xb6, 0xba, 0xc0, 0x1e, 0x86,
+       0x71, 0xe6, 0x3d, 0x18, 0x37, 0x70, 0xe6, 0xff,
+       0xe0, 0xbc, 0x0b, 0x22, 0xa0, 0x1f, 0xd3, 0xed,
+       0xa2, 0x55, 0x39, 0xab, 0xa8, 0x13, 0x73, 0x7c,
+       0x3f, 0xb2, 0xd6, 0x19, 0xac, 0xff, 0x99, 0xed,
+       0xe8, 0xe6, 0xa6, 0x22, 0xe3, 0x9c, 0xf1, 0x30,
+       0xdc, 0x01, 0x0a, 0x56, 0xfa, 0xe4, 0xc9, 0x99,
+       0xdd, 0xa8, 0xd8, 0xda, 0x35, 0x51, 0x73, 0xb4,
+       0x40, 0x86, 0x85, 0xdb, 0x5c, 0xd5, 0x85, 0x80,
+       0x14, 0x9c, 0xfd, 0x98, 0xa9, 0x82, 0xc5, 0x37,
+       0xff, 0x32, 0x5d, 0xd0, 0x0b, 0xfa, 0xdc, 0x04,
+       0x5e, 0x09, 0xd2, 0xca, 0x17, 0x4b, 0x1a, 0x8e,
+       0x15, 0xe1, 0xcc, 0x4e, 0x52, 0x88, 0x35, 0xbd,
+       0x48, 0xfe, 0x15, 0xa0, 0x91, 0xfd, 0x7e, 0x6c,
+       0x0e, 0x5d, 0x79, 0x1b, 0x81, 0x79, 0xd2, 0x09,
+       0x34, 0x70, 0x3d, 0x81, 0xec, 0xf6, 0x24, 0xbb,
+       0xfb, 0xf1, 0x7b, 0xdf, 0x54, 0xea, 0x80, 0x9b,
+       0xc7, 0x99, 0x9e, 0xbd, 0x16, 0x78, 0x12, 0x53,
+       0x5e, 0x01, 0xa7, 0x4e, 0xbd, 0x67, 0xe1, 0x9b,
+       0x4c, 0x0e, 0x61, 0x45, 0x97, 0xd2, 0xf0, 0x0f,
+       0xfe, 0x15, 0x08, 0xb7, 0x11, 0x4c, 0xe7, 0xff,
+       0x81, 0x53, 0xff, 0x91, 0x25, 0x38, 0x7e, 0x40,
+       0x94, 0xe5, 0xe0, 0xad, 0xe6, 0xd9, 0x79, 0xb6,
+       0x92, 0xc9, 0xfc, 0xde, 0xc3, 0x1a, 0x23, 0xbb,
+       0xdd, 0xc8, 0x51, 0x0c, 0x3a, 0x72, 0xfa, 0x73,
+       0x6f, 0xb7, 0xee, 0x61, 0x39, 0x03, 0x01, 0x3f,
+       0x7f, 0x94, 0x2e, 0x2e, 0xba, 0x3a, 0xbb, 0xb4,
+       0xfa, 0x6a, 0x17, 0xfe, 0xea, 0xef, 0x5e, 0x66,
+       0x97, 0x3f, 0x32, 0x3d, 0xd7, 0x3e, 0xb1, 0xf1,
+       0x6c, 0x14, 0x4c, 0xfd, 0x37, 0xd3, 0x38, 0x80,
+       0xfb, 0xde, 0xa6, 0x24, 0x1e, 0xc8, 0xca, 0x7f,
+       0x3a, 0x93, 0xd8, 0x8b, 0x18, 0x13, 0xb2, 0xe5,
+       0xe4, 0x93, 0x05, 0x53, 0x4f, 0x84, 0x66, 0xa7,
+       0x58, 0x5c, 0x7b, 0x86, 0x52, 0x6d, 0x0d, 0xce,
+       0xa4, 0x30, 0x7d, 0xb6, 0x18, 0x9f, 0xeb, 0xff,
+       0x22, 0xbb, 0x72, 0x29, 0xb9, 0x44, 0x0b, 0x48,
+       0x1e, 0x84, 0x71, 0x81, 0xe3, 0x6d, 0x73, 0x26,
+       0x92, 0xb4, 0x4d, 0x2a, 0x29, 0xb8, 0x1f, 0x72,
+       0xed, 0xd0, 0xe1, 0x64, 0x77, 0xea, 0x8e, 0x88,
+       0x0f, 0xef, 0x3f, 0xb1, 0x3b, 0xad, 0xf9, 0xc9,
+       0x8b, 0xd0, 0xac, 0xc6, 0xcc, 0xa9, 0x40, 0xcc,
+       0x76, 0xf6, 0x3b, 0x53, 0xb5, 0x88, 0xcb, 0xc8,
+       0x37, 0xf1, 0xa2, 0xba, 0x23, 0x15, 0x99, 0x09,
+       0xcc, 0xe7, 0x7a, 0x3b, 0x37, 0xf7, 0x58, 0xc8,
+       0x46, 0x8c, 0x2b, 0x2f, 0x4e, 0x0e, 0xa6, 0x5c,
+       0xea, 0x85, 0x55, 0xba, 0x02, 0x0e, 0x0e, 0x48,
+       0xbc, 0xe1, 0xb1, 0x01, 0x35, 0x79, 0x13, 0x3d,
+       0x1b, 0xc0, 0x53, 0x68, 0x11, 0xe7, 0x95, 0x0f,
+       0x9d, 0x3f, 0x4c, 0x47, 0x7b, 0x4d, 0x1c, 0xae,
+       0x50, 0x9b, 0xcb, 0xdd, 0x05, 0x8d, 0x9a, 0x97,
+       0xfd, 0x8c, 0xef, 0x0c, 0x1d, 0x67, 0x73, 0xa8,
+       0x28, 0x36, 0xd5, 0xb6, 0x92, 0x33, 0x40, 0x75,
+       0x0b, 0x51, 0xc3, 0x64, 0xba, 0x1d, 0xc2, 0xcc,
+       0xee, 0x7d, 0x54, 0x0f, 0x27, 0x69, 0xa7, 0x27,
+       0x63, 0x30, 0x29, 0xd9, 0xc8, 0x84, 0xd8, 0xdf,
+       0x9f, 0x68, 0x8d, 0x04, 0xca, 0xa6, 0xc5, 0xc7,
+       0x7a, 0x5c, 0xc8, 0xd1, 0xcb, 0x4a, 0xec, 0xd0,
+       0xd8, 0x20, 0x69, 0xc5, 0x17, 0xcd, 0x78, 0xc8,
+       0x75, 0x23, 0x30, 0x69, 0xc9, 0xd4, 0xea, 0x5c,
+       0x4f, 0x6b, 0x86, 0x3f, 0x8b, 0xfe, 0xee, 0x44,
+       0xc9, 0x7c, 0xb7, 0xdd, 0x3e, 0xe5, 0xec, 0x54,
+       0x03, 0x3e, 0xaa, 0x82, 0xc6, 0xdf, 0xb2, 0x38,
+       0x0e, 0x5d, 0xb3, 0x88, 0xd9, 0xd3, 0x69, 0x5f,
+       0x8f, 0x70, 0x8a, 0x7e, 0x11, 0xd9, 0x1e, 0x7b,
+       0x38, 0xf1, 0x42, 0x1a, 0xc0, 0x35, 0xf5, 0xc7,
+       0x36, 0x85, 0xf5, 0xf7, 0xb8, 0x7e, 0xc7, 0xef,
+       0x18, 0xf1, 0x63, 0xd6, 0x7a, 0xc6, 0xc9, 0x0e,
+       0x4d, 0x69, 0x4f, 0x84, 0xef, 0x26, 0x41, 0x0c,
+       0xec, 0xc7, 0xe0, 0x7e, 0x3c, 0x67, 0x01, 0x4c,
+       0x62, 0x1a, 0x20, 0x6f, 0xee, 0x47, 0x4d, 0xc0,
+       0x99, 0x13, 0x8d, 0x91, 0x4a, 0x26, 0xd4, 0x37,
+       0x28, 0x90, 0x58, 0x75, 0x66, 0x2b, 0x0a, 0xdf,
+       0xda, 0xee, 0x92, 0x25, 0x90, 0x62, 0x39, 0x9e,
+       0x44, 0x98, 0xad, 0xc1, 0x88, 0xed, 0xe4, 0xb4,
+       0xaf, 0xf5, 0x8c, 0x9b, 0x48, 0x4d, 0x56, 0x60,
+       0x97, 0x0f, 0x61, 0x59, 0x9e, 0xa6, 0x27, 0xfe,
+       0xc1, 0x91, 0x15, 0x38, 0xb8, 0x0f, 0xae, 0x61,
+       0x7d, 0x26, 0x13, 0x5a, 0x73, 0xff, 0x1c, 0xa3,
+       0x61, 0x04, 0x58, 0x48, 0x55, 0x44, 0x11, 0xfe,
+       0x15, 0xca, 0xc3, 0xbd, 0xca, 0xc5, 0xb4, 0x40,
+       0x5d, 0x1b, 0x7f, 0x39, 0xb5, 0x9c, 0x35, 0xec,
+       0x61, 0x15, 0x32, 0x32, 0xb8, 0x4e, 0x40, 0x9f,
+       0x17, 0x1f, 0x0a, 0x4d, 0xa9, 0x91, 0xef, 0xb7,
+       0xb0, 0xeb, 0xc2, 0x83, 0x9a, 0x6c, 0xd2, 0x79,
+       0x43, 0x78, 0x5e, 0x2f, 0xe5, 0xdd, 0x1a, 0x3c,
+       0x45, 0xab, 0x29, 0x40, 0x3a, 0x37, 0x5b, 0x6f,
+       0xd7, 0xfc, 0x48, 0x64, 0x3c, 0x49, 0xfb, 0x21,
+       0xbe, 0xc3, 0xff, 0x07, 0xfb, 0x17, 0xe9, 0xc9,
+       0x0c, 0x4c, 0x5c, 0x15, 0x9e, 0x8e, 0x22, 0x30,
+       0x0a, 0xde, 0x48, 0x7f, 0xdb, 0x0d, 0xd1, 0x2b,
+       0x87, 0x38, 0x9e, 0xcc, 0x5a, 0x01, 0x16, 0xee,
+       0x75, 0x49, 0x0d, 0x30, 0x01, 0x34, 0x6a, 0xb6,
+       0x9a, 0x5a, 0x2a, 0xec, 0xbb, 0x48, 0xac, 0xd3,
+       0x77, 0x83, 0xd8, 0x08, 0x86, 0x4f, 0x48, 0x09,
+       0x29, 0x41, 0x79, 0xa1, 0x03, 0x12, 0xc4, 0xcd,
+       0x90, 0x55, 0x47, 0x66, 0x74, 0x9a, 0xcc, 0x4f,
+       0x35, 0x8c, 0xd6, 0x98, 0xef, 0xeb, 0x45, 0xb9,
+       0x9a, 0x26, 0x2f, 0x39, 0xa5, 0x70, 0x6d, 0xfc,
+       0xb4, 0x51, 0xee, 0xf4, 0x9c, 0xe7, 0x38, 0x59,
+       0xad, 0xf4, 0xbc, 0x46, 0xff, 0x46, 0x8e, 0x60,
+       0x9c, 0xa3, 0x60, 0x1d, 0xf8, 0x26, 0x72, 0xf5,
+       0x72, 0x9d, 0x68, 0x80, 0x04, 0xf6, 0x0b, 0xa1,
+       0x0a, 0xd5, 0xa7, 0x82, 0x3a, 0x3e, 0x47, 0xa8,
+       0x5a, 0xde, 0x59, 0x4f, 0x7b, 0x07, 0xb3, 0xe9,
+       0x24, 0x19, 0x3d, 0x34, 0x05, 0xec, 0xf1, 0xab,
+       0x6e, 0x64, 0x8f, 0xd3, 0xe6, 0x41, 0x86, 0x80,
+       0x70, 0xe3, 0x8d, 0x60, 0x9c, 0x34, 0x25, 0x01,
+       0x07, 0x4d, 0x19, 0x41, 0x4e, 0x3d, 0x5c, 0x7e,
+       0xa8, 0xf5, 0xcc, 0xd5, 0x7b, 0xe2, 0x7d, 0x3d,
+       0x49, 0x86, 0x7d, 0x07, 0xb7, 0x10, 0xe3, 0x35,
+       0xb8, 0x84, 0x6d, 0x76, 0xab, 0x17, 0xc6, 0x38,
+       0xb4, 0xd3, 0x28, 0x57, 0xad, 0xd3, 0x88, 0x5a,
+       0xda, 0xea, 0xc8, 0x94, 0xcc, 0x37, 0x19, 0xac,
+       0x9c, 0x9f, 0x4b, 0x00, 0x15, 0xc0, 0xc8, 0xca,
+       0x1f, 0x15, 0xaa, 0xe0, 0xdb, 0xf9, 0x2f, 0x57,
+       0x1b, 0x24, 0xc7, 0x6f, 0x76, 0x29, 0xfb, 0xed,
+       0x25, 0x0d, 0xc0, 0xfe, 0xbd, 0x5a, 0xbf, 0x20,
+       0x08, 0x51, 0x05, 0xec, 0x71, 0xa3, 0xbf, 0xef,
+       0x5e, 0x99, 0x75, 0xdb, 0x3c, 0x5f, 0x9a, 0x8c,
+       0xbb, 0x19, 0x5c, 0x0e, 0x93, 0x19, 0xf8, 0x6a,
+       0xbc, 0xf2, 0x12, 0x54, 0x2f, 0xcb, 0x28, 0x64,
+       0x88, 0xb3, 0x92, 0x0d, 0x96, 0xd1, 0xa6, 0xe4,
+       0x1f, 0xf1, 0x4d, 0xa4, 0xab, 0x1c, 0xee, 0x54,
+       0xf2, 0xad, 0x29, 0x6d, 0x32, 0x37, 0xb2, 0x16,
+       0x77, 0x5c, 0xdc, 0x2e, 0x54, 0xec, 0x75, 0x26,
+       0xc6, 0x36, 0xd9, 0x17, 0x2c, 0xf1, 0x7a, 0xdc,
+       0x4b, 0xf1, 0xe2, 0xd9, 0x95, 0xba, 0xac, 0x87,
+       0xc1, 0xf3, 0x8e, 0x58, 0x08, 0xd8, 0x87, 0x60,
+       0xc9, 0xee, 0x6a, 0xde, 0xa4, 0xd2, 0xfc, 0x0d,
+       0xe5, 0x36, 0xc4, 0x5c, 0x52, 0xb3, 0x07, 0x54,
+       0x65, 0x24, 0xc1, 0xb1, 0xd1, 0xb1, 0x53, 0x13,
+       0x31, 0x79, 0x7f, 0x05, 0x76, 0xeb, 0x37, 0x59,
+       0x15, 0x2b, 0xd1, 0x3f, 0xac, 0x08, 0x97, 0xeb,
+       0x91, 0x98, 0xdf, 0x6c, 0x09, 0x0d, 0x04, 0x9f,
+       0xdc, 0x3b, 0x0e, 0x60, 0x68, 0x47, 0x23, 0x15,
+       0x16, 0xc6, 0x0b, 0x35, 0xf8, 0x77, 0xa2, 0x78,
+       0x50, 0xd4, 0x64, 0x22, 0x33, 0xff, 0xfb, 0x93,
+       0x71, 0x46, 0x50, 0x39, 0x1b, 0x9c, 0xea, 0x4e,
+       0x8d, 0x0c, 0x37, 0xe5, 0x5c, 0x51, 0x3a, 0x31,
+       0xb2, 0x85, 0x84, 0x3f, 0x41, 0xee, 0xa2, 0xc1,
+       0xc6, 0x13, 0x3b, 0x54, 0x28, 0xd2, 0x18, 0x37,
+       0xcc, 0x46, 0x9f, 0x6a, 0x91, 0x3d, 0x5a, 0x15,
+       0x3c, 0x89, 0xa3, 0x61, 0x06, 0x7d, 0x2e, 0x78,
+       0xbe, 0x7d, 0x40, 0xba, 0x2f, 0x95, 0xb1, 0x2f,
+       0x87, 0x3b, 0x8a, 0xbe, 0x6a, 0xf4, 0xc2, 0x31,
+       0x74, 0xee, 0x91, 0xe0, 0x23, 0xaa, 0x5d, 0x7f,
+       0xdd, 0xf0, 0x44, 0x8c, 0x0b, 0x59, 0x2b, 0xfc,
+       0x48, 0x3a, 0xdf, 0x07, 0x05, 0x38, 0x6c, 0xc9,
+       0xeb, 0x18, 0x24, 0x68, 0x8d, 0x58, 0x98, 0xd3,
+       0x31, 0xa3, 0xe4, 0x70, 0x59, 0xb1, 0x21, 0xbe,
+       0x7e, 0x65, 0x7d, 0xb8, 0x04, 0xab, 0xf6, 0xe4,
+       0xd7, 0xda, 0xec, 0x09, 0x8f, 0xda, 0x6d, 0x24,
+       0x07, 0xcc, 0x29, 0x17, 0x05, 0x78, 0x1a, 0xc1,
+       0xb1, 0xce, 0xfc, 0xaa, 0x2d, 0xe7, 0xcc, 0x85,
+       0x84, 0x84, 0x03, 0x2a, 0x0c, 0x3f, 0xa9, 0xf8,
+       0xfd, 0x84, 0x53, 0x59, 0x5c, 0xf0, 0xd4, 0x09,
+       0xf0, 0xd2, 0x6c, 0x32, 0x03, 0xb0, 0xa0, 0x8c,
+       0x52, 0xeb, 0x23, 0x91, 0x88, 0x43, 0x13, 0x46,
+       0xf6, 0x1e, 0xb4, 0x1b, 0xf5, 0x8e, 0x3a, 0xb5,
+       0x3d, 0x00, 0xf6, 0xe5, 0x08, 0x3d, 0x5f, 0x39,
+       0xd3, 0x21, 0x69, 0xbc, 0x03, 0x22, 0x3a, 0xd2,
+       0x5c, 0x84, 0xf8, 0x15, 0xc4, 0x80, 0x0b, 0xbc,
+       0x29, 0x3c, 0xf3, 0x95, 0x98, 0xcd, 0x8f, 0x35,
+       0xbc, 0xa5, 0x3e, 0xfc, 0xd4, 0x13, 0x9e, 0xde,
+       0x4f, 0xce, 0x71, 0x9d, 0x09, 0xad, 0xf2, 0x80,
+       0x6b, 0x65, 0x7f, 0x03, 0x00, 0x14, 0x7c, 0x15,
+       0x85, 0x40, 0x6d, 0x70, 0xea, 0xdc, 0xb3, 0x63,
+       0x35, 0x4f, 0x4d, 0xe0, 0xd9, 0xd5, 0x3c, 0x58,
+       0x56, 0x23, 0x80, 0xe2, 0x36, 0xdd, 0x75, 0x1d,
+       0x94, 0x11, 0x41, 0x8e, 0xe0, 0x81, 0x8e, 0xcf,
+       0xe0, 0xe5, 0xf6, 0xde, 0xd1, 0xe7, 0x04, 0x12,
+       0x79, 0x92, 0x2b, 0x71, 0x2a, 0x79, 0x8b, 0x7c,
+       0x44, 0x79, 0x16, 0x30, 0x4e, 0xf4, 0xf6, 0x9b,
+       0xb7, 0x40, 0xa3, 0x5a, 0xa7, 0x69, 0x3e, 0xc1,
+       0x3a, 0x04, 0xd0, 0x88, 0xa0, 0x3b, 0xdd, 0xc6,
+       0x9e, 0x7e, 0x1e, 0x1e, 0x8f, 0x44, 0xf7, 0x73,
+       0x67, 0x1e, 0x1a, 0x78, 0xfa, 0x62, 0xf4, 0xa9,
+       0xa8, 0xc6, 0x5b, 0xb8, 0xfa, 0x06, 0x7d, 0x5e,
+       0x38, 0x1c, 0x9a, 0x39, 0xe9, 0x39, 0x98, 0x22,
+       0x0b, 0xa7, 0xac, 0x0b, 0xf3, 0xbc, 0xf1, 0xeb,
+       0x8c, 0x81, 0xe3, 0x48, 0x8a, 0xed, 0x42, 0xc2,
+       0x38, 0xcf, 0x3e, 0xda, 0xd2, 0x89, 0x8d, 0x9c,
+       0x53, 0xb5, 0x2f, 0x41, 0x01, 0x26, 0x84, 0x9c,
+       0xa3, 0x56, 0xf6, 0x49, 0xc7, 0xd4, 0x9f, 0x93,
+       0x1b, 0x96, 0x49, 0x5e, 0xad, 0xb3, 0x84, 0x1f,
+       0x3c, 0xa4, 0xe0, 0x9b, 0xd1, 0x90, 0xbc, 0x38,
+       0x6c, 0xdd, 0x95, 0x4d, 0x9d, 0xb1, 0x71, 0x57,
+       0x2d, 0x34, 0xe8, 0xb8, 0x42, 0xc7, 0x99, 0x03,
+       0xc7, 0x07, 0x30, 0x65, 0x91, 0x55, 0xd5, 0x90,
+       0x70, 0x97, 0x37, 0x68, 0xd4, 0x11, 0xf9, 0xe8,
+       0xce, 0xec, 0xdc, 0x34, 0xd5, 0xd3, 0xb7, 0xc4,
+       0xb8, 0x97, 0x05, 0x92, 0xad, 0xf8, 0xe2, 0x36,
+       0x64, 0x41, 0xc9, 0xc5, 0x41, 0x77, 0x52, 0xd7,
+       0x2c, 0xa5, 0x24, 0x2f, 0xd9, 0x34, 0x0b, 0x47,
+       0x35, 0xa7, 0x28, 0x8b, 0xc5, 0xcd, 0xe9, 0x46,
+       0xac, 0x39, 0x94, 0x3c, 0x10, 0xc6, 0x29, 0x73,
+       0x0e, 0x0e, 0x5d, 0xe0, 0x71, 0x03, 0x8a, 0x72,
+       0x0e, 0x26, 0xb0, 0x7d, 0x84, 0xed, 0x95, 0x23,
+       0x49, 0x5a, 0x45, 0x83, 0x45, 0x60, 0x11, 0x4a,
+       0x46, 0x31, 0xd4, 0xd8, 0x16, 0x54, 0x98, 0x58,
+       0xed, 0x6d, 0xcc, 0x5d, 0xd6, 0x50, 0x61, 0x9f,
+       0x9d, 0xc5, 0x3e, 0x9d, 0x32, 0x47, 0xde, 0x96,
+       0xe1, 0x5d, 0xd8, 0xf8, 0xb4, 0x69, 0x6f, 0xb9,
+       0x15, 0x90, 0x57, 0x7a, 0xf6, 0xad, 0xb0, 0x5b,
+       0xf5, 0xa6, 0x36, 0x94, 0xfd, 0x84, 0xce, 0x1c,
+       0x0f, 0x4b, 0xd0, 0xc2, 0x5b, 0x6b, 0x56, 0xef,
+       0x73, 0x93, 0x0b, 0xc3, 0xee, 0xd9, 0xcf, 0xd3,
+       0xa4, 0x22, 0x58, 0xcd, 0x50, 0x6e, 0x65, 0xf4,
+       0xe9, 0xb7, 0x71, 0xaf, 0x4b, 0xb3, 0xb6, 0x2f,
+       0x0f, 0x0e, 0x3b, 0xc9, 0x85, 0x14, 0xf5, 0x17,
+       0xe8, 0x7a, 0x3a, 0xbf, 0x5f, 0x5e, 0xf8, 0x18,
+       0x48, 0xa6, 0x72, 0xab, 0x06, 0x95, 0xe9, 0xc8,
+       0xa7, 0xf4, 0x32, 0x44, 0x04, 0x0c, 0x84, 0x98,
+       0x73, 0xe3, 0x89, 0x8d, 0x5f, 0x7e, 0x4a, 0x42,
+       0x8f, 0xc5, 0x28, 0xb1, 0x82, 0xef, 0x1c, 0x97,
+       0x31, 0x3b, 0x4d, 0xe0, 0x0e, 0x10, 0x10, 0x97,
+       0x93, 0x49, 0x78, 0x2f, 0x0d, 0x86, 0x8b, 0xa1,
+       0x53, 0xa9, 0x81, 0x20, 0x79, 0xe7, 0x07, 0x77,
+       0xb6, 0xac, 0x5e, 0xd2, 0x05, 0xcd, 0xe9, 0xdb,
+       0x8a, 0x94, 0x82, 0x8a, 0x23, 0xb9, 0x3d, 0x1c,
+       0xa9, 0x7d, 0x72, 0x4a, 0xed, 0x33, 0xa3, 0xdb,
+       0x21, 0xa7, 0x86, 0x33, 0x45, 0xa5, 0xaa, 0x56,
+       0x45, 0xb5, 0x83, 0x29, 0x40, 0x47, 0x79, 0x04,
+       0x6e, 0xb9, 0x95, 0xd0, 0x81, 0x77, 0x2d, 0x48,
+       0x1e, 0xfe, 0xc3, 0xc2, 0x1e, 0xe5, 0xf2, 0xbe,
+       0xfd, 0x3b, 0x94, 0x9f, 0xc4, 0xc4, 0x26, 0x9d,
+       0xe4, 0x66, 0x1e, 0x19, 0xee, 0x6c, 0x79, 0x97,
+       0x11, 0x31, 0x4b, 0x0d, 0x01, 0xcb, 0xde, 0xa8,
+       0xf6, 0x6d, 0x7c, 0x39, 0x46, 0x4e, 0x7e, 0x3f,
+       0x94, 0x17, 0xdf, 0xa1, 0x7d, 0xd9, 0x1c, 0x8e,
+       0xbc, 0x7d, 0x33, 0x7d, 0xe3, 0x12, 0x40, 0xca,
+       0xab, 0x37, 0x11, 0x46, 0xd4, 0xae, 0xef, 0x44,
+       0xa2, 0xb3, 0x6a, 0x66, 0x0e, 0x0c, 0x90, 0x7f,
+       0xdf, 0x5c, 0x66, 0x5f, 0xf2, 0x94, 0x9f, 0xa6,
+       0x73, 0x4f, 0xeb, 0x0d, 0xad, 0xbf, 0xc0, 0x63,
+       0x5c, 0xdc, 0x46, 0x51, 0xe8, 0x8e, 0x90, 0x19,
+       0xa8, 0xa4, 0x3c, 0x91, 0x79, 0xfa, 0x7e, 0x58,
+       0x85, 0x13, 0x55, 0xc5, 0x19, 0x82, 0x37, 0x1b,
+       0x0a, 0x02, 0x1f, 0x99, 0x6b, 0x18, 0xf1, 0x28,
+       0x08, 0xa2, 0x73, 0xb8, 0x0f, 0x2e, 0xcd, 0xbf,
+       0xf3, 0x86, 0x7f, 0xea, 0xef, 0xd0, 0xbb, 0xa6,
+       0x21, 0xdf, 0x49, 0x73, 0x51, 0xcc, 0x36, 0xd3,
+       0x3e, 0xa0, 0xf8, 0x44, 0xdf, 0xd3, 0xa6, 0xbe,
+       0x8a, 0xd4, 0x57, 0xdd, 0x72, 0x94, 0x61, 0x0f,
+       0x82, 0xd1, 0x07, 0xb8, 0x7c, 0x18, 0x83, 0xdf,
+       0x3a, 0xe5, 0x50, 0x6a, 0x82, 0x20, 0xac, 0xa9,
+       0xa8, 0xff, 0xd9, 0xf3, 0x77, 0x33, 0x5a, 0x9e,
+       0x7f, 0x6d, 0xfe, 0x5d, 0x33, 0x41, 0x42, 0xe7,
+       0x6c, 0x19, 0xe0, 0x44, 0x8a, 0x15, 0xf6, 0x70,
+       0x98, 0xb7, 0x68, 0x4d, 0xfa, 0x97, 0x39, 0xb0,
+       0x8e, 0xe8, 0x84, 0x8b, 0x75, 0x30, 0xb7, 0x7d,
+       0x92, 0x69, 0x20, 0x9c, 0x81, 0xfb, 0x4b, 0xf4,
+       0x01, 0x50, 0xeb, 0xce, 0x0c, 0x1c, 0x6c, 0xb5,
+       0x4a, 0xd7, 0x27, 0x0c, 0xce, 0xbb, 0xe5, 0x85,
+       0xf0, 0xb6, 0xee, 0xd5, 0x70, 0xdd, 0x3b, 0xfc,
+       0xd4, 0x99, 0xf1, 0x33, 0xdd, 0x8b, 0xc4, 0x2f,
+       0xae, 0xab, 0x74, 0x96, 0x32, 0xc7, 0x4c, 0x56,
+       0x3c, 0x89, 0x0f, 0x96, 0x0b, 0x42, 0xc0, 0xcb,
+       0xee, 0x0f, 0x0b, 0x8c, 0xfb, 0x7e, 0x47, 0x7b,
+       0x64, 0x48, 0xfd, 0xb2, 0x00, 0x80, 0x89, 0xa5,
+       0x13, 0x55, 0x62, 0xfc, 0x8f, 0xe2, 0x42, 0x03,
+       0xb7, 0x4e, 0x2a, 0x79, 0xb4, 0x82, 0xea, 0x23,
+       0x49, 0xda, 0xaf, 0x52, 0x63, 0x1e, 0x60, 0x03,
+       0x89, 0x06, 0x44, 0x46, 0x08, 0xc3, 0xc4, 0x87,
+       0x70, 0x2e, 0xda, 0x94, 0xad, 0x6b, 0xe0, 0xe4,
+       0xd1, 0x8a, 0x06, 0xc2, 0xa8, 0xc0, 0xa7, 0x43,
+       0x3c, 0x47, 0x52, 0x0e, 0xc3, 0x77, 0x81, 0x11,
+       0x67, 0x0e, 0xa0, 0x70, 0x04, 0x47, 0x29, 0x40,
+       0x86, 0x0d, 0x34, 0x56, 0xa7, 0xc9, 0x35, 0x59,
+       0x68, 0xdc, 0x93, 0x81, 0x70, 0xee, 0x86, 0xd9,
+       0x80, 0x06, 0x40, 0x4f, 0x1a, 0x0d, 0x40, 0x30,
+       0x0b, 0xcb, 0x96, 0x47, 0xc1, 0xb7, 0x52, 0xfd,
+       0x56, 0xe0, 0x72, 0x4b, 0xfb, 0xbd, 0x92, 0x45,
+       0x61, 0x71, 0xc2, 0x33, 0x11, 0xbf, 0x52, 0x83,
+       0x79, 0x26, 0xe0, 0x49, 0x6b, 0xb7, 0x05, 0x8b,
+       0xe8, 0x0e, 0x87, 0x31, 0xd7, 0x9d, 0x8a, 0xf5,
+       0xc0, 0x5f, 0x2e, 0x58, 0x4a, 0xdb, 0x11, 0xb3,
+       0x6c, 0x30, 0x2a, 0x46, 0x19, 0xe3, 0x27, 0x84,
+       0x1f, 0x63, 0x6e, 0xf6, 0x57, 0xc7, 0xc9, 0xd8,
+       0x5e, 0xba, 0xb3, 0x87, 0xd5, 0x83, 0x26, 0x34,
+       0x21, 0x9e, 0x65, 0xde, 0x42, 0xd3, 0xbe, 0x7b,
+       0xbc, 0x91, 0x71, 0x44, 0x4d, 0x99, 0x3b, 0x31,
+       0xe5, 0x3f, 0x11, 0x4e, 0x7f, 0x13, 0x51, 0x3b,
+       0xae, 0x79, 0xc9, 0xd3, 0x81, 0x8e, 0x25, 0x40,
+       0x10, 0xfc, 0x07, 0x1e, 0xf9, 0x7b, 0x9a, 0x4b,
+       0x6c, 0xe3, 0xb3, 0xad, 0x1a, 0x0a, 0xdd, 0x9e,
+       0x59, 0x0c, 0xa2, 0xcd, 0xae, 0x48, 0x4a, 0x38,
+       0x5b, 0x47, 0x41, 0x94, 0x65, 0x6b, 0xbb, 0xeb,
+       0x5b, 0xe3, 0xaf, 0x07, 0x5b, 0xd4, 0x4a, 0xa2,
+       0xc9, 0x5d, 0x2f, 0x64, 0x03, 0xd7, 0x3a, 0x2c,
+       0x6e, 0xce, 0x76, 0x95, 0xb4, 0xb3, 0xc0, 0xf1,
+       0xe2, 0x45, 0x73, 0x7a, 0x5c, 0xab, 0xc1, 0xfc,
+       0x02, 0x8d, 0x81, 0x29, 0xb3, 0xac, 0x07, 0xec,
+       0x40, 0x7d, 0x45, 0xd9, 0x7a, 0x59, 0xee, 0x34,
+       0xf0, 0xe9, 0xd5, 0x7b, 0x96, 0xb1, 0x3d, 0x95,
+       0xcc, 0x86, 0xb5, 0xb6, 0x04, 0x2d, 0xb5, 0x92,
+       0x7e, 0x76, 0xf4, 0x06, 0xa9, 0xa3, 0x12, 0x0f,
+       0xb1, 0xaf, 0x26, 0xba, 0x7c, 0xfc, 0x7e, 0x1c,
+       0xbc, 0x2c, 0x49, 0x97, 0x53, 0x60, 0x13, 0x0b,
+       0xa6, 0x61, 0x83, 0x89, 0x42, 0xd4, 0x17, 0x0c,
+       0x6c, 0x26, 0x52, 0xc3, 0xb3, 0xd4, 0x67, 0xf5,
+       0xe3, 0x04, 0xb7, 0xf4, 0xcb, 0x80, 0xb8, 0xcb,
+       0x77, 0x56, 0x3e, 0xaa, 0x57, 0x54, 0xee, 0xb4,
+       0x2c, 0x67, 0xcf, 0xf2, 0xdc, 0xbe, 0x55, 0xf9,
+       0x43, 0x1f, 0x6e, 0x22, 0x97, 0x67, 0x7f, 0xc4,
+       0xef, 0xb1, 0x26, 0x31, 0x1e, 0x27, 0xdf, 0x41,
+       0x80, 0x47, 0x6c, 0xe2, 0xfa, 0xa9, 0x8c, 0x2a,
+       0xf6, 0xf2, 0xab, 0xf0, 0x15, 0xda, 0x6c, 0xc8,
+       0xfe, 0xb5, 0x23, 0xde, 0xa9, 0x05, 0x3f, 0x06,
+       0x54, 0x4c, 0xcd, 0xe1, 0xab, 0xfc, 0x0e, 0x62,
+       0x33, 0x31, 0x73, 0x2c, 0x76, 0xcb, 0xb4, 0x47,
+       0x1e, 0x20, 0xad, 0xd8, 0xf2, 0x31, 0xdd, 0xc4,
+       0x8b, 0x0c, 0x77, 0xbe, 0xe1, 0x8b, 0x26, 0x00,
+       0x02, 0x58, 0xd6, 0x8d, 0xef, 0xad, 0x74, 0x67,
+       0xab, 0x3f, 0xef, 0xcb, 0x6f, 0xb0, 0xcc, 0x81,
+       0x44, 0x4c, 0xaf, 0xe9, 0x49, 0x4f, 0xdb, 0xa0,
+       0x25, 0xa4, 0xf0, 0x89, 0xf1, 0xbe, 0xd8, 0x10,
+       0xff, 0xb1, 0x3b, 0x4b, 0xfa, 0x98, 0xf5, 0x79,
+       0x6d, 0x1e, 0x69, 0x4d, 0x57, 0xb1, 0xc8, 0x19,
+       0x1b, 0xbd, 0x1e, 0x8c, 0x84, 0xb7, 0x7b, 0xe8,
+       0xd2, 0x2d, 0x09, 0x41, 0x41, 0x37, 0x3d, 0xb1,
+       0x6f, 0x26, 0x5d, 0x71, 0x16, 0x3d, 0xb7, 0x83,
+       0x27, 0x2c, 0xa7, 0xb6, 0x50, 0xbd, 0x91, 0x86,
+       0xab, 0x24, 0xa1, 0x38, 0xfd, 0xea, 0x71, 0x55,
+       0x7e, 0x9a, 0x07, 0x77, 0x4b, 0xfa, 0x61, 0x66,
+       0x20, 0x1e, 0x28, 0x95, 0x18, 0x1b, 0xa4, 0xa0,
+       0xfd, 0xc0, 0x89, 0x72, 0x43, 0xd9, 0x3b, 0x49,
+       0x5a, 0x3f, 0x9d, 0xbf, 0xdb, 0xb4, 0x46, 0xea,
+       0x42, 0x01, 0x77, 0x23, 0x68, 0x95, 0xb6, 0x24,
+       0xb3, 0xa8, 0x6c, 0x28, 0x3b, 0x11, 0x40, 0x7e,
+       0x18, 0x65, 0x6d, 0xd8, 0x24, 0x42, 0x7d, 0x88,
+       0xc0, 0x52, 0xd9, 0x05, 0xe4, 0x95, 0x90, 0x87,
+       0x8c, 0xf4, 0xd0, 0x6b, 0xb9, 0x83, 0x99, 0x34,
+       0x6d, 0xfe, 0x54, 0x40, 0x94, 0x52, 0x21, 0x4f,
+       0x14, 0x25, 0xc5, 0xd6, 0x5e, 0x95, 0xdc, 0x0a,
+       0x2b, 0x89, 0x20, 0x11, 0x84, 0x48, 0xd6, 0x3a,
+       0xcd, 0x5c, 0x24, 0xad, 0x62, 0xe3, 0xb1, 0x93,
+       0x25, 0x8d, 0xcd, 0x7e, 0xfc, 0x27, 0xa3, 0x37,
+       0xfd, 0x84, 0xfc, 0x1b, 0xb2, 0xf1, 0x27, 0x38,
+       0x5a, 0xb7, 0xfc, 0xf2, 0xfa, 0x95, 0x66, 0xd4,
+       0xfb, 0xba, 0xa7, 0xd7, 0xa3, 0x72, 0x69, 0x48,
+       0x48, 0x8c, 0xeb, 0x28, 0x89, 0xfe, 0x33, 0x65,
+       0x5a, 0x36, 0x01, 0x7e, 0x06, 0x79, 0x0a, 0x09,
+       0x3b, 0x74, 0x11, 0x9a, 0x6e, 0xbf, 0xd4, 0x9e,
+       0x58, 0x90, 0x49, 0x4f, 0x4d, 0x08, 0xd4, 0xe5,
+       0x4a, 0x09, 0x21, 0xef, 0x8b, 0xb8, 0x74, 0x3b,
+       0x91, 0xdd, 0x36, 0x85, 0x60, 0x2d, 0xfa, 0xd4,
+       0x45, 0x7b, 0x45, 0x53, 0xf5, 0x47, 0x87, 0x7e,
+       0xa6, 0x37, 0xc8, 0x78, 0x7a, 0x68, 0x9d, 0x8d,
+       0x65, 0x2c, 0x0e, 0x91, 0x5c, 0xa2, 0x60, 0xf0,
+       0x8e, 0x3f, 0xe9, 0x1a, 0xcd, 0xaa, 0xe7, 0xd5,
+       0x77, 0x18, 0xaf, 0xc9, 0xbc, 0x18, 0xea, 0x48,
+       0x1b, 0xfb, 0x22, 0x48, 0x70, 0x16, 0x29, 0x9e,
+       0x5b, 0xc1, 0x2c, 0x66, 0x23, 0xbc, 0xf0, 0x1f,
+       0xef, 0xaf, 0xe4, 0xd6, 0x04, 0x19, 0x82, 0x7a,
+       0x0b, 0xba, 0x4b, 0x46, 0xb1, 0x6a, 0x85, 0x5d,
+       0xb4, 0x73, 0xd6, 0x21, 0xa1, 0x71, 0x60, 0x14,
+       0xee, 0x0a, 0x77, 0xc4, 0x66, 0x2e, 0xf9, 0x69,
+       0x30, 0xaf, 0x41, 0x0b, 0xc8, 0x83, 0x3c, 0x53,
+       0x99, 0x19, 0x27, 0x46, 0xf7, 0x41, 0x6e, 0x56,
+       0xdc, 0x94, 0x28, 0x67, 0x4e, 0xb7, 0x25, 0x48,
+       0x8a, 0xc2, 0xe0, 0x60, 0x96, 0xcc, 0x18, 0xf4,
+       0x84, 0xdd, 0xa7, 0x5e, 0x3e, 0x05, 0x0b, 0x26,
+       0x26, 0xb2, 0x5c, 0x1f, 0x57, 0x1a, 0x04, 0x7e,
+       0x6a, 0xe3, 0x2f, 0xb4, 0x35, 0xb6, 0x38, 0x40,
+       0x40, 0xcd, 0x6f, 0x87, 0x2e, 0xef, 0xa3, 0xd7,
+       0xa9, 0xc2, 0xe8, 0x0d, 0x27, 0xdf, 0x44, 0x62,
+       0x99, 0xa0, 0xfc, 0xcf, 0x81, 0x78, 0xcb, 0xfe,
+       0xe5, 0xa0, 0x03, 0x4e, 0x6c, 0xd7, 0xf4, 0xaf,
+       0x7a, 0xbb, 0x61, 0x82, 0xfe, 0x71, 0x89, 0xb2,
+       0x22, 0x7c, 0x8e, 0x83, 0x04, 0xce, 0xf6, 0x5d,
+       0x84, 0x8f, 0x95, 0x6a, 0x7f, 0xad, 0xfd, 0x32,
+       0x9c, 0x5e, 0xe4, 0x9c, 0x89, 0x60, 0x54, 0xaa,
+       0x96, 0x72, 0xd2, 0xd7, 0x36, 0x85, 0xa9, 0x45,
+       0xd2, 0x2a, 0xa1, 0x81, 0x49, 0x6f, 0x7e, 0x04,
+       0xfa, 0xe2, 0xfe, 0x90, 0x26, 0x77, 0x5a, 0x33,
+       0xb8, 0x04, 0x9a, 0x7a, 0xe6, 0x4c, 0x4f, 0xad,
+       0x72, 0x96, 0x08, 0x28, 0x58, 0x13, 0xf8, 0xc4,
+       0x1c, 0xf0, 0xc3, 0x45, 0x95, 0x49, 0x20, 0x8c,
+       0x9f, 0x39, 0x70, 0xe1, 0x77, 0xfe, 0xd5, 0x4b,
+       0xaf, 0x86, 0xda, 0xef, 0x22, 0x06, 0x83, 0x36,
+       0x29, 0x12, 0x11, 0x40, 0xbc, 0x3b, 0x86, 0xaa,
+       0xaa, 0x65, 0x60, 0xc3, 0x80, 0xca, 0xed, 0xa9,
+       0xf3, 0xb0, 0x79, 0x96, 0xa2, 0x55, 0x27, 0x28,
+       0x55, 0x73, 0x26, 0xa5, 0x50, 0xea, 0x92, 0x4b,
+       0x3c, 0x5c, 0x82, 0x33, 0xf0, 0x01, 0x3f, 0x03,
+       0xc1, 0x08, 0x05, 0xbf, 0x98, 0xf4, 0x9b, 0x6d,
+       0xa5, 0xa8, 0xb4, 0x82, 0x0c, 0x06, 0xfa, 0xff,
+       0x2d, 0x08, 0xf3, 0x05, 0x4f, 0x57, 0x2a, 0x39,
+       0xd4, 0x83, 0x0d, 0x75, 0x51, 0xd8, 0x5b, 0x1b,
+       0xd3, 0x51, 0x5a, 0x32, 0x2a, 0x9b, 0x32, 0xb2,
+       0xf2, 0xa4, 0x96, 0x12, 0xf2, 0xae, 0x40, 0x34,
+       0x67, 0xa8, 0xf5, 0x44, 0xd5, 0x35, 0x53, 0xfe,
+       0xa3, 0x60, 0x96, 0x63, 0x0f, 0x1f, 0x6e, 0xb0,
+       0x5a, 0x42, 0xa6, 0xfc, 0x51, 0x0b, 0x60, 0x27,
+       0xbc, 0x06, 0x71, 0xed, 0x65, 0x5b, 0x23, 0x86,
+       0x4a, 0x07, 0x3b, 0x22, 0x07, 0x46, 0xe6, 0x90,
+       0x3e, 0xf3, 0x25, 0x50, 0x1b, 0x4c, 0x7f, 0x03,
+       0x08, 0xa8, 0x36, 0x6b, 0x87, 0xe5, 0xe3, 0xdb,
+       0x9a, 0x38, 0x83, 0xff, 0x9f, 0x1a, 0x9f, 0x57,
+       0xa4, 0x2a, 0xf6, 0x37, 0xbc, 0x1a, 0xff, 0xc9,
+       0x1e, 0x35, 0x0c, 0xc3, 0x7c, 0xa3, 0xb2, 0xe5,
+       0xd2, 0xc6, 0xb4, 0x57, 0x47, 0xe4, 0x32, 0x16,
+       0x6d, 0xa9, 0xae, 0x64, 0xe6, 0x2d, 0x8d, 0xc5,
+       0x8d, 0x50, 0x8e, 0xe8, 0x1a, 0x22, 0x34, 0x2a,
+       0xd9, 0xeb, 0x51, 0x90, 0x4a, 0xb1, 0x41, 0x7d,
+       0x64, 0xf9, 0xb9, 0x0d, 0xf6, 0x23, 0x33, 0xb0,
+       0x33, 0xf4, 0xf7, 0x3f, 0x27, 0x84, 0xc6, 0x0f,
+       0x54, 0xa5, 0xc0, 0x2e, 0xec, 0x0b, 0x3a, 0x48,
+       0x6e, 0x80, 0x35, 0x81, 0x43, 0x9b, 0x90, 0xb1,
+       0xd0, 0x2b, 0xea, 0x21, 0xdc, 0xda, 0x5b, 0x09,
+       0xf4, 0xcc, 0x10, 0xb4, 0xc7, 0xfe, 0x79, 0x51,
+       0xc3, 0xc5, 0xac, 0x88, 0x74, 0x84, 0x0b, 0x4b,
+       0xca, 0x79, 0x16, 0x29, 0xfb, 0x69, 0x54, 0xdf,
+       0x41, 0x7e, 0xe9, 0xc7, 0x8e, 0xea, 0xa5, 0xfe,
+       0xfc, 0x76, 0x0e, 0x90, 0xc4, 0x92, 0x38, 0xad,
+       0x7b, 0x48, 0xe6, 0x6e, 0xf7, 0x21, 0xfd, 0x4e,
+       0x93, 0x0a, 0x7b, 0x41, 0x83, 0x68, 0xfb, 0x57,
+       0x51, 0x76, 0x34, 0xa9, 0x6c, 0x00, 0xaa, 0x4f,
+       0x66, 0x65, 0x98, 0x4a, 0x4f, 0xa3, 0xa0, 0xef,
+       0x69, 0x3f, 0xe3, 0x1c, 0x92, 0x8c, 0xfd, 0xd8,
+       0xe8, 0xde, 0x7c, 0x7f, 0x3e, 0x84, 0x8e, 0x69,
+       0x3c, 0xf1, 0xf2, 0x05, 0x46, 0xdc, 0x2f, 0x9d,
+       0x5e, 0x6e, 0x4c, 0xfb, 0xb5, 0x99, 0x2a, 0x59,
+       0x63, 0xc1, 0x34, 0xbc, 0x57, 0xc0, 0x0d, 0xb9,
+       0x61, 0x25, 0xf3, 0x33, 0x23, 0x51, 0xb6, 0x0d,
+       0x07, 0xa6, 0xab, 0x94, 0x4a, 0xb7, 0x2a, 0xea,
+       0xee, 0xac, 0xa3, 0xc3, 0x04, 0x8b, 0x0e, 0x56,
+       0xfe, 0x44, 0xa7, 0x39, 0xe2, 0xed, 0xed, 0xb4,
+       0x22, 0x2b, 0xac, 0x12, 0x32, 0x28, 0x91, 0xd8,
+       0xa5, 0xab, 0xff, 0x5f, 0xe0, 0x4b, 0xda, 0x78,
+       0x17, 0xda, 0xf1, 0x01, 0x5b, 0xcd, 0xe2, 0x5f,
+       0x50, 0x45, 0x73, 0x2b, 0xe4, 0x76, 0x77, 0xf4,
+       0x64, 0x1d, 0x43, 0xfb, 0x84, 0x7a, 0xea, 0x91,
+       0xae, 0xf9, 0x9e, 0xb7, 0xb4, 0xb0, 0x91, 0x5f,
+       0x16, 0x35, 0x9a, 0x11, 0xb8, 0xc7, 0xc1, 0x8c,
+       0xc6, 0x10, 0x8d, 0x2f, 0x63, 0x4a, 0xa7, 0x57,
+       0x3a, 0x51, 0xd6, 0x32, 0x2d, 0x64, 0x72, 0xd4,
+       0x66, 0xdc, 0x10, 0xa6, 0x67, 0xd6, 0x04, 0x23,
+       0x9d, 0x0a, 0x11, 0x77, 0xdd, 0x37, 0x94, 0x17,
+       0x3c, 0xbf, 0x8b, 0x65, 0xb0, 0x2e, 0x5e, 0x66,
+       0x47, 0x64, 0xac, 0xdd, 0xf0, 0x84, 0xfd, 0x39,
+       0xfa, 0x15, 0x5d, 0xef, 0xae, 0xca, 0xc1, 0x36,
+       0xa7, 0x5c, 0xbf, 0xc7, 0x08, 0xc2, 0x66, 0x00,
+       0x74, 0x74, 0x4e, 0x27, 0x3f, 0x55, 0x8a, 0xb7,
+       0x38, 0x66, 0x83, 0x6d, 0xcf, 0x99, 0x9e, 0x60,
+       0x8f, 0xdd, 0x2e, 0x62, 0x22, 0x0e, 0xef, 0x0c,
+       0x98, 0xa7, 0x85, 0x74, 0x3b, 0x9d, 0xec, 0x9e,
+       0xa9, 0x19, 0x72, 0xa5, 0x7f, 0x2c, 0x39, 0xb7,
+       0x7d, 0xb7, 0xf1, 0x12, 0x65, 0x27, 0x4b, 0x5a,
+       0xde, 0x17, 0xfe, 0xad, 0x44, 0xf3, 0x20, 0x4d,
+       0xfd, 0xe4, 0x1f, 0xb5, 0x81, 0xb0, 0x36, 0x37,
+       0x08, 0x6f, 0xc3, 0x0c, 0xe9, 0x85, 0x98, 0x82,
+       0xa9, 0x62, 0x0c, 0xc4, 0x97, 0xc0, 0x50, 0xc8,
+       0xa7, 0x3c, 0x50, 0x9f, 0x43, 0xb9, 0xcd, 0x5e,
+       0x4d, 0xfa, 0x1c, 0x4b, 0x0b, 0xa9, 0x98, 0x85,
+       0x38, 0x92, 0xac, 0x8d, 0xe4, 0xad, 0x9b, 0x98,
+       0xab, 0xd9, 0x38, 0xac, 0x62, 0x52, 0xa3, 0x22,
+       0x63, 0x0f, 0xbf, 0x95, 0x48, 0xdf, 0x69, 0xe7,
+       0x8b, 0x33, 0xd5, 0xb2, 0xbd, 0x05, 0x49, 0x49,
+       0x9d, 0x57, 0x73, 0x19, 0x33, 0xae, 0xfa, 0x33,
+       0xf1, 0x19, 0xa8, 0x80, 0xce, 0x04, 0x9f, 0xbc,
+       0x1d, 0x65, 0x82, 0x1b, 0xe5, 0x3a, 0x51, 0xc8,
+       0x1c, 0x21, 0xe3, 0x5d, 0xf3, 0x7d, 0x9b, 0x2f,
+       0x2c, 0x1d, 0x4a, 0x7f, 0x9b, 0x68, 0x35, 0xa3,
+       0xb2, 0x50, 0xf7, 0x62, 0x79, 0xcd, 0xf4, 0x98,
+       0x4f, 0xe5, 0x63, 0x7c, 0x3e, 0x45, 0x31, 0x8c,
+       0x16, 0xa0, 0x12, 0xc8, 0x58, 0xce, 0x39, 0xa6,
+       0xbc, 0x54, 0xdb, 0xc5, 0xe0, 0xd5, 0xba, 0xbc,
+       0xb9, 0x04, 0xf4, 0x8d, 0xe8, 0x2f, 0x15, 0x9d,
+};
+
+/* 100 test cases */
+static struct dahash_test {
+       uint16_t        start;  /* random 12 bit offset in buf */
+       uint16_t        length; /* random 8 bit length of test */
+       xfs_dahash_t    dahash; /* expected dahash result */
+} test[] __initdata =
+{
+       {0x0567, 0x0097, 0x96951389},
+       {0x0869, 0x0055, 0x6455ab4f},
+       {0x0c51, 0x00be, 0x8663afde},
+       {0x044a, 0x00fc, 0x98fbe432},
+       {0x0f29, 0x0079, 0x42371997},
+       {0x08ba, 0x0052, 0x942be4f7},
+       {0x01f2, 0x0013, 0x5262687e},
+       {0x09e3, 0x00e2, 0x8ffb0908},
+       {0x007c, 0x0051, 0xb3158491},
+       {0x0854, 0x001f, 0x83bb20d9},
+       {0x031b, 0x0008, 0x98970bdf},
+       {0x0de7, 0x0027, 0xbfbf6f6c},
+       {0x0f76, 0x0005, 0x906a7105},
+       {0x092e, 0x00d0, 0x86631850},
+       {0x0233, 0x0082, 0xdbdd914e},
+       {0x04c9, 0x0075, 0x5a400a9e},
+       {0x0b66, 0x0099, 0xae128b45},
+       {0x000d, 0x00ed, 0xe61c216a},
+       {0x0a31, 0x003d, 0xf69663b9},
+       {0x00a3, 0x0052, 0x643c39ae},
+       {0x0125, 0x00d5, 0x7c310b0d},
+       {0x0105, 0x004a, 0x06a77e74},
+       {0x0858, 0x008e, 0x265bc739},
+       {0x045e, 0x0095, 0x13d6b192},
+       {0x0dab, 0x003c, 0xc4498704},
+       {0x00cd, 0x00b5, 0x802a4e2d},
+       {0x069b, 0x008c, 0x5df60f71},
+       {0x0454, 0x006c, 0x5f03d8bb},
+       {0x040e, 0x0032, 0x0ce513b5},
+       {0x0874, 0x00e2, 0x6a811fb3},
+       {0x0521, 0x00b4, 0x93296833},
+       {0x0ddc, 0x00cf, 0xf9305338},
+       {0x0a70, 0x0023, 0x239549ea},
+       {0x083e, 0x0027, 0x2d88ba97},
+       {0x0241, 0x00a7, 0xfe0b32e1},
+       {0x0dfc, 0x0096, 0x1a11e815},
+       {0x023e, 0x001e, 0xebc9a1f3},
+       {0x067e, 0x0066, 0xb1067f81},
+       {0x09ea, 0x000e, 0x46fd7247},
+       {0x036b, 0x008c, 0x1a39acdf},
+       {0x078f, 0x0030, 0x964042ab},
+       {0x085c, 0x008f, 0x1829edab},
+       {0x02ec, 0x009f, 0x6aefa72d},
+       {0x043b, 0x00ce, 0x65642ff5},
+       {0x0a32, 0x00b8, 0xbd82759e},
+       {0x0d3c, 0x0087, 0xf4d66d54},
+       {0x09ec, 0x008a, 0x06bfa1ff},
+       {0x0902, 0x0015, 0x755025d2},
+       {0x08fe, 0x000e, 0xf690ce2d},
+       {0x00fb, 0x00dc, 0xe55f1528},
+       {0x0eaa, 0x003a, 0x0fe0a8d7},
+       {0x05fb, 0x0006, 0x86281cfb},
+       {0x0dd1, 0x00a7, 0x60ab51b4},
+       {0x0005, 0x001b, 0xf51d969b},
+       {0x077c, 0x00dd, 0xc2fed268},
+       {0x0575, 0x00f5, 0x432c0b1a},
+       {0x05be, 0x0088, 0x78baa04b},
+       {0x0c89, 0x0068, 0xeda9e428},
+       {0x0f5c, 0x0068, 0xec143c76},
+       {0x06a8, 0x0009, 0xd72651ce},
+       {0x060f, 0x008e, 0x765426cd},
+       {0x07b1, 0x0047, 0x2cfcfa0c},
+       {0x04f1, 0x0041, 0x55b172f9},
+       {0x0e05, 0x00ac, 0x61efde93},
+       {0x0bf7, 0x0097, 0x05b83eee},
+       {0x04e9, 0x00f3, 0x9928223a},
+       {0x023a, 0x0005, 0xdfada9bc},
+       {0x0acb, 0x000e, 0x2217cecd},
+       {0x0148, 0x0060, 0xbc3f7405},
+       {0x0764, 0x0059, 0xcbc201b1},
+       {0x021f, 0x0059, 0x5d6b2256},
+       {0x0f1e, 0x006c, 0xdefeeb45},
+       {0x071c, 0x00b9, 0xb9b59309},
+       {0x0564, 0x0063, 0xae064271},
+       {0x0b14, 0x0044, 0xdb867d9b},
+       {0x0e5a, 0x0055, 0xff06b685},
+       {0x015e, 0x00ba, 0x1115ccbc},
+       {0x0379, 0x00e6, 0x5f4e58dd},
+       {0x013b, 0x0067, 0x4897427e},
+       {0x0e64, 0x0071, 0x7af2b7a4},
+       {0x0a11, 0x0050, 0x92105726},
+       {0x0109, 0x0055, 0xd0d000f9},
+       {0x00aa, 0x0022, 0x815d229d},
+       {0x09ac, 0x004f, 0x02f9d985},
+       {0x0e1b, 0x00ce, 0x5cf92ab4},
+       {0x08af, 0x00d8, 0x17ca72d1},
+       {0x0e33, 0x000a, 0xda2dba6b},
+       {0x0ee3, 0x006a, 0xb00048e5},
+       {0x0648, 0x001a, 0x2364b8cb},
+       {0x0315, 0x0085, 0x0596fd0d},
+       {0x0fbb, 0x003e, 0x298230ca},
+       {0x0422, 0x006a, 0x78ada4ab},
+       {0x04ba, 0x0073, 0xced1fbc2},
+       {0x007d, 0x0061, 0x4b7ff236},
+       {0x070b, 0x00d0, 0x261cf0ae},
+       {0x0c1a, 0x0035, 0x8be92ee2},
+       {0x0af8, 0x0063, 0x824dcf03},
+       {0x08f8, 0x006d, 0xd289710c},
+       {0x021b, 0x00ee, 0x6ac1c41d},
+       {0x05b5, 0x00da, 0x8e52f0e2},
+};
+
+int __init
+xfs_dahash_test(void)
+{
+       unsigned int    i;
+       unsigned int    errors = 0;
+
+       for (i = 0; i < ARRAY_SIZE(test); i++) {
+               xfs_dahash_t    hash;
+
+               hash = xfs_da_hashname(test_buf + test[i].start,
+                               test[i].length);
+               if (hash != test[i].dahash)
+                       errors++;
+       }
+
+       if (errors) {
+               printk(KERN_ERR "xfs dir/attr hash test failed %u times!",
+                               errors);
+               return -ERANGE;
+       }
+
+       return 0;
+}
diff --git a/fs/xfs/xfs_dahash_test.h b/fs/xfs/xfs_dahash_test.h
new file mode 100644 (file)
index 0000000..1a05bf4
--- /dev/null
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 Oracle.  All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#ifndef __XFS_DAHASH_TEST_H__
+#define __XFS_DAHASH_TEST_H__
+
+int xfs_dahash_test(void);
+
+#endif /* __XFS_DAHASH_TEST_H__ */
+
index 69dbe78141280e7f82405129da19f0549a2d6ceb..285885c308bd7db943ca58357305a52a70cdcb6f 100644 (file)
@@ -1090,9 +1090,12 @@ xfs_buffered_write_iomap_begin(
                 */
                if (xfs_has_allocsize(mp))
                        prealloc_blocks = mp->m_allocsize_blocks;
-               else
+               else if (allocfork == XFS_DATA_FORK)
                        prealloc_blocks = xfs_iomap_prealloc_size(ip, allocfork,
                                                offset, count, &icur);
+               else
+                       prealloc_blocks = xfs_iomap_prealloc_size(ip, allocfork,
+                                               offset, count, &ccur);
                if (prealloc_blocks) {
                        xfs_extlen_t    align;
                        xfs_off_t       end_offset;
index 7dc0db7f5a761ca23bc7f99ccaed243482ea2918..6abcc34fafd8c2e807784908be3004c7e58ffda4 100644 (file)
@@ -1321,15 +1321,14 @@ xfs_qm_quotacheck(
 
        error = xfs_iwalk_threaded(mp, 0, 0, xfs_qm_dqusage_adjust, 0, true,
                        NULL);
-       if (error) {
-               /*
-                * The inode walk may have partially populated the dquot
-                * caches.  We must purge them before disabling quota and
-                * tearing down the quotainfo, or else the dquots will leak.
-                */
-               xfs_qm_dqpurge_all(mp);
-               goto error_return;
-       }
+
+       /*
+        * On error, the inode walk may have partially populated the dquot
+        * caches.  We must purge them before disabling quota and tearing down
+        * the quotainfo, or else the dquots will leak.
+        */
+       if (error)
+               goto error_purge;
 
        /*
         * We've made all the changes that we need to make incore.  Flush them
@@ -1363,10 +1362,8 @@ xfs_qm_quotacheck(
         * and turn quotaoff. The dquots won't be attached to any of the inodes
         * at this point (because we intentionally didn't in dqget_noattach).
         */
-       if (error) {
-               xfs_qm_dqpurge_all(mp);
-               goto error_return;
-       }
+       if (error)
+               goto error_purge;
 
        /*
         * If one type of quotas is off, then it will lose its
@@ -1376,7 +1373,7 @@ xfs_qm_quotacheck(
        mp->m_qflags &= ~XFS_ALL_QUOTA_CHKD;
        mp->m_qflags |= flags;
 
- error_return:
+error_return:
        xfs_buf_delwri_cancel(&buffer_list);
 
        if (error) {
@@ -1395,6 +1392,21 @@ xfs_qm_quotacheck(
        } else
                xfs_notice(mp, "Quotacheck: Done.");
        return error;
+
+error_purge:
+       /*
+        * On error, we may have inodes queued for inactivation. This may try
+        * to attach dquots to the inode before running cleanup operations on
+        * the inode and this can race with the xfs_qm_destroy_quotainfo() call
+        * below that frees mp->m_quotainfo. To avoid this race, flush all the
+        * pending inodegc operations before we purge the dquots from memory,
+        * ensuring that background inactivation is idle whilst we turn off
+        * quotas.
+        */
+       xfs_inodegc_flush(mp);
+       xfs_qm_dqpurge_all(mp);
+       goto error_return;
+
 }
 
 /*
index 2479b5cbd75ecf51850aa0a1c6dfb79b1def8c2b..4f814f9e12ab50a74d68612ce22c8562b86c3756 100644 (file)
@@ -41,6 +41,7 @@
 #include "xfs_attr_item.h"
 #include "xfs_xattr.h"
 #include "xfs_iunlink_item.h"
+#include "xfs_dahash_test.h"
 
 #include <linux/magic.h>
 #include <linux/fs_context.h>
@@ -2286,6 +2287,10 @@ init_xfs_fs(void)
 
        xfs_check_ondisk_structs();
 
+       error = xfs_dahash_test();
+       if (error)
+               return error;
+
        printk(KERN_INFO XFS_VERSION_STRING " with "
                         XFS_BUILD_OPTIONS " enabled\n");
 
index 7dc0fd6a6504743389d67c571d97c12086e7b497..9c0006c55fec3c869d2484106eba463c581a6fcd 100644 (file)
@@ -1883,6 +1883,13 @@ DEFINE_ALLOC_EVENT(xfs_alloc_vextent_noagbp);
 DEFINE_ALLOC_EVENT(xfs_alloc_vextent_loopfailed);
 DEFINE_ALLOC_EVENT(xfs_alloc_vextent_allfailed);
 
+DEFINE_ALLOC_EVENT(xfs_alloc_vextent_this_ag);
+DEFINE_ALLOC_EVENT(xfs_alloc_vextent_start_ag);
+DEFINE_ALLOC_EVENT(xfs_alloc_vextent_first_ag);
+DEFINE_ALLOC_EVENT(xfs_alloc_vextent_exact_bno);
+DEFINE_ALLOC_EVENT(xfs_alloc_vextent_near_bno);
+DEFINE_ALLOC_EVENT(xfs_alloc_vextent_finish);
+
 TRACE_EVENT(xfs_alloc_cur_check,
        TP_PROTO(struct xfs_mount *mp, xfs_btnum_t btnum, xfs_agblock_t bno,
                 xfs_extlen_t len, xfs_extlen_t diff, bool new),
index 7b9a0ed1b11f74b7870e0e52e4ad2fafad0feaf4..43e5c219aaed568ffb5a711b4583b2cdf1723d9c 100644 (file)
@@ -179,10 +179,6 @@ const struct xattr_handler *xfs_xattr_handlers[] = {
        &xfs_xattr_user_handler,
        &xfs_xattr_trusted_handler,
        &xfs_xattr_security_handler,
-#ifdef CONFIG_XFS_POSIX_ACL
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
-#endif
        NULL
 };
 
index 738b0e28d74b521259ae3e3eafececafbb061c93..132f01d3461f143a0e227020b4be1876aa2934f7 100644 (file)
@@ -382,14 +382,28 @@ static ssize_t zonefs_file_dio_append(struct kiocb *iocb, struct iov_iter *from)
        struct zonefs_zone *z = zonefs_inode_zone(inode);
        struct block_device *bdev = inode->i_sb->s_bdev;
        unsigned int max = bdev_max_zone_append_sectors(bdev);
+       pgoff_t start, end;
        struct bio *bio;
-       ssize_t size;
+       ssize_t size = 0;
        int nr_pages;
        ssize_t ret;
 
        max = ALIGN_DOWN(max << SECTOR_SHIFT, inode->i_sb->s_blocksize);
        iov_iter_truncate(from, max);
 
+       /*
+        * If the inode block size (zone write granularity) is smaller than the
+        * page size, we may be appending data belonging to the last page of the
+        * inode straddling inode->i_size, with that page already cached due to
+        * a buffered read or readahead. So make sure to invalidate that page.
+        * This will always be a no-op for the case where the block size is
+        * equal to the page size.
+        */
+       start = iocb->ki_pos >> PAGE_SHIFT;
+       end = (iocb->ki_pos + iov_iter_count(from) - 1) >> PAGE_SHIFT;
+       if (invalidate_inode_pages2_range(inode->i_mapping, start, end))
+               return -EBUSY;
+
        nr_pages = iov_iter_npages(from, BIO_MAX_VECS);
        if (!nr_pages)
                return 0;
@@ -426,7 +440,7 @@ static ssize_t zonefs_file_dio_append(struct kiocb *iocb, struct iov_iter *from)
                if (bio->bi_iter.bi_sector != wpsector) {
                        zonefs_warn(inode->i_sb,
                                "Corrupted write pointer %llu for zone at %llu\n",
-                               wpsector, z->z_sector);
+                               bio->bi_iter.bi_sector, z->z_sector);
                        ret = -EIO;
                }
        }
@@ -567,11 +581,21 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from)
                append = sync;
        }
 
-       if (append)
+       if (append) {
                ret = zonefs_file_dio_append(iocb, from);
-       else
+       } else {
+               /*
+                * iomap_dio_rw() may return ENOTBLK if there was an issue with
+                * page invalidation. Overwrite that error code with EBUSY to
+                * be consistent with zonefs_file_dio_append() return value for
+                * similar issues.
+                */
                ret = iomap_dio_rw(iocb, from, &zonefs_write_iomap_ops,
                                   &zonefs_write_dio_ops, 0, NULL, 0);
+               if (ret == -ENOTBLK)
+                       ret = -EBUSY;
+       }
+
        if (zonefs_zone_is_seq(z) &&
            (ret > 0 || ret == -EIOCBQUEUED)) {
                if (ret > 0)
index 0584e9f6e3397917d361e99f0ba1310f73414fb8..57acb895c03812fb47c44d11fbacef9115b7dafa 100644 (file)
@@ -657,6 +657,7 @@ static inline bool acpi_quirk_skip_acpi_ac_and_battery(void)
 #if IS_ENABLED(CONFIG_X86_ANDROID_TABLETS)
 bool acpi_quirk_skip_i2c_client_enumeration(struct acpi_device *adev);
 int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip);
+bool acpi_quirk_skip_gpio_event_handlers(void);
 #else
 static inline bool acpi_quirk_skip_i2c_client_enumeration(struct acpi_device *adev)
 {
@@ -668,6 +669,10 @@ acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip)
        *skip = false;
        return 0;
 }
+static inline bool acpi_quirk_skip_gpio_event_handlers(void)
+{
+       return false;
+}
 #endif
 
 #ifdef CONFIG_PM
index 95e4f56f97546665165c3ede9ed85f8451f40c6a..1b4f81f1ac5db3e56545cb0e6098effe7a3b3c75 100644 (file)
@@ -723,8 +723,7 @@ typedef u32 acpi_event_type;
 #define ACPI_EVENT_POWER_BUTTON         2
 #define ACPI_EVENT_SLEEP_BUTTON         3
 #define ACPI_EVENT_RTC                  4
-#define ACPI_EVENT_PCIE_WAKE            5
-#define ACPI_EVENT_MAX                  5
+#define ACPI_EVENT_MAX                  4
 #define ACPI_NUM_FIXED_EVENTS           ACPI_EVENT_MAX + 1
 
 /*
index 8ed9bec03e5341ce3669a59ce8f882b1a42cf21e..ff5a8da5d88329c8a7f62f4f9afba8b55414583e 100644 (file)
@@ -59,8 +59,6 @@ extern void acpi_video_unregister(void);
 extern void acpi_video_register_backlight(void);
 extern int acpi_video_get_edid(struct acpi_device *device, int type,
                               int device_id, void **edid);
-extern enum acpi_backlight_type acpi_video_get_backlight_type(void);
-extern bool acpi_video_backlight_use_native(void);
 /*
  * Note: The value returned by acpi_video_handles_brightness_key_presses()
  * may change over time and should not be cached.
@@ -69,6 +67,19 @@ extern bool acpi_video_handles_brightness_key_presses(void);
 extern int acpi_video_get_levels(struct acpi_device *device,
                                 struct acpi_video_device_brightness **dev_br,
                                 int *pmax_level);
+
+extern enum acpi_backlight_type __acpi_video_get_backlight_type(bool native,
+                                                               bool *auto_detect);
+
+static inline enum acpi_backlight_type acpi_video_get_backlight_type(void)
+{
+       return __acpi_video_get_backlight_type(false, NULL);
+}
+
+static inline bool acpi_video_backlight_use_native(void)
+{
+       return __acpi_video_get_backlight_type(true, NULL) == acpi_backlight_native;
+}
 #else
 static inline void acpi_video_report_nolcd(void) { return; };
 static inline int acpi_video_register(void) { return -ENODEV; }
index 04b8be9f1a77ceb93375a26b6079bb122bea1877..e271d6708c876bd94d96b4bcc369f793c2e0b370 100644 (file)
@@ -130,7 +130,7 @@ ATOMIC_OP(xor, ^)
 #define arch_atomic_read(v)                    READ_ONCE((v)->counter)
 #define arch_atomic_set(v, i)                  WRITE_ONCE(((v)->counter), (i))
 
-#define arch_atomic_xchg(ptr, v)               (arch_xchg(&(ptr)->counter, (v)))
-#define arch_atomic_cmpxchg(v, old, new)       (arch_cmpxchg(&((v)->counter), (old), (new)))
+#define arch_atomic_xchg(ptr, v)               (arch_xchg(&(ptr)->counter, (u32)(v)))
+#define arch_atomic_cmpxchg(v, old, new)       (arch_cmpxchg(&((v)->counter), (u32)(old), (u32)(new)))
 
 #endif /* __ASM_GENERIC_ATOMIC_H */
index c3e7315b7c1d660ff02ce230d47287291f0e6787..3df9f59a544e48bdd375cf119f05fa13122ed747 100644 (file)
@@ -26,16 +26,16 @@ static inline unsigned long __generic_cmpxchg_local(volatile void *ptr,
        raw_local_irq_save(flags);
        switch (size) {
        case 1: prev = *(u8 *)ptr;
-               if (prev == (u8)old)
-                       *(u8 *)ptr = (u8)new;
+               if (prev == (old & 0xffu))
+                       *(u8 *)ptr = (new & 0xffu);
                break;
        case 2: prev = *(u16 *)ptr;
-               if (prev == (u16)old)
-                       *(u16 *)ptr = (u16)new;
+               if (prev == (old & 0xffffu))
+                       *(u16 *)ptr = (new & 0xffffu);
                break;
        case 4: prev = *(u32 *)ptr;
-               if (prev == (u32)old)
-                       *(u32 *)ptr = (u32)new;
+               if (prev == (old & 0xffffffffffu))
+                       *(u32 *)ptr = (new & 0xffffffffu);
                break;
        case 8: prev = *(u64 *)ptr;
                if (prev == old)
index dca4419922a971fea7037a70ce7a550d37a92459..848de25fc4bf8f2b4d5e368e1621beec90e25b4a 100644 (file)
@@ -32,7 +32,7 @@ unsigned long __generic_xchg(unsigned long x, volatile void *ptr, int size)
 #else
                local_irq_save(flags);
                ret = *(volatile u8 *)ptr;
-               *(volatile u8 *)ptr = x;
+               *(volatile u8 *)ptr = (x & 0xffu);
                local_irq_restore(flags);
                return ret;
 #endif /* __xchg_u8 */
@@ -43,7 +43,7 @@ unsigned long __generic_xchg(unsigned long x, volatile void *ptr, int size)
 #else
                local_irq_save(flags);
                ret = *(volatile u16 *)ptr;
-               *(volatile u16 *)ptr = x;
+               *(volatile u16 *)ptr = (x & 0xffffu);
                local_irq_restore(flags);
                return ret;
 #endif /* __xchg_u16 */
@@ -54,7 +54,7 @@ unsigned long __generic_xchg(unsigned long x, volatile void *ptr, int size)
 #else
                local_irq_save(flags);
                ret = *(volatile u32 *)ptr;
-               *(volatile u32 *)ptr = x;
+               *(volatile u32 *)ptr = (x & 0xffffffffu);
                local_irq_restore(flags);
                return ret;
 #endif /* __xchg_u32 */
index 4c44a29b5e8ef0e06d4af08e0ea4560e68fce6cf..587e7e9b9a375c8ed362f53b3860193bd5e913b4 100644 (file)
@@ -236,7 +236,7 @@ static inline u64 readq(const volatile void __iomem *addr)
 
        log_read_mmio(64, addr, _THIS_IP_, _RET_IP_);
        __io_br();
-       val = __le64_to_cpu(__raw_readq(addr));
+       val = __le64_to_cpu((__le64 __force)__raw_readq(addr));
        __io_ar(val);
        log_post_read_mmio(val, 64, addr, _THIS_IP_, _RET_IP_);
        return val;
@@ -287,7 +287,7 @@ static inline void writeq(u64 value, volatile void __iomem *addr)
 {
        log_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_);
        __io_bw();
-       __raw_writeq(__cpu_to_le64(value), addr);
+       __raw_writeq((u64 __force)__cpu_to_le64(value), addr);
        __io_aw();
        log_post_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_);
 }
@@ -319,7 +319,7 @@ static inline u16 readw_relaxed(const volatile void __iomem *addr)
        u16 val;
 
        log_read_mmio(16, addr, _THIS_IP_, _RET_IP_);
-       val = __le16_to_cpu(__raw_readw(addr));
+       val = __le16_to_cpu((__le16 __force)__raw_readw(addr));
        log_post_read_mmio(val, 16, addr, _THIS_IP_, _RET_IP_);
        return val;
 }
@@ -332,7 +332,7 @@ static inline u32 readl_relaxed(const volatile void __iomem *addr)
        u32 val;
 
        log_read_mmio(32, addr, _THIS_IP_, _RET_IP_);
-       val = __le32_to_cpu(__raw_readl(addr));
+       val = __le32_to_cpu((__le32 __force)__raw_readl(addr));
        log_post_read_mmio(val, 32, addr, _THIS_IP_, _RET_IP_);
        return val;
 }
@@ -345,7 +345,7 @@ static inline u64 readq_relaxed(const volatile void __iomem *addr)
        u64 val;
 
        log_read_mmio(64, addr, _THIS_IP_, _RET_IP_);
-       val = __le64_to_cpu(__raw_readq(addr));
+       val = __le64_to_cpu((__le64 __force)__raw_readq(addr));
        log_post_read_mmio(val, 64, addr, _THIS_IP_, _RET_IP_);
        return val;
 }
@@ -366,7 +366,7 @@ static inline void writeb_relaxed(u8 value, volatile void __iomem *addr)
 static inline void writew_relaxed(u16 value, volatile void __iomem *addr)
 {
        log_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_);
-       __raw_writew(cpu_to_le16(value), addr);
+       __raw_writew((u16 __force)cpu_to_le16(value), addr);
        log_post_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_);
 }
 #endif
@@ -376,7 +376,7 @@ static inline void writew_relaxed(u16 value, volatile void __iomem *addr)
 static inline void writel_relaxed(u32 value, volatile void __iomem *addr)
 {
        log_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_);
-       __raw_writel(__cpu_to_le32(value), addr);
+       __raw_writel((u32 __force)__cpu_to_le32(value), addr);
        log_post_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_);
 }
 #endif
@@ -386,7 +386,7 @@ static inline void writel_relaxed(u32 value, volatile void __iomem *addr)
 static inline void writeq_relaxed(u64 value, volatile void __iomem *addr)
 {
        log_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_);
-       __raw_writeq(__cpu_to_le64(value), addr);
+       __raw_writeq((u64 __force)__cpu_to_le64(value), addr);
        log_post_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_);
 }
 #endif
index 68f7aa2a7e55cc9cbdb382cb608af619544983e6..653992a6e9410464f73a5d75a3393c80324835a0 100644 (file)
@@ -28,6 +28,10 @@ struct public_key {
        bool key_is_private;
        const char *id_type;
        const char *pkey_algo;
+       unsigned long key_eflags;       /* key extension flags */
+#define KEY_EFLAG_CA           0       /* set if the CA basic constraints is set */
+#define KEY_EFLAG_DIGITALSIG   1       /* set if the digitalSignature usage is set */
+#define KEY_EFLAG_KEYCERTSIGN  2       /* set if the keyCertSign usage is set */
 };
 
 extern void public_key_free(struct public_key *key);
@@ -71,6 +75,21 @@ extern int restrict_link_by_key_or_keyring_chain(struct key *trust_keyring,
                                                 const union key_payload *payload,
                                                 struct key *trusted);
 
+#if IS_REACHABLE(CONFIG_ASYMMETRIC_KEY_TYPE)
+extern int restrict_link_by_ca(struct key *dest_keyring,
+                              const struct key_type *type,
+                              const union key_payload *payload,
+                              struct key *trust_keyring);
+#else
+static inline int restrict_link_by_ca(struct key *dest_keyring,
+                                     const struct key_type *type,
+                                     const union key_payload *payload,
+                                     struct key *trust_keyring)
+{
+       return 0;
+}
+#endif
+
 extern int query_asymmetric_key(const struct kernel_pkey_params *,
                                struct kernel_pkey_query *);
 
@@ -80,7 +99,16 @@ extern int create_signature(struct kernel_pkey_params *, const void *, void *);
 extern int verify_signature(const struct key *,
                            const struct public_key_signature *);
 
+#if IS_REACHABLE(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE)
 int public_key_verify_signature(const struct public_key *pkey,
                                const struct public_key_signature *sig);
+#else
+static inline
+int public_key_verify_signature(const struct public_key *pkey,
+                               const struct public_key_signature *sig)
+{
+       return -EINVAL;
+}
+#endif
 
 #endif /* _LINUX_PUBLIC_KEY_H */
index 42f86327b40a790f71d5d9d92369ce9f053867df..bf964cdfb3300d98365be6ae487f8d69d2d71f47 100644 (file)
@@ -423,11 +423,11 @@ struct drm_bridge_funcs {
         *
         * The returned array must be allocated with kmalloc() and will be
         * freed by the caller. If the allocation fails, NULL should be
-        * returned. num_output_fmts must be set to the returned array size.
+        * returned. num_input_fmts must be set to the returned array size.
         * Formats listed in the returned array should be listed in decreasing
         * preference order (the core will try all formats until it finds one
         * that works). When the format is not supported NULL should be
-        * returned and num_output_fmts should be set to 0.
+        * returned and num_input_fmts should be set to 0.
         *
         * This method is called on all elements of the bridge chain as part of
         * the bus format negotiation process that happens in
index 772a4adf52870a1fba07d0976b7b447c3de94abe..f1f00fc2dba614b6fa3de952030be476f1d85b8c 100644 (file)
@@ -476,7 +476,9 @@ int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
 void drm_gem_lru_init(struct drm_gem_lru *lru, struct mutex *lock);
 void drm_gem_lru_remove(struct drm_gem_object *obj);
 void drm_gem_lru_move_tail(struct drm_gem_lru *lru, struct drm_gem_object *obj);
-unsigned long drm_gem_lru_scan(struct drm_gem_lru *lru, unsigned nr_to_scan,
+unsigned long drm_gem_lru_scan(struct drm_gem_lru *lru,
+                              unsigned int nr_to_scan,
+                              unsigned long *remaining,
                               bool (*shrink)(struct drm_gem_object *obj));
 
 #endif /* __DRM_GEM_H__ */
index 9db9e5e504eeb32f5c527ccbbaa1773388af15ad..9935d1e2ff69a38437de9d5729d15fd6b64b0d18 100644 (file)
@@ -228,13 +228,6 @@ struct drm_sched_entity {
         */
        struct rb_node                  rb_tree_node;
 
-       /**
-        * @elapsed_ns:
-        *
-        * Records the amount of time where jobs from this entity were active
-        * on the GPU.
-        */
-       uint64_t elapsed_ns;
 };
 
 /**
index cf6fb8f2ac1bd15d9a8526cf954c04b8c7fde3be..c0d88b318e9068b03812863b374fb3d47550ef2c 100644 (file)
@@ -72,7 +72,7 @@ typedef void (*kunit_resource_free_t)(struct kunit_resource *);
  *             params.gfp = gfp;
  *
  *             return kunit_alloc_resource(test, kunit_kmalloc_init,
- *                     kunit_kmalloc_free, &params);
+ *                     kunit_kmalloc_free, gfp, &params);
  *     }
  *
  * Resources can also be named, with lookup/removal done on a name
index 08d3559dd7038c720cdf839936b049922144925a..57b309c6ca27b3ae0c6348cd3305cf4ecb6b1913 100644 (file)
@@ -34,7 +34,7 @@ DECLARE_STATIC_KEY_FALSE(kunit_running);
 struct kunit;
 
 /* Size of log associated with test. */
-#define KUNIT_LOG_SIZE 512
+#define KUNIT_LOG_SIZE 2048
 
 /* Maximum size of parameter description string. */
 #define KUNIT_PARAM_DESC_SIZE 128
@@ -420,7 +420,7 @@ void __printf(2, 3) kunit_log_append(char *log, const char *fmt, ...);
 #define kunit_log(lvl, test_or_suite, fmt, ...)                                \
        do {                                                            \
                printk(lvl fmt, ##__VA_ARGS__);                         \
-               kunit_log_append((test_or_suite)->log,  fmt "\n",       \
+               kunit_log_append((test_or_suite)->log,  fmt,            \
                                 ##__VA_ARGS__);                        \
        } while (0)
 
index 71916de7c6c4de30259b77a2b723e4947128b2fa..c52a6e6839da9c8df41d50fa295f9ccc0871f14c 100644 (file)
@@ -23,6 +23,19 @@ enum kvm_arch_timer_regs {
        TIMER_REG_CTL,
 };
 
+struct arch_timer_offset {
+       /*
+        * If set, pointer to one of the offsets in the kvm's offset
+        * structure. If NULL, assume a zero offset.
+        */
+       u64     *vm_offset;
+};
+
+struct arch_timer_vm_data {
+       /* Offset applied to the virtual timer/counter */
+       u64     voffset;
+};
+
 struct arch_timer_context {
        struct kvm_vcpu                 *vcpu;
 
@@ -32,6 +45,8 @@ struct arch_timer_context {
        /* Emulated Timer (may be unused) */
        struct hrtimer                  hrtimer;
 
+       /* Offset for this counter/timer */
+       struct arch_timer_offset        offset;
        /*
         * We have multiple paths which can save/restore the timer state onto
         * the hardware, so we need some way of keeping track of where the
index 0a24ab7cb66fa2eab5650f815d9a8370e9fb8cab..8e2eefa9fbc0f0747b756a2097cb882a95362873 100644 (file)
@@ -9,7 +9,14 @@
 #include <linux/phy.h>
 
 #if IS_ENABLED(CONFIG_ACPI_MDIO)
-int acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode);
+int __acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode,
+                           struct module *owner);
+
+static inline int
+acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *handle)
+{
+       return __acpi_mdiobus_register(mdio, handle, THIS_MODULE);
+}
 #else /* CONFIG_ACPI_MDIO */
 static inline int
 acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode)
index dd5ce1137f04aeed0ce86b732b14d34c36710716..de0b0c3e7395a60f2316a99536fc58927eb36427 100644 (file)
@@ -228,6 +228,12 @@ static inline unsigned short req_get_ioprio(struct request *req)
        *(listptr) = rq;                                \
 } while (0)
 
+#define rq_list_add_tail(lastpptr, rq) do {            \
+       (rq)->rq_next = NULL;                           \
+       **(lastpptr) = rq;                              \
+       *(lastpptr) = &rq->rq_next;                     \
+} while (0)
+
 #define rq_list_pop(listptr)                           \
 ({                                                     \
        struct request *__req = NULL;                   \
index d1aee08f8c1811d645856ce4b92e24cb4cd236ab..941304f17492f05708d925bfd347755b2e5f272e 100644 (file)
@@ -1446,11 +1446,10 @@ static inline void blk_wake_io_task(struct task_struct *waiter)
                wake_up_process(waiter);
 }
 
-unsigned long bdev_start_io_acct(struct block_device *bdev,
-                                unsigned int sectors, enum req_op op,
+unsigned long bdev_start_io_acct(struct block_device *bdev, enum req_op op,
                                 unsigned long start_time);
 void bdev_end_io_acct(struct block_device *bdev, enum req_op op,
-               unsigned long start_time);
+                     unsigned int sectors, unsigned long start_time);
 
 unsigned long bio_start_io_acct(struct bio *bio);
 void bio_end_io_acct_remapped(struct bio *bio, unsigned long start_time,
index 842e72a5348fa3f571a1f1669af3c6c617ffe905..6f3175f0678a8d78153d96157eef9edc9bfce36e 100644 (file)
@@ -1363,7 +1363,13 @@ struct clk_hw_onecell_data {
        struct clk_hw *hws[];
 };
 
-#define CLK_OF_DECLARE(name, compat, fn) OF_DECLARE_1(clk, name, compat, fn)
+#define CLK_OF_DECLARE(name, compat, fn) \
+       static void __init __##name##_of_clk_init_declare(struct device_node *np) \
+       {                                                               \
+               fn(np);                                                 \
+               fwnode_dev_initialized(of_fwnode_handle(np), true);     \
+       }                                                               \
+       OF_DECLARE_1(clk, name, compat, __##name##_of_clk_init_declare)
 
 /*
  * Use this macro when you have a driver that requires two initialization
index d4afa8508a806bc500c3a058799722eb9c74e749..3a7909ed54980d7a373335874c43135f57c3f384 100644 (file)
@@ -96,6 +96,7 @@ static inline void user_exit_irqoff(void) { }
 static inline int exception_enter(void) { return 0; }
 static inline void exception_exit(enum ctx_state prev_ctx) { }
 static inline int ct_state(void) { return -1; }
+static inline int __ct_state(void) { return -1; }
 static __always_inline bool context_tracking_guest_enter(void) { return false; }
 static inline void context_tracking_guest_exit(void) { }
 #define CT_WARN_ON(cond) do { } while (0)
index 4a4d56f771802bf97cfcf16eee960ca948a29974..fdd537ea513ffa35562cc636900e0a0a5b7faaa4 100644 (file)
@@ -46,7 +46,9 @@ struct context_tracking {
 
 #ifdef CONFIG_CONTEXT_TRACKING
 DECLARE_PER_CPU(struct context_tracking, context_tracking);
+#endif
 
+#ifdef CONFIG_CONTEXT_TRACKING_USER
 static __always_inline int __ct_state(void)
 {
        return arch_atomic_read(this_cpu_ptr(&context_tracking.state)) & CT_STATE_MASK;
index c6fab004104a80199e65add70ba9a466068b0a20..5b2f8147d1ae3fe1edb9b352ed79e5c4bd959342 100644 (file)
@@ -218,7 +218,6 @@ enum cpuhp_state {
        CPUHP_AP_PERF_X86_CQM_ONLINE,
        CPUHP_AP_PERF_X86_CSTATE_ONLINE,
        CPUHP_AP_PERF_X86_IDXD_ONLINE,
-       CPUHP_AP_PERF_X86_IOMMU_PERF_ONLINE,
        CPUHP_AP_PERF_S390_CF_ONLINE,
        CPUHP_AP_PERF_S390_SF_ONLINE,
        CPUHP_AP_PERF_ARM_CCI_ONLINE,
index 8fbe76607965e9e3de8e948c8b923a086bbce763..ca736b05ec7b056ebafae5f347913ce1fec97d2d 100644 (file)
@@ -66,7 +66,7 @@ static inline void set_nr_cpu_ids(unsigned int nr)
  *
  * Finally, some operations just want the exact limit, either because
  * they set bits or just don't have any faster fixed-sized versions. We
- * call this just 'nr_cpumask_size'.
+ * call this just 'nr_cpumask_bits'.
  *
  * Note that these optional constants are always guaranteed to be at
  * least as big as 'nr_cpu_ids' itself is, and all our cpumask
@@ -147,7 +147,7 @@ static __always_inline void cpu_max_bits_warn(unsigned int cpu, unsigned int bit
 /* verify cpu argument to cpumask_* operators */
 static __always_inline unsigned int cpumask_check(unsigned int cpu)
 {
-       cpu_max_bits_warn(cpu, nr_cpumask_bits);
+       cpu_max_bits_warn(cpu, small_cpumask_bits);
        return cpu;
 }
 
@@ -350,6 +350,23 @@ unsigned int __pure cpumask_next_wrap(int n, const struct cpumask *mask, int sta
 #define for_each_cpu_andnot(cpu, mask1, mask2)                         \
        for_each_andnot_bit(cpu, cpumask_bits(mask1), cpumask_bits(mask2), small_cpumask_bits)
 
+/**
+ * for_each_cpu_or - iterate over every cpu present in either mask
+ * @cpu: the (optionally unsigned) integer iterator
+ * @mask1: the first cpumask pointer
+ * @mask2: the second cpumask pointer
+ *
+ * This saves a temporary CPU mask in many places.  It is equivalent to:
+ *     struct cpumask tmp;
+ *     cpumask_or(&tmp, &mask1, &mask2);
+ *     for_each_cpu(cpu, &tmp)
+ *             ...
+ *
+ * After the loop, cpu is >= nr_cpu_ids.
+ */
+#define for_each_cpu_or(cpu, mask1, mask2)                             \
+       for_each_or_bit(cpu, cpumask_bits(mask1), cpumask_bits(mask2), small_cpumask_bits)
+
 /**
  * cpumask_any_but - return a "random" in a cpumask, but not this one.
  * @mask: the cpumask to search
@@ -518,14 +535,14 @@ static __always_inline bool cpumask_test_and_clear_cpu(int cpu, struct cpumask *
 /**
  * cpumask_setall - set all cpus (< nr_cpu_ids) in a cpumask
  * @dstp: the cpumask pointer
- *
- * Note: since we set bits, we should use the tighter 'bitmap_set()' with
- * the eact number of bits, not 'bitmap_fill()' that will fill past the
- * end.
  */
 static inline void cpumask_setall(struct cpumask *dstp)
 {
-       bitmap_set(cpumask_bits(dstp), 0, nr_cpumask_bits);
+       if (small_const_nbits(small_cpumask_bits)) {
+               cpumask_bits(dstp)[0] = BITMAP_LAST_WORD_MASK(nr_cpumask_bits);
+               return;
+       }
+       bitmap_fill(cpumask_bits(dstp), nr_cpumask_bits);
 }
 
 /**
index 04a733f0ba9562115470787468c3fc10b605a9d4..7aa62c92185f6467069fe07aedb8cf4e0041d352 100644 (file)
@@ -693,6 +693,7 @@ efi_guid_to_str(efi_guid_t *guid, char *out)
 }
 
 extern void efi_init (void);
+extern void efi_earlycon_reprobe(void);
 #ifdef CONFIG_EFI
 extern void efi_enter_virtual_mode (void);     /* switch EFI to virtual mode, if possible */
 #else
index d8d20514ea052259c466b311fc058b5faa7cb9c6..02d09cb57f6c92ec13906352e831118f06dbb1ae 100644 (file)
@@ -212,6 +212,7 @@ struct fb_deferred_io {
        /* delay between mkwrite and deferred handler */
        unsigned long delay;
        bool sort_pagereflist; /* sort pagelist by offset */
+       int open_count; /* number of opened files; protected by fb_info lock */
        struct mutex lock; /* mutex that protects the pageref list */
        struct list_head pagereflist; /* list of pagerefs for touched pages */
        /* callback */
index 4647864a5ffdbb972fb1a1a21eb79178755b72d5..5e4f39ef2e72cc00b5924f048d60394e6e579313 100644 (file)
@@ -14,6 +14,8 @@ unsigned long _find_next_and_bit(const unsigned long *addr1, const unsigned long
                                        unsigned long nbits, unsigned long start);
 unsigned long _find_next_andnot_bit(const unsigned long *addr1, const unsigned long *addr2,
                                        unsigned long nbits, unsigned long start);
+unsigned long _find_next_or_bit(const unsigned long *addr1, const unsigned long *addr2,
+                                       unsigned long nbits, unsigned long start);
 unsigned long _find_next_zero_bit(const unsigned long *addr, unsigned long nbits,
                                         unsigned long start);
 extern unsigned long _find_first_bit(const unsigned long *addr, unsigned long size);
@@ -127,6 +129,36 @@ unsigned long find_next_andnot_bit(const unsigned long *addr1,
 }
 #endif
 
+#ifndef find_next_or_bit
+/**
+ * find_next_or_bit - find the next set bit in either memory regions
+ * @addr1: The first address to base the search on
+ * @addr2: The second address to base the search on
+ * @size: The bitmap size in bits
+ * @offset: The bitnumber to start searching at
+ *
+ * Returns the bit number for the next set bit
+ * If no bits are set, returns @size.
+ */
+static inline
+unsigned long find_next_or_bit(const unsigned long *addr1,
+               const unsigned long *addr2, unsigned long size,
+               unsigned long offset)
+{
+       if (small_const_nbits(size)) {
+               unsigned long val;
+
+               if (unlikely(offset >= size))
+                       return size;
+
+               val = (*addr1 | *addr2) & GENMASK(size - 1, offset);
+               return val ? __ffs(val) : size;
+       }
+
+       return _find_next_or_bit(addr1, addr2, size, offset);
+}
+#endif
+
 #ifndef find_next_zero_bit
 /**
  * find_next_zero_bit - find the next cleared bit in a memory region
@@ -536,6 +568,11 @@ unsigned long find_next_bit_le(const void *addr, unsigned
             (bit) = find_next_andnot_bit((addr1), (addr2), (size), (bit)), (bit) < (size);\
             (bit)++)
 
+#define for_each_or_bit(bit, addr1, addr2, size) \
+       for ((bit) = 0;                                                                 \
+            (bit) = find_next_or_bit((addr1), (addr2), (size), (bit)), (bit) < (size);\
+            (bit)++)
+
 /* same as for_each_set_bit() but use bit as value to start with */
 #define for_each_set_bit_from(bit, addr, size) \
        for (; (bit) = find_next_bit((addr), (size), (bit)), (bit) < (size); (bit)++)
index c85916e9f7db500474d043c1f6a6b5e5c8d22020..ef2281a2accef88e1326ee4f8b1d970792288254 100644 (file)
@@ -2675,6 +2675,8 @@ extern struct inode *new_inode(struct super_block *sb);
 extern void free_inode_nonrcu(struct inode *inode);
 extern int setattr_should_drop_suidgid(struct mnt_idmap *, struct inode *);
 extern int file_remove_privs(struct file *);
+int setattr_should_drop_sgid(struct mnt_idmap *idmap,
+                            const struct inode *inode);
 
 /*
  * This must be used for allocating filesystems specific inodes to set
@@ -2778,7 +2780,7 @@ enum {
 ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
                             struct block_device *bdev, struct iov_iter *iter,
                             get_block_t get_block,
-                            dio_iodone_t end_io, dio_submit_t submit_io,
+                            dio_iodone_t end_io,
                             int flags);
 
 static inline ssize_t blockdev_direct_IO(struct kiocb *iocb,
@@ -2787,7 +2789,7 @@ static inline ssize_t blockdev_direct_IO(struct kiocb *iocb,
                                         get_block_t get_block)
 {
        return __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev, iter,
-                       get_block, NULL, NULL, DIO_LOCKING | DIO_SKIP_HOLES);
+                       get_block, NULL, DIO_LOCKING | DIO_SKIP_HOLES);
 }
 #endif
 
index 5469ffee21c73f2b34d3bc8548a351e46e01f2f7..ff6341e09925bc84539351c560661400c032305d 100644 (file)
@@ -104,7 +104,6 @@ struct fs_context {
        unsigned int            sb_flags;       /* Proposed superblock flags (SB_*) */
        unsigned int            sb_flags_mask;  /* Superblock flags that were changed */
        unsigned int            s_iflags;       /* OR'd with sb->s_iflags */
-       unsigned int            lsm_flags;      /* Information flags from the fs to the LSM */
        enum fs_context_purpose purpose:8;
        enum fs_context_phase   phase:8;        /* The phase the context is in */
        bool                    need_free:1;    /* Need to call ops->free() */
index 366c730beaa3e4c52423ae09a8c1f1e548bf2a87..402fc061de75cdc7582c70f9fb403671e4fef3d6 100644 (file)
@@ -980,7 +980,7 @@ static inline void __ftrace_enabled_restore(int enabled)
 #define CALLER_ADDR5 ((unsigned long)ftrace_return_address(5))
 #define CALLER_ADDR6 ((unsigned long)ftrace_return_address(6))
 
-static inline unsigned long get_lock_parent_ip(void)
+static __always_inline unsigned long get_lock_parent_ip(void)
 {
        unsigned long addr = CALLER_ADDR0;
 
index eaf8ab1773033214f59d556e4ab686300a51e8d1..1ea8c7a3570b2880aeb353d9707ad4f9a7df1ca4 100644 (file)
@@ -834,6 +834,7 @@ struct hid_driver {
  * @output_report: send output report to device
  * @idle: send idle request to device
  * @may_wakeup: return if device may act as a wakeup source during system-suspend
+ * @max_buffer_size: over-ride maximum data buffer size (default: HID_MAX_BUFFER_SIZE)
  */
 struct hid_ll_driver {
        int (*start)(struct hid_device *hdev);
@@ -859,6 +860,8 @@ struct hid_ll_driver {
 
        int (*idle)(struct hid_device *hdev, int report, int idle, int reqtype);
        bool (*may_wakeup)(struct hid_device *hdev);
+
+       unsigned int max_buffer_size;
 };
 
 extern bool hid_is_usb(const struct hid_device *hdev);
index b06254e76d99af8fa4dddf59247b3b965802fe8b..8fc10089e19e8eba985cc335d21e2c0975379acf 100644 (file)
@@ -481,4 +481,10 @@ static inline void folio_zero_range(struct folio *folio,
        zero_user_segments(&folio->page, start, start + length, 0, 0);
 }
 
+static inline void put_and_unmap_page(struct page *page, void *addr)
+{
+       kunmap_local(addr);
+       put_page(page);
+}
+
 #endif /* _LINUX_HIGHMEM_H */
index 500404d85141dd5a1fee2f956eb22e4636eb9722..5ba89663ea8656fab46473920229a7a67935d1f8 100644 (file)
@@ -236,8 +236,8 @@ enum i2c_driver_flags {
 /**
  * struct i2c_driver - represent an I2C device driver
  * @class: What kind of i2c device we instantiate (for detect)
- * @probe: Callback for device binding - soon to be deprecated
- * @probe_new: New callback for device binding
+ * @probe: Callback for device binding
+ * @probe_new: Transitional callback for device binding - do not use
  * @remove: Callback for device unbinding
  * @shutdown: Callback for device shutdown
  * @alert: Alert callback, for example for the SMBus alert protocol
@@ -272,14 +272,18 @@ enum i2c_driver_flags {
 struct i2c_driver {
        unsigned int class;
 
+       union {
        /* Standard driver model interfaces */
-       int (*probe)(struct i2c_client *client, const struct i2c_device_id *id);
+               int (*probe)(struct i2c_client *client);
+               /*
+                * Legacy callback that was part of a conversion of .probe().
+                * Today it has the same semantic as .probe(). Don't use for new
+                * code.
+                */
+               int (*probe_new)(struct i2c_client *client);
+       };
        void (*remove)(struct i2c_client *client);
 
-       /* New driver model interface to aid the seamless removal of the
-        * current probe()'s, more commonly unused than used second parameter.
-        */
-       int (*probe_new)(struct i2c_client *client);
 
        /* driver model interfaces that don't relate to enumeration  */
        void (*shutdown)(struct i2c_client *client);
index 501fa84867494787e0f7a20e077c1252c5e932d8..1b608e00290aa14e41ba6ee3321d9d26c18cb2ff 100644 (file)
 
 /**
  * instrument_read - instrument regular read access
+ * @v: address of access
+ * @size: size of access
  *
  * Instrument a regular read access. The instrumentation should be inserted
  * before the actual read happens.
- *
- * @ptr address of access
- * @size size of access
  */
 static __always_inline void instrument_read(const volatile void *v, size_t size)
 {
@@ -30,12 +29,11 @@ static __always_inline void instrument_read(const volatile void *v, size_t size)
 
 /**
  * instrument_write - instrument regular write access
+ * @v: address of access
+ * @size: size of access
  *
  * Instrument a regular write access. The instrumentation should be inserted
  * before the actual write happens.
- *
- * @ptr address of access
- * @size size of access
  */
 static __always_inline void instrument_write(const volatile void *v, size_t size)
 {
@@ -45,12 +43,11 @@ static __always_inline void instrument_write(const volatile void *v, size_t size
 
 /**
  * instrument_read_write - instrument regular read-write access
+ * @v: address of access
+ * @size: size of access
  *
  * Instrument a regular write access. The instrumentation should be inserted
  * before the actual write happens.
- *
- * @ptr address of access
- * @size size of access
  */
 static __always_inline void instrument_read_write(const volatile void *v, size_t size)
 {
@@ -60,12 +57,11 @@ static __always_inline void instrument_read_write(const volatile void *v, size_t
 
 /**
  * instrument_atomic_read - instrument atomic read access
+ * @v: address of access
+ * @size: size of access
  *
  * Instrument an atomic read access. The instrumentation should be inserted
  * before the actual read happens.
- *
- * @ptr address of access
- * @size size of access
  */
 static __always_inline void instrument_atomic_read(const volatile void *v, size_t size)
 {
@@ -75,12 +71,11 @@ static __always_inline void instrument_atomic_read(const volatile void *v, size_
 
 /**
  * instrument_atomic_write - instrument atomic write access
+ * @v: address of access
+ * @size: size of access
  *
  * Instrument an atomic write access. The instrumentation should be inserted
  * before the actual write happens.
- *
- * @ptr address of access
- * @size size of access
  */
 static __always_inline void instrument_atomic_write(const volatile void *v, size_t size)
 {
@@ -90,12 +85,11 @@ static __always_inline void instrument_atomic_write(const volatile void *v, size
 
 /**
  * instrument_atomic_read_write - instrument atomic read-write access
+ * @v: address of access
+ * @size: size of access
  *
  * Instrument an atomic read-write access. The instrumentation should be
  * inserted before the actual write happens.
- *
- * @ptr address of access
- * @size size of access
  */
 static __always_inline void instrument_atomic_read_write(const volatile void *v, size_t size)
 {
@@ -105,13 +99,12 @@ static __always_inline void instrument_atomic_read_write(const volatile void *v,
 
 /**
  * instrument_copy_to_user - instrument reads of copy_to_user
+ * @to: destination address
+ * @from: source address
+ * @n: number of bytes to copy
  *
  * Instrument reads from kernel memory, that are due to copy_to_user (and
  * variants). The instrumentation must be inserted before the accesses.
- *
- * @to destination address
- * @from source address
- * @n number of bytes to copy
  */
 static __always_inline void
 instrument_copy_to_user(void __user *to, const void *from, unsigned long n)
@@ -123,13 +116,12 @@ instrument_copy_to_user(void __user *to, const void *from, unsigned long n)
 
 /**
  * instrument_copy_from_user_before - add instrumentation before copy_from_user
+ * @to: destination address
+ * @from: source address
+ * @n: number of bytes to copy
  *
  * Instrument writes to kernel memory, that are due to copy_from_user (and
  * variants). The instrumentation should be inserted before the accesses.
- *
- * @to destination address
- * @from source address
- * @n number of bytes to copy
  */
 static __always_inline void
 instrument_copy_from_user_before(const void *to, const void __user *from, unsigned long n)
@@ -140,14 +132,13 @@ instrument_copy_from_user_before(const void *to, const void __user *from, unsign
 
 /**
  * instrument_copy_from_user_after - add instrumentation after copy_from_user
+ * @to: destination address
+ * @from: source address
+ * @n: number of bytes to copy
+ * @left: number of bytes not copied (as returned by copy_from_user)
  *
  * Instrument writes to kernel memory, that are due to copy_from_user (and
  * variants). The instrumentation should be inserted after the accesses.
- *
- * @to destination address
- * @from source address
- * @n number of bytes to copy
- * @left number of bytes not copied (as returned by copy_from_user)
  */
 static __always_inline void
 instrument_copy_from_user_after(const void *to, const void __user *from,
@@ -158,12 +149,11 @@ instrument_copy_from_user_after(const void *to, const void __user *from,
 
 /**
  * instrument_get_user() - add instrumentation to get_user()-like macros
+ * @to: destination variable, may not be address-taken
  *
  * get_user() and friends are fragile, so it may depend on the implementation
  * whether the instrumentation happens before or after the data is copied from
  * the userspace.
- *
- * @to destination variable, may not be address-taken
  */
 #define instrument_get_user(to)                                \
 ({                                                     \
@@ -175,14 +165,13 @@ instrument_copy_from_user_after(const void *to, const void __user *from,
 
 /**
  * instrument_put_user() - add instrumentation to put_user()-like macros
+ * @from: source address
+ * @ptr: userspace pointer to copy to
+ * @size: number of bytes to copy
  *
  * put_user() and friends are fragile, so it may depend on the implementation
  * whether the instrumentation happens before or after the data is copied from
  * the userspace.
- *
- * @from source address
- * @ptr userspace pointer to copy to
- * @size number of bytes to copy
  */
 #define instrument_put_user(from, ptr, size)                   \
 ({                                                             \
index cd5c5a27557f5605b78eed7531b58124b114fbd6..d12cd18aab3f49448a49f46c0e56689329c234e3 100644 (file)
@@ -122,6 +122,9 @@ int icc_link_destroy(struct icc_node *src, struct icc_node *dst);
 void icc_node_add(struct icc_node *node, struct icc_provider *provider);
 void icc_node_del(struct icc_node *node);
 int icc_nodes_remove(struct icc_provider *provider);
+void icc_provider_init(struct icc_provider *provider);
+int icc_provider_register(struct icc_provider *provider);
+void icc_provider_deregister(struct icc_provider *provider);
 int icc_provider_add(struct icc_provider *provider);
 void icc_provider_del(struct icc_provider *provider);
 struct icc_node_data *of_icc_get_from_provider(struct of_phandle_args *spec);
@@ -167,6 +170,15 @@ static inline int icc_nodes_remove(struct icc_provider *provider)
        return -ENOTSUPP;
 }
 
+static inline void icc_provider_init(struct icc_provider *provider) { }
+
+static inline int icc_provider_register(struct icc_provider *provider)
+{
+       return -ENOTSUPP;
+}
+
+static inline void icc_provider_deregister(struct icc_provider *provider) { }
+
 static inline int icc_provider_add(struct icc_provider *provider)
 {
        return -ENOTSUPP;
index 934e5dd4ccc08d14f8d8731a41fd73c3c73d4d96..35b9328ca3352eeca32b89914ee169421f965262 100644 (file)
@@ -27,7 +27,7 @@ struct io_uring_cmd {
        const void      *cmd;
        union {
                /* callback to defer completions to task context */
-               void (*task_work_cb)(struct io_uring_cmd *cmd);
+               void (*task_work_cb)(struct io_uring_cmd *cmd, unsigned);
                /* used for polled completion */
                void *cookie;
        };
@@ -39,9 +39,10 @@ struct io_uring_cmd {
 #if defined(CONFIG_IO_URING)
 int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw,
                              struct iov_iter *iter, void *ioucmd);
-void io_uring_cmd_done(struct io_uring_cmd *cmd, ssize_t ret, ssize_t res2);
+void io_uring_cmd_done(struct io_uring_cmd *cmd, ssize_t ret, ssize_t res2,
+                       unsigned issue_flags);
 void io_uring_cmd_complete_in_task(struct io_uring_cmd *ioucmd,
-                       void (*task_work_cb)(struct io_uring_cmd *));
+                       void (*task_work_cb)(struct io_uring_cmd *, unsigned));
 struct sock *io_uring_get_socket(struct file *file);
 void __io_uring_cancel(bool cancel_all);
 void __io_uring_free(struct task_struct *tsk);
@@ -72,11 +73,11 @@ static inline int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw,
        return -EOPNOTSUPP;
 }
 static inline void io_uring_cmd_done(struct io_uring_cmd *cmd, ssize_t ret,
-               ssize_t ret2)
+               ssize_t ret2, unsigned issue_flags)
 {
 }
 static inline void io_uring_cmd_complete_in_task(struct io_uring_cmd *ioucmd,
-                       void (*task_work_cb)(struct io_uring_cmd *))
+                       void (*task_work_cb)(struct io_uring_cmd *, unsigned))
 {
 }
 static inline struct sock *io_uring_get_socket(struct file *file)
index 5962072a4b19e6e92de7f568dd4e5b8d666aad09..f619bae1dcc5d3a0ded86964f862d4310a289054 100644 (file)
@@ -1308,6 +1308,14 @@ struct journal_s
                                    struct buffer_head *bh,
                                    enum passtype pass, int off,
                                    tid_t expected_commit_id);
+
+       /**
+        * @j_bmap:
+        *
+        * Bmap function that should be used instead of the generic
+        * VFS bmap function.
+        */
+       int (*j_bmap)(struct journal_s *journal, sector_t *block);
 };
 
 #define jbd2_might_wait_for_commit(j) \
index e38ae3c346184630f1691d6431ffbc3675bd8194..30b17647ce3c73e56c06aaf94863cc70ed206a93 100644 (file)
@@ -134,11 +134,12 @@ void kmsan_kfree_large(const void *ptr);
  * @page_shift:        page_shift passed to vmap_range_noflush().
  *
  * KMSAN maps shadow and origin pages of @pages into contiguous ranges in
- * vmalloc metadata address range.
+ * vmalloc metadata address range. Returns 0 on success, callers must check
+ * for non-zero return value.
  */
-void kmsan_vmap_pages_range_noflush(unsigned long start, unsigned long end,
-                                   pgprot_t prot, struct page **pages,
-                                   unsigned int page_shift);
+int kmsan_vmap_pages_range_noflush(unsigned long start, unsigned long end,
+                                  pgprot_t prot, struct page **pages,
+                                  unsigned int page_shift);
 
 /**
  * kmsan_vunmap_kernel_range_noflush() - Notify KMSAN about a vunmap.
@@ -159,11 +160,12 @@ void kmsan_vunmap_range_noflush(unsigned long start, unsigned long end);
  * @page_shift:        page_shift argument passed to vmap_range_noflush().
  *
  * KMSAN creates new metadata pages for the physical pages mapped into the
- * virtual memory.
+ * virtual memory. Returns 0 on success, callers must check for non-zero return
+ * value.
  */
-void kmsan_ioremap_page_range(unsigned long addr, unsigned long end,
-                             phys_addr_t phys_addr, pgprot_t prot,
-                             unsigned int page_shift);
+int kmsan_ioremap_page_range(unsigned long addr, unsigned long end,
+                            phys_addr_t phys_addr, pgprot_t prot,
+                            unsigned int page_shift);
 
 /**
  * kmsan_iounmap_page_range() - Notify KMSAN about a iounmap_page_range() call.
@@ -281,12 +283,13 @@ static inline void kmsan_kfree_large(const void *ptr)
 {
 }
 
-static inline void kmsan_vmap_pages_range_noflush(unsigned long start,
-                                                 unsigned long end,
-                                                 pgprot_t prot,
-                                                 struct page **pages,
-                                                 unsigned int page_shift)
+static inline int kmsan_vmap_pages_range_noflush(unsigned long start,
+                                                unsigned long end,
+                                                pgprot_t prot,
+                                                struct page **pages,
+                                                unsigned int page_shift)
 {
+       return 0;
 }
 
 static inline void kmsan_vunmap_range_noflush(unsigned long start,
@@ -294,12 +297,12 @@ static inline void kmsan_vunmap_range_noflush(unsigned long start,
 {
 }
 
-static inline void kmsan_ioremap_page_range(unsigned long start,
-                                           unsigned long end,
-                                           phys_addr_t phys_addr,
-                                           pgprot_t prot,
-                                           unsigned int page_shift)
+static inline int kmsan_ioremap_page_range(unsigned long start,
+                                          unsigned long end,
+                                          phys_addr_t phys_addr, pgprot_t prot,
+                                          unsigned int page_shift)
 {
+       return 0;
 }
 
 static inline void kmsan_iounmap_page_range(unsigned long start,
index 8ada23756b0ec223b86eaa94945d070e3e7e9a16..a9adf75344bee024bf8fb02b13036046f9aabae5 100644 (file)
@@ -755,6 +755,7 @@ struct kvm {
        struct {
                spinlock_t        lock;
                struct list_head  items;
+               /* resampler_list update side is protected by resampler_lock. */
                struct list_head  resampler_list;
                struct mutex      resampler_lock;
        } irqfds;
@@ -1986,6 +1987,9 @@ int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args);
 #ifdef CONFIG_HAVE_KVM_IRQFD
 int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args);
 void kvm_irqfd_release(struct kvm *kvm);
+bool kvm_notify_irqfd_resampler(struct kvm *kvm,
+                               unsigned int irqchip,
+                               unsigned int pin);
 void kvm_irq_routing_update(struct kvm *);
 #else
 static inline int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args)
@@ -1994,6 +1998,13 @@ static inline int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args)
 }
 
 static inline void kvm_irqfd_release(struct kvm *kvm) {}
+
+static inline bool kvm_notify_irqfd_resampler(struct kvm *kvm,
+                                             unsigned int irqchip,
+                                             unsigned int pin)
+{
+       return false;
+}
 #endif
 
 #else
index dac047abdba7c5d571671da54f95a8c930307d67..8ad43692e3bbb459a75c3e33fd17fbd22b3d03e1 100644 (file)
@@ -31,7 +31,7 @@ struct kvm_kernel_irqfd_resampler {
        /*
         * Entry in list of kvm->irqfd.resampler_list.  Use for sharing
         * resamplers among irqfds on the same gsi.
-        * Accessed and modified under kvm->irqfds.resampler_lock
+        * RCU list modified under kvm->irqfds.resampler_lock
         */
        struct list_head link;
 };
index 9a6b55da8fd6442c895267128a02ee02682971ed..72831e35dca32d7412d2705fd38b00ac029d5927 100644 (file)
@@ -22,6 +22,7 @@
 #define        nlm4_fbig               cpu_to_be32(NLM_FBIG)
 #define        nlm4_failed             cpu_to_be32(NLM_FAILED)
 
+void   nlm4svc_set_file_lock_range(struct file_lock *fl, u64 off, u64 len);
 bool   nlm4svc_decode_void(struct svc_rqst *rqstp, struct xdr_stream *xdr);
 bool   nlm4svc_decode_testargs(struct svc_rqst *rqstp, struct xdr_stream *xdr);
 bool   nlm4svc_decode_lockargs(struct svc_rqst *rqstp, struct xdr_stream *xdr);
index 1023f349af716a1fb7b1cadaff3224ae0b4bbdf7..b32256e9e94434e9189688ef4b5dde29e6369b84 100644 (file)
@@ -134,7 +134,8 @@ struct held_lock {
        unsigned int read:2;        /* see lock_acquire() comment */
        unsigned int check:1;       /* see lock_acquire() comment */
        unsigned int hardirqs_off:1;
-       unsigned int references:12;                                     /* 32 bits */
+       unsigned int sync:1;
+       unsigned int references:11;                                     /* 32 bits */
        unsigned int pin_count;
 };
 
@@ -268,6 +269,10 @@ extern void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
 
 extern void lock_release(struct lockdep_map *lock, unsigned long ip);
 
+extern void lock_sync(struct lockdep_map *lock, unsigned int subclass,
+                     int read, int check, struct lockdep_map *nest_lock,
+                     unsigned long ip);
+
 /* lock_is_held_type() returns */
 #define LOCK_STATE_UNKNOWN     -1
 #define LOCK_STATE_NOT_HELD    0
@@ -554,6 +559,7 @@ do {                                                                        \
 #define lock_map_acquire_read(l)               lock_acquire_shared_recursive(l, 0, 0, NULL, _THIS_IP_)
 #define lock_map_acquire_tryread(l)            lock_acquire_shared_recursive(l, 0, 1, NULL, _THIS_IP_)
 #define lock_map_release(l)                    lock_release(l, _THIS_IP_)
+#define lock_map_sync(l)                       lock_sync(l, 0, 0, 1, NULL, _THIS_IP_)
 
 #ifdef CONFIG_PROVE_LOCKING
 # define might_lock(lock)                                              \
index 094b76dc716489c77d7fcfdc936f32f954725676..6bb55e61e8e87fddb499360b6fe826ac7304f478 100644 (file)
@@ -381,7 +381,7 @@ LSM_HOOK(int, 0, key_alloc, struct key *key, const struct cred *cred,
 LSM_HOOK(void, LSM_RET_VOID, key_free, struct key *key)
 LSM_HOOK(int, 0, key_permission, key_ref_t key_ref, const struct cred *cred,
         enum key_need_perm need_perm)
-LSM_HOOK(int, 0, key_getsecurity, struct key *key, char **_buffer)
+LSM_HOOK(int, 0, key_getsecurity, struct key *key, char **buffer)
 #endif /* CONFIG_KEYS */
 
 #ifdef CONFIG_AUDIT
index 6e156d2acffce446ffee035b620d83c657a827ee..ab2b2fafa4a459b4f03df8bedb611dc23c482f1e 100644 (file)
 #include <linux/init.h>
 #include <linux/rculist.h>
 
-/**
- * union security_list_options - Linux Security Module hook function list
- *
- * Security hooks for program execution operations.
- *
- * @bprm_creds_for_exec:
- *     If the setup in prepare_exec_creds did not setup @bprm->cred->security
- *     properly for executing @bprm->file, update the LSM's portion of
- *     @bprm->cred->security to be what commit_creds needs to install for the
- *     new program.  This hook may also optionally check permissions
- *     (e.g. for transitions between security domains).
- *     The hook must set @bprm->secureexec to 1 if AT_SECURE should be set to
- *     request libc enable secure mode.
- *     @bprm contains the linux_binprm structure.
- *     Return 0 if the hook is successful and permission is granted.
- * @bprm_creds_from_file:
- *     If @file is setpcap, suid, sgid or otherwise marked to change
- *     privilege upon exec, update @bprm->cred to reflect that change.
- *     This is called after finding the binary that will be executed.
- *     without an interpreter.  This ensures that the credentials will not
- *     be derived from a script that the binary will need to reopen, which
- *     when reopend may end up being a completely different file.  This
- *     hook may also optionally check permissions (e.g. for transitions
- *     between security domains).
- *     The hook must set @bprm->secureexec to 1 if AT_SECURE should be set to
- *     request libc enable secure mode.
- *     The hook must add to @bprm->per_clear any personality flags that
- *     should be cleared from current->personality.
- *     @bprm contains the linux_binprm structure.
- *     Return 0 if the hook is successful and permission is granted.
- * @bprm_check_security:
- *     This hook mediates the point when a search for a binary handler will
- *     begin.  It allows a check against the @bprm->cred->security value
- *     which was set in the preceding creds_for_exec call.  The argv list and
- *     envp list are reliably available in @bprm.  This hook may be called
- *     multiple times during a single execve.
- *     @bprm contains the linux_binprm structure.
- *     Return 0 if the hook is successful and permission is granted.
- * @bprm_committing_creds:
- *     Prepare to install the new security attributes of a process being
- *     transformed by an execve operation, based on the old credentials
- *     pointed to by @current->cred and the information set in @bprm->cred by
- *     the bprm_creds_for_exec hook.  @bprm points to the linux_binprm
- *     structure.  This hook is a good place to perform state changes on the
- *     process such as closing open file descriptors to which access will no
- *     longer be granted when the attributes are changed.  This is called
- *     immediately before commit_creds().
- * @bprm_committed_creds:
- *     Tidy up after the installation of the new security attributes of a
- *     process being transformed by an execve operation.  The new credentials
- *     have, by this point, been set to @current->cred.  @bprm points to the
- *     linux_binprm structure.  This hook is a good place to perform state
- *     changes on the process such as clearing out non-inheritable signal
- *     state.  This is called immediately after commit_creds().
- *
- * Security hooks for mount using fs_context.
- *     [See also Documentation/filesystems/mount_api.rst]
- *
- * @fs_context_dup:
- *     Allocate and attach a security structure to sc->security.  This pointer
- *     is initialised to NULL by the caller.
- *     @fc indicates the new filesystem context.
- *     @src_fc indicates the original filesystem context.
- *     Return 0 on success or a negative error code on failure.
- * @fs_context_parse_param:
- *     Userspace provided a parameter to configure a superblock.  The LSM may
- *     reject it with an error and may use it for itself, in which case it
- *     should return 0; otherwise it should return -ENOPARAM to pass it on to
- *     the filesystem.
- *     @fc indicates the filesystem context.
- *     @param The parameter.
- *
- * Security hooks for filesystem operations.
- *
- * @sb_alloc_security:
- *     Allocate and attach a security structure to the sb->s_security field.
- *     The s_security field is initialized to NULL when the structure is
- *     allocated.
- *     @sb contains the super_block structure to be modified.
- *     Return 0 if operation was successful.
- * @sb_delete:
- *     Release objects tied to a superblock (e.g. inodes).
- *     @sb contains the super_block structure being released.
- * @sb_free_security:
- *     Deallocate and clear the sb->s_security field.
- *     @sb contains the super_block structure to be modified.
- * @sb_free_mnt_opts:
- *     Free memory associated with @mnt_ops.
- * @sb_eat_lsm_opts:
- *     Eat (scan @orig options) and save them in @mnt_opts.
- *     Return 0 on success, negative values on failure.
- * @sb_statfs:
- *     Check permission before obtaining filesystem statistics for the @mnt
- *     mountpoint.
- *     @dentry is a handle on the superblock for the filesystem.
- *     Return 0 if permission is granted.
- * @sb_mount:
- *     Check permission before an object specified by @dev_name is mounted on
- *     the mount point named by @nd.  For an ordinary mount, @dev_name
- *     identifies a device if the file system type requires a device.  For a
- *     remount (@flags & MS_REMOUNT), @dev_name is irrelevant.  For a
- *     loopback/bind mount (@flags & MS_BIND), @dev_name identifies the
- *     pathname of the object being mounted.
- *     @dev_name contains the name for object being mounted.
- *     @path contains the path for mount point object.
- *     @type contains the filesystem type.
- *     @flags contains the mount flags.
- *     @data contains the filesystem-specific data.
- *     Return 0 if permission is granted.
- * @sb_mnt_opts_compat:
- *     Determine if the new mount options in @mnt_opts are allowed given
- *     the existing mounted filesystem at @sb.
- *     @sb superblock being compared.
- *     @mnt_opts new mount options.
- *     Return 0 if options are compatible.
- * @sb_remount:
- *     Extracts security system specific mount options and verifies no changes
- *     are being made to those options.
- *     @sb superblock being remounted.
- *     @data contains the filesystem-specific data.
- *     Return 0 if permission is granted.
- * @sb_kern_mount:
- *     Mount this @sb if allowed by permissions.
- *     Return 0 if permission is granted.
- * @sb_show_options:
- *     Show (print on @m) mount options for this @sb.
- *     Return 0 on success, negative values on failure.
- * @sb_umount:
- *     Check permission before the @mnt file system is unmounted.
- *     @mnt contains the mounted file system.
- *     @flags contains the unmount flags, e.g. MNT_FORCE.
- *     Return 0 if permission is granted.
- * @sb_pivotroot:
- *     Check permission before pivoting the root filesystem.
- *     @old_path contains the path for the new location of the
- *     current root (put_old).
- *     @new_path contains the path for the new root (new_root).
- *     Return 0 if permission is granted.
- * @sb_set_mnt_opts:
- *     Set the security relevant mount options used for a superblock
- *     @sb the superblock to set security mount options for.
- *     @opts binary data structure containing all lsm mount data.
- *     Return 0 on success, error on failure.
- * @sb_clone_mnt_opts:
- *     Copy all security options from a given superblock to another
- *     @oldsb old superblock which contain information to clone.
- *     @newsb new superblock which needs filled in.
- *     Return 0 on success, error on failure.
- * @move_mount:
- *     Check permission before a mount is moved.
- *     @from_path indicates the mount that is going to be moved.
- *     @to_path indicates the mountpoint that will be mounted upon.
- *     Return 0 if permission is granted.
- * @dentry_init_security:
- *     Compute a context for a dentry as the inode is not yet available
- *     since NFSv4 has no label backed by an EA anyway.
- *     @dentry dentry to use in calculating the context.
- *     @mode mode used to determine resource type.
- *     @name name of the last path component used to create file.
- *     @xattr_name pointer to place the pointer to security xattr name.
- *                 Caller does not have to free the resulting pointer. Its
- *                 a pointer to static string.
- *     @ctx pointer to place the pointer to the resulting context in.
- *     @ctxlen point to place the length of the resulting context.
- *     Return 0 on success, negative values on failure.
- * @dentry_create_files_as:
- *     Compute a context for a dentry as the inode is not yet available
- *     and set that context in passed in creds so that new files are
- *     created using that context. Context is calculated using the
- *     passed in creds and not the creds of the caller.
- *     @dentry dentry to use in calculating the context.
- *     @mode mode used to determine resource type.
- *     @name name of the last path component used to create file.
- *     @old creds which should be used for context calculation.
- *     @new creds to modify.
- *     Return 0 on success, error on failure.
- *
- *
- * Security hooks for inode operations.
- *
- * @inode_alloc_security:
- *     Allocate and attach a security structure to @inode->i_security.  The
- *     i_security field is initialized to NULL when the inode structure is
- *     allocated.
- *     @inode contains the inode structure.
- *     Return 0 if operation was successful.
- * @inode_free_security:
- *     @inode contains the inode structure.
- *     Deallocate the inode security structure and set @inode->i_security to
- *     NULL.
- * @inode_init_security:
- *     Obtain the security attribute name suffix and value to set on a newly
- *     created inode and set up the incore security field for the new inode.
- *     This hook is called by the fs code as part of the inode creation
- *     transaction and provides for atomic labeling of the inode, unlike
- *     the post_create/mkdir/... hooks called by the VFS.  The hook function
- *     is expected to allocate the name and value via kmalloc, with the caller
- *     being responsible for calling kfree after using them.
- *     If the security module does not use security attributes or does
- *     not wish to put a security attribute on this particular inode,
- *     then it should return -EOPNOTSUPP to skip this processing.
- *     @inode contains the inode structure of the newly created inode.
- *     @dir contains the inode structure of the parent directory.
- *     @qstr contains the last path component of the new object.
- *     @name will be set to the allocated name suffix (e.g. selinux).
- *     @value will be set to the allocated attribute value.
- *     @len will be set to the length of the value.
- *     Returns 0 if @name and @value have been successfully set,
- *     -EOPNOTSUPP if no security attribute is needed, or
- *     -ENOMEM on memory allocation failure.
- * @inode_init_security_anon:
- *      Set up the incore security field for the new anonymous inode
- *      and return whether the inode creation is permitted by the security
- *      module or not.
- *      @inode contains the inode structure.
- *      @name name of the anonymous inode class.
- *      @context_inode optional related inode.
- *     Returns 0 on success, -EACCES if the security module denies the
- *     creation of this inode, or another -errno upon other errors.
- * @inode_create:
- *     Check permission to create a regular file.
- *     @dir contains inode structure of the parent of the new file.
- *     @dentry contains the dentry structure for the file to be created.
- *     @mode contains the file mode of the file to be created.
- *     Return 0 if permission is granted.
- * @inode_link:
- *     Check permission before creating a new hard link to a file.
- *     @old_dentry contains the dentry structure for an existing
- *     link to the file.
- *     @dir contains the inode structure of the parent directory
- *     of the new link.
- *     @new_dentry contains the dentry structure for the new link.
- *     Return 0 if permission is granted.
- * @path_link:
- *     Check permission before creating a new hard link to a file.
- *     @old_dentry contains the dentry structure for an existing link
- *     to the file.
- *     @new_dir contains the path structure of the parent directory of
- *     the new link.
- *     @new_dentry contains the dentry structure for the new link.
- *     Return 0 if permission is granted.
- * @inode_unlink:
- *     Check the permission to remove a hard link to a file.
- *     @dir contains the inode structure of parent directory of the file.
- *     @dentry contains the dentry structure for file to be unlinked.
- *     Return 0 if permission is granted.
- * @path_unlink:
- *     Check the permission to remove a hard link to a file.
- *     @dir contains the path structure of parent directory of the file.
- *     @dentry contains the dentry structure for file to be unlinked.
- *     Return 0 if permission is granted.
- * @inode_symlink:
- *     Check the permission to create a symbolic link to a file.
- *     @dir contains the inode structure of parent directory of
- *     the symbolic link.
- *     @dentry contains the dentry structure of the symbolic link.
- *     @old_name contains the pathname of file.
- *     Return 0 if permission is granted.
- * @path_symlink:
- *     Check the permission to create a symbolic link to a file.
- *     @dir contains the path structure of parent directory of
- *     the symbolic link.
- *     @dentry contains the dentry structure of the symbolic link.
- *     @old_name contains the pathname of file.
- *     Return 0 if permission is granted.
- * @inode_mkdir:
- *     Check permissions to create a new directory in the existing directory
- *     associated with inode structure @dir.
- *     @dir contains the inode structure of parent of the directory
- *     to be created.
- *     @dentry contains the dentry structure of new directory.
- *     @mode contains the mode of new directory.
- *     Return 0 if permission is granted.
- * @path_mkdir:
- *     Check permissions to create a new directory in the existing directory
- *     associated with path structure @path.
- *     @dir contains the path structure of parent of the directory
- *     to be created.
- *     @dentry contains the dentry structure of new directory.
- *     @mode contains the mode of new directory.
- *     Return 0 if permission is granted.
- * @inode_rmdir:
- *     Check the permission to remove a directory.
- *     @dir contains the inode structure of parent of the directory
- *     to be removed.
- *     @dentry contains the dentry structure of directory to be removed.
- *     Return 0 if permission is granted.
- * @path_rmdir:
- *     Check the permission to remove a directory.
- *     @dir contains the path structure of parent of the directory to be
- *     removed.
- *     @dentry contains the dentry structure of directory to be removed.
- *     Return 0 if permission is granted.
- * @inode_mknod:
- *     Check permissions when creating a special file (or a socket or a fifo
- *     file created via the mknod system call).  Note that if mknod operation
- *     is being done for a regular file, then the create hook will be called
- *     and not this hook.
- *     @dir contains the inode structure of parent of the new file.
- *     @dentry contains the dentry structure of the new file.
- *     @mode contains the mode of the new file.
- *     @dev contains the device number.
- *     Return 0 if permission is granted.
- * @path_mknod:
- *     Check permissions when creating a file. Note that this hook is called
- *     even if mknod operation is being done for a regular file.
- *     @dir contains the path structure of parent of the new file.
- *     @dentry contains the dentry structure of the new file.
- *     @mode contains the mode of the new file.
- *     @dev contains the undecoded device number. Use new_decode_dev() to get
- *     the decoded device number.
- *     Return 0 if permission is granted.
- * @inode_rename:
- *     Check for permission to rename a file or directory.
- *     @old_dir contains the inode structure for parent of the old link.
- *     @old_dentry contains the dentry structure of the old link.
- *     @new_dir contains the inode structure for parent of the new link.
- *     @new_dentry contains the dentry structure of the new link.
- *     Return 0 if permission is granted.
- * @path_rename:
- *     Check for permission to rename a file or directory.
- *     @old_dir contains the path structure for parent of the old link.
- *     @old_dentry contains the dentry structure of the old link.
- *     @new_dir contains the path structure for parent of the new link.
- *     @new_dentry contains the dentry structure of the new link.
- *     @flags may contain rename options such as RENAME_EXCHANGE.
- *     Return 0 if permission is granted.
- * @path_chmod:
- *     Check for permission to change a mode of the file @path. The new
- *     mode is specified in @mode.
- *     @path contains the path structure of the file to change the mode.
- *     @mode contains the new DAC's permission, which is a bitmask of
- *     constants from <include/uapi/linux/stat.h>.
- *     Return 0 if permission is granted.
- * @path_chown:
- *     Check for permission to change owner/group of a file or directory.
- *     @path contains the path structure.
- *     @uid contains new owner's ID.
- *     @gid contains new group's ID.
- *     Return 0 if permission is granted.
- * @path_chroot:
- *     Check for permission to change root directory.
- *     @path contains the path structure.
- *     Return 0 if permission is granted.
- * @path_notify:
- *     Check permissions before setting a watch on events as defined by @mask,
- *     on an object at @path, whose type is defined by @obj_type.
- *     Return 0 if permission is granted.
- * @inode_readlink:
- *     Check the permission to read the symbolic link.
- *     @dentry contains the dentry structure for the file link.
- *     Return 0 if permission is granted.
- * @inode_follow_link:
- *     Check permission to follow a symbolic link when looking up a pathname.
- *     @dentry contains the dentry structure for the link.
- *     @inode contains the inode, which itself is not stable in RCU-walk.
- *     @rcu indicates whether we are in RCU-walk mode.
- *     Return 0 if permission is granted.
- * @inode_permission:
- *     Check permission before accessing an inode.  This hook is called by the
- *     existing Linux permission function, so a security module can use it to
- *     provide additional checking for existing Linux permission checks.
- *     Notice that this hook is called when a file is opened (as well as many
- *     other operations), whereas the file_security_ops permission hook is
- *     called when the actual read/write operations are performed.
- *     @inode contains the inode structure to check.
- *     @mask contains the permission mask.
- *     Return 0 if permission is granted.
- * @inode_setattr:
- *     Check permission before setting file attributes.  Note that the kernel
- *     call to notify_change is performed from several locations, whenever
- *     file attributes change (such as when a file is truncated, chown/chmod
- *     operations, transferring disk quotas, etc).
- *     @dentry contains the dentry structure for the file.
- *     @attr is the iattr structure containing the new file attributes.
- *     Return 0 if permission is granted.
- * @path_truncate:
- *     Check permission before truncating the file indicated by path.
- *     Note that truncation permissions may also be checked based on
- *     already opened files, using the @file_truncate hook.
- *     @path contains the path structure for the file.
- *     Return 0 if permission is granted.
- * @inode_getattr:
- *     Check permission before obtaining file attributes.
- *     @path contains the path structure for the file.
- *     Return 0 if permission is granted.
- * @inode_setxattr:
- *     Check permission before setting the extended attributes
- *     @value identified by @name for @dentry.
- *     Return 0 if permission is granted.
- * @inode_post_setxattr:
- *     Update inode security field after successful setxattr operation.
- *     @value identified by @name for @dentry.
- * @inode_getxattr:
- *     Check permission before obtaining the extended attributes
- *     identified by @name for @dentry.
- *     Return 0 if permission is granted.
- * @inode_listxattr:
- *     Check permission before obtaining the list of extended attribute
- *     names for @dentry.
- *     Return 0 if permission is granted.
- * @inode_removexattr:
- *     Check permission before removing the extended attribute
- *     identified by @name for @dentry.
- *     Return 0 if permission is granted.
- * @inode_set_acl:
- *     Check permission before setting posix acls
- *     The posix acls in @kacl are identified by @acl_name.
- *     Return 0 if permission is granted.
- * @inode_get_acl:
- *     Check permission before getting osix acls
- *     The posix acls are identified by @acl_name.
- *     Return 0 if permission is granted.
- * @inode_remove_acl:
- *     Check permission before removing posix acls
- *     The posix acls are identified by @acl_name.
- *     Return 0 if permission is granted.
- * @inode_getsecurity:
- *     Retrieve a copy of the extended attribute representation of the
- *     security label associated with @name for @inode via @buffer.  Note that
- *     @name is the remainder of the attribute name after the security prefix
- *     has been removed. @alloc is used to specify if the call should return a
- *     value via the buffer or just the value length.
- *     Return size of buffer on success.
- * @inode_setsecurity:
- *     Set the security label associated with @name for @inode from the
- *     extended attribute value @value.  @size indicates the size of the
- *     @value in bytes.  @flags may be XATTR_CREATE, XATTR_REPLACE, or 0.
- *     Note that @name is the remainder of the attribute name after the
- *     security. prefix has been removed.
- *     Return 0 on success.
- * @inode_listsecurity:
- *     Copy the extended attribute names for the security labels
- *     associated with @inode into @buffer.  The maximum size of @buffer
- *     is specified by @buffer_size.  @buffer may be NULL to request
- *     the size of the buffer required.
- *     Returns number of bytes used/required on success.
- * @inode_need_killpriv:
- *     Called when an inode has been changed.
- *     @dentry is the dentry being changed.
- *     Return <0 on error to abort the inode change operation.
- *     Return 0 if inode_killpriv does not need to be called.
- *     Return >0 if inode_killpriv does need to be called.
- * @inode_killpriv:
- *     The setuid bit is being removed.  Remove similar security labels.
- *     Called with the dentry->d_inode->i_mutex held.
- *     @idmap: idmap of the mount.
- *     @dentry is the dentry being changed.
- *     Return 0 on success.  If error is returned, then the operation
- *     causing setuid bit removal is failed.
- * @inode_getsecid:
- *     Get the secid associated with the node.
- *     @inode contains a pointer to the inode.
- *     @secid contains a pointer to the location where result will be saved.
- *     In case of failure, @secid will be set to zero.
- * @inode_copy_up:
- *     A file is about to be copied up from lower layer to upper layer of
- *     overlay filesystem. Security module can prepare a set of new creds
- *     and modify as need be and return new creds. Caller will switch to
- *     new creds temporarily to create new file and release newly allocated
- *     creds.
- *     @src indicates the union dentry of file that is being copied up.
- *     @new pointer to pointer to return newly allocated creds.
- *     Returns 0 on success or a negative error code on error.
- * @inode_copy_up_xattr:
- *     Filter the xattrs being copied up when a unioned file is copied
- *     up from a lower layer to the union/overlay layer.
- *     @name indicates the name of the xattr.
- *     Returns 0 to accept the xattr, 1 to discard the xattr, -EOPNOTSUPP if
- *     security module does not know about attribute or a negative error code
- *     to abort the copy up. Note that the caller is responsible for reading
- *     and writing the xattrs as this hook is merely a filter.
- * @d_instantiate:
- *     Fill in @inode security information for a @dentry if allowed.
- * @getprocattr:
- *     Read attribute @name for process @p and store it into @value if allowed.
- *     Return the length of @value on success, a negative value otherwise.
- * @setprocattr:
- *     Write (set) attribute @name to @value, size @size if allowed.
- *     Return written bytes on success, a negative value otherwise.
- *
- * Security hooks for kernfs node operations
- *
- * @kernfs_init_security:
- *     Initialize the security context of a newly created kernfs node based
- *     on its own and its parent's attributes.
- *     @kn_dir the parent kernfs node.
- *     @kn the new child kernfs node.
- *     Return 0 if permission is granted.
- *
- * Security hooks for file operations
- *
- * @file_permission:
- *     Check file permissions before accessing an open file.  This hook is
- *     called by various operations that read or write files.  A security
- *     module can use this hook to perform additional checking on these
- *     operations, e.g.  to revalidate permissions on use to support privilege
- *     bracketing or policy changes.  Notice that this hook is used when the
- *     actual read/write operations are performed, whereas the
- *     inode_security_ops hook is called when a file is opened (as well as
- *     many other operations).
- *     Caveat:  Although this hook can be used to revalidate permissions for
- *     various system call operations that read or write files, it does not
- *     address the revalidation of permissions for memory-mapped files.
- *     Security modules must handle this separately if they need such
- *     revalidation.
- *     @file contains the file structure being accessed.
- *     @mask contains the requested permissions.
- *     Return 0 if permission is granted.
- * @file_alloc_security:
- *     Allocate and attach a security structure to the file->f_security field.
- *     The security field is initialized to NULL when the structure is first
- *     created.
- *     @file contains the file structure to secure.
- *     Return 0 if the hook is successful and permission is granted.
- * @file_free_security:
- *     Deallocate and free any security structures stored in file->f_security.
- *     @file contains the file structure being modified.
- * @file_ioctl:
- *     @file contains the file structure.
- *     @cmd contains the operation to perform.
- *     @arg contains the operational arguments.
- *     Check permission for an ioctl operation on @file.  Note that @arg
- *     sometimes represents a user space pointer; in other cases, it may be a
- *     simple integer value.  When @arg represents a user space pointer, it
- *     should never be used by the security module.
- *     Return 0 if permission is granted.
- * @mmap_addr:
- *     Check permissions for a mmap operation at @addr.
- *     @addr contains virtual address that will be used for the operation.
- *     Return 0 if permission is granted.
- * @mmap_file:
- *     Check permissions for a mmap operation.  The @file may be NULL, e.g.
- *     if mapping anonymous memory.
- *     @file contains the file structure for file to map (may be NULL).
- *     @reqprot contains the protection requested by the application.
- *     @prot contains the protection that will be applied by the kernel.
- *     @flags contains the operational flags.
- *     Return 0 if permission is granted.
- * @file_mprotect:
- *     Check permissions before changing memory access permissions.
- *     @vma contains the memory region to modify.
- *     @reqprot contains the protection requested by the application.
- *     @prot contains the protection that will be applied by the kernel.
- *     Return 0 if permission is granted.
- * @file_lock:
- *     Check permission before performing file locking operations.
- *     Note the hook mediates both flock and fcntl style locks.
- *     @file contains the file structure.
- *     @cmd contains the posix-translated lock operation to perform
- *     (e.g. F_RDLCK, F_WRLCK).
- *     Return 0 if permission is granted.
- * @file_fcntl:
- *     Check permission before allowing the file operation specified by @cmd
- *     from being performed on the file @file.  Note that @arg sometimes
- *     represents a user space pointer; in other cases, it may be a simple
- *     integer value.  When @arg represents a user space pointer, it should
- *     never be used by the security module.
- *     @file contains the file structure.
- *     @cmd contains the operation to be performed.
- *     @arg contains the operational arguments.
- *     Return 0 if permission is granted.
- * @file_set_fowner:
- *     Save owner security information (typically from current->security) in
- *     file->f_security for later use by the send_sigiotask hook.
- *     @file contains the file structure to update.
- *     Return 0 on success.
- * @file_send_sigiotask:
- *     Check permission for the file owner @fown to send SIGIO or SIGURG to the
- *     process @tsk.  Note that this hook is sometimes called from interrupt.
- *     Note that the fown_struct, @fown, is never outside the context of a
- *     struct file, so the file structure (and associated security information)
- *     can always be obtained: container_of(fown, struct file, f_owner)
- *     @tsk contains the structure of task receiving signal.
- *     @fown contains the file owner information.
- *     @sig is the signal that will be sent.  When 0, kernel sends SIGIO.
- *     Return 0 if permission is granted.
- * @file_receive:
- *     This hook allows security modules to control the ability of a process
- *     to receive an open file descriptor via socket IPC.
- *     @file contains the file structure being received.
- *     Return 0 if permission is granted.
- * @file_truncate:
- *     Check permission before truncating a file, i.e. using ftruncate.
- *     Note that truncation permission may also be checked based on the path,
- *     using the @path_truncate hook.
- *     @file contains the file structure for the file.
- *     Return 0 if permission is granted.
- * @file_open:
- *     Save open-time permission checking state for later use upon
- *     file_permission, and recheck access if anything has changed
- *     since inode_permission.
- *     Return 0 if permission is granted.
- *
- * Security hooks for task operations.
- *
- * @task_alloc:
- *     @task task being allocated.
- *     @clone_flags contains the flags indicating what should be shared.
- *     Handle allocation of task-related resources.
- *     Returns a zero on success, negative values on failure.
- * @task_free:
- *     @task task about to be freed.
- *     Handle release of task-related resources. (Note that this can be called
- *     from interrupt context.)
- * @cred_alloc_blank:
- *     @cred points to the credentials.
- *     @gfp indicates the atomicity of any memory allocations.
- *     Only allocate sufficient memory and attach to @cred such that
- *     cred_transfer() will not get ENOMEM.
- *     Return 0 on success, negative values on failure.
- * @cred_free:
- *     @cred points to the credentials.
- *     Deallocate and clear the cred->security field in a set of credentials.
- * @cred_prepare:
- *     @new points to the new credentials.
- *     @old points to the original credentials.
- *     @gfp indicates the atomicity of any memory allocations.
- *     Prepare a new set of credentials by copying the data from the old set.
- *     Return 0 on success, negative values on failure.
- * @cred_transfer:
- *     @new points to the new credentials.
- *     @old points to the original credentials.
- *     Transfer data from original creds to new creds
- * @cred_getsecid:
- *     Retrieve the security identifier of the cred structure @c
- *     @c contains the credentials, secid will be placed into @secid.
- *     In case of failure, @secid will be set to zero.
- * @kernel_act_as:
- *     Set the credentials for a kernel service to act as (subjective context).
- *     @new points to the credentials to be modified.
- *     @secid specifies the security ID to be set.
- *     The current task must be the one that nominated @secid.
- *     Return 0 if successful.
- * @kernel_create_files_as:
- *     Set the file creation context in a set of credentials to be the same as
- *     the objective context of the specified inode.
- *     @new points to the credentials to be modified.
- *     @inode points to the inode to use as a reference.
- *     The current task must be the one that nominated @inode.
- *     Return 0 if successful.
- * @kernel_module_request:
- *     Ability to trigger the kernel to automatically upcall to userspace for
- *     userspace to load a kernel module with the given name.
- *     @kmod_name name of the module requested by the kernel.
- *     Return 0 if successful.
- * @kernel_load_data:
- *     Load data provided by userspace.
- *     @id kernel load data identifier.
- *     @contents if a subsequent @kernel_post_load_data will be called.
- *     Return 0 if permission is granted.
- * @kernel_post_load_data:
- *     Load data provided by a non-file source (usually userspace buffer).
- *     @buf pointer to buffer containing the data contents.
- *     @size length of the data contents.
- *     @id kernel load data identifier.
- *     @description a text description of what was loaded, @id-specific.
- *     Return 0 if permission is granted.
- *     This must be paired with a prior @kernel_load_data call that had
- *     @contents set to true.
- * @kernel_read_file:
- *     Read a file specified by userspace.
- *     @file contains the file structure pointing to the file being read
- *     by the kernel.
- *     @id kernel read file identifier.
- *     @contents if a subsequent @kernel_post_read_file will be called.
- *     Return 0 if permission is granted.
- * @kernel_post_read_file:
- *     Read a file specified by userspace.
- *     @file contains the file structure pointing to the file being read
- *     by the kernel.
- *     @buf pointer to buffer containing the file contents.
- *     @size length of the file contents.
- *     @id kernel read file identifier.
- *     This must be paired with a prior @kernel_read_file call that had
- *     @contents set to true.
- *     Return 0 if permission is granted.
- * @task_fix_setuid:
- *     Update the module's state after setting one or more of the user
- *     identity attributes of the current process.  The @flags parameter
- *     indicates which of the set*uid system calls invoked this hook.  If
- *     @new is the set of credentials that will be installed.  Modifications
- *     should be made to this rather than to @current->cred.
- *     @old is the set of credentials that are being replaced.
- *     @flags contains one of the LSM_SETID_* values.
- *     Return 0 on success.
- * @task_fix_setgid:
- *     Update the module's state after setting one or more of the group
- *     identity attributes of the current process.  The @flags parameter
- *     indicates which of the set*gid system calls invoked this hook.
- *     @new is the set of credentials that will be installed.  Modifications
- *     should be made to this rather than to @current->cred.
- *     @old is the set of credentials that are being replaced.
- *     @flags contains one of the LSM_SETID_* values.
- *     Return 0 on success.
- * @task_fix_setgroups:
- *     Update the module's state after setting the supplementary group
- *     identity attributes of the current process.
- *     @new is the set of credentials that will be installed.  Modifications
- *     should be made to this rather than to @current->cred.
- *     @old is the set of credentials that are being replaced.
- *     Return 0 on success.
- * @task_setpgid:
- *     Check permission before setting the process group identifier of the
- *     process @p to @pgid.
- *     @p contains the task_struct for process being modified.
- *     @pgid contains the new pgid.
- *     Return 0 if permission is granted.
- * @task_getpgid:
- *     Check permission before getting the process group identifier of the
- *     process @p.
- *     @p contains the task_struct for the process.
- *     Return 0 if permission is granted.
- * @task_getsid:
- *     Check permission before getting the session identifier of the process
- *     @p.
- *     @p contains the task_struct for the process.
- *     Return 0 if permission is granted.
- * @current_getsecid_subj:
- *     Retrieve the subjective security identifier of the current task and
- *     return it in @secid.
- *     In case of failure, @secid will be set to zero.
- * @task_getsecid_obj:
- *     Retrieve the objective security identifier of the task_struct in @p
- *     and return it in @secid.
- *     In case of failure, @secid will be set to zero.
- *
- * @task_setnice:
- *     Check permission before setting the nice value of @p to @nice.
- *     @p contains the task_struct of process.
- *     @nice contains the new nice value.
- *     Return 0 if permission is granted.
- * @task_setioprio:
- *     Check permission before setting the ioprio value of @p to @ioprio.
- *     @p contains the task_struct of process.
- *     @ioprio contains the new ioprio value.
- *     Return 0 if permission is granted.
- * @task_getioprio:
- *     Check permission before getting the ioprio value of @p.
- *     @p contains the task_struct of process.
- *     Return 0 if permission is granted.
- * @task_prlimit:
- *     Check permission before getting and/or setting the resource limits of
- *     another task.
- *     @cred points to the cred structure for the current task.
- *     @tcred points to the cred structure for the target task.
- *     @flags contains the LSM_PRLIMIT_* flag bits indicating whether the
- *     resource limits are being read, modified, or both.
- *     Return 0 if permission is granted.
- * @task_setrlimit:
- *     Check permission before setting the resource limits of process @p
- *     for @resource to @new_rlim.  The old resource limit values can
- *     be examined by dereferencing (p->signal->rlim + resource).
- *     @p points to the task_struct for the target task's group leader.
- *     @resource contains the resource whose limit is being set.
- *     @new_rlim contains the new limits for @resource.
- *     Return 0 if permission is granted.
- * @task_setscheduler:
- *     Check permission before setting scheduling policy and/or parameters of
- *     process @p.
- *     @p contains the task_struct for process.
- *     Return 0 if permission is granted.
- * @task_getscheduler:
- *     Check permission before obtaining scheduling information for process
- *     @p.
- *     @p contains the task_struct for process.
- *     Return 0 if permission is granted.
- * @task_movememory:
- *     Check permission before moving memory owned by process @p.
- *     @p contains the task_struct for process.
- *     Return 0 if permission is granted.
- * @task_kill:
- *     Check permission before sending signal @sig to @p.  @info can be NULL,
- *     the constant 1, or a pointer to a kernel_siginfo structure.  If @info is 1 or
- *     SI_FROMKERNEL(info) is true, then the signal should be viewed as coming
- *     from the kernel and should typically be permitted.
- *     SIGIO signals are handled separately by the send_sigiotask hook in
- *     file_security_ops.
- *     @p contains the task_struct for process.
- *     @info contains the signal information.
- *     @sig contains the signal value.
- *     @cred contains the cred of the process where the signal originated, or
- *     NULL if the current task is the originator.
- *     Return 0 if permission is granted.
- * @task_prctl:
- *     Check permission before performing a process control operation on the
- *     current process.
- *     @option contains the operation.
- *     @arg2 contains a argument.
- *     @arg3 contains a argument.
- *     @arg4 contains a argument.
- *     @arg5 contains a argument.
- *     Return -ENOSYS if no-one wanted to handle this op, any other value to
- *     cause prctl() to return immediately with that value.
- * @task_to_inode:
- *     Set the security attributes for an inode based on an associated task's
- *     security attributes, e.g. for /proc/pid inodes.
- *     @p contains the task_struct for the task.
- *     @inode contains the inode structure for the inode.
- * @userns_create:
- *     Check permission prior to creating a new user namespace.
- *     @cred points to prepared creds.
- *     Return 0 if successful, otherwise < 0 error code.
- *
- * Security hooks for Netlink messaging.
- *
- * @netlink_send:
- *     Save security information for a netlink message so that permission
- *     checking can be performed when the message is processed.  The security
- *     information can be saved using the eff_cap field of the
- *     netlink_skb_parms structure.  Also may be used to provide fine
- *     grained control over message transmission.
- *     @sk associated sock of task sending the message.
- *     @skb contains the sk_buff structure for the netlink message.
- *     Return 0 if the information was successfully saved and message
- *     is allowed to be transmitted.
- *
- * Security hooks for Unix domain networking.
- *
- * @unix_stream_connect:
- *     Check permissions before establishing a Unix domain stream connection
- *     between @sock and @other.
- *     @sock contains the sock structure.
- *     @other contains the peer sock structure.
- *     @newsk contains the new sock structure.
- *     Return 0 if permission is granted.
- * @unix_may_send:
- *     Check permissions before connecting or sending datagrams from @sock to
- *     @other.
- *     @sock contains the socket structure.
- *     @other contains the peer socket structure.
- *     Return 0 if permission is granted.
- *
- * The @unix_stream_connect and @unix_may_send hooks were necessary because
- * Linux provides an alternative to the conventional file name space for Unix
- * domain sockets.  Whereas binding and connecting to sockets in the file name
- * space is mediated by the typical file permissions (and caught by the mknod
- * and permission hooks in inode_security_ops), binding and connecting to
- * sockets in the abstract name space is completely unmediated.  Sufficient
- * control of Unix domain sockets in the abstract name space isn't possible
- * using only the socket layer hooks, since we need to know the actual target
- * socket, which is not looked up until we are inside the af_unix code.
- *
- * Security hooks for socket operations.
- *
- * @socket_create:
- *     Check permissions prior to creating a new socket.
- *     @family contains the requested protocol family.
- *     @type contains the requested communications type.
- *     @protocol contains the requested protocol.
- *     @kern set to 1 if a kernel socket.
- *     Return 0 if permission is granted.
- * @socket_post_create:
- *     This hook allows a module to update or allocate a per-socket security
- *     structure. Note that the security field was not added directly to the
- *     socket structure, but rather, the socket security information is stored
- *     in the associated inode.  Typically, the inode alloc_security hook will
- *     allocate and attach security information to
- *     SOCK_INODE(sock)->i_security.  This hook may be used to update the
- *     SOCK_INODE(sock)->i_security field with additional information that
- *     wasn't available when the inode was allocated.
- *     @sock contains the newly created socket structure.
- *     @family contains the requested protocol family.
- *     @type contains the requested communications type.
- *     @protocol contains the requested protocol.
- *     @kern set to 1 if a kernel socket.
- *     Return 0 if permission is granted.
- * @socket_socketpair:
- *     Check permissions before creating a fresh pair of sockets.
- *     @socka contains the first socket structure.
- *     @sockb contains the second socket structure.
- *     Return 0 if permission is granted and the connection was established.
- * @socket_bind:
- *     Check permission before socket protocol layer bind operation is
- *     performed and the socket @sock is bound to the address specified in the
- *     @address parameter.
- *     @sock contains the socket structure.
- *     @address contains the address to bind to.
- *     @addrlen contains the length of address.
- *     Return 0 if permission is granted.
- * @socket_connect:
- *     Check permission before socket protocol layer connect operation
- *     attempts to connect socket @sock to a remote address, @address.
- *     @sock contains the socket structure.
- *     @address contains the address of remote endpoint.
- *     @addrlen contains the length of address.
- *     Return 0 if permission is granted.
- * @socket_listen:
- *     Check permission before socket protocol layer listen operation.
- *     @sock contains the socket structure.
- *     @backlog contains the maximum length for the pending connection queue.
- *     Return 0 if permission is granted.
- * @socket_accept:
- *     Check permission before accepting a new connection.  Note that the new
- *     socket, @newsock, has been created and some information copied to it,
- *     but the accept operation has not actually been performed.
- *     @sock contains the listening socket structure.
- *     @newsock contains the newly created server socket for connection.
- *     Return 0 if permission is granted.
- * @socket_sendmsg:
- *     Check permission before transmitting a message to another socket.
- *     @sock contains the socket structure.
- *     @msg contains the message to be transmitted.
- *     @size contains the size of message.
- *     Return 0 if permission is granted.
- * @socket_recvmsg:
- *     Check permission before receiving a message from a socket.
- *     @sock contains the socket structure.
- *     @msg contains the message structure.
- *     @size contains the size of message structure.
- *     @flags contains the operational flags.
- *     Return 0 if permission is granted.
- * @socket_getsockname:
- *     Check permission before the local address (name) of the socket object
- *     @sock is retrieved.
- *     @sock contains the socket structure.
- *     Return 0 if permission is granted.
- * @socket_getpeername:
- *     Check permission before the remote address (name) of a socket object
- *     @sock is retrieved.
- *     @sock contains the socket structure.
- *     Return 0 if permission is granted.
- * @socket_getsockopt:
- *     Check permissions before retrieving the options associated with socket
- *     @sock.
- *     @sock contains the socket structure.
- *     @level contains the protocol level to retrieve option from.
- *     @optname contains the name of option to retrieve.
- *     Return 0 if permission is granted.
- * @socket_setsockopt:
- *     Check permissions before setting the options associated with socket
- *     @sock.
- *     @sock contains the socket structure.
- *     @level contains the protocol level to set options for.
- *     @optname contains the name of the option to set.
- *     Return 0 if permission is granted.
- * @socket_shutdown:
- *     Checks permission before all or part of a connection on the socket
- *     @sock is shut down.
- *     @sock contains the socket structure.
- *     @how contains the flag indicating how future sends and receives
- *     are handled.
- *     Return 0 if permission is granted.
- * @socket_sock_rcv_skb:
- *     Check permissions on incoming network packets.  This hook is distinct
- *     from Netfilter's IP input hooks since it is the first time that the
- *     incoming sk_buff @skb has been associated with a particular socket, @sk.
- *     Must not sleep inside this hook because some callers hold spinlocks.
- *     @sk contains the sock (not socket) associated with the incoming sk_buff.
- *     @skb contains the incoming network data.
- *     Return 0 if permission is granted.
- * @socket_getpeersec_stream:
- *     This hook allows the security module to provide peer socket security
- *     state for unix or connected tcp sockets to userspace via getsockopt
- *     SO_GETPEERSEC.  For tcp sockets this can be meaningful if the
- *     socket is associated with an ipsec SA.
- *     @sock is the local socket.
- *     @optval memory where the security state is to be copied.
- *     @optlen memory where the module should copy the actual length
- *     of the security state.
- *     @len as input is the maximum length to copy to userspace provided
- *     by the caller.
- *     Return 0 if all is well, otherwise, typical getsockopt return
- *     values.
- * @socket_getpeersec_dgram:
- *     This hook allows the security module to provide peer socket security
- *     state for udp sockets on a per-packet basis to userspace via
- *     getsockopt SO_GETPEERSEC. The application must first have indicated
- *     the IP_PASSSEC option via getsockopt. It can then retrieve the
- *     security state returned by this hook for a packet via the SCM_SECURITY
- *     ancillary message type.
- *     @sock contains the peer socket. May be NULL.
- *     @skb is the sk_buff for the packet being queried. May be NULL.
- *     @secid pointer to store the secid of the packet.
- *     Return 0 on success, error on failure.
- * @sk_alloc_security:
- *     Allocate and attach a security structure to the sk->sk_security field,
- *     which is used to copy security attributes between local stream sockets.
- *     Return 0 on success, error on failure.
- * @sk_free_security:
- *     Deallocate security structure.
- * @sk_clone_security:
- *     Clone/copy security structure.
- * @sk_getsecid:
- *     Retrieve the LSM-specific secid for the sock to enable caching
- *     of network authorizations.
- * @sock_graft:
- *     Sets the socket's isec sid to the sock's sid.
- * @inet_conn_request:
- *     Sets the openreq's sid to socket's sid with MLS portion taken
- *     from peer sid.
- *     Return 0 if permission is granted.
- * @inet_csk_clone:
- *     Sets the new child socket's sid to the openreq sid.
- * @inet_conn_established:
- *     Sets the connection's peersid to the secmark on skb.
- * @secmark_relabel_packet:
- *     Check if the process should be allowed to relabel packets to
- *     the given secid.
- *     Return 0 if permission is granted.
- * @secmark_refcount_inc:
- *     Tells the LSM to increment the number of secmark labeling rules loaded.
- * @secmark_refcount_dec:
- *     Tells the LSM to decrement the number of secmark labeling rules loaded.
- * @req_classify_flow:
- *     Sets the flow's sid to the openreq sid.
- * @tun_dev_alloc_security:
- *     This hook allows a module to allocate a security structure for a TUN
- *     device.
- *     @security pointer to a security structure pointer.
- *     Returns a zero on success, negative values on failure.
- * @tun_dev_free_security:
- *     This hook allows a module to free the security structure for a TUN
- *     device.
- *     @security pointer to the TUN device's security structure.
- * @tun_dev_create:
- *     Check permissions prior to creating a new TUN device.
- *     Return 0 if permission is granted.
- * @tun_dev_attach_queue:
- *     Check permissions prior to attaching to a TUN device queue.
- *     @security pointer to the TUN device's security structure.
- *     Return 0 if permission is granted.
- * @tun_dev_attach:
- *     This hook can be used by the module to update any security state
- *     associated with the TUN device's sock structure.
- *     @sk contains the existing sock structure.
- *     @security pointer to the TUN device's security structure.
- *     Return 0 if permission is granted.
- * @tun_dev_open:
- *     This hook can be used by the module to update any security state
- *     associated with the TUN device's security structure.
- *     @security pointer to the TUN devices's security structure.
- *     Return 0 if permission is granted.
- *
- * Security hooks for SCTP
- *
- * @sctp_assoc_request:
- *     Passes the @asoc and @chunk->skb of the association INIT packet to
- *     the security module.
- *     @asoc pointer to sctp association structure.
- *     @skb pointer to skbuff of association packet.
- *     Return 0 on success, error on failure.
- * @sctp_bind_connect:
- *     Validiate permissions required for each address associated with sock
- *     @sk. Depending on @optname, the addresses will be treated as either
- *     for a connect or bind service. The @addrlen is calculated on each
- *     ipv4 and ipv6 address using sizeof(struct sockaddr_in) or
- *     sizeof(struct sockaddr_in6).
- *     @sk pointer to sock structure.
- *     @optname name of the option to validate.
- *     @address list containing one or more ipv4/ipv6 addresses.
- *     @addrlen total length of address(s).
- *     Return 0 on success, error on failure.
- * @sctp_sk_clone:
- *     Called whenever a new socket is created by accept(2) (i.e. a TCP
- *     style socket) or when a socket is 'peeled off' e.g userspace
- *     calls sctp_peeloff(3).
- *     @asoc pointer to current sctp association structure.
- *     @sk pointer to current sock structure.
- *     @newsk pointer to new sock structure.
- * @sctp_assoc_established:
- *     Passes the @asoc and @chunk->skb of the association COOKIE_ACK packet
- *     to the security module.
- *     @asoc pointer to sctp association structure.
- *     @skb pointer to skbuff of association packet.
- *     Return 0 if permission is granted.
- *
- * Security hooks for Infiniband
- *
- * @ib_pkey_access:
- *     Check permission to access a pkey when modifing a QP.
- *     @subnet_prefix the subnet prefix of the port being used.
- *     @pkey the pkey to be accessed.
- *     @sec pointer to a security structure.
- *     Return 0 if permission is granted.
- * @ib_endport_manage_subnet:
- *     Check permissions to send and receive SMPs on a end port.
- *     @dev_name the IB device name (i.e. mlx4_0).
- *     @port_num the port number.
- *     @sec pointer to a security structure.
- *     Return 0 if permission is granted.
- * @ib_alloc_security:
- *     Allocate a security structure for Infiniband objects.
- *     @sec pointer to a security structure pointer.
- *     Returns 0 on success, non-zero on failure.
- * @ib_free_security:
- *     Deallocate an Infiniband security structure.
- *     @sec contains the security structure to be freed.
- *
- * Security hooks for XFRM operations.
- *
- * @xfrm_policy_alloc_security:
- *     @ctxp is a pointer to the xfrm_sec_ctx being added to Security Policy
- *     Database used by the XFRM system.
- *     @sec_ctx contains the security context information being provided by
- *     the user-level policy update program (e.g., setkey).
- *     @gfp is to specify the context for the allocation.
- *     Allocate a security structure to the xp->security field; the security
- *     field is initialized to NULL when the xfrm_policy is allocated.
- *     Return 0 if operation was successful (memory to allocate, legal
- *     context).
- * @xfrm_policy_clone_security:
- *     @old_ctx contains an existing xfrm_sec_ctx.
- *     @new_ctxp contains a new xfrm_sec_ctx being cloned from old.
- *     Allocate a security structure in new_ctxp that contains the
- *     information from the old_ctx structure.
- *     Return 0 if operation was successful (memory to allocate).
- * @xfrm_policy_free_security:
- *     @ctx contains the xfrm_sec_ctx.
- *     Deallocate xp->security.
- * @xfrm_policy_delete_security:
- *     @ctx contains the xfrm_sec_ctx.
- *     Authorize deletion of xp->security.
- *     Return 0 if permission is granted.
- * @xfrm_state_alloc:
- *     @x contains the xfrm_state being added to the Security Association
- *     Database by the XFRM system.
- *     @sec_ctx contains the security context information being provided by
- *     the user-level SA generation program (e.g., setkey or racoon).
- *     Allocate a security structure to the x->security field; the security
- *     field is initialized to NULL when the xfrm_state is allocated. Set the
- *     context to correspond to sec_ctx. Return 0 if operation was successful
- *     (memory to allocate, legal context).
- * @xfrm_state_alloc_acquire:
- *     @x contains the xfrm_state being added to the Security Association
- *     Database by the XFRM system.
- *     @polsec contains the policy's security context.
- *     @secid contains the secid from which to take the mls portion of the
- *     context.
- *     Allocate a security structure to the x->security field; the security
- *     field is initialized to NULL when the xfrm_state is allocated. Set the
- *     context to correspond to secid. Return 0 if operation was successful
- *     (memory to allocate, legal context).
- * @xfrm_state_free_security:
- *     @x contains the xfrm_state.
- *     Deallocate x->security.
- * @xfrm_state_delete_security:
- *     @x contains the xfrm_state.
- *     Authorize deletion of x->security.
- *     Return 0 if permission is granted.
- * @xfrm_policy_lookup:
- *     @ctx contains the xfrm_sec_ctx for which the access control is being
- *     checked.
- *     @fl_secid contains the flow security label that is used to authorize
- *     access to the policy xp.
- *     @dir contains the direction of the flow (input or output).
- *     Check permission when a flow selects a xfrm_policy for processing
- *     XFRMs on a packet.  The hook is called when selecting either a
- *     per-socket policy or a generic xfrm policy.
- *     Return 0 if permission is granted, -ESRCH otherwise, or -errno
- *     on other errors.
- * @xfrm_state_pol_flow_match:
- *     @x contains the state to match.
- *     @xp contains the policy to check for a match.
- *     @flic contains the flowi_common struct to check for a match.
- *     Return 1 if there is a match.
- * @xfrm_decode_session:
- *     @skb points to skb to decode.
- *     @secid points to the flow key secid to set.
- *     @ckall says if all xfrms used should be checked for same secid.
- *     Return 0 if ckall is zero or all xfrms used have the same secid.
- *
- * Security hooks affecting all Key Management operations
- *
- * @key_alloc:
- *     Permit allocation of a key and assign security data. Note that key does
- *     not have a serial number assigned at this point.
- *     @key points to the key.
- *     @flags is the allocation flags.
- *     Return 0 if permission is granted, -ve error otherwise.
- * @key_free:
- *     Notification of destruction; free security data.
- *     @key points to the key.
- *     No return value.
- * @key_permission:
- *     See whether a specific operational right is granted to a process on a
- *     key.
- *     @key_ref refers to the key (key pointer + possession attribute bit).
- *     @cred points to the credentials to provide the context against which to
- *     evaluate the security data on the key.
- *     @perm describes the combination of permissions required of this key.
- *     Return 0 if permission is granted, -ve error otherwise.
- * @key_getsecurity:
- *     Get a textual representation of the security context attached to a key
- *     for the purposes of honouring KEYCTL_GETSECURITY.  This function
- *     allocates the storage for the NUL-terminated string and the caller
- *     should free it.
- *     @key points to the key to be queried.
- *     @_buffer points to a pointer that should be set to point to the
- *     resulting string (if no label or an error occurs).
- *     Return the length of the string (including terminating NUL) or -ve if
- *     an error.
- *     May also return 0 (and a NULL buffer pointer) if there is no label.
- *
- * Security hooks affecting all System V IPC operations.
- *
- * @ipc_permission:
- *     Check permissions for access to IPC
- *     @ipcp contains the kernel IPC permission structure.
- *     @flag contains the desired (requested) permission set.
- *     Return 0 if permission is granted.
- * @ipc_getsecid:
- *     Get the secid associated with the ipc object.
- *     @ipcp contains the kernel IPC permission structure.
- *     @secid contains a pointer to the location where result will be saved.
- *     In case of failure, @secid will be set to zero.
- *
- * Security hooks for individual messages held in System V IPC message queues
- *
- * @msg_msg_alloc_security:
- *     Allocate and attach a security structure to the msg->security field.
- *     The security field is initialized to NULL when the structure is first
- *     created.
- *     @msg contains the message structure to be modified.
- *     Return 0 if operation was successful and permission is granted.
- * @msg_msg_free_security:
- *     Deallocate the security structure for this message.
- *     @msg contains the message structure to be modified.
- *
- * Security hooks for System V IPC Message Queues
- *
- * @msg_queue_alloc_security:
- *     Allocate and attach a security structure to the
- *     @perm->security field. The security field is initialized to
- *     NULL when the structure is first created.
- *     @perm contains the IPC permissions of the message queue.
- *     Return 0 if operation was successful and permission is granted.
- * @msg_queue_free_security:
- *     Deallocate security field @perm->security for the message queue.
- *     @perm contains the IPC permissions of the message queue.
- * @msg_queue_associate:
- *     Check permission when a message queue is requested through the
- *     msgget system call. This hook is only called when returning the
- *     message queue identifier for an existing message queue, not when a
- *     new message queue is created.
- *     @perm contains the IPC permissions of the message queue.
- *     @msqflg contains the operation control flags.
- *     Return 0 if permission is granted.
- * @msg_queue_msgctl:
- *     Check permission when a message control operation specified by @cmd
- *     is to be performed on the message queue with permissions @perm.
- *     The @perm may be NULL, e.g. for IPC_INFO or MSG_INFO.
- *     @perm contains the IPC permissions of the msg queue. May be NULL.
- *     @cmd contains the operation to be performed.
- *     Return 0 if permission is granted.
- * @msg_queue_msgsnd:
- *     Check permission before a message, @msg, is enqueued on the message
- *     queue with permissions @perm.
- *     @perm contains the IPC permissions of the message queue.
- *     @msg contains the message to be enqueued.
- *     @msqflg contains operational flags.
- *     Return 0 if permission is granted.
- * @msg_queue_msgrcv:
- *     Check permission before a message, @msg, is removed from the message
- *     queue. The @target task structure contains a pointer to the
- *     process that will be receiving the message (not equal to the current
- *     process when inline receives are being performed).
- *     @perm contains the IPC permissions of the message queue.
- *     @msg contains the message destination.
- *     @target contains the task structure for recipient process.
- *     @type contains the type of message requested.
- *     @mode contains the operational flags.
- *     Return 0 if permission is granted.
- *
- * Security hooks for System V Shared Memory Segments
- *
- * @shm_alloc_security:
- *     Allocate and attach a security structure to the @perm->security
- *     field. The security field is initialized to NULL when the structure is
- *     first created.
- *     @perm contains the IPC permissions of the shared memory structure.
- *     Return 0 if operation was successful and permission is granted.
- * @shm_free_security:
- *     Deallocate the security structure @perm->security for the memory segment.
- *     @perm contains the IPC permissions of the shared memory structure.
- * @shm_associate:
- *     Check permission when a shared memory region is requested through the
- *     shmget system call. This hook is only called when returning the shared
- *     memory region identifier for an existing region, not when a new shared
- *     memory region is created.
- *     @perm contains the IPC permissions of the shared memory structure.
- *     @shmflg contains the operation control flags.
- *     Return 0 if permission is granted.
- * @shm_shmctl:
- *     Check permission when a shared memory control operation specified by
- *     @cmd is to be performed on the shared memory region with permissions @perm.
- *     The @perm may be NULL, e.g. for IPC_INFO or SHM_INFO.
- *     @perm contains the IPC permissions of the shared memory structure.
- *     @cmd contains the operation to be performed.
- *     Return 0 if permission is granted.
- * @shm_shmat:
- *     Check permissions prior to allowing the shmat system call to attach the
- *     shared memory segment with permissions @perm to the data segment of the
- *     calling process. The attaching address is specified by @shmaddr.
- *     @perm contains the IPC permissions of the shared memory structure.
- *     @shmaddr contains the address to attach memory region to.
- *     @shmflg contains the operational flags.
- *     Return 0 if permission is granted.
- *
- * Security hooks for System V Semaphores
- *
- * @sem_alloc_security:
- *     Allocate and attach a security structure to the @perm->security
- *     field. The security field is initialized to NULL when the structure is
- *     first created.
- *     @perm contains the IPC permissions of the semaphore.
- *     Return 0 if operation was successful and permission is granted.
- * @sem_free_security:
- *     Deallocate security structure @perm->security for the semaphore.
- *     @perm contains the IPC permissions of the semaphore.
- * @sem_associate:
- *     Check permission when a semaphore is requested through the semget
- *     system call. This hook is only called when returning the semaphore
- *     identifier for an existing semaphore, not when a new one must be
- *     created.
- *     @perm contains the IPC permissions of the semaphore.
- *     @semflg contains the operation control flags.
- *     Return 0 if permission is granted.
- * @sem_semctl:
- *     Check permission when a semaphore operation specified by @cmd is to be
- *     performed on the semaphore. The @perm may be NULL, e.g. for
- *     IPC_INFO or SEM_INFO.
- *     @perm contains the IPC permissions of the semaphore. May be NULL.
- *     @cmd contains the operation to be performed.
- *     Return 0 if permission is granted.
- * @sem_semop:
- *     Check permissions before performing operations on members of the
- *     semaphore set. If the @alter flag is nonzero, the semaphore set
- *     may be modified.
- *     @perm contains the IPC permissions of the semaphore.
- *     @sops contains the operations to perform.
- *     @nsops contains the number of operations to perform.
- *     @alter contains the flag indicating whether changes are to be made.
- *     Return 0 if permission is granted.
- *
- * @binder_set_context_mgr:
- *     Check whether @mgr is allowed to be the binder context manager.
- *     @mgr contains the struct cred for the current binder process.
- *     Return 0 if permission is granted.
- * @binder_transaction:
- *     Check whether @from is allowed to invoke a binder transaction call
- *     to @to.
- *     @from contains the struct cred for the sending process.
- *     @to contains the struct cred for the receiving process.
- *     Return 0 if permission is granted.
- * @binder_transfer_binder:
- *     Check whether @from is allowed to transfer a binder reference to @to.
- *     @from contains the struct cred for the sending process.
- *     @to contains the struct cred for the receiving process.
- *     Return 0 if permission is granted.
- * @binder_transfer_file:
- *     Check whether @from is allowed to transfer @file to @to.
- *     @from contains the struct cred for the sending process.
- *     @file contains the struct file being transferred.
- *     @to contains the struct cred for the receiving process.
- *     Return 0 if permission is granted.
- *
- * @ptrace_access_check:
- *     Check permission before allowing the current process to trace the
- *     @child process.
- *     Security modules may also want to perform a process tracing check
- *     during an execve in the set_security or apply_creds hooks of
- *     tracing check during an execve in the bprm_set_creds hook of
- *     binprm_security_ops if the process is being traced and its security
- *     attributes would be changed by the execve.
- *     @child contains the task_struct structure for the target process.
- *     @mode contains the PTRACE_MODE flags indicating the form of access.
- *     Return 0 if permission is granted.
- * @ptrace_traceme:
- *     Check that the @parent process has sufficient permission to trace the
- *     current process before allowing the current process to present itself
- *     to the @parent process for tracing.
- *     @parent contains the task_struct structure for debugger process.
- *     Return 0 if permission is granted.
- * @capget:
- *     Get the @effective, @inheritable, and @permitted capability sets for
- *     the @target process.  The hook may also perform permission checking to
- *     determine if the current process is allowed to see the capability sets
- *     of the @target process.
- *     @target contains the task_struct structure for target process.
- *     @effective contains the effective capability set.
- *     @inheritable contains the inheritable capability set.
- *     @permitted contains the permitted capability set.
- *     Return 0 if the capability sets were successfully obtained.
- * @capset:
- *     Set the @effective, @inheritable, and @permitted capability sets for
- *     the current process.
- *     @new contains the new credentials structure for target process.
- *     @old contains the current credentials structure for target process.
- *     @effective contains the effective capability set.
- *     @inheritable contains the inheritable capability set.
- *     @permitted contains the permitted capability set.
- *     Return 0 and update @new if permission is granted.
- * @capable:
- *     Check whether the @tsk process has the @cap capability in the indicated
- *     credentials.
- *     @cred contains the credentials to use.
- *     @ns contains the user namespace we want the capability in.
- *     @cap contains the capability <include/linux/capability.h>.
- *     @opts contains options for the capable check <include/linux/security.h>.
- *     Return 0 if the capability is granted for @tsk.
- * @quotactl:
- *     Check whether the quotactl syscall is allowed for this @sb.
- *     Return 0 if permission is granted.
- * @quota_on:
- *     Check whether QUOTAON is allowed for this @dentry.
- *     Return 0 if permission is granted.
- * @syslog:
- *     Check permission before accessing the kernel message ring or changing
- *     logging to the console.
- *     See the syslog(2) manual page for an explanation of the @type values.
- *     @type contains the SYSLOG_ACTION_* constant from
- *     <include/linux/syslog.h>.
- *     Return 0 if permission is granted.
- * @settime:
- *     Check permission to change the system time.
- *     struct timespec64 is defined in <include/linux/time64.h> and timezone
- *     is defined in <include/linux/time.h>
- *     @ts contains new time.
- *     @tz contains new timezone.
- *     Return 0 if permission is granted.
- * @vm_enough_memory:
- *     Check permissions for allocating a new virtual mapping.
- *     @mm contains the mm struct it is being added to.
- *     @pages contains the number of pages.
- *     Return 0 if permission is granted by the LSM infrastructure to the
- *     caller. If all LSMs return a positive value, __vm_enough_memory() will
- *     be called with cap_sys_admin set. If at least one LSM returns 0 or
- *     negative, __vm_enough_memory() will be called with cap_sys_admin
- *     cleared.
- *
- * @ismaclabel:
- *     Check if the extended attribute specified by @name
- *     represents a MAC label. Returns 1 if name is a MAC
- *     attribute otherwise returns 0.
- *     @name full extended attribute name to check against
- *     LSM as a MAC label.
- *
- * @secid_to_secctx:
- *     Convert secid to security context.  If secdata is NULL the length of
- *     the result will be returned in seclen, but no secdata will be returned.
- *     This does mean that the length could change between calls to check the
- *     length and the next call which actually allocates and returns the
- *     secdata.
- *     @secid contains the security ID.
- *     @secdata contains the pointer that stores the converted security
- *     context.
- *     @seclen pointer which contains the length of the data.
- *     Return 0 on success, error on failure.
- * @secctx_to_secid:
- *     Convert security context to secid.
- *     @secid contains the pointer to the generated security ID.
- *     @secdata contains the security context.
- *     Return 0 on success, error on failure.
- *
- * @release_secctx:
- *     Release the security context.
- *     @secdata contains the security context.
- *     @seclen contains the length of the security context.
- *
- * Security hooks for Audit
- *
- * @audit_rule_init:
- *     Allocate and initialize an LSM audit rule structure.
- *     @field contains the required Audit action.
- *     Fields flags are defined in <include/linux/audit.h>
- *     @op contains the operator the rule uses.
- *     @rulestr contains the context where the rule will be applied to.
- *     @lsmrule contains a pointer to receive the result.
- *     Return 0 if @lsmrule has been successfully set,
- *     -EINVAL in case of an invalid rule.
- *
- * @audit_rule_known:
- *     Specifies whether given @krule contains any fields related to
- *     current LSM.
- *     @krule contains the audit rule of interest.
- *     Return 1 in case of relation found, 0 otherwise.
- *
- * @audit_rule_match:
- *     Determine if given @secid matches a rule previously approved
- *     by @audit_rule_known.
- *     @secid contains the security id in question.
- *     @field contains the field which relates to current LSM.
- *     @op contains the operator that will be used for matching.
- *     @lrule points to the audit rule that will be checked against.
- *     Return 1 if secid matches the rule, 0 if it does not, -ERRNO on failure.
- *
- * @audit_rule_free:
- *     Deallocate the LSM audit rule structure previously allocated by
- *     audit_rule_init.
- *     @lsmrule contains the allocated rule.
- *
- * @inode_invalidate_secctx:
- *     Notify the security module that it must revalidate the security context
- *     of an inode.
- *
- * @inode_notifysecctx:
- *     Notify the security module of what the security context of an inode
- *     should be.  Initializes the incore security context managed by the
- *     security module for this inode.  Example usage:  NFS client invokes
- *     this hook to initialize the security context in its incore inode to the
- *     value provided by the server for the file when the server returned the
- *     file's attributes to the client.
- *     Must be called with inode->i_mutex locked.
- *     @inode we wish to set the security context of.
- *     @ctx contains the string which we wish to set in the inode.
- *     @ctxlen contains the length of @ctx.
- *     Return 0 on success, error on failure.
- *
- * @inode_setsecctx:
- *     Change the security context of an inode.  Updates the
- *     incore security context managed by the security module and invokes the
- *     fs code as needed (via __vfs_setxattr_noperm) to update any backing
- *     xattrs that represent the context.  Example usage:  NFS server invokes
- *     this hook to change the security context in its incore inode and on the
- *     backing filesystem to a value provided by the client on a SETATTR
- *     operation.
- *     Must be called with inode->i_mutex locked.
- *     @dentry contains the inode we wish to set the security context of.
- *     @ctx contains the string which we wish to set in the inode.
- *     @ctxlen contains the length of @ctx.
- *     Return 0 on success, error on failure.
- *
- * @inode_getsecctx:
- *     On success, returns 0 and fills out @ctx and @ctxlen with the security
- *     context for the given @inode.
- *     @inode we wish to get the security context of.
- *     @ctx is a pointer in which to place the allocated security context.
- *     @ctxlen points to the place to put the length of @ctx.
- *     Return 0 on success, error on failure.
- *
- * Security hooks for the general notification queue:
- *
- * @post_notification:
- *     Check to see if a watch notification can be posted to a particular
- *     queue.
- *     @w_cred: The credentials of the whoever set the watch.
- *     @cred: The event-triggerer's credentials.
- *     @n: The notification being posted.
- *     Return 0 if permission is granted.
- *
- * @watch_key:
- *     Check to see if a process is allowed to watch for event notifications
- *     from a key or keyring.
- *     @key: The key to watch.
- *     Return 0 if permission is granted.
- *
- * Security hooks for using the eBPF maps and programs functionalities through
- * eBPF syscalls.
- *
- * @bpf:
- *     Do a initial check for all bpf syscalls after the attribute is copied
- *     into the kernel. The actual security module can implement their own
- *     rules to check the specific cmd they need.
- *     Return 0 if permission is granted.
- *
- * @bpf_map:
- *     Do a check when the kernel generate and return a file descriptor for
- *     eBPF maps.
- *     @map: bpf map that we want to access.
- *     @mask: the access flags.
- *     Return 0 if permission is granted.
- *
- * @bpf_prog:
- *     Do a check when the kernel generate and return a file descriptor for
- *     eBPF programs.
- *     @prog: bpf prog that userspace want to use.
- *     Return 0 if permission is granted.
- *
- * @bpf_map_alloc_security:
- *     Initialize the security field inside bpf map.
- *     Return 0 on success, error on failure.
- *
- * @bpf_map_free_security:
- *     Clean up the security information stored inside bpf map.
- *
- * @bpf_prog_alloc_security:
- *     Initialize the security field inside bpf program.
- *     Return 0 on success, error on failure.
- *
- * @bpf_prog_free_security:
- *     Clean up the security information stored inside bpf prog.
- *
- * @locked_down:
- *     Determine whether a kernel feature that potentially enables arbitrary
- *     code execution in kernel space should be permitted.
- *     @what: kernel feature being accessed.
- *     Return 0 if permission is granted.
- *
- * Security hooks for perf events
- *
- * @perf_event_open:
- *     Check whether the @type of perf_event_open syscall is allowed.
- *     Return 0 if permission is granted.
- * @perf_event_alloc:
- *     Allocate and save perf_event security info.
- *     Return 0 on success, error on failure.
- * @perf_event_free:
- *     Release (free) perf_event security info.
- * @perf_event_read:
- *     Read perf_event security info if allowed.
- *     Return 0 if permission is granted.
- * @perf_event_write:
- *     Write perf_event security info if allowed.
- *     Return 0 if permission is granted.
- *
- * Security hooks for io_uring
- *
- * @uring_override_creds:
- *     Check if the current task, executing an io_uring operation, is allowed
- *     to override it's credentials with @new.
- *     @new: the new creds to use.
- *     Return 0 if permission is granted.
- *
- * @uring_sqpoll:
- *     Check whether the current task is allowed to spawn a io_uring polling
- *     thread (IORING_SETUP_SQPOLL).
- *     Return 0 if permission is granted.
- *
- * @uring_cmd:
- *     Check whether the file_operations uring_cmd is allowed to run.
- *     Return 0 if permission is granted.
- *
- */
 union security_list_options {
        #define LSM_HOOK(RET, DEFAULT, NAME, ...) RET (*NAME)(__VA_ARGS__);
        #include "lsm_hook_defs.h"
@@ -1716,6 +92,7 @@ extern void security_add_hooks(struct security_hook_list *hooks, int count,
 enum lsm_order {
        LSM_ORDER_FIRST = -1,   /* This is only for capabilities. */
        LSM_ORDER_MUTABLE = 0,
+       LSM_ORDER_LAST = 1,     /* This is only for integrity. */
 };
 
 struct lsm_info {
@@ -1740,36 +117,6 @@ extern struct lsm_info __start_early_lsm_info[], __end_early_lsm_info[];
                __used __section(".early_lsm_info.init")                \
                __aligned(sizeof(unsigned long))
 
-#ifdef CONFIG_SECURITY_SELINUX_DISABLE
-/*
- * Assuring the safety of deleting a security module is up to
- * the security module involved. This may entail ordering the
- * module's hook list in a particular way, refusing to disable
- * the module once a policy is loaded or any number of other
- * actions better imagined than described.
- *
- * The name of the configuration option reflects the only module
- * that currently uses the mechanism. Any developer who thinks
- * disabling their module is a good idea needs to be at least as
- * careful as the SELinux team.
- */
-static inline void security_delete_hooks(struct security_hook_list *hooks,
-                                               int count)
-{
-       int i;
-
-       for (i = 0; i < count; i++)
-               hlist_del_rcu(&hooks[i].list);
-}
-#endif /* CONFIG_SECURITY_SELINUX_DISABLE */
-
-/* Currently required to handle SELinux runtime hook disable. */
-#ifdef CONFIG_SECURITY_WRITABLE_HOOKS
-#define __lsm_ro_after_init
-#else
-#define __lsm_ro_after_init    __ro_after_init
-#endif /* CONFIG_SECURITY_WRITABLE_HOOKS */
-
 extern int lsm_inode_alloc(struct inode *inode);
 
 #endif /* ! __LINUX_LSM_HOOKS_H */
index 71b06ebad4024c429bf6b33cf3637e9e0c7fc61e..1db19a9d26e324a86ac0a5b9e4dfeea409ac1dfd 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/types.h>
 #include <rdma/ib_verbs.h>
 #include <linux/mlx5/mlx5_ifc.h>
+#include <linux/bitfield.h>
 
 #if defined(__LITTLE_ENDIAN)
 #define MLX5_SET_HOST_ENDIANNESS       0
@@ -980,14 +981,23 @@ enum {
 };
 
 enum {
-       CQE_RSS_HTYPE_IP        = 0x3 << 2,
+       CQE_RSS_HTYPE_IP        = GENMASK(3, 2),
        /* cqe->rss_hash_type[3:2] - IP destination selected for hash
         * (00 = none,  01 = IPv4, 10 = IPv6, 11 = Reserved)
         */
-       CQE_RSS_HTYPE_L4        = 0x3 << 6,
+       CQE_RSS_IP_NONE         = 0x0,
+       CQE_RSS_IPV4            = 0x1,
+       CQE_RSS_IPV6            = 0x2,
+       CQE_RSS_RESERVED        = 0x3,
+
+       CQE_RSS_HTYPE_L4        = GENMASK(7, 6),
        /* cqe->rss_hash_type[7:6] - L4 destination selected for hash
         * (00 = none, 01 = TCP. 10 = UDP, 11 = IPSEC.SPI
         */
+       CQE_RSS_L4_NONE         = 0x0,
+       CQE_RSS_L4_TCP          = 0x1,
+       CQE_RSS_L4_UDP          = 0x2,
+       CQE_RSS_L4_IPSEC        = 0x3,
 };
 
 enum {
index f33389b42209e472c7dd6245c96c9f6c4203b503..7e225e41d55b8b61a93b6ac6ad223e0d2b218b0c 100644 (file)
@@ -1211,11 +1211,6 @@ static inline bool mlx5_core_is_vf(const struct mlx5_core_dev *dev)
        return dev->coredev_type == MLX5_COREDEV_VF;
 }
 
-static inline bool mlx5_core_is_management_pf(const struct mlx5_core_dev *dev)
-{
-       return MLX5_CAP_GEN(dev, num_ports) == 1 && !MLX5_CAP_GEN(dev, native_port_num);
-}
-
 static inline bool mlx5_core_is_ecpf(const struct mlx5_core_dev *dev)
 {
        return dev->caps.embedded_cpu;
index 0722859c36478d92f06455c6841144a7bfe5d207..a57e6ae78e6569ef67058faa9e353175628de44c 100644 (file)
@@ -774,7 +774,8 @@ struct mm_struct {
        unsigned long cpu_bitmap[];
 };
 
-#define MM_MT_FLAGS    (MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN)
+#define MM_MT_FLAGS    (MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN | \
+                        MT_FLAGS_USE_RCU)
 extern struct mm_struct init_mm;
 
 /* Pointer magic because the dynamic array size confuses some compilers. */
index 6a14b7b117668ca2c8b1f914ecb49fb4311784ab..c35f04f636f15a2a034baedd0b60b0857b96f0e0 100644 (file)
@@ -297,9 +297,11 @@ struct hh_cache {
  * relationship HH alignment <= LL alignment.
  */
 #define LL_RESERVED_SPACE(dev) \
-       ((((dev)->hard_header_len+(dev)->needed_headroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
+       ((((dev)->hard_header_len + READ_ONCE((dev)->needed_headroom)) \
+         & ~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
 #define LL_RESERVED_SPACE_EXTRA(dev,extra) \
-       ((((dev)->hard_header_len+(dev)->needed_headroom+(extra))&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
+       ((((dev)->hard_header_len + READ_ONCE((dev)->needed_headroom) + (extra)) \
+         & ~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
 
 struct header_ops {
        int     (*create) (struct sk_buff *skb, struct net_device *dev,
@@ -1622,7 +1624,8 @@ struct net_device_ops {
 
 struct xdp_metadata_ops {
        int     (*xmo_rx_timestamp)(const struct xdp_md *ctx, u64 *timestamp);
-       int     (*xmo_rx_hash)(const struct xdp_md *ctx, u32 *hash);
+       int     (*xmo_rx_hash)(const struct xdp_md *ctx, u32 *hash,
+                              enum xdp_rss_hash_type *rss_type);
 };
 
 /**
index aef88c2d117366bfc0cab51264312a445cf585e3..2aba75145144c9f1a8ea0156c72460ffe9810044 100644 (file)
@@ -73,6 +73,9 @@ struct raw_notifier_head {
 
 struct srcu_notifier_head {
        struct mutex mutex;
+#ifdef CONFIG_TREE_SRCU
+       struct srcu_usage srcuu;
+#endif
        struct srcu_struct srcu;
        struct notifier_block __rcu *head;
 };
@@ -107,7 +110,7 @@ extern void srcu_init_notifier_head(struct srcu_notifier_head *nh);
        {                                                       \
                .mutex = __MUTEX_INITIALIZER(name.mutex),       \
                .head = NULL,                                   \
-               .srcu = __SRCU_STRUCT_INIT(name.srcu, pcpu),    \
+               .srcu = __SRCU_STRUCT_INIT(name.srcu, name.srcuu, pcpu), \
        }
 
 #define ATOMIC_NOTIFIER_HEAD(name)                             \
index 75470159a194d97fa91e208999217767dd3c9761..57ebe1267f7fbe96166e9c40621192330d6fcbc4 100644 (file)
@@ -115,8 +115,9 @@ struct nvme_tcp_icresp_pdu {
 struct nvme_tcp_term_pdu {
        struct nvme_tcp_hdr     hdr;
        __le16                  fes;
-       __le32                  fei;
-       __u8                    rsvd[8];
+       __le16                  feil;
+       __le16                  feiu;
+       __u8                    rsvd[10];
 };
 
 /**
index 4fad4aa245fb0621ee3adbec1793981ae54f1ea7..779507ac750b803db2c8a185d461e6114969b5b3 100644 (file)
@@ -812,6 +812,7 @@ enum nvme_opcode {
                nvme_opcode_name(nvme_cmd_compare),             \
                nvme_opcode_name(nvme_cmd_write_zeroes),        \
                nvme_opcode_name(nvme_cmd_dsm),                 \
+               nvme_opcode_name(nvme_cmd_verify),              \
                nvme_opcode_name(nvme_cmd_resv_register),       \
                nvme_opcode_name(nvme_cmd_resv_report),         \
                nvme_opcode_name(nvme_cmd_resv_acquire),        \
@@ -1144,10 +1145,14 @@ enum nvme_admin_opcode {
                nvme_admin_opcode_name(nvme_admin_ns_mgmt),             \
                nvme_admin_opcode_name(nvme_admin_activate_fw),         \
                nvme_admin_opcode_name(nvme_admin_download_fw),         \
+               nvme_admin_opcode_name(nvme_admin_dev_self_test),       \
                nvme_admin_opcode_name(nvme_admin_ns_attach),           \
                nvme_admin_opcode_name(nvme_admin_keep_alive),          \
                nvme_admin_opcode_name(nvme_admin_directive_send),      \
                nvme_admin_opcode_name(nvme_admin_directive_recv),      \
+               nvme_admin_opcode_name(nvme_admin_virtual_mgmt),        \
+               nvme_admin_opcode_name(nvme_admin_nvme_mi_send),        \
+               nvme_admin_opcode_name(nvme_admin_nvme_mi_recv),        \
                nvme_admin_opcode_name(nvme_admin_dbbuf),               \
                nvme_admin_opcode_name(nvme_admin_format_nvm),          \
                nvme_admin_opcode_name(nvme_admin_security_send),       \
index da633d34ab866bd92a693459a2a23b69de6940fb..8a52ef2e6fa6bb495313edad7026df3f1dedcb84 100644 (file)
 
 #if IS_ENABLED(CONFIG_OF_MDIO)
 bool of_mdiobus_child_is_phy(struct device_node *child);
-int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np);
-int devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio,
-                            struct device_node *np);
+int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np,
+                         struct module *owner);
+
+static inline int of_mdiobus_register(struct mii_bus *mdio,
+                                     struct device_node *np)
+{
+       return __of_mdiobus_register(mdio, np, THIS_MODULE);
+}
+
+int __devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio,
+                              struct device_node *np, struct module *owner);
+
+static inline int devm_of_mdiobus_register(struct device *dev,
+                                          struct mii_bus *mdio,
+                                          struct device_node *np)
+{
+       return __devm_of_mdiobus_register(dev, mdio, np, THIS_MODULE);
+}
+
 struct mdio_device *of_mdio_find_device(struct device_node *np);
 struct phy_device *of_phy_find_device(struct device_node *phy_np);
 struct phy_device *
index 0acb8e1fb7afdc92b8d17c1216294d02f6fa19d9..853184a46411f46d9ac2337c19c58825b34184e1 100644 (file)
@@ -1066,12 +1066,6 @@ static inline void folio_cancel_dirty(struct folio *folio)
 bool folio_clear_dirty_for_io(struct folio *folio);
 bool clear_page_dirty_for_io(struct page *page);
 void folio_invalidate(struct folio *folio, size_t offset, size_t length);
-int __must_check folio_write_one(struct folio *folio);
-static inline int __must_check write_one_page(struct page *page)
-{
-       return folio_write_one(page_folio(page));
-}
-
 int __set_page_dirty_nobuffers(struct page *page);
 bool noop_dirty_folio(struct address_space *mapping, struct folio *folio);
 
index ed9b4df792b8858be22221ec77f24abafce9cc75..43765eaf2342c6996db747a14d9dcef89d6993e8 100644 (file)
@@ -34,6 +34,10 @@ struct pci_doe_mb;
  * @work: Used internally by the mailbox
  * @doe_mb: Used internally by the mailbox
  *
+ * Payloads are treated as opaque byte streams which are transmitted verbatim,
+ * without byte-swapping.  If payloads contain little-endian register values,
+ * the caller is responsible for conversion with cpu_to_le32() / le32_to_cpu().
+ *
  * The payload sizes and rv are specified in bytes with the following
  * restrictions concerning the protocol.
  *
@@ -45,9 +49,9 @@ struct pci_doe_mb;
  */
 struct pci_doe_task {
        struct pci_doe_protocol prot;
-       u32 *request_pl;
+       __le32 *request_pl;
        size_t request_pl_sz;
-       u32 *response_pl;
+       __le32 *response_pl;
        size_t response_pl_sz;
        int rv;
        void (*complete)(struct pci_doe_task *task);
index fafd8020c6d7f1f7a02b82199874d11b6b0870dd..a5dda515fcd1d4f7fe2cd4b6e384797c0083027d 100644 (file)
@@ -1438,6 +1438,7 @@ void pci_bus_add_resource(struct pci_bus *bus, struct resource *res,
                          unsigned int flags);
 struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n);
 void pci_bus_remove_resources(struct pci_bus *bus);
+void pci_bus_remove_resource(struct pci_bus *bus, struct resource *res);
 int devm_request_pci_bus_resources(struct device *dev,
                                   struct list_head *resources);
 
@@ -1623,6 +1624,8 @@ pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs,
                                              flags, NULL);
 }
 
+static inline bool pci_msix_can_alloc_dyn(struct pci_dev *dev)
+{ return false; }
 static inline struct msi_map pci_msix_alloc_irq_at(struct pci_dev *dev, unsigned int index,
                                                   const struct irq_affinity_desc *affdesc)
 {
index 521a733e21a920cc04a401788048143ecb64f236..75b73c83bc9d0d1074c9e0f67ad39776b12c5eb1 100644 (file)
@@ -45,7 +45,6 @@ void percpu_counter_set(struct percpu_counter *fbc, s64 amount);
 void percpu_counter_add_batch(struct percpu_counter *fbc, s64 amount,
                              s32 batch);
 s64 __percpu_counter_sum(struct percpu_counter *fbc);
-s64 percpu_counter_sum_all(struct percpu_counter *fbc);
 int __percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch);
 void percpu_counter_sync(struct percpu_counter *fbc);
 
@@ -196,11 +195,6 @@ static inline s64 percpu_counter_sum(struct percpu_counter *fbc)
        return percpu_counter_read(fbc);
 }
 
-static inline s64 percpu_counter_sum_all(struct percpu_counter *fbc)
-{
-       return percpu_counter_read(fbc);
-}
-
 static inline bool percpu_counter_initialized(struct percpu_counter *fbc)
 {
        return true;
index 36bf0bbc8efa0cd33c73d96e08d5758bd8089b32..db7c0bd67559dc3e0af53a89df938b302eb2f97b 100644 (file)
@@ -1547,7 +1547,7 @@ int fwnode_get_phy_id(struct fwnode_handle *fwnode, u32 *phy_id);
 struct mdio_device *fwnode_mdio_find_device(struct fwnode_handle *fwnode);
 struct phy_device *fwnode_phy_find_device(struct fwnode_handle *phy_fwnode);
 struct phy_device *device_phy_find_device(struct device *dev);
-struct fwnode_handle *fwnode_get_phy_node(struct fwnode_handle *fwnode);
+struct fwnode_handle *fwnode_get_phy_node(const struct fwnode_handle *fwnode);
 struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45);
 int phy_device_register(struct phy_device *phy);
 void phy_device_free(struct phy_device *phydev);
index c492c26202b5b89a535273ba16b5a86f25581997..637698ed5cb6cb00ce313adaee94f99ee6341429 100644 (file)
@@ -574,6 +574,7 @@ struct phylink *phylink_create(struct phylink_config *, struct fwnode_handle *,
                               phy_interface_t iface,
                               const struct phylink_mac_ops *mac_ops);
 void phylink_destroy(struct phylink *);
+bool phylink_expects_phy(struct phylink *pl);
 
 int phylink_connect_phy(struct phylink *, struct phy_device *);
 int phylink_of_phy_connect(struct phylink *, struct device_node *, u32 flags);
index 343abf22092e6b54a973dc6d457e06e317e6c9ed..b75de288a8c29ac47f10137078e094fe2a63fbe9 100644 (file)
@@ -80,6 +80,7 @@ extern struct pid *pidfd_pid(const struct file *file);
 struct pid *pidfd_get_pid(unsigned int fd, unsigned int *flags);
 struct task_struct *pidfd_get_task(int pidfd, unsigned int *flags);
 int pidfd_create(struct pid *pid, unsigned int flags);
+int pidfd_prepare(struct pid *pid, unsigned int flags, struct file **ret);
 
 static inline struct pid *get_pid(struct pid *pid)
 {
index 21cc29b8a9e8d18000702316773d04a11d6d9ed9..0e65b3d634d9afd330ccfff3263142ffa1457aec 100644 (file)
@@ -106,6 +106,8 @@ struct posix_acl *vfs_get_acl(struct mnt_idmap *idmap,
                              struct dentry *dentry, const char *acl_name);
 int vfs_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
                   const char *acl_name);
+int posix_acl_listxattr(struct inode *inode, char **buffer,
+                       ssize_t *remaining_size);
 #else
 static inline int posix_acl_chmod(struct mnt_idmap *idmap,
                                  struct dentry *dentry, umode_t mode)
@@ -153,6 +155,11 @@ static inline int vfs_remove_acl(struct mnt_idmap *idmap,
 {
        return -EOPNOTSUPP;
 }
+static inline int posix_acl_listxattr(struct inode *inode, char **buffer,
+                                     ssize_t *remaining_size)
+{
+       return 0;
+}
 #endif /* CONFIG_FS_POSIX_ACL */
 
 struct posix_acl *get_inode_acl(struct inode *inode, int type);
index 54cd7a14330dd5689a725f98fd0b787336b2a464..e86f3b731da25ced707633d252ccb62b14216598 100644 (file)
@@ -68,7 +68,8 @@ static inline int posix_acl_type(const char *name)
        return -1;
 }
 
-extern const struct xattr_handler posix_acl_access_xattr_handler;
-extern const struct xattr_handler posix_acl_default_xattr_handler;
+/* These are legacy handlers. Don't use them for new code. */
+extern const struct xattr_handler nop_posix_acl_access;
+extern const struct xattr_handler nop_posix_acl_default;
 
 #endif /* _POSIX_ACL_XATTR_H */
index 75807ecef880f1b12f690da75717e61600f50318..49539bc416cecb7b45bfd4f11df817cd11f2e791 100644 (file)
@@ -72,7 +72,6 @@ static inline int ns_alloc_inum(struct ns_common *ns)
 
 #define ns_free_inum(ns) proc_free_inum((ns)->inum)
 
-extern struct file *proc_ns_fget(int fd);
 #define get_proc_ns(inode) ((struct ns_common *)(inode)->i_private)
 extern int ns_get_path(struct path *path, struct task_struct *task,
                        const struct proc_ns_operations *ns_ops);
index 92ad75549e9cdbabb78cd9c6cc7e4c2356cf850a..b6e6378dcbbd7070200a709e32fe7553d614d9f9 100644 (file)
@@ -25,7 +25,8 @@ void rtmsg_ifinfo_newnet(int type, struct net_device *dev, unsigned int change,
 struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev,
                                       unsigned change, u32 event,
                                       gfp_t flags, int *new_nsid,
-                                      int new_ifindex, u32 portid, u32 seq);
+                                      int new_ifindex, u32 portid,
+                                      const struct nlmsghdr *nlh);
 void rtmsg_ifinfo_send(struct sk_buff *skb, struct net_device *dev,
                       gfp_t flags, u32 portid, const struct nlmsghdr *nlh);
 
index 63d242164b1a91af1fcb89c3cf6e146b32cda391..e1e605b1255b8c2ed1a78bdc517b8c51f1a344c2 100644 (file)
@@ -1729,7 +1729,7 @@ extern struct pid *cad_pid;
 #define PF_MEMALLOC            0x00000800      /* Allocating memory */
 #define PF_NPROC_EXCEEDED      0x00001000      /* set_user() noticed that RLIMIT_NPROC was exceeded */
 #define PF_USED_MATH           0x00002000      /* If unset the fpu must be initialized before use */
-#define PF__HOLE__00004000     0x00004000
+#define PF_USER_WORKER         0x00004000      /* Kernel thread cloned from userspace thread */
 #define PF_NOFREEZE            0x00008000      /* This thread should not be frozen */
 #define PF__HOLE__00010000     0x00010000
 #define PF_KSWAPD              0x00020000      /* I am kswapd */
index 357e0068497c162b097a18099922ae23a20c7015..537cbf9a2adeab8ef6bc372474ab63afe292d74d 100644 (file)
@@ -23,7 +23,13 @@ struct kernel_clone_args {
        int __user *pidfd;
        int __user *child_tid;
        int __user *parent_tid;
+       const char *name;
        int exit_signal;
+       u32 kthread:1;
+       u32 io_thread:1;
+       u32 user_worker:1;
+       u32 no_files:1;
+       u32 ignore_signals:1;
        unsigned long stack;
        unsigned long stack_size;
        unsigned long tls;
@@ -31,8 +37,6 @@ struct kernel_clone_args {
        /* Number of elements in *set_tid */
        size_t set_tid_size;
        int cgroup;
-       int io_thread;
-       int kthread;
        int idle;
        int (*fn)(void *);
        void *fn_arg;
@@ -89,9 +93,12 @@ extern void exit_files(struct task_struct *);
 extern void exit_itimers(struct task_struct *);
 
 extern pid_t kernel_clone(struct kernel_clone_args *kargs);
+struct task_struct *copy_process(struct pid *pid, int trace, int node,
+                                struct kernel_clone_args *args);
 struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node);
 struct task_struct *fork_idle(int);
-extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+extern pid_t kernel_thread(int (*fn)(void *), void *arg, const char *name,
+                           unsigned long flags);
 extern pid_t user_mode_thread(int (*fn)(void *), void *arg, unsigned long flags);
 extern long kernel_wait4(pid_t, int __user *, int, struct rusage *);
 int kernel_wait(pid_t pid, int *stat);
diff --git a/include/linux/sched/vhost_task.h b/include/linux/sched/vhost_task.h
new file mode 100644 (file)
index 0000000..6123c10
--- /dev/null
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_VHOST_TASK_H
+#define _LINUX_VHOST_TASK_H
+
+#include <linux/completion.h>
+
+struct task_struct;
+
+struct vhost_task {
+       int (*fn)(void *data);
+       void *data;
+       struct completion exited;
+       unsigned long flags;
+       struct task_struct *task;
+};
+
+struct vhost_task *vhost_task_create(int (*fn)(void *), void *arg,
+                                    const char *name);
+void vhost_task_start(struct vhost_task *vtsk);
+void vhost_task_stop(struct vhost_task *vtsk);
+bool vhost_task_should_stop(struct vhost_task *vtsk);
+
+#endif
index 5984d0d550b41bc1b134b63b67af46b4653eb710..e2734e9e44d5c7a4145712aa29b1bd163e598a12 100644 (file)
@@ -68,7 +68,7 @@ struct watch_notification;
 /* If capable is being called by a setid function */
 #define CAP_OPT_INSETID BIT(2)
 
-/* LSM Agnostic defines for fs_context::lsm_flags */
+/* LSM Agnostic defines for security_sb_set_mnt_opts() flags */
 #define SECURITY_LSM_NATIVE_LABELS     1
 
 struct ctl_table;
@@ -336,9 +336,6 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
 int security_inode_init_security_anon(struct inode *inode,
                                      const struct qstr *name,
                                      const struct inode *context_inode);
-int security_old_inode_init_security(struct inode *inode, struct inode *dir,
-                                    const struct qstr *qstr, const char **name,
-                                    void **value, size_t *len);
 int security_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode);
 int security_inode_link(struct dentry *old_dentry, struct inode *dir,
                         struct dentry *new_dentry);
@@ -778,15 +775,6 @@ static inline int security_inode_init_security_anon(struct inode *inode,
        return 0;
 }
 
-static inline int security_old_inode_init_security(struct inode *inode,
-                                                  struct inode *dir,
-                                                  const struct qstr *qstr,
-                                                  const char **name,
-                                                  void **value, size_t *len)
-{
-       return -EOPNOTSUPP;
-}
-
 static inline int security_inode_create(struct inode *dir,
                                         struct dentry *dentry,
                                         umode_t mode)
index 52b98f9666a2fc676ea51cee559c75d24c8a9e11..ef06a195b3c2bc588f485364d3a6bd86f992dec5 100644 (file)
@@ -557,7 +557,7 @@ int sfp_get_module_eeprom_by_page(struct sfp_bus *bus,
 void sfp_upstream_start(struct sfp_bus *bus);
 void sfp_upstream_stop(struct sfp_bus *bus);
 void sfp_bus_put(struct sfp_bus *bus);
-struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode);
+struct sfp_bus *sfp_bus_find_fwnode(const struct fwnode_handle *fwnode);
 int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream,
                         const struct sfp_upstream_ops *ops);
 void sfp_bus_del_upstream(struct sfp_bus *bus);
@@ -619,7 +619,8 @@ static inline void sfp_bus_put(struct sfp_bus *bus)
 {
 }
 
-static inline struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode)
+static inline struct sfp_bus *
+sfp_bus_find_fwnode(const struct fwnode_handle *fwnode)
 {
        return NULL;
 }
index ff7ad331fb8259fd06c07913dfa197d7ac448390..dbcaac8b696653e07961a94715ab63009295b21b 100644 (file)
@@ -294,6 +294,7 @@ struct nf_bridge_info {
        u8                      pkt_otherhost:1;
        u8                      in_prerouting:1;
        u8                      bridged_dnat:1;
+       u8                      sabotage_in_done:1;
        __u16                   frag_max_size;
        struct net_device       *physindev;
 
@@ -4712,7 +4713,7 @@ static inline void nf_reset_ct(struct sk_buff *skb)
 
 static inline void nf_reset_trace(struct sk_buff *skb)
 {
-#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || defined(CONFIG_NF_TABLES)
+#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || IS_ENABLED(CONFIG_NF_TABLES)
        skb->nf_trace = 0;
 #endif
 }
@@ -4732,7 +4733,7 @@ static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src,
        dst->_nfct = src->_nfct;
        nf_conntrack_get(skb_nfct(src));
 #endif
-#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || defined(CONFIG_NF_TABLES)
+#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || IS_ENABLED(CONFIG_NF_TABLES)
        if (copy)
                dst->nf_trace = src->nf_trace;
 #endif
index 74796cd7e7a9d20d2cf5d3c50c66fc422e0832da..41c4b26fb1c1949f08b59426192813cfe10a3c9f 100644 (file)
@@ -102,6 +102,32 @@ static inline int srcu_read_lock_held(const struct srcu_struct *ssp)
        return lock_is_held(&ssp->dep_map);
 }
 
+/*
+ * Annotations provide deadlock detection for SRCU.
+ *
+ * Similar to other lockdep annotations, except there is an additional
+ * srcu_lock_sync(), which is basically an empty *write*-side critical section,
+ * see lock_sync() for more information.
+ */
+
+/* Annotates a srcu_read_lock() */
+static inline void srcu_lock_acquire(struct lockdep_map *map)
+{
+       lock_map_acquire_read(map);
+}
+
+/* Annotates a srcu_read_lock() */
+static inline void srcu_lock_release(struct lockdep_map *map)
+{
+       lock_map_release(map);
+}
+
+/* Annotates a synchronize_srcu() */
+static inline void srcu_lock_sync(struct lockdep_map *map)
+{
+       lock_map_sync(map);
+}
+
 #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
 
 static inline int srcu_read_lock_held(const struct srcu_struct *ssp)
@@ -109,6 +135,10 @@ static inline int srcu_read_lock_held(const struct srcu_struct *ssp)
        return 1;
 }
 
+#define srcu_lock_acquire(m) do { } while (0)
+#define srcu_lock_release(m) do { } while (0)
+#define srcu_lock_sync(m) do { } while (0)
+
 #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
 
 #define SRCU_NMI_UNKNOWN       0x0
@@ -182,7 +212,7 @@ static inline int srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp)
 
        srcu_check_nmi_safety(ssp, false);
        retval = __srcu_read_lock(ssp);
-       rcu_lock_acquire(&(ssp)->dep_map);
+       srcu_lock_acquire(&(ssp)->dep_map);
        return retval;
 }
 
@@ -254,7 +284,7 @@ static inline void srcu_read_unlock(struct srcu_struct *ssp, int idx)
 {
        WARN_ON_ONCE(idx & ~0x1);
        srcu_check_nmi_safety(ssp, false);
-       rcu_lock_release(&(ssp)->dep_map);
+       srcu_lock_release(&(ssp)->dep_map);
        __srcu_read_unlock(ssp, idx);
 }
 
index 5aa5e0faf6a121a2770e6362cf368ce3efceefc7..ebd72491af99246cae9287b2c8a27e40ccb4c540 100644 (file)
@@ -31,7 +31,7 @@ struct srcu_struct {
 
 void srcu_drive_gp(struct work_struct *wp);
 
-#define __SRCU_STRUCT_INIT(name, __ignored)                            \
+#define __SRCU_STRUCT_INIT(name, __ignored, ___ignored)                        \
 {                                                                      \
        .srcu_wq = __SWAIT_QUEUE_HEAD_INITIALIZER(name.srcu_wq),        \
        .srcu_cb_tail = &name.srcu_cb_head,                             \
@@ -44,9 +44,9 @@ void srcu_drive_gp(struct work_struct *wp);
  * Tree SRCU, which needs some per-CPU data.
  */
 #define DEFINE_SRCU(name) \
-       struct srcu_struct name = __SRCU_STRUCT_INIT(name, name)
+       struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name)
 #define DEFINE_STATIC_SRCU(name) \
-       static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name)
+       static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name)
 
 void synchronize_srcu(struct srcu_struct *ssp);
 
index 558057b517b74cf5892d85ba95872f15ad42e1ce..8f3f72480e78b0d467167c777592e6472e3485e7 100644 (file)
@@ -58,9 +58,9 @@ struct srcu_node {
 };
 
 /*
- * Per-SRCU-domain structure, similar in function to rcu_state.
+ * Per-SRCU-domain structure, update-side data linked from srcu_struct.
  */
-struct srcu_struct {
+struct srcu_usage {
        struct srcu_node *node;                 /* Combining tree. */
        struct srcu_node *level[RCU_NUM_LVLS + 1];
                                                /* First node at each level. */
@@ -68,7 +68,6 @@ struct srcu_struct {
        struct mutex srcu_cb_mutex;             /* Serialize CB preparation. */
        spinlock_t __private lock;              /* Protect counters and size state. */
        struct mutex srcu_gp_mutex;             /* Serialize GP work. */
-       unsigned int srcu_idx;                  /* Current rdr array element. */
        unsigned long srcu_gp_seq;              /* Grace-period seq #. */
        unsigned long srcu_gp_seq_needed;       /* Latest gp_seq needed. */
        unsigned long srcu_gp_seq_needed_exp;   /* Furthest future exp GP. */
@@ -77,7 +76,6 @@ struct srcu_struct {
        unsigned long srcu_size_jiffies;        /* Current contention-measurement interval. */
        unsigned long srcu_n_lock_retries;      /* Contention events in current interval. */
        unsigned long srcu_n_exp_nodelay;       /* # expedited no-delays in current GP phase. */
-       struct srcu_data __percpu *sda;         /* Per-CPU srcu_data array. */
        bool sda_is_static;                     /* May ->sda be passed to free_percpu()? */
        unsigned long srcu_barrier_seq;         /* srcu_barrier seq #. */
        struct mutex srcu_barrier_mutex;        /* Serialize barrier ops. */
@@ -89,32 +87,68 @@ struct srcu_struct {
        unsigned long reschedule_jiffies;
        unsigned long reschedule_count;
        struct delayed_work work;
+       struct srcu_struct *srcu_ssp;
+};
+
+/*
+ * Per-SRCU-domain structure, similar in function to rcu_state.
+ */
+struct srcu_struct {
+       unsigned int srcu_idx;                  /* Current rdr array element. */
+       struct srcu_data __percpu *sda;         /* Per-CPU srcu_data array. */
        struct lockdep_map dep_map;
+       struct srcu_usage *srcu_sup;            /* Update-side data. */
 };
 
-/* Values for size state variable (->srcu_size_state). */
-#define SRCU_SIZE_SMALL                0
-#define SRCU_SIZE_ALLOC                1
-#define SRCU_SIZE_WAIT_BARRIER 2
-#define SRCU_SIZE_WAIT_CALL    3
-#define SRCU_SIZE_WAIT_CBS1    4
-#define SRCU_SIZE_WAIT_CBS2    5
-#define SRCU_SIZE_WAIT_CBS3    6
-#define SRCU_SIZE_WAIT_CBS4    7
-#define SRCU_SIZE_BIG          8
+// Values for size state variable (->srcu_size_state).  Once the state
+// has been set to SRCU_SIZE_ALLOC, the grace-period code advances through
+// this state machine one step per grace period until the SRCU_SIZE_BIG state
+// is reached.  Otherwise, the state machine remains in the SRCU_SIZE_SMALL
+// state indefinitely.
+#define SRCU_SIZE_SMALL                0       // No srcu_node combining tree, ->node == NULL
+#define SRCU_SIZE_ALLOC                1       // An srcu_node tree is being allocated, initialized,
+                                       //  and then referenced by ->node.  It will not be used.
+#define SRCU_SIZE_WAIT_BARRIER 2       // The srcu_node tree starts being used by everything
+                                       //  except call_srcu(), especially by srcu_barrier().
+                                       //  By the end of this state, all CPUs and threads
+                                       //  are aware of this tree's existence.
+#define SRCU_SIZE_WAIT_CALL    3       // The srcu_node tree starts being used by call_srcu().
+                                       //  By the end of this state, all of the call_srcu()
+                                       //  invocations that were running on a non-boot CPU
+                                       //  and using the boot CPU's callback queue will have
+                                       //  completed.
+#define SRCU_SIZE_WAIT_CBS1    4       // Don't trust the ->srcu_have_cbs[] grace-period
+#define SRCU_SIZE_WAIT_CBS2    5       //  sequence elements or the ->srcu_data_have_cbs[]
+#define SRCU_SIZE_WAIT_CBS3    6       //  CPU-bitmask elements until all four elements of
+#define SRCU_SIZE_WAIT_CBS4    7       //  each array have been initialized.
+#define SRCU_SIZE_BIG          8       // The srcu_node combining tree is fully initialized
+                                       //  and all aspects of it are being put to use.
 
 /* Values for state variable (bottom bits of ->srcu_gp_seq). */
 #define SRCU_STATE_IDLE                0
 #define SRCU_STATE_SCAN1       1
 #define SRCU_STATE_SCAN2       2
 
-#define __SRCU_STRUCT_INIT(name, pcpu_name)                            \
-{                                                                      \
-       .sda = &pcpu_name,                                              \
-       .lock = __SPIN_LOCK_UNLOCKED(name.lock),                        \
-       .srcu_gp_seq_needed = -1UL,                                     \
-       .work = __DELAYED_WORK_INITIALIZER(name.work, NULL, 0),         \
-       __SRCU_DEP_MAP_INIT(name)                                       \
+#define __SRCU_USAGE_INIT(name)                                                                        \
+{                                                                                              \
+       .lock = __SPIN_LOCK_UNLOCKED(name.lock),                                                \
+       .srcu_gp_seq_needed = -1UL,                                                             \
+       .work = __DELAYED_WORK_INITIALIZER(name.work, NULL, 0),                                 \
+}
+
+#define __SRCU_STRUCT_INIT_COMMON(name, usage_name)                                            \
+       .srcu_sup = &usage_name,                                                                \
+       __SRCU_DEP_MAP_INIT(name)
+
+#define __SRCU_STRUCT_INIT_MODULE(name, usage_name)                                            \
+{                                                                                              \
+       __SRCU_STRUCT_INIT_COMMON(name, usage_name)                                             \
+}
+
+#define __SRCU_STRUCT_INIT(name, usage_name, pcpu_name)                                                \
+{                                                                                              \
+       .sda = &pcpu_name,                                                                      \
+       __SRCU_STRUCT_INIT_COMMON(name, usage_name)                                             \
 }
 
 /*
@@ -137,16 +171,18 @@ struct srcu_struct {
  * See include/linux/percpu-defs.h for the rules on per-CPU variables.
  */
 #ifdef MODULE
-# define __DEFINE_SRCU(name, is_static)                                        \
-       is_static struct srcu_struct name;                              \
-       extern struct srcu_struct * const __srcu_struct_##name;         \
-       struct srcu_struct * const __srcu_struct_##name                 \
+# define __DEFINE_SRCU(name, is_static)                                                                \
+       static struct srcu_usage name##_srcu_usage = __SRCU_USAGE_INIT(name##_srcu_usage);      \
+       is_static struct srcu_struct name = __SRCU_STRUCT_INIT_MODULE(name, name##_srcu_usage); \
+       extern struct srcu_struct * const __srcu_struct_##name;                                 \
+       struct srcu_struct * const __srcu_struct_##name                                         \
                __section("___srcu_struct_ptrs") = &name
 #else
-# define __DEFINE_SRCU(name, is_static)                                        \
-       static DEFINE_PER_CPU(struct srcu_data, name##_srcu_data);      \
-       is_static struct srcu_struct name =                             \
-               __SRCU_STRUCT_INIT(name, name##_srcu_data)
+# define __DEFINE_SRCU(name, is_static)                                                                \
+       static DEFINE_PER_CPU(struct srcu_data, name##_srcu_data);                              \
+       static struct srcu_usage name##_srcu_usage = __SRCU_USAGE_INIT(name##_srcu_usage);      \
+       is_static struct srcu_struct name =                                                     \
+               __SRCU_STRUCT_INIT(name, name##_srcu_usage, name##_srcu_data)
 #endif
 #define DEFINE_SRCU(name)              __DEFINE_SRCU(name, /* not static */)
 #define DEFINE_STATIC_SRCU(name)       __DEFINE_SRCU(name, static)
index a152678b82b714bd53f59764a8772627c8e25a05..a2414c18748370f40c0e8d99c0056e56103a26af 100644 (file)
@@ -215,7 +215,7 @@ struct plat_stmmacenet_data {
        int unicast_filter_entries;
        int tx_fifo_size;
        int rx_fifo_size;
-       u32 addr64;
+       u32 host_dma_width;
        u32 rx_queues_to_use;
        u32 tx_queues_to_use;
        u8 rx_sched_algorithm;
index 8ba8b5be5567511dfecf4386de133af14e359807..c1ef5fc60a3cba54d640a3e77dc419506801f42c 100644 (file)
@@ -70,11 +70,16 @@ static inline void sysfb_disable(void)
 #ifdef CONFIG_EFI
 
 extern struct efifb_dmi_info efifb_dmi_list[];
-void sysfb_apply_efi_quirks(struct platform_device *pd);
+void sysfb_apply_efi_quirks(void);
+void sysfb_set_efifb_fwnode(struct platform_device *pd);
 
 #else /* CONFIG_EFI */
 
-static inline void sysfb_apply_efi_quirks(struct platform_device *pd)
+static inline void sysfb_apply_efi_quirks(void)
+{
+}
+
+static inline void sysfb_set_efifb_fwnode(struct platform_device *pd)
 {
 }
 
index 2bb4bf33f4f32df80449108f53aaa7c193a75fb2..13c6aaed18df3e2f63a9da830f448e7575988c73 100644 (file)
@@ -384,6 +384,7 @@ devm_thermal_of_cooling_device_register(struct device *dev,
                                struct device_node *np,
                                char *type, void *devdata,
                                const struct thermal_cooling_device_ops *ops);
+void thermal_cooling_device_update(struct thermal_cooling_device *);
 void thermal_cooling_device_unregister(struct thermal_cooling_device *);
 struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name);
 int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
index bfd571f18cfdc9c474139234aeceaa4244ebb1b1..9459fef5b85736d0c895a5643ae0d87feabbb41d 100644 (file)
@@ -216,6 +216,7 @@ extern void tick_nohz_dep_set_signal(struct task_struct *tsk,
                                     enum tick_dep_bits bit);
 extern void tick_nohz_dep_clear_signal(struct signal_struct *signal,
                                       enum tick_dep_bits bit);
+extern bool tick_nohz_cpu_hotpluggable(unsigned int cpu);
 
 /*
  * The below are tick_nohz_[set,clear]_dep() wrappers that optimize off-cases
@@ -280,6 +281,7 @@ static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask) { }
 
 static inline void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit) { }
 static inline void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit) { }
+static inline bool tick_nohz_cpu_hotpluggable(unsigned int cpu) { return true; }
 
 static inline void tick_dep_set(enum tick_dep_bits bit) { }
 static inline void tick_dep_clear(enum tick_dep_bits bit) { }
index e299f29375bb7f1e55789adca45b45e31bebde84..6811e43c1b5c2afed0bad0a2e7469e8573916eb9 100644 (file)
@@ -242,12 +242,11 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
  * not add unwanted padding between the beginning of the section and the
  * structure. Force alignment to the same alignment as the section start.
  *
- * When lockdep is enabled, we make sure to always do the RCU portions of
- * the tracepoint code, regardless of whether tracing is on. However,
- * don't check if the condition is false, due to interaction with idle
- * instrumentation. This lets us find RCU issues triggered with tracepoints
- * even when this tracepoint is off. This code has no purpose other than
- * poking RCU a bit.
+ * When lockdep is enabled, we make sure to always test if RCU is
+ * "watching" regardless if the tracepoint is enabled or not. Tracepoints
+ * require RCU to be active, and it should always warn at the tracepoint
+ * site if it is not watching, as it will need to be active when the
+ * tracepoint is enabled.
  */
 #define __DECLARE_TRACE(name, proto, args, cond, data_proto)           \
        extern int __traceiter_##name(data_proto);                      \
@@ -260,9 +259,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
                                TP_ARGS(args),                          \
                                TP_CONDITION(cond), 0);                 \
                if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) {             \
-                       rcu_read_lock_sched_notrace();                  \
-                       rcu_dereference_sched(__tracepoint_##name.funcs);\
-                       rcu_read_unlock_sched_notrace();                \
+                       WARN_ON_ONCE(!rcu_is_watching());               \
                }                                                       \
        }                                                               \
        __DECLARE_TRACE_RCU(name, PARAMS(proto), PARAMS(args),          \
index 27e3fd942960978b3bf1e461eb893f0c827a3f0f..ed35f4427a0ad48a9db9b941163b80f95c6fb4f9 100644 (file)
@@ -49,14 +49,35 @@ struct iov_iter {
                size_t iov_offset;
                int last_offset;
        };
-       size_t count;
+       /*
+        * Hack alert: overlay ubuf_iovec with iovec + count, so
+        * that the members resolve correctly regardless of the type
+        * of iterator used. This means that you can use:
+        *
+        * &iter->__ubuf_iovec or iter->__iov
+        *
+        * interchangably for the user_backed cases, hence simplifying
+        * some of the cases that need to deal with both.
+        */
        union {
-               const struct iovec *iov;
-               const struct kvec *kvec;
-               const struct bio_vec *bvec;
-               struct xarray *xarray;
-               struct pipe_inode_info *pipe;
-               void __user *ubuf;
+               /*
+                * This really should be a const, but we cannot do that without
+                * also modifying any of the zero-filling iter init functions.
+                * Leave it non-const for now, but it should be treated as such.
+                */
+               struct iovec __ubuf_iovec;
+               struct {
+                       union {
+                               /* use iter_iov() to get the current vec */
+                               const struct iovec *__iov;
+                               const struct kvec *kvec;
+                               const struct bio_vec *bvec;
+                               struct xarray *xarray;
+                               struct pipe_inode_info *pipe;
+                               void __user *ubuf;
+                       };
+                       size_t count;
+               };
        };
        union {
                unsigned long nr_segs;
@@ -68,6 +89,16 @@ struct iov_iter {
        };
 };
 
+static inline const struct iovec *iter_iov(const struct iov_iter *iter)
+{
+       if (iter->iter_type == ITER_UBUF)
+               return (const struct iovec *) &iter->__ubuf_iovec;
+       return iter->__iov;
+}
+
+#define iter_iov_addr(iter)    (iter_iov(iter)->iov_base + (iter)->iov_offset)
+#define iter_iov_len(iter)     (iter_iov(iter)->iov_len - (iter)->iov_offset)
+
 static inline enum iter_type iov_iter_type(const struct iov_iter *i)
 {
        return i->iter_type;
@@ -143,15 +174,6 @@ static inline size_t iov_length(const struct iovec *iov, unsigned long nr_segs)
        return ret;
 }
 
-static inline struct iovec iov_iter_iovec(const struct iov_iter *iter)
-{
-       return (struct iovec) {
-               .iov_base = iter->iov->iov_base + iter->iov_offset,
-               .iov_len = min(iter->count,
-                              iter->iov->iov_len - iter->iov_offset),
-       };
-}
-
 size_t copy_page_from_iter_atomic(struct page *page, unsigned offset,
                                  size_t bytes, struct iov_iter *i);
 void iov_iter_advance(struct iov_iter *i, size_t bytes);
@@ -359,7 +381,8 @@ static inline void iov_iter_ubuf(struct iov_iter *i, unsigned int direction,
                .user_backed = true,
                .data_source = direction,
                .ubuf = buf,
-               .count = count
+               .count = count,
+               .nr_segs = 1
        };
 }
 /* Flags for iov_iter_get/extract_pages*() */
index 6af72461397d425e9f99f33148450f06d6a9103e..d591ef59aa98efed1f6cda7d54a21f94ed828bc4 100644 (file)
@@ -47,6 +47,22 @@ struct xattr_handler {
                   size_t size, int flags);
 };
 
+/**
+ * xattr_handler_can_list - check whether xattr can be listed
+ * @handler: handler for this type of xattr
+ * @dentry: dentry whose inode xattr to list
+ *
+ * Determine whether the xattr associated with @dentry can be listed given
+ * @handler.
+ *
+ * Return: true if xattr can be listed, false if not.
+ */
+static inline bool xattr_handler_can_list(const struct xattr_handler *handler,
+                                         struct dentry *dentry)
+{
+       return handler && (!handler->list || handler->list(dentry));
+}
+
 const char *xattr_full_name(const struct xattr_handler *, const char *);
 
 struct xattr {
@@ -78,7 +94,7 @@ int vfs_getxattr_alloc(struct mnt_idmap *idmap,
                       struct dentry *dentry, const char *name,
                       char **xattr_value, size_t size, gfp_t flags);
 
-int xattr_supported_namespace(struct inode *inode, const char *prefix);
+int xattr_supports_user_prefix(struct inode *inode);
 
 static inline const char *xattr_prefix(const struct xattr_handler *handler)
 {
@@ -109,5 +125,6 @@ ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
                          char *buffer, size_t size);
 void simple_xattr_add(struct simple_xattrs *xattrs,
                      struct simple_xattr *new_xattr);
+int xattr_list_one(char **buffer, ssize_t *remaining_size, const char *name);
 
 #endif /* _LINUX_XATTR_H */
index 7254edfba4c9c43fd0ea2f6f44fe1b2d2083d2e4..d5311ceb21c62f30d302ecf8aa4ac16bc2edc062 100644 (file)
@@ -954,6 +954,7 @@ enum {
        HCI_CONN_STK_ENCRYPT,
        HCI_CONN_AUTH_INITIATOR,
        HCI_CONN_DROP,
+       HCI_CONN_CANCEL,
        HCI_CONN_PARAM_REMOVAL_PEND,
        HCI_CONN_NEW_LINK_KEY,
        HCI_CONN_SCANNING,
@@ -1613,6 +1614,7 @@ void hci_conn_add_sysfs(struct hci_conn *conn);
 void hci_conn_del_sysfs(struct hci_conn *conn);
 
 #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev))
+#define GET_HCIDEV_DEV(hdev) ((hdev)->dev.parent)
 
 /* ----- LMP capabilities ----- */
 #define lmp_encrypt_capable(dev)   ((dev)->features[0][0] & LMP_ENCRYPT)
index ea36ab7f9e724bd3650d7502c969ab1b8ba2f7ba..c3843239517d539c15985f38b4887a888c940d9d 100644 (file)
@@ -761,13 +761,17 @@ static inline int bond_get_targets_ip(__be32 *targets, __be32 ip)
 #if IS_ENABLED(CONFIG_IPV6)
 static inline int bond_get_targets_ip6(struct in6_addr *targets, struct in6_addr *ip)
 {
+       struct in6_addr mcaddr;
        int i;
 
-       for (i = 0; i < BOND_MAX_NS_TARGETS; i++)
-               if (ipv6_addr_equal(&targets[i], ip))
+       for (i = 0; i < BOND_MAX_NS_TARGETS; i++) {
+               addrconf_addr_solict_mult(&targets[i], &mcaddr);
+               if ((ipv6_addr_equal(&targets[i], ip)) ||
+                   (ipv6_addr_equal(&mcaddr, ip)))
                        return i;
                else if (ipv6_addr_any(&targets[i]))
                        break;
+       }
 
        return -1;
 }
index 9430128aae991144f6e24d7b373a04153d6e3f0e..1b8e305bb54aec82f71a79755ae166ed64387838 100644 (file)
@@ -1085,6 +1085,10 @@ struct nft_chain {
 };
 
 int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain);
+int nft_setelem_validate(const struct nft_ctx *ctx, struct nft_set *set,
+                        const struct nft_set_iter *iter,
+                        struct nft_set_elem *elem);
+int nft_set_catchall_validate(const struct nft_ctx *ctx, struct nft_set *set);
 
 enum nft_chain_types {
        NFT_CHAIN_T_DEFAULT = 0,
index 82d0e41b76f224f02a5b8fb3fec6d4c64721066a..faa108b1ba675ba89724b16ba3c16df2776aeb6b 100644 (file)
@@ -17,6 +17,13 @@ static inline bool nf_tproxy_sk_is_transparent(struct sock *sk)
        return false;
 }
 
+static inline void nf_tproxy_twsk_deschedule_put(struct inet_timewait_sock *tw)
+{
+       local_bh_disable();
+       inet_twsk_deschedule_put(tw);
+       local_bh_enable();
+}
+
 /* assign a socket to the skb -- consumes sk */
 static inline void nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk)
 {
index 2c004c20ed996d1dbe07f2c8d25edd2ce03cca03..3af5289fdead9aa5eb517171a6bd5b4f63fe7390 100644 (file)
@@ -37,7 +37,7 @@ int raw_rcv(struct sock *, struct sk_buff *);
 struct raw_hashinfo {
        spinlock_t lock;
 
-       struct hlist_nulls_head ht[RAW_HTABLE_SIZE] ____cacheline_aligned;
+       struct hlist_head ht[RAW_HTABLE_SIZE] ____cacheline_aligned;
 };
 
 static inline u32 raw_hashfunc(const struct net *net, u32 proto)
@@ -51,7 +51,7 @@ static inline void raw_hashinfo_init(struct raw_hashinfo *hashinfo)
 
        spin_lock_init(&hashinfo->lock);
        for (i = 0; i < RAW_HTABLE_SIZE; i++)
-               INIT_HLIST_NULLS_HEAD(&hashinfo->ht[i], i);
+               INIT_HLIST_HEAD(&hashinfo->ht[i]);
 }
 
 #ifdef CONFIG_PROC_FS
index d517bfac937b0a2bda248f594750fbb0c9a082ab..76aa748e792374abc91166561c072b18833e1a63 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/skbuff.h> /* skb_shared_info */
 #include <uapi/linux/netdev.h>
+#include <linux/bitfield.h>
 
 /**
  * DOC: XDP RX-queue information
@@ -425,15 +426,67 @@ XDP_METADATA_KFUNC_xxx
 MAX_XDP_METADATA_KFUNC,
 };
 
+enum xdp_rss_hash_type {
+       /* First part: Individual bits for L3/L4 types */
+       XDP_RSS_L3_IPV4         = BIT(0),
+       XDP_RSS_L3_IPV6         = BIT(1),
+
+       /* The fixed (L3) IPv4 and IPv6 headers can both be followed by
+        * variable/dynamic headers, IPv4 called Options and IPv6 called
+        * Extension Headers. HW RSS type can contain this info.
+        */
+       XDP_RSS_L3_DYNHDR       = BIT(2),
+
+       /* When RSS hash covers L4 then drivers MUST set XDP_RSS_L4 bit in
+        * addition to the protocol specific bit.  This ease interaction with
+        * SKBs and avoids reserving a fixed mask for future L4 protocol bits.
+        */
+       XDP_RSS_L4              = BIT(3), /* L4 based hash, proto can be unknown */
+       XDP_RSS_L4_TCP          = BIT(4),
+       XDP_RSS_L4_UDP          = BIT(5),
+       XDP_RSS_L4_SCTP         = BIT(6),
+       XDP_RSS_L4_IPSEC        = BIT(7), /* L4 based hash include IPSEC SPI */
+
+       /* Second part: RSS hash type combinations used for driver HW mapping */
+       XDP_RSS_TYPE_NONE            = 0,
+       XDP_RSS_TYPE_L2              = XDP_RSS_TYPE_NONE,
+
+       XDP_RSS_TYPE_L3_IPV4         = XDP_RSS_L3_IPV4,
+       XDP_RSS_TYPE_L3_IPV6         = XDP_RSS_L3_IPV6,
+       XDP_RSS_TYPE_L3_IPV4_OPT     = XDP_RSS_L3_IPV4 | XDP_RSS_L3_DYNHDR,
+       XDP_RSS_TYPE_L3_IPV6_EX      = XDP_RSS_L3_IPV6 | XDP_RSS_L3_DYNHDR,
+
+       XDP_RSS_TYPE_L4_ANY          = XDP_RSS_L4,
+       XDP_RSS_TYPE_L4_IPV4_TCP     = XDP_RSS_L3_IPV4 | XDP_RSS_L4 | XDP_RSS_L4_TCP,
+       XDP_RSS_TYPE_L4_IPV4_UDP     = XDP_RSS_L3_IPV4 | XDP_RSS_L4 | XDP_RSS_L4_UDP,
+       XDP_RSS_TYPE_L4_IPV4_SCTP    = XDP_RSS_L3_IPV4 | XDP_RSS_L4 | XDP_RSS_L4_SCTP,
+       XDP_RSS_TYPE_L4_IPV4_IPSEC   = XDP_RSS_L3_IPV4 | XDP_RSS_L4 | XDP_RSS_L4_IPSEC,
+
+       XDP_RSS_TYPE_L4_IPV6_TCP     = XDP_RSS_L3_IPV6 | XDP_RSS_L4 | XDP_RSS_L4_TCP,
+       XDP_RSS_TYPE_L4_IPV6_UDP     = XDP_RSS_L3_IPV6 | XDP_RSS_L4 | XDP_RSS_L4_UDP,
+       XDP_RSS_TYPE_L4_IPV6_SCTP    = XDP_RSS_L3_IPV6 | XDP_RSS_L4 | XDP_RSS_L4_SCTP,
+       XDP_RSS_TYPE_L4_IPV6_IPSEC   = XDP_RSS_L3_IPV6 | XDP_RSS_L4 | XDP_RSS_L4_IPSEC,
+
+       XDP_RSS_TYPE_L4_IPV6_TCP_EX  = XDP_RSS_TYPE_L4_IPV6_TCP  | XDP_RSS_L3_DYNHDR,
+       XDP_RSS_TYPE_L4_IPV6_UDP_EX  = XDP_RSS_TYPE_L4_IPV6_UDP  | XDP_RSS_L3_DYNHDR,
+       XDP_RSS_TYPE_L4_IPV6_SCTP_EX = XDP_RSS_TYPE_L4_IPV6_SCTP | XDP_RSS_L3_DYNHDR,
+};
+
 #ifdef CONFIG_NET
 u32 bpf_xdp_metadata_kfunc_id(int id);
 bool bpf_dev_bound_kfunc_id(u32 btf_id);
+void xdp_set_features_flag(struct net_device *dev, xdp_features_t val);
 void xdp_features_set_redirect_target(struct net_device *dev, bool support_sg);
 void xdp_features_clear_redirect_target(struct net_device *dev);
 #else
 static inline u32 bpf_xdp_metadata_kfunc_id(int id) { return 0; }
 static inline bool bpf_dev_bound_kfunc_id(u32 btf_id) { return false; }
 
+static inline void
+xdp_set_features_flag(struct net_device *dev, xdp_features_t val)
+{
+}
+
 static inline void
 xdp_features_set_redirect_target(struct net_device *dev, bool support_sg)
 {
@@ -445,4 +498,9 @@ xdp_features_clear_redirect_target(struct net_device *dev)
 }
 #endif
 
+static inline void xdp_clear_features_flag(struct net_device *dev)
+{
+       xdp_set_features_flag(dev, 0);
+}
+
 #endif /* __LINUX_NET_XDP_H__ */
index de310f21406c546f7d8d0819e56ef4a9a4ec7ea4..f10a008e5bfa1408b4836465015c9c3ac984cb32 100644 (file)
@@ -145,6 +145,7 @@ struct scsi_device {
        const char * model;             /* ... after scan; point to static string */
        const char * rev;               /* ... "nullnullnullnull" before scan */
 
+#define SCSI_DEFAULT_VPD_LEN   255     /* default SCSI VPD page size (max) */
        struct scsi_vpd __rcu *vpd_pg0;
        struct scsi_vpd __rcu *vpd_pg83;
        struct scsi_vpd __rcu *vpd_pg80;
@@ -215,6 +216,7 @@ struct scsi_device {
                                         * creation time */
        unsigned ignore_media_change:1; /* Ignore MEDIA CHANGE on resume */
        unsigned silence_suspend:1;     /* Do not print runtime PM related messages */
+       unsigned no_vpd_size:1;         /* No VPD size reported in header */
 
        unsigned int queue_stopped;     /* request queue is quiesced */
        bool offline_already;           /* Device offline message logged */
index 5d14adae21c78903188052187076eeec9644188a..6b548dc2c49654c95aa9e213692e2931395701e6 100644 (file)
@@ -32,7 +32,8 @@
 #define BLIST_IGN_MEDIA_CHANGE ((__force blist_flags_t)(1ULL << 11))
 /* do not do automatic start on add */
 #define BLIST_NOSTARTONADD     ((__force blist_flags_t)(1ULL << 12))
-#define __BLIST_UNUSED_13      ((__force blist_flags_t)(1ULL << 13))
+/* do not ask for VPD page size first on some broken targets */
+#define BLIST_NO_VPD_SIZE      ((__force blist_flags_t)(1ULL << 13))
 #define __BLIST_UNUSED_14      ((__force blist_flags_t)(1ULL << 14))
 #define __BLIST_UNUSED_15      ((__force blist_flags_t)(1ULL << 15))
 #define __BLIST_UNUSED_16      ((__force blist_flags_t)(1ULL << 16))
@@ -74,8 +75,7 @@
 #define __BLIST_HIGH_UNUSED (~(__BLIST_LAST_USED | \
                               (__force blist_flags_t) \
                               ((__force __u64)__BLIST_LAST_USED - 1ULL)))
-#define __BLIST_UNUSED_MASK (__BLIST_UNUSED_13 | \
-                            __BLIST_UNUSED_14 | \
+#define __BLIST_UNUSED_MASK (__BLIST_UNUSED_14 | \
                             __BLIST_UNUSED_15 | \
                             __BLIST_UNUSED_16 | \
                             __BLIST_UNUSED_24 | \
index cf4a0d28b178b356c730b1c591cc73bc1f73deba..71dbe8bfa7db23e0d72383e2f09f2c03075aa5b4 100644 (file)
@@ -71,8 +71,8 @@ TRACE_EVENT(erofs_fill_inode,
        TP_fast_assign(
                __entry->dev            = inode->i_sb->s_dev;
                __entry->nid            = EROFS_I(inode)->nid;
-               __entry->blkaddr        = erofs_blknr(erofs_iloc(inode));
-               __entry->ofs            = erofs_blkoff(erofs_iloc(inode));
+               __entry->blkaddr        = erofs_blknr(inode->i_sb, erofs_iloc(inode));
+               __entry->ofs            = erofs_blkoff(inode->i_sb, erofs_iloc(inode));
        ),
 
        TP_printk("dev = (%d,%d), nid = %llu, blkaddr %u ofs %u",
index 1322d34a5dfc17cdcdc26eee30b0c497a4a4fe91..99cbc5949e3cd0ae13f72eff9efdf88eed2c1df6 100644 (file)
@@ -512,7 +512,7 @@ TRACE_EVENT(f2fs_truncate_partial_nodes,
        TP_STRUCT__entry(
                __field(dev_t,  dev)
                __field(ino_t,  ino)
-               __field(nid_t,  nid[3])
+               __array(nid_t,  nid, 3)
                __field(int,    depth)
                __field(int,    err)
        ),
index 216de5f0362101d8adf9f9e231f03c086951df0d..f8d61485de16deadad88d6062676d2374f1079e5 100644 (file)
@@ -35,7 +35,7 @@ TRACE_EVENT(vm_unmapped_area,
                __entry->align_offset = info->align_offset;
        ),
 
-       TP_printk("addr=0x%lx err=%ld total_vm=0x%lx flags=0x%lx len=0x%lx lo=0x%lx hi=0x%lx mask=0x%lx ofs=0x%lx\n",
+       TP_printk("addr=0x%lx err=%ld total_vm=0x%lx flags=0x%lx len=0x%lx lo=0x%lx hi=0x%lx mask=0x%lx ofs=0x%lx",
                IS_ERR_VALUE(__entry->addr) ? 0 : __entry->addr,
                IS_ERR_VALUE(__entry->addr) ? __entry->addr : 0,
                __entry->total_vm, __entry->flags, __entry->length,
@@ -110,7 +110,7 @@ TRACE_EVENT(exit_mmap,
                       __entry->mt              = &mm->mm_mt;
        ),
 
-       TP_printk("mt_mod %p, DESTROY\n",
+       TP_printk("mt_mod %p, DESTROY",
                  __entry->mt
        )
 );
index 90b2fb0292cb1525d7ecd1f82f10b163804f7ee0..2ef9c719772afbd6002c4b658c3dcaaa99da1246 100644 (file)
@@ -768,7 +768,7 @@ TRACE_EVENT_RCU(rcu_torture_read,
        TP_ARGS(rcutorturename, rhp, secs, c_old, c),
 
        TP_STRUCT__entry(
-               __field(char, rcutorturename[RCUTORTURENAME_LEN])
+               __array(char, rcutorturename, RCUTORTURENAME_LEN)
                __field(struct rcu_head *, rhp)
                __field(unsigned long, secs)
                __field(unsigned long, c_old)
@@ -776,9 +776,7 @@ TRACE_EVENT_RCU(rcu_torture_read,
        ),
 
        TP_fast_assign(
-               strncpy(__entry->rcutorturename, rcutorturename,
-                       RCUTORTURENAME_LEN);
-               __entry->rcutorturename[RCUTORTURENAME_LEN - 1] = 0;
+               strscpy(__entry->rcutorturename, rcutorturename, RCUTORTURENAME_LEN);
                __entry->rhp = rhp;
                __entry->secs = secs;
                __entry->c_old = c_old;
index 2e713a7d9aa3a45c11c551d038d8ea4d087017d6..3e8619c72f774589592ff6149f93746f0b48eca7 100644 (file)
@@ -371,7 +371,8 @@ TRACE_EVENT(itimer_expire,
                tick_dep_name(PERF_EVENTS)              \
                tick_dep_name(SCHED)                    \
                tick_dep_name(CLOCK_UNSTABLE)           \
-               tick_dep_name_end(RCU)
+               tick_dep_name(RCU)                      \
+               tick_dep_name_end(RCU_EXP)
 
 #undef tick_dep_name
 #undef tick_dep_mask_name
index ac5c24d3beeb24950996b07803ced5ccda09ca6f..e30a13be46ba560eaac1d11eb8e4843faf176891 100644 (file)
@@ -9,17 +9,30 @@
 #undef __entry
 #define __entry entry
 
+/*
+ * Fields should never declare an array: i.e. __field(int, arr[5])
+ * If they do, it will cause issues in parsing and possibly corrupt the
+ * events. To prevent that from happening, test the sizeof() a fictitious
+ * type called "struct _test_no_array_##item" which will fail if "item"
+ * contains array elements (like "arr[5]").
+ *
+ * If you hit this, use __array(int, arr, 5) instead.
+ */
 #undef __field
-#define __field(type, item)
+#define __field(type, item)                                    \
+       { (void)sizeof(struct _test_no_array_##item *); }
 
 #undef __field_ext
-#define __field_ext(type, item, filter_type)
+#define __field_ext(type, item, filter_type)                   \
+       { (void)sizeof(struct _test_no_array_##item *); }
 
 #undef __field_struct
-#define __field_struct(type, item)
+#define __field_struct(type, item)                             \
+       { (void)sizeof(struct _test_no_array_##item *); }
 
 #undef __field_struct_ext
-#define __field_struct_ext(type, item, filter_type)
+#define __field_struct_ext(type, item, filter_type)            \
+       { (void)sizeof(struct _test_no_array_##item *); }
 
 #undef __array
 #define __array(type, item, len)
index 1ecdb911add8de3b16f4b05dff630a0ca47285d1..80f37a0d40d7d4efefe406f73598f0f150bd9973 100644 (file)
@@ -91,7 +91,6 @@
 
 /* a horrid kludge trying to make sure that this will fail on old kernels */
 #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
-#define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT)      
 
 #ifndef O_NDELAY
 #define O_NDELAY       O_NONBLOCK
index b4f0f9531119f2df1b9eb4f84ce3e5e19485822a..ada0a489bf2b69287416321e7dcf43144de68a0b 100644 (file)
@@ -245,7 +245,17 @@ struct btrfs_ioctl_dev_info_args {
        __u8 uuid[BTRFS_UUID_SIZE];             /* in/out */
        __u64 bytes_used;                       /* out */
        __u64 total_bytes;                      /* out */
-       __u64 unused[379];                      /* pad to 4k */
+       /*
+        * Optional, out.
+        *
+        * Showing the fsid of the device, allowing user space to check if this
+        * device is a seeding one.
+        *
+        * Introduced in v6.3, thus user space still needs to check if kernel
+        * changed this value.  Older kernel will not touch the values here.
+        */
+       __u8 fsid[BTRFS_UUID_SIZE];
+       __u64 unused[377];                      /* pad to 4k */
        __u8 path[BTRFS_DEVICE_PATH_NAME_MAX];  /* out */
 };
 
index 19ebbef41a63cbf824dd0dd61586f0bf06c020f0..b5cd3e7b3775a61690ce5998b6fe379de34b9e01 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
 /* Do not edit directly, auto-generated from: */
 /*     Documentation/netlink/specs/fou.yaml */
 /* YNL-GEN uapi header */
index f3223f9646913cc9539a66b9ee6a10ced108f954..81d09ef9aa50e902d92baed031f07e32b8f2e07c 100644 (file)
@@ -130,21 +130,37 @@ struct landlock_path_beneath_attr {
  * - %LANDLOCK_ACCESS_FS_MAKE_BLOCK: Create (or rename or link) a block device.
  * - %LANDLOCK_ACCESS_FS_MAKE_SYM: Create (or rename or link) a symbolic link.
  * - %LANDLOCK_ACCESS_FS_REFER: Link or rename a file from or to a different
- *   directory (i.e. reparent a file hierarchy).  This access right is
- *   available since the second version of the Landlock ABI.  This is also the
- *   only access right which is always considered handled by any ruleset in
- *   such a way that reparenting a file hierarchy is always denied by default.
- *   To avoid privilege escalation, it is not enough to add a rule with this
- *   access right.  When linking or renaming a file, the destination directory
- *   hierarchy must also always have the same or a superset of restrictions of
- *   the source hierarchy.  If it is not the case, or if the domain doesn't
- *   handle this access right, such actions are denied by default with errno
- *   set to ``EXDEV``.  Linking also requires a ``LANDLOCK_ACCESS_FS_MAKE_*``
- *   access right on the destination directory, and renaming also requires a
- *   ``LANDLOCK_ACCESS_FS_REMOVE_*`` access right on the source's (file or
- *   directory) parent.  Otherwise, such actions are denied with errno set to
- *   ``EACCES``.  The ``EACCES`` errno prevails over ``EXDEV`` to let user space
- *   efficiently deal with an unrecoverable error.
+ *   directory (i.e. reparent a file hierarchy).
+ *
+ *   This access right is available since the second version of the Landlock
+ *   ABI.
+ *
+ *   This is the only access right which is denied by default by any ruleset,
+ *   even if the right is not specified as handled at ruleset creation time.
+ *   The only way to make a ruleset grant this right is to explicitly allow it
+ *   for a specific directory by adding a matching rule to the ruleset.
+ *
+ *   In particular, when using the first Landlock ABI version, Landlock will
+ *   always deny attempts to reparent files between different directories.
+ *
+ *   In addition to the source and destination directories having the
+ *   %LANDLOCK_ACCESS_FS_REFER access right, the attempted link or rename
+ *   operation must meet the following constraints:
+ *
+ *   * The reparented file may not gain more access rights in the destination
+ *     directory than it previously had in the source directory.  If this is
+ *     attempted, the operation results in an ``EXDEV`` error.
+ *
+ *   * When linking or renaming, the ``LANDLOCK_ACCESS_FS_MAKE_*`` right for the
+ *     respective file type must be granted for the destination directory.
+ *     Otherwise, the operation results in an ``EACCES`` error.
+ *
+ *   * When renaming, the ``LANDLOCK_ACCESS_FS_REMOVE_*`` right for the
+ *     respective file type must be granted for the source directory.  Otherwise,
+ *     the operation results in an ``EACCES`` error.
+ *
+ *   If multiple requirements are not met, the ``EACCES`` error code takes
+ *   precedence over ``EXDEV``.
  *
  * .. warning::
  *
index 588391447bfb09d260448c5c63f8bd3ba0521a52..639524b59930bfcabcd0d352048a3fd4aa1da08b 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
 /* Do not edit directly, auto-generated from: */
 /*     Documentation/netlink/specs/netdev.yaml */
 /* YNL-GEN uapi header */
@@ -33,6 +33,8 @@ enum netdev_xdp_act {
        NETDEV_XDP_ACT_HW_OFFLOAD = 16,
        NETDEV_XDP_ACT_RX_SG = 32,
        NETDEV_XDP_ACT_NDO_XMIT_SG = 64,
+
+       NETDEV_XDP_ACT_MASK = 127,
 };
 
 enum {
index 25a0af57dd5ed3c204897f8da892a4c378bf5c08..51c13cf9c5aee4a2d1ab33c1a89043383d67b9cf 100644 (file)
@@ -789,6 +789,7 @@ enum {
        TCA_ROOT_FLAGS,
        TCA_ROOT_COUNT,
        TCA_ROOT_TIME_DELTA, /* in msecs */
+       TCA_ROOT_EXT_WARN_MSG,
        __TCA_ROOT_MAX,
 #define        TCA_ROOT_MAX (__TCA_ROOT_MAX - 1)
 };
index 5af2a0300bb9d59a48beba17b79964af76985590..3744e4da1b2a7d1121b6873a3839ed962fa4898f 100644 (file)
@@ -140,11 +140,11 @@ struct virtio_blk_config {
 
        /* Zoned block device characteristics (if VIRTIO_BLK_F_ZONED) */
        struct virtio_blk_zoned_characteristics {
-               __le32 zone_sectors;
-               __le32 max_open_zones;
-               __le32 max_active_zones;
-               __le32 max_append_sectors;
-               __le32 write_granularity;
+               __virtio32 zone_sectors;
+               __virtio32 max_open_zones;
+               __virtio32 max_active_zones;
+               __virtio32 max_append_sectors;
+               __virtio32 write_granularity;
                __u8 model;
                __u8 unused2[3];
        } zoned;
@@ -241,11 +241,11 @@ struct virtio_blk_outhdr {
  */
 struct virtio_blk_zone_descriptor {
        /* Zone capacity */
-       __le64 z_cap;
+       __virtio64 z_cap;
        /* The starting sector of the zone */
-       __le64 z_start;
+       __virtio64 z_start;
        /* Zone write pointer position in sectors */
-       __le64 z_wp;
+       __virtio64 z_wp;
        /* Zone type */
        __u8 z_type;
        /* Zone state */
@@ -254,7 +254,7 @@ struct virtio_blk_zone_descriptor {
 };
 
 struct virtio_blk_zone_report {
-       __le64 nr_zones;
+       __virtio64 nr_zones;
        __u8 reserved[56];
        struct virtio_blk_zone_descriptor zones[];
 };
index 25aab8ec4f86be11780176b250c915ca73865b98..431c3afb2ce0f2048d6a50e77d90121ad8557239 100644 (file)
@@ -979,7 +979,6 @@ struct ufs_hba {
        struct completion *uic_async_done;
 
        enum ufshcd_state ufshcd_state;
-       bool logical_unit_scan_finished;
        u32 eh_flags;
        u32 intr_mask;
        u16 ee_ctrl_mask;
index 655d92e803e1498d35b9a96e2c2a7c645c6ba726..79a443c65ea93c0f93696aa83711ce64b138615b 100644 (file)
@@ -483,6 +483,8 @@ struct xenpf_symdata {
 };
 DEFINE_GUEST_HANDLE_STRUCT(xenpf_symdata);
 
+#define XENPF_get_dom0_console 64
+
 struct xen_platform_op {
        uint32_t cmd;
        uint32_t interface_version; /* XENPF_INTERFACE_VERSION */
@@ -506,6 +508,7 @@ struct xen_platform_op {
                struct xenpf_mem_hotadd        mem_add;
                struct xenpf_core_parking      core_parking;
                struct xenpf_symdata           symdata;
+               struct dom0_vga_console_info   dom0_console;
                uint8_t                        pad[128];
        } u;
 };
index 1fb5f313d18f0fa93739348c575b547be801ee40..c88bb30a8b0b026285d7905c812da9ee27e7bfff 100644 (file)
@@ -890,18 +890,14 @@ config CC_IMPLICIT_FALLTHROUGH
        default "-Wimplicit-fallthrough=5" if CC_IS_GCC && $(cc-option,-Wimplicit-fallthrough=5)
        default "-Wimplicit-fallthrough" if CC_IS_CLANG && $(cc-option,-Wunreachable-code-fallthrough)
 
-# Currently, disable gcc-11,12 array-bounds globally.
-# We may want to target only particular configurations some day.
+# Currently, disable gcc-11+ array-bounds globally.
+# It's still broken in gcc-13, so no upper bound yet.
 config GCC11_NO_ARRAY_BOUNDS
        def_bool y
 
-config GCC12_NO_ARRAY_BOUNDS
-       def_bool y
-
 config CC_NO_ARRAY_BOUNDS
        bool
-       default y if CC_IS_GCC && GCC_VERSION >= 110000 && GCC_VERSION < 120000 && GCC11_NO_ARRAY_BOUNDS
-       default y if CC_IS_GCC && GCC_VERSION >= 120000 && GCC_VERSION < 130000 && GCC12_NO_ARRAY_BOUNDS
+       default y if CC_IS_GCC && GCC_VERSION >= 110000 && GCC11_NO_ARRAY_BOUNDS
 
 #
 # For architectures that know their GCC __int128 support is sound
index f6c112e30bd47d9363086ea6f2154b1c7e2a0ccf..e7a01c2ccd1b0c33f795dd94a0c58ab57092bb93 100644 (file)
@@ -60,15 +60,8 @@ static void __init error(char *x)
                message = x;
 }
 
-static void panic_show_mem(const char *fmt, ...)
-{
-       va_list args;
-
-       show_mem(0, NULL);
-       va_start(args, fmt);
-       panic(fmt, args);
-       va_end(args);
-}
+#define panic_show_mem(fmt, ...) \
+       ({ show_mem(0, NULL); panic(fmt, ##__VA_ARGS__); })
 
 /* link hash */
 
index 4425d1783d5c21e8f1da703e503a5edc37a3d93f..123f50eb362b43806eb4e71297b76ff4e2e82f43 100644 (file)
@@ -156,7 +156,7 @@ static char *extra_init_args;
 
 #ifdef CONFIG_BOOT_CONFIG
 /* Is bootconfig on command line? */
-static bool bootconfig_found = IS_ENABLED(CONFIG_BOOT_CONFIG_FORCE);
+static bool bootconfig_found;
 static size_t initargs_offs;
 #else
 # define bootconfig_found false
@@ -429,7 +429,7 @@ static void __init setup_boot_config(void)
        err = parse_args("bootconfig", tmp_cmdline, NULL, 0, 0, 0, NULL,
                         bootconfig_params);
 
-       if (IS_ERR(err) || !bootconfig_found)
+       if (IS_ERR(err) || !(bootconfig_found || IS_ENABLED(CONFIG_BOOT_CONFIG_FORCE)))
                return;
 
        /* parse_args() stops at the next param of '--' and returns an address */
@@ -437,7 +437,11 @@ static void __init setup_boot_config(void)
                initargs_offs = err - tmp_cmdline;
 
        if (!data) {
-               pr_err("'bootconfig' found on command line, but no bootconfig found\n");
+               /* If user intended to use bootconfig, show an error level message */
+               if (bootconfig_found)
+                       pr_err("'bootconfig' found on command line, but no bootconfig found\n");
+               else
+                       pr_info("No bootconfig data provided, so skipping bootconfig");
                return;
        }
 
@@ -707,7 +711,7 @@ noinline void __ref rest_init(void)
        rcu_read_unlock();
 
        numa_default_policy();
-       pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
+       pid = kernel_thread(kthreadd, NULL, NULL, CLONE_FS | CLONE_FILES);
        rcu_read_lock();
        kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
        rcu_read_unlock();
index 729793ae97127a0d83c2df9864bcfe10130eee00..c2cde88aeed53f6e8d31438a83c10677a70d43f3 100644 (file)
@@ -27,6 +27,7 @@ static inline struct io_cache_entry *io_alloc_cache_get(struct io_alloc_cache *c
                struct hlist_node *node = cache->list.first;
 
                hlist_del(node);
+               cache->nr_cached--;
                return container_of(node, struct io_cache_entry, node);
        }
 
index 68dfc6936aa7250181a981dba6bb58e1ba6115d3..b80614e7d605112507363644c510d6312b65259d 100644 (file)
@@ -19,6 +19,9 @@ static int io_file_bitmap_get(struct io_ring_ctx *ctx)
        unsigned long nr = ctx->file_alloc_end;
        int ret;
 
+       if (!table->bitmap)
+               return -ENFILE;
+
        do {
                ret = find_next_zero_bit(table->bitmap, nr, table->alloc_hint);
                if (ret != nr)
index 411bb2d1acd452f6bb1af070dd338fd57fb6d3f7..f81c0a7136a5867b10cec91be62e0801b706560c 100644 (file)
@@ -616,7 +616,7 @@ static int io_wqe_worker(void *data)
        struct io_wqe_acct *acct = io_wqe_get_acct(worker);
        struct io_wqe *wqe = worker->wqe;
        struct io_wq *wq = wqe->wq;
-       bool last_timeout = false;
+       bool exit_mask = false, last_timeout = false;
        char buf[TASK_COMM_LEN];
 
        worker->flags |= (IO_WORKER_F_UP | IO_WORKER_F_RUNNING);
@@ -632,8 +632,11 @@ static int io_wqe_worker(void *data)
                        io_worker_handle_work(worker);
 
                raw_spin_lock(&wqe->lock);
-               /* timed out, exit unless we're the last worker */
-               if (last_timeout && acct->nr_workers > 1) {
+               /*
+                * Last sleep timed out. Exit if we're not the last worker,
+                * or if someone modified our affinity.
+                */
+               if (last_timeout && (exit_mask || acct->nr_workers > 1)) {
                        acct->nr_workers--;
                        raw_spin_unlock(&wqe->lock);
                        __set_current_state(TASK_RUNNING);
@@ -652,7 +655,11 @@ static int io_wqe_worker(void *data)
                                continue;
                        break;
                }
-               last_timeout = !ret;
+               if (!ret) {
+                       last_timeout = true;
+                       exit_mask = !cpumask_test_cpu(raw_smp_processor_id(),
+                                                       wqe->cpu_mask);
+               }
        }
 
        if (test_bit(IO_WQ_BIT_EXIT, &wq->state))
@@ -704,7 +711,6 @@ static void io_init_new_worker(struct io_wqe *wqe, struct io_worker *worker,
        tsk->worker_private = worker;
        worker->task = tsk;
        set_cpus_allowed_ptr(tsk, wqe->cpu_mask);
-       tsk->flags |= PF_NO_SETAFFINITY;
 
        raw_spin_lock(&wqe->lock);
        hlist_nulls_add_head_rcu(&worker->nulls_node, &wqe->free_list);
index fd1cc35a1c00b67cc02fb8cf1f4421f933c43419..4a865f0e85d0b8116c6ef3bd37b5f6db4af29835 100644 (file)
@@ -998,7 +998,7 @@ static void __io_req_complete_post(struct io_kiocb *req)
 
 void io_req_complete_post(struct io_kiocb *req, unsigned issue_flags)
 {
-       if (req->ctx->task_complete && (issue_flags & IO_URING_F_IOWQ)) {
+       if (req->ctx->task_complete && req->ctx->submitter_task != current) {
                req->io_task_work.func = io_req_task_complete;
                io_req_task_work_add(req);
        } else if (!(issue_flags & IO_URING_F_UNLOCKED) ||
@@ -1499,14 +1499,14 @@ void io_free_batch_list(struct io_ring_ctx *ctx, struct io_wq_work_node *node)
 static void __io_submit_flush_completions(struct io_ring_ctx *ctx)
        __must_hold(&ctx->uring_lock)
 {
-       struct io_wq_work_node *node, *prev;
        struct io_submit_state *state = &ctx->submit_state;
+       struct io_wq_work_node *node;
 
        __io_cq_lock(ctx);
        /* must come first to preserve CQE ordering in failure cases */
        if (state->cqes_count)
                __io_flush_post_cqes(ctx);
-       wq_list_for_each(node, prev, &state->compl_reqs) {
+       __wq_list_for_each(node, &state->compl_reqs) {
                struct io_kiocb *req = container_of(node, struct io_kiocb,
                                            comp_list);
 
@@ -2789,8 +2789,8 @@ static __cold void io_ring_ctx_free(struct io_ring_ctx *ctx)
        io_eventfd_unregister(ctx);
        io_alloc_cache_free(&ctx->apoll_cache, io_apoll_cache_free);
        io_alloc_cache_free(&ctx->netmsg_cache, io_netmsg_cache_free);
-       mutex_unlock(&ctx->uring_lock);
        io_destroy_buffers(ctx);
+       mutex_unlock(&ctx->uring_lock);
        if (ctx->sq_creds)
                put_cred(ctx->sq_creds);
        if (ctx->submitter_task)
index 3002dc827195916b160fce8376de009feb86f3c5..a90c820ce99e12e5e72d37dee4fefd2d24665c3a 100644 (file)
@@ -228,17 +228,18 @@ static int __io_remove_buffers(struct io_ring_ctx *ctx,
                return i;
        }
 
-       /* the head kbuf is the list itself */
+       /* protects io_buffers_cache */
+       lockdep_assert_held(&ctx->uring_lock);
+
        while (!list_empty(&bl->buf_list)) {
                struct io_buffer *nxt;
 
                nxt = list_first_entry(&bl->buf_list, struct io_buffer, list);
-               list_del(&nxt->list);
+               list_move(&nxt->list, &ctx->io_buffers_cache);
                if (++i == nbufs)
                        return i;
                cond_resched();
        }
-       i++;
 
        return i;
 }
index 8803c0979e2a91345d5dc1c29da1686a224c241d..85fd7ce5f05b85f10fc8ab91af8b428629356140 100644 (file)
@@ -202,7 +202,7 @@ static int io_msg_install_complete(struct io_kiocb *req, unsigned int issue_flag
         * completes with -EOVERFLOW, then the sender must ensure that a
         * later IORING_OP_MSG_RING delivers the message.
         */
-       if (!io_post_aux_cqe(target_ctx, msg->user_data, msg->len, 0))
+       if (!io_post_aux_cqe(target_ctx, msg->user_data, ret, 0))
                ret = -EOVERFLOW;
 out_unlock:
        io_double_unlock_ctx(target_ctx);
@@ -229,6 +229,8 @@ static int io_msg_send_fd(struct io_kiocb *req, unsigned int issue_flags)
        struct io_ring_ctx *ctx = req->ctx;
        struct file *src_file = msg->src_file;
 
+       if (msg->len)
+               return -EINVAL;
        if (target_ctx == ctx)
                return -EINVAL;
        if (target_ctx->flags & IORING_SETUP_R_DISABLED)
index b7f190ca528e6e259eb2b072d7a16aaba98848cb..89e839013837ffd34947076ae7e9be54e1b1cfc7 100644 (file)
@@ -47,6 +47,7 @@ struct io_connect {
        struct sockaddr __user          *addr;
        int                             addr_len;
        bool                            in_progress;
+       bool                            seen_econnaborted;
 };
 
 struct io_sr_msg {
@@ -183,8 +184,8 @@ static int io_setup_async_msg(struct io_kiocb *req,
                async_msg->msg.msg_name = &async_msg->addr;
        /* if were using fast_iov, set it to the new one */
        if (iter_is_iovec(&kmsg->msg.msg_iter) && !kmsg->free_iov) {
-               size_t fast_idx = kmsg->msg.msg_iter.iov - kmsg->fast_iov;
-               async_msg->msg.msg_iter.iov = &async_msg->fast_iov[fast_idx];
+               size_t fast_idx = iter_iov(&kmsg->msg.msg_iter) - kmsg->fast_iov;
+               async_msg->msg.msg_iter.__iov = &async_msg->fast_iov[fast_idx];
        }
 
        return -EAGAIN;
@@ -1424,7 +1425,7 @@ int io_connect_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 
        conn->addr = u64_to_user_ptr(READ_ONCE(sqe->addr));
        conn->addr_len =  READ_ONCE(sqe->addr2);
-       conn->in_progress = false;
+       conn->in_progress = conn->seen_econnaborted = false;
        return 0;
 }
 
@@ -1461,18 +1462,24 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags)
 
        ret = __sys_connect_file(req->file, &io->address,
                                        connect->addr_len, file_flags);
-       if ((ret == -EAGAIN || ret == -EINPROGRESS) && force_nonblock) {
+       if ((ret == -EAGAIN || ret == -EINPROGRESS || ret == -ECONNABORTED)
+           && force_nonblock) {
                if (ret == -EINPROGRESS) {
                        connect->in_progress = true;
-               } else {
-                       if (req_has_async_data(req))
-                               return -EAGAIN;
-                       if (io_alloc_async_data(req)) {
-                               ret = -ENOMEM;
+                       return -EAGAIN;
+               }
+               if (ret == -ECONNABORTED) {
+                       if (connect->seen_econnaborted)
                                goto out;
-                       }
-                       memcpy(req->async_data, &__io, sizeof(__io));
+                       connect->seen_econnaborted = true;
+               }
+               if (req_has_async_data(req))
+                       return -EAGAIN;
+               if (io_alloc_async_data(req)) {
+                       ret = -ENOMEM;
+                       goto out;
                }
+               memcpy(req->async_data, &__io, sizeof(__io));
                return -EAGAIN;
        }
        if (ret == -ERESTARTSYS)
index 795facbd0e9f174ab4af7bbd1444b4eaedeb29da..55306e801081376acb380487fed2308e09a0f1d9 100644 (file)
@@ -726,6 +726,7 @@ int io_arm_poll_handler(struct io_kiocb *req, unsigned issue_flags)
        apoll = io_req_alloc_apoll(req, issue_flags);
        if (!apoll)
                return IO_APOLL_ABORTED;
+       req->flags &= ~(REQ_F_SINGLE_POLL | REQ_F_DOUBLE_POLL);
        req->flags |= REQ_F_POLLED;
        ipt.pt._qproc = io_async_queue_proc;
 
index 056f40946ff68ff8d2d72781c5bdc9e3e303cea4..7a43aed8e395cb4d22885e0800bf193c862f0b1f 100644 (file)
@@ -410,7 +410,7 @@ __cold static int io_rsrc_data_alloc(struct io_ring_ctx *ctx,
                                     unsigned nr, struct io_rsrc_data **pdata)
 {
        struct io_rsrc_data *data;
-       int ret = -ENOMEM;
+       int ret = 0;
        unsigned i;
 
        data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -794,6 +794,7 @@ void __io_sqe_files_unregister(struct io_ring_ctx *ctx)
        }
 #endif
        io_free_file_tables(&ctx->file_table);
+       io_file_table_set_alloc_range(ctx, 0, 0);
        io_rsrc_data_free(ctx->file_data);
        ctx->file_data = NULL;
        ctx->nr_user_files = 0;
@@ -1235,7 +1236,13 @@ static int io_sqe_buffer_register(struct io_ring_ctx *ctx, struct iovec *iov,
                        }
                }
                if (folio) {
-                       folio_put_refs(folio, nr_pages - 1);
+                       /*
+                        * The pages are bound to the folio, it doesn't
+                        * actually unpin them but drops all but one reference,
+                        * which is usually put down by io_buffer_unmap().
+                        * Note, needs a better helper.
+                        */
+                       unpin_user_pages(&pages[1], nr_pages - 1);
                        nr_pages = 1;
                }
        }
index 2b8743645efcbd5d29709fbd2ecff2b6d51e86f3..f27f4975217d94ada42a3474fe5da0b04285eb3c 100644 (file)
@@ -144,15 +144,13 @@ static inline void io_req_set_rsrc_node(struct io_kiocb *req,
                                        unsigned int issue_flags)
 {
        if (!req->rsrc_node) {
-               req->rsrc_node = ctx->rsrc_node;
+               io_ring_submit_lock(ctx, issue_flags);
 
-               if (!(issue_flags & IO_URING_F_UNLOCKED)) {
-                       lockdep_assert_held(&ctx->uring_lock);
+               lockdep_assert_held(&ctx->uring_lock);
 
-                       io_charge_rsrc_node(ctx);
-               } else {
-                       percpu_ref_get(&req->rsrc_node->refs);
-               }
+               req->rsrc_node = ctx->rsrc_node;
+               io_charge_rsrc_node(ctx);
+               io_ring_submit_unlock(ctx, issue_flags);
        }
 }
 
index 4c233910e20097e2833c9e3a6c2f78995c2b7947..f33ba6f282474c2e24f589b42aa30530b1f7c3f0 100644 (file)
@@ -447,26 +447,25 @@ static ssize_t loop_rw_iter(int ddir, struct io_rw *rw, struct iov_iter *iter)
        ppos = io_kiocb_ppos(kiocb);
 
        while (iov_iter_count(iter)) {
-               struct iovec iovec;
+               void __user *addr;
+               size_t len;
                ssize_t nr;
 
                if (iter_is_ubuf(iter)) {
-                       iovec.iov_base = iter->ubuf + iter->iov_offset;
-                       iovec.iov_len = iov_iter_count(iter);
+                       addr = iter->ubuf + iter->iov_offset;
+                       len = iov_iter_count(iter);
                } else if (!iov_iter_is_bvec(iter)) {
-                       iovec = iov_iter_iovec(iter);
+                       addr = iter_iov_addr(iter);
+                       len = iter_iov_len(iter);
                } else {
-                       iovec.iov_base = u64_to_user_ptr(rw->addr);
-                       iovec.iov_len = rw->len;
+                       addr = u64_to_user_ptr(rw->addr);
+                       len = rw->len;
                }
 
-               if (ddir == READ) {
-                       nr = file->f_op->read(file, iovec.iov_base,
-                                             iovec.iov_len, ppos);
-               } else {
-                       nr = file->f_op->write(file, iovec.iov_base,
-                                              iovec.iov_len, ppos);
-               }
+               if (ddir == READ)
+                       nr = file->f_op->read(file, addr, len, ppos);
+               else
+                       nr = file->f_op->write(file, addr, len, ppos);
 
                if (nr < 0) {
                        if (!ret)
@@ -482,7 +481,7 @@ static ssize_t loop_rw_iter(int ddir, struct io_rw *rw, struct iov_iter *iter)
                        if (!rw->len)
                                break;
                }
-               if (nr != iovec.iov_len)
+               if (nr != len)
                        break;
        }
 
@@ -503,10 +502,10 @@ static void io_req_map_rw(struct io_kiocb *req, const struct iovec *iovec,
        if (!iovec) {
                unsigned iov_off = 0;
 
-               io->s.iter.iov = io->s.fast_iov;
-               if (iter->iov != fast_iov) {
-                       iov_off = iter->iov - fast_iov;
-                       io->s.iter.iov += iov_off;
+               io->s.iter.__iov = io->s.fast_iov;
+               if (iter->__iov != fast_iov) {
+                       iov_off = iter_iov(iter) - fast_iov;
+                       io->s.iter.__iov += iov_off;
                }
                if (io->s.fast_iov != fast_iov)
                        memcpy(io->s.fast_iov + iov_off, fast_iov + iov_off,
index 7c198a40d5f11d799e49441aefc9034cc71169f5..0eb194817242e5eb98e83077a195209a053e4eab 100644 (file)
@@ -3,6 +3,9 @@
 
 #include <linux/io_uring_types.h>
 
+#define __wq_list_for_each(pos, head)                          \
+       for (pos = (head)->first; pos; pos = (pos)->next)
+
 #define wq_list_for_each(pos, prv, head)                       \
        for (pos = (head)->first, prv = NULL; pos; prv = pos, pos = (pos)->next)
 
@@ -113,4 +116,4 @@ static inline struct io_wq_work *wq_next_work(struct io_wq_work *work)
        return container_of(work->list.next, struct io_wq_work, list);
 }
 
-#endif // INTERNAL_IO_SLIST_H
\ No newline at end of file
+#endif // INTERNAL_IO_SLIST_H
index 0119d3f1a55698a9958d26d9baadb68e3028141a..9db4bc1f521a3162d3480000cdc82e9a1aacfe62 100644 (file)
@@ -233,7 +233,6 @@ static int io_sq_thread(void *data)
                set_cpus_allowed_ptr(current, cpumask_of(sqd->sq_cpu));
        else
                set_cpus_allowed_ptr(current, cpu_online_mask);
-       current->flags |= PF_NO_SETAFFINITY;
 
        mutex_lock(&sqd->lock);
        while (1) {
index 446a189b78b037ceb4b272ff02180ec9a3539f17..9a1dee5718724a109461560b39fc789132d6a13b 100644 (file)
 static void io_uring_cmd_work(struct io_kiocb *req, bool *locked)
 {
        struct io_uring_cmd *ioucmd = io_kiocb_to_cmd(req, struct io_uring_cmd);
+       unsigned issue_flags = *locked ? 0 : IO_URING_F_UNLOCKED;
 
-       ioucmd->task_work_cb(ioucmd);
+       ioucmd->task_work_cb(ioucmd, issue_flags);
 }
 
 void io_uring_cmd_complete_in_task(struct io_uring_cmd *ioucmd,
-                       void (*task_work_cb)(struct io_uring_cmd *))
+                       void (*task_work_cb)(struct io_uring_cmd *, unsigned))
 {
        struct io_kiocb *req = cmd_to_io_kiocb(ioucmd);
 
@@ -42,7 +43,8 @@ static inline void io_req_set_cqe32_extra(struct io_kiocb *req,
  * Called by consumers of io_uring_cmd, if they originally returned
  * -EIOCBQUEUED upon receiving the command.
  */
-void io_uring_cmd_done(struct io_uring_cmd *ioucmd, ssize_t ret, ssize_t res2)
+void io_uring_cmd_done(struct io_uring_cmd *ioucmd, ssize_t ret, ssize_t res2,
+                      unsigned issue_flags)
 {
        struct io_kiocb *req = cmd_to_io_kiocb(ioucmd);
 
@@ -56,7 +58,7 @@ void io_uring_cmd_done(struct io_uring_cmd *ioucmd, ssize_t ret, ssize_t res2)
                /* order with io_iopoll_req_issued() checking ->iopoll_complete */
                smp_store_release(&req->iopoll_completed, 1);
        else
-               io_req_complete_post(req, 0);
+               io_req_complete_post(req, issue_flags);
 }
 EXPORT_SYMBOL_GPL(io_uring_cmd_done);
 
@@ -108,7 +110,7 @@ int io_uring_cmd(struct io_kiocb *req, unsigned int issue_flags)
        struct file *file = req->file;
        int ret;
 
-       if (!req->file->f_op->uring_cmd)
+       if (!file->f_op->uring_cmd)
                return -EOPNOTSUPP;
 
        ret = security_uring_cmd(ioucmd);
@@ -120,6 +122,8 @@ int io_uring_cmd(struct io_kiocb *req, unsigned int issue_flags)
        if (ctx->flags & IORING_SETUP_CQE32)
                issue_flags |= IO_URING_F_CQE32;
        if (ctx->flags & IORING_SETUP_IOPOLL) {
+               if (!file->f_op->uring_cmd_iopoll)
+                       return -EOPNOTSUPP;
                issue_flags |= IO_URING_F_IOPOLL;
                req->iopoll_completed = 0;
                WRITE_ONCE(ioucmd->cookie, NULL);
index 10ef068f598d5db37a00f951f057c90b61e04326..6fc72b3afbde10c420317764fd12e0ec77446711 100644 (file)
@@ -15,6 +15,7 @@ obj-y     = fork.o exec_domain.o panic.o \
 obj-$(CONFIG_USERMODE_DRIVER) += usermode_driver.o
 obj-$(CONFIG_MODULES) += kmod.o
 obj-$(CONFIG_MULTIUSER) += groups.o
+obj-$(CONFIG_VHOST_TASK) += vhost_task.o
 
 ifdef CONFIG_FUNCTION_TRACER
 # Do not trace internal ftrace files
index 05f4c66c9089f69a40365651d5d490bcb40313bf..85720311cc6747f3c3e1d1fef0005ecf0eacbed0 100644 (file)
@@ -84,16 +84,13 @@ void bpf_inode_storage_free(struct inode *inode)
 static void *bpf_fd_inode_storage_lookup_elem(struct bpf_map *map, void *key)
 {
        struct bpf_local_storage_data *sdata;
-       struct file *f;
-       int fd;
+       struct fd f = fdget_raw(*(int *)key);
 
-       fd = *(int *)key;
-       f = fget_raw(fd);
-       if (!f)
+       if (!f.file)
                return ERR_PTR(-EBADF);
 
-       sdata = inode_storage_lookup(f->f_inode, map, true);
-       fput(f);
+       sdata = inode_storage_lookup(file_inode(f.file), map, true);
+       fdput(f);
        return sdata ? sdata->data : NULL;
 }
 
@@ -101,22 +98,19 @@ static int bpf_fd_inode_storage_update_elem(struct bpf_map *map, void *key,
                                         void *value, u64 map_flags)
 {
        struct bpf_local_storage_data *sdata;
-       struct file *f;
-       int fd;
+       struct fd f = fdget_raw(*(int *)key);
 
-       fd = *(int *)key;
-       f = fget_raw(fd);
-       if (!f)
+       if (!f.file)
                return -EBADF;
-       if (!inode_storage_ptr(f->f_inode)) {
-               fput(f);
+       if (!inode_storage_ptr(file_inode(f.file))) {
+               fdput(f);
                return -EBADF;
        }
 
-       sdata = bpf_local_storage_update(f->f_inode,
+       sdata = bpf_local_storage_update(file_inode(f.file),
                                         (struct bpf_local_storage_map *)map,
                                         value, map_flags, GFP_ATOMIC);
-       fput(f);
+       fdput(f);
        return PTR_ERR_OR_ZERO(sdata);
 }
 
@@ -135,16 +129,14 @@ static int inode_storage_delete(struct inode *inode, struct bpf_map *map)
 
 static int bpf_fd_inode_storage_delete_elem(struct bpf_map *map, void *key)
 {
-       struct file *f;
-       int fd, err;
+       struct fd f = fdget_raw(*(int *)key);
+       int err;
 
-       fd = *(int *)key;
-       f = fget_raw(fd);
-       if (!f)
+       if (!f.file)
                return -EBADF;
 
-       err = inode_storage_delete(f->f_inode, map);
-       fput(f);
+       err = inode_storage_delete(file_inode(f.file), map);
+       fdput(f);
        return err;
 }
 
index fa22ec79ac0e1cea56932e64fdb4150770c6968c..73780748404c29bfd6b4d2284b2aff615093497f 100644 (file)
@@ -4569,6 +4569,7 @@ static int btf_datasec_resolve(struct btf_verifier_env *env,
        struct btf *btf = env->btf;
        u16 i;
 
+       env->resolve_mode = RESOLVE_TBD;
        for_each_vsi_from(i, v->next_member, v->t, vsi) {
                u32 var_type_id = vsi->type, type_id, type_size = 0;
                const struct btf_type *var_type = btf_type_by_id(env->btf,
index b297e9f60ca1015ec0d788b54f6381b2e9140d6a..e2d256c820723ffb7f2264fc45bfcbc841036974 100644 (file)
@@ -972,7 +972,7 @@ static int __init bpf_jit_charge_init(void)
 {
        /* Only used as heuristic here to derive limit. */
        bpf_jit_limit_max = bpf_jit_alloc_exec_limit();
-       bpf_jit_limit = min_t(u64, round_up(bpf_jit_limit_max >> 2,
+       bpf_jit_limit = min_t(u64, round_up(bpf_jit_limit_max >> 1,
                                            PAGE_SIZE), LONG_MAX);
        return 0;
 }
index 272563a0b7702a98f4060be952b85570934e210c..767e8930b0bd5da90cdde093461c7442257b2666 100644 (file)
@@ -2967,6 +2967,21 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx,
                        }
                } else if (opcode == BPF_EXIT) {
                        return -ENOTSUPP;
+               } else if (BPF_SRC(insn->code) == BPF_X) {
+                       if (!(*reg_mask & (dreg | sreg)))
+                               return 0;
+                       /* dreg <cond> sreg
+                        * Both dreg and sreg need precision before
+                        * this insn. If only sreg was marked precise
+                        * before it would be equally necessary to
+                        * propagate it to dreg.
+                        */
+                       *reg_mask |= (sreg | dreg);
+                        /* else dreg <cond> K
+                         * Only dreg still needs precision before
+                         * this insn, so for the K-based conditional
+                         * there is nothing new to be marked.
+                         */
                }
        } else if (class == BPF_LD) {
                if (!(*reg_mask & dreg))
@@ -3826,6 +3841,8 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
                                                continue;
                                        if (type == STACK_MISC)
                                                continue;
+                                       if (type == STACK_INVALID && env->allow_uninit_stack)
+                                               continue;
                                        verbose(env, "invalid read from stack off %d+%d size %d\n",
                                                off, i, size);
                                        return -EACCES;
@@ -3863,6 +3880,8 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
                                continue;
                        if (type == STACK_ZERO)
                                continue;
+                       if (type == STACK_INVALID && env->allow_uninit_stack)
+                               continue;
                        verbose(env, "invalid read from stack off %d+%d size %d\n",
                                off, i, size);
                        return -EACCES;
@@ -5754,7 +5773,8 @@ static int check_stack_range_initialized(
                stype = &state->stack[spi].slot_type[slot % BPF_REG_SIZE];
                if (*stype == STACK_MISC)
                        goto mark;
-               if (*stype == STACK_ZERO) {
+               if ((*stype == STACK_ZERO) ||
+                   (*stype == STACK_INVALID && env->allow_uninit_stack)) {
                        if (clobber) {
                                /* helper can write anything into the stack */
                                *stype = STACK_MISC;
@@ -13936,6 +13956,10 @@ static bool stacksafe(struct bpf_verifier_env *env, struct bpf_func_state *old,
                if (old->stack[spi].slot_type[i % BPF_REG_SIZE] == STACK_INVALID)
                        continue;
 
+               if (env->allow_uninit_stack &&
+                   old->stack[spi].slot_type[i % BPF_REG_SIZE] == STACK_MISC)
+                       continue;
+
                /* explored stack has more populated slots than current stack
                 * and these slots were used
                 */
index 935e8121b21e67063d32c839b0d3a340b9915176..4b249f81c6933b2499c1f968972211973ba4a087 100644 (file)
@@ -6856,14 +6856,12 @@ EXPORT_SYMBOL_GPL(cgroup_get_from_path);
 struct cgroup *cgroup_v1v2_get_from_fd(int fd)
 {
        struct cgroup *cgrp;
-       struct file *f;
-
-       f = fget_raw(fd);
-       if (!f)
+       struct fd f = fdget_raw(fd);
+       if (!f.file)
                return ERR_PTR(-EBADF);
 
-       cgrp = cgroup_v1v2_get_from_file(f);
-       fput(f);
+       cgrp = cgroup_v1v2_get_from_file(f.file);
+       fdput(f);
        return cgrp;
 }
 
index 636f1c682ac07a86668b186e808c5b1b98f70a6b..505d86b166426e46dd3549683c7b74d614d02af7 100644 (file)
@@ -1513,7 +1513,7 @@ static int update_parent_subparts_cpumask(struct cpuset *cs, int cmd,
        spin_unlock_irq(&callback_lock);
 
        if (adding || deleting)
-               update_tasks_cpumask(parent, tmp->new_cpus);
+               update_tasks_cpumask(parent, tmp->addmask);
 
        /*
         * Set or clear CS_SCHED_LOAD_BALANCE when partcmd_update, if necessary.
@@ -1770,10 +1770,13 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
        /*
         * Use the cpumasks in trialcs for tmpmasks when they are pointers
         * to allocated cpumasks.
+        *
+        * Note that update_parent_subparts_cpumask() uses only addmask &
+        * delmask, but not new_cpus.
         */
        tmp.addmask  = trialcs->subparts_cpus;
        tmp.delmask  = trialcs->effective_cpus;
-       tmp.new_cpus = trialcs->cpus_allowed;
+       tmp.new_cpus = NULL;
 #endif
 
        retval = validate_change(cs, trialcs);
@@ -1838,6 +1841,11 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
        }
        spin_unlock_irq(&callback_lock);
 
+#ifdef CONFIG_CPUMASK_OFFSTACK
+       /* Now trialcs->cpus_allowed is available */
+       tmp.new_cpus = trialcs->cpus_allowed;
+#endif
+
        /* effective_cpus will be updated here */
        update_cpumasks_hier(cs, &tmp, false);
 
@@ -2445,6 +2453,20 @@ static int fmeter_getrate(struct fmeter *fmp)
 
 static struct cpuset *cpuset_attach_old_cs;
 
+/*
+ * Check to see if a cpuset can accept a new task
+ * For v1, cpus_allowed and mems_allowed can't be empty.
+ * For v2, effective_cpus can't be empty.
+ * Note that in v1, effective_cpus = cpus_allowed.
+ */
+static int cpuset_can_attach_check(struct cpuset *cs)
+{
+       if (cpumask_empty(cs->effective_cpus) ||
+          (!is_in_v2_mode() && nodes_empty(cs->mems_allowed)))
+               return -ENOSPC;
+       return 0;
+}
+
 /* Called by cgroups to determine if a cpuset is usable; cpuset_rwsem held */
 static int cpuset_can_attach(struct cgroup_taskset *tset)
 {
@@ -2459,16 +2481,9 @@ static int cpuset_can_attach(struct cgroup_taskset *tset)
 
        percpu_down_write(&cpuset_rwsem);
 
-       /* allow moving tasks into an empty cpuset if on default hierarchy */
-       ret = -ENOSPC;
-       if (!is_in_v2_mode() &&
-           (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed)))
-               goto out_unlock;
-
-       /*
-        * Task cannot be moved to a cpuset with empty effective cpus.
-        */
-       if (cpumask_empty(cs->effective_cpus))
+       /* Check to see if task is allowed in the cpuset */
+       ret = cpuset_can_attach_check(cs);
+       if (ret)
                goto out_unlock;
 
        cgroup_taskset_for_each(task, css, tset) {
@@ -2485,7 +2500,6 @@ static int cpuset_can_attach(struct cgroup_taskset *tset)
         * changes which zero cpus/mems_allowed.
         */
        cs->attach_in_progress++;
-       ret = 0;
 out_unlock:
        percpu_up_write(&cpuset_rwsem);
        return ret;
@@ -2494,25 +2508,47 @@ out_unlock:
 static void cpuset_cancel_attach(struct cgroup_taskset *tset)
 {
        struct cgroup_subsys_state *css;
+       struct cpuset *cs;
 
        cgroup_taskset_first(tset, &css);
+       cs = css_cs(css);
 
        percpu_down_write(&cpuset_rwsem);
-       css_cs(css)->attach_in_progress--;
+       cs->attach_in_progress--;
+       if (!cs->attach_in_progress)
+               wake_up(&cpuset_attach_wq);
        percpu_up_write(&cpuset_rwsem);
 }
 
 /*
- * Protected by cpuset_rwsem.  cpus_attach is used only by cpuset_attach()
+ * Protected by cpuset_rwsem. cpus_attach is used only by cpuset_attach_task()
  * but we can't allocate it dynamically there.  Define it global and
  * allocate from cpuset_init().
  */
 static cpumask_var_t cpus_attach;
+static nodemask_t cpuset_attach_nodemask_to;
+
+static void cpuset_attach_task(struct cpuset *cs, struct task_struct *task)
+{
+       percpu_rwsem_assert_held(&cpuset_rwsem);
+
+       if (cs != &top_cpuset)
+               guarantee_online_cpus(task, cpus_attach);
+       else
+               cpumask_andnot(cpus_attach, task_cpu_possible_mask(task),
+                              cs->subparts_cpus);
+       /*
+        * can_attach beforehand should guarantee that this doesn't
+        * fail.  TODO: have a better way to handle failure here
+        */
+       WARN_ON_ONCE(set_cpus_allowed_ptr(task, cpus_attach));
+
+       cpuset_change_task_nodemask(task, &cpuset_attach_nodemask_to);
+       cpuset_update_task_spread_flags(cs, task);
+}
 
 static void cpuset_attach(struct cgroup_taskset *tset)
 {
-       /* static buf protected by cpuset_rwsem */
-       static nodemask_t cpuset_attach_nodemask_to;
        struct task_struct *task;
        struct task_struct *leader;
        struct cgroup_subsys_state *css;
@@ -2543,20 +2579,8 @@ static void cpuset_attach(struct cgroup_taskset *tset)
 
        guarantee_online_mems(cs, &cpuset_attach_nodemask_to);
 
-       cgroup_taskset_for_each(task, css, tset) {
-               if (cs != &top_cpuset)
-                       guarantee_online_cpus(task, cpus_attach);
-               else
-                       cpumask_copy(cpus_attach, task_cpu_possible_mask(task));
-               /*
-                * can_attach beforehand should guarantee that this doesn't
-                * fail.  TODO: have a better way to handle failure here
-                */
-               WARN_ON_ONCE(set_cpus_allowed_ptr(task, cpus_attach));
-
-               cpuset_change_task_nodemask(task, &cpuset_attach_nodemask_to);
-               cpuset_update_task_spread_flags(cs, task);
-       }
+       cgroup_taskset_for_each(task, css, tset)
+               cpuset_attach_task(cs, task);
 
        /*
         * Change mm for all threadgroup leaders. This is expensive and may
@@ -3247,6 +3271,68 @@ static void cpuset_bind(struct cgroup_subsys_state *root_css)
        percpu_up_write(&cpuset_rwsem);
 }
 
+/*
+ * In case the child is cloned into a cpuset different from its parent,
+ * additional checks are done to see if the move is allowed.
+ */
+static int cpuset_can_fork(struct task_struct *task, struct css_set *cset)
+{
+       struct cpuset *cs = css_cs(cset->subsys[cpuset_cgrp_id]);
+       bool same_cs;
+       int ret;
+
+       rcu_read_lock();
+       same_cs = (cs == task_cs(current));
+       rcu_read_unlock();
+
+       if (same_cs)
+               return 0;
+
+       lockdep_assert_held(&cgroup_mutex);
+       percpu_down_write(&cpuset_rwsem);
+
+       /* Check to see if task is allowed in the cpuset */
+       ret = cpuset_can_attach_check(cs);
+       if (ret)
+               goto out_unlock;
+
+       ret = task_can_attach(task, cs->effective_cpus);
+       if (ret)
+               goto out_unlock;
+
+       ret = security_task_setscheduler(task);
+       if (ret)
+               goto out_unlock;
+
+       /*
+        * Mark attach is in progress.  This makes validate_change() fail
+        * changes which zero cpus/mems_allowed.
+        */
+       cs->attach_in_progress++;
+out_unlock:
+       percpu_up_write(&cpuset_rwsem);
+       return ret;
+}
+
+static void cpuset_cancel_fork(struct task_struct *task, struct css_set *cset)
+{
+       struct cpuset *cs = css_cs(cset->subsys[cpuset_cgrp_id]);
+       bool same_cs;
+
+       rcu_read_lock();
+       same_cs = (cs == task_cs(current));
+       rcu_read_unlock();
+
+       if (same_cs)
+               return;
+
+       percpu_down_write(&cpuset_rwsem);
+       cs->attach_in_progress--;
+       if (!cs->attach_in_progress)
+               wake_up(&cpuset_attach_wq);
+       percpu_up_write(&cpuset_rwsem);
+}
+
 /*
  * Make sure the new task conform to the current state of its parent,
  * which could have been changed by cpuset just after it inherits the
@@ -3254,11 +3340,33 @@ static void cpuset_bind(struct cgroup_subsys_state *root_css)
  */
 static void cpuset_fork(struct task_struct *task)
 {
-       if (task_css_is_root(task, cpuset_cgrp_id))
+       struct cpuset *cs;
+       bool same_cs;
+
+       rcu_read_lock();
+       cs = task_cs(task);
+       same_cs = (cs == task_cs(current));
+       rcu_read_unlock();
+
+       if (same_cs) {
+               if (cs == &top_cpuset)
+                       return;
+
+               set_cpus_allowed_ptr(task, current->cpus_ptr);
+               task->mems_allowed = current->mems_allowed;
                return;
+       }
+
+       /* CLONE_INTO_CGROUP */
+       percpu_down_write(&cpuset_rwsem);
+       guarantee_online_mems(cs, &cpuset_attach_nodemask_to);
+       cpuset_attach_task(cs, task);
+
+       cs->attach_in_progress--;
+       if (!cs->attach_in_progress)
+               wake_up(&cpuset_attach_wq);
 
-       set_cpus_allowed_ptr(task, current->cpus_ptr);
-       task->mems_allowed = current->mems_allowed;
+       percpu_up_write(&cpuset_rwsem);
 }
 
 struct cgroup_subsys cpuset_cgrp_subsys = {
@@ -3271,6 +3379,8 @@ struct cgroup_subsys cpuset_cgrp_subsys = {
        .attach         = cpuset_attach,
        .post_attach    = cpuset_post_attach,
        .bind           = cpuset_bind,
+       .can_fork       = cpuset_can_fork,
+       .cancel_fork    = cpuset_cancel_fork,
        .fork           = cpuset_fork,
        .legacy_cftypes = legacy_files,
        .dfl_cftypes    = dfl_files,
index 1b6b21851e9d47daa3456123d604ab4d5e0f3b9c..936473203a6b511c2fa095a04ba219282913ab6a 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/freezer.h>
 #include <linux/seq_file.h>
 #include <linux/mutex.h>
+#include <linux/cpu.h>
 
 /*
  * A cgroup is freezing if any FREEZING flags are set.  FREEZING_SELF is
@@ -350,7 +351,7 @@ static void freezer_apply_state(struct freezer *freezer, bool freeze,
 
        if (freeze) {
                if (!(freezer->state & CGROUP_FREEZING))
-                       static_branch_inc(&freezer_active);
+                       static_branch_inc_cpuslocked(&freezer_active);
                freezer->state |= state;
                freeze_cgroup(freezer);
        } else {
@@ -361,7 +362,7 @@ static void freezer_apply_state(struct freezer *freezer, bool freeze,
                if (!(freezer->state & CGROUP_FREEZING)) {
                        freezer->state &= ~CGROUP_FROZEN;
                        if (was_freezing)
-                               static_branch_dec(&freezer_active);
+                               static_branch_dec_cpuslocked(&freezer_active);
                        unfreeze_cgroup(freezer);
                }
        }
@@ -379,6 +380,7 @@ static void freezer_change_state(struct freezer *freezer, bool freeze)
 {
        struct cgroup_subsys_state *pos;
 
+       cpus_read_lock();
        /*
         * Update all its descendants in pre-order traversal.  Each
         * descendant will try to inherit its parent's FREEZING state as
@@ -407,6 +409,7 @@ static void freezer_change_state(struct freezer *freezer, bool freeze)
        }
        rcu_read_unlock();
        mutex_unlock(&freezer_mutex);
+       cpus_read_unlock();
 }
 
 static ssize_t freezer_write(struct kernfs_open_file *of,
index 831f1f472bb814c945006f996d978c545e7a8759..0a2b4967e3334ca54003725c0aec38fd169c435e 100644 (file)
@@ -457,9 +457,7 @@ static void root_cgroup_cputime(struct cgroup_base_stat *bstat)
        struct task_cputime *cputime = &bstat->cputime;
        int i;
 
-       cputime->stime = 0;
-       cputime->utime = 0;
-       cputime->sum_exec_runtime = 0;
+       memset(bstat, 0, sizeof(*bstat));
        for_each_possible_cpu(i) {
                struct kernel_cpustat kcpustat;
                u64 *cpustat = kcpustat.cpustat;
index 55551989d9da50215c2c0954d55baa2a83bc03a9..fb50f29d9b361db607391c0228c9ee9a6f713b38 100644 (file)
@@ -152,7 +152,7 @@ COMPAT_SYSCALL_DEFINE3(sched_getaffinity, compat_pid_t,  pid, unsigned int, len,
        if (len & (sizeof(compat_ulong_t)-1))
                return -EINVAL;
 
-       if (!alloc_cpumask_var(&mask, GFP_KERNEL))
+       if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
                return -ENOMEM;
 
        ret = sched_getaffinity(pid, mask);
index 03e3251cd9d2b63daceebcf99dfa4c9971dadfe2..dac42a2ad5883c16b851dc94c53d17c638a91b66 100644 (file)
@@ -623,10 +623,10 @@ static int swiotlb_do_find_slots(struct device *dev, int area_index,
                phys_to_dma_unencrypted(dev, mem->start) & boundary_mask;
        unsigned long max_slots = get_max_slots(boundary_mask);
        unsigned int iotlb_align_mask =
-               dma_get_min_align_mask(dev) & ~(IO_TLB_SIZE - 1);
+               dma_get_min_align_mask(dev) | alloc_align_mask;
        unsigned int nslots = nr_slots(alloc_size), stride;
-       unsigned int index, wrap, count = 0, i;
        unsigned int offset = swiotlb_align_offset(dev, orig_addr);
+       unsigned int index, slots_checked, count = 0, i;
        unsigned long flags;
        unsigned int slot_base;
        unsigned int slot_index;
@@ -634,30 +634,35 @@ static int swiotlb_do_find_slots(struct device *dev, int area_index,
        BUG_ON(!nslots);
        BUG_ON(area_index >= mem->nareas);
 
+       /*
+        * For allocations of PAGE_SIZE or larger only look for page aligned
+        * allocations.
+        */
+       if (alloc_size >= PAGE_SIZE)
+               iotlb_align_mask |= ~PAGE_MASK;
+       iotlb_align_mask &= ~(IO_TLB_SIZE - 1);
+
        /*
         * For mappings with an alignment requirement don't bother looping to
-        * unaligned slots once we found an aligned one.  For allocations of
-        * PAGE_SIZE or larger only look for page aligned allocations.
+        * unaligned slots once we found an aligned one.
         */
        stride = (iotlb_align_mask >> IO_TLB_SHIFT) + 1;
-       if (alloc_size >= PAGE_SIZE)
-               stride = max(stride, stride << (PAGE_SHIFT - IO_TLB_SHIFT));
-       stride = max(stride, (alloc_align_mask >> IO_TLB_SHIFT) + 1);
 
        spin_lock_irqsave(&area->lock, flags);
        if (unlikely(nslots > mem->area_nslabs - area->used))
                goto not_found;
 
        slot_base = area_index * mem->area_nslabs;
-       index = wrap = wrap_area_index(mem, ALIGN(area->index, stride));
+       index = area->index;
 
-       do {
+       for (slots_checked = 0; slots_checked < mem->area_nslabs; ) {
                slot_index = slot_base + index;
 
                if (orig_addr &&
                    (slot_addr(tbl_dma_addr, slot_index) &
                     iotlb_align_mask) != (orig_addr & iotlb_align_mask)) {
                        index = wrap_area_index(mem, index + 1);
+                       slots_checked++;
                        continue;
                }
 
@@ -673,7 +678,8 @@ static int swiotlb_do_find_slots(struct device *dev, int area_index,
                                goto found;
                }
                index = wrap_area_index(mem, index + stride);
-       } while (index != wrap);
+               slots_checked += stride;
+       }
 
 not_found:
        spin_unlock_irqrestore(&area->lock, flags);
@@ -693,10 +699,7 @@ found:
        /*
         * Update the indices to avoid searching in the next round.
         */
-       if (index + nslots < mem->area_nslabs)
-               area->index = index + nslots;
-       else
-               area->index = 0;
+       area->index = wrap_area_index(mem, index + nslots);
        area->used += nslots;
        spin_unlock_irqrestore(&area->lock, flags);
        return slot_index;
index 846add8394c4159c8e5accb77ecc10e463519e3b..be61332c66b54a02b37d7a1847001b23a82d910e 100644 (file)
@@ -21,7 +21,7 @@ static __always_inline void __enter_from_user_mode(struct pt_regs *regs)
        arch_enter_from_user_mode(regs);
        lockdep_hardirqs_off(CALLER_ADDR0);
 
-       CT_WARN_ON(ct_state() != CONTEXT_USER);
+       CT_WARN_ON(__ct_state() != CONTEXT_USER);
        user_exit_irqoff();
 
        instrumentation_begin();
@@ -192,13 +192,14 @@ static unsigned long exit_to_user_mode_loop(struct pt_regs *regs,
 
 static void exit_to_user_mode_prepare(struct pt_regs *regs)
 {
-       unsigned long ti_work = read_thread_flags();
+       unsigned long ti_work;
 
        lockdep_assert_irqs_disabled();
 
        /* Flush pending rcuog wakeup before the last need_resched() check */
        tick_nohz_user_enter_prepare();
 
+       ti_work = read_thread_flags();
        if (unlikely(ti_work & EXIT_TO_USER_MODE_WORK))
                ti_work = exit_to_user_mode_loop(regs, ti_work);
 
index f79fd8b87f75edc22453a47dee8c9b14855e8eeb..435815d3be3f8104cee70f8330bcc7058e38402b 100644 (file)
@@ -2163,7 +2163,7 @@ static void perf_group_detach(struct perf_event *event)
                /* Inherit group flags from the previous leader */
                sibling->group_caps = event->group_caps;
 
-               if (!RB_EMPTY_NODE(&event->group_node)) {
+               if (sibling->attach_state & PERF_ATTACH_CONTEXT) {
                        add_event_to_groups(sibling, event->ctx);
 
                        if (sibling->state == PERF_EVENT_STATE_ACTIVE)
@@ -3872,7 +3872,7 @@ ctx_sched_in(struct perf_event_context *ctx, enum event_type_t event_type)
        if (likely(!ctx->nr_events))
                return;
 
-       if (is_active ^ EVENT_TIME) {
+       if (!(is_active & EVENT_TIME)) {
                /* start ctx time */
                __update_context_time(ctx, false);
                perf_cgroup_set_timestamp(cpuctx);
@@ -9187,7 +9187,7 @@ static void perf_event_bpf_output(struct perf_event *event, void *data)
 
        perf_event_header__init_id(&bpf_event->event_id.header,
                                   &sample, event);
-       ret = perf_output_begin(&handle, data, event,
+       ret = perf_output_begin(&handle, &sample, event,
                                bpf_event->event_id.header.size);
        if (ret)
                return;
@@ -12173,7 +12173,7 @@ perf_event_set_output(struct perf_event *event, struct perf_event *output_event)
        /*
         * If its not a per-cpu rb, it must be the same task.
         */
-       if (output_event->cpu == -1 && output_event->ctx != event->ctx)
+       if (output_event->cpu == -1 && output_event->hw.target != event->hw.target)
                goto out;
 
        /*
@@ -12893,12 +12893,14 @@ void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu)
        __perf_pmu_remove(src_ctx, src_cpu, pmu, &src_ctx->pinned_groups, &events);
        __perf_pmu_remove(src_ctx, src_cpu, pmu, &src_ctx->flexible_groups, &events);
 
-       /*
-        * Wait for the events to quiesce before re-instating them.
-        */
-       synchronize_rcu();
+       if (!list_empty(&events)) {
+               /*
+                * Wait for the events to quiesce before re-instating them.
+                */
+               synchronize_rcu();
 
-       __perf_pmu_install(dst_ctx, dst_cpu, pmu, &events);
+               __perf_pmu_install(dst_ctx, dst_cpu, pmu, &events);
+       }
 
        mutex_unlock(&dst_ctx->mutex);
        mutex_unlock(&src_ctx->mutex);
index f68954d05e89dce1f7d430610322fff0a3a379f1..bfe73db1c26c21c0ea8fe775fe90a3d3c475bb36 100644 (file)
@@ -617,6 +617,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
        if (retval)
                goto out;
 
+       mt_clear_in_rcu(vmi.mas.tree);
        for_each_vma(old_vmi, mpnt) {
                struct file *file;
 
@@ -700,6 +701,8 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
        retval = arch_dup_mmap(oldmm, mm);
 loop_out:
        vma_iter_free(&vmi);
+       if (!retval)
+               mt_set_in_rcu(vmi.mas.tree);
 out:
        mmap_write_unlock(mm);
        flush_tlb_mm(oldmm);
@@ -755,11 +758,6 @@ static void check_mm(struct mm_struct *mm)
        for (i = 0; i < NR_MM_COUNTERS; i++) {
                long x = percpu_counter_sum(&mm->rss_stat[i]);
 
-               if (likely(!x))
-                       continue;
-
-               /* Making sure this is not due to race with CPU offlining. */
-               x = percpu_counter_sum_all(&mm->rss_stat[i]);
                if (unlikely(x))
                        pr_alert("BUG: Bad rss-counter state mm:%p type:%s val:%ld\n",
                                 mm, resident_page_types[i], x);
@@ -1176,6 +1174,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
 fail_pcpu:
        while (i > 0)
                percpu_counter_destroy(&mm->rss_stat[--i]);
+       destroy_context(mm);
 fail_nocontext:
        mm_free_pgd(mm);
 fail_nopgd:
@@ -1627,7 +1626,8 @@ static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
        return 0;
 }
 
-static int copy_files(unsigned long clone_flags, struct task_struct *tsk)
+static int copy_files(unsigned long clone_flags, struct task_struct *tsk,
+                     int no_files)
 {
        struct files_struct *oldf, *newf;
        int error = 0;
@@ -1639,6 +1639,11 @@ static int copy_files(unsigned long clone_flags, struct task_struct *tsk)
        if (!oldf)
                goto out;
 
+       if (no_files) {
+               tsk->files = NULL;
+               goto out;
+       }
+
        if (clone_flags & CLONE_FILES) {
                atomic_inc(&oldf->count);
                goto out;
@@ -1956,6 +1961,91 @@ const struct file_operations pidfd_fops = {
 #endif
 };
 
+/**
+ * __pidfd_prepare - allocate a new pidfd_file and reserve a pidfd
+ * @pid:   the struct pid for which to create a pidfd
+ * @flags: flags of the new @pidfd
+ * @pidfd: the pidfd to return
+ *
+ * Allocate a new file that stashes @pid and reserve a new pidfd number in the
+ * caller's file descriptor table. The pidfd is reserved but not installed yet.
+
+ * The helper doesn't perform checks on @pid which makes it useful for pidfds
+ * created via CLONE_PIDFD where @pid has no task attached when the pidfd and
+ * pidfd file are prepared.
+ *
+ * If this function returns successfully the caller is responsible to either
+ * call fd_install() passing the returned pidfd and pidfd file as arguments in
+ * order to install the pidfd into its file descriptor table or they must use
+ * put_unused_fd() and fput() on the returned pidfd and pidfd file
+ * respectively.
+ *
+ * This function is useful when a pidfd must already be reserved but there
+ * might still be points of failure afterwards and the caller wants to ensure
+ * that no pidfd is leaked into its file descriptor table.
+ *
+ * Return: On success, a reserved pidfd is returned from the function and a new
+ *         pidfd file is returned in the last argument to the function. On
+ *         error, a negative error code is returned from the function and the
+ *         last argument remains unchanged.
+ */
+static int __pidfd_prepare(struct pid *pid, unsigned int flags, struct file **ret)
+{
+       int pidfd;
+       struct file *pidfd_file;
+
+       if (flags & ~(O_NONBLOCK | O_RDWR | O_CLOEXEC))
+               return -EINVAL;
+
+       pidfd = get_unused_fd_flags(O_RDWR | O_CLOEXEC);
+       if (pidfd < 0)
+               return pidfd;
+
+       pidfd_file = anon_inode_getfile("[pidfd]", &pidfd_fops, pid,
+                                       flags | O_RDWR | O_CLOEXEC);
+       if (IS_ERR(pidfd_file)) {
+               put_unused_fd(pidfd);
+               return PTR_ERR(pidfd_file);
+       }
+       get_pid(pid); /* held by pidfd_file now */
+       *ret = pidfd_file;
+       return pidfd;
+}
+
+/**
+ * pidfd_prepare - allocate a new pidfd_file and reserve a pidfd
+ * @pid:   the struct pid for which to create a pidfd
+ * @flags: flags of the new @pidfd
+ * @pidfd: the pidfd to return
+ *
+ * Allocate a new file that stashes @pid and reserve a new pidfd number in the
+ * caller's file descriptor table. The pidfd is reserved but not installed yet.
+ *
+ * The helper verifies that @pid is used as a thread group leader.
+ *
+ * If this function returns successfully the caller is responsible to either
+ * call fd_install() passing the returned pidfd and pidfd file as arguments in
+ * order to install the pidfd into its file descriptor table or they must use
+ * put_unused_fd() and fput() on the returned pidfd and pidfd file
+ * respectively.
+ *
+ * This function is useful when a pidfd must already be reserved but there
+ * might still be points of failure afterwards and the caller wants to ensure
+ * that no pidfd is leaked into its file descriptor table.
+ *
+ * Return: On success, a reserved pidfd is returned from the function and a new
+ *         pidfd file is returned in the last argument to the function. On
+ *         error, a negative error code is returned from the function and the
+ *         last argument remains unchanged.
+ */
+int pidfd_prepare(struct pid *pid, unsigned int flags, struct file **ret)
+{
+       if (!pid || !pid_has_task(pid, PIDTYPE_TGID))
+               return -EINVAL;
+
+       return __pidfd_prepare(pid, flags, ret);
+}
+
 static void __delayed_free_task(struct rcu_head *rhp)
 {
        struct task_struct *tsk = container_of(rhp, struct task_struct, rcu);
@@ -2010,7 +2100,7 @@ static void rv_task_fork(struct task_struct *p)
  * parts of the process environment (as per the clone
  * flags). The actual kick-off is left to the caller.
  */
-static __latent_entropy struct task_struct *copy_process(
+__latent_entropy struct task_struct *copy_process(
                                        struct pid *pid,
                                        int trace,
                                        int node,
@@ -2103,6 +2193,8 @@ static __latent_entropy struct task_struct *copy_process(
        p->flags &= ~PF_KTHREAD;
        if (args->kthread)
                p->flags |= PF_KTHREAD;
+       if (args->user_worker)
+               p->flags |= PF_USER_WORKER;
        if (args->io_thread) {
                /*
                 * Mark us an IO worker, and block any signal that isn't
@@ -2112,6 +2204,9 @@ static __latent_entropy struct task_struct *copy_process(
                siginitsetinv(&p->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP));
        }
 
+       if (args->name)
+               strscpy_pad(p->comm, args->name, sizeof(p->comm));
+
        p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? args->child_tid : NULL;
        /*
         * Clear TID on mm_release()?
@@ -2254,7 +2349,7 @@ static __latent_entropy struct task_struct *copy_process(
        retval = copy_semundo(clone_flags, p);
        if (retval)
                goto bad_fork_cleanup_security;
-       retval = copy_files(clone_flags, p);
+       retval = copy_files(clone_flags, p, args->no_files);
        if (retval)
                goto bad_fork_cleanup_semundo;
        retval = copy_fs(clone_flags, p);
@@ -2279,6 +2374,9 @@ static __latent_entropy struct task_struct *copy_process(
        if (retval)
                goto bad_fork_cleanup_io;
 
+       if (args->ignore_signals)
+               ignore_signals(p);
+
        stackleak_task_init(p);
 
        if (pid != &init_struct_pid) {
@@ -2296,21 +2394,12 @@ static __latent_entropy struct task_struct *copy_process(
         * if the fd table isn't shared).
         */
        if (clone_flags & CLONE_PIDFD) {
-               retval = get_unused_fd_flags(O_RDWR | O_CLOEXEC);
+               /* Note that no task has been attached to @pid yet. */
+               retval = __pidfd_prepare(pid, O_RDWR | O_CLOEXEC, &pidfile);
                if (retval < 0)
                        goto bad_fork_free_pid;
-
                pidfd = retval;
 
-               pidfile = anon_inode_getfile("[pidfd]", &pidfd_fops, pid,
-                                             O_RDWR | O_CLOEXEC);
-               if (IS_ERR(pidfile)) {
-                       put_unused_fd(pidfd);
-                       retval = PTR_ERR(pidfile);
-                       goto bad_fork_free_pid;
-               }
-               get_pid(pid);   /* held by pidfile now */
-
                retval = put_user(pidfd, args->pidfd);
                if (retval)
                        goto bad_fork_put_pidfd;
@@ -2627,6 +2716,7 @@ struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node)
                .fn             = fn,
                .fn_arg         = arg,
                .io_thread      = 1,
+               .user_worker    = 1,
        };
 
        return copy_process(NULL, 0, node, &args);
@@ -2730,7 +2820,8 @@ pid_t kernel_clone(struct kernel_clone_args *args)
 /*
  * Create a kernel thread.
  */
-pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+pid_t kernel_thread(int (*fn)(void *), void *arg, const char *name,
+                   unsigned long flags)
 {
        struct kernel_clone_args args = {
                .flags          = ((lower_32_bits(flags) | CLONE_VM |
@@ -2738,6 +2829,7 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
                .exit_signal    = (lower_32_bits(flags) & CSIGNAL),
                .fn             = fn,
                .fn_arg         = arg,
+               .name           = name,
                .kthread        = 1,
        };
 
@@ -2936,7 +3028,7 @@ static bool clone3_args_valid(struct kernel_clone_args *kargs)
         * - make the CLONE_DETACHED bit reusable for clone3
         * - make the CSIGNAL bits reusable for clone3
         */
-       if (kargs->flags & (CLONE_DETACHED | CSIGNAL))
+       if (kargs->flags & (CLONE_DETACHED | (CSIGNAL & (~CLONE_NEWTIME))))
                return false;
 
        if ((kargs->flags & (CLONE_SIGHAND | CLONE_CLEAR_SIGHAND)) ==
index 8cf70f068d92d31fda0d147782d55760c6854b5a..a45f3dfc8d14169ae3ea4ee875897213f81236be 100644 (file)
@@ -16,6 +16,6 @@ obj-y := core.o debugfs.o report.o
 KCSAN_INSTRUMENT_BARRIERS_selftest.o := y
 obj-$(CONFIG_KCSAN_SELFTEST) += selftest.o
 
-CFLAGS_kcsan_test.o := $(CFLAGS_KCSAN) -g -fno-omit-frame-pointer
+CFLAGS_kcsan_test.o := $(CFLAGS_KCSAN) -fno-omit-frame-pointer
 CFLAGS_kcsan_test.o += $(DISABLE_STRUCTLEAK_PLUGIN)
 obj-$(CONFIG_KCSAN_KUNIT_TEST) += kcsan_test.o
index 54d077e1a2dc7ba80be3662c32a065dcc42d9836..5a60cc52adc0c508602b54bc691fd091f2da3beb 100644 (file)
@@ -337,11 +337,20 @@ static void delay_access(int type)
  */
 static __always_inline u64 read_instrumented_memory(const volatile void *ptr, size_t size)
 {
+       /*
+        * In the below we don't necessarily need the read of the location to
+        * be atomic, and we don't use READ_ONCE(), since all we need for race
+        * detection is to observe 2 different values.
+        *
+        * Furthermore, on certain architectures (such as arm64), READ_ONCE()
+        * may turn into more complex instructions than a plain load that cannot
+        * do unaligned accesses.
+        */
        switch (size) {
-       case 1:  return READ_ONCE(*(const u8 *)ptr);
-       case 2:  return READ_ONCE(*(const u16 *)ptr);
-       case 4:  return READ_ONCE(*(const u32 *)ptr);
-       case 8:  return READ_ONCE(*(const u64 *)ptr);
+       case 1:  return *(const volatile u8 *)ptr;
+       case 2:  return *(const volatile u16 *)ptr;
+       case 4:  return *(const volatile u32 *)ptr;
+       case 8:  return *(const volatile u64 *)ptr;
        default: return 0; /* Ignore; we do not diff the values. */
        }
 }
index 7e6751b29101e5ca4050aa512b922ab05ddfc5e2..4bc6e0971ec93ce9322f5743b3d7c8b43a76b9b0 100644 (file)
@@ -38,6 +38,7 @@ struct task_struct *kthreadd_task;
 struct kthread_create_info
 {
        /* Information passed to kthread() from kthreadd. */
+       char *full_name;
        int (*threadfn)(void *data);
        void *data;
        int node;
@@ -343,10 +344,12 @@ static int kthread(void *_create)
        /* Release the structure when caller killed by a fatal signal. */
        done = xchg(&create->done, NULL);
        if (!done) {
+               kfree(create->full_name);
                kfree(create);
                kthread_exit(-EINTR);
        }
 
+       self->full_name = create->full_name;
        self->threadfn = threadfn;
        self->data = data;
 
@@ -396,11 +399,13 @@ static void create_kthread(struct kthread_create_info *create)
        current->pref_node_fork = create->node;
 #endif
        /* We want our own signal handler (we take no signals by default). */
-       pid = kernel_thread(kthread, create, CLONE_FS | CLONE_FILES | SIGCHLD);
+       pid = kernel_thread(kthread, create, create->full_name,
+                           CLONE_FS | CLONE_FILES | SIGCHLD);
        if (pid < 0) {
                /* Release the structure when caller killed by a fatal signal. */
                struct completion *done = xchg(&create->done, NULL);
 
+               kfree(create->full_name);
                if (!done) {
                        kfree(create);
                        return;
@@ -427,6 +432,11 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
        create->data = data;
        create->node = node;
        create->done = &done;
+       create->full_name = kvasprintf(GFP_KERNEL, namefmt, args);
+       if (!create->full_name) {
+               task = ERR_PTR(-ENOMEM);
+               goto free_create;
+       }
 
        spin_lock(&kthread_create_lock);
        list_add_tail(&create->list, &kthread_create_list);
@@ -453,26 +463,7 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
                wait_for_completion(&done);
        }
        task = create->result;
-       if (!IS_ERR(task)) {
-               char name[TASK_COMM_LEN];
-               va_list aq;
-               int len;
-
-               /*
-                * task is already visible to other tasks, so updating
-                * COMM must be protected.
-                */
-               va_copy(aq, args);
-               len = vsnprintf(name, sizeof(name), namefmt, aq);
-               va_end(aq);
-               if (len >= TASK_COMM_LEN) {
-                       struct kthread *kthread = to_kthread(task);
-
-                       /* leave it truncated when out of memory. */
-                       kthread->full_name = kvasprintf(GFP_KERNEL, namefmt, args);
-               }
-               set_task_comm(task, name);
-       }
+free_create:
        kfree(create);
        return task;
 }
index 50d4863974e7a218a3c4b855d3934712c80c614a..dcd1d5bfc1e077a57da1253d0eaab90e61100bd2 100644 (file)
@@ -1881,6 +1881,8 @@ print_circular_lock_scenario(struct held_lock *src,
        struct lock_class *source = hlock_class(src);
        struct lock_class *target = hlock_class(tgt);
        struct lock_class *parent = prt->class;
+       int src_read = src->read;
+       int tgt_read = tgt->read;
 
        /*
         * A direct locking problem where unsafe_class lock is taken
@@ -1908,7 +1910,10 @@ print_circular_lock_scenario(struct held_lock *src,
        printk(" Possible unsafe locking scenario:\n\n");
        printk("       CPU0                    CPU1\n");
        printk("       ----                    ----\n");
-       printk("  lock(");
+       if (tgt_read != 0)
+               printk("  rlock(");
+       else
+               printk("  lock(");
        __print_lock_name(target);
        printk(KERN_CONT ");\n");
        printk("                               lock(");
@@ -1917,7 +1922,12 @@ print_circular_lock_scenario(struct held_lock *src,
        printk("                               lock(");
        __print_lock_name(target);
        printk(KERN_CONT ");\n");
-       printk("  lock(");
+       if (src_read != 0)
+               printk("  rlock(");
+       else if (src->sync)
+               printk("  sync(");
+       else
+               printk("  lock(");
        __print_lock_name(source);
        printk(KERN_CONT ");\n");
        printk("\n *** DEADLOCK ***\n\n");
@@ -4531,7 +4541,13 @@ mark_usage(struct task_struct *curr, struct held_lock *hlock, int check)
                                        return 0;
                }
        }
-       if (!hlock->hardirqs_off) {
+
+       /*
+        * For lock_sync(), don't mark the ENABLED usage, since lock_sync()
+        * creates no critical section and no extra dependency can be introduced
+        * by interrupts
+        */
+       if (!hlock->hardirqs_off && !hlock->sync) {
                if (hlock->read) {
                        if (!mark_lock(curr, hlock,
                                        LOCK_ENABLED_HARDIRQ_READ))
@@ -4910,7 +4926,7 @@ static int __lock_is_held(const struct lockdep_map *lock, int read);
 static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
                          int trylock, int read, int check, int hardirqs_off,
                          struct lockdep_map *nest_lock, unsigned long ip,
-                         int references, int pin_count)
+                         int references, int pin_count, int sync)
 {
        struct task_struct *curr = current;
        struct lock_class *class = NULL;
@@ -4961,7 +4977,8 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
 
        class_idx = class - lock_classes;
 
-       if (depth) { /* we're holding locks */
+       if (depth && !sync) {
+               /* we're holding locks and the new held lock is not a sync */
                hlock = curr->held_locks + depth - 1;
                if (hlock->class_idx == class_idx && nest_lock) {
                        if (!references)
@@ -4995,6 +5012,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
        hlock->trylock = trylock;
        hlock->read = read;
        hlock->check = check;
+       hlock->sync = !!sync;
        hlock->hardirqs_off = !!hardirqs_off;
        hlock->references = references;
 #ifdef CONFIG_LOCK_STAT
@@ -5056,6 +5074,10 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
        if (!validate_chain(curr, hlock, chain_head, chain_key))
                return 0;
 
+       /* For lock_sync(), we are done here since no actual critical section */
+       if (hlock->sync)
+               return 1;
+
        curr->curr_chain_key = chain_key;
        curr->lockdep_depth++;
        check_chain_key(curr);
@@ -5197,7 +5219,7 @@ static int reacquire_held_locks(struct task_struct *curr, unsigned int depth,
                                    hlock->read, hlock->check,
                                    hlock->hardirqs_off,
                                    hlock->nest_lock, hlock->acquire_ip,
-                                   hlock->references, hlock->pin_count)) {
+                                   hlock->references, hlock->pin_count, 0)) {
                case 0:
                        return 1;
                case 1:
@@ -5667,7 +5689,7 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
 
        lockdep_recursion_inc();
        __lock_acquire(lock, subclass, trylock, read, check,
-                      irqs_disabled_flags(flags), nest_lock, ip, 0, 0);
+                      irqs_disabled_flags(flags), nest_lock, ip, 0, 0, 0);
        lockdep_recursion_finish();
        raw_local_irq_restore(flags);
 }
@@ -5693,6 +5715,34 @@ void lock_release(struct lockdep_map *lock, unsigned long ip)
 }
 EXPORT_SYMBOL_GPL(lock_release);
 
+/*
+ * lock_sync() - A special annotation for synchronize_{s,}rcu()-like API.
+ *
+ * No actual critical section is created by the APIs annotated with this: these
+ * APIs are used to wait for one or multiple critical sections (on other CPUs
+ * or threads), and it means that calling these APIs inside these critical
+ * sections is potential deadlock.
+ */
+void lock_sync(struct lockdep_map *lock, unsigned subclass, int read,
+              int check, struct lockdep_map *nest_lock, unsigned long ip)
+{
+       unsigned long flags;
+
+       if (unlikely(!lockdep_enabled()))
+               return;
+
+       raw_local_irq_save(flags);
+       check_flags(flags);
+
+       lockdep_recursion_inc();
+       __lock_acquire(lock, subclass, 0, read, check,
+                      irqs_disabled_flags(flags), nest_lock, ip, 0, 0, 1);
+       check_chain_key(current);
+       lockdep_recursion_finish();
+       raw_local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(lock_sync);
+
 noinstr int lock_is_held_type(const struct lockdep_map *lock, int read)
 {
        unsigned long flags;
index f04b1978899dda4185697b6d2d69bbdf02c1ea38..153ddc4c47eff1dd35599b1b3390a4959a693409 100644 (file)
@@ -51,8 +51,11 @@ torture_param(int, rt_boost, 2,
 torture_param(int, rt_boost_factor, 50, "A factor determining how often rt-boost happens.");
 torture_param(int, verbose, 1,
             "Enable verbose debugging printk()s");
+torture_param(int, nested_locks, 0, "Number of nested locks (max = 8)");
+/* Going much higher trips "BUG: MAX_LOCKDEP_CHAIN_HLOCKS too low!" errors */
+#define MAX_NESTED_LOCKS 8
 
-static char *torture_type = "spin_lock";
+static char *torture_type = IS_ENABLED(CONFIG_PREEMPT_RT) ? "raw_spin_lock" : "spin_lock";
 module_param(torture_type, charp, 0444);
 MODULE_PARM_DESC(torture_type,
                 "Type of lock to torture (spin_lock, spin_lock_irq, mutex_lock, ...)");
@@ -79,10 +82,12 @@ static void lock_torture_cleanup(void);
 struct lock_torture_ops {
        void (*init)(void);
        void (*exit)(void);
+       int (*nested_lock)(int tid, u32 lockset);
        int (*writelock)(int tid);
        void (*write_delay)(struct torture_random_state *trsp);
        void (*task_boost)(struct torture_random_state *trsp);
        void (*writeunlock)(int tid);
+       void (*nested_unlock)(int tid, u32 lockset);
        int (*readlock)(int tid);
        void (*read_delay)(struct torture_random_state *trsp);
        void (*readunlock)(int tid);
@@ -252,6 +257,59 @@ static struct lock_torture_ops spin_lock_irq_ops = {
        .name           = "spin_lock_irq"
 };
 
+static DEFINE_RAW_SPINLOCK(torture_raw_spinlock);
+
+static int torture_raw_spin_lock_write_lock(int tid __maybe_unused)
+__acquires(torture_raw_spinlock)
+{
+       raw_spin_lock(&torture_raw_spinlock);
+       return 0;
+}
+
+static void torture_raw_spin_lock_write_unlock(int tid __maybe_unused)
+__releases(torture_raw_spinlock)
+{
+       raw_spin_unlock(&torture_raw_spinlock);
+}
+
+static struct lock_torture_ops raw_spin_lock_ops = {
+       .writelock      = torture_raw_spin_lock_write_lock,
+       .write_delay    = torture_spin_lock_write_delay,
+       .task_boost     = torture_rt_boost,
+       .writeunlock    = torture_raw_spin_lock_write_unlock,
+       .readlock       = NULL,
+       .read_delay     = NULL,
+       .readunlock     = NULL,
+       .name           = "raw_spin_lock"
+};
+
+static int torture_raw_spin_lock_write_lock_irq(int tid __maybe_unused)
+__acquires(torture_raw_spinlock)
+{
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&torture_raw_spinlock, flags);
+       cxt.cur_ops->flags = flags;
+       return 0;
+}
+
+static void torture_raw_spin_lock_write_unlock_irq(int tid __maybe_unused)
+__releases(torture_raw_spinlock)
+{
+       raw_spin_unlock_irqrestore(&torture_raw_spinlock, cxt.cur_ops->flags);
+}
+
+static struct lock_torture_ops raw_spin_lock_irq_ops = {
+       .writelock      = torture_raw_spin_lock_write_lock_irq,
+       .write_delay    = torture_spin_lock_write_delay,
+       .task_boost     = torture_rt_boost,
+       .writeunlock    = torture_raw_spin_lock_write_unlock_irq,
+       .readlock       = NULL,
+       .read_delay     = NULL,
+       .readunlock     = NULL,
+       .name           = "raw_spin_lock_irq"
+};
+
 static DEFINE_RWLOCK(torture_rwlock);
 
 static int torture_rwlock_write_lock(int tid __maybe_unused)
@@ -365,6 +423,28 @@ static struct lock_torture_ops rw_lock_irq_ops = {
 };
 
 static DEFINE_MUTEX(torture_mutex);
+static struct mutex torture_nested_mutexes[MAX_NESTED_LOCKS];
+static struct lock_class_key nested_mutex_keys[MAX_NESTED_LOCKS];
+
+static void torture_mutex_init(void)
+{
+       int i;
+
+       for (i = 0; i < MAX_NESTED_LOCKS; i++)
+               __mutex_init(&torture_nested_mutexes[i], __func__,
+                            &nested_mutex_keys[i]);
+}
+
+static int torture_mutex_nested_lock(int tid __maybe_unused,
+                                    u32 lockset)
+{
+       int i;
+
+       for (i = 0; i < nested_locks; i++)
+               if (lockset & (1 << i))
+                       mutex_lock(&torture_nested_mutexes[i]);
+       return 0;
+}
 
 static int torture_mutex_lock(int tid __maybe_unused)
 __acquires(torture_mutex)
@@ -393,11 +473,24 @@ __releases(torture_mutex)
        mutex_unlock(&torture_mutex);
 }
 
+static void torture_mutex_nested_unlock(int tid __maybe_unused,
+                                       u32 lockset)
+{
+       int i;
+
+       for (i = nested_locks - 1; i >= 0; i--)
+               if (lockset & (1 << i))
+                       mutex_unlock(&torture_nested_mutexes[i]);
+}
+
 static struct lock_torture_ops mutex_lock_ops = {
+       .init           = torture_mutex_init,
+       .nested_lock    = torture_mutex_nested_lock,
        .writelock      = torture_mutex_lock,
        .write_delay    = torture_mutex_delay,
        .task_boost     = torture_rt_boost,
        .writeunlock    = torture_mutex_unlock,
+       .nested_unlock  = torture_mutex_nested_unlock,
        .readlock       = NULL,
        .read_delay     = NULL,
        .readunlock     = NULL,
@@ -504,6 +597,28 @@ static struct lock_torture_ops ww_mutex_lock_ops = {
 
 #ifdef CONFIG_RT_MUTEXES
 static DEFINE_RT_MUTEX(torture_rtmutex);
+static struct rt_mutex torture_nested_rtmutexes[MAX_NESTED_LOCKS];
+static struct lock_class_key nested_rtmutex_keys[MAX_NESTED_LOCKS];
+
+static void torture_rtmutex_init(void)
+{
+       int i;
+
+       for (i = 0; i < MAX_NESTED_LOCKS; i++)
+               __rt_mutex_init(&torture_nested_rtmutexes[i], __func__,
+                               &nested_rtmutex_keys[i]);
+}
+
+static int torture_rtmutex_nested_lock(int tid __maybe_unused,
+                                      u32 lockset)
+{
+       int i;
+
+       for (i = 0; i < nested_locks; i++)
+               if (lockset & (1 << i))
+                       rt_mutex_lock(&torture_nested_rtmutexes[i]);
+       return 0;
+}
 
 static int torture_rtmutex_lock(int tid __maybe_unused)
 __acquires(torture_rtmutex)
@@ -545,11 +660,24 @@ static void torture_rt_boost_rtmutex(struct torture_random_state *trsp)
        __torture_rt_boost(trsp);
 }
 
+static void torture_rtmutex_nested_unlock(int tid __maybe_unused,
+                                         u32 lockset)
+{
+       int i;
+
+       for (i = nested_locks - 1; i >= 0; i--)
+               if (lockset & (1 << i))
+                       rt_mutex_unlock(&torture_nested_rtmutexes[i]);
+}
+
 static struct lock_torture_ops rtmutex_lock_ops = {
+       .init           = torture_rtmutex_init,
+       .nested_lock    = torture_rtmutex_nested_lock,
        .writelock      = torture_rtmutex_lock,
        .write_delay    = torture_rtmutex_delay,
        .task_boost     = torture_rt_boost_rtmutex,
        .writeunlock    = torture_rtmutex_unlock,
+       .nested_unlock  = torture_rtmutex_nested_unlock,
        .readlock       = NULL,
        .read_delay     = NULL,
        .readunlock     = NULL,
@@ -684,6 +812,8 @@ static int lock_torture_writer(void *arg)
        struct lock_stress_stats *lwsp = arg;
        int tid = lwsp - cxt.lwsa;
        DEFINE_TORTURE_RANDOM(rand);
+       u32 lockset_mask;
+       bool skip_main_lock;
 
        VERBOSE_TOROUT_STRING("lock_torture_writer task started");
        set_user_nice(current, MAX_NICE);
@@ -692,19 +822,40 @@ static int lock_torture_writer(void *arg)
                if ((torture_random(&rand) & 0xfffff) == 0)
                        schedule_timeout_uninterruptible(1);
 
-               cxt.cur_ops->task_boost(&rand);
-               cxt.cur_ops->writelock(tid);
-               if (WARN_ON_ONCE(lock_is_write_held))
-                       lwsp->n_lock_fail++;
-               lock_is_write_held = true;
-               if (WARN_ON_ONCE(atomic_read(&lock_is_read_held)))
-                       lwsp->n_lock_fail++; /* rare, but... */
+               lockset_mask = torture_random(&rand);
+               /*
+                * When using nested_locks, we want to occasionally
+                * skip the main lock so we can avoid always serializing
+                * the lock chains on that central lock. By skipping the
+                * main lock occasionally, we can create different
+                * contention patterns (allowing for multiple disjoint
+                * blocked trees)
+                */
+               skip_main_lock = (nested_locks &&
+                                !(torture_random(&rand) % 100));
 
-               lwsp->n_lock_acquired++;
+               cxt.cur_ops->task_boost(&rand);
+               if (cxt.cur_ops->nested_lock)
+                       cxt.cur_ops->nested_lock(tid, lockset_mask);
+
+               if (!skip_main_lock) {
+                       cxt.cur_ops->writelock(tid);
+                       if (WARN_ON_ONCE(lock_is_write_held))
+                               lwsp->n_lock_fail++;
+                       lock_is_write_held = true;
+                       if (WARN_ON_ONCE(atomic_read(&lock_is_read_held)))
+                               lwsp->n_lock_fail++; /* rare, but... */
+
+                       lwsp->n_lock_acquired++;
+               }
                cxt.cur_ops->write_delay(&rand);
-               lock_is_write_held = false;
-               WRITE_ONCE(last_lock_release, jiffies);
-               cxt.cur_ops->writeunlock(tid);
+               if (!skip_main_lock) {
+                       lock_is_write_held = false;
+                       WRITE_ONCE(last_lock_release, jiffies);
+                       cxt.cur_ops->writeunlock(tid);
+               }
+               if (cxt.cur_ops->nested_unlock)
+                       cxt.cur_ops->nested_unlock(tid, lockset_mask);
 
                stutter_wait("lock_torture_writer");
        } while (!torture_must_stop());
@@ -845,11 +996,11 @@ lock_torture_print_module_parms(struct lock_torture_ops *cur_ops,
                                const char *tag)
 {
        pr_alert("%s" TORTURE_FLAG
-                "--- %s%s: nwriters_stress=%d nreaders_stress=%d stat_interval=%d verbose=%d shuffle_interval=%d stutter=%d shutdown_secs=%d onoff_interval=%d onoff_holdoff=%d\n",
+                "--- %s%s: nwriters_stress=%d nreaders_stress=%d nested_locks=%d stat_interval=%d verbose=%d shuffle_interval=%d stutter=%d shutdown_secs=%d onoff_interval=%d onoff_holdoff=%d\n",
                 torture_type, tag, cxt.debug_lock ? " [debug]": "",
-                cxt.nrealwriters_stress, cxt.nrealreaders_stress, stat_interval,
-                verbose, shuffle_interval, stutter, shutdown_secs,
-                onoff_interval, onoff_holdoff);
+                cxt.nrealwriters_stress, cxt.nrealreaders_stress,
+                nested_locks, stat_interval, verbose, shuffle_interval,
+                stutter, shutdown_secs, onoff_interval, onoff_holdoff);
 }
 
 static void lock_torture_cleanup(void)
@@ -919,6 +1070,7 @@ static int __init lock_torture_init(void)
        static struct lock_torture_ops *torture_ops[] = {
                &lock_busted_ops,
                &spin_lock_ops, &spin_lock_irq_ops,
+               &raw_spin_lock_ops, &raw_spin_lock_irq_ops,
                &rw_lock_ops, &rw_lock_irq_ops,
                &mutex_lock_ops,
                &ww_mutex_lock_ops,
@@ -1068,6 +1220,10 @@ static int __init lock_torture_init(void)
                }
        }
 
+       /* cap nested_locks to MAX_NESTED_LOCKS */
+       if (nested_locks > MAX_NESTED_LOCKS)
+               nested_locks = MAX_NESTED_LOCKS;
+
        if (cxt.cur_ops->readlock) {
                reader_tasks = kcalloc(cxt.nrealreaders_stress,
                                       sizeof(reader_tasks[0]),
index 29dc253d03af7c1c6f5f2c47694b842ac744fdab..93cca6e698600ac798a8968b95b1e94ae9380126 100644 (file)
@@ -659,7 +659,7 @@ static int __init test_ww_mutex_init(void)
        if (ret)
                return ret;
 
-       ret = stress(4095, hweight32(STRESS_ALL)*ncpus, STRESS_ALL);
+       ret = stress(2047, hweight32(STRESS_ALL)*ncpus, STRESS_ALL);
        if (ret)
                return ret;
 
index a487ff24129b8ea5f4c343eade407dae82fc4f52..80d9c6d77a452648045c7dfd21e375ca01b46a3c 100644 (file)
@@ -545,21 +545,20 @@ static void commit_nsset(struct nsset *nsset)
 
 SYSCALL_DEFINE2(setns, int, fd, int, flags)
 {
-       struct file *file;
+       struct fd f = fdget(fd);
        struct ns_common *ns = NULL;
        struct nsset nsset = {};
        int err = 0;
 
-       file = fget(fd);
-       if (!file)
+       if (!f.file)
                return -EBADF;
 
-       if (proc_ns_file(file)) {
-               ns = get_proc_ns(file_inode(file));
+       if (proc_ns_file(f.file)) {
+               ns = get_proc_ns(file_inode(f.file));
                if (flags && (ns->ops->type != flags))
                        err = -EINVAL;
                flags = ns->ops->type;
-       } else if (!IS_ERR(pidfd_pid(file))) {
+       } else if (!IS_ERR(pidfd_pid(f.file))) {
                err = check_setns_flags(flags);
        } else {
                err = -EINVAL;
@@ -571,17 +570,17 @@ SYSCALL_DEFINE2(setns, int, fd, int, flags)
        if (err)
                goto out;
 
-       if (proc_ns_file(file))
+       if (proc_ns_file(f.file))
                err = validate_ns(&nsset, ns);
        else
-               err = validate_nsset(&nsset, file->private_data);
+               err = validate_nsset(&nsset, f.file->private_data);
        if (!err) {
                commit_nsset(&nsset);
                perf_event_namespaces(current);
        }
        put_nsset(&nsset);
 out:
-       fput(file);
+       fdput(f);
        return err;
 }
 
index 3fbc5e46b72173cf216850ea85afc24ace98fd3c..f93954a0384d3889fb6d52de977562d10be1a012 100644 (file)
@@ -594,20 +594,15 @@ struct task_struct *pidfd_get_task(int pidfd, unsigned int *flags)
  */
 int pidfd_create(struct pid *pid, unsigned int flags)
 {
-       int fd;
-
-       if (!pid || !pid_has_task(pid, PIDTYPE_TGID))
-               return -EINVAL;
+       int pidfd;
+       struct file *pidfd_file;
 
-       if (flags & ~(O_NONBLOCK | O_RDWR | O_CLOEXEC))
-               return -EINVAL;
-
-       fd = anon_inode_getfd("[pidfd]", &pidfd_fops, get_pid(pid),
-                             flags | O_RDWR | O_CLOEXEC);
-       if (fd < 0)
-               put_pid(pid);
+       pidfd = pidfd_prepare(pid, flags, &pidfd_file);
+       if (pidfd < 0)
+               return pidfd;
 
-       return fd;
+       fd_install(pidfd, pidfd_file);
+       return pidfd;
 }
 
 /**
index ab62074174c32d184d51d13cd158bdb30d3da6cb..9071182b1284bb97bce2c062724bb81d897d97f1 100644 (file)
@@ -53,9 +53,6 @@ config RCU_EXPERT
 
          Say N if you are unsure.
 
-config SRCU
-       def_bool y
-
 config TINY_SRCU
        bool
        default y if TINY_RCU
index 115616ac3bfa6d1cb83bd0efdf823f64df3ab855..4a1b9622598be4193c0b758f6728dc8153d86208 100644 (file)
 
 /*
  * Grace-period counter management.
+ *
+ * The two least significant bits contain the control flags.
+ * The most significant bits contain the grace-period sequence counter.
+ *
+ * When both control flags are zero, no grace period is in progress.
+ * When either bit is non-zero, a grace period has started and is in
+ * progress. When the grace period completes, the control flags are reset
+ * to 0 and the grace-period sequence counter is incremented.
+ *
+ * However some specific RCU usages make use of custom values.
+ *
+ * SRCU special control values:
+ *
+ *     SRCU_SNP_INIT_SEQ       :       Invalid/init value set when SRCU node
+ *                                     is initialized.
+ *
+ *     SRCU_STATE_IDLE         :       No SRCU gp is in progress
+ *
+ *     SRCU_STATE_SCAN1        :       State set by rcu_seq_start(). Indicates
+ *                                     we are scanning the readers on the slot
+ *                                     defined as inactive (there might well
+ *                                     be pending readers that will use that
+ *                                     index, but their number is bounded).
+ *
+ *     SRCU_STATE_SCAN2        :       State set manually via rcu_seq_set_state()
+ *                                     Indicates we are flipping the readers
+ *                                     index and then scanning the readers on the
+ *                                     slot newly designated as inactive (again,
+ *                                     the number of pending readers that will use
+ *                                     this inactive index is bounded).
+ *
+ * RCU polled GP special control value:
+ *
+ *     RCU_GET_STATE_COMPLETED :       State value indicating an already-completed
+ *                                     polled GP has completed.  This value covers
+ *                                     both the state and the counter of the
+ *                                     grace-period sequence number.
  */
 
 #define RCU_SEQ_CTR_SHIFT      2
@@ -341,11 +378,13 @@ extern void rcu_init_geometry(void);
  * specified state structure (for SRCU) or the only rcu_state structure
  * (for RCU).
  */
-#define srcu_for_each_node_breadth_first(sp, rnp) \
+#define _rcu_for_each_node_breadth_first(sp, rnp) \
        for ((rnp) = &(sp)->node[0]; \
             (rnp) < &(sp)->node[rcu_num_nodes]; (rnp)++)
 #define rcu_for_each_node_breadth_first(rnp) \
-       srcu_for_each_node_breadth_first(&rcu_state, rnp)
+       _rcu_for_each_node_breadth_first(&rcu_state, rnp)
+#define srcu_for_each_node_breadth_first(ssp, rnp) \
+       _rcu_for_each_node_breadth_first(ssp->srcu_sup, rnp)
 
 /*
  * Scan the leaves of the rcu_node hierarchy for the rcu_state structure.
index 91fb5905a008ff243039e4d967d76deb187537ec..e82ec9f9a5d80c71682760730b239c26d9252efa 100644 (file)
@@ -631,8 +631,7 @@ static int compute_real(int n)
 static int
 rcu_scale_shutdown(void *arg)
 {
-       wait_event(shutdown_wq,
-                  atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters);
+       wait_event_idle(shutdown_wq, atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters);
        smp_mb(); /* Wake before output. */
        rcu_scale_cleanup();
        kernel_power_off();
@@ -716,7 +715,7 @@ kfree_scale_thread(void *arg)
                        // is tested.
                        if ((kfree_rcu_test_single && !kfree_rcu_test_double) ||
                                        (kfree_rcu_test_both && torture_random(&tr) & 0x800))
-                               kfree_rcu(alloc_ptr);
+                               kfree_rcu_mightsleep(alloc_ptr);
                        else
                                kfree_rcu(alloc_ptr, rh);
                }
@@ -771,8 +770,8 @@ kfree_scale_cleanup(void)
 static int
 kfree_scale_shutdown(void *arg)
 {
-       wait_event(shutdown_wq,
-                  atomic_read(&n_kfree_scale_thread_ended) >= kfree_nrealthreads);
+       wait_event_idle(shutdown_wq,
+                       atomic_read(&n_kfree_scale_thread_ended) >= kfree_nrealthreads);
 
        smp_mb(); /* Wake before output. */
 
index 8e6c023212cb314555514f568a18fb4b6898caad..147551c23baf03e273fcf0380678d8a5e3822a72 100644 (file)
@@ -119,7 +119,9 @@ torture_param(int, stutter, 5, "Number of seconds to run/halt test");
 torture_param(int, test_boost, 1, "Test RCU prio boost: 0=no, 1=maybe, 2=yes.");
 torture_param(int, test_boost_duration, 4, "Duration of each boost test, seconds.");
 torture_param(int, test_boost_interval, 7, "Interval between boost tests, seconds.");
+torture_param(int, test_nmis, 0, "End-test NMI tests, 0 to disable.");
 torture_param(bool, test_no_idle_hz, true, "Test support for tickless idle CPUs");
+torture_param(int, test_srcu_lockdep, 0, "Test specified SRCU deadlock scenario.");
 torture_param(int, verbose, 1, "Enable verbose debugging printk()s");
 
 static char *torture_type = "rcu";
@@ -179,7 +181,6 @@ static atomic_t n_rcu_torture_mbchk_tries;
 static atomic_t n_rcu_torture_error;
 static long n_rcu_torture_barrier_error;
 static long n_rcu_torture_boost_ktrerror;
-static long n_rcu_torture_boost_rterror;
 static long n_rcu_torture_boost_failure;
 static long n_rcu_torture_boosts;
 static atomic_long_t n_rcu_torture_timers;
@@ -2194,12 +2195,11 @@ rcu_torture_stats_print(void)
                atomic_read(&n_rcu_torture_alloc),
                atomic_read(&n_rcu_torture_alloc_fail),
                atomic_read(&n_rcu_torture_free));
-       pr_cont("rtmbe: %d rtmbkf: %d/%d rtbe: %ld rtbke: %ld rtbre: %ld ",
+       pr_cont("rtmbe: %d rtmbkf: %d/%d rtbe: %ld rtbke: %ld ",
                atomic_read(&n_rcu_torture_mberror),
                atomic_read(&n_rcu_torture_mbchk_fail), atomic_read(&n_rcu_torture_mbchk_tries),
                n_rcu_torture_barrier_error,
-               n_rcu_torture_boost_ktrerror,
-               n_rcu_torture_boost_rterror);
+               n_rcu_torture_boost_ktrerror);
        pr_cont("rtbf: %ld rtb: %ld nt: %ld ",
                n_rcu_torture_boost_failure,
                n_rcu_torture_boosts,
@@ -2217,15 +2217,13 @@ rcu_torture_stats_print(void)
        if (atomic_read(&n_rcu_torture_mberror) ||
            atomic_read(&n_rcu_torture_mbchk_fail) ||
            n_rcu_torture_barrier_error || n_rcu_torture_boost_ktrerror ||
-           n_rcu_torture_boost_rterror || n_rcu_torture_boost_failure ||
-           i > 1) {
+           n_rcu_torture_boost_failure || i > 1) {
                pr_cont("%s", "!!! ");
                atomic_inc(&n_rcu_torture_error);
                WARN_ON_ONCE(atomic_read(&n_rcu_torture_mberror));
                WARN_ON_ONCE(atomic_read(&n_rcu_torture_mbchk_fail));
                WARN_ON_ONCE(n_rcu_torture_barrier_error);  // rcu_barrier()
                WARN_ON_ONCE(n_rcu_torture_boost_ktrerror); // no boost kthread
-               WARN_ON_ONCE(n_rcu_torture_boost_rterror); // can't set RT prio
                WARN_ON_ONCE(n_rcu_torture_boost_failure); // boost failed (TIMER_SOFTIRQ RT prio?)
                WARN_ON_ONCE(i > 1); // Too-short grace period
        }
@@ -2358,7 +2356,8 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag)
                 "n_barrier_cbs=%d "
                 "onoff_interval=%d onoff_holdoff=%d "
                 "read_exit_delay=%d read_exit_burst=%d "
-                "nocbs_nthreads=%d nocbs_toggle=%d\n",
+                "nocbs_nthreads=%d nocbs_toggle=%d "
+                "test_nmis=%d\n",
                 torture_type, tag, nrealreaders, nfakewriters,
                 stat_interval, verbose, test_no_idle_hz, shuffle_interval,
                 stutter, irqreader, fqs_duration, fqs_holdoff, fqs_stutter,
@@ -2369,7 +2368,8 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag)
                 n_barrier_cbs,
                 onoff_interval, onoff_holdoff,
                 read_exit_delay, read_exit_burst,
-                nocbs_nthreads, nocbs_toggle);
+                nocbs_nthreads, nocbs_toggle,
+                test_nmis);
 }
 
 static int rcutorture_booster_cleanup(unsigned int cpu)
@@ -3273,6 +3273,29 @@ static void rcu_torture_read_exit_cleanup(void)
        torture_stop_kthread(rcutorture_read_exit, read_exit_task);
 }
 
+static void rcutorture_test_nmis(int n)
+{
+#if IS_BUILTIN(CONFIG_RCU_TORTURE_TEST)
+       int cpu;
+       int dumpcpu;
+       int i;
+
+       for (i = 0; i < n; i++) {
+               preempt_disable();
+               cpu = smp_processor_id();
+               dumpcpu = cpu + 1;
+               if (dumpcpu >= nr_cpu_ids)
+                       dumpcpu = 0;
+               pr_alert("%s: CPU %d invoking dump_cpu_task(%d)\n", __func__, cpu, dumpcpu);
+               dump_cpu_task(dumpcpu);
+               preempt_enable();
+               schedule_timeout_uninterruptible(15 * HZ);
+       }
+#else // #if IS_BUILTIN(CONFIG_RCU_TORTURE_TEST)
+       WARN_ONCE(n, "Non-zero rcutorture.test_nmis=%d permitted only when rcutorture is built in.\n", test_nmis);
+#endif // #else // #if IS_BUILTIN(CONFIG_RCU_TORTURE_TEST)
+}
+
 static enum cpuhp_state rcutor_hp;
 
 static void
@@ -3297,6 +3320,8 @@ rcu_torture_cleanup(void)
                return;
        }
 
+       rcutorture_test_nmis(test_nmis);
+
        if (cur_ops->gp_kthread_dbg)
                cur_ops->gp_kthread_dbg();
        rcu_torture_read_exit_cleanup();
@@ -3463,6 +3488,188 @@ static void rcutorture_sync(void)
                cur_ops->sync();
 }
 
+static DEFINE_MUTEX(mut0);
+static DEFINE_MUTEX(mut1);
+static DEFINE_MUTEX(mut2);
+static DEFINE_MUTEX(mut3);
+static DEFINE_MUTEX(mut4);
+static DEFINE_MUTEX(mut5);
+static DEFINE_MUTEX(mut6);
+static DEFINE_MUTEX(mut7);
+static DEFINE_MUTEX(mut8);
+static DEFINE_MUTEX(mut9);
+
+static DECLARE_RWSEM(rwsem0);
+static DECLARE_RWSEM(rwsem1);
+static DECLARE_RWSEM(rwsem2);
+static DECLARE_RWSEM(rwsem3);
+static DECLARE_RWSEM(rwsem4);
+static DECLARE_RWSEM(rwsem5);
+static DECLARE_RWSEM(rwsem6);
+static DECLARE_RWSEM(rwsem7);
+static DECLARE_RWSEM(rwsem8);
+static DECLARE_RWSEM(rwsem9);
+
+DEFINE_STATIC_SRCU(srcu0);
+DEFINE_STATIC_SRCU(srcu1);
+DEFINE_STATIC_SRCU(srcu2);
+DEFINE_STATIC_SRCU(srcu3);
+DEFINE_STATIC_SRCU(srcu4);
+DEFINE_STATIC_SRCU(srcu5);
+DEFINE_STATIC_SRCU(srcu6);
+DEFINE_STATIC_SRCU(srcu7);
+DEFINE_STATIC_SRCU(srcu8);
+DEFINE_STATIC_SRCU(srcu9);
+
+static int srcu_lockdep_next(const char *f, const char *fl, const char *fs, const char *fu, int i,
+                            int cyclelen, int deadlock)
+{
+       int j = i + 1;
+
+       if (j >= cyclelen)
+               j = deadlock ? 0 : -1;
+       if (j >= 0)
+               pr_info("%s: %s(%d), %s(%d), %s(%d)\n", f, fl, i, fs, j, fu, i);
+       else
+               pr_info("%s: %s(%d), %s(%d)\n", f, fl, i, fu, i);
+       return j;
+}
+
+// Test lockdep on SRCU-based deadlock scenarios.
+static void rcu_torture_init_srcu_lockdep(void)
+{
+       int cyclelen;
+       int deadlock;
+       bool err = false;
+       int i;
+       int j;
+       int idx;
+       struct mutex *muts[] = { &mut0, &mut1, &mut2, &mut3, &mut4,
+                                &mut5, &mut6, &mut7, &mut8, &mut9 };
+       struct rw_semaphore *rwsems[] = { &rwsem0, &rwsem1, &rwsem2, &rwsem3, &rwsem4,
+                                         &rwsem5, &rwsem6, &rwsem7, &rwsem8, &rwsem9 };
+       struct srcu_struct *srcus[] = { &srcu0, &srcu1, &srcu2, &srcu3, &srcu4,
+                                       &srcu5, &srcu6, &srcu7, &srcu8, &srcu9 };
+       int testtype;
+
+       if (!test_srcu_lockdep)
+               return;
+
+       deadlock = test_srcu_lockdep / 1000;
+       testtype = (test_srcu_lockdep / 10) % 100;
+       cyclelen = test_srcu_lockdep % 10;
+       WARN_ON_ONCE(ARRAY_SIZE(muts) != ARRAY_SIZE(srcus));
+       if (WARN_ONCE(deadlock != !!deadlock,
+                     "%s: test_srcu_lockdep=%d and deadlock digit %d must be zero or one.\n",
+                     __func__, test_srcu_lockdep, deadlock))
+               err = true;
+       if (WARN_ONCE(cyclelen <= 0,
+                     "%s: test_srcu_lockdep=%d and cycle-length digit %d must be greater than zero.\n",
+                     __func__, test_srcu_lockdep, cyclelen))
+               err = true;
+       if (err)
+               goto err_out;
+
+       if (testtype == 0) {
+               pr_info("%s: test_srcu_lockdep = %05d: SRCU %d-way %sdeadlock.\n",
+                       __func__, test_srcu_lockdep, cyclelen, deadlock ? "" : "non-");
+               if (deadlock && cyclelen == 1)
+                       pr_info("%s: Expect hang.\n", __func__);
+               for (i = 0; i < cyclelen; i++) {
+                       j = srcu_lockdep_next(__func__, "srcu_read_lock", "synchronize_srcu",
+                                             "srcu_read_unlock", i, cyclelen, deadlock);
+                       idx = srcu_read_lock(srcus[i]);
+                       if (j >= 0)
+                               synchronize_srcu(srcus[j]);
+                       srcu_read_unlock(srcus[i], idx);
+               }
+               return;
+       }
+
+       if (testtype == 1) {
+               pr_info("%s: test_srcu_lockdep = %05d: SRCU/mutex %d-way %sdeadlock.\n",
+                       __func__, test_srcu_lockdep, cyclelen, deadlock ? "" : "non-");
+               for (i = 0; i < cyclelen; i++) {
+                       pr_info("%s: srcu_read_lock(%d), mutex_lock(%d), mutex_unlock(%d), srcu_read_unlock(%d)\n",
+                               __func__, i, i, i, i);
+                       idx = srcu_read_lock(srcus[i]);
+                       mutex_lock(muts[i]);
+                       mutex_unlock(muts[i]);
+                       srcu_read_unlock(srcus[i], idx);
+
+                       j = srcu_lockdep_next(__func__, "mutex_lock", "synchronize_srcu",
+                                             "mutex_unlock", i, cyclelen, deadlock);
+                       mutex_lock(muts[i]);
+                       if (j >= 0)
+                               synchronize_srcu(srcus[j]);
+                       mutex_unlock(muts[i]);
+               }
+               return;
+       }
+
+       if (testtype == 2) {
+               pr_info("%s: test_srcu_lockdep = %05d: SRCU/rwsem %d-way %sdeadlock.\n",
+                       __func__, test_srcu_lockdep, cyclelen, deadlock ? "" : "non-");
+               for (i = 0; i < cyclelen; i++) {
+                       pr_info("%s: srcu_read_lock(%d), down_read(%d), up_read(%d), srcu_read_unlock(%d)\n",
+                               __func__, i, i, i, i);
+                       idx = srcu_read_lock(srcus[i]);
+                       down_read(rwsems[i]);
+                       up_read(rwsems[i]);
+                       srcu_read_unlock(srcus[i], idx);
+
+                       j = srcu_lockdep_next(__func__, "down_write", "synchronize_srcu",
+                                             "up_write", i, cyclelen, deadlock);
+                       down_write(rwsems[i]);
+                       if (j >= 0)
+                               synchronize_srcu(srcus[j]);
+                       up_write(rwsems[i]);
+               }
+               return;
+       }
+
+#ifdef CONFIG_TASKS_TRACE_RCU
+       if (testtype == 3) {
+               pr_info("%s: test_srcu_lockdep = %05d: SRCU and Tasks Trace RCU %d-way %sdeadlock.\n",
+                       __func__, test_srcu_lockdep, cyclelen, deadlock ? "" : "non-");
+               if (deadlock && cyclelen == 1)
+                       pr_info("%s: Expect hang.\n", __func__);
+               for (i = 0; i < cyclelen; i++) {
+                       char *fl = i == 0 ? "rcu_read_lock_trace" : "srcu_read_lock";
+                       char *fs = i == cyclelen - 1 ? "synchronize_rcu_tasks_trace"
+                                                    : "synchronize_srcu";
+                       char *fu = i == 0 ? "rcu_read_unlock_trace" : "srcu_read_unlock";
+
+                       j = srcu_lockdep_next(__func__, fl, fs, fu, i, cyclelen, deadlock);
+                       if (i == 0)
+                               rcu_read_lock_trace();
+                       else
+                               idx = srcu_read_lock(srcus[i]);
+                       if (j >= 0) {
+                               if (i == cyclelen - 1)
+                                       synchronize_rcu_tasks_trace();
+                               else
+                                       synchronize_srcu(srcus[j]);
+                       }
+                       if (i == 0)
+                               rcu_read_unlock_trace();
+                       else
+                               srcu_read_unlock(srcus[i], idx);
+               }
+               return;
+       }
+#endif // #ifdef CONFIG_TASKS_TRACE_RCU
+
+err_out:
+       pr_info("%s: test_srcu_lockdep = %05d does nothing.\n", __func__, test_srcu_lockdep);
+       pr_info("%s: test_srcu_lockdep = DNNL.\n", __func__);
+       pr_info("%s: D: Deadlock if nonzero.\n", __func__);
+       pr_info("%s: NN: Test number, 0=SRCU, 1=SRCU/mutex, 2=SRCU/rwsem, 3=SRCU/Tasks Trace RCU.\n", __func__);
+       pr_info("%s: L: Cycle length.\n", __func__);
+       if (!IS_ENABLED(CONFIG_TASKS_TRACE_RCU))
+               pr_info("%s: NN=3 disallowed because kernel is built with CONFIG_TASKS_TRACE_RCU=n\n", __func__);
+}
+
 static int __init
 rcu_torture_init(void)
 {
@@ -3501,9 +3708,17 @@ rcu_torture_init(void)
                pr_alert("rcu-torture: ->fqs NULL and non-zero fqs_duration, fqs disabled.\n");
                fqs_duration = 0;
        }
+       if (nocbs_nthreads != 0 && (cur_ops != &rcu_ops ||
+                                   !IS_ENABLED(CONFIG_RCU_NOCB_CPU))) {
+               pr_alert("rcu-torture types: %s and CONFIG_RCU_NOCB_CPU=%d, nocb toggle disabled.\n",
+                        cur_ops->name, IS_ENABLED(CONFIG_RCU_NOCB_CPU));
+               nocbs_nthreads = 0;
+       }
        if (cur_ops->init)
                cur_ops->init();
 
+       rcu_torture_init_srcu_lockdep();
+
        if (nreaders >= 0) {
                nrealreaders = nreaders;
        } else {
@@ -3540,7 +3755,6 @@ rcu_torture_init(void)
        atomic_set(&n_rcu_torture_error, 0);
        n_rcu_torture_barrier_error = 0;
        n_rcu_torture_boost_ktrerror = 0;
-       n_rcu_torture_boost_rterror = 0;
        n_rcu_torture_boost_failure = 0;
        n_rcu_torture_boosts = 0;
        for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
index afa3e1a2f6902c41c1c094efe09181e510a58142..1970ce5f22d405bc075015f5b8a4ec1f1635d1ee 100644 (file)
@@ -1031,7 +1031,7 @@ ref_scale_cleanup(void)
 static int
 ref_scale_shutdown(void *arg)
 {
-       wait_event(shutdown_wq, shutdown_start);
+       wait_event_idle(shutdown_wq, shutdown_start);
 
        smp_mb(); // Wake before output.
        ref_scale_cleanup();
index b12fb0cec44d61708302ebf388e2fdbcd2d58399..336af24e0fe358a71209120786ffa1d0255d63f6 100644 (file)
@@ -197,6 +197,8 @@ void synchronize_srcu(struct srcu_struct *ssp)
 {
        struct rcu_synchronize rs;
 
+       srcu_lock_sync(&ssp->dep_map);
+
        RCU_LOCKDEP_WARN(lockdep_is_held(ssp) ||
                        lock_is_held(&rcu_bh_lock_map) ||
                        lock_is_held(&rcu_lock_map) ||
index ab4ee58af84bfcfaf6890a6650b40117be09bfb0..20d7a238d675a8ece4b0ca1751944f176a38b305 100644 (file)
@@ -103,7 +103,7 @@ do {                                                                                \
 
 #define spin_trylock_irqsave_rcu_node(p, flags)                                        \
 ({                                                                             \
-       bool ___locked = spin_trylock_irqsave(&ACCESS_PRIVATE(p, lock), flags); \
+       bool ___locked = spin_trylock_irqsave(&ACCESS_PRIVATE(p, lock), flags); \
                                                                                \
        if (___locked)                                                          \
                smp_mb__after_unlock_lock();                                    \
@@ -135,8 +135,8 @@ static void init_srcu_struct_data(struct srcu_struct *ssp)
                spin_lock_init(&ACCESS_PRIVATE(sdp, lock));
                rcu_segcblist_init(&sdp->srcu_cblist);
                sdp->srcu_cblist_invoking = false;
-               sdp->srcu_gp_seq_needed = ssp->srcu_gp_seq;
-               sdp->srcu_gp_seq_needed_exp = ssp->srcu_gp_seq;
+               sdp->srcu_gp_seq_needed = ssp->srcu_sup->srcu_gp_seq;
+               sdp->srcu_gp_seq_needed_exp = ssp->srcu_sup->srcu_gp_seq;
                sdp->mynode = NULL;
                sdp->cpu = cpu;
                INIT_WORK(&sdp->work, srcu_invoke_callbacks);
@@ -173,14 +173,14 @@ static bool init_srcu_struct_nodes(struct srcu_struct *ssp, gfp_t gfp_flags)
 
        /* Initialize geometry if it has not already been initialized. */
        rcu_init_geometry();
-       ssp->node = kcalloc(rcu_num_nodes, sizeof(*ssp->node), gfp_flags);
-       if (!ssp->node)
+       ssp->srcu_sup->node = kcalloc(rcu_num_nodes, sizeof(*ssp->srcu_sup->node), gfp_flags);
+       if (!ssp->srcu_sup->node)
                return false;
 
        /* Work out the overall tree geometry. */
-       ssp->level[0] = &ssp->node[0];
+       ssp->srcu_sup->level[0] = &ssp->srcu_sup->node[0];
        for (i = 1; i < rcu_num_lvls; i++)
-               ssp->level[i] = ssp->level[i - 1] + num_rcu_lvl[i - 1];
+               ssp->srcu_sup->level[i] = ssp->srcu_sup->level[i - 1] + num_rcu_lvl[i - 1];
        rcu_init_levelspread(levelspread, num_rcu_lvl);
 
        /* Each pass through this loop initializes one srcu_node structure. */
@@ -195,17 +195,17 @@ static bool init_srcu_struct_nodes(struct srcu_struct *ssp, gfp_t gfp_flags)
                snp->srcu_gp_seq_needed_exp = SRCU_SNP_INIT_SEQ;
                snp->grplo = -1;
                snp->grphi = -1;
-               if (snp == &ssp->node[0]) {
+               if (snp == &ssp->srcu_sup->node[0]) {
                        /* Root node, special case. */
                        snp->srcu_parent = NULL;
                        continue;
                }
 
                /* Non-root node. */
-               if (snp == ssp->level[level + 1])
+               if (snp == ssp->srcu_sup->level[level + 1])
                        level++;
-               snp->srcu_parent = ssp->level[level - 1] +
-                                  (snp - ssp->level[level]) /
+               snp->srcu_parent = ssp->srcu_sup->level[level - 1] +
+                                  (snp - ssp->srcu_sup->level[level]) /
                                   levelspread[level - 1];
        }
 
@@ -214,7 +214,7 @@ static bool init_srcu_struct_nodes(struct srcu_struct *ssp, gfp_t gfp_flags)
         * leaves of the srcu_node tree.
         */
        level = rcu_num_lvls - 1;
-       snp_first = ssp->level[level];
+       snp_first = ssp->srcu_sup->level[level];
        for_each_possible_cpu(cpu) {
                sdp = per_cpu_ptr(ssp->sda, cpu);
                sdp->mynode = &snp_first[cpu / levelspread[level]];
@@ -225,7 +225,7 @@ static bool init_srcu_struct_nodes(struct srcu_struct *ssp, gfp_t gfp_flags)
                }
                sdp->grpmask = 1 << (cpu - sdp->mynode->grplo);
        }
-       smp_store_release(&ssp->srcu_size_state, SRCU_SIZE_WAIT_BARRIER);
+       smp_store_release(&ssp->srcu_sup->srcu_size_state, SRCU_SIZE_WAIT_BARRIER);
        return true;
 }
 
@@ -236,36 +236,47 @@ static bool init_srcu_struct_nodes(struct srcu_struct *ssp, gfp_t gfp_flags)
  */
 static int init_srcu_struct_fields(struct srcu_struct *ssp, bool is_static)
 {
-       ssp->srcu_size_state = SRCU_SIZE_SMALL;
-       ssp->node = NULL;
-       mutex_init(&ssp->srcu_cb_mutex);
-       mutex_init(&ssp->srcu_gp_mutex);
+       if (!is_static)
+               ssp->srcu_sup = kzalloc(sizeof(*ssp->srcu_sup), GFP_KERNEL);
+       if (!ssp->srcu_sup)
+               return -ENOMEM;
+       if (!is_static)
+               spin_lock_init(&ACCESS_PRIVATE(ssp->srcu_sup, lock));
+       ssp->srcu_sup->srcu_size_state = SRCU_SIZE_SMALL;
+       ssp->srcu_sup->node = NULL;
+       mutex_init(&ssp->srcu_sup->srcu_cb_mutex);
+       mutex_init(&ssp->srcu_sup->srcu_gp_mutex);
        ssp->srcu_idx = 0;
-       ssp->srcu_gp_seq = 0;
-       ssp->srcu_barrier_seq = 0;
-       mutex_init(&ssp->srcu_barrier_mutex);
-       atomic_set(&ssp->srcu_barrier_cpu_cnt, 0);
-       INIT_DELAYED_WORK(&ssp->work, process_srcu);
-       ssp->sda_is_static = is_static;
+       ssp->srcu_sup->srcu_gp_seq = 0;
+       ssp->srcu_sup->srcu_barrier_seq = 0;
+       mutex_init(&ssp->srcu_sup->srcu_barrier_mutex);
+       atomic_set(&ssp->srcu_sup->srcu_barrier_cpu_cnt, 0);
+       INIT_DELAYED_WORK(&ssp->srcu_sup->work, process_srcu);
+       ssp->srcu_sup->sda_is_static = is_static;
        if (!is_static)
                ssp->sda = alloc_percpu(struct srcu_data);
-       if (!ssp->sda)
+       if (!ssp->sda) {
+               if (!is_static)
+                       kfree(ssp->srcu_sup);
                return -ENOMEM;
+       }
        init_srcu_struct_data(ssp);
-       ssp->srcu_gp_seq_needed_exp = 0;
-       ssp->srcu_last_gp_end = ktime_get_mono_fast_ns();
-       if (READ_ONCE(ssp->srcu_size_state) == SRCU_SIZE_SMALL && SRCU_SIZING_IS_INIT()) {
+       ssp->srcu_sup->srcu_gp_seq_needed_exp = 0;
+       ssp->srcu_sup->srcu_last_gp_end = ktime_get_mono_fast_ns();
+       if (READ_ONCE(ssp->srcu_sup->srcu_size_state) == SRCU_SIZE_SMALL && SRCU_SIZING_IS_INIT()) {
                if (!init_srcu_struct_nodes(ssp, GFP_ATOMIC)) {
-                       if (!ssp->sda_is_static) {
+                       if (!ssp->srcu_sup->sda_is_static) {
                                free_percpu(ssp->sda);
                                ssp->sda = NULL;
+                               kfree(ssp->srcu_sup);
                                return -ENOMEM;
                        }
                } else {
-                       WRITE_ONCE(ssp->srcu_size_state, SRCU_SIZE_BIG);
+                       WRITE_ONCE(ssp->srcu_sup->srcu_size_state, SRCU_SIZE_BIG);
                }
        }
-       smp_store_release(&ssp->srcu_gp_seq_needed, 0); /* Init done. */
+       ssp->srcu_sup->srcu_ssp = ssp;
+       smp_store_release(&ssp->srcu_sup->srcu_gp_seq_needed, 0); /* Init done. */
        return 0;
 }
 
@@ -277,7 +288,6 @@ int __init_srcu_struct(struct srcu_struct *ssp, const char *name,
        /* Don't re-initialize a lock while it is held. */
        debug_check_no_locks_freed((void *)ssp, sizeof(*ssp));
        lockdep_init_map(&ssp->dep_map, name, key, 0);
-       spin_lock_init(&ACCESS_PRIVATE(ssp, lock));
        return init_srcu_struct_fields(ssp, false);
 }
 EXPORT_SYMBOL_GPL(__init_srcu_struct);
@@ -294,7 +304,6 @@ EXPORT_SYMBOL_GPL(__init_srcu_struct);
  */
 int init_srcu_struct(struct srcu_struct *ssp)
 {
-       spin_lock_init(&ACCESS_PRIVATE(ssp, lock));
        return init_srcu_struct_fields(ssp, false);
 }
 EXPORT_SYMBOL_GPL(init_srcu_struct);
@@ -306,8 +315,8 @@ EXPORT_SYMBOL_GPL(init_srcu_struct);
  */
 static void __srcu_transition_to_big(struct srcu_struct *ssp)
 {
-       lockdep_assert_held(&ACCESS_PRIVATE(ssp, lock));
-       smp_store_release(&ssp->srcu_size_state, SRCU_SIZE_ALLOC);
+       lockdep_assert_held(&ACCESS_PRIVATE(ssp->srcu_sup, lock));
+       smp_store_release(&ssp->srcu_sup->srcu_size_state, SRCU_SIZE_ALLOC);
 }
 
 /*
@@ -318,15 +327,15 @@ static void srcu_transition_to_big(struct srcu_struct *ssp)
        unsigned long flags;
 
        /* Double-checked locking on ->srcu_size-state. */
-       if (smp_load_acquire(&ssp->srcu_size_state) != SRCU_SIZE_SMALL)
+       if (smp_load_acquire(&ssp->srcu_sup->srcu_size_state) != SRCU_SIZE_SMALL)
                return;
-       spin_lock_irqsave_rcu_node(ssp, flags);
-       if (smp_load_acquire(&ssp->srcu_size_state) != SRCU_SIZE_SMALL) {
-               spin_unlock_irqrestore_rcu_node(ssp, flags);
+       spin_lock_irqsave_rcu_node(ssp->srcu_sup, flags);
+       if (smp_load_acquire(&ssp->srcu_sup->srcu_size_state) != SRCU_SIZE_SMALL) {
+               spin_unlock_irqrestore_rcu_node(ssp->srcu_sup, flags);
                return;
        }
        __srcu_transition_to_big(ssp);
-       spin_unlock_irqrestore_rcu_node(ssp, flags);
+       spin_unlock_irqrestore_rcu_node(ssp->srcu_sup, flags);
 }
 
 /*
@@ -337,14 +346,14 @@ static void spin_lock_irqsave_check_contention(struct srcu_struct *ssp)
 {
        unsigned long j;
 
-       if (!SRCU_SIZING_IS_CONTEND() || ssp->srcu_size_state)
+       if (!SRCU_SIZING_IS_CONTEND() || ssp->srcu_sup->srcu_size_state)
                return;
        j = jiffies;
-       if (ssp->srcu_size_jiffies != j) {
-               ssp->srcu_size_jiffies = j;
-               ssp->srcu_n_lock_retries = 0;
+       if (ssp->srcu_sup->srcu_size_jiffies != j) {
+               ssp->srcu_sup->srcu_size_jiffies = j;
+               ssp->srcu_sup->srcu_n_lock_retries = 0;
        }
-       if (++ssp->srcu_n_lock_retries <= small_contention_lim)
+       if (++ssp->srcu_sup->srcu_n_lock_retries <= small_contention_lim)
                return;
        __srcu_transition_to_big(ssp);
 }
@@ -361,9 +370,9 @@ static void spin_lock_irqsave_sdp_contention(struct srcu_data *sdp, unsigned lon
 
        if (spin_trylock_irqsave_rcu_node(sdp, *flags))
                return;
-       spin_lock_irqsave_rcu_node(ssp, *flags);
+       spin_lock_irqsave_rcu_node(ssp->srcu_sup, *flags);
        spin_lock_irqsave_check_contention(ssp);
-       spin_unlock_irqrestore_rcu_node(ssp, *flags);
+       spin_unlock_irqrestore_rcu_node(ssp->srcu_sup, *flags);
        spin_lock_irqsave_rcu_node(sdp, *flags);
 }
 
@@ -375,9 +384,9 @@ static void spin_lock_irqsave_sdp_contention(struct srcu_data *sdp, unsigned lon
  */
 static void spin_lock_irqsave_ssp_contention(struct srcu_struct *ssp, unsigned long *flags)
 {
-       if (spin_trylock_irqsave_rcu_node(ssp, *flags))
+       if (spin_trylock_irqsave_rcu_node(ssp->srcu_sup, *flags))
                return;
-       spin_lock_irqsave_rcu_node(ssp, *flags);
+       spin_lock_irqsave_rcu_node(ssp->srcu_sup, *flags);
        spin_lock_irqsave_check_contention(ssp);
 }
 
@@ -394,15 +403,15 @@ static void check_init_srcu_struct(struct srcu_struct *ssp)
        unsigned long flags;
 
        /* The smp_load_acquire() pairs with the smp_store_release(). */
-       if (!rcu_seq_state(smp_load_acquire(&ssp->srcu_gp_seq_needed))) /*^^^*/
+       if (!rcu_seq_state(smp_load_acquire(&ssp->srcu_sup->srcu_gp_seq_needed))) /*^^^*/
                return; /* Already initialized. */
-       spin_lock_irqsave_rcu_node(ssp, flags);
-       if (!rcu_seq_state(ssp->srcu_gp_seq_needed)) {
-               spin_unlock_irqrestore_rcu_node(ssp, flags);
+       spin_lock_irqsave_rcu_node(ssp->srcu_sup, flags);
+       if (!rcu_seq_state(ssp->srcu_sup->srcu_gp_seq_needed)) {
+               spin_unlock_irqrestore_rcu_node(ssp->srcu_sup, flags);
                return;
        }
        init_srcu_struct_fields(ssp, true);
-       spin_unlock_irqrestore_rcu_node(ssp, flags);
+       spin_unlock_irqrestore_rcu_node(ssp->srcu_sup, flags);
 }
 
 /*
@@ -607,17 +616,18 @@ static unsigned long srcu_get_delay(struct srcu_struct *ssp)
        unsigned long gpstart;
        unsigned long j;
        unsigned long jbase = SRCU_INTERVAL;
+       struct srcu_usage *sup = ssp->srcu_sup;
 
-       if (ULONG_CMP_LT(READ_ONCE(ssp->srcu_gp_seq), READ_ONCE(ssp->srcu_gp_seq_needed_exp)))
+       if (ULONG_CMP_LT(READ_ONCE(sup->srcu_gp_seq), READ_ONCE(sup->srcu_gp_seq_needed_exp)))
                jbase = 0;
-       if (rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq))) {
+       if (rcu_seq_state(READ_ONCE(sup->srcu_gp_seq))) {
                j = jiffies - 1;
-               gpstart = READ_ONCE(ssp->srcu_gp_start);
+               gpstart = READ_ONCE(sup->srcu_gp_start);
                if (time_after(j, gpstart))
                        jbase += j - gpstart;
                if (!jbase) {
-                       WRITE_ONCE(ssp->srcu_n_exp_nodelay, READ_ONCE(ssp->srcu_n_exp_nodelay) + 1);
-                       if (READ_ONCE(ssp->srcu_n_exp_nodelay) > srcu_max_nodelay_phase)
+                       WRITE_ONCE(sup->srcu_n_exp_nodelay, READ_ONCE(sup->srcu_n_exp_nodelay) + 1);
+                       if (READ_ONCE(sup->srcu_n_exp_nodelay) > srcu_max_nodelay_phase)
                                jbase = 1;
                }
        }
@@ -634,12 +644,13 @@ static unsigned long srcu_get_delay(struct srcu_struct *ssp)
 void cleanup_srcu_struct(struct srcu_struct *ssp)
 {
        int cpu;
+       struct srcu_usage *sup = ssp->srcu_sup;
 
        if (WARN_ON(!srcu_get_delay(ssp)))
                return; /* Just leak it! */
        if (WARN_ON(srcu_readers_active(ssp)))
                return; /* Just leak it! */
-       flush_delayed_work(&ssp->work);
+       flush_delayed_work(&sup->work);
        for_each_possible_cpu(cpu) {
                struct srcu_data *sdp = per_cpu_ptr(ssp->sda, cpu);
 
@@ -648,21 +659,23 @@ void cleanup_srcu_struct(struct srcu_struct *ssp)
                if (WARN_ON(rcu_segcblist_n_cbs(&sdp->srcu_cblist)))
                        return; /* Forgot srcu_barrier(), so just leak it! */
        }
-       if (WARN_ON(rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)) != SRCU_STATE_IDLE) ||
-           WARN_ON(rcu_seq_current(&ssp->srcu_gp_seq) != ssp->srcu_gp_seq_needed) ||
+       if (WARN_ON(rcu_seq_state(READ_ONCE(sup->srcu_gp_seq)) != SRCU_STATE_IDLE) ||
+           WARN_ON(rcu_seq_current(&sup->srcu_gp_seq) != sup->srcu_gp_seq_needed) ||
            WARN_ON(srcu_readers_active(ssp))) {
                pr_info("%s: Active srcu_struct %p read state: %d gp state: %lu/%lu\n",
-                       __func__, ssp, rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)),
-                       rcu_seq_current(&ssp->srcu_gp_seq), ssp->srcu_gp_seq_needed);
+                       __func__, ssp, rcu_seq_state(READ_ONCE(sup->srcu_gp_seq)),
+                       rcu_seq_current(&sup->srcu_gp_seq), sup->srcu_gp_seq_needed);
                return; /* Caller forgot to stop doing call_srcu()? */
        }
-       if (!ssp->sda_is_static) {
+       kfree(sup->node);
+       sup->node = NULL;
+       sup->srcu_size_state = SRCU_SIZE_SMALL;
+       if (!sup->sda_is_static) {
                free_percpu(ssp->sda);
                ssp->sda = NULL;
+               kfree(sup);
+               ssp->srcu_sup = NULL;
        }
-       kfree(ssp->node);
-       ssp->node = NULL;
-       ssp->srcu_size_state = SRCU_SIZE_SMALL;
 }
 EXPORT_SYMBOL_GPL(cleanup_srcu_struct);
 
@@ -760,23 +773,23 @@ static void srcu_gp_start(struct srcu_struct *ssp)
        struct srcu_data *sdp;
        int state;
 
-       if (smp_load_acquire(&ssp->srcu_size_state) < SRCU_SIZE_WAIT_BARRIER)
+       if (smp_load_acquire(&ssp->srcu_sup->srcu_size_state) < SRCU_SIZE_WAIT_BARRIER)
                sdp = per_cpu_ptr(ssp->sda, get_boot_cpu_id());
        else
                sdp = this_cpu_ptr(ssp->sda);
-       lockdep_assert_held(&ACCESS_PRIVATE(ssp, lock));
-       WARN_ON_ONCE(ULONG_CMP_GE(ssp->srcu_gp_seq, ssp->srcu_gp_seq_needed));
+       lockdep_assert_held(&ACCESS_PRIVATE(ssp->srcu_sup, lock));
+       WARN_ON_ONCE(ULONG_CMP_GE(ssp->srcu_sup->srcu_gp_seq, ssp->srcu_sup->srcu_gp_seq_needed));
        spin_lock_rcu_node(sdp);  /* Interrupts already disabled. */
        rcu_segcblist_advance(&sdp->srcu_cblist,
-                             rcu_seq_current(&ssp->srcu_gp_seq));
+                             rcu_seq_current(&ssp->srcu_sup->srcu_gp_seq));
        (void)rcu_segcblist_accelerate(&sdp->srcu_cblist,
-                                      rcu_seq_snap(&ssp->srcu_gp_seq));
+                                      rcu_seq_snap(&ssp->srcu_sup->srcu_gp_seq));
        spin_unlock_rcu_node(sdp);  /* Interrupts remain disabled. */
-       WRITE_ONCE(ssp->srcu_gp_start, jiffies);
-       WRITE_ONCE(ssp->srcu_n_exp_nodelay, 0);
+       WRITE_ONCE(ssp->srcu_sup->srcu_gp_start, jiffies);
+       WRITE_ONCE(ssp->srcu_sup->srcu_n_exp_nodelay, 0);
        smp_mb(); /* Order prior store to ->srcu_gp_seq_needed vs. GP start. */
-       rcu_seq_start(&ssp->srcu_gp_seq);
-       state = rcu_seq_state(ssp->srcu_gp_seq);
+       rcu_seq_start(&ssp->srcu_sup->srcu_gp_seq);
+       state = rcu_seq_state(ssp->srcu_sup->srcu_gp_seq);
        WARN_ON_ONCE(state != SRCU_STATE_SCAN1);
 }
 
@@ -849,28 +862,29 @@ static void srcu_gp_end(struct srcu_struct *ssp)
        unsigned long sgsne;
        struct srcu_node *snp;
        int ss_state;
+       struct srcu_usage *sup = ssp->srcu_sup;
 
        /* Prevent more than one additional grace period. */
-       mutex_lock(&ssp->srcu_cb_mutex);
+       mutex_lock(&sup->srcu_cb_mutex);
 
        /* End the current grace period. */
-       spin_lock_irq_rcu_node(ssp);
-       idx = rcu_seq_state(ssp->srcu_gp_seq);
+       spin_lock_irq_rcu_node(sup);
+       idx = rcu_seq_state(sup->srcu_gp_seq);
        WARN_ON_ONCE(idx != SRCU_STATE_SCAN2);
-       if (ULONG_CMP_LT(READ_ONCE(ssp->srcu_gp_seq), READ_ONCE(ssp->srcu_gp_seq_needed_exp)))
+       if (ULONG_CMP_LT(READ_ONCE(sup->srcu_gp_seq), READ_ONCE(sup->srcu_gp_seq_needed_exp)))
                cbdelay = 0;
 
-       WRITE_ONCE(ssp->srcu_last_gp_end, ktime_get_mono_fast_ns());
-       rcu_seq_end(&ssp->srcu_gp_seq);
-       gpseq = rcu_seq_current(&ssp->srcu_gp_seq);
-       if (ULONG_CMP_LT(ssp->srcu_gp_seq_needed_exp, gpseq))
-               WRITE_ONCE(ssp->srcu_gp_seq_needed_exp, gpseq);
-       spin_unlock_irq_rcu_node(ssp);
-       mutex_unlock(&ssp->srcu_gp_mutex);
+       WRITE_ONCE(sup->srcu_last_gp_end, ktime_get_mono_fast_ns());
+       rcu_seq_end(&sup->srcu_gp_seq);
+       gpseq = rcu_seq_current(&sup->srcu_gp_seq);
+       if (ULONG_CMP_LT(sup->srcu_gp_seq_needed_exp, gpseq))
+               WRITE_ONCE(sup->srcu_gp_seq_needed_exp, gpseq);
+       spin_unlock_irq_rcu_node(sup);
+       mutex_unlock(&sup->srcu_gp_mutex);
        /* A new grace period can start at this point.  But only one. */
 
        /* Initiate callback invocation as needed. */
-       ss_state = smp_load_acquire(&ssp->srcu_size_state);
+       ss_state = smp_load_acquire(&sup->srcu_size_state);
        if (ss_state < SRCU_SIZE_WAIT_BARRIER) {
                srcu_schedule_cbs_sdp(per_cpu_ptr(ssp->sda, get_boot_cpu_id()),
                                        cbdelay);
@@ -879,7 +893,7 @@ static void srcu_gp_end(struct srcu_struct *ssp)
                srcu_for_each_node_breadth_first(ssp, snp) {
                        spin_lock_irq_rcu_node(snp);
                        cbs = false;
-                       last_lvl = snp >= ssp->level[rcu_num_lvls - 1];
+                       last_lvl = snp >= sup->level[rcu_num_lvls - 1];
                        if (last_lvl)
                                cbs = ss_state < SRCU_SIZE_BIG || snp->srcu_have_cbs[idx] == gpseq;
                        snp->srcu_have_cbs[idx] = gpseq;
@@ -911,18 +925,18 @@ static void srcu_gp_end(struct srcu_struct *ssp)
                }
 
        /* Callback initiation done, allow grace periods after next. */
-       mutex_unlock(&ssp->srcu_cb_mutex);
+       mutex_unlock(&sup->srcu_cb_mutex);
 
        /* Start a new grace period if needed. */
-       spin_lock_irq_rcu_node(ssp);
-       gpseq = rcu_seq_current(&ssp->srcu_gp_seq);
+       spin_lock_irq_rcu_node(sup);
+       gpseq = rcu_seq_current(&sup->srcu_gp_seq);
        if (!rcu_seq_state(gpseq) &&
-           ULONG_CMP_LT(gpseq, ssp->srcu_gp_seq_needed)) {
+           ULONG_CMP_LT(gpseq, sup->srcu_gp_seq_needed)) {
                srcu_gp_start(ssp);
-               spin_unlock_irq_rcu_node(ssp);
+               spin_unlock_irq_rcu_node(sup);
                srcu_reschedule(ssp, 0);
        } else {
-               spin_unlock_irq_rcu_node(ssp);
+               spin_unlock_irq_rcu_node(sup);
        }
 
        /* Transition to big if needed. */
@@ -930,7 +944,7 @@ static void srcu_gp_end(struct srcu_struct *ssp)
                if (ss_state == SRCU_SIZE_ALLOC)
                        init_srcu_struct_nodes(ssp, GFP_KERNEL);
                else
-                       smp_store_release(&ssp->srcu_size_state, ss_state + 1);
+                       smp_store_release(&sup->srcu_size_state, ss_state + 1);
        }
 }
 
@@ -950,7 +964,7 @@ static void srcu_funnel_exp_start(struct srcu_struct *ssp, struct srcu_node *snp
        if (snp)
                for (; snp != NULL; snp = snp->srcu_parent) {
                        sgsne = READ_ONCE(snp->srcu_gp_seq_needed_exp);
-                       if (WARN_ON_ONCE(rcu_seq_done(&ssp->srcu_gp_seq, s)) ||
+                       if (WARN_ON_ONCE(rcu_seq_done(&ssp->srcu_sup->srcu_gp_seq, s)) ||
                            (!srcu_invl_snp_seq(sgsne) && ULONG_CMP_GE(sgsne, s)))
                                return;
                        spin_lock_irqsave_rcu_node(snp, flags);
@@ -963,9 +977,9 @@ static void srcu_funnel_exp_start(struct srcu_struct *ssp, struct srcu_node *snp
                        spin_unlock_irqrestore_rcu_node(snp, flags);
                }
        spin_lock_irqsave_ssp_contention(ssp, &flags);
-       if (ULONG_CMP_LT(ssp->srcu_gp_seq_needed_exp, s))
-               WRITE_ONCE(ssp->srcu_gp_seq_needed_exp, s);
-       spin_unlock_irqrestore_rcu_node(ssp, flags);
+       if (ULONG_CMP_LT(ssp->srcu_sup->srcu_gp_seq_needed_exp, s))
+               WRITE_ONCE(ssp->srcu_sup->srcu_gp_seq_needed_exp, s);
+       spin_unlock_irqrestore_rcu_node(ssp->srcu_sup, flags);
 }
 
 /*
@@ -990,9 +1004,10 @@ static void srcu_funnel_gp_start(struct srcu_struct *ssp, struct srcu_data *sdp,
        struct srcu_node *snp;
        struct srcu_node *snp_leaf;
        unsigned long snp_seq;
+       struct srcu_usage *sup = ssp->srcu_sup;
 
        /* Ensure that snp node tree is fully initialized before traversing it */
-       if (smp_load_acquire(&ssp->srcu_size_state) < SRCU_SIZE_WAIT_BARRIER)
+       if (smp_load_acquire(&sup->srcu_size_state) < SRCU_SIZE_WAIT_BARRIER)
                snp_leaf = NULL;
        else
                snp_leaf = sdp->mynode;
@@ -1000,7 +1015,7 @@ static void srcu_funnel_gp_start(struct srcu_struct *ssp, struct srcu_data *sdp,
        if (snp_leaf)
                /* Each pass through the loop does one level of the srcu_node tree. */
                for (snp = snp_leaf; snp != NULL; snp = snp->srcu_parent) {
-                       if (WARN_ON_ONCE(rcu_seq_done(&ssp->srcu_gp_seq, s)) && snp != snp_leaf)
+                       if (WARN_ON_ONCE(rcu_seq_done(&sup->srcu_gp_seq, s)) && snp != snp_leaf)
                                return; /* GP already done and CBs recorded. */
                        spin_lock_irqsave_rcu_node(snp, flags);
                        snp_seq = snp->srcu_have_cbs[idx];
@@ -1027,20 +1042,20 @@ static void srcu_funnel_gp_start(struct srcu_struct *ssp, struct srcu_data *sdp,
 
        /* Top of tree, must ensure the grace period will be started. */
        spin_lock_irqsave_ssp_contention(ssp, &flags);
-       if (ULONG_CMP_LT(ssp->srcu_gp_seq_needed, s)) {
+       if (ULONG_CMP_LT(sup->srcu_gp_seq_needed, s)) {
                /*
                 * Record need for grace period s.  Pair with load
                 * acquire setting up for initialization.
                 */
-               smp_store_release(&ssp->srcu_gp_seq_needed, s); /*^^^*/
+               smp_store_release(&sup->srcu_gp_seq_needed, s); /*^^^*/
        }
-       if (!do_norm && ULONG_CMP_LT(ssp->srcu_gp_seq_needed_exp, s))
-               WRITE_ONCE(ssp->srcu_gp_seq_needed_exp, s);
+       if (!do_norm && ULONG_CMP_LT(sup->srcu_gp_seq_needed_exp, s))
+               WRITE_ONCE(sup->srcu_gp_seq_needed_exp, s);
 
        /* If grace period not already in progress, start it. */
-       if (!WARN_ON_ONCE(rcu_seq_done(&ssp->srcu_gp_seq, s)) &&
-           rcu_seq_state(ssp->srcu_gp_seq) == SRCU_STATE_IDLE) {
-               WARN_ON_ONCE(ULONG_CMP_GE(ssp->srcu_gp_seq, ssp->srcu_gp_seq_needed));
+       if (!WARN_ON_ONCE(rcu_seq_done(&sup->srcu_gp_seq, s)) &&
+           rcu_seq_state(sup->srcu_gp_seq) == SRCU_STATE_IDLE) {
+               WARN_ON_ONCE(ULONG_CMP_GE(sup->srcu_gp_seq, sup->srcu_gp_seq_needed));
                srcu_gp_start(ssp);
 
                // And how can that list_add() in the "else" clause
@@ -1049,12 +1064,12 @@ static void srcu_funnel_gp_start(struct srcu_struct *ssp, struct srcu_data *sdp,
                // can only be executed during early boot when there is only
                // the one boot CPU running with interrupts still disabled.
                if (likely(srcu_init_done))
-                       queue_delayed_work(rcu_gp_wq, &ssp->work,
+                       queue_delayed_work(rcu_gp_wq, &sup->work,
                                           !!srcu_get_delay(ssp));
-               else if (list_empty(&ssp->work.work.entry))
-                       list_add(&ssp->work.work.entry, &srcu_boot_list);
+               else if (list_empty(&sup->work.work.entry))
+                       list_add(&sup->work.work.entry, &srcu_boot_list);
        }
-       spin_unlock_irqrestore_rcu_node(ssp, flags);
+       spin_unlock_irqrestore_rcu_node(sup, flags);
 }
 
 /*
@@ -1085,16 +1100,36 @@ static bool try_check_zero(struct srcu_struct *ssp, int idx, int trycount)
 static void srcu_flip(struct srcu_struct *ssp)
 {
        /*
-        * Ensure that if this updater saw a given reader's increment
-        * from __srcu_read_lock(), that reader was using an old value
-        * of ->srcu_idx.  Also ensure that if a given reader sees the
-        * new value of ->srcu_idx, this updater's earlier scans cannot
-        * have seen that reader's increments (which is OK, because this
-        * grace period need not wait on that reader).
+        * Because the flip of ->srcu_idx is executed only if the
+        * preceding call to srcu_readers_active_idx_check() found that
+        * the ->srcu_unlock_count[] and ->srcu_lock_count[] sums matched
+        * and because that summing uses atomic_long_read(), there is
+        * ordering due to a control dependency between that summing and
+        * the WRITE_ONCE() in this call to srcu_flip().  This ordering
+        * ensures that if this updater saw a given reader's increment from
+        * __srcu_read_lock(), that reader was using a value of ->srcu_idx
+        * from before the previous call to srcu_flip(), which should be
+        * quite rare.  This ordering thus helps forward progress because
+        * the grace period could otherwise be delayed by additional
+        * calls to __srcu_read_lock() using that old (soon to be new)
+        * value of ->srcu_idx.
+        *
+        * This sum-equality check and ordering also ensures that if
+        * a given call to __srcu_read_lock() uses the new value of
+        * ->srcu_idx, this updater's earlier scans cannot have seen
+        * that reader's increments, which is all to the good, because
+        * this grace period need not wait on that reader.  After all,
+        * if those earlier scans had seen that reader, there would have
+        * been a sum mismatch and this code would not be reached.
+        *
+        * This means that the following smp_mb() is redundant, but
+        * it stays until either (1) Compilers learn about this sort of
+        * control dependency or (2) Some production workload running on
+        * a production system is unduly delayed by this slowpath smp_mb().
         */
        smp_mb(); /* E */  /* Pairs with B and C. */
 
-       WRITE_ONCE(ssp->srcu_idx, ssp->srcu_idx + 1);
+       WRITE_ONCE(ssp->srcu_idx, ssp->srcu_idx + 1); // Flip the counter.
 
        /*
         * Ensure that if the updater misses an __srcu_read_unlock()
@@ -1154,18 +1189,18 @@ static bool srcu_might_be_idle(struct srcu_struct *ssp)
 
        /* First, see if enough time has passed since the last GP. */
        t = ktime_get_mono_fast_ns();
-       tlast = READ_ONCE(ssp->srcu_last_gp_end);
+       tlast = READ_ONCE(ssp->srcu_sup->srcu_last_gp_end);
        if (exp_holdoff == 0 ||
            time_in_range_open(t, tlast, tlast + exp_holdoff))
                return false; /* Too soon after last GP. */
 
        /* Next, check for probable idleness. */
-       curseq = rcu_seq_current(&ssp->srcu_gp_seq);
+       curseq = rcu_seq_current(&ssp->srcu_sup->srcu_gp_seq);
        smp_mb(); /* Order ->srcu_gp_seq with ->srcu_gp_seq_needed. */
-       if (ULONG_CMP_LT(curseq, READ_ONCE(ssp->srcu_gp_seq_needed)))
+       if (ULONG_CMP_LT(curseq, READ_ONCE(ssp->srcu_sup->srcu_gp_seq_needed)))
                return false; /* Grace period in progress, so not idle. */
        smp_mb(); /* Order ->srcu_gp_seq with prior access. */
-       if (curseq != rcu_seq_current(&ssp->srcu_gp_seq))
+       if (curseq != rcu_seq_current(&ssp->srcu_sup->srcu_gp_seq))
                return false; /* GP # changed, so not idle. */
        return true; /* With reasonable probability, idle! */
 }
@@ -1199,7 +1234,7 @@ static unsigned long srcu_gp_start_if_needed(struct srcu_struct *ssp,
         * sequence number cannot wrap around in the meantime.
         */
        idx = __srcu_read_lock_nmisafe(ssp);
-       ss_state = smp_load_acquire(&ssp->srcu_size_state);
+       ss_state = smp_load_acquire(&ssp->srcu_sup->srcu_size_state);
        if (ss_state < SRCU_SIZE_WAIT_CALL)
                sdp = per_cpu_ptr(ssp->sda, get_boot_cpu_id());
        else
@@ -1208,8 +1243,8 @@ static unsigned long srcu_gp_start_if_needed(struct srcu_struct *ssp,
        if (rhp)
                rcu_segcblist_enqueue(&sdp->srcu_cblist, rhp);
        rcu_segcblist_advance(&sdp->srcu_cblist,
-                             rcu_seq_current(&ssp->srcu_gp_seq));
-       s = rcu_seq_snap(&ssp->srcu_gp_seq);
+                             rcu_seq_current(&ssp->srcu_sup->srcu_gp_seq));
+       s = rcu_seq_snap(&ssp->srcu_sup->srcu_gp_seq);
        (void)rcu_segcblist_accelerate(&sdp->srcu_cblist, s);
        if (ULONG_CMP_LT(sdp->srcu_gp_seq_needed, s)) {
                sdp->srcu_gp_seq_needed = s;
@@ -1307,6 +1342,8 @@ static void __synchronize_srcu(struct srcu_struct *ssp, bool do_norm)
 {
        struct rcu_synchronize rcu;
 
+       srcu_lock_sync(&ssp->dep_map);
+
        RCU_LOCKDEP_WARN(lockdep_is_held(ssp) ||
                         lock_is_held(&rcu_bh_lock_map) ||
                         lock_is_held(&rcu_lock_map) ||
@@ -1420,7 +1457,7 @@ unsigned long get_state_synchronize_srcu(struct srcu_struct *ssp)
        // Any prior manipulation of SRCU-protected data must happen
        // before the load from ->srcu_gp_seq.
        smp_mb();
-       return rcu_seq_snap(&ssp->srcu_gp_seq);
+       return rcu_seq_snap(&ssp->srcu_sup->srcu_gp_seq);
 }
 EXPORT_SYMBOL_GPL(get_state_synchronize_srcu);
 
@@ -1467,7 +1504,7 @@ EXPORT_SYMBOL_GPL(start_poll_synchronize_srcu);
  */
 bool poll_state_synchronize_srcu(struct srcu_struct *ssp, unsigned long cookie)
 {
-       if (!rcu_seq_done(&ssp->srcu_gp_seq, cookie))
+       if (!rcu_seq_done(&ssp->srcu_sup->srcu_gp_seq, cookie))
                return false;
        // Ensure that the end of the SRCU grace period happens before
        // any subsequent code that the caller might execute.
@@ -1486,8 +1523,8 @@ static void srcu_barrier_cb(struct rcu_head *rhp)
 
        sdp = container_of(rhp, struct srcu_data, srcu_barrier_head);
        ssp = sdp->ssp;
-       if (atomic_dec_and_test(&ssp->srcu_barrier_cpu_cnt))
-               complete(&ssp->srcu_barrier_completion);
+       if (atomic_dec_and_test(&ssp->srcu_sup->srcu_barrier_cpu_cnt))
+               complete(&ssp->srcu_sup->srcu_barrier_completion);
 }
 
 /*
@@ -1501,13 +1538,13 @@ static void srcu_barrier_cb(struct rcu_head *rhp)
 static void srcu_barrier_one_cpu(struct srcu_struct *ssp, struct srcu_data *sdp)
 {
        spin_lock_irq_rcu_node(sdp);
-       atomic_inc(&ssp->srcu_barrier_cpu_cnt);
+       atomic_inc(&ssp->srcu_sup->srcu_barrier_cpu_cnt);
        sdp->srcu_barrier_head.func = srcu_barrier_cb;
        debug_rcu_head_queue(&sdp->srcu_barrier_head);
        if (!rcu_segcblist_entrain(&sdp->srcu_cblist,
                                   &sdp->srcu_barrier_head)) {
                debug_rcu_head_unqueue(&sdp->srcu_barrier_head);
-               atomic_dec(&ssp->srcu_barrier_cpu_cnt);
+               atomic_dec(&ssp->srcu_sup->srcu_barrier_cpu_cnt);
        }
        spin_unlock_irq_rcu_node(sdp);
 }
@@ -1520,23 +1557,23 @@ void srcu_barrier(struct srcu_struct *ssp)
 {
        int cpu;
        int idx;
-       unsigned long s = rcu_seq_snap(&ssp->srcu_barrier_seq);
+       unsigned long s = rcu_seq_snap(&ssp->srcu_sup->srcu_barrier_seq);
 
        check_init_srcu_struct(ssp);
-       mutex_lock(&ssp->srcu_barrier_mutex);
-       if (rcu_seq_done(&ssp->srcu_barrier_seq, s)) {
+       mutex_lock(&ssp->srcu_sup->srcu_barrier_mutex);
+       if (rcu_seq_done(&ssp->srcu_sup->srcu_barrier_seq, s)) {
                smp_mb(); /* Force ordering following return. */
-               mutex_unlock(&ssp->srcu_barrier_mutex);
+               mutex_unlock(&ssp->srcu_sup->srcu_barrier_mutex);
                return; /* Someone else did our work for us. */
        }
-       rcu_seq_start(&ssp->srcu_barrier_seq);
-       init_completion(&ssp->srcu_barrier_completion);
+       rcu_seq_start(&ssp->srcu_sup->srcu_barrier_seq);
+       init_completion(&ssp->srcu_sup->srcu_barrier_completion);
 
        /* Initial count prevents reaching zero until all CBs are posted. */
-       atomic_set(&ssp->srcu_barrier_cpu_cnt, 1);
+       atomic_set(&ssp->srcu_sup->srcu_barrier_cpu_cnt, 1);
 
        idx = __srcu_read_lock_nmisafe(ssp);
-       if (smp_load_acquire(&ssp->srcu_size_state) < SRCU_SIZE_WAIT_BARRIER)
+       if (smp_load_acquire(&ssp->srcu_sup->srcu_size_state) < SRCU_SIZE_WAIT_BARRIER)
                srcu_barrier_one_cpu(ssp, per_cpu_ptr(ssp->sda, get_boot_cpu_id()));
        else
                for_each_possible_cpu(cpu)
@@ -1544,12 +1581,12 @@ void srcu_barrier(struct srcu_struct *ssp)
        __srcu_read_unlock_nmisafe(ssp, idx);
 
        /* Remove the initial count, at which point reaching zero can happen. */
-       if (atomic_dec_and_test(&ssp->srcu_barrier_cpu_cnt))
-               complete(&ssp->srcu_barrier_completion);
-       wait_for_completion(&ssp->srcu_barrier_completion);
+       if (atomic_dec_and_test(&ssp->srcu_sup->srcu_barrier_cpu_cnt))
+               complete(&ssp->srcu_sup->srcu_barrier_completion);
+       wait_for_completion(&ssp->srcu_sup->srcu_barrier_completion);
 
-       rcu_seq_end(&ssp->srcu_barrier_seq);
-       mutex_unlock(&ssp->srcu_barrier_mutex);
+       rcu_seq_end(&ssp->srcu_sup->srcu_barrier_seq);
+       mutex_unlock(&ssp->srcu_sup->srcu_barrier_mutex);
 }
 EXPORT_SYMBOL_GPL(srcu_barrier);
 
@@ -1575,7 +1612,7 @@ static void srcu_advance_state(struct srcu_struct *ssp)
 {
        int idx;
 
-       mutex_lock(&ssp->srcu_gp_mutex);
+       mutex_lock(&ssp->srcu_sup->srcu_gp_mutex);
 
        /*
         * Because readers might be delayed for an extended period after
@@ -1587,39 +1624,39 @@ static void srcu_advance_state(struct srcu_struct *ssp)
         * The load-acquire ensures that we see the accesses performed
         * by the prior grace period.
         */
-       idx = rcu_seq_state(smp_load_acquire(&ssp->srcu_gp_seq)); /* ^^^ */
+       idx = rcu_seq_state(smp_load_acquire(&ssp->srcu_sup->srcu_gp_seq)); /* ^^^ */
        if (idx == SRCU_STATE_IDLE) {
-               spin_lock_irq_rcu_node(ssp);
-               if (ULONG_CMP_GE(ssp->srcu_gp_seq, ssp->srcu_gp_seq_needed)) {
-                       WARN_ON_ONCE(rcu_seq_state(ssp->srcu_gp_seq));
-                       spin_unlock_irq_rcu_node(ssp);
-                       mutex_unlock(&ssp->srcu_gp_mutex);
+               spin_lock_irq_rcu_node(ssp->srcu_sup);
+               if (ULONG_CMP_GE(ssp->srcu_sup->srcu_gp_seq, ssp->srcu_sup->srcu_gp_seq_needed)) {
+                       WARN_ON_ONCE(rcu_seq_state(ssp->srcu_sup->srcu_gp_seq));
+                       spin_unlock_irq_rcu_node(ssp->srcu_sup);
+                       mutex_unlock(&ssp->srcu_sup->srcu_gp_mutex);
                        return;
                }
-               idx = rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq));
+               idx = rcu_seq_state(READ_ONCE(ssp->srcu_sup->srcu_gp_seq));
                if (idx == SRCU_STATE_IDLE)
                        srcu_gp_start(ssp);
-               spin_unlock_irq_rcu_node(ssp);
+               spin_unlock_irq_rcu_node(ssp->srcu_sup);
                if (idx != SRCU_STATE_IDLE) {
-                       mutex_unlock(&ssp->srcu_gp_mutex);
+                       mutex_unlock(&ssp->srcu_sup->srcu_gp_mutex);
                        return; /* Someone else started the grace period. */
                }
        }
 
-       if (rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)) == SRCU_STATE_SCAN1) {
+       if (rcu_seq_state(READ_ONCE(ssp->srcu_sup->srcu_gp_seq)) == SRCU_STATE_SCAN1) {
                idx = 1 ^ (ssp->srcu_idx & 1);
                if (!try_check_zero(ssp, idx, 1)) {
-                       mutex_unlock(&ssp->srcu_gp_mutex);
+                       mutex_unlock(&ssp->srcu_sup->srcu_gp_mutex);
                        return; /* readers present, retry later. */
                }
                srcu_flip(ssp);
-               spin_lock_irq_rcu_node(ssp);
-               rcu_seq_set_state(&ssp->srcu_gp_seq, SRCU_STATE_SCAN2);
-               ssp->srcu_n_exp_nodelay = 0;
-               spin_unlock_irq_rcu_node(ssp);
+               spin_lock_irq_rcu_node(ssp->srcu_sup);
+               rcu_seq_set_state(&ssp->srcu_sup->srcu_gp_seq, SRCU_STATE_SCAN2);
+               ssp->srcu_sup->srcu_n_exp_nodelay = 0;
+               spin_unlock_irq_rcu_node(ssp->srcu_sup);
        }
 
-       if (rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)) == SRCU_STATE_SCAN2) {
+       if (rcu_seq_state(READ_ONCE(ssp->srcu_sup->srcu_gp_seq)) == SRCU_STATE_SCAN2) {
 
                /*
                 * SRCU read-side critical sections are normally short,
@@ -1627,10 +1664,10 @@ static void srcu_advance_state(struct srcu_struct *ssp)
                 */
                idx = 1 ^ (ssp->srcu_idx & 1);
                if (!try_check_zero(ssp, idx, 2)) {
-                       mutex_unlock(&ssp->srcu_gp_mutex);
+                       mutex_unlock(&ssp->srcu_sup->srcu_gp_mutex);
                        return; /* readers present, retry later. */
                }
-               ssp->srcu_n_exp_nodelay = 0;
+               ssp->srcu_sup->srcu_n_exp_nodelay = 0;
                srcu_gp_end(ssp);  /* Releases ->srcu_gp_mutex. */
        }
 }
@@ -1656,7 +1693,7 @@ static void srcu_invoke_callbacks(struct work_struct *work)
        rcu_cblist_init(&ready_cbs);
        spin_lock_irq_rcu_node(sdp);
        rcu_segcblist_advance(&sdp->srcu_cblist,
-                             rcu_seq_current(&ssp->srcu_gp_seq));
+                             rcu_seq_current(&ssp->srcu_sup->srcu_gp_seq));
        if (sdp->srcu_cblist_invoking ||
            !rcu_segcblist_ready_cbs(&sdp->srcu_cblist)) {
                spin_unlock_irq_rcu_node(sdp);
@@ -1684,7 +1721,7 @@ static void srcu_invoke_callbacks(struct work_struct *work)
        spin_lock_irq_rcu_node(sdp);
        rcu_segcblist_add_len(&sdp->srcu_cblist, -len);
        (void)rcu_segcblist_accelerate(&sdp->srcu_cblist,
-                                      rcu_seq_snap(&ssp->srcu_gp_seq));
+                                      rcu_seq_snap(&ssp->srcu_sup->srcu_gp_seq));
        sdp->srcu_cblist_invoking = false;
        more = rcu_segcblist_ready_cbs(&sdp->srcu_cblist);
        spin_unlock_irq_rcu_node(sdp);
@@ -1700,20 +1737,20 @@ static void srcu_reschedule(struct srcu_struct *ssp, unsigned long delay)
 {
        bool pushgp = true;
 
-       spin_lock_irq_rcu_node(ssp);
-       if (ULONG_CMP_GE(ssp->srcu_gp_seq, ssp->srcu_gp_seq_needed)) {
-               if (!WARN_ON_ONCE(rcu_seq_state(ssp->srcu_gp_seq))) {
+       spin_lock_irq_rcu_node(ssp->srcu_sup);
+       if (ULONG_CMP_GE(ssp->srcu_sup->srcu_gp_seq, ssp->srcu_sup->srcu_gp_seq_needed)) {
+               if (!WARN_ON_ONCE(rcu_seq_state(ssp->srcu_sup->srcu_gp_seq))) {
                        /* All requests fulfilled, time to go idle. */
                        pushgp = false;
                }
-       } else if (!rcu_seq_state(ssp->srcu_gp_seq)) {
+       } else if (!rcu_seq_state(ssp->srcu_sup->srcu_gp_seq)) {
                /* Outstanding request and no GP.  Start one. */
                srcu_gp_start(ssp);
        }
-       spin_unlock_irq_rcu_node(ssp);
+       spin_unlock_irq_rcu_node(ssp->srcu_sup);
 
        if (pushgp)
-               queue_delayed_work(rcu_gp_wq, &ssp->work, delay);
+               queue_delayed_work(rcu_gp_wq, &ssp->srcu_sup->work, delay);
 }
 
 /*
@@ -1724,22 +1761,24 @@ static void process_srcu(struct work_struct *work)
        unsigned long curdelay;
        unsigned long j;
        struct srcu_struct *ssp;
+       struct srcu_usage *sup;
 
-       ssp = container_of(work, struct srcu_struct, work.work);
+       sup = container_of(work, struct srcu_usage, work.work);
+       ssp = sup->srcu_ssp;
 
        srcu_advance_state(ssp);
        curdelay = srcu_get_delay(ssp);
        if (curdelay) {
-               WRITE_ONCE(ssp->reschedule_count, 0);
+               WRITE_ONCE(sup->reschedule_count, 0);
        } else {
                j = jiffies;
-               if (READ_ONCE(ssp->reschedule_jiffies) == j) {
-                       WRITE_ONCE(ssp->reschedule_count, READ_ONCE(ssp->reschedule_count) + 1);
-                       if (READ_ONCE(ssp->reschedule_count) > srcu_max_nodelay)
+               if (READ_ONCE(sup->reschedule_jiffies) == j) {
+                       WRITE_ONCE(sup->reschedule_count, READ_ONCE(sup->reschedule_count) + 1);
+                       if (READ_ONCE(sup->reschedule_count) > srcu_max_nodelay)
                                curdelay = 1;
                } else {
-                       WRITE_ONCE(ssp->reschedule_count, 1);
-                       WRITE_ONCE(ssp->reschedule_jiffies, j);
+                       WRITE_ONCE(sup->reschedule_count, 1);
+                       WRITE_ONCE(sup->reschedule_jiffies, j);
                }
        }
        srcu_reschedule(ssp, curdelay);
@@ -1752,7 +1791,7 @@ void srcutorture_get_gp_data(enum rcutorture_type test_type,
        if (test_type != SRCU_FLAVOR)
                return;
        *flags = 0;
-       *gp_seq = rcu_seq_current(&ssp->srcu_gp_seq);
+       *gp_seq = rcu_seq_current(&ssp->srcu_sup->srcu_gp_seq);
 }
 EXPORT_SYMBOL_GPL(srcutorture_get_gp_data);
 
@@ -1774,14 +1813,14 @@ void srcu_torture_stats_print(struct srcu_struct *ssp, char *tt, char *tf)
        int cpu;
        int idx;
        unsigned long s0 = 0, s1 = 0;
-       int ss_state = READ_ONCE(ssp->srcu_size_state);
+       int ss_state = READ_ONCE(ssp->srcu_sup->srcu_size_state);
        int ss_state_idx = ss_state;
 
        idx = ssp->srcu_idx & 0x1;
        if (ss_state < 0 || ss_state >= ARRAY_SIZE(srcu_size_state_name))
                ss_state_idx = ARRAY_SIZE(srcu_size_state_name) - 1;
        pr_alert("%s%s Tree SRCU g%ld state %d (%s)",
-                tt, tf, rcu_seq_current(&ssp->srcu_gp_seq), ss_state,
+                tt, tf, rcu_seq_current(&ssp->srcu_sup->srcu_gp_seq), ss_state,
                 srcu_size_state_name[ss_state_idx]);
        if (!ssp->sda) {
                // Called after cleanup_srcu_struct(), perhaps.
@@ -1838,7 +1877,7 @@ early_initcall(srcu_bootup_announce);
 
 void __init srcu_init(void)
 {
-       struct srcu_struct *ssp;
+       struct srcu_usage *sup;
 
        /* Decide on srcu_struct-size strategy. */
        if (SRCU_SIZING_IS(SRCU_SIZING_AUTO)) {
@@ -1858,12 +1897,13 @@ void __init srcu_init(void)
         */
        srcu_init_done = true;
        while (!list_empty(&srcu_boot_list)) {
-               ssp = list_first_entry(&srcu_boot_list, struct srcu_struct,
+               sup = list_first_entry(&srcu_boot_list, struct srcu_usage,
                                      work.work.entry);
-               list_del_init(&ssp->work.work.entry);
-               if (SRCU_SIZING_IS(SRCU_SIZING_INIT) && ssp->srcu_size_state == SRCU_SIZE_SMALL)
-                       ssp->srcu_size_state = SRCU_SIZE_ALLOC;
-               queue_work(rcu_gp_wq, &ssp->work.work);
+               list_del_init(&sup->work.work.entry);
+               if (SRCU_SIZING_IS(SRCU_SIZING_INIT) &&
+                   sup->srcu_size_state == SRCU_SIZE_SMALL)
+                       sup->srcu_size_state = SRCU_SIZE_ALLOC;
+               queue_work(rcu_gp_wq, &sup->work.work);
        }
 }
 
@@ -1873,13 +1913,14 @@ void __init srcu_init(void)
 static int srcu_module_coming(struct module *mod)
 {
        int i;
+       struct srcu_struct *ssp;
        struct srcu_struct **sspp = mod->srcu_struct_ptrs;
-       int ret;
 
        for (i = 0; i < mod->num_srcu_structs; i++) {
-               ret = init_srcu_struct(*(sspp++));
-               if (WARN_ON_ONCE(ret))
-                       return ret;
+               ssp = *(sspp++);
+               ssp->sda = alloc_percpu(struct srcu_data);
+               if (WARN_ON_ONCE(!ssp->sda))
+                       return -ENOMEM;
        }
        return 0;
 }
@@ -1888,10 +1929,17 @@ static int srcu_module_coming(struct module *mod)
 static void srcu_module_going(struct module *mod)
 {
        int i;
+       struct srcu_struct *ssp;
        struct srcu_struct **sspp = mod->srcu_struct_ptrs;
 
-       for (i = 0; i < mod->num_srcu_structs; i++)
-               cleanup_srcu_struct(*(sspp++));
+       for (i = 0; i < mod->num_srcu_structs; i++) {
+               ssp = *(sspp++);
+               if (!rcu_seq_state(smp_load_acquire(&ssp->srcu_sup->srcu_gp_seq_needed)) &&
+                   !WARN_ON_ONCE(!ssp->srcu_sup->sda_is_static))
+                       cleanup_srcu_struct(ssp);
+               if (!WARN_ON(srcu_readers_active(ssp)))
+                       free_percpu(ssp->sda);
+       }
 }
 
 /* Handle one module, either coming or going. */
index bfb5e1549f2b22d510758840df48467c59b5dc93..5f4fc8184dd0b5db02ed1cae4c9ec5e260786107 100644 (file)
@@ -136,8 +136,16 @@ static struct rcu_tasks rt_name =                                                  \
        .kname = #rt_name,                                                              \
 }
 
+#ifdef CONFIG_TASKS_RCU
 /* Track exiting tasks in order to allow them to be waited for. */
 DEFINE_STATIC_SRCU(tasks_rcu_exit_srcu);
+#endif
+
+#ifdef CONFIG_TASKS_RCU
+/* Report delay in synchronize_srcu() completion in rcu_tasks_postscan(). */
+static void tasks_rcu_exit_srcu_stall(struct timer_list *unused);
+static DEFINE_TIMER(tasks_rcu_exit_srcu_stall_timer, tasks_rcu_exit_srcu_stall);
+#endif
 
 /* Avoid IPIing CPUs early in the grace period. */
 #define RCU_TASK_IPI_DELAY (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB) ? HZ / 2 : 0)
@@ -830,6 +838,13 @@ static void rcu_tasks_pertask(struct task_struct *t, struct list_head *hop)
 /* Processing between scanning taskslist and draining the holdout list. */
 static void rcu_tasks_postscan(struct list_head *hop)
 {
+       int rtsi = READ_ONCE(rcu_task_stall_info);
+
+       if (!IS_ENABLED(CONFIG_TINY_RCU)) {
+               tasks_rcu_exit_srcu_stall_timer.expires = jiffies + rtsi;
+               add_timer(&tasks_rcu_exit_srcu_stall_timer);
+       }
+
        /*
         * Exiting tasks may escape the tasklist scan. Those are vulnerable
         * until their final schedule() with TASK_DEAD state. To cope with
@@ -848,6 +863,9 @@ static void rcu_tasks_postscan(struct list_head *hop)
         * call to synchronize_rcu().
         */
        synchronize_srcu(&tasks_rcu_exit_srcu);
+
+       if (!IS_ENABLED(CONFIG_TINY_RCU))
+               del_timer_sync(&tasks_rcu_exit_srcu_stall_timer);
 }
 
 /* See if tasks are still holding out, complain if so. */
@@ -923,6 +941,21 @@ static void rcu_tasks_postgp(struct rcu_tasks *rtp)
 void call_rcu_tasks(struct rcu_head *rhp, rcu_callback_t func);
 DEFINE_RCU_TASKS(rcu_tasks, rcu_tasks_wait_gp, call_rcu_tasks, "RCU Tasks");
 
+static void tasks_rcu_exit_srcu_stall(struct timer_list *unused)
+{
+#ifndef CONFIG_TINY_RCU
+       int rtsi;
+
+       rtsi = READ_ONCE(rcu_task_stall_info);
+       pr_info("%s: %s grace period number %lu (since boot) gp_state: %s is %lu jiffies old.\n",
+               __func__, rcu_tasks.kname, rcu_tasks.tasks_gp_seq,
+               tasks_gp_state_getname(&rcu_tasks), jiffies - rcu_tasks.gp_jiffies);
+       pr_info("Please check any exiting tasks stuck between calls to exit_tasks_rcu_start() and exit_tasks_rcu_finish()\n");
+       tasks_rcu_exit_srcu_stall_timer.expires = jiffies + rtsi;
+       add_timer(&tasks_rcu_exit_srcu_stall_timer);
+#endif // #ifndef CONFIG_TINY_RCU
+}
+
 /**
  * call_rcu_tasks() - Queue an RCU for invocation task-based grace period
  * @rhp: structure to be used for queueing the RCU updates.
index 8e880c09ab59ed0fab53abd7954e60eaaa2c25f2..f52ff7241041666e0bef539351ad24c0ca326926 100644 (file)
@@ -640,6 +640,7 @@ void __rcu_irq_enter_check_tick(void)
        }
        raw_spin_unlock_rcu_node(rdp->mynode);
 }
+NOKPROBE_SYMBOL(__rcu_irq_enter_check_tick);
 #endif /* CONFIG_NO_HZ_FULL */
 
 /*
@@ -1955,7 +1956,6 @@ rcu_report_qs_rdp(struct rcu_data *rdp)
 {
        unsigned long flags;
        unsigned long mask;
-       bool needwake = false;
        bool needacc = false;
        struct rcu_node *rnp;
 
@@ -1987,7 +1987,12 @@ rcu_report_qs_rdp(struct rcu_data *rdp)
                 * NOCB kthreads have their own way to deal with that...
                 */
                if (!rcu_rdp_is_offloaded(rdp)) {
-                       needwake = rcu_accelerate_cbs(rnp, rdp);
+                       /*
+                        * The current GP has not yet ended, so it
+                        * should not be possible for rcu_accelerate_cbs()
+                        * to return true.  So complain, but don't awaken.
+                        */
+                       WARN_ON_ONCE(rcu_accelerate_cbs(rnp, rdp));
                } else if (!rcu_segcblist_completely_offloaded(&rdp->cblist)) {
                        /*
                         * ...but NOCB kthreads may miss or delay callbacks acceleration
@@ -1999,8 +2004,6 @@ rcu_report_qs_rdp(struct rcu_data *rdp)
                rcu_disable_urgency_upon_qs(rdp);
                rcu_report_qs_rnp(mask, rnp, rnp->gp_seq, flags);
                /* ^^^ Released rnp->lock */
-               if (needwake)
-                       rcu_gp_kthread_wake();
 
                if (needacc) {
                        rcu_nocb_lock_irqsave(rdp, flags);
@@ -2131,6 +2134,8 @@ static void rcu_do_batch(struct rcu_data *rdp)
                                break;
                        }
                } else {
+                       // In rcuoc context, so no worries about depriving
+                       // other softirq vectors of CPU cycles.
                        local_bh_enable();
                        lockdep_assert_irqs_enabled();
                        cond_resched_tasks_rcu_qs();
@@ -3024,6 +3029,18 @@ need_offload_krc(struct kfree_rcu_cpu *krcp)
        return !!READ_ONCE(krcp->head);
 }
 
+static bool
+need_wait_for_krwp_work(struct kfree_rcu_cpu_work *krwp)
+{
+       int i;
+
+       for (i = 0; i < FREE_N_CHANNELS; i++)
+               if (!list_empty(&krwp->bulk_head_free[i]))
+                       return true;
+
+       return !!krwp->head_free;
+}
+
 static int krc_count(struct kfree_rcu_cpu *krcp)
 {
        int sum = atomic_read(&krcp->head_count);
@@ -3107,15 +3124,14 @@ static void kfree_rcu_monitor(struct work_struct *work)
        for (i = 0; i < KFREE_N_BATCHES; i++) {
                struct kfree_rcu_cpu_work *krwp = &(krcp->krw_arr[i]);
 
-               // Try to detach bulk_head or head and attach it over any
-               // available corresponding free channel. It can be that
-               // a previous RCU batch is in progress, it means that
-               // immediately to queue another one is not possible so
-               // in that case the monitor work is rearmed.
-               if ((!list_empty(&krcp->bulk_head[0]) && list_empty(&krwp->bulk_head_free[0])) ||
-                       (!list_empty(&krcp->bulk_head[1]) && list_empty(&krwp->bulk_head_free[1])) ||
-                               (READ_ONCE(krcp->head) && !krwp->head_free)) {
+               // Try to detach bulk_head or head and attach it, only when
+               // all channels are free.  Any channel is not free means at krwp
+               // there is on-going rcu work to handle krwp's free business.
+               if (need_wait_for_krwp_work(krwp))
+                       continue;
 
+               // kvfree_rcu_drain_ready() might handle this krcp, if so give up.
+               if (need_offload_krc(krcp)) {
                        // Channel 1 corresponds to the SLAB-pointer bulk path.
                        // Channel 2 corresponds to vmalloc-pointer bulk path.
                        for (j = 0; j < FREE_N_CHANNELS; j++) {
@@ -4940,9 +4956,8 @@ void __init rcu_init(void)
        else
                qovld_calc = qovld;
 
-       // Kick-start any polled grace periods that started early.
-       if (!(per_cpu_ptr(&rcu_data, cpu)->mynode->exp_seq_poll_rq & 0x1))
-               (void)start_poll_synchronize_rcu_expedited();
+       // Kick-start in case any polled grace periods started early.
+       (void)start_poll_synchronize_rcu_expedited();
 
        rcu_test_sync_prims();
 }
index 249c2967d9e6c0ba7197997885523506365f9649..3b7abb58157df63b839e7d37752208db12a15a8b 100644 (file)
@@ -594,6 +594,7 @@ static void synchronize_rcu_expedited_wait(void)
        struct rcu_data *rdp;
        struct rcu_node *rnp;
        struct rcu_node *rnp_root = rcu_get_root();
+       unsigned long flags;
 
        trace_rcu_exp_grace_period(rcu_state.name, rcu_exp_gp_seq_endval(), TPS("startwait"));
        jiffies_stall = rcu_exp_jiffies_till_stall_check();
@@ -602,17 +603,17 @@ static void synchronize_rcu_expedited_wait(void)
                if (synchronize_rcu_expedited_wait_once(1))
                        return;
                rcu_for_each_leaf_node(rnp) {
+                       raw_spin_lock_irqsave_rcu_node(rnp, flags);
                        mask = READ_ONCE(rnp->expmask);
                        for_each_leaf_node_cpu_mask(rnp, cpu, mask) {
                                rdp = per_cpu_ptr(&rcu_data, cpu);
                                if (rdp->rcu_forced_tick_exp)
                                        continue;
                                rdp->rcu_forced_tick_exp = true;
-                               preempt_disable();
                                if (cpu_online(cpu))
                                        tick_dep_set_cpu(cpu, TICK_DEP_BIT_RCU_EXP);
-                               preempt_enable();
                        }
+                       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                }
                j = READ_ONCE(jiffies_till_first_fqs);
                if (synchronize_rcu_expedited_wait_once(j + HZ))
@@ -802,9 +803,11 @@ static int rcu_print_task_exp_stall(struct rcu_node *rnp)
        int ndetected = 0;
        struct task_struct *t;
 
-       if (!READ_ONCE(rnp->exp_tasks))
-               return 0;
        raw_spin_lock_irqsave_rcu_node(rnp, flags);
+       if (!rnp->exp_tasks) {
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
+               return 0;
+       }
        t = list_entry(rnp->exp_tasks->prev,
                       struct task_struct, rcu_node_entry);
        list_for_each_entry_continue(t, &rnp->blkd_tasks, rcu_node_entry) {
@@ -1065,9 +1068,10 @@ unsigned long start_poll_synchronize_rcu_expedited(void)
        if (rcu_init_invoked())
                raw_spin_lock_irqsave(&rnp->exp_poll_lock, flags);
        if (!poll_state_synchronize_rcu(s)) {
-               rnp->exp_seq_poll_rq = s;
-               if (rcu_init_invoked())
+               if (rcu_init_invoked()) {
+                       rnp->exp_seq_poll_rq = s;
                        queue_work(rcu_gp_wq, &rnp->exp_poll_wq);
+               }
        }
        if (rcu_init_invoked())
                raw_spin_unlock_irqrestore(&rnp->exp_poll_lock, flags);
index 9e1c8caec5ceb983a0422954c0383a191643b3c2..f2280616f9d51bdac29f94fc2381696af790ec7a 100644 (file)
@@ -1312,6 +1312,7 @@ int rcu_nocb_cpu_offload(int cpu)
 }
 EXPORT_SYMBOL_GPL(rcu_nocb_cpu_offload);
 
+#ifdef CONFIG_RCU_LAZY
 static unsigned long
 lazy_rcu_shrink_count(struct shrinker *shrink, struct shrink_control *sc)
 {
@@ -1360,6 +1361,7 @@ static struct shrinker lazy_rcu_shrinker = {
        .batch = 0,
        .seeks = DEFAULT_SEEKS,
 };
+#endif // #ifdef CONFIG_RCU_LAZY
 
 void __init rcu_init_nohz(void)
 {
@@ -1391,8 +1393,10 @@ void __init rcu_init_nohz(void)
        if (!rcu_state.nocb_is_setup)
                return;
 
+#ifdef CONFIG_RCU_LAZY
        if (register_shrinker(&lazy_rcu_shrinker, "rcu-lazy"))
                pr_err("Failed to register lazy_rcu shrinker!\n");
+#endif // #ifdef CONFIG_RCU_LAZY
 
        if (!cpumask_subset(rcu_nocb_mask, cpu_possible_mask)) {
                pr_info("\tNote: kernel parameter 'rcu_nocbs=', 'nohz_full', or 'isolcpus=' contains nonexistent CPUs.\n");
index af017e038b482f47b0783efe6c089b1c5c9bfab0..0d18c3969f90400e5c91e1e0132268dcff5feb65 100644 (file)
@@ -2084,6 +2084,9 @@ static inline void dequeue_task(struct rq *rq, struct task_struct *p, int flags)
 
 void activate_task(struct rq *rq, struct task_struct *p, int flags)
 {
+       if (task_on_rq_migrating(p))
+               flags |= ENQUEUE_MIGRATED;
+
        enqueue_task(rq, p, flags);
 
        p->on_rq = TASK_ON_RQ_QUEUED;
@@ -8414,14 +8417,14 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len,
        if (len & (sizeof(unsigned long)-1))
                return -EINVAL;
 
-       if (!alloc_cpumask_var(&mask, GFP_KERNEL))
+       if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
                return -ENOMEM;
 
        ret = sched_getaffinity(pid, mask);
        if (ret == 0) {
                unsigned int retlen = min(len, cpumask_size());
 
-               if (copy_to_user(user_mask_ptr, mask, retlen))
+               if (copy_to_user(user_mask_ptr, cpumask_bits(mask), retlen))
                        ret = -EFAULT;
                else
                        ret = retlen;
index 7a1b1f855b9635e75282913850b70ffba2006322..5f6587d94c1dd692d2d0cbcf64151e66e690de55 100644 (file)
@@ -4648,11 +4648,33 @@ static void check_spread(struct cfs_rq *cfs_rq, struct sched_entity *se)
 #endif
 }
 
+static inline bool entity_is_long_sleeper(struct sched_entity *se)
+{
+       struct cfs_rq *cfs_rq;
+       u64 sleep_time;
+
+       if (se->exec_start == 0)
+               return false;
+
+       cfs_rq = cfs_rq_of(se);
+
+       sleep_time = rq_clock_task(rq_of(cfs_rq));
+
+       /* Happen while migrating because of clock task divergence */
+       if (sleep_time <= se->exec_start)
+               return false;
+
+       sleep_time -= se->exec_start;
+       if (sleep_time > ((1ULL << 63) / scale_load_down(NICE_0_LOAD)))
+               return true;
+
+       return false;
+}
+
 static void
 place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
 {
        u64 vruntime = cfs_rq->min_vruntime;
-       u64 sleep_time;
 
        /*
         * The 'current' period is already promised to the current tasks,
@@ -4684,13 +4706,24 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
 
        /*
         * Pull vruntime of the entity being placed to the base level of
-        * cfs_rq, to prevent boosting it if placed backwards.  If the entity
-        * slept for a long time, don't even try to compare its vruntime with
-        * the base as it may be too far off and the comparison may get
-        * inversed due to s64 overflow.
-        */
-       sleep_time = rq_clock_task(rq_of(cfs_rq)) - se->exec_start;
-       if ((s64)sleep_time > 60LL * NSEC_PER_SEC)
+        * cfs_rq, to prevent boosting it if placed backwards.
+        * However, min_vruntime can advance much faster than real time, with
+        * the extreme being when an entity with the minimal weight always runs
+        * on the cfs_rq. If the waking entity slept for a long time, its
+        * vruntime difference from min_vruntime may overflow s64 and their
+        * comparison may get inversed, so ignore the entity's original
+        * vruntime in that case.
+        * The maximal vruntime speedup is given by the ratio of normal to
+        * minimal weight: scale_load_down(NICE_0_LOAD) / MIN_SHARES.
+        * When placing a migrated waking entity, its exec_start has been set
+        * from a different rq. In order to take into account a possible
+        * divergence between new and prev rq's clocks task because of irq and
+        * stolen time, we take an additional margin.
+        * So, cutting off on the sleep time of
+        *     2^63 / scale_load_down(NICE_0_LOAD) ~ 104 days
+        * should be safe.
+        */
+       if (entity_is_long_sleeper(se))
                se->vruntime = vruntime;
        else
                se->vruntime = max_vruntime(se->vruntime, vruntime);
@@ -4770,6 +4803,9 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
 
        if (flags & ENQUEUE_WAKEUP)
                place_entity(cfs_rq, se, 0);
+       /* Entity has migrated, no longer consider this task hot */
+       if (flags & ENQUEUE_MIGRATED)
+               se->exec_start = 0;
 
        check_schedstat_required();
        update_stats_enqueue_fair(cfs_rq, se, flags);
@@ -7657,9 +7693,6 @@ static void migrate_task_rq_fair(struct task_struct *p, int new_cpu)
        /* Tell new CPU we are migrated */
        se->avg.last_update_time = 0;
 
-       /* We have migrated, no longer consider this task hot */
-       se->exec_start = 0;
-
        update_scan_period(p, new_cpu);
 }
 
@@ -10205,6 +10238,16 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s
 
                sds->avg_load = (sds->total_load * SCHED_CAPACITY_SCALE) /
                                sds->total_capacity;
+
+               /*
+                * If the local group is more loaded than the average system
+                * load, don't try to pull any tasks.
+                */
+               if (local->avg_load >= sds->avg_load) {
+                       env->imbalance = 0;
+                       return;
+               }
+
        }
 
        /*
index 495cd87d9bf41b718e4b9acdf7b549a971c8d032..351de791630205d0000a5c354a2f9b0ff2e5c39a 100644 (file)
@@ -664,6 +664,7 @@ long __sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
        struct cred *new;
        int retval;
        kuid_t kruid, keuid, ksuid;
+       bool ruid_new, euid_new, suid_new;
 
        kruid = make_kuid(ns, ruid);
        keuid = make_kuid(ns, euid);
@@ -678,25 +679,29 @@ long __sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
        if ((suid != (uid_t) -1) && !uid_valid(ksuid))
                return -EINVAL;
 
+       old = current_cred();
+
+       /* check for no-op */
+       if ((ruid == (uid_t) -1 || uid_eq(kruid, old->uid)) &&
+           (euid == (uid_t) -1 || (uid_eq(keuid, old->euid) &&
+                                   uid_eq(keuid, old->fsuid))) &&
+           (suid == (uid_t) -1 || uid_eq(ksuid, old->suid)))
+               return 0;
+
+       ruid_new = ruid != (uid_t) -1        && !uid_eq(kruid, old->uid) &&
+                  !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid);
+       euid_new = euid != (uid_t) -1        && !uid_eq(keuid, old->uid) &&
+                  !uid_eq(keuid, old->euid) && !uid_eq(keuid, old->suid);
+       suid_new = suid != (uid_t) -1        && !uid_eq(ksuid, old->uid) &&
+                  !uid_eq(ksuid, old->euid) && !uid_eq(ksuid, old->suid);
+       if ((ruid_new || euid_new || suid_new) &&
+           !ns_capable_setid(old->user_ns, CAP_SETUID))
+               return -EPERM;
+
        new = prepare_creds();
        if (!new)
                return -ENOMEM;
 
-       old = current_cred();
-
-       retval = -EPERM;
-       if (!ns_capable_setid(old->user_ns, CAP_SETUID)) {
-               if (ruid != (uid_t) -1        && !uid_eq(kruid, old->uid) &&
-                   !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid))
-                       goto error;
-               if (euid != (uid_t) -1        && !uid_eq(keuid, old->uid) &&
-                   !uid_eq(keuid, old->euid) && !uid_eq(keuid, old->suid))
-                       goto error;
-               if (suid != (uid_t) -1        && !uid_eq(ksuid, old->uid) &&
-                   !uid_eq(ksuid, old->euid) && !uid_eq(ksuid, old->suid))
-                       goto error;
-       }
-
        if (ruid != (uid_t) -1) {
                new->uid = kruid;
                if (!uid_eq(kruid, old->uid)) {
@@ -761,6 +766,7 @@ long __sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
        struct cred *new;
        int retval;
        kgid_t krgid, kegid, ksgid;
+       bool rgid_new, egid_new, sgid_new;
 
        krgid = make_kgid(ns, rgid);
        kegid = make_kgid(ns, egid);
@@ -773,23 +779,28 @@ long __sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
        if ((sgid != (gid_t) -1) && !gid_valid(ksgid))
                return -EINVAL;
 
+       old = current_cred();
+
+       /* check for no-op */
+       if ((rgid == (gid_t) -1 || gid_eq(krgid, old->gid)) &&
+           (egid == (gid_t) -1 || (gid_eq(kegid, old->egid) &&
+                                   gid_eq(kegid, old->fsgid))) &&
+           (sgid == (gid_t) -1 || gid_eq(ksgid, old->sgid)))
+               return 0;
+
+       rgid_new = rgid != (gid_t) -1        && !gid_eq(krgid, old->gid) &&
+                  !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid);
+       egid_new = egid != (gid_t) -1        && !gid_eq(kegid, old->gid) &&
+                  !gid_eq(kegid, old->egid) && !gid_eq(kegid, old->sgid);
+       sgid_new = sgid != (gid_t) -1        && !gid_eq(ksgid, old->gid) &&
+                  !gid_eq(ksgid, old->egid) && !gid_eq(ksgid, old->sgid);
+       if ((rgid_new || egid_new || sgid_new) &&
+           !ns_capable_setid(old->user_ns, CAP_SETGID))
+               return -EPERM;
+
        new = prepare_creds();
        if (!new)
                return -ENOMEM;
-       old = current_cred();
-
-       retval = -EPERM;
-       if (!ns_capable_setid(old->user_ns, CAP_SETGID)) {
-               if (rgid != (gid_t) -1        && !gid_eq(krgid, old->gid) &&
-                   !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid))
-                       goto error;
-               if (egid != (gid_t) -1        && !gid_eq(kegid, old->gid) &&
-                   !gid_eq(kegid, old->egid) && !gid_eq(kegid, old->sgid))
-                       goto error;
-               if (sgid != (gid_t) -1        && !gid_eq(ksgid, old->gid) &&
-                   !gid_eq(ksgid, old->egid) && !gid_eq(ksgid, old->sgid))
-                       goto error;
-       }
 
        if (rgid != (gid_t) -1)
                new->gid = krgid;
index b0e3c9205946f7e8503c574ce6d1e133b9d94412..a46506f7ec6d02f99c19a3ddf6c3714587880750 100644 (file)
@@ -281,6 +281,11 @@ static bool check_tick_dependency(atomic_t *dep)
                return true;
        }
 
+       if (val & TICK_DEP_MASK_RCU_EXP) {
+               trace_tick_stop(0, TICK_DEP_MASK_RCU_EXP);
+               return true;
+       }
+
        return false;
 }
 
@@ -527,7 +532,7 @@ void __init tick_nohz_full_setup(cpumask_var_t cpumask)
        tick_nohz_full_running = true;
 }
 
-static int tick_nohz_cpu_down(unsigned int cpu)
+bool tick_nohz_cpu_hotpluggable(unsigned int cpu)
 {
        /*
         * The tick_do_timer_cpu CPU handles housekeeping duty (unbound
@@ -535,8 +540,13 @@ static int tick_nohz_cpu_down(unsigned int cpu)
         * CPUs. It must remain online when nohz full is enabled.
         */
        if (tick_nohz_full_running && tick_do_timer_cpu == cpu)
-               return -EBUSY;
-       return 0;
+               return false;
+       return true;
+}
+
+static int tick_nohz_cpu_down(unsigned int cpu)
+{
+       return tick_nohz_cpu_hotpluggable(cpu) ? 0 : -EBUSY;
 }
 
 void __init tick_nohz_init(void)
index 29baa97d0d534284237a4376dda1d88aca6f7c06..c67bcc89a77168cd9d9d7db3e0381db4ebdb86b7 100644 (file)
@@ -1564,7 +1564,8 @@ static struct dyn_ftrace *lookup_rec(unsigned long start, unsigned long end)
        key.flags = end;        /* overload flags, as it is unsigned long */
 
        for (pg = ftrace_pages_start; pg; pg = pg->next) {
-               if (end < pg->records[0].ip ||
+               if (pg->index == 0 ||
+                   end < pg->records[0].ip ||
                    start >= (pg->records[pg->index - 1].ip + MCOUNT_INSN_SIZE))
                        continue;
                rec = bsearch(&key, pg->records, pg->index,
@@ -2591,7 +2592,7 @@ static void call_direct_funcs(unsigned long ip, unsigned long pip,
        arch_ftrace_set_direct_caller(fregs, addr);
 }
 
-struct ftrace_ops direct_ops = {
+static struct ftrace_ops direct_ops = {
        .func           = call_direct_funcs,
        .flags          = FTRACE_OPS_FL_DIRECT | FTRACE_OPS_FL_SAVE_REGS
                          | FTRACE_OPS_FL_PERMANENT,
@@ -5666,12 +5667,15 @@ int modify_ftrace_direct(unsigned long ip,
                ret = 0;
        }
 
-       if (unlikely(ret && new_direct)) {
-               direct->count++;
-               list_del_rcu(&new_direct->next);
-               synchronize_rcu_tasks();
-               kfree(new_direct);
-               ftrace_direct_func_count--;
+       if (ret) {
+               direct->addr = old_addr;
+               if (unlikely(new_direct)) {
+                       direct->count++;
+                       list_del_rcu(&new_direct->next);
+                       synchronize_rcu_tasks();
+                       kfree(new_direct);
+                       ftrace_direct_func_count--;
+               }
        }
 
  out_unlock:
index 4850fdfe27f1cb040118eed41c8a3036c4926d2c..5a4b722b50451bfdee42769a6d3be39c055690d1 100644 (file)
@@ -146,7 +146,7 @@ static int __init test_gen_kprobe_cmd(void)
        if (trace_event_file_is_valid(gen_kprobe_test))
                gen_kprobe_test = NULL;
        /* We got an error after creating the event, delete it */
-       ret = kprobe_event_delete("gen_kprobe_test");
+       kprobe_event_delete("gen_kprobe_test");
        goto out;
 }
 
@@ -211,7 +211,7 @@ static int __init test_gen_kretprobe_cmd(void)
        if (trace_event_file_is_valid(gen_kretprobe_test))
                gen_kretprobe_test = NULL;
        /* We got an error after creating the event, delete it */
-       ret = kprobe_event_delete("gen_kretprobe_test");
+       kprobe_event_delete("gen_kretprobe_test");
        goto out;
 }
 
index af50d931b020227991e2e63f4e961c9d0618323f..76a2d91eecad9f302fb30e24c7fc4803ea0eeee5 100644 (file)
@@ -354,10 +354,6 @@ static void rb_init_page(struct buffer_data_page *bpage)
        local_set(&bpage->commit, 0);
 }
 
-/*
- * Also stolen from mm/slob.c. Thanks to Mathieu Desnoyers for pointing
- * this issue out.
- */
 static void free_buffer_page(struct buffer_page *bpage)
 {
        free_page((unsigned long)bpage->page);
@@ -3102,6 +3098,10 @@ rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer)
                if (RB_WARN_ON(cpu_buffer,
                               rb_is_reader_page(cpu_buffer->tail_page)))
                        return;
+               /*
+                * No need for a memory barrier here, as the update
+                * of the tail_page did it for this page.
+                */
                local_set(&cpu_buffer->commit_page->page->commit,
                          rb_page_write(cpu_buffer->commit_page));
                rb_inc_page(&cpu_buffer->commit_page);
@@ -3111,6 +3111,8 @@ rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer)
        while (rb_commit_index(cpu_buffer) !=
               rb_page_write(cpu_buffer->commit_page)) {
 
+               /* Make sure the readers see the content of what is committed. */
+               smp_wmb();
                local_set(&cpu_buffer->commit_page->page->commit,
                          rb_page_write(cpu_buffer->commit_page));
                RB_WARN_ON(cpu_buffer,
@@ -4688,7 +4690,12 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
 
        /*
         * Make sure we see any padding after the write update
-        * (see rb_reset_tail())
+        * (see rb_reset_tail()).
+        *
+        * In addition, a writer may be writing on the reader page
+        * if the page has not been fully filled, so the read barrier
+        * is also needed to make sure we see the content of what is
+        * committed by the writer (see rb_set_commit_to_write()).
         */
        smp_rmb();
 
index 45551c7b4c36588fac4378f04fe4a4d7ef8e36a9..36a6037823cd9db9ae712258201fc632c437a425 100644 (file)
@@ -1149,22 +1149,22 @@ static void tracing_snapshot_instance_cond(struct trace_array *tr,
        unsigned long flags;
 
        if (in_nmi()) {
-               internal_trace_puts("*** SNAPSHOT CALLED FROM NMI CONTEXT ***\n");
-               internal_trace_puts("*** snapshot is being ignored        ***\n");
+               trace_array_puts(tr, "*** SNAPSHOT CALLED FROM NMI CONTEXT ***\n");
+               trace_array_puts(tr, "*** snapshot is being ignored        ***\n");
                return;
        }
 
        if (!tr->allocated_snapshot) {
-               internal_trace_puts("*** SNAPSHOT NOT ALLOCATED ***\n");
-               internal_trace_puts("*** stopping trace here!   ***\n");
-               tracing_off();
+               trace_array_puts(tr, "*** SNAPSHOT NOT ALLOCATED ***\n");
+               trace_array_puts(tr, "*** stopping trace here!   ***\n");
+               tracer_tracing_off(tr);
                return;
        }
 
        /* Note, snapshot can not be used when the tracer uses it */
        if (tracer->use_max_tr) {
-               internal_trace_puts("*** LATENCY TRACER ACTIVE ***\n");
-               internal_trace_puts("*** Can not use snapshot (sorry) ***\n");
+               trace_array_puts(tr, "*** LATENCY TRACER ACTIVE ***\n");
+               trace_array_puts(tr, "*** Can not use snapshot (sorry) ***\n");
                return;
        }
 
@@ -5167,6 +5167,8 @@ loff_t tracing_lseek(struct file *file, loff_t offset, int whence)
 static const struct file_operations tracing_fops = {
        .open           = tracing_open,
        .read           = seq_read,
+       .read_iter      = seq_read_iter,
+       .splice_read    = generic_file_splice_read,
        .write          = tracing_write_stub,
        .llseek         = tracing_lseek,
        .release        = tracing_release,
@@ -9514,6 +9516,7 @@ static int __remove_instance(struct trace_array *tr)
        tracefs_remove(tr->dir);
        free_percpu(tr->last_func_repeats);
        free_trace_buffers(tr);
+       clear_tracing_err_log(tr);
 
        for (i = 0; i < tr->nr_topts; i++) {
                kfree(tr->topts[i].topts);
@@ -10391,19 +10394,20 @@ out:
 
 void __init ftrace_boot_snapshot(void)
 {
+#ifdef CONFIG_TRACER_MAX_TRACE
        struct trace_array *tr;
 
-       if (snapshot_at_boot) {
-               tracing_snapshot();
-               internal_trace_puts("** Boot snapshot taken **\n");
-       }
+       if (!snapshot_at_boot)
+               return;
 
        list_for_each_entry(tr, &ftrace_trace_arrays, list) {
-               if (tr == &global_trace)
+               if (!tr->allocated_snapshot)
                        continue;
-               trace_array_puts(tr, "** Boot snapshot taken **\n");
+
                tracing_snapshot_instance(tr);
+               trace_array_puts(tr, "** Boot snapshot taken **\n");
        }
+#endif
 }
 
 void __init early_trace_init(void)
index 89877a18f93307fce29789166b68a60d9a7f0c1e..486cca3c2b75450f23f8b680045421cf234d232f 100644 (file)
@@ -1331,6 +1331,9 @@ static const char *hist_field_name(struct hist_field *field,
 {
        const char *field_name = "";
 
+       if (WARN_ON_ONCE(!field))
+               return field_name;
+
        if (level > 1)
                return field_name;
 
@@ -4235,6 +4238,15 @@ static int __create_val_field(struct hist_trigger_data *hist_data,
                goto out;
        }
 
+       /* Some types cannot be a value */
+       if (hist_field->flags & (HIST_FIELD_FL_GRAPH | HIST_FIELD_FL_PERCENT |
+                                HIST_FIELD_FL_BUCKET | HIST_FIELD_FL_LOG2 |
+                                HIST_FIELD_FL_SYM | HIST_FIELD_FL_SYM_OFFSET |
+                                HIST_FIELD_FL_SYSCALL | HIST_FIELD_FL_STACKTRACE)) {
+               hist_err(file->tr, HIST_ERR_BAD_FIELD_MODIFIER, errpos(field_str));
+               ret = -EINVAL;
+       }
+
        hist_data->fields[val_idx] = hist_field;
 
        ++hist_data->n_vals;
index 46d0abb32d0fa7c031a0fe33bd9d6e4fb12b9646..d6a70aff24101604016c47f2a8d1d0ae30530a76 100644 (file)
@@ -44,14 +44,21 @@ enum { ERRORS };
 
 static const char *err_text[] = { ERRORS };
 
+static DEFINE_MUTEX(lastcmd_mutex);
 static char *last_cmd;
 
 static int errpos(const char *str)
 {
+       int ret = 0;
+
+       mutex_lock(&lastcmd_mutex);
        if (!str || !last_cmd)
-               return 0;
+               goto out;
 
-       return err_pos(last_cmd, str);
+       ret = err_pos(last_cmd, str);
+ out:
+       mutex_unlock(&lastcmd_mutex);
+       return ret;
 }
 
 static void last_cmd_set(const char *str)
@@ -59,18 +66,22 @@ static void last_cmd_set(const char *str)
        if (!str)
                return;
 
+       mutex_lock(&lastcmd_mutex);
        kfree(last_cmd);
-
        last_cmd = kstrdup(str, GFP_KERNEL);
+       mutex_unlock(&lastcmd_mutex);
 }
 
 static void synth_err(u8 err_type, u16 err_pos)
 {
+       mutex_lock(&lastcmd_mutex);
        if (!last_cmd)
-               return;
+               goto out;
 
        tracing_log_err(NULL, "synthetic_events", last_cmd, err_text,
                        err_type, err_pos);
+ out:
+       mutex_unlock(&lastcmd_mutex);
 }
 
 static int create_synth_event(const char *raw_command);
index d440ddd5fd8b29adf605075004fc5edd9a7ee17c..2f37a6e68aa9f851f19b968eeafdb1034d3efae2 100644 (file)
@@ -339,7 +339,7 @@ static void move_to_next_cpu(void)
        cpumask_clear(current_mask);
        cpumask_set_cpu(next_cpu, current_mask);
 
-       sched_setaffinity(0, current_mask);
+       set_cpus_allowed_ptr(current, current_mask);
        return;
 
  change_mode:
@@ -446,7 +446,7 @@ static int start_single_kthread(struct trace_array *tr)
 
        }
 
-       sched_setaffinity(kthread->pid, current_mask);
+       set_cpus_allowed_ptr(kthread, current_mask);
 
        kdata->kthread = kthread;
        wake_up_process(kthread);
@@ -492,6 +492,10 @@ static int start_cpu_kthread(unsigned int cpu)
 {
        struct task_struct *kthread;
 
+       /* Do not start a new hwlatd thread if it is already running */
+       if (per_cpu(hwlat_per_cpu_data, cpu).kthread)
+               return 0;
+
        kthread = kthread_run_on_cpu(kthread_fn, NULL, cpu, "hwlatd/%u");
        if (IS_ERR(kthread)) {
                pr_err(BANNER "could not start sampling thread\n");
@@ -584,9 +588,6 @@ static int start_per_cpu_kthreads(struct trace_array *tr)
         */
        cpumask_and(current_mask, cpu_online_mask, tr->tracing_cpumask);
 
-       for_each_online_cpu(cpu)
-               per_cpu(hwlat_per_cpu_data, cpu).kthread = NULL;
-
        for_each_cpu(cpu, current_mask) {
                retval = start_cpu_kthread(cpu);
                if (retval)
index 04f0fdae19a1c0382d6e0ec4f415a36d86d610f7..efbbec2caff832898f45e6f250c5bc43e26f04e9 100644 (file)
@@ -159,7 +159,7 @@ static void osnoise_unregister_instance(struct trace_array *tr)
        if (!found)
                return;
 
-       kvfree_rcu(inst);
+       kvfree_rcu_mightsleep(inst);
 }
 
 /*
@@ -217,7 +217,7 @@ struct osnoise_variables {
 /*
  * Per-cpu runtime information.
  */
-DEFINE_PER_CPU(struct osnoise_variables, per_cpu_osnoise_var);
+static DEFINE_PER_CPU(struct osnoise_variables, per_cpu_osnoise_var);
 
 /*
  * this_cpu_osn_var - Return the per-cpu osnoise_variables on its relative CPU
@@ -240,7 +240,7 @@ struct timerlat_variables {
        u64                     count;
 };
 
-DEFINE_PER_CPU(struct timerlat_variables, per_cpu_timerlat_var);
+static DEFINE_PER_CPU(struct timerlat_variables, per_cpu_timerlat_var);
 
 /*
  * this_cpu_tmr_var - Return the per-cpu timerlat_variables on its relative CPU
@@ -332,7 +332,7 @@ struct timerlat_sample {
 /*
  * Protect the interface.
  */
-struct mutex interface_lock;
+static struct mutex interface_lock;
 
 /*
  * Tracer data.
@@ -1296,7 +1296,7 @@ static void notify_new_max_latency(u64 latency)
        rcu_read_lock();
        list_for_each_entry_rcu(inst, &osnoise_instances, list) {
                tr = inst->tr;
-               if (tr->max_latency < latency) {
+               if (tracer_tracing_is_on(tr) && tr->max_latency < latency) {
                        tr->max_latency = latency;
                        latency_fsnotify(tr);
                }
@@ -1738,6 +1738,8 @@ static int timerlat_main(void *data)
 
                trace_timerlat_sample(&s);
 
+               notify_new_max_latency(diff);
+
                timerlat_dump_stack(time_to_us(diff));
 
                tlat->tracing_thread = false;
@@ -2239,8 +2241,8 @@ static struct trace_min_max_param osnoise_print_stack = {
 /*
  * osnoise/timerlat_period: min 100 us, max 1 s
  */
-u64 timerlat_min_period = 100;
-u64 timerlat_max_period = 1000000;
+static u64 timerlat_min_period = 100;
+static u64 timerlat_max_period = 1000000;
 static struct trace_min_max_param timerlat_period = {
        .lock   = &interface_lock,
        .val    = &osnoise_data.timerlat_period,
index 20d0c4a9763324c1f411f00b552d2b0f0e13f31b..2d261667829504b36c7e515e693a371f71515ef5 100644 (file)
@@ -1172,7 +1172,7 @@ int trace_probe_remove_file(struct trace_probe *tp,
                return -ENOENT;
 
        list_del_rcu(&link->list);
-       kvfree_rcu(link);
+       kvfree_rcu_mightsleep(link);
 
        if (list_empty(&tp->event->files))
                trace_probe_clear_flag(tp, TP_FLAG_TRACE);
diff --git a/kernel/vhost_task.c b/kernel/vhost_task.c
new file mode 100644 (file)
index 0000000..b7cbd66
--- /dev/null
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Oracle Corporation
+ */
+#include <linux/slab.h>
+#include <linux/completion.h>
+#include <linux/sched/task.h>
+#include <linux/sched/vhost_task.h>
+#include <linux/sched/signal.h>
+
+enum vhost_task_flags {
+       VHOST_TASK_FLAGS_STOP,
+};
+
+static int vhost_task_fn(void *data)
+{
+       struct vhost_task *vtsk = data;
+       int ret;
+
+       ret = vtsk->fn(vtsk->data);
+       complete(&vtsk->exited);
+       do_exit(ret);
+}
+
+/**
+ * vhost_task_stop - stop a vhost_task
+ * @vtsk: vhost_task to stop
+ *
+ * Callers must call vhost_task_should_stop and return from their worker
+ * function when it returns true;
+ */
+void vhost_task_stop(struct vhost_task *vtsk)
+{
+       pid_t pid = vtsk->task->pid;
+
+       set_bit(VHOST_TASK_FLAGS_STOP, &vtsk->flags);
+       wake_up_process(vtsk->task);
+       /*
+        * Make sure vhost_task_fn is no longer accessing the vhost_task before
+        * freeing it below. If userspace crashed or exited without closing,
+        * then the vhost_task->task could already be marked dead so
+        * kernel_wait will return early.
+        */
+       wait_for_completion(&vtsk->exited);
+       /*
+        * If we are just closing/removing a device and the parent process is
+        * not exiting then reap the task.
+        */
+       kernel_wait4(pid, NULL, __WCLONE, NULL);
+       kfree(vtsk);
+}
+EXPORT_SYMBOL_GPL(vhost_task_stop);
+
+/**
+ * vhost_task_should_stop - should the vhost task return from the work function
+ * @vtsk: vhost_task to stop
+ */
+bool vhost_task_should_stop(struct vhost_task *vtsk)
+{
+       return test_bit(VHOST_TASK_FLAGS_STOP, &vtsk->flags);
+}
+EXPORT_SYMBOL_GPL(vhost_task_should_stop);
+
+/**
+ * vhost_task_create - create a copy of a process to be used by the kernel
+ * @fn: thread stack
+ * @arg: data to be passed to fn
+ * @name: the thread's name
+ *
+ * This returns a specialized task for use by the vhost layer or NULL on
+ * failure. The returned task is inactive, and the caller must fire it up
+ * through vhost_task_start().
+ */
+struct vhost_task *vhost_task_create(int (*fn)(void *), void *arg,
+                                    const char *name)
+{
+       struct kernel_clone_args args = {
+               .flags          = CLONE_FS | CLONE_UNTRACED | CLONE_VM,
+               .exit_signal    = 0,
+               .fn             = vhost_task_fn,
+               .name           = name,
+               .user_worker    = 1,
+               .no_files       = 1,
+               .ignore_signals = 1,
+       };
+       struct vhost_task *vtsk;
+       struct task_struct *tsk;
+
+       vtsk = kzalloc(sizeof(*vtsk), GFP_KERNEL);
+       if (!vtsk)
+               return NULL;
+       init_completion(&vtsk->exited);
+       vtsk->data = arg;
+       vtsk->fn = fn;
+
+       args.fn_arg = vtsk;
+
+       tsk = copy_process(NULL, 0, NUMA_NO_NODE, &args);
+       if (IS_ERR(tsk)) {
+               kfree(vtsk);
+               return NULL;
+       }
+
+       vtsk->task = tsk;
+       return vtsk;
+}
+EXPORT_SYMBOL_GPL(vhost_task_create);
+
+/**
+ * vhost_task_start - start a vhost_task created with vhost_task_create
+ * @vtsk: vhost_task to wake up
+ */
+void vhost_task_start(struct vhost_task *vtsk)
+{
+       wake_up_new_task(vtsk->task);
+}
+EXPORT_SYMBOL_GPL(vhost_task_start);
index a6f9bdd956c39d2fabbb5932441965672c747aa2..f10f403104e7dcccaf8d702ed73d71d1e5ac9a35 100644 (file)
@@ -273,6 +273,7 @@ long watch_queue_set_size(struct pipe_inode_info *pipe, unsigned int nr_notes)
        if (ret < 0)
                goto error;
 
+       ret = -ENOMEM;
        pages = kcalloc(sizeof(struct page *), nr_pages, GFP_KERNEL);
        if (!pages)
                goto error;
index c8b379e2e9adc14f0a79dbb2b97497a356a2c6e5..39d1d93164bd094e72f88e2db9ce2a0d854abb17 100644 (file)
@@ -1143,7 +1143,7 @@ menu "Scheduler Debugging"
 
 config SCHED_DEBUG
        bool "Collect scheduler debugging info"
-       depends on DEBUG_KERNEL && PROC_FS
+       depends on DEBUG_KERNEL && DEBUG_FS
        default y
        help
          If you say Y here, the /sys/kernel/debug/sched file will be provided
@@ -1392,7 +1392,7 @@ config LOCKDEP_STACK_TRACE_HASH_BITS
        range 10 30
        default 14
        help
-         Try increasing this value if you need large MAX_STACK_TRACE_ENTRIES.
+         Try increasing this value if you need large STACK_TRACE_HASH_SIZE.
 
 config LOCKDEP_CIRCULAR_QUEUE_BITS
        int "Bitsize for elements in circular_queue struct"
index f9d33efa6d09060445dfbf481c01f5594dc37417..f15ac666e9d38bd23bb0cb4ed08beb626540a0c4 100644 (file)
@@ -31,6 +31,7 @@ MODULE_PARM_DESC(iterations,
 
 static void dhry_benchmark(void)
 {
+       unsigned int cpu = get_cpu();
        int i, n;
 
        if (iterations > 0) {
@@ -45,9 +46,10 @@ static void dhry_benchmark(void)
        }
 
 report:
+       put_cpu();
        if (n >= 0)
-               pr_info("CPU%u: Dhrystones per Second: %d (%d DMIPS)\n",
-                       smp_processor_id(), n, n / DHRY_VAX);
+               pr_info("CPU%u: Dhrystones per Second: %d (%d DMIPS)\n", cpu,
+                       n, n / DHRY_VAX);
        else if (n == -EAGAIN)
                pr_err("Please increase the number of iterations\n");
        else
index c10920e667889c1a2e86f5916b9998b21893ba77..32f99e9a670e64fcdc8e9a7e67d29df199486a69 100644 (file)
@@ -182,6 +182,15 @@ unsigned long _find_next_andnot_bit(const unsigned long *addr1, const unsigned l
 EXPORT_SYMBOL(_find_next_andnot_bit);
 #endif
 
+#ifndef find_next_or_bit
+unsigned long _find_next_or_bit(const unsigned long *addr1, const unsigned long *addr2,
+                                       unsigned long nbits, unsigned long start)
+{
+       return FIND_NEXT_BIT(addr1[idx] | addr2[idx], /* nop */, nbits, start);
+}
+EXPORT_SYMBOL(_find_next_or_bit);
+#endif
+
 #ifndef find_next_zero_bit
 unsigned long _find_next_zero_bit(const unsigned long *addr, unsigned long nbits,
                                         unsigned long start)
index 274014e4eafec2d325470757f32c0dbab65b0b8d..967fba189c5ff068e6da252a6d80e22defb26cc8 100644 (file)
@@ -126,13 +126,13 @@ __out:                                                            \
                        iterate_buf(i, n, base, len, off,       \
                                                i->ubuf, (I))   \
                } else if (likely(iter_is_iovec(i))) {          \
-                       const struct iovec *iov = i->iov;       \
+                       const struct iovec *iov = iter_iov(i);  \
                        void __user *base;                      \
                        size_t len;                             \
                        iterate_iovec(i, n, base, len, off,     \
                                                iov, (I))       \
-                       i->nr_segs -= iov - i->iov;             \
-                       i->iov = iov;                           \
+                       i->nr_segs -= iov - iter_iov(i);        \
+                       i->__iov = iov;                         \
                } else if (iov_iter_is_bvec(i)) {               \
                        const struct bio_vec *bvec = i->bvec;   \
                        void *base;                             \
@@ -355,7 +355,7 @@ size_t fault_in_iov_iter_readable(const struct iov_iter *i, size_t size)
                size_t skip;
 
                size -= count;
-               for (p = i->iov, skip = i->iov_offset; count; p++, skip = 0) {
+               for (p = iter_iov(i), skip = i->iov_offset; count; p++, skip = 0) {
                        size_t len = min(count, p->iov_len - skip);
                        size_t ret;
 
@@ -398,7 +398,7 @@ size_t fault_in_iov_iter_writeable(const struct iov_iter *i, size_t size)
                size_t skip;
 
                size -= count;
-               for (p = i->iov, skip = i->iov_offset; count; p++, skip = 0) {
+               for (p = iter_iov(i), skip = i->iov_offset; count; p++, skip = 0) {
                        size_t len = min(count, p->iov_len - skip);
                        size_t ret;
 
@@ -425,7 +425,7 @@ void iov_iter_init(struct iov_iter *i, unsigned int direction,
                .nofault = false,
                .user_backed = true,
                .data_source = direction,
-               .iov = iov,
+               .__iov = iov,
                .nr_segs = nr_segs,
                .iov_offset = 0,
                .count = count
@@ -876,14 +876,14 @@ static void iov_iter_iovec_advance(struct iov_iter *i, size_t size)
        i->count -= size;
 
        size += i->iov_offset; // from beginning of current segment
-       for (iov = i->iov, end = iov + i->nr_segs; iov < end; iov++) {
+       for (iov = iter_iov(i), end = iov + i->nr_segs; iov < end; iov++) {
                if (likely(size < iov->iov_len))
                        break;
                size -= iov->iov_len;
        }
        i->iov_offset = size;
-       i->nr_segs -= iov - i->iov;
-       i->iov = iov;
+       i->nr_segs -= iov - iter_iov(i);
+       i->__iov = iov;
 }
 
 void iov_iter_advance(struct iov_iter *i, size_t size)
@@ -958,12 +958,12 @@ void iov_iter_revert(struct iov_iter *i, size_t unroll)
                        unroll -= n;
                }
        } else { /* same logics for iovec and kvec */
-               const struct iovec *iov = i->iov;
+               const struct iovec *iov = iter_iov(i);
                while (1) {
                        size_t n = (--iov)->iov_len;
                        i->nr_segs++;
                        if (unroll <= n) {
-                               i->iov = iov;
+                               i->__iov = iov;
                                i->iov_offset = n - unroll;
                                return;
                        }
@@ -980,7 +980,7 @@ size_t iov_iter_single_seg_count(const struct iov_iter *i)
 {
        if (i->nr_segs > 1) {
                if (likely(iter_is_iovec(i) || iov_iter_is_kvec(i)))
-                       return min(i->count, i->iov->iov_len - i->iov_offset);
+                       return min(i->count, iter_iov(i)->iov_len - i->iov_offset);
                if (iov_iter_is_bvec(i))
                        return min(i->count, i->bvec->bv_len - i->iov_offset);
        }
@@ -1095,13 +1095,14 @@ static bool iov_iter_aligned_iovec(const struct iov_iter *i, unsigned addr_mask,
        unsigned k;
 
        for (k = 0; k < i->nr_segs; k++, skip = 0) {
-               size_t len = i->iov[k].iov_len - skip;
+               const struct iovec *iov = iter_iov(i) + k;
+               size_t len = iov->iov_len - skip;
 
                if (len > size)
                        len = size;
                if (len & len_mask)
                        return false;
-               if ((unsigned long)(i->iov[k].iov_base + skip) & addr_mask)
+               if ((unsigned long)(iov->iov_base + skip) & addr_mask)
                        return false;
 
                size -= len;
@@ -1194,9 +1195,10 @@ static unsigned long iov_iter_alignment_iovec(const struct iov_iter *i)
        unsigned k;
 
        for (k = 0; k < i->nr_segs; k++, skip = 0) {
-               size_t len = i->iov[k].iov_len - skip;
+               const struct iovec *iov = iter_iov(i) + k;
+               size_t len = iov->iov_len - skip;
                if (len) {
-                       res |= (unsigned long)i->iov[k].iov_base + skip;
+                       res |= (unsigned long)iov->iov_base + skip;
                        if (len > size)
                                len = size;
                        res |= len;
@@ -1273,14 +1275,15 @@ unsigned long iov_iter_gap_alignment(const struct iov_iter *i)
                return ~0U;
 
        for (k = 0; k < i->nr_segs; k++) {
-               if (i->iov[k].iov_len) {
-                       unsigned long base = (unsigned long)i->iov[k].iov_base;
+               const struct iovec *iov = iter_iov(i) + k;
+               if (iov->iov_len) {
+                       unsigned long base = (unsigned long)iov->iov_base;
                        if (v) // if not the first one
                                res |= base | v; // this start | previous end
-                       v = base + i->iov[k].iov_len;
-                       if (size <= i->iov[k].iov_len)
+                       v = base + iov->iov_len;
+                       if (size <= iov->iov_len)
                                break;
-                       size -= i->iov[k].iov_len;
+                       size -= iov->iov_len;
                }
        }
        return res;
@@ -1396,13 +1399,14 @@ static unsigned long first_iovec_segment(const struct iov_iter *i, size_t *size)
                return (unsigned long)i->ubuf + i->iov_offset;
 
        for (k = 0, skip = i->iov_offset; k < i->nr_segs; k++, skip = 0) {
-               size_t len = i->iov[k].iov_len - skip;
+               const struct iovec *iov = iter_iov(i) + k;
+               size_t len = iov->iov_len - skip;
 
                if (unlikely(!len))
                        continue;
                if (*size > len)
                        *size = len;
-               return (unsigned long)i->iov[k].iov_base + skip;
+               return (unsigned long)iov->iov_base + skip;
        }
        BUG(); // if it had been empty, we wouldn't get called
 }
@@ -1614,7 +1618,7 @@ static int iov_npages(const struct iov_iter *i, int maxpages)
        const struct iovec *p;
        int npages = 0;
 
-       for (p = i->iov; size; skip = 0, p++) {
+       for (p = iter_iov(i); size; skip = 0, p++) {
                unsigned offs = offset_in_page(p->iov_base + skip);
                size_t len = min(p->iov_len - skip, size);
 
@@ -1691,14 +1695,14 @@ const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags)
                                    flags);
        else if (iov_iter_is_kvec(new) || iter_is_iovec(new))
                /* iovec and kvec have identical layout */
-               return new->iov = kmemdup(new->iov,
+               return new->__iov = kmemdup(new->__iov,
                                   new->nr_segs * sizeof(struct iovec),
                                   flags);
        return NULL;
 }
 EXPORT_SYMBOL(dup_iter);
 
-static int copy_compat_iovec_from_user(struct iovec *iov,
+static __noclone int copy_compat_iovec_from_user(struct iovec *iov,
                const struct iovec __user *uvec, unsigned long nr_segs)
 {
        const struct compat_iovec __user *uiov =
@@ -1731,18 +1735,35 @@ uaccess_end:
 }
 
 static int copy_iovec_from_user(struct iovec *iov,
-               const struct iovec __user *uvec, unsigned long nr_segs)
+               const struct iovec __user *uiov, unsigned long nr_segs)
 {
-       unsigned long seg;
+       int ret = -EFAULT;
 
-       if (copy_from_user(iov, uvec, nr_segs * sizeof(*uvec)))
+       if (!user_access_begin(uiov, nr_segs * sizeof(*uiov)))
                return -EFAULT;
-       for (seg = 0; seg < nr_segs; seg++) {
-               if ((ssize_t)iov[seg].iov_len < 0)
-                       return -EINVAL;
-       }
 
-       return 0;
+       do {
+               void __user *buf;
+               ssize_t len;
+
+               unsafe_get_user(len, &uiov->iov_len, uaccess_end);
+               unsafe_get_user(buf, &uiov->iov_base, uaccess_end);
+
+               /* check for size_t not fitting in ssize_t .. */
+               if (unlikely(len < 0)) {
+                       ret = -EINVAL;
+                       goto uaccess_end;
+               }
+               iov->iov_base = buf;
+               iov->iov_len = len;
+
+               uiov++; iov++;
+       } while (--nr_segs);
+
+       ret = 0;
+uaccess_end:
+       user_access_end();
+       return ret;
 }
 
 struct iovec *iovec_from_user(const struct iovec __user *uvec,
@@ -1767,7 +1788,7 @@ struct iovec *iovec_from_user(const struct iovec __user *uvec,
                        return ERR_PTR(-ENOMEM);
        }
 
-       if (compat)
+       if (unlikely(compat))
                ret = copy_compat_iovec_from_user(iov, uvec, nr_segs);
        else
                ret = copy_iovec_from_user(iov, uvec, nr_segs);
@@ -1780,6 +1801,30 @@ struct iovec *iovec_from_user(const struct iovec __user *uvec,
        return iov;
 }
 
+/*
+ * Single segment iovec supplied by the user, import it as ITER_UBUF.
+ */
+static ssize_t __import_iovec_ubuf(int type, const struct iovec __user *uvec,
+                                  struct iovec **iovp, struct iov_iter *i,
+                                  bool compat)
+{
+       struct iovec *iov = *iovp;
+       ssize_t ret;
+
+       if (compat)
+               ret = copy_compat_iovec_from_user(iov, uvec, 1);
+       else
+               ret = copy_iovec_from_user(iov, uvec, 1);
+       if (unlikely(ret))
+               return ret;
+
+       ret = import_ubuf(type, iov->iov_base, iov->iov_len, i);
+       if (unlikely(ret))
+               return ret;
+       *iovp = NULL;
+       return i->count;
+}
+
 ssize_t __import_iovec(int type, const struct iovec __user *uvec,
                 unsigned nr_segs, unsigned fast_segs, struct iovec **iovp,
                 struct iov_iter *i, bool compat)
@@ -1788,6 +1833,9 @@ ssize_t __import_iovec(int type, const struct iovec __user *uvec,
        unsigned long seg;
        struct iovec *iov;
 
+       if (nr_segs == 1)
+               return __import_iovec_ubuf(type, uvec, iovp, i, compat);
+
        iov = iovec_from_user(uvec, nr_segs, fast_segs, *iovp, compat);
        if (IS_ERR(iov)) {
                *iovp = NULL;
@@ -1866,9 +1914,7 @@ int import_single_range(int rw, void __user *buf, size_t len,
        if (unlikely(!access_ok(buf, len)))
                return -EFAULT;
 
-       iov->iov_base = buf;
-       iov->iov_len = len;
-       iov_iter_init(i, rw, iov, 1, len);
+       iov_iter_ubuf(i, rw, buf, len);
        return 0;
 }
 EXPORT_SYMBOL(import_single_range);
@@ -1918,7 +1964,7 @@ void iov_iter_restore(struct iov_iter *i, struct iov_iter_state *state)
        if (iov_iter_is_bvec(i))
                i->bvec -= state->nr_segs - i->nr_segs;
        else
-               i->iov -= state->nr_segs - i->nr_segs;
+               i->__iov -= state->nr_segs - i->nr_segs;
        i->nr_segs = state->nr_segs;
 }
 
index de0ee2e03ed60a44ec6e0c806a407d882144a5ed..b08bb1fba106d8c1c96a53f698a927e304c74439 100644 (file)
@@ -55,14 +55,24 @@ static int debugfs_print_results(struct seq_file *seq, void *v)
        enum kunit_status success = kunit_suite_has_succeeded(suite);
        struct kunit_case *test_case;
 
-       if (!suite || !suite->log)
+       if (!suite)
                return 0;
 
-       seq_printf(seq, "%s", suite->log);
+       /* Print KTAP header so the debugfs log can be parsed as valid KTAP. */
+       seq_puts(seq, "KTAP version 1\n");
+       seq_puts(seq, "1..1\n");
+
+       /* Print suite header because it is not stored in the test logs. */
+       seq_puts(seq, KUNIT_SUBTEST_INDENT "KTAP version 1\n");
+       seq_printf(seq, KUNIT_SUBTEST_INDENT "# Subtest: %s\n", suite->name);
+       seq_printf(seq, KUNIT_SUBTEST_INDENT "1..%zd\n", kunit_suite_num_test_cases(suite));
 
        kunit_suite_for_each_test_case(suite, test_case)
                debugfs_print_result(seq, suite, test_case);
 
+       if (suite->log)
+               seq_printf(seq, "%s", suite->log);
+
        seq_printf(seq, "%s %d %s\n",
                   kunit_status_to_ok_not_ok(success), 1, suite->name);
        return 0;
index 4df0335d0d06edb874820f37128c91013152e2c3..42e44caa1bdd89fe4c0db7fa7140a3db48135dca 100644 (file)
@@ -6,6 +6,7 @@
  * Author: Brendan Higgins <brendanhiggins@google.com>
  */
 #include <kunit/test.h>
+#include <kunit/test-bug.h>
 
 #include "try-catch-impl.h"
 
@@ -443,18 +444,6 @@ static struct kunit_suite kunit_resource_test_suite = {
        .test_cases = kunit_resource_test_cases,
 };
 
-static void kunit_log_test(struct kunit *test);
-
-static struct kunit_case kunit_log_test_cases[] = {
-       KUNIT_CASE(kunit_log_test),
-       {}
-};
-
-static struct kunit_suite kunit_log_test_suite = {
-       .name = "kunit-log-test",
-       .test_cases = kunit_log_test_cases,
-};
-
 static void kunit_log_test(struct kunit *test)
 {
        struct kunit_suite suite;
@@ -481,6 +470,29 @@ static void kunit_log_test(struct kunit *test)
 #endif
 }
 
+static void kunit_log_newline_test(struct kunit *test)
+{
+       kunit_info(test, "Add newline\n");
+       if (test->log) {
+               KUNIT_ASSERT_NOT_NULL_MSG(test, strstr(test->log, "Add newline\n"),
+                       "Missing log line, full log:\n%s", test->log);
+               KUNIT_EXPECT_NULL(test, strstr(test->log, "Add newline\n\n"));
+       } else {
+               kunit_skip(test, "only useful when debugfs is enabled");
+       }
+}
+
+static struct kunit_case kunit_log_test_cases[] = {
+       KUNIT_CASE(kunit_log_test),
+       KUNIT_CASE(kunit_log_newline_test),
+       {}
+};
+
+static struct kunit_suite kunit_log_test_suite = {
+       .name = "kunit-log-test",
+       .test_cases = kunit_log_test_cases,
+};
+
 static void kunit_status_set_failure_test(struct kunit *test)
 {
        struct kunit fake;
@@ -521,7 +533,46 @@ static struct kunit_suite kunit_status_test_suite = {
        .test_cases = kunit_status_test_cases,
 };
 
+static void kunit_current_test(struct kunit *test)
+{
+       /* Check results of both current->kunit_test and
+        * kunit_get_current_test() are equivalent to current test.
+        */
+       KUNIT_EXPECT_PTR_EQ(test, test, current->kunit_test);
+       KUNIT_EXPECT_PTR_EQ(test, test, kunit_get_current_test());
+}
+
+static void kunit_current_fail_test(struct kunit *test)
+{
+       struct kunit fake;
+
+       kunit_init_test(&fake, "fake test", NULL);
+       KUNIT_EXPECT_EQ(test, fake.status, KUNIT_SUCCESS);
+
+       /* Set current->kunit_test to fake test. */
+       current->kunit_test = &fake;
+
+       kunit_fail_current_test("This should make `fake` test fail.");
+       KUNIT_EXPECT_EQ(test, fake.status, (enum kunit_status)KUNIT_FAILURE);
+       kunit_cleanup(&fake);
+
+       /* Reset current->kunit_test to current test. */
+       current->kunit_test = test;
+}
+
+static struct kunit_case kunit_current_test_cases[] = {
+       KUNIT_CASE(kunit_current_test),
+       KUNIT_CASE(kunit_current_fail_test),
+       {}
+};
+
+static struct kunit_suite kunit_current_test_suite = {
+       .name = "kunit_current",
+       .test_cases = kunit_current_test_cases,
+};
+
 kunit_test_suites(&kunit_try_catch_test_suite, &kunit_resource_test_suite,
-                 &kunit_log_test_suite, &kunit_status_test_suite);
+                 &kunit_log_test_suite, &kunit_status_test_suite,
+                 &kunit_current_test_suite);
 
 MODULE_LICENSE("GPL v2");
index c9e15bb60058470adb4106cf892da1a169d657fd..e2910b2611129ddd91d54aa4cffc296b707de39c 100644 (file)
@@ -108,28 +108,51 @@ static void kunit_print_test_stats(struct kunit *test,
                  stats.total);
 }
 
+/**
+ * kunit_log_newline() - Add newline to the end of log if one is not
+ * already present.
+ * @log: The log to add the newline to.
+ */
+static void kunit_log_newline(char *log)
+{
+       int log_len, len_left;
+
+       log_len = strlen(log);
+       len_left = KUNIT_LOG_SIZE - log_len - 1;
+
+       if (log_len > 0 && log[log_len - 1] != '\n')
+               strncat(log, "\n", len_left);
+}
+
 /*
  * Append formatted message to log, size of which is limited to
  * KUNIT_LOG_SIZE bytes (including null terminating byte).
  */
 void kunit_log_append(char *log, const char *fmt, ...)
 {
-       char line[KUNIT_LOG_SIZE];
        va_list args;
-       int len_left;
+       int len, log_len, len_left;
 
        if (!log)
                return;
 
-       len_left = KUNIT_LOG_SIZE - strlen(log) - 1;
+       log_len = strlen(log);
+       len_left = KUNIT_LOG_SIZE - log_len - 1;
        if (len_left <= 0)
                return;
 
+       /* Evaluate length of line to add to log */
+       va_start(args, fmt);
+       len = vsnprintf(NULL, 0, fmt, args) + 1;
+       va_end(args);
+
+       /* Print formatted line to the log */
        va_start(args, fmt);
-       vsnprintf(line, sizeof(line), fmt, args);
+       vsnprintf(log + log_len, min(len, len_left), fmt, args);
        va_end(args);
 
-       strncat(log, line, len_left);
+       /* Add newline to end of log if not already present. */
+       kunit_log_newline(log);
 }
 EXPORT_SYMBOL_GPL(kunit_log_append);
 
@@ -147,10 +170,18 @@ EXPORT_SYMBOL_GPL(kunit_suite_num_test_cases);
 
 static void kunit_print_suite_start(struct kunit_suite *suite)
 {
-       kunit_log(KERN_INFO, suite, KUNIT_SUBTEST_INDENT "KTAP version 1\n");
-       kunit_log(KERN_INFO, suite, KUNIT_SUBTEST_INDENT "# Subtest: %s",
+       /*
+        * We do not log the test suite header as doing so would
+        * mean debugfs display would consist of the test suite
+        * header prior to individual test results.
+        * Hence directly printk the suite status, and we will
+        * separately seq_printf() the suite header for the debugfs
+        * representation.
+        */
+       pr_info(KUNIT_SUBTEST_INDENT "KTAP version 1\n");
+       pr_info(KUNIT_SUBTEST_INDENT "# Subtest: %s\n",
                  suite->name);
-       kunit_log(KERN_INFO, suite, KUNIT_SUBTEST_INDENT "1..%zd",
+       pr_info(KUNIT_SUBTEST_INDENT "1..%zd\n",
                  kunit_suite_num_test_cases(suite));
 }
 
@@ -167,10 +198,9 @@ static void kunit_print_ok_not_ok(void *test_or_suite,
 
        /*
         * We do not log the test suite results as doing so would
-        * mean debugfs display would consist of the test suite
-        * description and status prior to individual test results.
-        * Hence directly printk the suite status, and we will
-        * separately seq_printf() the suite status for the debugfs
+        * mean debugfs display would consist of an incorrect test
+        * number. Hence directly printk the suite result, and we will
+        * separately seq_printf() the suite results for the debugfs
         * representation.
         */
        if (suite)
@@ -437,7 +467,6 @@ static void kunit_run_case_catch_errors(struct kunit_suite *suite,
        struct kunit_try_catch_context context;
        struct kunit_try_catch *try_catch;
 
-       kunit_init_test(test, test_case->name, test_case->log);
        try_catch = &test->try_catch;
 
        kunit_try_catch_init(try_catch,
@@ -533,6 +562,8 @@ int kunit_run_tests(struct kunit_suite *suite)
                struct kunit_result_stats param_stats = { 0 };
                test_case->status = KUNIT_SKIPPED;
 
+               kunit_init_test(&test, test_case->name, test_case->log);
+
                if (!test_case->generate_params) {
                        /* Non-parameterised test. */
                        kunit_run_case_catch_errors(suite, test_case, &test);
index d374cf5d1a5790ee7be762630434acbcb1eca31a..0cc27de9cec88899b63a246cb542187b8bbac9b9 100644 (file)
@@ -8,6 +8,7 @@
 #include <kunit/test.h>
 
 #include <linux/list.h>
+#include <linux/klist.h>
 
 struct list_test_struct {
        int data;
@@ -1199,6 +1200,303 @@ static struct kunit_suite hlist_test_module = {
        .test_cases = hlist_test_cases,
 };
 
-kunit_test_suites(&list_test_module, &hlist_test_module);
+
+struct klist_test_struct {
+       int data;
+       struct klist klist;
+       struct klist_node klist_node;
+};
+
+static int node_count;
+static struct klist_node *last_node;
+
+static void check_node(struct klist_node *node_ptr)
+{
+       node_count++;
+       last_node = node_ptr;
+}
+
+static void check_delete_node(struct klist_node *node_ptr)
+{
+       node_count--;
+       last_node = node_ptr;
+}
+
+static void klist_test_add_tail(struct kunit *test)
+{
+       struct klist_node a, b;
+       struct klist mylist;
+       struct klist_iter i;
+
+       node_count = 0;
+       klist_init(&mylist, &check_node, NULL);
+
+       klist_add_tail(&a, &mylist);
+       KUNIT_EXPECT_EQ(test, node_count, 1);
+       KUNIT_EXPECT_PTR_EQ(test, last_node, &a);
+
+       klist_add_tail(&b, &mylist);
+       KUNIT_EXPECT_EQ(test, node_count, 2);
+       KUNIT_EXPECT_PTR_EQ(test, last_node, &b);
+
+       /* should be [list] -> a -> b */
+       klist_iter_init(&mylist, &i);
+
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
+       KUNIT_EXPECT_NULL(test, klist_next(&i));
+
+       klist_iter_exit(&i);
+
+}
+
+static void klist_test_add_head(struct kunit *test)
+{
+       struct klist_node a, b;
+       struct klist mylist;
+       struct klist_iter i;
+
+       node_count = 0;
+       klist_init(&mylist, &check_node, NULL);
+
+       klist_add_head(&a, &mylist);
+       KUNIT_EXPECT_EQ(test, node_count, 1);
+       KUNIT_EXPECT_PTR_EQ(test, last_node, &a);
+
+       klist_add_head(&b, &mylist);
+       KUNIT_EXPECT_EQ(test, node_count, 2);
+       KUNIT_EXPECT_PTR_EQ(test, last_node, &b);
+
+       /* should be [list] -> b -> a */
+       klist_iter_init(&mylist, &i);
+
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
+       KUNIT_EXPECT_NULL(test, klist_next(&i));
+
+       klist_iter_exit(&i);
+
+}
+
+static void klist_test_add_behind(struct kunit *test)
+{
+       struct klist_node a, b, c, d;
+       struct klist mylist;
+       struct klist_iter i;
+
+       node_count = 0;
+       klist_init(&mylist, &check_node, NULL);
+
+       klist_add_head(&a, &mylist);
+       klist_add_head(&b, &mylist);
+
+       klist_add_behind(&c, &a);
+       KUNIT_EXPECT_EQ(test, node_count, 3);
+       KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
+
+       klist_add_behind(&d, &b);
+       KUNIT_EXPECT_EQ(test, node_count, 4);
+       KUNIT_EXPECT_PTR_EQ(test, last_node, &d);
+
+       klist_iter_init(&mylist, &i);
+
+       /* should be [list] -> b -> d -> a -> c*/
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &c);
+       KUNIT_EXPECT_NULL(test, klist_next(&i));
+
+       klist_iter_exit(&i);
+
+}
+
+static void klist_test_add_before(struct kunit *test)
+{
+       struct klist_node a, b, c, d;
+       struct klist mylist;
+       struct klist_iter i;
+
+       node_count = 0;
+       klist_init(&mylist, &check_node, NULL);
+
+       klist_add_head(&a, &mylist);
+       klist_add_head(&b, &mylist);
+       klist_add_before(&c, &a);
+       KUNIT_EXPECT_EQ(test, node_count, 3);
+       KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
+
+       klist_add_before(&d, &b);
+       KUNIT_EXPECT_EQ(test, node_count, 4);
+       KUNIT_EXPECT_PTR_EQ(test, last_node, &d);
+
+       klist_iter_init(&mylist, &i);
+
+       /* should be [list] -> b -> d -> a -> c*/
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &c);
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
+       KUNIT_EXPECT_NULL(test, klist_next(&i));
+
+       klist_iter_exit(&i);
+
+}
+
+/*
+ * Verify that klist_del() delays the deletion of a node until there
+ * are no other references to it
+ */
+static void klist_test_del_refcount_greater_than_zero(struct kunit *test)
+{
+       struct klist_node a, b, c, d;
+       struct klist mylist;
+       struct klist_iter i;
+
+       node_count = 0;
+       klist_init(&mylist, &check_node, &check_delete_node);
+
+       /* Add nodes a,b,c,d to the list*/
+       klist_add_tail(&a, &mylist);
+       klist_add_tail(&b, &mylist);
+       klist_add_tail(&c, &mylist);
+       klist_add_tail(&d, &mylist);
+
+       klist_iter_init(&mylist, &i);
+
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
+       /* Advance the iterator to point to node c*/
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &c);
+
+       /* Try to delete node c while there is a reference to it*/
+       klist_del(&c);
+
+       /*
+        * Verify that node c is still attached to the list even after being
+        * deleted. Since the iterator still points to c, the reference count is not
+        * decreased to 0
+        */
+       KUNIT_EXPECT_TRUE(test, klist_node_attached(&c));
+
+       /* Check that node c has not been removed yet*/
+       KUNIT_EXPECT_EQ(test, node_count, 4);
+       KUNIT_EXPECT_PTR_EQ(test, last_node, &d);
+
+       klist_iter_exit(&i);
+
+       /*
+        * Since the iterator is no longer pointing to node c, node c is removed
+        * from the list
+        */
+       KUNIT_EXPECT_EQ(test, node_count, 3);
+       KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
+
+}
+
+/*
+ * Verify that klist_del() deletes a node immediately when there are no
+ * other references to it.
+ */
+static void klist_test_del_refcount_zero(struct kunit *test)
+{
+       struct klist_node a, b, c, d;
+       struct klist mylist;
+       struct klist_iter i;
+
+       node_count = 0;
+       klist_init(&mylist, &check_node, &check_delete_node);
+
+       /* Add nodes a,b,c,d to the list*/
+       klist_add_tail(&a, &mylist);
+       klist_add_tail(&b, &mylist);
+       klist_add_tail(&c, &mylist);
+       klist_add_tail(&d, &mylist);
+       /* Delete node c*/
+       klist_del(&c);
+
+       /* Check that node c is deleted from the list*/
+       KUNIT_EXPECT_EQ(test, node_count, 3);
+       KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
+
+       /* Should be [list] -> a -> b -> d*/
+       klist_iter_init(&mylist, &i);
+
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
+       KUNIT_EXPECT_NULL(test, klist_next(&i));
+
+       klist_iter_exit(&i);
+
+}
+
+static void klist_test_remove(struct kunit *test)
+{
+       /* This test doesn't check correctness under concurrent access */
+       struct klist_node a, b, c, d;
+       struct klist mylist;
+       struct klist_iter i;
+
+       node_count = 0;
+       klist_init(&mylist, &check_node, &check_delete_node);
+
+       /* Add nodes a,b,c,d to the list*/
+       klist_add_tail(&a, &mylist);
+       klist_add_tail(&b, &mylist);
+       klist_add_tail(&c, &mylist);
+       klist_add_tail(&d, &mylist);
+       /* Delete node c*/
+       klist_remove(&c);
+
+       /* Check the nodes in the list*/
+       KUNIT_EXPECT_EQ(test, node_count, 3);
+       KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
+
+       /* should be [list] -> a -> b -> d*/
+       klist_iter_init(&mylist, &i);
+
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
+       KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
+       KUNIT_EXPECT_NULL(test, klist_next(&i));
+
+       klist_iter_exit(&i);
+
+}
+
+static void klist_test_node_attached(struct kunit *test)
+{
+       struct klist_node a = {};
+       struct klist mylist;
+
+       klist_init(&mylist, NULL, NULL);
+
+       KUNIT_EXPECT_FALSE(test, klist_node_attached(&a));
+       klist_add_head(&a, &mylist);
+       KUNIT_EXPECT_TRUE(test, klist_node_attached(&a));
+       klist_del(&a);
+       KUNIT_EXPECT_FALSE(test, klist_node_attached(&a));
+
+}
+
+static struct kunit_case klist_test_cases[] = {
+       KUNIT_CASE(klist_test_add_tail),
+       KUNIT_CASE(klist_test_add_head),
+       KUNIT_CASE(klist_test_add_behind),
+       KUNIT_CASE(klist_test_add_before),
+       KUNIT_CASE(klist_test_del_refcount_greater_than_zero),
+       KUNIT_CASE(klist_test_del_refcount_zero),
+       KUNIT_CASE(klist_test_remove),
+       KUNIT_CASE(klist_test_node_attached),
+       {},
+};
+
+static struct kunit_suite klist_test_module = {
+       .name = "klist",
+       .test_cases = klist_test_cases,
+};
+
+kunit_test_suites(&list_test_module, &hlist_test_module, &klist_test_module);
 
 MODULE_LICENSE("GPL v2");
index 646297cae5d16dea90e9fbc0b22d02f2198c6b93..1281a40d5735c423c47a451c53eec273dd8deda1 100644 (file)
@@ -185,7 +185,7 @@ static void mt_free_rcu(struct rcu_head *head)
  */
 static void ma_free_rcu(struct maple_node *node)
 {
-       node->parent = ma_parent_ptr(node);
+       WARN_ON(node->parent != ma_parent_ptr(node));
        call_rcu(&node->rcu, mt_free_rcu);
 }
 
@@ -539,11 +539,14 @@ static inline struct maple_node *mte_parent(const struct maple_enode *enode)
  */
 static inline bool ma_dead_node(const struct maple_node *node)
 {
-       struct maple_node *parent = (void *)((unsigned long)
-                                            node->parent & ~MAPLE_NODE_MASK);
+       struct maple_node *parent;
 
+       /* Do not reorder reads from the node prior to the parent check */
+       smp_rmb();
+       parent = (void *)((unsigned long) node->parent & ~MAPLE_NODE_MASK);
        return (parent == node);
 }
+
 /*
  * mte_dead_node() - check if the @enode is dead.
  * @enode: The encoded maple node
@@ -555,6 +558,8 @@ static inline bool mte_dead_node(const struct maple_enode *enode)
        struct maple_node *parent, *node;
 
        node = mte_to_node(enode);
+       /* Do not reorder reads from the node prior to the parent check */
+       smp_rmb();
        parent = mte_parent(enode);
        return (parent == node);
 }
@@ -625,6 +630,8 @@ static inline unsigned int mas_alloc_req(const struct ma_state *mas)
  * @node - the maple node
  * @type - the node type
  *
+ * In the event of a dead node, this array may be %NULL
+ *
  * Return: A pointer to the maple node pivots
  */
 static inline unsigned long *ma_pivots(struct maple_node *node,
@@ -817,6 +824,11 @@ static inline void *mt_slot(const struct maple_tree *mt,
        return rcu_dereference_check(slots[offset], mt_locked(mt));
 }
 
+static inline void *mt_slot_locked(struct maple_tree *mt, void __rcu **slots,
+                                  unsigned char offset)
+{
+       return rcu_dereference_protected(slots[offset], mt_locked(mt));
+}
 /*
  * mas_slot_locked() - Get the slot value when holding the maple tree lock.
  * @mas: The maple state
@@ -828,7 +840,7 @@ static inline void *mt_slot(const struct maple_tree *mt,
 static inline void *mas_slot_locked(struct ma_state *mas, void __rcu **slots,
                                       unsigned char offset)
 {
-       return rcu_dereference_protected(slots[offset], mt_locked(mas->tree));
+       return mt_slot_locked(mas->tree, slots, offset);
 }
 
 /*
@@ -899,6 +911,45 @@ static inline void ma_set_meta(struct maple_node *mn, enum maple_type mt,
        meta->end = end;
 }
 
+/*
+ * mt_clear_meta() - clear the metadata information of a node, if it exists
+ * @mt: The maple tree
+ * @mn: The maple node
+ * @type: The maple node type
+ * @offset: The offset of the highest sub-gap in this node.
+ * @end: The end of the data in this node.
+ */
+static inline void mt_clear_meta(struct maple_tree *mt, struct maple_node *mn,
+                                 enum maple_type type)
+{
+       struct maple_metadata *meta;
+       unsigned long *pivots;
+       void __rcu **slots;
+       void *next;
+
+       switch (type) {
+       case maple_range_64:
+               pivots = mn->mr64.pivot;
+               if (unlikely(pivots[MAPLE_RANGE64_SLOTS - 2])) {
+                       slots = mn->mr64.slot;
+                       next = mt_slot_locked(mt, slots,
+                                             MAPLE_RANGE64_SLOTS - 1);
+                       if (unlikely((mte_to_node(next) &&
+                                     mte_node_type(next))))
+                               return; /* no metadata, could be node */
+               }
+               fallthrough;
+       case maple_arange_64:
+               meta = ma_meta(mn, type);
+               break;
+       default:
+               return;
+       }
+
+       meta->gap = 0;
+       meta->end = 0;
+}
+
 /*
  * ma_meta_end() - Get the data end of a node from the metadata
  * @mn: The maple node
@@ -1096,8 +1147,11 @@ static int mas_ascend(struct ma_state *mas)
                a_type = mas_parent_enum(mas, p_enode);
                a_node = mte_parent(p_enode);
                a_slot = mte_parent_slot(p_enode);
-               pivots = ma_pivots(a_node, a_type);
                a_enode = mt_mk_node(a_node, a_type);
+               pivots = ma_pivots(a_node, a_type);
+
+               if (unlikely(ma_dead_node(a_node)))
+                       return 1;
 
                if (!set_min && a_slot) {
                        set_min = true;
@@ -1249,26 +1303,21 @@ static inline void mas_alloc_nodes(struct ma_state *mas, gfp_t gfp)
        node = mas->alloc;
        node->request_count = 0;
        while (requested) {
-               max_req = MAPLE_ALLOC_SLOTS;
-               if (node->node_count) {
-                       unsigned int offset = node->node_count;
-
-                       slots = (void **)&node->slot[offset];
-                       max_req -= offset;
-               } else {
-                       slots = (void **)&node->slot;
-               }
-
+               max_req = MAPLE_ALLOC_SLOTS - node->node_count;
+               slots = (void **)&node->slot[node->node_count];
                max_req = min(requested, max_req);
                count = mt_alloc_bulk(gfp, max_req, slots);
                if (!count)
                        goto nomem_bulk;
 
+               if (node->node_count == 0) {
+                       node->slot[0]->node_count = 0;
+                       node->slot[0]->request_count = 0;
+               }
+
                node->node_count += count;
                allocated += count;
                node = node->slot[0];
-               node->node_count = 0;
-               node->request_count = 0;
                requested -= count;
        }
        mas->alloc->total = allocated;
@@ -1354,12 +1403,16 @@ static inline struct maple_enode *mas_start(struct ma_state *mas)
                mas->max = ULONG_MAX;
                mas->depth = 0;
 
+retry:
                root = mas_root(mas);
                /* Tree with nodes */
                if (likely(xa_is_node(root))) {
                        mas->depth = 1;
                        mas->node = mte_safe_root(root);
                        mas->offset = 0;
+                       if (mte_dead_node(mas->node))
+                               goto retry;
+
                        return NULL;
                }
 
@@ -1401,6 +1454,9 @@ static inline unsigned char ma_data_end(struct maple_node *node,
 {
        unsigned char offset;
 
+       if (!pivots)
+               return 0;
+
        if (type == maple_arange_64)
                return ma_meta_end(node, type);
 
@@ -1436,6 +1492,9 @@ static inline unsigned char mas_data_end(struct ma_state *mas)
                return ma_meta_end(node, type);
 
        pivots = ma_pivots(node, type);
+       if (unlikely(ma_dead_node(node)))
+               return 0;
+
        offset = mt_pivots[type] - 1;
        if (likely(!pivots[offset]))
                return ma_meta_end(node, type);
@@ -1724,8 +1783,10 @@ static inline void mas_replace(struct ma_state *mas, bool advanced)
                rcu_assign_pointer(slots[offset], mas->node);
        }
 
-       if (!advanced)
+       if (!advanced) {
+               mte_set_node_dead(old_enode);
                mas_free(mas, old_enode);
+       }
 }
 
 /*
@@ -3659,10 +3720,9 @@ static inline int mas_root_expand(struct ma_state *mas, void *entry)
                slot++;
        mas->depth = 1;
        mas_set_height(mas);
-
+       ma_set_meta(node, maple_leaf_64, 0, slot);
        /* swap the new root into the tree */
        rcu_assign_pointer(mas->tree->ma_root, mte_mk_root(mas->node));
-       ma_set_meta(node, maple_leaf_64, 0, slot);
        return slot;
 }
 
@@ -3875,18 +3935,13 @@ static inline void *mtree_lookup_walk(struct ma_state *mas)
                end = ma_data_end(node, type, pivots, max);
                if (unlikely(ma_dead_node(node)))
                        goto dead_node;
-
-               if (pivots[offset] >= mas->index)
-                       goto next;
-
                do {
-                       offset++;
-               } while ((offset < end) && (pivots[offset] < mas->index));
-
-               if (likely(offset > end))
-                       max = pivots[offset];
+                       if (pivots[offset] >= mas->index) {
+                               max = pivots[offset];
+                               break;
+                       }
+               } while (++offset < end);
 
-next:
                slots = ma_slots(node, type);
                next = mt_slot(mas->tree, slots, offset);
                if (unlikely(ma_dead_node(node)))
@@ -4164,6 +4219,7 @@ static inline bool mas_wr_node_store(struct ma_wr_state *wr_mas)
 done:
        mas_leaf_set_meta(mas, newnode, dst_pivots, maple_leaf_64, new_end);
        if (in_rcu) {
+               mte_set_node_dead(mas->node);
                mas->node = mt_mk_node(newnode, wr_mas->type);
                mas_replace(mas, false);
        } else {
@@ -4505,6 +4561,9 @@ static inline int mas_prev_node(struct ma_state *mas, unsigned long min)
        node = mas_mn(mas);
        slots = ma_slots(node, mt);
        pivots = ma_pivots(node, mt);
+       if (unlikely(ma_dead_node(node)))
+               return 1;
+
        mas->max = pivots[offset];
        if (offset)
                mas->min = pivots[offset - 1] + 1;
@@ -4526,6 +4585,9 @@ static inline int mas_prev_node(struct ma_state *mas, unsigned long min)
                slots = ma_slots(node, mt);
                pivots = ma_pivots(node, mt);
                offset = ma_data_end(node, mt, pivots, mas->max);
+               if (unlikely(ma_dead_node(node)))
+                       return 1;
+
                if (offset)
                        mas->min = pivots[offset - 1] + 1;
 
@@ -4574,6 +4636,7 @@ static inline int mas_next_node(struct ma_state *mas, struct maple_node *node,
        struct maple_enode *enode;
        int level = 0;
        unsigned char offset;
+       unsigned char node_end;
        enum maple_type mt;
        void __rcu **slots;
 
@@ -4597,7 +4660,11 @@ static inline int mas_next_node(struct ma_state *mas, struct maple_node *node,
                node = mas_mn(mas);
                mt = mte_node_type(mas->node);
                pivots = ma_pivots(node, mt);
-       } while (unlikely(offset == ma_data_end(node, mt, pivots, mas->max)));
+               node_end = ma_data_end(node, mt, pivots, mas->max);
+               if (unlikely(ma_dead_node(node)))
+                       return 1;
+
+       } while (unlikely(offset == node_end));
 
        slots = ma_slots(node, mt);
        pivot = mas_safe_pivot(mas, pivots, ++offset, mt);
@@ -4613,6 +4680,9 @@ static inline int mas_next_node(struct ma_state *mas, struct maple_node *node,
                mt = mte_node_type(mas->node);
                slots = ma_slots(node, mt);
                pivots = ma_pivots(node, mt);
+               if (unlikely(ma_dead_node(node)))
+                       return 1;
+
                offset = 0;
                pivot = pivots[0];
        }
@@ -4659,11 +4729,14 @@ static inline void *mas_next_nentry(struct ma_state *mas,
                return NULL;
        }
 
-       pivots = ma_pivots(node, type);
        slots = ma_slots(node, type);
-       mas->index = mas_safe_min(mas, pivots, mas->offset);
+       pivots = ma_pivots(node, type);
        count = ma_data_end(node, type, pivots, mas->max);
-       if (ma_dead_node(node))
+       if (unlikely(ma_dead_node(node)))
+               return NULL;
+
+       mas->index = mas_safe_min(mas, pivots, mas->offset);
+       if (unlikely(ma_dead_node(node)))
                return NULL;
 
        if (mas->index > max)
@@ -4817,6 +4890,11 @@ retry:
 
        slots = ma_slots(mn, mt);
        pivots = ma_pivots(mn, mt);
+       if (unlikely(ma_dead_node(mn))) {
+               mas_rewalk(mas, index);
+               goto retry;
+       }
+
        if (offset == mt_pivots[mt])
                pivot = mas->max;
        else
@@ -4887,7 +4965,8 @@ not_found:
  * Return: True if found in a leaf, false otherwise.
  *
  */
-static bool mas_rev_awalk(struct ma_state *mas, unsigned long size)
+static bool mas_rev_awalk(struct ma_state *mas, unsigned long size,
+               unsigned long *gap_min, unsigned long *gap_max)
 {
        enum maple_type type = mte_node_type(mas->node);
        struct maple_node *node = mas_mn(mas);
@@ -4952,8 +5031,8 @@ static bool mas_rev_awalk(struct ma_state *mas, unsigned long size)
 
        if (unlikely(ma_is_leaf(type))) {
                mas->offset = offset;
-               mas->min = min;
-               mas->max = min + gap - 1;
+               *gap_min = min;
+               *gap_max = min + gap - 1;
                return true;
        }
 
@@ -4977,10 +5056,10 @@ static inline bool mas_anode_descend(struct ma_state *mas, unsigned long size)
 {
        enum maple_type type = mte_node_type(mas->node);
        unsigned long pivot, min, gap = 0;
-       unsigned char offset;
-       unsigned long *gaps;
-       unsigned long *pivots = ma_pivots(mas_mn(mas), type);
-       void __rcu **slots = ma_slots(mas_mn(mas), type);
+       unsigned char offset, data_end;
+       unsigned long *gaps, *pivots;
+       void __rcu **slots;
+       struct maple_node *node;
        bool found = false;
 
        if (ma_is_dense(type)) {
@@ -4988,13 +5067,15 @@ static inline bool mas_anode_descend(struct ma_state *mas, unsigned long size)
                return true;
        }
 
-       gaps = ma_gaps(mte_to_node(mas->node), type);
+       node = mas_mn(mas);
+       pivots = ma_pivots(node, type);
+       slots = ma_slots(node, type);
+       gaps = ma_gaps(node, type);
        offset = mas->offset;
        min = mas_safe_min(mas, pivots, offset);
-       for (; offset < mt_slots[type]; offset++) {
-               pivot = mas_safe_pivot(mas, pivots, offset, type);
-               if (offset && !pivot)
-                       break;
+       data_end = ma_data_end(node, type, pivots, mas->max);
+       for (; offset <= data_end; offset++) {
+               pivot = mas_logical_pivot(mas, pivots, offset, type);
 
                /* Not within lower bounds */
                if (mas->index > pivot)
@@ -5099,35 +5180,21 @@ static inline bool mas_rewind_node(struct ma_state *mas)
  */
 static inline bool mas_skip_node(struct ma_state *mas)
 {
-       unsigned char slot, slot_count;
-       unsigned long *pivots;
-       enum maple_type mt;
+       if (mas_is_err(mas))
+               return false;
 
-       mt = mte_node_type(mas->node);
-       slot_count = mt_slots[mt] - 1;
        do {
                if (mte_is_root(mas->node)) {
-                       slot = mas->offset;
-                       if (slot > slot_count) {
+                       if (mas->offset >= mas_data_end(mas)) {
                                mas_set_err(mas, -EBUSY);
                                return false;
                        }
                } else {
                        mas_ascend(mas);
-                       slot = mas->offset;
-                       mt = mte_node_type(mas->node);
-                       slot_count = mt_slots[mt] - 1;
                }
-       } while (slot > slot_count);
-
-       mas->offset = ++slot;
-       pivots = ma_pivots(mas_mn(mas), mt);
-       if (slot > 0)
-               mas->min = pivots[slot - 1] + 1;
-
-       if (slot <= slot_count)
-               mas->max = pivots[slot];
+       } while (mas->offset >= mas_data_end(mas));
 
+       mas->offset++;
        return true;
 }
 
@@ -5243,6 +5310,9 @@ int mas_empty_area(struct ma_state *mas, unsigned long min,
        unsigned long *pivots;
        enum maple_type mt;
 
+       if (min >= max)
+               return -EINVAL;
+
        if (mas_is_start(mas))
                mas_start(mas);
        else if (mas->offset >= 2)
@@ -5297,6 +5367,9 @@ int mas_empty_area_rev(struct ma_state *mas, unsigned long min,
 {
        struct maple_enode *last = mas->node;
 
+       if (min >= max)
+               return -EINVAL;
+
        if (mas_is_start(mas)) {
                mas_start(mas);
                mas->offset = mas_data_end(mas);
@@ -5316,7 +5389,7 @@ int mas_empty_area_rev(struct ma_state *mas, unsigned long min,
        mas->index = min;
        mas->last = max;
 
-       while (!mas_rev_awalk(mas, size)) {
+       while (!mas_rev_awalk(mas, size, &min, &max)) {
                if (last == mas->node) {
                        if (!mas_rewind_node(mas))
                                return -EBUSY;
@@ -5331,17 +5404,9 @@ int mas_empty_area_rev(struct ma_state *mas, unsigned long min,
        if (unlikely(mas->offset == MAPLE_NODE_SLOTS))
                return -EBUSY;
 
-       /*
-        * mas_rev_awalk() has set mas->min and mas->max to the gap values.  If
-        * the maximum is outside the window we are searching, then use the last
-        * location in the search.
-        * mas->max and mas->min is the range of the gap.
-        * mas->index and mas->last are currently set to the search range.
-        */
-
        /* Trim the upper limit to the max. */
-       if (mas->max <= mas->last)
-               mas->last = mas->max;
+       if (max <= mas->last)
+               mas->last = max;
 
        mas->index = mas->last - size + 1;
        return 0;
@@ -5414,24 +5479,26 @@ no_gap:
 }
 
 /*
- * mas_dead_leaves() - Mark all leaves of a node as dead.
+ * mte_dead_leaves() - Mark all leaves of a node as dead.
  * @mas: The maple state
  * @slots: Pointer to the slot array
+ * @type: The maple node type
  *
  * Must hold the write lock.
  *
  * Return: The number of leaves marked as dead.
  */
 static inline
-unsigned char mas_dead_leaves(struct ma_state *mas, void __rcu **slots)
+unsigned char mte_dead_leaves(struct maple_enode *enode, struct maple_tree *mt,
+                             void __rcu **slots)
 {
        struct maple_node *node;
        enum maple_type type;
        void *entry;
        int offset;
 
-       for (offset = 0; offset < mt_slot_count(mas->node); offset++) {
-               entry = mas_slot_locked(mas, slots, offset);
+       for (offset = 0; offset < mt_slot_count(enode); offset++) {
+               entry = mt_slot(mt, slots, offset);
                type = mte_node_type(entry);
                node = mte_to_node(entry);
                /* Use both node and type to catch LE & BE metadata */
@@ -5439,7 +5506,6 @@ unsigned char mas_dead_leaves(struct ma_state *mas, void __rcu **slots)
                        break;
 
                mte_set_node_dead(entry);
-               smp_wmb(); /* Needed for RCU */
                node->type = type;
                rcu_assign_pointer(slots[offset], node);
        }
@@ -5447,151 +5513,160 @@ unsigned char mas_dead_leaves(struct ma_state *mas, void __rcu **slots)
        return offset;
 }
 
-static void __rcu **mas_dead_walk(struct ma_state *mas, unsigned char offset)
+/**
+ * mte_dead_walk() - Walk down a dead tree to just before the leaves
+ * @enode: The maple encoded node
+ * @offset: The starting offset
+ *
+ * Note: This can only be used from the RCU callback context.
+ */
+static void __rcu **mte_dead_walk(struct maple_enode **enode, unsigned char offset)
 {
        struct maple_node *node, *next;
        void __rcu **slots = NULL;
 
-       next = mas_mn(mas);
+       next = mte_to_node(*enode);
        do {
-               mas->node = ma_enode_ptr(next);
-               node = mas_mn(mas);
+               *enode = ma_enode_ptr(next);
+               node = mte_to_node(*enode);
                slots = ma_slots(node, node->type);
-               next = mas_slot_locked(mas, slots, offset);
+               next = rcu_dereference_protected(slots[offset],
+                                       lock_is_held(&rcu_callback_map));
                offset = 0;
        } while (!ma_is_leaf(next->type));
 
        return slots;
 }
 
+/**
+ * mt_free_walk() - Walk & free a tree in the RCU callback context
+ * @head: The RCU head that's within the node.
+ *
+ * Note: This can only be used from the RCU callback context.
+ */
 static void mt_free_walk(struct rcu_head *head)
 {
        void __rcu **slots;
        struct maple_node *node, *start;
-       struct maple_tree mt;
+       struct maple_enode *enode;
        unsigned char offset;
        enum maple_type type;
-       MA_STATE(mas, &mt, 0, 0);
 
        node = container_of(head, struct maple_node, rcu);
 
        if (ma_is_leaf(node->type))
                goto free_leaf;
 
-       mt_init_flags(&mt, node->ma_flags);
-       mas_lock(&mas);
        start = node;
-       mas.node = mt_mk_node(node, node->type);
-       slots = mas_dead_walk(&mas, 0);
-       node = mas_mn(&mas);
+       enode = mt_mk_node(node, node->type);
+       slots = mte_dead_walk(&enode, 0);
+       node = mte_to_node(enode);
        do {
                mt_free_bulk(node->slot_len, slots);
                offset = node->parent_slot + 1;
-               mas.node = node->piv_parent;
-               if (mas_mn(&mas) == node)
-                       goto start_slots_free;
-
-               type = mte_node_type(mas.node);
-               slots = ma_slots(mte_to_node(mas.node), type);
-               if ((offset < mt_slots[type]) && (slots[offset]))
-                       slots = mas_dead_walk(&mas, offset);
-
-               node = mas_mn(&mas);
+               enode = node->piv_parent;
+               if (mte_to_node(enode) == node)
+                       goto free_leaf;
+
+               type = mte_node_type(enode);
+               slots = ma_slots(mte_to_node(enode), type);
+               if ((offset < mt_slots[type]) &&
+                   rcu_dereference_protected(slots[offset],
+                                             lock_is_held(&rcu_callback_map)))
+                       slots = mte_dead_walk(&enode, offset);
+               node = mte_to_node(enode);
        } while ((node != start) || (node->slot_len < offset));
 
        slots = ma_slots(node, node->type);
        mt_free_bulk(node->slot_len, slots);
 
-start_slots_free:
-       mas_unlock(&mas);
 free_leaf:
        mt_free_rcu(&node->rcu);
 }
 
-static inline void __rcu **mas_destroy_descend(struct ma_state *mas,
-                       struct maple_enode *prev, unsigned char offset)
+static inline void __rcu **mte_destroy_descend(struct maple_enode **enode,
+       struct maple_tree *mt, struct maple_enode *prev, unsigned char offset)
 {
        struct maple_node *node;
-       struct maple_enode *next = mas->node;
+       struct maple_enode *next = *enode;
        void __rcu **slots = NULL;
+       enum maple_type type;
+       unsigned char next_offset = 0;
 
        do {
-               mas->node = next;
-               node = mas_mn(mas);
-               slots = ma_slots(node, mte_node_type(mas->node));
-               next = mas_slot_locked(mas, slots, 0);
+               *enode = next;
+               node = mte_to_node(*enode);
+               type = mte_node_type(*enode);
+               slots = ma_slots(node, type);
+               next = mt_slot_locked(mt, slots, next_offset);
                if ((mte_dead_node(next)))
-                       next = mas_slot_locked(mas, slots, 1);
+                       next = mt_slot_locked(mt, slots, ++next_offset);
 
-               mte_set_node_dead(mas->node);
-               node->type = mte_node_type(mas->node);
+               mte_set_node_dead(*enode);
+               node->type = type;
                node->piv_parent = prev;
                node->parent_slot = offset;
-               offset = 0;
-               prev = mas->node;
+               offset = next_offset;
+               next_offset = 0;
+               prev = *enode;
        } while (!mte_is_leaf(next));
 
        return slots;
 }
 
-static void mt_destroy_walk(struct maple_enode *enode, unsigned char ma_flags,
+static void mt_destroy_walk(struct maple_enode *enode, struct maple_tree *mt,
                            bool free)
 {
        void __rcu **slots;
        struct maple_node *node = mte_to_node(enode);
        struct maple_enode *start;
-       struct maple_tree mt;
-
-       MA_STATE(mas, &mt, 0, 0);
 
-       if (mte_is_leaf(enode))
+       if (mte_is_leaf(enode)) {
+               node->type = mte_node_type(enode);
                goto free_leaf;
+       }
 
-       mt_init_flags(&mt, ma_flags);
-       mas_lock(&mas);
-
-       mas.node = start = enode;
-       slots = mas_destroy_descend(&mas, start, 0);
-       node = mas_mn(&mas);
+       start = enode;
+       slots = mte_destroy_descend(&enode, mt, start, 0);
+       node = mte_to_node(enode); // Updated in the above call.
        do {
                enum maple_type type;
                unsigned char offset;
                struct maple_enode *parent, *tmp;
 
-               node->slot_len = mas_dead_leaves(&mas, slots);
+               node->slot_len = mte_dead_leaves(enode, mt, slots);
                if (free)
                        mt_free_bulk(node->slot_len, slots);
                offset = node->parent_slot + 1;
-               mas.node = node->piv_parent;
-               if (mas_mn(&mas) == node)
-                       goto start_slots_free;
+               enode = node->piv_parent;
+               if (mte_to_node(enode) == node)
+                       goto free_leaf;
 
-               type = mte_node_type(mas.node);
-               slots = ma_slots(mte_to_node(mas.node), type);
+               type = mte_node_type(enode);
+               slots = ma_slots(mte_to_node(enode), type);
                if (offset >= mt_slots[type])
                        goto next;
 
-               tmp = mas_slot_locked(&mas, slots, offset);
+               tmp = mt_slot_locked(mt, slots, offset);
                if (mte_node_type(tmp) && mte_to_node(tmp)) {
-                       parent = mas.node;
-                       mas.node = tmp;
-                       slots = mas_destroy_descend(&mas, parent, offset);
+                       parent = enode;
+                       enode = tmp;
+                       slots = mte_destroy_descend(&enode, mt, parent, offset);
                }
 next:
-               node = mas_mn(&mas);
-       } while (start != mas.node);
+               node = mte_to_node(enode);
+       } while (start != enode);
 
-       node = mas_mn(&mas);
-       node->slot_len = mas_dead_leaves(&mas, slots);
+       node = mte_to_node(enode);
+       node->slot_len = mte_dead_leaves(enode, mt, slots);
        if (free)
                mt_free_bulk(node->slot_len, slots);
 
-start_slots_free:
-       mas_unlock(&mas);
-
 free_leaf:
        if (free)
                mt_free_rcu(&node->rcu);
+       else
+               mt_clear_meta(mt, node, node->type);
 }
 
 /*
@@ -5607,10 +5682,10 @@ static inline void mte_destroy_walk(struct maple_enode *enode,
        struct maple_node *node = mte_to_node(enode);
 
        if (mt_in_rcu(mt)) {
-               mt_destroy_walk(enode, mt->ma_flags, false);
+               mt_destroy_walk(enode, mt, false);
                call_rcu(&node->rcu, mt_free_walk);
        } else {
-               mt_destroy_walk(enode, mt->ma_flags, true);
+               mt_destroy_walk(enode, mt, true);
        }
 }
 
@@ -6631,11 +6706,11 @@ static inline void *mas_first_entry(struct ma_state *mas, struct maple_node *mn,
        while (likely(!ma_is_leaf(mt))) {
                MT_BUG_ON(mas->tree, mte_dead_node(mas->node));
                slots = ma_slots(mn, mt);
-               pivots = ma_pivots(mn, mt);
-               max = pivots[0];
                entry = mas_slot(mas, slots, 0);
+               pivots = ma_pivots(mn, mt);
                if (unlikely(ma_dead_node(mn)))
                        return NULL;
+               max = pivots[0];
                mas->node = entry;
                mn = mas_mn(mas);
                mt = mte_node_type(mas->node);
@@ -6655,13 +6730,13 @@ static inline void *mas_first_entry(struct ma_state *mas, struct maple_node *mn,
        if (likely(entry))
                return entry;
 
-       pivots = ma_pivots(mn, mt);
-       mas->index = pivots[0] + 1;
        mas->offset = 1;
        entry = mas_slot(mas, slots, 1);
+       pivots = ma_pivots(mn, mt);
        if (unlikely(ma_dead_node(mn)))
                return NULL;
 
+       mas->index = pivots[0] + 1;
        if (mas->index > limit)
                goto none;
 
index dba56c5c1837912132b5e01bd66eba8a8e3a01fa..5004463c4f9f1243674ca77c2aea8e7050edfbda 100644 (file)
@@ -122,8 +122,19 @@ void percpu_counter_sync(struct percpu_counter *fbc)
 }
 EXPORT_SYMBOL(percpu_counter_sync);
 
-static s64 __percpu_counter_sum_mask(struct percpu_counter *fbc,
-                             const struct cpumask *cpu_mask)
+/*
+ * Add up all the per-cpu counts, return the result.  This is a more accurate
+ * but much slower version of percpu_counter_read_positive().
+ *
+ * We use the cpu mask of (cpu_online_mask | cpu_dying_mask) to capture sums
+ * from CPUs that are in the process of being taken offline. Dying cpus have
+ * been removed from the online mask, but may not have had the hotplug dead
+ * notifier called to fold the percpu count back into the global counter sum.
+ * By including dying CPUs in the iteration mask, we avoid this race condition
+ * so __percpu_counter_sum() just does the right thing when CPUs are being taken
+ * offline.
+ */
+s64 __percpu_counter_sum(struct percpu_counter *fbc)
 {
        s64 ret;
        int cpu;
@@ -131,35 +142,15 @@ static s64 __percpu_counter_sum_mask(struct percpu_counter *fbc,
 
        raw_spin_lock_irqsave(&fbc->lock, flags);
        ret = fbc->count;
-       for_each_cpu(cpu, cpu_mask) {
+       for_each_cpu_or(cpu, cpu_online_mask, cpu_dying_mask) {
                s32 *pcount = per_cpu_ptr(fbc->counters, cpu);
                ret += *pcount;
        }
        raw_spin_unlock_irqrestore(&fbc->lock, flags);
        return ret;
 }
-
-/*
- * Add up all the per-cpu counts, return the result.  This is a more accurate
- * but much slower version of percpu_counter_read_positive()
- */
-s64 __percpu_counter_sum(struct percpu_counter *fbc)
-{
-       return __percpu_counter_sum_mask(fbc, cpu_online_mask);
-}
 EXPORT_SYMBOL(__percpu_counter_sum);
 
-/*
- * This is slower version of percpu_counter_sum as it traverses all possible
- * cpus. Use this only in the cases where accurate data is needed in the
- * presense of CPUs getting offlined.
- */
-s64 percpu_counter_sum_all(struct percpu_counter *fbc)
-{
-       return __percpu_counter_sum_mask(fbc, cpu_possible_mask);
-}
-EXPORT_SYMBOL(percpu_counter_sum_all);
-
 int __percpu_counter_init(struct percpu_counter *fbc, s64 amount, gfp_t gfp,
                          struct lock_class_key *key)
 {
index 3d19b1f78d7189a8a0a63241f765bbec12729d93..f1db333270e9fa4f2743a1e4c72420358eea5831 100644 (file)
@@ -2670,6 +2670,49 @@ static noinline void check_empty_area_window(struct maple_tree *mt)
        rcu_read_unlock();
 }
 
+static noinline void check_empty_area_fill(struct maple_tree *mt)
+{
+       const unsigned long max = 0x25D78000;
+       unsigned long size;
+       int loop, shift;
+       MA_STATE(mas, mt, 0, 0);
+
+       mt_set_non_kernel(99999);
+       for (shift = 12; shift <= 16; shift++) {
+               loop = 5000;
+               size = 1 << shift;
+               while (loop--) {
+                       mas_set(&mas, 0);
+                       mas_lock(&mas);
+                       MT_BUG_ON(mt, mas_empty_area(&mas, 0, max, size) != 0);
+                       MT_BUG_ON(mt, mas.last != mas.index + size - 1);
+                       mas_store_gfp(&mas, (void *)size, GFP_KERNEL);
+                       mas_unlock(&mas);
+                       mas_reset(&mas);
+               }
+       }
+
+       /* No space left. */
+       size = 0x1000;
+       rcu_read_lock();
+       MT_BUG_ON(mt, mas_empty_area(&mas, 0, max, size) != -EBUSY);
+       rcu_read_unlock();
+
+       /* Fill a depth 3 node to the maximum */
+       for (unsigned long i = 629440511; i <= 629440800; i += 6)
+               mtree_store_range(mt, i, i + 5, (void *)i, GFP_KERNEL);
+       /* Make space in the second-last depth 4 node */
+       mtree_erase(mt, 631668735);
+       /* Make space in the last depth 4 node */
+       mtree_erase(mt, 629506047);
+       mas_reset(&mas);
+       /* Search from just after the gap in the second-last depth 4 */
+       rcu_read_lock();
+       MT_BUG_ON(mt, mas_empty_area(&mas, 629506048, 690000000, 0x5000) != 0);
+       rcu_read_unlock();
+       mt_set_non_kernel(0);
+}
+
 static DEFINE_MTREE(tree);
 static int maple_tree_seed(void)
 {
@@ -2926,6 +2969,11 @@ static int maple_tree_seed(void)
        check_empty_area_window(&tree);
        mtree_destroy(&tree);
 
+       mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
+       check_empty_area_fill(&tree);
+       mtree_destroy(&tree);
+
+
 #if defined(BENCH)
 skip:
 #endif
index de4ee0d50906215e9469b29229594251a9995dcf..cd2bdba6d3edbcd44aeaa1995a96afd1e0646a8a 100644 (file)
@@ -334,7 +334,7 @@ kvfree_rcu_1_arg_vmalloc_test(void)
                        return -1;
 
                p->array[0] = 'a';
-               kvfree_rcu(p);
+               kvfree_rcu_mightsleep(p);
        }
 
        return 0;
index 7a5bf44839c9ce0d633362451dc875c7679f5ba9..f06df065dec01126c07a225e009981b809caf2b2 100644 (file)
@@ -84,7 +84,7 @@ static uint64_t ZSTD_div64(uint64_t dividend, uint32_t divisor) {
 
 #include <linux/kernel.h>
 
-#define assert(x) WARN_ON((x))
+#define assert(x) WARN_ON(!(x))
 
 #endif /* ZSTD_DEPS_ASSERT */
 #endif /* ZSTD_DEPS_NEED_ASSERT */
index 89b269a641c7e03aeb8f54892e6c401f04ed91a0..60958afebc41506928bcc75199af86226c786443 100644 (file)
@@ -985,7 +985,7 @@ static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 targetLog, const U32
 
 static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog,
                            const sortedSymbol_t* sortedList,
-                           const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,
+                           const U32* rankStart, rankValCol_t *rankValOrigin, const U32 maxWeight,
                            const U32 nbBitsBaseline)
 {
     U32* const rankVal = rankValOrigin[0];
index b9b935a9f5c0da9c6c3c5d3fc8d38fccd4fcc6ce..6b3177c947114a74723d2cd905e959fc3299237e 100644 (file)
@@ -798,7 +798,7 @@ static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity,
         if (srcSize == 0) return 0;
         RETURN_ERROR(dstBuffer_null, "");
     }
-    ZSTD_memcpy(dst, src, srcSize);
+    ZSTD_memmove(dst, src, srcSize);
     return srcSize;
 }
 
@@ -858,6 +858,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
 
     /* Loop on each block */
     while (1) {
+        BYTE* oBlockEnd = oend;
         size_t decodedSize;
         blockProperties_t blockProperties;
         size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSrcSize, &blockProperties);
@@ -867,16 +868,34 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
         remainingSrcSize -= ZSTD_blockHeaderSize;
         RETURN_ERROR_IF(cBlockSize > remainingSrcSize, srcSize_wrong, "");
 
+        if (ip >= op && ip < oBlockEnd) {
+            /* We are decompressing in-place. Limit the output pointer so that we
+             * don't overwrite the block that we are currently reading. This will
+             * fail decompression if the input & output pointers aren't spaced
+             * far enough apart.
+             *
+             * This is important to set, even when the pointers are far enough
+             * apart, because ZSTD_decompressBlock_internal() can decide to store
+             * literals in the output buffer, after the block it is decompressing.
+             * Since we don't want anything to overwrite our input, we have to tell
+             * ZSTD_decompressBlock_internal to never write past ip.
+             *
+             * See ZSTD_allocateLiteralsBuffer() for reference.
+             */
+            oBlockEnd = op + (ip - op);
+        }
+
         switch(blockProperties.blockType)
         {
         case bt_compressed:
-            decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oend-op), ip, cBlockSize, /* frame */ 1, not_streaming);
+            decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oBlockEnd-op), ip, cBlockSize, /* frame */ 1, not_streaming);
             break;
         case bt_raw :
+            /* Use oend instead of oBlockEnd because this function is safe to overlap. It uses memmove. */
             decodedSize = ZSTD_copyRawBlock(op, (size_t)(oend-op), ip, cBlockSize);
             break;
         case bt_rle :
-            decodedSize = ZSTD_setRleBlock(op, (size_t)(oend-op), *ip, blockProperties.origSize);
+            decodedSize = ZSTD_setRleBlock(op, (size_t)(oBlockEnd-op), *ip, blockProperties.origSize);
             break;
         case bt_reserved :
         default:
index 4751031f3f052238f44b0eb9a4fc8eb610ae7878..ebfe5796adf83fac91c09b1920adcaa796304d8b 100644 (file)
@@ -686,7 +686,6 @@ config BOUNCE
 
 config MMU_NOTIFIER
        bool
-       select SRCU
        select INTERVAL_TREE
 
 config KSM
index a53b9360b72ec8cf3bfd8af86486a56de1b6be5a..30d2d0386fdb914a5f5a42ba302ad7157eb7a9ca 100644 (file)
@@ -507,6 +507,15 @@ static LIST_HEAD(offline_cgwbs);
 static void cleanup_offline_cgwbs_workfn(struct work_struct *work);
 static DECLARE_WORK(cleanup_offline_cgwbs_work, cleanup_offline_cgwbs_workfn);
 
+static void cgwb_free_rcu(struct rcu_head *rcu_head)
+{
+       struct bdi_writeback *wb = container_of(rcu_head,
+                       struct bdi_writeback, rcu);
+
+       percpu_ref_exit(&wb->refcnt);
+       kfree(wb);
+}
+
 static void cgwb_release_workfn(struct work_struct *work)
 {
        struct bdi_writeback *wb = container_of(work, struct bdi_writeback,
@@ -529,11 +538,10 @@ static void cgwb_release_workfn(struct work_struct *work)
        list_del(&wb->offline_node);
        spin_unlock_irq(&cgwb_lock);
 
-       percpu_ref_exit(&wb->refcnt);
        wb_exit(wb);
        bdi_put(bdi);
        WARN_ON_ONCE(!list_empty(&wb->b_attached));
-       kfree_rcu(wb, rcu);
+       call_rcu(&wb->rcu, cgwb_free_rcu);
 }
 
 static void cgwb_release(struct percpu_ref *refcnt)
index 6c655d9b5639106722baed45b3f27fae1ca20664..dd9c33fbe805273f32fbc518356d722bacf4e09b 100644 (file)
@@ -130,7 +130,6 @@ static bool damon_pa_young(unsigned long paddr, unsigned long *folio_sz)
                        accessed = false;
                else
                        accessed = true;
-               folio_put(folio);
                goto out;
        }
 
@@ -144,10 +143,10 @@ static bool damon_pa_young(unsigned long paddr, unsigned long *folio_sz)
 
        if (need_lock)
                folio_unlock(folio);
-       folio_put(folio);
 
 out:
        *folio_sz = folio_size(folio);
+       folio_put(folio);
        return accessed;
 }
 
@@ -281,8 +280,8 @@ static inline unsigned long damon_pa_mark_accessed_or_deactivate(
                        folio_mark_accessed(folio);
                else
                        folio_deactivate(folio);
-               folio_put(folio);
                applied += folio_nr_pages(folio);
+               folio_put(folio);
        }
        return applied * PAGE_SIZE;
 }
index 4fc43859e59a31932a657cd2fac2b511c00e812b..3fae2d2496ab5d9929ed5d6a862fcd7737e45f8f 100644 (file)
@@ -1838,10 +1838,10 @@ int change_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
        if (is_swap_pmd(*pmd)) {
                swp_entry_t entry = pmd_to_swp_entry(*pmd);
                struct page *page = pfn_swap_entry_to_page(entry);
+               pmd_t newpmd;
 
                VM_BUG_ON(!is_pmd_migration_entry(*pmd));
                if (is_writable_migration_entry(entry)) {
-                       pmd_t newpmd;
                        /*
                         * A protection check is difficult so
                         * just be safe and disable write
@@ -1855,8 +1855,16 @@ int change_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
                                newpmd = pmd_swp_mksoft_dirty(newpmd);
                        if (pmd_swp_uffd_wp(*pmd))
                                newpmd = pmd_swp_mkuffd_wp(newpmd);
-                       set_pmd_at(mm, addr, pmd, newpmd);
+               } else {
+                       newpmd = *pmd;
                }
+
+               if (uffd_wp)
+                       newpmd = pmd_swp_mkuffd_wp(newpmd);
+               else if (uffd_wp_resolve)
+                       newpmd = pmd_swp_clear_uffd_wp(newpmd);
+               if (!pmd_same(*pmd, newpmd))
+                       set_pmd_at(mm, addr, pmd, newpmd);
                goto unlock;
        }
 #endif
@@ -2037,7 +2045,7 @@ static void __split_huge_zero_page_pmd(struct vm_area_struct *vma,
 {
        struct mm_struct *mm = vma->vm_mm;
        pgtable_t pgtable;
-       pmd_t _pmd;
+       pmd_t _pmd, old_pmd;
        int i;
 
        /*
@@ -2048,7 +2056,7 @@ static void __split_huge_zero_page_pmd(struct vm_area_struct *vma,
         *
         * See Documentation/mm/mmu_notifier.rst
         */
-       pmdp_huge_clear_flush(vma, haddr, pmd);
+       old_pmd = pmdp_huge_clear_flush(vma, haddr, pmd);
 
        pgtable = pgtable_trans_huge_withdraw(mm, pmd);
        pmd_populate(mm, &_pmd, pgtable);
@@ -2057,6 +2065,8 @@ static void __split_huge_zero_page_pmd(struct vm_area_struct *vma,
                pte_t *pte, entry;
                entry = pfn_pte(my_zero_pfn(haddr), vma->vm_page_prot);
                entry = pte_mkspecial(entry);
+               if (pmd_uffd_wp(old_pmd))
+                       entry = pte_mkuffd_wp(entry);
                pte = pte_offset_map(&_pmd, haddr);
                VM_BUG_ON(!pte_none(*pte));
                set_pte_at(mm, haddr, pte, entry);
@@ -2655,9 +2665,10 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)
        VM_BUG_ON_FOLIO(!folio_test_large(folio), folio);
 
        is_hzp = is_huge_zero_page(&folio->page);
-       VM_WARN_ON_ONCE_FOLIO(is_hzp, folio);
-       if (is_hzp)
+       if (is_hzp) {
+               pr_warn_ratelimited("Called split_huge_page for huge zero page\n");
                return -EBUSY;
+       }
 
        if (folio_test_writeback(folio))
                return -EBUSY;
@@ -3249,6 +3260,8 @@ int set_pmd_migration_entry(struct page_vma_mapped_walk *pvmw,
        pmdswp = swp_entry_to_pmd(entry);
        if (pmd_soft_dirty(pmdval))
                pmdswp = pmd_swp_mksoft_dirty(pmdswp);
+       if (pmd_uffd_wp(pmdval))
+               pmdswp = pmd_swp_mkuffd_wp(pmdswp);
        set_pmd_at(mm, address, pvmw->pmd, pmdswp);
        page_remove_rmap(page, vma, true);
        put_page(page);
index 07abcb6eb203044e39ed9cb839023774c53f3a8a..245038a9fe4eaa27e51ad83ba0abf4cb2c403deb 100644 (file)
@@ -5478,7 +5478,7 @@ static vm_fault_t hugetlb_wp(struct mm_struct *mm, struct vm_area_struct *vma,
                       struct folio *pagecache_folio, spinlock_t *ptl)
 {
        const bool unshare = flags & FAULT_FLAG_UNSHARE;
-       pte_t pte;
+       pte_t pte = huge_ptep_get(ptep);
        struct hstate *h = hstate_vma(vma);
        struct page *old_page;
        struct folio *new_folio;
@@ -5487,6 +5487,17 @@ static vm_fault_t hugetlb_wp(struct mm_struct *mm, struct vm_area_struct *vma,
        unsigned long haddr = address & huge_page_mask(h);
        struct mmu_notifier_range range;
 
+       /*
+        * Never handle CoW for uffd-wp protected pages.  It should be only
+        * handled when the uffd-wp protection is removed.
+        *
+        * Note that only the CoW optimization path (in hugetlb_no_page())
+        * can trigger this, because hugetlb_fault() will always resolve
+        * uffd-wp bit first.
+        */
+       if (!unshare && huge_pte_uffd_wp(pte))
+               return 0;
+
        /*
         * hugetlb does not support FOLL_FORCE-style write faults that keep the
         * PTE mapped R/O such as maybe_mkwrite() would do.
@@ -5500,7 +5511,6 @@ static vm_fault_t hugetlb_wp(struct mm_struct *mm, struct vm_area_struct *vma,
                return 0;
        }
 
-       pte = huge_ptep_get(ptep);
        old_page = pte_page(pte);
 
        delayacct_wpcopy_start();
index 0bb95728a7845ff2210ede9c712743cee8dc6347..2de2a58d11a101d328fbb73862bd5bcaf27a1463 100644 (file)
@@ -2,5 +2,5 @@
 
 obj-y := core.o report.o
 
-CFLAGS_kfence_test.o := -g -fno-omit-frame-pointer -fno-optimize-sibling-calls
+CFLAGS_kfence_test.o := -fno-omit-frame-pointer -fno-optimize-sibling-calls
 obj-$(CONFIG_KFENCE_KUNIT_TEST) += kfence_test.o
index 5349c37a5dac9fc83f9a1eec0f12a9f6c6ab4b48..1065e0568d05a350641b4cbb6fce7ef7c808203b 100644 (file)
@@ -556,15 +556,11 @@ static unsigned long kfence_init_pool(void)
         * enters __slab_free() slow-path.
         */
        for (i = 0; i < KFENCE_POOL_SIZE / PAGE_SIZE; i++) {
-               struct slab *slab = page_slab(&pages[i]);
+               struct slab *slab = page_slab(nth_page(pages, i));
 
                if (!i || (i % 2))
                        continue;
 
-               /* Verify we do not have a compound head page. */
-               if (WARN_ON(compound_head(&pages[i]) != &pages[i]))
-                       return addr;
-
                __folio_set_slab(slab_folio(slab));
 #ifdef CONFIG_MEMCG
                slab->memcg_data = (unsigned long)&kfence_metadata[i / 2 - 1].objcg |
@@ -597,12 +593,26 @@ static unsigned long kfence_init_pool(void)
 
                /* Protect the right redzone. */
                if (unlikely(!kfence_protect(addr + PAGE_SIZE)))
-                       return addr;
+                       goto reset_slab;
 
                addr += 2 * PAGE_SIZE;
        }
 
        return 0;
+
+reset_slab:
+       for (i = 0; i < KFENCE_POOL_SIZE / PAGE_SIZE; i++) {
+               struct slab *slab = page_slab(nth_page(pages, i));
+
+               if (!i || (i % 2))
+                       continue;
+#ifdef CONFIG_MEMCG
+               slab->memcg_data = 0;
+#endif
+               __folio_clear_slab(slab_folio(slab));
+       }
+
+       return addr;
 }
 
 static bool __init kfence_init_pool_early(void)
@@ -632,16 +642,6 @@ static bool __init kfence_init_pool_early(void)
         * fails for the first page, and therefore expect addr==__kfence_pool in
         * most failure cases.
         */
-       for (char *p = (char *)addr; p < __kfence_pool + KFENCE_POOL_SIZE; p += PAGE_SIZE) {
-               struct slab *slab = virt_to_slab(p);
-
-               if (!slab)
-                       continue;
-#ifdef CONFIG_MEMCG
-               slab->memcg_data = 0;
-#endif
-               __folio_clear_slab(slab_folio(slab));
-       }
        memblock_free_late(__pa(addr), KFENCE_POOL_SIZE - (addr - (unsigned long)__kfence_pool));
        __kfence_pool = NULL;
        return false;
@@ -726,10 +726,14 @@ static const struct seq_operations objects_sops = {
 };
 DEFINE_SEQ_ATTRIBUTE(objects);
 
-static int __init kfence_debugfs_init(void)
+static int kfence_debugfs_init(void)
 {
-       struct dentry *kfence_dir = debugfs_create_dir("kfence", NULL);
+       struct dentry *kfence_dir;
+
+       if (!READ_ONCE(kfence_enabled))
+               return 0;
 
+       kfence_dir = debugfs_create_dir("kfence", NULL);
        debugfs_create_file("stats", 0444, kfence_dir, NULL, &stats_fops);
        debugfs_create_file("objects", 0400, kfence_dir, NULL, &objects_fops);
        return 0;
@@ -883,6 +887,8 @@ static int kfence_init_late(void)
        }
 
        kfence_init_enable();
+       kfence_debugfs_init();
+
        return 0;
 }
 
index 92e6f56a932da3b5ca401f62a5e956f1a7d230db..0ec69b96b497bb11db2563d70adf1604a0cfa7a9 100644 (file)
@@ -572,6 +572,10 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
                        result = SCAN_PTE_NON_PRESENT;
                        goto out;
                }
+               if (pte_uffd_wp(pteval)) {
+                       result = SCAN_PTE_UFFD_WP;
+                       goto out;
+               }
                page = vm_normal_page(vma, address, pteval);
                if (unlikely(!page) || unlikely(is_zone_device_page(page))) {
                        result = SCAN_PAGE_NULL;
index 3807502766a3e3baa639400db8e4f69224f3941e..ec0da72e65aa09a2ddd525c6cbf2f39597352699 100644 (file)
@@ -148,35 +148,74 @@ void kmsan_vunmap_range_noflush(unsigned long start, unsigned long end)
  * into the virtual memory. If those physical pages already had shadow/origin,
  * those are ignored.
  */
-void kmsan_ioremap_page_range(unsigned long start, unsigned long end,
-                             phys_addr_t phys_addr, pgprot_t prot,
-                             unsigned int page_shift)
+int kmsan_ioremap_page_range(unsigned long start, unsigned long end,
+                            phys_addr_t phys_addr, pgprot_t prot,
+                            unsigned int page_shift)
 {
        gfp_t gfp_mask = GFP_KERNEL | __GFP_ZERO;
        struct page *shadow, *origin;
        unsigned long off = 0;
-       int nr;
+       int nr, err = 0, clean = 0, mapped;
 
        if (!kmsan_enabled || kmsan_in_runtime())
-               return;
+               return 0;
 
        nr = (end - start) / PAGE_SIZE;
        kmsan_enter_runtime();
-       for (int i = 0; i < nr; i++, off += PAGE_SIZE) {
+       for (int i = 0; i < nr; i++, off += PAGE_SIZE, clean = i) {
                shadow = alloc_pages(gfp_mask, 1);
                origin = alloc_pages(gfp_mask, 1);
-               __vmap_pages_range_noflush(
+               if (!shadow || !origin) {
+                       err = -ENOMEM;
+                       goto ret;
+               }
+               mapped = __vmap_pages_range_noflush(
                        vmalloc_shadow(start + off),
                        vmalloc_shadow(start + off + PAGE_SIZE), prot, &shadow,
                        PAGE_SHIFT);
-               __vmap_pages_range_noflush(
+               if (mapped) {
+                       err = mapped;
+                       goto ret;
+               }
+               shadow = NULL;
+               mapped = __vmap_pages_range_noflush(
                        vmalloc_origin(start + off),
                        vmalloc_origin(start + off + PAGE_SIZE), prot, &origin,
                        PAGE_SHIFT);
+               if (mapped) {
+                       __vunmap_range_noflush(
+                               vmalloc_shadow(start + off),
+                               vmalloc_shadow(start + off + PAGE_SIZE));
+                       err = mapped;
+                       goto ret;
+               }
+               origin = NULL;
+       }
+       /* Page mapping loop finished normally, nothing to clean up. */
+       clean = 0;
+
+ret:
+       if (clean > 0) {
+               /*
+                * Something went wrong. Clean up shadow/origin pages allocated
+                * on the last loop iteration, then delete mappings created
+                * during the previous iterations.
+                */
+               if (shadow)
+                       __free_pages(shadow, 1);
+               if (origin)
+                       __free_pages(origin, 1);
+               __vunmap_range_noflush(
+                       vmalloc_shadow(start),
+                       vmalloc_shadow(start + clean * PAGE_SIZE));
+               __vunmap_range_noflush(
+                       vmalloc_origin(start),
+                       vmalloc_origin(start + clean * PAGE_SIZE));
        }
        flush_cache_vmap(vmalloc_shadow(start), vmalloc_shadow(end));
        flush_cache_vmap(vmalloc_origin(start), vmalloc_origin(end));
        kmsan_leave_runtime();
+       return err;
 }
 
 void kmsan_iounmap_page_range(unsigned long start, unsigned long end)
index a787c04e9583cfad45814d92d9ea8a644f6b5e25..b8bb95eea5e3de243423f122a486648b4e1a225a 100644 (file)
@@ -216,27 +216,29 @@ void kmsan_free_page(struct page *page, unsigned int order)
        kmsan_leave_runtime();
 }
 
-void kmsan_vmap_pages_range_noflush(unsigned long start, unsigned long end,
-                                   pgprot_t prot, struct page **pages,
-                                   unsigned int page_shift)
+int kmsan_vmap_pages_range_noflush(unsigned long start, unsigned long end,
+                                  pgprot_t prot, struct page **pages,
+                                  unsigned int page_shift)
 {
        unsigned long shadow_start, origin_start, shadow_end, origin_end;
        struct page **s_pages, **o_pages;
-       int nr, mapped;
+       int nr, mapped, err = 0;
 
        if (!kmsan_enabled)
-               return;
+               return 0;
 
        shadow_start = vmalloc_meta((void *)start, KMSAN_META_SHADOW);
        shadow_end = vmalloc_meta((void *)end, KMSAN_META_SHADOW);
        if (!shadow_start)
-               return;
+               return 0;
 
        nr = (end - start) / PAGE_SIZE;
        s_pages = kcalloc(nr, sizeof(*s_pages), GFP_KERNEL);
        o_pages = kcalloc(nr, sizeof(*o_pages), GFP_KERNEL);
-       if (!s_pages || !o_pages)
+       if (!s_pages || !o_pages) {
+               err = -ENOMEM;
                goto ret;
+       }
        for (int i = 0; i < nr; i++) {
                s_pages[i] = shadow_page_for(pages[i]);
                o_pages[i] = origin_page_for(pages[i]);
@@ -249,10 +251,16 @@ void kmsan_vmap_pages_range_noflush(unsigned long start, unsigned long end,
        kmsan_enter_runtime();
        mapped = __vmap_pages_range_noflush(shadow_start, shadow_end, prot,
                                            s_pages, page_shift);
-       KMSAN_WARN_ON(mapped);
+       if (mapped) {
+               err = mapped;
+               goto ret;
+       }
        mapped = __vmap_pages_range_noflush(origin_start, origin_end, prot,
                                            o_pages, page_shift);
-       KMSAN_WARN_ON(mapped);
+       if (mapped) {
+               err = mapped;
+               goto ret;
+       }
        kmsan_leave_runtime();
        flush_tlb_kernel_range(shadow_start, shadow_end);
        flush_tlb_kernel_range(origin_start, origin_end);
@@ -262,6 +270,7 @@ void kmsan_vmap_pages_range_noflush(unsigned long start, unsigned long end,
 ret:
        kfree(s_pages);
        kfree(o_pages);
+       return err;
 }
 
 /* Allocate metadata for pages allocated at boot time. */
index ad591b779d534127a0ccde6781db77ee32cee0dc..2b8d30068cbbd702862a91bd3ce9cfcecfce01e2 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -988,9 +988,15 @@ static int unmerge_and_remove_all_rmap_items(void)
 
                mm = mm_slot->slot.mm;
                mmap_read_lock(mm);
+
+               /*
+                * Exit right away if mm is exiting to avoid lockdep issue in
+                * the maple tree
+                */
+               if (ksm_test_exit(mm))
+                       goto mm_exiting;
+
                for_each_vma(vmi, vma) {
-                       if (ksm_test_exit(mm))
-                               break;
                        if (!(vma->vm_flags & VM_MERGEABLE) || !vma->anon_vma)
                                continue;
                        err = unmerge_ksm_pages(vma,
@@ -999,6 +1005,7 @@ static int unmerge_and_remove_all_rmap_items(void)
                                goto error;
                }
 
+mm_exiting:
                remove_trailing_rmap_items(&mm_slot->rmap_list);
                mmap_read_unlock(mm);
 
index 340125d08c03d9638cc5a47a19f6179039ef2b6c..9f389c5304d24f6cb27483d19853028b5f46e1e3 100644 (file)
@@ -1456,7 +1456,7 @@ SYSCALL_DEFINE5(process_madvise, int, pidfd, const struct iovec __user *, vec,
                size_t, vlen, int, behavior, unsigned int, flags)
 {
        ssize_t ret;
-       struct iovec iovstack[UIO_FASTIOV], iovec;
+       struct iovec iovstack[UIO_FASTIOV];
        struct iovec *iov = iovstack;
        struct iov_iter iter;
        struct task_struct *task;
@@ -1503,12 +1503,11 @@ SYSCALL_DEFINE5(process_madvise, int, pidfd, const struct iovec __user *, vec,
        total_len = iov_iter_count(&iter);
 
        while (iov_iter_count(&iter)) {
-               iovec = iov_iter_iovec(&iter);
-               ret = do_madvise(mm, (unsigned long)iovec.iov_base,
-                                       iovec.iov_len, behavior);
+               ret = do_madvise(mm, (unsigned long)iter_iov_addr(&iter),
+                                       iter_iov_len(&iter), behavior);
                if (ret < 0)
                        break;
-               iov_iter_advance(&iter, iovec.iov_len);
+               iov_iter_advance(&iter, iter_iov_len(&iter));
        }
 
        ret = (total_len - iov_iter_count(&iter)) ? : ret;
index f456f3b5049cf1545e875436cd9138b3c2b6ead4..01a23ad48a042ddf69d0cec5cb3fb8c83b6cd2f3 100644 (file)
@@ -3563,8 +3563,21 @@ static vm_fault_t remove_device_exclusive_entry(struct vm_fault *vmf)
        struct vm_area_struct *vma = vmf->vma;
        struct mmu_notifier_range range;
 
-       if (!folio_lock_or_retry(folio, vma->vm_mm, vmf->flags))
+       /*
+        * We need a reference to lock the folio because we don't hold
+        * the PTL so a racing thread can remove the device-exclusive
+        * entry and unmap it. If the folio is free the entry must
+        * have been removed already. If it happens to have already
+        * been re-allocated after being freed all we do is lock and
+        * unlock it.
+        */
+       if (!folio_try_get(folio))
+               return 0;
+
+       if (!folio_lock_or_retry(folio, vma->vm_mm, vmf->flags)) {
+               folio_put(folio);
                return VM_FAULT_RETRY;
+       }
        mmu_notifier_range_init_owner(&range, MMU_NOTIFY_EXCLUSIVE, 0,
                                vma->vm_mm, vmf->address & PAGE_MASK,
                                (vmf->address & PAGE_MASK) + PAGE_SIZE, NULL);
@@ -3577,6 +3590,7 @@ static vm_fault_t remove_device_exclusive_entry(struct vm_fault *vmf)
 
        pte_unmap_unlock(vmf->pte, vmf->ptl);
        folio_unlock(folio);
+       folio_put(folio);
 
        mmu_notifier_invalidate_range_end(&range);
        return 0;
index a256a241fd1dae8d54abb08d866fa1000773c796..2068b594dc882fa0f0da9a4c781302e36423f980 100644 (file)
@@ -790,61 +790,50 @@ static int vma_replace_policy(struct vm_area_struct *vma,
        return err;
 }
 
-/* Step 2: apply policy to a range and do splits. */
-static int mbind_range(struct mm_struct *mm, unsigned long start,
-                      unsigned long end, struct mempolicy *new_pol)
+/* Split or merge the VMA (if required) and apply the new policy */
+static int mbind_range(struct vma_iterator *vmi, struct vm_area_struct *vma,
+               struct vm_area_struct **prev, unsigned long start,
+               unsigned long end, struct mempolicy *new_pol)
 {
-       VMA_ITERATOR(vmi, mm, start);
-       struct vm_area_struct *prev;
-       struct vm_area_struct *vma;
-       int err = 0;
+       struct vm_area_struct *merged;
+       unsigned long vmstart, vmend;
        pgoff_t pgoff;
+       int err;
 
-       prev = vma_prev(&vmi);
-       vma = vma_find(&vmi, end);
-       if (WARN_ON(!vma))
+       vmend = min(end, vma->vm_end);
+       if (start > vma->vm_start) {
+               *prev = vma;
+               vmstart = start;
+       } else {
+               vmstart = vma->vm_start;
+       }
+
+       if (mpol_equal(vma_policy(vma), new_pol))
                return 0;
 
-       if (start > vma->vm_start)
-               prev = vma;
-
-       do {
-               unsigned long vmstart = max(start, vma->vm_start);
-               unsigned long vmend = min(end, vma->vm_end);
-
-               if (mpol_equal(vma_policy(vma), new_pol))
-                       goto next;
-
-               pgoff = vma->vm_pgoff +
-                       ((vmstart - vma->vm_start) >> PAGE_SHIFT);
-               prev = vma_merge(&vmi, mm, prev, vmstart, vmend, vma->vm_flags,
-                                vma->anon_vma, vma->vm_file, pgoff,
-                                new_pol, vma->vm_userfaultfd_ctx,
-                                anon_vma_name(vma));
-               if (prev) {
-                       vma = prev;
-                       goto replace;
-               }
-               if (vma->vm_start != vmstart) {
-                       err = split_vma(&vmi, vma, vmstart, 1);
-                       if (err)
-                               goto out;
-               }
-               if (vma->vm_end != vmend) {
-                       err = split_vma(&vmi, vma, vmend, 0);
-                       if (err)
-                               goto out;
-               }
-replace:
-               err = vma_replace_policy(vma, new_pol);
+       pgoff = vma->vm_pgoff + ((vmstart - vma->vm_start) >> PAGE_SHIFT);
+       merged = vma_merge(vmi, vma->vm_mm, *prev, vmstart, vmend, vma->vm_flags,
+                        vma->anon_vma, vma->vm_file, pgoff, new_pol,
+                        vma->vm_userfaultfd_ctx, anon_vma_name(vma));
+       if (merged) {
+               *prev = merged;
+               return vma_replace_policy(merged, new_pol);
+       }
+
+       if (vma->vm_start != vmstart) {
+               err = split_vma(vmi, vma, vmstart, 1);
                if (err)
-                       goto out;
-next:
-               prev = vma;
-       } for_each_vma_range(vmi, vma, end);
+                       return err;
+       }
 
-out:
-       return err;
+       if (vma->vm_end != vmend) {
+               err = split_vma(vmi, vma, vmend, 0);
+               if (err)
+                       return err;
+       }
+
+       *prev = vma;
+       return vma_replace_policy(vma, new_pol);
 }
 
 /* Set the process memory policy */
@@ -1259,6 +1248,8 @@ static long do_mbind(unsigned long start, unsigned long len,
                     nodemask_t *nmask, unsigned long flags)
 {
        struct mm_struct *mm = current->mm;
+       struct vm_area_struct *vma, *prev;
+       struct vma_iterator vmi;
        struct mempolicy *new;
        unsigned long end;
        int err;
@@ -1328,7 +1319,13 @@ static long do_mbind(unsigned long start, unsigned long len,
                goto up_out;
        }
 
-       err = mbind_range(mm, start, end, new);
+       vma_iter_init(&vmi, mm, start);
+       prev = vma_prev(&vmi);
+       for_each_vma_range(vmi, vma, end) {
+               err = mbind_range(&vmi, vma, &prev, start, end, new);
+               if (err)
+                       break;
+       }
 
        if (!err) {
                int nr_failed = 0;
@@ -1489,10 +1486,8 @@ SYSCALL_DEFINE4(set_mempolicy_home_node, unsigned long, start, unsigned long, le
                unsigned long, home_node, unsigned long, flags)
 {
        struct mm_struct *mm = current->mm;
-       struct vm_area_struct *vma;
+       struct vm_area_struct *vma, *prev;
        struct mempolicy *new, *old;
-       unsigned long vmstart;
-       unsigned long vmend;
        unsigned long end;
        int err = -ENOENT;
        VMA_ITERATOR(vmi, mm, start);
@@ -1521,6 +1516,7 @@ SYSCALL_DEFINE4(set_mempolicy_home_node, unsigned long, start, unsigned long, le
        if (end == start)
                return 0;
        mmap_write_lock(mm);
+       prev = vma_prev(&vmi);
        for_each_vma_range(vmi, vma, end) {
                /*
                 * If any vma in the range got policy other than MPOL_BIND
@@ -1541,9 +1537,7 @@ SYSCALL_DEFINE4(set_mempolicy_home_node, unsigned long, start, unsigned long, le
                }
 
                new->home_node = home_node;
-               vmstart = max(start, vma->vm_start);
-               vmend   = min(end, vma->vm_end);
-               err = mbind_range(mm, vmstart, vmend, new);
+               err = mbind_range(&vmi, vma, &prev, start, end, new);
                mpol_put(new);
                if (err)
                        break;
index 98f1c11197a8c5f057ed23f5aea9cdc62536bed4..db3f154446af4e1210d7557bcb65eaa57cae03e8 100644 (file)
@@ -1112,9 +1112,8 @@ static void migrate_folio_done(struct folio *src,
 /* Obtain the lock on page, remove all ptes. */
 static int migrate_folio_unmap(new_page_t get_new_page, free_page_t put_new_page,
                               unsigned long private, struct folio *src,
-                              struct folio **dstp, int force, bool avoid_force_lock,
-                              enum migrate_mode mode, enum migrate_reason reason,
-                              struct list_head *ret)
+                              struct folio **dstp, enum migrate_mode mode,
+                              enum migrate_reason reason, struct list_head *ret)
 {
        struct folio *dst;
        int rc = -EAGAIN;
@@ -1144,7 +1143,7 @@ static int migrate_folio_unmap(new_page_t get_new_page, free_page_t put_new_page
        dst->private = NULL;
 
        if (!folio_trylock(src)) {
-               if (!force || mode == MIGRATE_ASYNC)
+               if (mode == MIGRATE_ASYNC)
                        goto out;
 
                /*
@@ -1163,17 +1162,6 @@ static int migrate_folio_unmap(new_page_t get_new_page, free_page_t put_new_page
                if (current->flags & PF_MEMALLOC)
                        goto out;
 
-               /*
-                * We have locked some folios and are going to wait to lock
-                * this folio.  To avoid a potential deadlock, let's bail
-                * out and not do that. The locked folios will be moved and
-                * unlocked, then we can wait to lock this folio.
-                */
-               if (avoid_force_lock) {
-                       rc = -EDEADLOCK;
-                       goto out;
-               }
-
                folio_lock(src);
        }
        locked = true;
@@ -1193,8 +1181,6 @@ static int migrate_folio_unmap(new_page_t get_new_page, free_page_t put_new_page
                        rc = -EBUSY;
                        goto out;
                }
-               if (!force)
-                       goto out;
                folio_wait_writeback(src);
        }
 
@@ -1253,7 +1239,7 @@ static int migrate_folio_unmap(new_page_t get_new_page, free_page_t put_new_page
                /* Establish migration ptes */
                VM_BUG_ON_FOLIO(folio_test_anon(src) &&
                               !folio_test_ksm(src) && !anon_vma, src);
-               try_to_migrate(src, TTU_BATCH_FLUSH);
+               try_to_migrate(src, mode == MIGRATE_ASYNC ? TTU_BATCH_FLUSH : 0);
                page_was_mapped = 1;
        }
 
@@ -1267,7 +1253,7 @@ out:
         * A folio that has not been unmapped will be restored to
         * right list unless we want to retry.
         */
-       if (rc == -EAGAIN || rc == -EDEADLOCK)
+       if (rc == -EAGAIN)
                ret = NULL;
 
        migrate_folio_undo_src(src, page_was_mapped, anon_vma, locked, ret);
@@ -1508,6 +1494,9 @@ static inline int try_split_folio(struct folio *folio, struct list_head *split_f
 #define NR_MAX_BATCHED_MIGRATION       512
 #endif
 #define NR_MAX_MIGRATE_PAGES_RETRY     10
+#define NR_MAX_MIGRATE_ASYNC_RETRY     3
+#define NR_MAX_MIGRATE_SYNC_RETRY                                      \
+       (NR_MAX_MIGRATE_PAGES_RETRY - NR_MAX_MIGRATE_ASYNC_RETRY)
 
 struct migrate_pages_stats {
        int nr_succeeded;       /* Normal and large folios migrated successfully, in
@@ -1618,13 +1607,19 @@ static int migrate_hugetlbs(struct list_head *from, new_page_t get_new_page,
 /*
  * migrate_pages_batch() first unmaps folios in the from list as many as
  * possible, then move the unmapped folios.
+ *
+ * We only batch migration if mode == MIGRATE_ASYNC to avoid to wait a
+ * lock or bit when we have locked more than one folio.  Which may cause
+ * deadlock (e.g., for loop device).  So, if mode != MIGRATE_ASYNC, the
+ * length of the from list must be <= 1.
  */
 static int migrate_pages_batch(struct list_head *from, new_page_t get_new_page,
                free_page_t put_new_page, unsigned long private,
                enum migrate_mode mode, int reason, struct list_head *ret_folios,
-               struct migrate_pages_stats *stats)
+               struct list_head *split_folios, struct migrate_pages_stats *stats,
+               int nr_pass)
 {
-       int retry;
+       int retry = 1;
        int large_retry = 1;
        int thp_retry = 1;
        int nr_failed = 0;
@@ -1634,21 +1629,15 @@ static int migrate_pages_batch(struct list_head *from, new_page_t get_new_page,
        bool is_large = false;
        bool is_thp = false;
        struct folio *folio, *folio2, *dst = NULL, *dst2;
-       int rc, rc_saved, nr_pages;
-       LIST_HEAD(split_folios);
+       int rc, rc_saved = 0, nr_pages;
        LIST_HEAD(unmap_folios);
        LIST_HEAD(dst_folios);
        bool nosplit = (reason == MR_NUMA_MISPLACED);
-       bool no_split_folio_counting = false;
-       bool avoid_force_lock;
 
-retry:
-       rc_saved = 0;
-       avoid_force_lock = false;
-       retry = 1;
-       for (pass = 0;
-            pass < NR_MAX_MIGRATE_PAGES_RETRY && (retry || large_retry);
-            pass++) {
+       VM_WARN_ON_ONCE(mode != MIGRATE_ASYNC &&
+                       !list_empty(from) && !list_is_singular(from));
+
+       for (pass = 0; pass < nr_pass && (retry || large_retry); pass++) {
                retry = 0;
                large_retry = 0;
                thp_retry = 0;
@@ -1679,7 +1668,7 @@ retry:
                        if (!thp_migration_supported() && is_thp) {
                                nr_large_failed++;
                                stats->nr_thp_failed++;
-                               if (!try_split_folio(folio, &split_folios)) {
+                               if (!try_split_folio(folio, split_folios)) {
                                        stats->nr_thp_split++;
                                        continue;
                                }
@@ -1689,15 +1678,13 @@ retry:
                        }
 
                        rc = migrate_folio_unmap(get_new_page, put_new_page, private,
-                                                folio, &dst, pass > 2, avoid_force_lock,
-                                                mode, reason, ret_folios);
+                                                folio, &dst, mode, reason, ret_folios);
                        /*
                         * The rules are:
                         *      Success: folio will be freed
                         *      Unmap: folio will be put on unmap_folios list,
                         *             dst folio put on dst_folios list
                         *      -EAGAIN: stay on the from list
-                        *      -EDEADLOCK: stay on the from list
                         *      -ENOMEM: stay on the from list
                         *      Other errno: put on ret_folios list
                         */
@@ -1712,7 +1699,7 @@ retry:
                                        stats->nr_thp_failed += is_thp;
                                        /* Large folio NUMA faulting doesn't split to retry. */
                                        if (!nosplit) {
-                                               int ret = try_split_folio(folio, &split_folios);
+                                               int ret = try_split_folio(folio, split_folios);
 
                                                if (!ret) {
                                                        stats->nr_thp_split += is_thp;
@@ -1729,18 +1716,11 @@ retry:
                                                        break;
                                                }
                                        }
-                               } else if (!no_split_folio_counting) {
+                               } else {
                                        nr_failed++;
                                }
 
                                stats->nr_failed_pages += nr_pages + nr_retry_pages;
-                               /*
-                                * There might be some split folios of fail-to-migrate large
-                                * folios left in split_folios list. Move them to ret_folios
-                                * list so that they could be put back to the right list by
-                                * the caller otherwise the folio refcnt will be leaked.
-                                */
-                               list_splice_init(&split_folios, ret_folios);
                                /* nr_failed isn't updated for not used */
                                nr_large_failed += large_retry;
                                stats->nr_thp_failed += thp_retry;
@@ -1749,19 +1729,11 @@ retry:
                                        goto out;
                                else
                                        goto move;
-                       case -EDEADLOCK:
-                               /*
-                                * The folio cannot be locked for potential deadlock.
-                                * Go move (and unlock) all locked folios.  Then we can
-                                * try again.
-                                */
-                               rc_saved = rc;
-                               goto move;
                        case -EAGAIN:
                                if (is_large) {
                                        large_retry++;
                                        thp_retry += is_thp;
-                               } else if (!no_split_folio_counting) {
+                               } else {
                                        retry++;
                                }
                                nr_retry_pages += nr_pages;
@@ -1771,11 +1743,6 @@ retry:
                                stats->nr_thp_succeeded += is_thp;
                                break;
                        case MIGRATEPAGE_UNMAP:
-                               /*
-                                * We have locked some folios, don't force lock
-                                * to avoid deadlock.
-                                */
-                               avoid_force_lock = true;
                                list_move_tail(&folio->lru, &unmap_folios);
                                list_add_tail(&dst->lru, &dst_folios);
                                break;
@@ -1789,7 +1756,7 @@ retry:
                                if (is_large) {
                                        nr_large_failed++;
                                        stats->nr_thp_failed += is_thp;
-                               } else if (!no_split_folio_counting) {
+                               } else {
                                        nr_failed++;
                                }
 
@@ -1807,9 +1774,7 @@ move:
        try_to_unmap_flush();
 
        retry = 1;
-       for (pass = 0;
-            pass < NR_MAX_MIGRATE_PAGES_RETRY && (retry || large_retry);
-            pass++) {
+       for (pass = 0; pass < nr_pass && (retry || large_retry); pass++) {
                retry = 0;
                large_retry = 0;
                thp_retry = 0;
@@ -1838,7 +1803,7 @@ move:
                                if (is_large) {
                                        large_retry++;
                                        thp_retry += is_thp;
-                               } else if (!no_split_folio_counting) {
+                               } else {
                                        retry++;
                                }
                                nr_retry_pages += nr_pages;
@@ -1851,7 +1816,7 @@ move:
                                if (is_large) {
                                        nr_large_failed++;
                                        stats->nr_thp_failed += is_thp;
-                               } else if (!no_split_folio_counting) {
+                               } else {
                                        nr_failed++;
                                }
 
@@ -1888,30 +1853,52 @@ out:
                dst2 = list_next_entry(dst, lru);
        }
 
-       /*
-        * Try to migrate split folios of fail-to-migrate large folios, no
-        * nr_failed counting in this round, since all split folios of a
-        * large folio is counted as 1 failure in the first round.
-        */
-       if (rc >= 0 && !list_empty(&split_folios)) {
-               /*
-                * Move non-migrated folios (after NR_MAX_MIGRATE_PAGES_RETRY
-                * retries) to ret_folios to avoid migrating them again.
-                */
-               list_splice_init(from, ret_folios);
-               list_splice_init(&split_folios, from);
-               no_split_folio_counting = true;
-               goto retry;
-       }
+       return rc;
+}
 
+static int migrate_pages_sync(struct list_head *from, new_page_t get_new_page,
+               free_page_t put_new_page, unsigned long private,
+               enum migrate_mode mode, int reason, struct list_head *ret_folios,
+               struct list_head *split_folios, struct migrate_pages_stats *stats)
+{
+       int rc, nr_failed = 0;
+       LIST_HEAD(folios);
+       struct migrate_pages_stats astats;
+
+       memset(&astats, 0, sizeof(astats));
+       /* Try to migrate in batch with MIGRATE_ASYNC mode firstly */
+       rc = migrate_pages_batch(from, get_new_page, put_new_page, private, MIGRATE_ASYNC,
+                                reason, &folios, split_folios, &astats,
+                                NR_MAX_MIGRATE_ASYNC_RETRY);
+       stats->nr_succeeded += astats.nr_succeeded;
+       stats->nr_thp_succeeded += astats.nr_thp_succeeded;
+       stats->nr_thp_split += astats.nr_thp_split;
+       if (rc < 0) {
+               stats->nr_failed_pages += astats.nr_failed_pages;
+               stats->nr_thp_failed += astats.nr_thp_failed;
+               list_splice_tail(&folios, ret_folios);
+               return rc;
+       }
+       stats->nr_thp_failed += astats.nr_thp_split;
+       nr_failed += astats.nr_thp_split;
        /*
-        * We have unlocked all locked folios, so we can force lock now, let's
-        * try again.
+        * Fall back to migrate all failed folios one by one synchronously. All
+        * failed folios except split THPs will be retried, so their failure
+        * isn't counted
         */
-       if (rc == -EDEADLOCK)
-               goto retry;
+       list_splice_tail_init(&folios, from);
+       while (!list_empty(from)) {
+               list_move(from->next, &folios);
+               rc = migrate_pages_batch(&folios, get_new_page, put_new_page,
+                                        private, mode, reason, ret_folios,
+                                        split_folios, stats, NR_MAX_MIGRATE_SYNC_RETRY);
+               list_splice_tail_init(&folios, ret_folios);
+               if (rc < 0)
+                       return rc;
+               nr_failed += rc;
+       }
 
-       return rc;
+       return nr_failed;
 }
 
 /*
@@ -1949,6 +1936,7 @@ int migrate_pages(struct list_head *from, new_page_t get_new_page,
        struct folio *folio, *folio2;
        LIST_HEAD(folios);
        LIST_HEAD(ret_folios);
+       LIST_HEAD(split_folios);
        struct migrate_pages_stats stats;
 
        trace_mm_migrate_pages_start(mode, reason);
@@ -1959,6 +1947,7 @@ int migrate_pages(struct list_head *from, new_page_t get_new_page,
                                     mode, reason, &stats, &ret_folios);
        if (rc_gather < 0)
                goto out;
+
 again:
        nr_pages = 0;
        list_for_each_entry_safe(folio, folio2, from, lru) {
@@ -1969,20 +1958,36 @@ again:
                }
 
                nr_pages += folio_nr_pages(folio);
-               if (nr_pages > NR_MAX_BATCHED_MIGRATION)
+               if (nr_pages >= NR_MAX_BATCHED_MIGRATION)
                        break;
        }
-       if (nr_pages > NR_MAX_BATCHED_MIGRATION)
-               list_cut_before(&folios, from, &folio->lru);
+       if (nr_pages >= NR_MAX_BATCHED_MIGRATION)
+               list_cut_before(&folios, from, &folio2->lru);
        else
                list_splice_init(from, &folios);
-       rc = migrate_pages_batch(&folios, get_new_page, put_new_page, private,
-                                mode, reason, &ret_folios, &stats);
+       if (mode == MIGRATE_ASYNC)
+               rc = migrate_pages_batch(&folios, get_new_page, put_new_page, private,
+                                        mode, reason, &ret_folios, &split_folios, &stats,
+                                        NR_MAX_MIGRATE_PAGES_RETRY);
+       else
+               rc = migrate_pages_sync(&folios, get_new_page, put_new_page, private,
+                                       mode, reason, &ret_folios, &split_folios, &stats);
        list_splice_tail_init(&folios, &ret_folios);
        if (rc < 0) {
                rc_gather = rc;
+               list_splice_tail(&split_folios, &ret_folios);
                goto out;
        }
+       if (!list_empty(&split_folios)) {
+               /*
+                * Failure isn't counted since all split folios of a large folio
+                * is counted as 1 failure already.  And, we only try to migrate
+                * with minimal effort, force MIGRATE_ASYNC mode and retry once.
+                */
+               migrate_pages_batch(&split_folios, get_new_page, put_new_page, private,
+                                   MIGRATE_ASYNC, reason, &ret_folios, NULL, &stats, 1);
+               list_splice_tail_init(&split_folios, &ret_folios);
+       }
        rc_gather += rc;
        if (!list_empty(from))
                goto again;
index cd69b9db00812655c42fdc91957d6826bd97d9d6..d359650b0f75b9c099e75ecd994a0b82ac38a9fa 100644 (file)
@@ -33,7 +33,7 @@ static int mincore_hugetlb(pte_t *pte, unsigned long hmask, unsigned long addr,
         * Hugepages under user process are always in RAM and never
         * swapped out, but theoretically it needs to be checked.
         */
-       present = pte && !huge_pte_none(huge_ptep_get(pte));
+       present = pte && !huge_pte_none_mostly(huge_ptep_get(pte));
        for (; addr != end; vec++, addr += PAGE_SIZE)
                *vec = present;
        walk->private = vec;
index 740b54be3ed4140f16a6731a275ab49f3a8b256f..d5475fbf572969dd14361e8781620b027dec6b0e 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1518,7 +1518,8 @@ static inline int accountable_mapping(struct file *file, vm_flags_t vm_flags)
  */
 static unsigned long unmapped_area(struct vm_unmapped_area_info *info)
 {
-       unsigned long length, gap;
+       unsigned long length, gap, low_limit;
+       struct vm_area_struct *tmp;
 
        MA_STATE(mas, &current->mm->mm_mt, 0, 0);
 
@@ -1527,12 +1528,29 @@ static unsigned long unmapped_area(struct vm_unmapped_area_info *info)
        if (length < info->length)
                return -ENOMEM;
 
-       if (mas_empty_area(&mas, info->low_limit, info->high_limit - 1,
-                                 length))
+       low_limit = info->low_limit;
+retry:
+       if (mas_empty_area(&mas, low_limit, info->high_limit - 1, length))
                return -ENOMEM;
 
        gap = mas.index;
        gap += (info->align_offset - gap) & info->align_mask;
+       tmp = mas_next(&mas, ULONG_MAX);
+       if (tmp && (tmp->vm_flags & VM_GROWSDOWN)) { /* Avoid prev check if possible */
+               if (vm_start_gap(tmp) < gap + length - 1) {
+                       low_limit = tmp->vm_end;
+                       mas_reset(&mas);
+                       goto retry;
+               }
+       } else {
+               tmp = mas_prev(&mas, 0);
+               if (tmp && vm_end_gap(tmp) > gap) {
+                       low_limit = vm_end_gap(tmp);
+                       mas_reset(&mas);
+                       goto retry;
+               }
+       }
+
        return gap;
 }
 
@@ -1548,7 +1566,8 @@ static unsigned long unmapped_area(struct vm_unmapped_area_info *info)
  */
 static unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info)
 {
-       unsigned long length, gap;
+       unsigned long length, gap, high_limit, gap_end;
+       struct vm_area_struct *tmp;
 
        MA_STATE(mas, &current->mm->mm_mt, 0, 0);
        /* Adjust search length to account for worst case alignment overhead */
@@ -1556,12 +1575,31 @@ static unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info)
        if (length < info->length)
                return -ENOMEM;
 
-       if (mas_empty_area_rev(&mas, info->low_limit, info->high_limit - 1,
+       high_limit = info->high_limit;
+retry:
+       if (mas_empty_area_rev(&mas, info->low_limit, high_limit - 1,
                                length))
                return -ENOMEM;
 
        gap = mas.last + 1 - info->length;
        gap -= (gap - info->align_offset) & info->align_mask;
+       gap_end = mas.last;
+       tmp = mas_next(&mas, ULONG_MAX);
+       if (tmp && (tmp->vm_flags & VM_GROWSDOWN)) { /* Avoid prev check if possible */
+               if (vm_start_gap(tmp) <= gap_end) {
+                       high_limit = vm_start_gap(tmp);
+                       mas_reset(&mas);
+                       goto retry;
+               }
+       } else {
+               tmp = mas_prev(&mas, 0);
+               if (tmp && vm_end_gap(tmp) > gap) {
+                       high_limit = tmp->vm_start;
+                       mas_reset(&mas);
+                       goto retry;
+               }
+       }
+
        return gap;
 }
 
@@ -2277,7 +2315,7 @@ do_vmi_align_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma,
        int count = 0;
        int error = -ENOMEM;
        MA_STATE(mas_detach, &mt_detach, 0, 0);
-       mt_init_flags(&mt_detach, MT_FLAGS_LOCK_EXTERN);
+       mt_init_flags(&mt_detach, vmi->mas.tree->ma_flags & MT_FLAGS_LOCK_MASK);
        mt_set_external_lock(&mt_detach, &mm->mmap_lock);
 
        /*
@@ -2621,12 +2659,7 @@ cannot_expand:
 
        if (map_deny_write_exec(vma, vma->vm_flags)) {
                error = -EACCES;
-               if (file)
-                       goto close_and_free_vma;
-               else if (vma->vm_file)
-                       goto unmap_and_free_vma;
-               else
-                       goto free_vma;
+               goto close_and_free_vma;
        }
 
        /* Allow architectures to sanity-check the vm_flags */
@@ -3042,6 +3075,7 @@ void exit_mmap(struct mm_struct *mm)
         */
        set_bit(MMF_OOM_SKIP, &mm->flags);
        mmap_write_lock(mm);
+       mt_clear_in_rcu(&mm->mm_mt);
        free_pgtables(&tlb, &mm->mm_mt, vma, FIRST_USER_ADDRESS,
                      USER_PGTABLES_CEILING);
        tlb_finish_mmu(&tlb);
index 231929f119d958f73aba0680b6ed8bae8493b35d..36351a00c0e82de1508575f152b816c4d40cf66c 100644 (file)
@@ -805,7 +805,7 @@ static int do_mprotect_pkey(unsigned long start, size_t len,
 
                if (map_deny_write_exec(vma, newflags)) {
                        error = -EACCES;
-                       goto out;
+                       break;
                }
 
                /* Allow architectures to sanity-check the new flags */
@@ -838,7 +838,7 @@ static int do_mprotect_pkey(unsigned long start, size_t len,
        }
        tlb_finish_mmu(&tlb);
 
-       if (vma_iter_end(&vmi) < end)
+       if (!error && vma_iter_end(&vmi) < end)
                error = -ENOMEM;
 
 out:
index 516b1aa247e83fd4564dfcea0f8892c8481a1dab..db7943999007346c279bb79185efba4b4384a6bb 100644 (file)
@@ -2583,46 +2583,6 @@ int do_writepages(struct address_space *mapping, struct writeback_control *wbc)
        return ret;
 }
 
-/**
- * folio_write_one - write out a single folio and wait on I/O.
- * @folio: The folio to write.
- *
- * The folio must be locked by the caller and will be unlocked upon return.
- *
- * Note that the mapping's AS_EIO/AS_ENOSPC flags will be cleared when this
- * function returns.
- *
- * Return: %0 on success, negative error code otherwise
- */
-int folio_write_one(struct folio *folio)
-{
-       struct address_space *mapping = folio->mapping;
-       int ret = 0;
-       struct writeback_control wbc = {
-               .sync_mode = WB_SYNC_ALL,
-               .nr_to_write = folio_nr_pages(folio),
-       };
-
-       BUG_ON(!folio_test_locked(folio));
-
-       folio_wait_writeback(folio);
-
-       if (folio_clear_dirty_for_io(folio)) {
-               folio_get(folio);
-               ret = mapping->a_ops->writepage(&folio->page, &wbc);
-               if (ret == 0)
-                       folio_wait_writeback(folio);
-               folio_put(folio);
-       } else {
-               folio_unlock(folio);
-       }
-
-       if (!ret)
-               ret = filemap_check_errors(mapping);
-       return ret;
-}
-EXPORT_SYMBOL(folio_write_one);
-
 /*
  * For address_spaces which do not use buffers nor write back.
  */
index ac1fc986af44c46736d4891dea771473c3bee7f1..8e39705c7bdc29f7669fae143af05100b0d93a61 100644 (file)
@@ -1398,6 +1398,7 @@ static __always_inline bool free_pages_prepare(struct page *page,
                        unsigned int order, bool check_free, fpi_t fpi_flags)
 {
        int bad = 0;
+       bool skip_kasan_poison = should_skip_kasan_poison(page, fpi_flags);
        bool init = want_init_on_free();
 
        VM_BUG_ON_PAGE(PageTail(page), page);
@@ -1470,7 +1471,7 @@ static __always_inline bool free_pages_prepare(struct page *page,
         * With hardware tag-based KASAN, memory tags must be set before the
         * page becomes unavailable via debug_pagealloc or arch_free_page.
         */
-       if (!should_skip_kasan_poison(page, fpi_flags)) {
+       if (!skip_kasan_poison) {
                kasan_poison_pages(page, order, init);
 
                /* Memory is already initialized if KASAN did it internally. */
@@ -6631,7 +6632,21 @@ static void __build_all_zonelists(void *data)
        int nid;
        int __maybe_unused cpu;
        pg_data_t *self = data;
+       unsigned long flags;
 
+       /*
+        * Explicitly disable this CPU's interrupts before taking seqlock
+        * to prevent any IRQ handler from calling into the page allocator
+        * (e.g. GFP_ATOMIC) that could hit zonelist_iter_begin and livelock.
+        */
+       local_irq_save(flags);
+       /*
+        * Explicitly disable this CPU's synchronous printk() before taking
+        * seqlock to prevent any printk() from trying to hold port->lock, for
+        * tty_insert_flip_string_and_push_buffer() on other CPU might be
+        * calling kmalloc(GFP_ATOMIC | __GFP_NOWARN) with port->lock held.
+        */
+       printk_deferred_enter();
        write_seqlock(&zonelist_update_seq);
 
 #ifdef CONFIG_NUMA
@@ -6670,6 +6685,8 @@ static void __build_all_zonelists(void *data)
        }
 
        write_sequnlock(&zonelist_update_seq);
+       printk_deferred_exit();
+       local_irq_restore(flags);
 }
 
 static noinline void __init
@@ -9449,6 +9466,9 @@ static bool pfn_range_valid_contig(struct zone *z, unsigned long start_pfn,
 
                if (PageReserved(page))
                        return false;
+
+               if (PageHuge(page))
+                       return false;
        }
        return true;
 }
index 448f393d8ab2b1bd5f22eec603195977716a8727..b76521ed372dfdfc03117b2773b39f104b9901a6 100644 (file)
@@ -3339,10 +3339,6 @@ static const struct xattr_handler shmem_trusted_xattr_handler = {
 };
 
 static const struct xattr_handler *shmem_xattr_handlers[] = {
-#ifdef CONFIG_TMPFS_POSIX_ACL
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
-#endif
        &shmem_security_xattr_handler,
        &shmem_trusted_xattr_handler,
        NULL
index dabc2a671fc6f7ffc5da481a3b7a9574500cdb0a..edbe722fb906481fc151f7038652894b85b5b5cc 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -839,7 +839,7 @@ static int init_cache_node(struct kmem_cache *cachep, int node, gfp_t gfp)
        return 0;
 }
 
-#if (defined(CONFIG_NUMA) && defined(CONFIG_MEMORY_HOTPLUG)) || defined(CONFIG_SMP)
+#if defined(CONFIG_NUMA) || defined(CONFIG_SMP)
 /*
  * Allocates and initializes node for a node on each slab cache, used for
  * either memory or cpu hotplug.  If memory is being hot-added, the kmem_cache_node
index 57cb01b042f6231b87378529fe02c84116afb968..423199ee8478c19542126c029c7dbd2f7a4db6bc 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -222,7 +222,7 @@ static void folio_batch_move_lru(struct folio_batch *fbatch, move_fn_t move_fn)
        if (lruvec)
                unlock_page_lruvec_irqrestore(lruvec, flags);
        folios_put(fbatch->folios, folio_batch_count(fbatch));
-       folio_batch_init(fbatch);
+       folio_batch_reinit(fbatch);
 }
 
 static void folio_batch_add_and_move(struct folio_batch *fbatch,
index 62ba2bf577d7e7210398181b47f11fca9e5f5099..2c718f45745f8c87fdac889fa3d255ffa58b774a 100644 (file)
@@ -679,6 +679,7 @@ static void __del_from_avail_list(struct swap_info_struct *p)
 {
        int nid;
 
+       assert_spin_locked(&p->lock);
        for_each_node(nid)
                plist_del(&p->avail_lists[nid], &swap_avail_heads[nid]);
 }
@@ -2434,8 +2435,8 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
                spin_unlock(&swap_lock);
                goto out_dput;
        }
-       del_from_avail_list(p);
        spin_lock(&p->lock);
+       del_from_avail_list(p);
        if (p->prio < 0) {
                struct swap_info_struct *si = p;
                int nid;
index ef910bf349e1361e64edc0ed0166605160a0fe52..31ff782d368b02138b4cc2606290aba862c7ebd7 100644 (file)
@@ -313,8 +313,8 @@ int ioremap_page_range(unsigned long addr, unsigned long end,
                                 ioremap_max_page_shift);
        flush_cache_vmap(addr, end);
        if (!err)
-               kmsan_ioremap_page_range(addr, end, phys_addr, prot,
-                                        ioremap_max_page_shift);
+               err = kmsan_ioremap_page_range(addr, end, phys_addr, prot,
+                                              ioremap_max_page_shift);
        return err;
 }
 
@@ -605,7 +605,11 @@ int __vmap_pages_range_noflush(unsigned long addr, unsigned long end,
 int vmap_pages_range_noflush(unsigned long addr, unsigned long end,
                pgprot_t prot, struct page **pages, unsigned int page_shift)
 {
-       kmsan_vmap_pages_range_noflush(addr, end, prot, pages, page_shift);
+       int ret = kmsan_vmap_pages_range_noflush(addr, end, prot, pages,
+                                                page_shift);
+
+       if (ret)
+               return ret;
        return __vmap_pages_range_noflush(addr, end, prot, pages, page_shift);
 }
 
@@ -2883,6 +2887,8 @@ vm_area_alloc_pages(gfp_t gfp, int nid,
                unsigned int order, unsigned int nr_pages, struct page **pages)
 {
        unsigned int nr_allocated = 0;
+       gfp_t alloc_gfp = gfp;
+       bool nofail = false;
        struct page *page;
        int i;
 
@@ -2893,6 +2899,7 @@ vm_area_alloc_pages(gfp_t gfp, int nid,
         * more permissive.
         */
        if (!order) {
+               /* bulk allocator doesn't support nofail req. officially */
                gfp_t bulk_gfp = gfp & ~__GFP_NOFAIL;
 
                while (nr_allocated < nr_pages) {
@@ -2931,20 +2938,35 @@ vm_area_alloc_pages(gfp_t gfp, int nid,
                        if (nr != nr_pages_request)
                                break;
                }
+       } else if (gfp & __GFP_NOFAIL) {
+               /*
+                * Higher order nofail allocations are really expensive and
+                * potentially dangerous (pre-mature OOM, disruptive reclaim
+                * and compaction etc.
+                */
+               alloc_gfp &= ~__GFP_NOFAIL;
+               nofail = true;
        }
 
        /* High-order pages or fallback path if "bulk" fails. */
-
        while (nr_allocated < nr_pages) {
                if (fatal_signal_pending(current))
                        break;
 
                if (nid == NUMA_NO_NODE)
-                       page = alloc_pages(gfp, order);
+                       page = alloc_pages(alloc_gfp, order);
                else
-                       page = alloc_pages_node(nid, gfp, order);
-               if (unlikely(!page))
-                       break;
+                       page = alloc_pages_node(nid, alloc_gfp, order);
+               if (unlikely(!page)) {
+                       if (!nofail)
+                               break;
+
+                       /* fall back to the zero order allocations */
+                       alloc_gfp |= __GFP_NOFAIL;
+                       order = 0;
+                       continue;
+               }
+
                /*
                 * Higher order allocations must be able to be treated as
                 * indepdenent small pages by callers (as they can with
@@ -3024,9 +3046,11 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
         * allocation request, free them via vfree() if any.
         */
        if (area->nr_pages != nr_small_pages) {
-               warn_alloc(gfp_mask, NULL,
-                       "vmalloc error: size %lu, page order %u, failed to allocate pages",
-                       area->nr_pages * PAGE_SIZE, page_order);
+               /* vm_area_alloc_pages() can also fail due to a fatal signal */
+               if (!fatal_signal_pending(current))
+                       warn_alloc(gfp_mask, NULL,
+                               "vmalloc error: size %lu, page order %u, failed to allocate pages",
+                               area->nr_pages * PAGE_SIZE, page_order);
                goto fail;
        }
 
index 9c1c5e8b24b8f56fe05d8d3883ce17ffaa2eb7f3..7ba6bfdd9a5f7bf3ef357947bb98c25b87da2c07 100644 (file)
@@ -1151,12 +1151,12 @@ void reclaim_throttle(pg_data_t *pgdat, enum vmscan_throttle_state reason)
        DEFINE_WAIT(wait);
 
        /*
-        * Do not throttle IO workers, kthreads other than kswapd or
+        * Do not throttle user workers, kthreads other than kswapd or
         * workqueues. They may be required for reclaim to make
         * forward progress (e.g. journalling workqueues or kthreads).
         */
        if (!current_is_kswapd() &&
-           current->flags & (PF_IO_WORKER|PF_KTHREAD)) {
+           current->flags & (PF_USER_WORKER|PF_KTHREAD)) {
                cond_resched();
                return;
        }
index c64050e839ac6faccd7f9741654cfa74bf661836..1fffe2bed5b02f3480b9f074d8b472016708729f 100644 (file)
@@ -280,6 +280,10 @@ static void xen_9pfs_front_free(struct xen_9pfs_front_priv *priv)
        write_unlock(&xen_9pfs_lock);
 
        for (i = 0; i < priv->num_rings; i++) {
+               struct xen_9pfs_dataring *ring = &priv->rings[i];
+
+               cancel_work_sync(&ring->work);
+
                if (!priv->rings[i].intf)
                        break;
                if (priv->rings[i].irq > 0)
index 17b946f9ba317c7c04222379f95b12e104f88a87..8455ba141ee6192cb039020e58de6c662e4d34f9 100644 (file)
@@ -68,7 +68,7 @@ static const struct sco_param esco_param_msbc[] = {
 };
 
 /* This function requires the caller holds hdev->lock */
-static void hci_connect_le_scan_cleanup(struct hci_conn *conn)
+static void hci_connect_le_scan_cleanup(struct hci_conn *conn, u8 status)
 {
        struct hci_conn_params *params;
        struct hci_dev *hdev = conn->hdev;
@@ -88,9 +88,28 @@ static void hci_connect_le_scan_cleanup(struct hci_conn *conn)
 
        params = hci_pend_le_action_lookup(&hdev->pend_le_conns, bdaddr,
                                           bdaddr_type);
-       if (!params || !params->explicit_connect)
+       if (!params)
                return;
 
+       if (params->conn) {
+               hci_conn_drop(params->conn);
+               hci_conn_put(params->conn);
+               params->conn = NULL;
+       }
+
+       if (!params->explicit_connect)
+               return;
+
+       /* If the status indicates successful cancellation of
+        * the attempt (i.e. Unknown Connection Id) there's no point of
+        * notifying failure since we'll go back to keep trying to
+        * connect. The only exception is explicit connect requests
+        * where a timeout + cancel does indicate an actual failure.
+        */
+       if (status && status != HCI_ERROR_UNKNOWN_CONN_ID)
+               mgmt_connect_failed(hdev, &conn->dst, conn->type,
+                                   conn->dst_type, status);
+
        /* The connection attempt was doing scan for new RPA, and is
         * in scan phase. If params are not associated with any other
         * autoconnect action, remove them completely. If they are, just unmark
@@ -178,7 +197,7 @@ static void le_scan_cleanup(struct work_struct *work)
        rcu_read_unlock();
 
        if (c == conn) {
-               hci_connect_le_scan_cleanup(conn);
+               hci_connect_le_scan_cleanup(conn, 0x00);
                hci_conn_cleanup(conn);
        }
 
@@ -1049,6 +1068,17 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
        return conn;
 }
 
+static bool hci_conn_unlink(struct hci_conn *conn)
+{
+       if (!conn->link)
+               return false;
+
+       conn->link->link = NULL;
+       conn->link = NULL;
+
+       return true;
+}
+
 int hci_conn_del(struct hci_conn *conn)
 {
        struct hci_dev *hdev = conn->hdev;
@@ -1060,15 +1090,16 @@ int hci_conn_del(struct hci_conn *conn)
        cancel_delayed_work_sync(&conn->idle_work);
 
        if (conn->type == ACL_LINK) {
-               struct hci_conn *sco = conn->link;
-               if (sco) {
-                       sco->link = NULL;
+               struct hci_conn *link = conn->link;
+
+               if (link) {
+                       hci_conn_unlink(conn);
                        /* Due to race, SCO connection might be not established
                         * yet at this point. Delete it now, otherwise it is
                         * possible for it to be stuck and can't be deleted.
                         */
-                       if (sco->handle == HCI_CONN_HANDLE_UNSET)
-                               hci_conn_del(sco);
+                       if (link->handle == HCI_CONN_HANDLE_UNSET)
+                               hci_conn_del(link);
                }
 
                /* Unacked frames */
@@ -1084,7 +1115,7 @@ int hci_conn_del(struct hci_conn *conn)
                struct hci_conn *acl = conn->link;
 
                if (acl) {
-                       acl->link = NULL;
+                       hci_conn_unlink(conn);
                        hci_conn_drop(acl);
                }
 
@@ -1179,31 +1210,8 @@ EXPORT_SYMBOL(hci_get_route);
 static void hci_le_conn_failed(struct hci_conn *conn, u8 status)
 {
        struct hci_dev *hdev = conn->hdev;
-       struct hci_conn_params *params;
 
-       params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst,
-                                          conn->dst_type);
-       if (params && params->conn) {
-               hci_conn_drop(params->conn);
-               hci_conn_put(params->conn);
-               params->conn = NULL;
-       }
-
-       /* If the status indicates successful cancellation of
-        * the attempt (i.e. Unknown Connection Id) there's no point of
-        * notifying failure since we'll go back to keep trying to
-        * connect. The only exception is explicit connect requests
-        * where a timeout + cancel does indicate an actual failure.
-        */
-       if (status != HCI_ERROR_UNKNOWN_CONN_ID ||
-           (params && params->explicit_connect))
-               mgmt_connect_failed(hdev, &conn->dst, conn->type,
-                                   conn->dst_type, status);
-
-       /* Since we may have temporarily stopped the background scanning in
-        * favor of connection establishment, we should restart it.
-        */
-       hci_update_passive_scan(hdev);
+       hci_connect_le_scan_cleanup(conn, status);
 
        /* Enable advertising in case this was a failed connection
         * attempt as a peripheral.
@@ -1237,15 +1245,15 @@ static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err)
 {
        struct hci_conn *conn = data;
 
+       bt_dev_dbg(hdev, "err %d", err);
+
        hci_dev_lock(hdev);
 
        if (!err) {
-               hci_connect_le_scan_cleanup(conn);
+               hci_connect_le_scan_cleanup(conn, 0x00);
                goto done;
        }
 
-       bt_dev_err(hdev, "request failed to create LE connection: err %d", err);
-
        /* Check if connection is still pending */
        if (conn != hci_lookup_le_connect(hdev))
                goto done;
@@ -2438,6 +2446,12 @@ void hci_conn_hash_flush(struct hci_dev *hdev)
                c->state = BT_CLOSED;
 
                hci_disconn_cfm(c, HCI_ERROR_LOCAL_HOST_TERM);
+
+               /* Unlink before deleting otherwise it is possible that
+                * hci_conn_del removes the link which may cause the list to
+                * contain items already freed.
+                */
+               hci_conn_unlink(c);
                hci_conn_del(c);
        }
 }
@@ -2775,6 +2789,9 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason)
 {
        int r = 0;
 
+       if (test_and_set_bit(HCI_CONN_CANCEL, &conn->flags))
+               return 0;
+
        switch (conn->state) {
        case BT_CONNECTED:
        case BT_CONFIG:
index b65c3aabcd53665fa32bcaee888b3ecdaeb76b07..334e308451f5397fb4cda8b8b6f8ef724aade2c1 100644 (file)
@@ -2871,10 +2871,25 @@ int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
                return -ENXIO;
        }
 
-       if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT &&
-           hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
-           hci_skb_pkt_type(skb) != HCI_SCODATA_PKT &&
-           hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) {
+       switch (hci_skb_pkt_type(skb)) {
+       case HCI_EVENT_PKT:
+               break;
+       case HCI_ACLDATA_PKT:
+               /* Detect if ISO packet has been sent as ACL */
+               if (hci_conn_num(hdev, ISO_LINK)) {
+                       __u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle);
+                       __u8 type;
+
+                       type = hci_conn_lookup_type(hdev, hci_handle(handle));
+                       if (type == ISO_LINK)
+                               hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
+               }
+               break;
+       case HCI_SCODATA_PKT:
+               break;
+       case HCI_ISODATA_PKT:
+               break;
+       default:
                kfree_skb(skb);
                return -EINVAL;
        }
index ad92a4be5851739cba345c629690b9274e154db5..e87c928c9e17ae5608bd4614ed6f59edf680bcf4 100644 (file)
@@ -2881,16 +2881,6 @@ static void cs_le_create_conn(struct hci_dev *hdev, bdaddr_t *peer_addr,
 
        conn->resp_addr_type = peer_addr_type;
        bacpy(&conn->resp_addr, peer_addr);
-
-       /* We don't want the connection attempt to stick around
-        * indefinitely since LE doesn't have a page timeout concept
-        * like BR/EDR. Set a timer for any connection that doesn't use
-        * the accept list for connecting.
-        */
-       if (filter_policy == HCI_LE_USE_PEER_ADDR)
-               queue_delayed_work(conn->hdev->workqueue,
-                                  &conn->le_conn_timeout,
-                                  conn->conn_timeout);
 }
 
 static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
@@ -5902,6 +5892,12 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
        if (status)
                goto unlock;
 
+       /* Drop the connection if it has been aborted */
+       if (test_bit(HCI_CONN_CANCEL, &conn->flags)) {
+               hci_conn_drop(conn);
+               goto unlock;
+       }
+
        if (conn->dst_type == ADDR_LE_DEV_PUBLIC)
                addr_type = BDADDR_LE_PUBLIC;
        else
@@ -6995,7 +6991,7 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
                bis->iso_qos.in.latency = le16_to_cpu(ev->interval) * 125 / 100;
                bis->iso_qos.in.sdu = le16_to_cpu(ev->max_pdu);
 
-               hci_connect_cfm(bis, ev->status);
+               hci_iso_setup_path(bis);
        }
 
        hci_dev_unlock(hdev);
index 117eedb6f70993a5b58987a7a7bf794aaf8e000e..632be12672887ae0fdb8d4df67de4f63aa855f4e 100644 (file)
@@ -246,8 +246,9 @@ int __hci_cmd_sync_status_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
 
        skb = __hci_cmd_sync_sk(hdev, opcode, plen, param, event, timeout, sk);
        if (IS_ERR(skb)) {
-               bt_dev_err(hdev, "Opcode 0x%4x failed: %ld", opcode,
-                               PTR_ERR(skb));
+               if (!event)
+                       bt_dev_err(hdev, "Opcode 0x%4x failed: %ld", opcode,
+                                  PTR_ERR(skb));
                return PTR_ERR(skb);
        }
 
@@ -643,6 +644,7 @@ void hci_cmd_sync_clear(struct hci_dev *hdev)
        cancel_work_sync(&hdev->cmd_sync_work);
        cancel_work_sync(&hdev->reenable_adv_work);
 
+       mutex_lock(&hdev->cmd_sync_work_lock);
        list_for_each_entry_safe(entry, tmp, &hdev->cmd_sync_work_list, list) {
                if (entry->destroy)
                        entry->destroy(hdev, entry->data, -ECANCELED);
@@ -650,6 +652,7 @@ void hci_cmd_sync_clear(struct hci_dev *hdev)
                list_del(&entry->list);
                kfree(entry);
        }
+       mutex_unlock(&hdev->cmd_sync_work_lock);
 }
 
 void __hci_cmd_sync_cancel(struct hci_dev *hdev, int err)
@@ -2367,6 +2370,45 @@ static int hci_resume_advertising_sync(struct hci_dev *hdev)
        return err;
 }
 
+static int hci_pause_addr_resolution(struct hci_dev *hdev)
+{
+       int err;
+
+       if (!use_ll_privacy(hdev))
+               return 0;
+
+       if (!hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION))
+               return 0;
+
+       /* Cannot disable addr resolution if scanning is enabled or
+        * when initiating an LE connection.
+        */
+       if (hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
+           hci_lookup_le_connect(hdev)) {
+               bt_dev_err(hdev, "Command not allowed when scan/LE connect");
+               return -EPERM;
+       }
+
+       /* Cannot disable addr resolution if advertising is enabled. */
+       err = hci_pause_advertising_sync(hdev);
+       if (err) {
+               bt_dev_err(hdev, "Pause advertising failed: %d", err);
+               return err;
+       }
+
+       err = hci_le_set_addr_resolution_enable_sync(hdev, 0x00);
+       if (err)
+               bt_dev_err(hdev, "Unable to disable Address Resolution: %d",
+                          err);
+
+       /* Return if address resolution is disabled and RPA is not used. */
+       if (!err && scan_use_rpa(hdev))
+               return err;
+
+       hci_resume_advertising_sync(hdev);
+       return err;
+}
+
 struct sk_buff *hci_read_local_oob_data_sync(struct hci_dev *hdev,
                                             bool extended, struct sock *sk)
 {
@@ -2402,7 +2444,7 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
        u8 filter_policy;
        int err;
 
-       /* Pause advertising if resolving list can be used as controllers are
+       /* Pause advertising if resolving list can be used as controllers
         * cannot accept resolving list modifications while advertising.
         */
        if (use_ll_privacy(hdev)) {
@@ -3319,6 +3361,7 @@ static const struct hci_init_stage amp_init1[] = {
        HCI_INIT(hci_read_flow_control_mode_sync),
        /* HCI_OP_READ_LOCATION_DATA */
        HCI_INIT(hci_read_location_data_sync),
+       {}
 };
 
 static int hci_init1_sync(struct hci_dev *hdev)
@@ -3353,6 +3396,7 @@ static int hci_init1_sync(struct hci_dev *hdev)
 static const struct hci_init_stage amp_init2[] = {
        /* HCI_OP_READ_LOCAL_FEATURES */
        HCI_INIT(hci_read_local_features_sync),
+       {}
 };
 
 /* Read Buffer Size (ACL mtu, max pkt, etc.) */
@@ -5083,8 +5127,11 @@ static int hci_le_connect_cancel_sync(struct hci_dev *hdev,
        if (test_bit(HCI_CONN_SCANNING, &conn->flags))
                return 0;
 
+       if (test_and_set_bit(HCI_CONN_CANCEL, &conn->flags))
+               return 0;
+
        return __hci_cmd_sync_status(hdev, HCI_OP_LE_CREATE_CONN_CANCEL,
-                                    6, &conn->dst, HCI_CMD_TIMEOUT);
+                                    0, NULL, HCI_CMD_TIMEOUT);
 }
 
 static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn)
@@ -5394,27 +5441,12 @@ static int hci_active_scan_sync(struct hci_dev *hdev, uint16_t interval)
 
        cancel_interleave_scan(hdev);
 
-       /* Pause advertising since active scanning disables address resolution
-        * which advertising depend on in order to generate its RPAs.
+       /* Pause address resolution for active scan and stop advertising if
+        * privacy is enabled.
         */
-       if (use_ll_privacy(hdev) && hci_dev_test_flag(hdev, HCI_PRIVACY)) {
-               err = hci_pause_advertising_sync(hdev);
-               if (err) {
-                       bt_dev_err(hdev, "pause advertising failed: %d", err);
-                       goto failed;
-               }
-       }
-
-       /* Disable address resolution while doing active scanning since the
-        * accept list shall not be used and all reports shall reach the host
-        * anyway.
-        */
-       err = hci_le_set_addr_resolution_enable_sync(hdev, 0x00);
-       if (err) {
-               bt_dev_err(hdev, "Unable to disable Address Resolution: %d",
-                          err);
+       err = hci_pause_addr_resolution(hdev);
+       if (err)
                goto failed;
-       }
 
        /* All active scans will be done with either a resolvable private
         * address (when privacy feature has been enabled) or non-resolvable
@@ -6074,6 +6106,9 @@ int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn)
                                       conn->conn_timeout, NULL);
 
 done:
+       if (err == -ETIMEDOUT)
+               hci_le_connect_cancel_sync(hdev, conn);
+
        /* Re-enable advertising after the connection attempt is finished. */
        hci_resume_advertising_sync(hdev);
        return err;
index bed1a7b9205c20cceacd45a529b50f9b378dff9c..707f229f896a1fb01195b3001fd1629cbf16d0d9 100644 (file)
@@ -433,7 +433,7 @@ static void hidp_set_timer(struct hidp_session *session)
 static void hidp_del_timer(struct hidp_session *session)
 {
        if (session->idle_to > 0)
-               del_timer(&session->timer);
+               del_timer_sync(&session->timer);
 }
 
 static void hidp_process_report(struct hidp_session *session, int type,
index 24444b502e5865400d4eecbdcf68ace4b9e687b6..8d136a7301630d3172178e063b0a8c36b5540f4f 100644 (file)
@@ -1620,7 +1620,6 @@ static void iso_disconn_cfm(struct hci_conn *hcon, __u8 reason)
 void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
 {
        struct iso_conn *conn = hcon->iso_data;
-       struct hci_iso_data_hdr *hdr;
        __u16 pb, ts, len;
 
        if (!conn)
@@ -1642,6 +1641,8 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
                }
 
                if (ts) {
+                       struct hci_iso_ts_data_hdr *hdr;
+
                        /* TODO: add timestamp to the packet? */
                        hdr = skb_pull_data(skb, HCI_ISO_TS_DATA_HDR_SIZE);
                        if (!hdr) {
@@ -1649,15 +1650,19 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
                                goto drop;
                        }
 
+                       len = __le16_to_cpu(hdr->slen);
                } else {
+                       struct hci_iso_data_hdr *hdr;
+
                        hdr = skb_pull_data(skb, HCI_ISO_DATA_HDR_SIZE);
                        if (!hdr) {
                                BT_ERR("Frame is too short (len %d)", skb->len);
                                goto drop;
                        }
+
+                       len = __le16_to_cpu(hdr->slen);
                }
 
-               len    = __le16_to_cpu(hdr->slen);
                flags  = hci_iso_data_flags(len);
                len    = hci_iso_data_len(len);
 
index adfc3ea06d088ef6b68dc28422092351bafa7133..55a7226233f96df0836e5945be61e9ec3fed8880 100644 (file)
@@ -708,6 +708,17 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
 }
 EXPORT_SYMBOL_GPL(l2cap_chan_del);
 
+static void __l2cap_chan_list_id(struct l2cap_conn *conn, u16 id,
+                                l2cap_chan_func_t func, void *data)
+{
+       struct l2cap_chan *chan, *l;
+
+       list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
+               if (chan->ident == id)
+                       func(chan, data);
+       }
+}
+
 static void __l2cap_chan_list(struct l2cap_conn *conn, l2cap_chan_func_t func,
                              void *data)
 {
@@ -775,23 +786,9 @@ static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
 
 static void l2cap_chan_ecred_connect_reject(struct l2cap_chan *chan)
 {
-       struct l2cap_conn *conn = chan->conn;
-       struct l2cap_ecred_conn_rsp rsp;
-       u16 result;
-
-       if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
-               result = L2CAP_CR_LE_AUTHORIZATION;
-       else
-               result = L2CAP_CR_LE_BAD_PSM;
-
        l2cap_state_change(chan, BT_DISCONN);
 
-       memset(&rsp, 0, sizeof(rsp));
-
-       rsp.result  = cpu_to_le16(result);
-
-       l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
-                      &rsp);
+       __l2cap_ecred_conn_rsp_defer(chan);
 }
 
 static void l2cap_chan_connect_reject(struct l2cap_chan *chan)
@@ -846,7 +843,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
                                        break;
                                case L2CAP_MODE_EXT_FLOWCTL:
                                        l2cap_chan_ecred_connect_reject(chan);
-                                       break;
+                                       return;
                                }
                        }
                }
@@ -3938,43 +3935,86 @@ void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan)
                       &rsp);
 }
 
-void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan)
+static void l2cap_ecred_list_defer(struct l2cap_chan *chan, void *data)
 {
+       int *result = data;
+
+       if (*result || test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
+               return;
+
+       switch (chan->state) {
+       case BT_CONNECT2:
+               /* If channel still pending accept add to result */
+               (*result)++;
+               return;
+       case BT_CONNECTED:
+               return;
+       default:
+               /* If not connected or pending accept it has been refused */
+               *result = -ECONNREFUSED;
+               return;
+       }
+}
+
+struct l2cap_ecred_rsp_data {
        struct {
                struct l2cap_ecred_conn_rsp rsp;
-               __le16 dcid[5];
+               __le16 scid[L2CAP_ECRED_MAX_CID];
        } __packed pdu;
+       int count;
+};
+
+static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data)
+{
+       struct l2cap_ecred_rsp_data *rsp = data;
+
+       if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
+               return;
+
+       /* Reset ident so only one response is sent */
+       chan->ident = 0;
+
+       /* Include all channels pending with the same ident */
+       if (!rsp->pdu.rsp.result)
+               rsp->pdu.rsp.dcid[rsp->count++] = cpu_to_le16(chan->scid);
+       else
+               l2cap_chan_del(chan, ECONNRESET);
+}
+
+void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan)
+{
        struct l2cap_conn *conn = chan->conn;
-       u16 ident = chan->ident;
-       int i = 0;
+       struct l2cap_ecred_rsp_data data;
+       u16 id = chan->ident;
+       int result = 0;
 
-       if (!ident)
+       if (!id)
                return;
 
-       BT_DBG("chan %p ident %d", chan, ident);
+       BT_DBG("chan %p id %d", chan, id);
 
-       pdu.rsp.mtu     = cpu_to_le16(chan->imtu);
-       pdu.rsp.mps     = cpu_to_le16(chan->mps);
-       pdu.rsp.credits = cpu_to_le16(chan->rx_credits);
-       pdu.rsp.result  = cpu_to_le16(L2CAP_CR_LE_SUCCESS);
+       memset(&data, 0, sizeof(data));
 
-       mutex_lock(&conn->chan_lock);
+       data.pdu.rsp.mtu     = cpu_to_le16(chan->imtu);
+       data.pdu.rsp.mps     = cpu_to_le16(chan->mps);
+       data.pdu.rsp.credits = cpu_to_le16(chan->rx_credits);
+       data.pdu.rsp.result  = cpu_to_le16(L2CAP_CR_LE_SUCCESS);
 
-       list_for_each_entry(chan, &conn->chan_l, list) {
-               if (chan->ident != ident)
-                       continue;
+       /* Verify that all channels are ready */
+       __l2cap_chan_list_id(conn, id, l2cap_ecred_list_defer, &result);
 
-               /* Reset ident so only one response is sent */
-               chan->ident = 0;
+       if (result > 0)
+               return;
 
-               /* Include all channels pending with the same ident */
-               pdu.dcid[i++] = cpu_to_le16(chan->scid);
-       }
+       if (result < 0)
+               data.pdu.rsp.result = cpu_to_le16(L2CAP_CR_LE_AUTHORIZATION);
 
-       mutex_unlock(&conn->chan_lock);
+       /* Build response */
+       __l2cap_chan_list_id(conn, id, l2cap_ecred_rsp_defer, &data);
 
-       l2cap_send_cmd(conn, ident, L2CAP_ECRED_CONN_RSP,
-                       sizeof(pdu.rsp) + i * sizeof(__le16), &pdu);
+       l2cap_send_cmd(conn, id, L2CAP_ECRED_CONN_RSP,
+                      sizeof(data.pdu.rsp) + (data.count * sizeof(__le16)),
+                      &data.pdu);
 }
 
 void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
@@ -4612,33 +4652,27 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
 
        BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
 
-       mutex_lock(&conn->chan_lock);
-
-       chan = __l2cap_get_chan_by_scid(conn, dcid);
+       chan = l2cap_get_chan_by_scid(conn, dcid);
        if (!chan) {
-               mutex_unlock(&conn->chan_lock);
                cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid);
                return 0;
        }
 
-       l2cap_chan_hold(chan);
-       l2cap_chan_lock(chan);
-
        rsp.dcid = cpu_to_le16(chan->scid);
        rsp.scid = cpu_to_le16(chan->dcid);
        l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
 
        chan->ops->set_shutdown(chan);
 
+       mutex_lock(&conn->chan_lock);
        l2cap_chan_del(chan, ECONNRESET);
+       mutex_unlock(&conn->chan_lock);
 
        chan->ops->close(chan);
 
        l2cap_chan_unlock(chan);
        l2cap_chan_put(chan);
 
-       mutex_unlock(&conn->chan_lock);
-
        return 0;
 }
 
@@ -4658,33 +4692,27 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
 
        BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
 
-       mutex_lock(&conn->chan_lock);
-
-       chan = __l2cap_get_chan_by_scid(conn, scid);
+       chan = l2cap_get_chan_by_scid(conn, scid);
        if (!chan) {
                mutex_unlock(&conn->chan_lock);
                return 0;
        }
 
-       l2cap_chan_hold(chan);
-       l2cap_chan_lock(chan);
-
        if (chan->state != BT_DISCONN) {
                l2cap_chan_unlock(chan);
                l2cap_chan_put(chan);
-               mutex_unlock(&conn->chan_lock);
                return 0;
        }
 
+       mutex_lock(&conn->chan_lock);
        l2cap_chan_del(chan, 0);
+       mutex_unlock(&conn->chan_lock);
 
        chan->ops->close(chan);
 
        l2cap_chan_unlock(chan);
        l2cap_chan_put(chan);
 
-       mutex_unlock(&conn->chan_lock);
-
        return 0;
 }
 
@@ -6078,6 +6106,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
                __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
 
                chan->ident = cmd->ident;
+               chan->mode = L2CAP_MODE_EXT_FLOWCTL;
 
                if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
                        l2cap_state_change(chan, BT_CONNECT2);
index 7add66f30e4d1a858a75dfba41260c922eacb444..249dc6777fb4e92963d150a1ec135299fb7faa29 100644 (file)
@@ -4639,12 +4639,6 @@ static int set_mgmt_mesh_func(struct sock *sk, struct hci_dev *hdev,
                                       MGMT_OP_SET_EXP_FEATURE,
                                       MGMT_STATUS_INVALID_INDEX);
 
-       /* Changes can only be made when controller is powered down */
-       if (hdev_is_powered(hdev))
-               return mgmt_cmd_status(sk, hdev->id,
-                                      MGMT_OP_SET_EXP_FEATURE,
-                                      MGMT_STATUS_REJECTED);
-
        /* Parameters are limited to a single octet */
        if (data_len != MGMT_SET_EXP_FEATURE_SIZE + 1)
                return mgmt_cmd_status(sk, hdev->id,
@@ -9363,7 +9357,8 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
        { add_ext_adv_data,        MGMT_ADD_EXT_ADV_DATA_SIZE,
                                                HCI_MGMT_VAR_LEN },
        { add_adv_patterns_monitor_rssi,
-                                  MGMT_ADD_ADV_PATTERNS_MONITOR_RSSI_SIZE },
+                                  MGMT_ADD_ADV_PATTERNS_MONITOR_RSSI_SIZE,
+                                               HCI_MGMT_VAR_LEN },
        { set_mesh,                MGMT_SET_MESH_RECEIVER_SIZE,
                                                HCI_MGMT_VAR_LEN },
        { mesh_features,           MGMT_MESH_READ_FEATURES_SIZE },
index 1111da4e2f2bd533572ee82a1b42ffd725a2d593..cd1a27ac555d009a65dbebb5a5ea125b9261f147 100644 (file)
@@ -235,27 +235,41 @@ static int sco_chan_add(struct sco_conn *conn, struct sock *sk,
        return err;
 }
 
-static int sco_connect(struct hci_dev *hdev, struct sock *sk)
+static int sco_connect(struct sock *sk)
 {
        struct sco_conn *conn;
        struct hci_conn *hcon;
+       struct hci_dev  *hdev;
        int err, type;
 
        BT_DBG("%pMR -> %pMR", &sco_pi(sk)->src, &sco_pi(sk)->dst);
 
+       hdev = hci_get_route(&sco_pi(sk)->dst, &sco_pi(sk)->src, BDADDR_BREDR);
+       if (!hdev)
+               return -EHOSTUNREACH;
+
+       hci_dev_lock(hdev);
+
        if (lmp_esco_capable(hdev) && !disable_esco)
                type = ESCO_LINK;
        else
                type = SCO_LINK;
 
        if (sco_pi(sk)->setting == BT_VOICE_TRANSPARENT &&
-           (!lmp_transp_capable(hdev) || !lmp_esco_capable(hdev)))
-               return -EOPNOTSUPP;
+           (!lmp_transp_capable(hdev) || !lmp_esco_capable(hdev))) {
+               err = -EOPNOTSUPP;
+               goto unlock;
+       }
 
        hcon = hci_connect_sco(hdev, type, &sco_pi(sk)->dst,
                               sco_pi(sk)->setting, &sco_pi(sk)->codec);
-       if (IS_ERR(hcon))
-               return PTR_ERR(hcon);
+       if (IS_ERR(hcon)) {
+               err = PTR_ERR(hcon);
+               goto unlock;
+       }
+
+       hci_dev_unlock(hdev);
+       hci_dev_put(hdev);
 
        conn = sco_conn_add(hcon);
        if (!conn) {
@@ -263,13 +277,15 @@ static int sco_connect(struct hci_dev *hdev, struct sock *sk)
                return -ENOMEM;
        }
 
-       /* Update source addr of the socket */
-       bacpy(&sco_pi(sk)->src, &hcon->src);
-
        err = sco_chan_add(conn, sk, NULL);
        if (err)
                return err;
 
+       lock_sock(sk);
+
+       /* Update source addr of the socket */
+       bacpy(&sco_pi(sk)->src, &hcon->src);
+
        if (hcon->state == BT_CONNECTED) {
                sco_sock_clear_timer(sk);
                sk->sk_state = BT_CONNECTED;
@@ -278,6 +294,13 @@ static int sco_connect(struct hci_dev *hdev, struct sock *sk)
                sco_sock_set_timer(sk, sk->sk_sndtimeo);
        }
 
+       release_sock(sk);
+
+       return err;
+
+unlock:
+       hci_dev_unlock(hdev);
+       hci_dev_put(hdev);
        return err;
 }
 
@@ -565,7 +588,6 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen
 {
        struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
        struct sock *sk = sock->sk;
-       struct hci_dev  *hdev;
        int err;
 
        BT_DBG("sk %p", sk);
@@ -574,37 +596,26 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen
            addr->sa_family != AF_BLUETOOTH)
                return -EINVAL;
 
-       lock_sock(sk);
-       if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) {
-               err = -EBADFD;
-               goto done;
-       }
+       if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
+               return -EBADFD;
 
-       if (sk->sk_type != SOCK_SEQPACKET) {
+       if (sk->sk_type != SOCK_SEQPACKET)
                err = -EINVAL;
-               goto done;
-       }
-
-       hdev = hci_get_route(&sa->sco_bdaddr, &sco_pi(sk)->src, BDADDR_BREDR);
-       if (!hdev) {
-               err = -EHOSTUNREACH;
-               goto done;
-       }
-       hci_dev_lock(hdev);
 
+       lock_sock(sk);
        /* Set destination address and psm */
        bacpy(&sco_pi(sk)->dst, &sa->sco_bdaddr);
+       release_sock(sk);
 
-       err = sco_connect(hdev, sk);
-       hci_dev_unlock(hdev);
-       hci_dev_put(hdev);
+       err = sco_connect(sk);
        if (err)
-               goto done;
+               return err;
+
+       lock_sock(sk);
 
        err = bt_sock_wait_state(sk, BT_CONNECTED,
                                 sock_sndtimeo(sk, flags & O_NONBLOCK));
 
-done:
        release_sock(sk);
        return err;
 }
@@ -1129,6 +1140,8 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname,
                        break;
                }
 
+               release_sock(sk);
+
                /* find total buffer size required to copy codec + caps */
                hci_dev_lock(hdev);
                list_for_each_entry(c, &hdev->local_codecs, list) {
@@ -1146,15 +1159,13 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname,
                buf_len += sizeof(struct bt_codecs);
                if (buf_len > len) {
                        hci_dev_put(hdev);
-                       err = -ENOBUFS;
-                       break;
+                       return -ENOBUFS;
                }
                ptr = optval;
 
                if (put_user(num_codecs, ptr)) {
                        hci_dev_put(hdev);
-                       err = -EFAULT;
-                       break;
+                       return -EFAULT;
                }
                ptr += sizeof(num_codecs);
 
@@ -1194,12 +1205,14 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname,
                        ptr += len;
                }
 
-               if (!err && put_user(buf_len, optlen))
-                       err = -EFAULT;
-
                hci_dev_unlock(hdev);
                hci_dev_put(hdev);
 
+               lock_sock(sk);
+
+               if (!err && put_user(buf_len, optlen))
+                       err = -EFAULT;
+
                break;
 
        default:
index 6f3d654b3339c0841d109ce0f3db1c98bd9365aa..f81b24320a36e139f71689075e87d2413cd54a89 100644 (file)
@@ -97,8 +97,11 @@ reset:
 struct xdp_page_head {
        struct xdp_buff orig_ctx;
        struct xdp_buff ctx;
-       struct xdp_frame frm;
-       u8 data[];
+       union {
+               /* ::data_hard_start starts here */
+               DECLARE_FLEX_ARRAY(struct xdp_frame, frame);
+               DECLARE_FLEX_ARRAY(u8, data);
+       };
 };
 
 struct xdp_test_data {
@@ -113,6 +116,10 @@ struct xdp_test_data {
        u32 frame_cnt;
 };
 
+/* tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c:%MAX_PKT_SIZE
+ * must be updated accordingly this gets changed, otherwise BPF selftests
+ * will fail.
+ */
 #define TEST_XDP_FRAME_SIZE (PAGE_SIZE - sizeof(struct xdp_page_head))
 #define TEST_XDP_MAX_BATCH 256
 
@@ -132,8 +139,8 @@ static void xdp_test_run_init_page(struct page *page, void *arg)
        headroom -= meta_len;
 
        new_ctx = &head->ctx;
-       frm = &head->frm;
-       data = &head->data;
+       frm = head->frame;
+       data = head->data;
        memcpy(data + headroom, orig_ctx->data_meta, frm_len);
 
        xdp_init_buff(new_ctx, TEST_XDP_FRAME_SIZE, &xdp->rxq);
@@ -223,7 +230,7 @@ static void reset_ctx(struct xdp_page_head *head)
        head->ctx.data = head->orig_ctx.data;
        head->ctx.data_meta = head->orig_ctx.data_meta;
        head->ctx.data_end = head->orig_ctx.data_end;
-       xdp_update_frame_from_buff(&head->ctx, &head->frm);
+       xdp_update_frame_from_buff(&head->ctx, head->frame);
 }
 
 static int xdp_recv_frames(struct xdp_frame **frames, int nframes,
@@ -285,7 +292,7 @@ static int xdp_test_run_batch(struct xdp_test_data *xdp, struct bpf_prog *prog,
                head = phys_to_virt(page_to_phys(page));
                reset_ctx(head);
                ctx = &head->ctx;
-               frm = &head->frm;
+               frm = head->frame;
                xdp->frame_cnt++;
 
                act = bpf_prog_run_xdp(prog, ctx);
index 638a4d5359db08f72a1191548a8874190c5983f2..4bc6761517bbc4c8da3622deea6f81e56508f30c 100644 (file)
@@ -868,12 +868,17 @@ static unsigned int ip_sabotage_in(void *priv,
 {
        struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
 
-       if (nf_bridge && !nf_bridge->in_prerouting &&
-           !netif_is_l3_master(skb->dev) &&
-           !netif_is_l3_slave(skb->dev)) {
-               nf_bridge_info_free(skb);
-               state->okfn(state->net, state->sk, skb);
-               return NF_STOLEN;
+       if (nf_bridge) {
+               if (nf_bridge->sabotage_in_done)
+                       return NF_ACCEPT;
+
+               if (!nf_bridge->in_prerouting &&
+                   !netif_is_l3_master(skb->dev) &&
+                   !netif_is_l3_slave(skb->dev)) {
+                       nf_bridge->sabotage_in_done = 1;
+                       state->okfn(state->net, state->sk, skb);
+                       return NF_STOLEN;
+               }
        }
 
        return NF_ACCEPT;
index de18e9c1d7a784dcc89a514f91ad7ed8a0aa6b71..ba95c4d74a60141ca488d488cfded3e56ef4d602 100644 (file)
@@ -148,6 +148,17 @@ br_switchdev_fdb_notify(struct net_bridge *br,
        if (test_bit(BR_FDB_LOCKED, &fdb->flags))
                return;
 
+       /* Entries with these flags were created using ndm_state == NUD_REACHABLE,
+        * ndm_flags == NTF_MASTER( | NTF_STICKY), ext_flags == 0 by something
+        * equivalent to 'bridge fdb add ... master dynamic (sticky)'.
+        * Drivers don't know how to deal with these, so don't notify them to
+        * avoid confusing them.
+        */
+       if (test_bit(BR_FDB_ADDED_BY_USER, &fdb->flags) &&
+           !test_bit(BR_FDB_STATIC, &fdb->flags) &&
+           !test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags))
+               return;
+
        br_switchdev_fdb_populate(br, &item, fdb, NULL);
 
        switch (type) {
index ebc202ffdd8d8d8fbb14e1009a86cbcad48094b4..bf61ea4b8132d0c625290e751dd4a5d850922abf 100644 (file)
@@ -134,6 +134,9 @@ static int cfusbl_device_notify(struct notifier_block *me, unsigned long what,
        struct usb_device *usbdev;
        int res;
 
+       if (what == NETDEV_UNREGISTER && dev->reg_state >= NETREG_UNREGISTERED)
+               return 0;
+
        /* Check whether we have a NCM device, and find its VID/PID. */
        if (!(dev->dev.parent && dev->dev.parent->driver &&
              strcmp(dev->dev.parent->driver->name, "cdc_ncm") == 0))
index 27706f6ace34a0296392ae66ca5b0ab1fad26e04..a962ec2b8ba5b393a7e5fafa6e88450dd7359008 100644 (file)
@@ -941,6 +941,8 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 
                        cf = op->frames + op->cfsiz * i;
                        err = memcpy_from_msg((u8 *)cf, msg, op->cfsiz);
+                       if (err < 0)
+                               goto free_op;
 
                        if (op->flags & CAN_FD_FRAME) {
                                if (cf->len > 64)
@@ -950,12 +952,8 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
                                        err = -EINVAL;
                        }
 
-                       if (err < 0) {
-                               if (op->frames != &op->sframe)
-                                       kfree(op->frames);
-                               kfree(op);
-                               return err;
-                       }
+                       if (err < 0)
+                               goto free_op;
 
                        if (msg_head->flags & TX_CP_CAN_ID) {
                                /* copy can_id into frame */
@@ -1026,6 +1024,12 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
                bcm_tx_start_timer(op);
 
        return msg_head->nframes * op->cfsiz + MHSIZ;
+
+free_op:
+       if (op->frames != &op->sframe)
+               kfree(op->frames);
+       kfree(op);
+       return err;
 }
 
 /*
index 9bc344851704e3683c4be04cd841b7db0eade8e8..5761d4ab839dd9776f072ba9ce78ac969defc97d 100644 (file)
@@ -119,7 +119,8 @@ enum {
        ISOTP_WAIT_FIRST_FC,
        ISOTP_WAIT_FC,
        ISOTP_WAIT_DATA,
-       ISOTP_SENDING
+       ISOTP_SENDING,
+       ISOTP_SHUTDOWN,
 };
 
 struct tpcon {
@@ -880,8 +881,8 @@ static enum hrtimer_restart isotp_tx_timer_handler(struct hrtimer *hrtimer)
                                             txtimer);
        struct sock *sk = &so->sk;
 
-       /* don't handle timeouts in IDLE state */
-       if (so->tx.state == ISOTP_IDLE)
+       /* don't handle timeouts in IDLE or SHUTDOWN state */
+       if (so->tx.state == ISOTP_IDLE || so->tx.state == ISOTP_SHUTDOWN)
                return HRTIMER_NORESTART;
 
        /* we did not get any flow control or echo frame in time */
@@ -918,7 +919,6 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
 {
        struct sock *sk = sock->sk;
        struct isotp_sock *so = isotp_sk(sk);
-       u32 old_state = so->tx.state;
        struct sk_buff *skb;
        struct net_device *dev;
        struct canfd_frame *cf;
@@ -928,23 +928,24 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
        int off;
        int err;
 
-       if (!so->bound)
+       if (!so->bound || so->tx.state == ISOTP_SHUTDOWN)
                return -EADDRNOTAVAIL;
 
+wait_free_buffer:
        /* we do not support multiple buffers - for now */
-       if (cmpxchg(&so->tx.state, ISOTP_IDLE, ISOTP_SENDING) != ISOTP_IDLE ||
-           wq_has_sleeper(&so->wait)) {
-               if (msg->msg_flags & MSG_DONTWAIT) {
-                       err = -EAGAIN;
-                       goto err_out;
-               }
+       if (wq_has_sleeper(&so->wait) && (msg->msg_flags & MSG_DONTWAIT))
+               return -EAGAIN;
 
-               /* wait for complete transmission of current pdu */
-               err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
-               if (err)
-                       goto err_out;
+       /* wait for complete transmission of current pdu */
+       err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
+       if (err)
+               goto err_event_drop;
 
-               so->tx.state = ISOTP_SENDING;
+       if (cmpxchg(&so->tx.state, ISOTP_IDLE, ISOTP_SENDING) != ISOTP_IDLE) {
+               if (so->tx.state == ISOTP_SHUTDOWN)
+                       return -EADDRNOTAVAIL;
+
+               goto wait_free_buffer;
        }
 
        if (!size || size > MAX_MSG_LENGTH) {
@@ -1074,7 +1075,9 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
 
        if (wait_tx_done) {
                /* wait for complete transmission of current pdu */
-               wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
+               err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
+               if (err)
+                       goto err_event_drop;
 
                if (sk->sk_err)
                        return -sk->sk_err;
@@ -1082,13 +1085,15 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
 
        return size;
 
+err_event_drop:
+       /* got signal: force tx state machine to be idle */
+       so->tx.state = ISOTP_IDLE;
+       hrtimer_cancel(&so->txfrtimer);
+       hrtimer_cancel(&so->txtimer);
 err_out_drop:
        /* drop this PDU and unlock a potential wait queue */
-       old_state = ISOTP_IDLE;
-err_out:
-       so->tx.state = old_state;
-       if (so->tx.state == ISOTP_IDLE)
-               wake_up_interruptible(&so->wait);
+       so->tx.state = ISOTP_IDLE;
+       wake_up_interruptible(&so->wait);
 
        return err;
 }
@@ -1120,7 +1125,7 @@ static int isotp_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
        if (ret < 0)
                goto out_err;
 
-       sock_recv_timestamp(msg, sk, skb);
+       sock_recv_cmsgs(msg, sk, skb);
 
        if (msg->msg_name) {
                __sockaddr_check_size(ISOTP_MIN_NAMELEN);
@@ -1150,10 +1155,12 @@ static int isotp_release(struct socket *sock)
        net = sock_net(sk);
 
        /* wait for complete transmission of current pdu */
-       wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
+       while (wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE) == 0 &&
+              cmpxchg(&so->tx.state, ISOTP_IDLE, ISOTP_SHUTDOWN) != ISOTP_IDLE)
+               ;
 
        /* force state machines to be idle also when a signal occurred */
-       so->tx.state = ISOTP_IDLE;
+       so->tx.state = ISOTP_SHUTDOWN;
        so->rx.state = ISOTP_IDLE;
 
        spin_lock(&isotp_notifier_lock);
@@ -1608,6 +1615,21 @@ static int isotp_init(struct sock *sk)
        return 0;
 }
 
+static __poll_t isotp_poll(struct file *file, struct socket *sock, poll_table *wait)
+{
+       struct sock *sk = sock->sk;
+       struct isotp_sock *so = isotp_sk(sk);
+
+       __poll_t mask = datagram_poll(file, sock, wait);
+       poll_wait(file, &so->wait, wait);
+
+       /* Check for false positives due to TX state */
+       if ((mask & EPOLLWRNORM) && (so->tx.state != ISOTP_IDLE))
+               mask &= ~(EPOLLOUT | EPOLLWRNORM);
+
+       return mask;
+}
+
 static int isotp_sock_no_ioctlcmd(struct socket *sock, unsigned int cmd,
                                  unsigned long arg)
 {
@@ -1623,7 +1645,7 @@ static const struct proto_ops isotp_ops = {
        .socketpair = sock_no_socketpair,
        .accept = sock_no_accept,
        .getname = isotp_getname,
-       .poll = datagram_poll,
+       .poll = isotp_poll,
        .ioctl = isotp_sock_no_ioctlcmd,
        .gettstamp = sock_gettstamp,
        .listen = sock_no_listen,
index fce9b9ebf13f668584c26bda3be121bf227baa12..fe3df23a259578e13bb4ca449e0cc722f2eca95f 100644 (file)
@@ -604,7 +604,10 @@ sk_buff *j1939_tp_tx_dat_new(struct j1939_priv *priv,
        /* reserve CAN header */
        skb_reserve(skb, offsetof(struct can_frame, data));
 
-       memcpy(skb->cb, re_skcb, sizeof(skb->cb));
+       /* skb->cb must be large enough to hold a j1939_sk_buff_cb structure */
+       BUILD_BUG_ON(sizeof(skb->cb) < sizeof(*re_skcb));
+
+       memcpy(skb->cb, re_skcb, sizeof(*re_skcb));
        skcb = j1939_skb_to_cb(skb);
        if (swap_src_dst)
                j1939_skbcb_swap(skcb);
@@ -1124,8 +1127,6 @@ static void __j1939_session_cancel(struct j1939_session *session,
 
        if (session->sk)
                j1939_sk_send_loop_abort(session->sk, session->err);
-       else
-               j1939_sk_errqueue(session, J1939_ERRQUEUE_RX_ABORT);
 }
 
 static void j1939_session_cancel(struct j1939_session *session,
@@ -1140,6 +1141,9 @@ static void j1939_session_cancel(struct j1939_session *session,
        }
 
        j1939_session_list_unlock(session->priv);
+
+       if (!session->sk)
+               j1939_sk_errqueue(session, J1939_ERRQUEUE_RX_ABORT);
 }
 
 static enum hrtimer_restart j1939_tp_txtimer(struct hrtimer *hrtimer)
@@ -1253,6 +1257,9 @@ static enum hrtimer_restart j1939_tp_rxtimer(struct hrtimer *hrtimer)
                        __j1939_session_cancel(session, J1939_XTP_ABORT_TIMEOUT);
                }
                j1939_session_list_unlock(session->priv);
+
+               if (!session->sk)
+                       j1939_sk_errqueue(session, J1939_ERRQUEUE_RX_ABORT);
        }
 
        j1939_session_put(session);
index 253584777101f2e6af3fc30107516f1e1197f8d3..1488f700bf819a9ee0b8cb59cdfa501075b2e74a 100644 (file)
@@ -3199,6 +3199,7 @@ static u16 skb_tx_hash(const struct net_device *dev,
        }
 
        if (skb_rx_queue_recorded(skb)) {
+               DEBUG_NET_WARN_ON_ONCE(qcount == 0);
                hash = skb_get_rx_queue(skb);
                if (hash >= qoffset)
                        hash -= qoffset;
@@ -10846,7 +10847,7 @@ void unregister_netdevice_many_notify(struct list_head *head,
                    dev->rtnl_link_state == RTNL_LINK_INITIALIZED)
                        skb = rtmsg_ifinfo_build_skb(RTM_DELLINK, dev, ~0U, 0,
                                                     GFP_KERNEL, NULL, 0,
-                                                    portid, nlmsg_seq(nlh));
+                                                    portid, nlh);
 
                /*
                 *      Flush the unicast and multicast chains
index 7b69cf882b8efd901be57217013ebb155b616787..3e3598cd49f23e8202c4dd9b8c04edb77d296af7 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/sched/task.h>
 #include <linux/uidgid.h>
 #include <linux/cookie.h>
+#include <linux/proc_fs.h>
 
 #include <net/sock.h>
 #include <net/netlink.h>
@@ -676,21 +677,19 @@ EXPORT_SYMBOL_GPL(get_net_ns);
 
 struct net *get_net_ns_by_fd(int fd)
 {
-       struct file *file;
-       struct ns_common *ns;
-       struct net *net;
+       struct fd f = fdget(fd);
+       struct net *net = ERR_PTR(-EINVAL);
 
-       file = proc_ns_fget(fd);
-       if (IS_ERR(file))
-               return ERR_CAST(file);
+       if (!f.file)
+               return ERR_PTR(-EBADF);
 
-       ns = get_proc_ns(file_inode(file));
-       if (ns->ops == &netns_operations)
-               net = get_net(container_of(ns, struct net, ns));
-       else
-               net = ERR_PTR(-EINVAL);
+       if (proc_ns_file(f.file)) {
+               struct ns_common *ns = get_proc_ns(file_inode(f.file));
+               if (ns->ops == &netns_operations)
+                       net = get_net(container_of(ns, struct net, ns));
+       }
+       fdput(f);
 
-       fput(file);
        return net;
 }
 EXPORT_SYMBOL_GPL(get_net_ns_by_fd);
index 48812ec843f5533eff8e211230752d537e0737d8..3abab70d66ddc8a3342dfe6c3f94f2eff9bb3a79 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: BSD-3-Clause
+// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
 /* Do not edit directly, auto-generated from: */
 /*     Documentation/netlink/specs/netdev.yaml */
 /* YNL-GEN kernel source */
index b16dc7e026bb13425d94f7500868090403b59213..74d74fc23167988996d56107771e90e9a3cc7e0e 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: BSD-3-Clause */
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
 /* Do not edit directly, auto-generated from: */
 /*     Documentation/netlink/specs/netdev.yaml */
 /* YNL-GEN kernel header */
index a089b704b986d78692b3c2a202a6c4f542716bf6..e6a739b1afa9e480ce3ca6b2adae43b667ae8cf7 100644 (file)
@@ -137,6 +137,20 @@ static void queue_process(struct work_struct *work)
        }
 }
 
+static int netif_local_xmit_active(struct net_device *dev)
+{
+       int i;
+
+       for (i = 0; i < dev->num_tx_queues; i++) {
+               struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
+
+               if (READ_ONCE(txq->xmit_lock_owner) == smp_processor_id())
+                       return 1;
+       }
+
+       return 0;
+}
+
 static void poll_one_napi(struct napi_struct *napi)
 {
        int work;
@@ -183,7 +197,10 @@ void netpoll_poll_dev(struct net_device *dev)
        if (!ni || down_trylock(&ni->dev_lock))
                return;
 
-       if (!netif_running(dev)) {
+       /* Some drivers will take the same locks in poll and xmit,
+        * we can't poll if local CPU is already in xmit.
+        */
+       if (!netif_running(dev) || netif_local_xmit_active(dev)) {
                up(&ni->dev_lock);
                return;
        }
index 5d8eb57867a96fa1730fcafd95f0801fbfc76188..6e44e92ebdf5dc6aaa91b32c3c439b15044024ef 100644 (file)
@@ -3972,16 +3972,23 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
 struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev,
                                       unsigned int change,
                                       u32 event, gfp_t flags, int *new_nsid,
-                                      int new_ifindex, u32 portid, u32 seq)
+                                      int new_ifindex, u32 portid,
+                                      const struct nlmsghdr *nlh)
 {
        struct net *net = dev_net(dev);
        struct sk_buff *skb;
        int err = -ENOBUFS;
+       u32 seq = 0;
 
        skb = nlmsg_new(if_nlmsg_size(dev, 0), flags);
        if (skb == NULL)
                goto errout;
 
+       if (nlmsg_report(nlh))
+               seq = nlmsg_seq(nlh);
+       else
+               portid = 0;
+
        err = rtnl_fill_ifinfo(skb, dev, dev_net(dev),
                               type, portid, seq, change, 0, 0, event,
                               new_nsid, new_ifindex, -1, flags);
@@ -4017,7 +4024,7 @@ static void rtmsg_ifinfo_event(int type, struct net_device *dev,
                return;
 
        skb = rtmsg_ifinfo_build_skb(type, dev, change, event, flags, new_nsid,
-                                    new_ifindex, portid, nlmsg_seq(nlh));
+                                    new_ifindex, portid, nlh);
        if (skb)
                rtmsg_ifinfo_send(skb, dev, flags, portid, nlh);
 }
index eb7d33b41e7107b07e4d8af7abf474b22255a9cd..4c0879798eb8a830abf748bdada7790d06154f7a 100644 (file)
@@ -517,18 +517,16 @@ static void *kmalloc_reserve(unsigned int *size, gfp_t flags, int node,
 #ifdef HAVE_SKB_SMALL_HEAD_CACHE
        if (obj_size <= SKB_SMALL_HEAD_CACHE_SIZE &&
            !(flags & KMALLOC_NOT_NORMAL_BITS)) {
-
-               /* skb_small_head_cache has non power of two size,
-                * likely forcing SLUB to use order-3 pages.
-                * We deliberately attempt a NOMEMALLOC allocation only.
-                */
                obj = kmem_cache_alloc_node(skb_small_head_cache,
                                flags | __GFP_NOMEMALLOC | __GFP_NOWARN,
                                node);
-               if (obj) {
-                       *size = SKB_SMALL_HEAD_CACHE_SIZE;
+               *size = SKB_SMALL_HEAD_CACHE_SIZE;
+               if (obj || !(gfp_pfmemalloc_allowed(flags)))
                        goto out;
-               }
+               /* Try again but now we are using pfmemalloc reserves */
+               ret_pfmemalloc = true;
+               obj = kmem_cache_alloc_node(skb_small_head_cache, flags, node);
+               goto out;
        }
 #endif
        *size = obj_size = kmalloc_size_roundup(obj_size);
@@ -2082,6 +2080,7 @@ struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom)
 }
 EXPORT_SYMBOL(skb_realloc_headroom);
 
+/* Note: We plan to rework this in linux-6.4 */
 int __skb_unclone_keeptruesize(struct sk_buff *skb, gfp_t pri)
 {
        unsigned int saved_end_offset, saved_truesize;
@@ -2100,6 +2099,22 @@ int __skb_unclone_keeptruesize(struct sk_buff *skb, gfp_t pri)
        if (likely(skb_end_offset(skb) == saved_end_offset))
                return 0;
 
+#ifdef HAVE_SKB_SMALL_HEAD_CACHE
+       /* We can not change skb->end if the original or new value
+        * is SKB_SMALL_HEAD_HEADROOM, as it might break skb_kfree_head().
+        */
+       if (saved_end_offset == SKB_SMALL_HEAD_HEADROOM ||
+           skb_end_offset(skb) == SKB_SMALL_HEAD_HEADROOM) {
+               /* We think this path should not be taken.
+                * Add a temporary trace to warn us just in case.
+                */
+               pr_err_once("__skb_unclone_keeptruesize() skb_end_offset() %u -> %u\n",
+                           saved_end_offset, skb_end_offset(skb));
+               WARN_ON_ONCE(1);
+               return 0;
+       }
+#endif
+
        shinfo = skb_shinfo(skb);
 
        /* We are about to change back skb->end,
@@ -5584,18 +5599,18 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
        if (skb_cloned(to))
                return false;
 
-       /* In general, avoid mixing slab allocated and page_pool allocated
-        * pages within the same SKB. However when @to is not pp_recycle and
-        * @from is cloned, we can transition frag pages from page_pool to
-        * reference counted.
-        *
-        * On the other hand, don't allow coalescing two pp_recycle SKBs if
-        * @from is cloned, in case the SKB is using page_pool fragment
+       /* In general, avoid mixing page_pool and non-page_pool allocated
+        * pages within the same SKB. Additionally avoid dealing with clones
+        * with page_pool pages, in case the SKB is using page_pool fragment
         * references (PP_FLAG_PAGE_FRAG). Since we only take full page
         * references for cloned SKBs at the moment that would result in
         * inconsistent reference counts.
+        * In theory we could take full references if @from is cloned and
+        * !@to->pp_recycle but its tricky (due to potential race with
+        * the clone disappearing) and rare, so not worth dealing with.
         */
-       if (to->pp_recycle != (from->pp_recycle && !skb_cloned(from)))
+       if (to->pp_recycle != from->pp_recycle ||
+           (from->pp_recycle && skb_cloned(from)))
                return false;
 
        if (len <= skb_tailroom(to)) {
index 341c565dbc262fcece1c5b410609d910a68edcb0..c258887953905c340ad6deab8b66cbf45ecbf178 100644 (file)
@@ -2818,7 +2818,8 @@ static void sk_enter_memory_pressure(struct sock *sk)
 static void sk_leave_memory_pressure(struct sock *sk)
 {
        if (sk->sk_prot->leave_memory_pressure) {
-               sk->sk_prot->leave_memory_pressure(sk);
+               INDIRECT_CALL_INET_1(sk->sk_prot->leave_memory_pressure,
+                                    tcp_leave_memory_pressure, sk);
        } else {
                unsigned long *memory_pressure = sk->sk_prot->memory_pressure;
 
index 74842b453407015a735118f4a06a77be47bcfafb..782273bb93c23c10b733dd6a1100f309acdb67f9 100644 (file)
@@ -177,7 +177,7 @@ static int rps_sock_flow_sysctl(struct ctl_table *table, int write,
                        if (orig_sock_table) {
                                static_branch_dec(&rps_needed);
                                static_branch_dec(&rfs_needed);
-                               kvfree_rcu(orig_sock_table);
+                               kvfree_rcu_mightsleep(orig_sock_table);
                        }
                }
        }
@@ -215,7 +215,7 @@ static int flow_limit_cpu_sysctl(struct ctl_table *table, int write,
                                     lockdep_is_held(&flow_limit_update_mutex));
                        if (cur && !cpumask_test_cpu(i, mask)) {
                                RCU_INIT_POINTER(sd->flow_limit, NULL);
-                               kfree_rcu(cur);
+                               kfree_rcu_mightsleep(cur);
                        } else if (!cur && cpumask_test_cpu(i, mask)) {
                                cur = kzalloc_node(len, GFP_KERNEL,
                                                   cpu_to_node(i));
index 8c92fc55331771495b7c11fe5b4e660d8c11a11c..fb85aca819619b344bdbb74f72e1e0a0d4c3e5b2 100644 (file)
@@ -720,7 +720,10 @@ __diag_ignore_all("-Wmissing-prototypes",
  * @ctx: XDP context pointer.
  * @timestamp: Return value pointer.
  *
- * Returns 0 on success or ``-errno`` on error.
+ * Return:
+ * * Returns 0 on success or ``-errno`` on error.
+ * * ``-EOPNOTSUPP`` : means device driver does not implement kfunc
+ * * ``-ENODATA``    : means no RX-timestamp available for this frame
  */
 __bpf_kfunc int bpf_xdp_metadata_rx_timestamp(const struct xdp_md *ctx, u64 *timestamp)
 {
@@ -731,10 +734,21 @@ __bpf_kfunc int bpf_xdp_metadata_rx_timestamp(const struct xdp_md *ctx, u64 *tim
  * bpf_xdp_metadata_rx_hash - Read XDP frame RX hash.
  * @ctx: XDP context pointer.
  * @hash: Return value pointer.
+ * @rss_type: Return value pointer for RSS type.
  *
- * Returns 0 on success or ``-errno`` on error.
+ * The RSS hash type (@rss_type) specifies what portion of packet headers NIC
+ * hardware used when calculating RSS hash value.  The RSS type can be decoded
+ * via &enum xdp_rss_hash_type either matching on individual L3/L4 bits
+ * ``XDP_RSS_L*`` or by combined traditional *RSS Hashing Types*
+ * ``XDP_RSS_TYPE_L*``.
+ *
+ * Return:
+ * * Returns 0 on success or ``-errno`` on error.
+ * * ``-EOPNOTSUPP`` : means device driver doesn't implement kfunc
+ * * ``-ENODATA``    : means no RX-hash available for this frame
  */
-__bpf_kfunc int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, u32 *hash)
+__bpf_kfunc int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, u32 *hash,
+                                        enum xdp_rss_hash_type *rss_type)
 {
        return -EOPNOTSUPP;
 }
@@ -774,20 +788,34 @@ static int __init xdp_metadata_init(void)
 }
 late_initcall(xdp_metadata_init);
 
+void xdp_set_features_flag(struct net_device *dev, xdp_features_t val)
+{
+       val &= NETDEV_XDP_ACT_MASK;
+       if (dev->xdp_features == val)
+               return;
+
+       dev->xdp_features = val;
+
+       if (dev->reg_state == NETREG_REGISTERED)
+               call_netdevice_notifiers(NETDEV_XDP_FEAT_CHANGE, dev);
+}
+EXPORT_SYMBOL_GPL(xdp_set_features_flag);
+
 void xdp_features_set_redirect_target(struct net_device *dev, bool support_sg)
 {
-       dev->xdp_features |= NETDEV_XDP_ACT_NDO_XMIT;
-       if (support_sg)
-               dev->xdp_features |= NETDEV_XDP_ACT_NDO_XMIT_SG;
+       xdp_features_t val = (dev->xdp_features | NETDEV_XDP_ACT_NDO_XMIT);
 
-       call_netdevice_notifiers(NETDEV_XDP_FEAT_CHANGE, dev);
+       if (support_sg)
+               val |= NETDEV_XDP_ACT_NDO_XMIT_SG;
+       xdp_set_features_flag(dev, val);
 }
 EXPORT_SYMBOL_GPL(xdp_features_set_redirect_target);
 
 void xdp_features_clear_redirect_target(struct net_device *dev)
 {
-       dev->xdp_features &= ~(NETDEV_XDP_ACT_NDO_XMIT |
-                              NETDEV_XDP_ACT_NDO_XMIT_SG);
-       call_netdevice_notifiers(NETDEV_XDP_FEAT_CHANGE, dev);
+       xdp_features_t val = dev->xdp_features;
+
+       val &= ~(NETDEV_XDP_ACT_NDO_XMIT | NETDEV_XDP_ACT_NDO_XMIT_SG);
+       xdp_set_features_flag(dev, val);
 }
 EXPORT_SYMBOL_GPL(xdp_features_clear_redirect_target);
index 6957971c2db23a0cd68cdf74830615d0bc7760a4..165bb2cb84316092261f67dcdd1efdebd78ca199 100644 (file)
@@ -57,6 +57,12 @@ struct dsa_standalone_event_work {
        u16 vid;
 };
 
+struct dsa_host_vlan_rx_filtering_ctx {
+       struct net_device *dev;
+       const unsigned char *addr;
+       enum dsa_standalone_event event;
+};
+
 static bool dsa_switch_supports_uc_filtering(struct dsa_switch *ds)
 {
        return ds->ops->port_fdb_add && ds->ops->port_fdb_del &&
@@ -155,18 +161,37 @@ static int dsa_slave_schedule_standalone_work(struct net_device *dev,
        return 0;
 }
 
+static int dsa_slave_host_vlan_rx_filtering(struct net_device *vdev, int vid,
+                                           void *arg)
+{
+       struct dsa_host_vlan_rx_filtering_ctx *ctx = arg;
+
+       return dsa_slave_schedule_standalone_work(ctx->dev, ctx->event,
+                                                 ctx->addr, vid);
+}
+
 static int dsa_slave_sync_uc(struct net_device *dev,
                             const unsigned char *addr)
 {
        struct net_device *master = dsa_slave_to_master(dev);
        struct dsa_port *dp = dsa_slave_to_port(dev);
+       struct dsa_host_vlan_rx_filtering_ctx ctx = {
+               .dev = dev,
+               .addr = addr,
+               .event = DSA_UC_ADD,
+       };
+       int err;
 
        dev_uc_add(master, addr);
 
        if (!dsa_switch_supports_uc_filtering(dp->ds))
                return 0;
 
-       return dsa_slave_schedule_standalone_work(dev, DSA_UC_ADD, addr, 0);
+       err = dsa_slave_schedule_standalone_work(dev, DSA_UC_ADD, addr, 0);
+       if (err)
+               return err;
+
+       return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx);
 }
 
 static int dsa_slave_unsync_uc(struct net_device *dev,
@@ -174,13 +199,23 @@ static int dsa_slave_unsync_uc(struct net_device *dev,
 {
        struct net_device *master = dsa_slave_to_master(dev);
        struct dsa_port *dp = dsa_slave_to_port(dev);
+       struct dsa_host_vlan_rx_filtering_ctx ctx = {
+               .dev = dev,
+               .addr = addr,
+               .event = DSA_UC_DEL,
+       };
+       int err;
 
        dev_uc_del(master, addr);
 
        if (!dsa_switch_supports_uc_filtering(dp->ds))
                return 0;
 
-       return dsa_slave_schedule_standalone_work(dev, DSA_UC_DEL, addr, 0);
+       err = dsa_slave_schedule_standalone_work(dev, DSA_UC_DEL, addr, 0);
+       if (err)
+               return err;
+
+       return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx);
 }
 
 static int dsa_slave_sync_mc(struct net_device *dev,
@@ -188,13 +223,23 @@ static int dsa_slave_sync_mc(struct net_device *dev,
 {
        struct net_device *master = dsa_slave_to_master(dev);
        struct dsa_port *dp = dsa_slave_to_port(dev);
+       struct dsa_host_vlan_rx_filtering_ctx ctx = {
+               .dev = dev,
+               .addr = addr,
+               .event = DSA_MC_ADD,
+       };
+       int err;
 
        dev_mc_add(master, addr);
 
        if (!dsa_switch_supports_mc_filtering(dp->ds))
                return 0;
 
-       return dsa_slave_schedule_standalone_work(dev, DSA_MC_ADD, addr, 0);
+       err = dsa_slave_schedule_standalone_work(dev, DSA_MC_ADD, addr, 0);
+       if (err)
+               return err;
+
+       return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx);
 }
 
 static int dsa_slave_unsync_mc(struct net_device *dev,
@@ -202,13 +247,23 @@ static int dsa_slave_unsync_mc(struct net_device *dev,
 {
        struct net_device *master = dsa_slave_to_master(dev);
        struct dsa_port *dp = dsa_slave_to_port(dev);
+       struct dsa_host_vlan_rx_filtering_ctx ctx = {
+               .dev = dev,
+               .addr = addr,
+               .event = DSA_MC_DEL,
+       };
+       int err;
 
        dev_mc_del(master, addr);
 
        if (!dsa_switch_supports_mc_filtering(dp->ds))
                return 0;
 
-       return dsa_slave_schedule_standalone_work(dev, DSA_MC_DEL, addr, 0);
+       err = dsa_slave_schedule_standalone_work(dev, DSA_MC_DEL, addr, 0);
+       if (err)
+               return err;
+
+       return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx);
 }
 
 void dsa_slave_sync_ha(struct net_device *dev)
@@ -1702,6 +1757,8 @@ static int dsa_slave_vlan_rx_add_vid(struct net_device *dev, __be16 proto,
                .flags = 0,
        };
        struct netlink_ext_ack extack = {0};
+       struct dsa_switch *ds = dp->ds;
+       struct netdev_hw_addr *ha;
        int ret;
 
        /* User port... */
@@ -1721,6 +1778,30 @@ static int dsa_slave_vlan_rx_add_vid(struct net_device *dev, __be16 proto,
                return ret;
        }
 
+       if (!dsa_switch_supports_uc_filtering(ds) &&
+           !dsa_switch_supports_mc_filtering(ds))
+               return 0;
+
+       netif_addr_lock_bh(dev);
+
+       if (dsa_switch_supports_mc_filtering(ds)) {
+               netdev_for_each_synced_mc_addr(ha, dev) {
+                       dsa_slave_schedule_standalone_work(dev, DSA_MC_ADD,
+                                                          ha->addr, vid);
+               }
+       }
+
+       if (dsa_switch_supports_uc_filtering(ds)) {
+               netdev_for_each_synced_uc_addr(ha, dev) {
+                       dsa_slave_schedule_standalone_work(dev, DSA_UC_ADD,
+                                                          ha->addr, vid);
+               }
+       }
+
+       netif_addr_unlock_bh(dev);
+
+       dsa_flush_workqueue();
+
        return 0;
 }
 
@@ -1733,13 +1814,43 @@ static int dsa_slave_vlan_rx_kill_vid(struct net_device *dev, __be16 proto,
                /* This API only allows programming tagged, non-PVID VIDs */
                .flags = 0,
        };
+       struct dsa_switch *ds = dp->ds;
+       struct netdev_hw_addr *ha;
        int err;
 
        err = dsa_port_vlan_del(dp, &vlan);
        if (err)
                return err;
 
-       return dsa_port_host_vlan_del(dp, &vlan);
+       err = dsa_port_host_vlan_del(dp, &vlan);
+       if (err)
+               return err;
+
+       if (!dsa_switch_supports_uc_filtering(ds) &&
+           !dsa_switch_supports_mc_filtering(ds))
+               return 0;
+
+       netif_addr_lock_bh(dev);
+
+       if (dsa_switch_supports_mc_filtering(ds)) {
+               netdev_for_each_synced_mc_addr(ha, dev) {
+                       dsa_slave_schedule_standalone_work(dev, DSA_MC_DEL,
+                                                          ha->addr, vid);
+               }
+       }
+
+       if (dsa_switch_supports_uc_filtering(ds)) {
+               netdev_for_each_synced_uc_addr(ha, dev) {
+                       dsa_slave_schedule_standalone_work(dev, DSA_UC_DEL,
+                                                          ha->addr, vid);
+               }
+       }
+
+       netif_addr_unlock_bh(dev);
+
+       dsa_flush_workqueue();
+
+       return 0;
 }
 
 static int dsa_slave_restore_vlan(struct net_device *vdev, int vid, void *arg)
@@ -1933,6 +2044,7 @@ int dsa_slave_change_mtu(struct net_device *dev, int new_mtu)
        int new_master_mtu;
        int old_master_mtu;
        int mtu_limit;
+       int overhead;
        int cpu_mtu;
        int err;
 
@@ -1961,9 +2073,10 @@ int dsa_slave_change_mtu(struct net_device *dev, int new_mtu)
                        largest_mtu = slave_mtu;
        }
 
-       mtu_limit = min_t(int, master->max_mtu, dev->max_mtu);
+       overhead = dsa_tag_protocol_overhead(cpu_dp->tag_ops);
+       mtu_limit = min_t(int, master->max_mtu, dev->max_mtu + overhead);
        old_master_mtu = master->mtu;
-       new_master_mtu = largest_mtu + dsa_tag_protocol_overhead(cpu_dp->tag_ops);
+       new_master_mtu = largest_mtu + overhead;
        if (new_master_mtu > mtu_limit)
                return -ERANGE;
 
@@ -1998,8 +2111,7 @@ int dsa_slave_change_mtu(struct net_device *dev, int new_mtu)
 
 out_port_failed:
        if (new_master_mtu != old_master_mtu)
-               dsa_port_mtu_change(cpu_dp, old_master_mtu -
-                                   dsa_tag_protocol_overhead(cpu_dp->tag_ops));
+               dsa_port_mtu_change(cpu_dp, old_master_mtu - overhead);
 out_cpu_failed:
        if (new_master_mtu != old_master_mtu)
                dev_set_mtu(master, old_master_mtu);
index b2fba1a003ce369a275b7fdbb08952d7165804a5..5105a5ff58fa20156099977a64f81edc98f9c710 100644 (file)
@@ -114,7 +114,7 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
                skb = nskb;
        }
 
-       dev_sw_netstats_rx_add(skb->dev, skb->len);
+       dev_sw_netstats_rx_add(skb->dev, skb->len + ETH_HLEN);
 
        if (dsa_skb_defer_rx_timestamp(p, skb))
                return 0;
index 10239daa57454360b7f867a3bc9771f204f1bbe6..cacdafb41200e5f941dff2e259a57720fb916f43 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/dsa/brcm.h>
 #include <linux/etherdevice.h>
+#include <linux/if_vlan.h>
 #include <linux/list.h>
 #include <linux/slab.h>
 
@@ -252,6 +253,7 @@ static struct sk_buff *brcm_leg_tag_xmit(struct sk_buff *skb,
 static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
                                        struct net_device *dev)
 {
+       int len = BRCM_LEG_TAG_LEN;
        int source_port;
        u8 *brcm_tag;
 
@@ -266,12 +268,16 @@ static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
        if (!skb->dev)
                return NULL;
 
+       /* VLAN tag is added by BCM63xx internal switch */
+       if (netdev_uses_dsa(skb->dev))
+               len += VLAN_HLEN;
+
        /* Remove Broadcom tag and update checksum */
-       skb_pull_rcsum(skb, BRCM_LEG_TAG_LEN);
+       skb_pull_rcsum(skb, len);
 
        dsa_default_offload_fwd_mark(skb);
 
-       dsa_strip_etype_header(skb, BRCM_LEG_TAG_LEN);
+       dsa_strip_etype_header(skb, len);
 
        return skb;
 }
index fab66c169b9fa92f2f23b6d3654076f0d0457377..20165e07ef901b20e274487b61d5684d23c60ee7 100644 (file)
@@ -270,11 +270,12 @@ static int ethnl_update_linkmodes(struct genl_info *info, struct nlattr **tb,
                                            "lanes configuration not supported by device");
                        return -EOPNOTSUPP;
                }
-       } else if (!lsettings->autoneg) {
-               /* If autoneg is off and lanes parameter is not passed from user,
-                * set the lanes parameter to 0.
+       } else if (!lsettings->autoneg && ksettings->lanes) {
+               /* If autoneg is off and lanes parameter is not passed from user but
+                * it was defined previously then set the lanes parameter to 0.
                 */
                ksettings->lanes = 0;
+               *mod = true;
        }
 
        ret = ethnl_update_bitset(ksettings->link_modes.advertising,
index 00db74d96583d0f7b33b29697037b979f052c1d5..b77f1189d19d1ff5dc76f4a7345efc7a65918399 100644 (file)
@@ -415,7 +415,7 @@ void hsr_addr_subst_dest(struct hsr_node *node_src, struct sk_buff *skb,
        node_dst = find_node_by_addr_A(&port->hsr->node_db,
                                       eth_hdr(skb)->h_dest);
        if (!node_dst) {
-               if (net_ratelimit())
+               if (port->hsr->prot_version != PRP_V1 && net_ratelimit())
                        netdev_err(skb->dev, "%s: Unknown node\n", __func__);
                return;
        }
index 2215f576ee3788f74ea175b046d05d285bac752d..832e3c50816c47a23d16b59107e5e9be9a5163d5 100644 (file)
@@ -1412,7 +1412,7 @@ static int nl802154_trigger_scan(struct sk_buff *skb, struct genl_info *info)
                return -EOPNOTSUPP;
        }
 
-       if (!nla_get_u8(info->attrs[NL802154_ATTR_SCAN_TYPE])) {
+       if (!info->attrs[NL802154_ATTR_SCAN_TYPE]) {
                NL_SET_ERR_MSG(info->extack, "Malformed request, missing scan type");
                return -EINVAL;
        }
@@ -2488,8 +2488,7 @@ static int nl802154_del_llsec_seclevel(struct sk_buff *skb,
        if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
                return -EOPNOTSUPP;
 
-       if (!info->attrs[NL802154_ATTR_SEC_LEVEL] ||
-           llsec_parse_seclevel(info->attrs[NL802154_ATTR_SEC_LEVEL],
+       if (llsec_parse_seclevel(info->attrs[NL802154_ATTR_SEC_LEVEL],
                                 &sl) < 0)
                return -EINVAL;
 
index b5736ef16ed2d54d1b15be79de35766d36bd12b3..390f4be7f7bec20f33aa80e9bf12d5e2f3760562 100644 (file)
@@ -576,6 +576,9 @@ static int rtentry_to_fib_config(struct net *net, int cmd, struct rtentry *rt,
                        cfg->fc_scope = RT_SCOPE_UNIVERSE;
        }
 
+       if (!cfg->fc_table)
+               cfg->fc_table = RT_TABLE_MAIN;
+
        if (cmd == SIOCDELRT)
                return 0;
 
index 6c3820f41dd5de44bae5f2d59b69639167998c58..6c37c4f98ccab403e29740f41003b3696df7250f 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: BSD-3-Clause
+// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
 /* Do not edit directly, auto-generated from: */
 /*     Documentation/netlink/specs/fou.yaml */
 /* YNL-GEN kernel source */
index b7a68121ce6f79061e73462e02f706195d78988b..dbd0780a5d34c3963681c1d7f0aaf579fc186e5e 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: BSD-3-Clause */
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
 /* Do not edit directly, auto-generated from: */
 /*     Documentation/netlink/specs/fou.yaml */
 /* YNL-GEN kernel header */
index 8cebb476b3ab1833b4efe073efc57dbdfeffd21d..b8607763d113a5878181ffd17a36a3ea4261ca55 100644 (file)
@@ -749,6 +749,11 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info,
                room = 576;
        room -= sizeof(struct iphdr) + icmp_param.replyopts.opt.opt.optlen;
        room -= sizeof(struct icmphdr);
+       /* Guard against tiny mtu. We need to include at least one
+        * IP network header for this message to make any sense.
+        */
+       if (room <= (int)sizeof(struct iphdr))
+               goto ende;
 
        icmp_param.data_len = skb_in->len - icmp_param.offset;
        if (icmp_param.data_len > room)
index e41fdc38ce196fa3ba7c8ed5e6a0aa20c7e30362..6edae3886885565985f9f45bae65ef2f4498f22f 100644 (file)
@@ -828,8 +828,14 @@ bool inet_bind2_bucket_match_addr_any(const struct inet_bind2_bucket *tb, const
 #if IS_ENABLED(CONFIG_IPV6)
        struct in6_addr addr_any = {};
 
-       if (sk->sk_family != tb->family)
+       if (sk->sk_family != tb->family) {
+               if (sk->sk_family == AF_INET)
+                       return net_eq(ib2_net(tb), net) && tb->port == port &&
+                               tb->l3mdev == l3mdev &&
+                               ipv6_addr_equal(&tb->v6_rcv_saddr, &addr_any);
+
                return false;
+       }
 
        if (sk->sk_family == AF_INET6)
                return net_eq(ib2_net(tb), net) && tb->port == port &&
index ffff46cdcb58f9b5b4c210a548d685d8f0c7716a..e55a202649608f6f3c814e143581d631ce0467e6 100644 (file)
@@ -552,7 +552,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev)
                truncate = true;
        }
 
-       nhoff = skb_network_header(skb) - skb_mac_header(skb);
+       nhoff = skb_network_offset(skb);
        if (skb->protocol == htons(ETH_P_IP) &&
            (ntohs(ip_hdr(skb)->tot_len) > skb->len - nhoff))
                truncate = true;
@@ -561,7 +561,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev)
                int thoff;
 
                if (skb_transport_header_was_set(skb))
-                       thoff = skb_transport_header(skb) - skb_mac_header(skb);
+                       thoff = skb_transport_offset(skb);
                else
                        thoff = nhoff + sizeof(struct ipv6hdr);
                if (ntohs(ipv6_hdr(skb)->payload_len) > skb->len - thoff)
index de90b09dfe78fc4510985dd436c017d3c46f054c..2541083d49ad66fcc6c4485abb4bd96c50dc0989 100644 (file)
@@ -614,10 +614,10 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
        }
 
        headroom += LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len;
-       if (headroom > dev->needed_headroom)
-               dev->needed_headroom = headroom;
+       if (headroom > READ_ONCE(dev->needed_headroom))
+               WRITE_ONCE(dev->needed_headroom, headroom);
 
-       if (skb_cow_head(skb, dev->needed_headroom)) {
+       if (skb_cow_head(skb, READ_ONCE(dev->needed_headroom))) {
                ip_rt_put(rt);
                goto tx_dropped;
        }
@@ -800,10 +800,10 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
 
        max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr)
                        + rt->dst.header_len + ip_encap_hlen(&tunnel->encap);
-       if (max_headroom > dev->needed_headroom)
-               dev->needed_headroom = max_headroom;
+       if (max_headroom > READ_ONCE(dev->needed_headroom))
+               WRITE_ONCE(dev->needed_headroom, max_headroom);
 
-       if (skb_cow_head(skb, dev->needed_headroom)) {
+       if (skb_cow_head(skb, READ_ONCE(dev->needed_headroom))) {
                ip_rt_put(rt);
                DEV_STATS_INC(dev, tx_dropped);
                kfree_skb(skb);
index b22b2c745c76c317dad4f4d65d6c5ac48624d24d..69e331799604304078367011040b0dea69fcacf0 100644 (file)
@@ -38,7 +38,7 @@ nf_tproxy_handle_time_wait4(struct net *net, struct sk_buff *skb,
                                            hp->source, lport ? lport : hp->dest,
                                            skb->dev, NF_TPROXY_LOOKUP_LISTENER);
                if (sk2) {
-                       inet_twsk_deschedule_put(inet_twsk(sk));
+                       nf_tproxy_twsk_deschedule_put(inet_twsk(sk));
                        sk = sk2;
                }
        }
index 409ec2a1f95b0657dc12734f715d28d441894370..5178a3f3cb5378befbfef34442e6934a1b6ffc22 100644 (file)
@@ -1089,13 +1089,13 @@ static struct sock *ping_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 void *ping_seq_start(struct seq_file *seq, loff_t *pos, sa_family_t family)
-       __acquires(RCU)
+       __acquires(ping_table.lock)
 {
        struct ping_iter_state *state = seq->private;
        state->bucket = 0;
        state->family = family;
 
-       rcu_read_lock();
+       spin_lock(&ping_table.lock);
 
        return *pos ? ping_get_idx(seq, *pos-1) : SEQ_START_TOKEN;
 }
@@ -1121,9 +1121,9 @@ void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 EXPORT_SYMBOL_GPL(ping_seq_next);
 
 void ping_seq_stop(struct seq_file *seq, void *v)
-       __releases(RCU)
+       __releases(ping_table.lock)
 {
-       rcu_read_unlock();
+       spin_unlock(&ping_table.lock);
 }
 EXPORT_SYMBOL_GPL(ping_seq_stop);
 
index 94df935ee0c5a83a4b1393653b79ac6060b4f12a..8088a5011e7df0b49b785390b50ed3ce3cd3504e 100644 (file)
@@ -91,12 +91,12 @@ EXPORT_SYMBOL_GPL(raw_v4_hashinfo);
 int raw_hash_sk(struct sock *sk)
 {
        struct raw_hashinfo *h = sk->sk_prot->h.raw_hash;
-       struct hlist_nulls_head *hlist;
+       struct hlist_head *hlist;
 
        hlist = &h->ht[raw_hashfunc(sock_net(sk), inet_sk(sk)->inet_num)];
 
        spin_lock(&h->lock);
-       __sk_nulls_add_node_rcu(sk, hlist);
+       sk_add_node_rcu(sk, hlist);
        sock_set_flag(sk, SOCK_RCU_FREE);
        spin_unlock(&h->lock);
        sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
@@ -110,7 +110,7 @@ void raw_unhash_sk(struct sock *sk)
        struct raw_hashinfo *h = sk->sk_prot->h.raw_hash;
 
        spin_lock(&h->lock);
-       if (__sk_nulls_del_node_init_rcu(sk))
+       if (sk_del_node_init_rcu(sk))
                sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
        spin_unlock(&h->lock);
 }
@@ -163,16 +163,15 @@ static int icmp_filter(const struct sock *sk, const struct sk_buff *skb)
 static int raw_v4_input(struct net *net, struct sk_buff *skb,
                        const struct iphdr *iph, int hash)
 {
-       struct hlist_nulls_head *hlist;
-       struct hlist_nulls_node *hnode;
        int sdif = inet_sdif(skb);
+       struct hlist_head *hlist;
        int dif = inet_iif(skb);
        int delivered = 0;
        struct sock *sk;
 
        hlist = &raw_v4_hashinfo.ht[hash];
        rcu_read_lock();
-       sk_nulls_for_each(sk, hnode, hlist) {
+       sk_for_each_rcu(sk, hlist) {
                if (!raw_v4_match(net, sk, iph->protocol,
                                  iph->saddr, iph->daddr, dif, sdif))
                        continue;
@@ -264,10 +263,9 @@ static void raw_err(struct sock *sk, struct sk_buff *skb, u32 info)
 void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
 {
        struct net *net = dev_net(skb->dev);
-       struct hlist_nulls_head *hlist;
-       struct hlist_nulls_node *hnode;
        int dif = skb->dev->ifindex;
        int sdif = inet_sdif(skb);
+       struct hlist_head *hlist;
        const struct iphdr *iph;
        struct sock *sk;
        int hash;
@@ -276,7 +274,7 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
        hlist = &raw_v4_hashinfo.ht[hash];
 
        rcu_read_lock();
-       sk_nulls_for_each(sk, hnode, hlist) {
+       sk_for_each_rcu(sk, hlist) {
                iph = (const struct iphdr *)skb->data;
                if (!raw_v4_match(net, sk, iph->protocol,
                                  iph->daddr, iph->saddr, dif, sdif))
@@ -950,14 +948,13 @@ static struct sock *raw_get_first(struct seq_file *seq, int bucket)
 {
        struct raw_hashinfo *h = pde_data(file_inode(seq->file));
        struct raw_iter_state *state = raw_seq_private(seq);
-       struct hlist_nulls_head *hlist;
-       struct hlist_nulls_node *hnode;
+       struct hlist_head *hlist;
        struct sock *sk;
 
        for (state->bucket = bucket; state->bucket < RAW_HTABLE_SIZE;
                        ++state->bucket) {
                hlist = &h->ht[state->bucket];
-               sk_nulls_for_each(sk, hnode, hlist) {
+               sk_for_each(sk, hlist) {
                        if (sock_net(sk) == seq_file_net(seq))
                                return sk;
                }
@@ -970,7 +967,7 @@ static struct sock *raw_get_next(struct seq_file *seq, struct sock *sk)
        struct raw_iter_state *state = raw_seq_private(seq);
 
        do {
-               sk = sk_nulls_next(sk);
+               sk = sk_next(sk);
        } while (sk && sock_net(sk) != seq_file_net(seq));
 
        if (!sk)
@@ -989,9 +986,12 @@ static struct sock *raw_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 void *raw_seq_start(struct seq_file *seq, loff_t *pos)
-       __acquires(RCU)
+       __acquires(&h->lock)
 {
-       rcu_read_lock();
+       struct raw_hashinfo *h = pde_data(file_inode(seq->file));
+
+       spin_lock(&h->lock);
+
        return *pos ? raw_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
 }
 EXPORT_SYMBOL_GPL(raw_seq_start);
@@ -1010,9 +1010,11 @@ void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 EXPORT_SYMBOL_GPL(raw_seq_next);
 
 void raw_seq_stop(struct seq_file *seq, void *v)
-       __releases(RCU)
+       __releases(&h->lock)
 {
-       rcu_read_unlock();
+       struct raw_hashinfo *h = pde_data(file_inode(seq->file));
+
+       spin_unlock(&h->lock);
 }
 EXPORT_SYMBOL_GPL(raw_seq_stop);
 
index 999321834b94a8f7f2a4996575b7cfaafb6fa2b7..da3591a66a169f5a790676c01111b430d93d72ab 100644 (file)
@@ -57,8 +57,7 @@ static bool raw_lookup(struct net *net, struct sock *sk,
 static struct sock *raw_sock_get(struct net *net, const struct inet_diag_req_v2 *r)
 {
        struct raw_hashinfo *hashinfo = raw_get_hashinfo(r);
-       struct hlist_nulls_head *hlist;
-       struct hlist_nulls_node *hnode;
+       struct hlist_head *hlist;
        struct sock *sk;
        int slot;
 
@@ -68,7 +67,7 @@ static struct sock *raw_sock_get(struct net *net, const struct inet_diag_req_v2
        rcu_read_lock();
        for (slot = 0; slot < RAW_HTABLE_SIZE; slot++) {
                hlist = &hashinfo->ht[slot];
-               sk_nulls_for_each(sk, hnode, hlist) {
+               sk_for_each_rcu(sk, hlist) {
                        if (raw_lookup(net, sk, r)) {
                                /*
                                 * Grab it and keep until we fill
@@ -142,9 +141,8 @@ static void raw_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
        struct raw_hashinfo *hashinfo = raw_get_hashinfo(r);
        struct net *net = sock_net(skb->sk);
        struct inet_diag_dump_data *cb_data;
-       struct hlist_nulls_head *hlist;
-       struct hlist_nulls_node *hnode;
        int num, s_num, slot, s_slot;
+       struct hlist_head *hlist;
        struct sock *sk = NULL;
        struct nlattr *bc;
 
@@ -161,7 +159,7 @@ static void raw_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
                num = 0;
 
                hlist = &hashinfo->ht[slot];
-               sk_nulls_for_each(sk, hnode, hlist) {
+               sk_for_each_rcu(sk, hlist) {
                        struct inet_sock *inet = inet_sk(sk);
 
                        if (!net_eq(sock_net(sk), net))
index 0d0cc4ef2b85a453582d3301f62d7d25d439e592..40fe70fc2015d5ce0a8d2791a714f1324ecb231e 100644 (file)
@@ -25,6 +25,7 @@ static int ip_local_port_range_min[] = { 1, 1 };
 static int ip_local_port_range_max[] = { 65535, 65535 };
 static int tcp_adv_win_scale_min = -31;
 static int tcp_adv_win_scale_max = 31;
+static int tcp_app_win_max = 31;
 static int tcp_min_snd_mss_min = TCP_MIN_SND_MSS;
 static int tcp_min_snd_mss_max = 65535;
 static int ip_privileged_port_min;
@@ -1198,6 +1199,8 @@ static struct ctl_table ipv4_net_table[] = {
                .maxlen         = sizeof(u8),
                .mode           = 0644,
                .proc_handler   = proc_dou8vec_minmax,
+               .extra1         = SYSCTL_ZERO,
+               .extra2         = &tcp_app_win_max,
        },
        {
                .procname       = "tcp_adv_win_scale",
index cf26d65ca3893d5fc1b9c4fdc7d4e85316c1fc76..ebf91751193706ccec1bb9cfac48be28b5e28337 100644 (file)
@@ -186,6 +186,9 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
        if (unlikely(flags & MSG_ERRQUEUE))
                return inet_recv_error(sk, msg, len, addr_len);
 
+       if (!len)
+               return 0;
+
        psock = sk_psock_get(sk);
        if (unlikely(!psock))
                return tcp_recvmsg(sk, msg, len, flags, addr_len);
@@ -244,6 +247,9 @@ static int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
        if (unlikely(flags & MSG_ERRQUEUE))
                return inet_recv_error(sk, msg, len, addr_len);
 
+       if (!len)
+               return 0;
+
        psock = sk_psock_get(sk);
        if (unlikely(!psock))
                return tcp_recvmsg(sk, msg, len, flags, addr_len);
index ea370afa70ed979266dbeea474b034e833b15db4..b9d55277cb858a3a288e1ae800c9f507444f0be1 100644 (file)
@@ -2780,7 +2780,7 @@ static int tcp_prog_seq_show(struct bpf_prog *prog, struct bpf_iter_meta *meta,
 static void bpf_iter_tcp_put_batch(struct bpf_tcp_iter_state *iter)
 {
        while (iter->cur_sk < iter->end_sk)
-               sock_put(iter->batch[iter->cur_sk++]);
+               sock_gen_put(iter->batch[iter->cur_sk++]);
 }
 
 static int bpf_iter_tcp_realloc_batch(struct bpf_tcp_iter_state *iter,
@@ -2941,7 +2941,7 @@ static void *bpf_iter_tcp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
                 * st->bucket.  See tcp_seek_last_pos().
                 */
                st->offset++;
-               sock_put(iter->batch[iter->cur_sk++]);
+               sock_gen_put(iter->batch[iter->cur_sk++]);
        }
 
        if (iter->cur_sk < iter->end_sk)
index 71d01cf3c13eb4bd3d314ef140568d2ffd6a499e..ba839e441450f195012a8d77cb9e5ed956962d2f 100644 (file)
@@ -3605,7 +3605,7 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
        th->window = htons(min(req->rsk_rcv_wnd, 65535U));
        tcp_options_write(th, NULL, &opts);
        th->doff = (tcp_header_size >> 2);
-       __TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS);
+       TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS);
 
 #ifdef CONFIG_TCP_MD5SIG
        /* Okay, we have all we need - do the md5 hash if needed */
index e5dc91d0e0793ce6b203e0a6e4e0ffbd617b6820..0735d820e413f3002bb83fb011d998a9cad1b05c 100644 (file)
@@ -68,6 +68,9 @@ static int udp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
        if (unlikely(flags & MSG_ERRQUEUE))
                return inet_recv_error(sk, msg, len, addr_len);
 
+       if (!len)
+               return 0;
+
        psock = sk_psock_get(sk);
        if (unlikely(!psock))
                return sk_udp_recvmsg(sk, msg, len, flags, addr_len);
index 47447f0241df604bc657acbd9ce37008b49bacf0..bee45dfeb18741106fa517ef634fa09d25f0cea3 100644 (file)
@@ -477,6 +477,7 @@ int ila_xlat_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info)
 
        rcu_read_lock();
 
+       ret = -ESRCH;
        ila = ila_lookup_by_params(&xp, ilan);
        if (ila) {
                ret = ila_dump_info(ila,
index 89f5f0f3f5d65b6aac0dae2302d8a5607a492155..a4ecfc9d25930967a6af7bd9de9aa52bfd08730d 100644 (file)
@@ -959,7 +959,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
                truncate = true;
        }
 
-       nhoff = skb_network_header(skb) - skb_mac_header(skb);
+       nhoff = skb_network_offset(skb);
        if (skb->protocol == htons(ETH_P_IP) &&
            (ntohs(ip_hdr(skb)->tot_len) > skb->len - nhoff))
                truncate = true;
@@ -968,7 +968,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
                int thoff;
 
                if (skb_transport_header_was_set(skb))
-                       thoff = skb_transport_header(skb) - skb_mac_header(skb);
+                       thoff = skb_transport_offset(skb);
                else
                        thoff = nhoff + sizeof(struct ipv6hdr);
                if (ntohs(ipv6_hdr(skb)->payload_len) > skb->len - thoff)
index c314fdde0097c8c8dc30ab1dc43cbc2905c0f5d1..95a55c6630add2c060d8923a3f7311dd7bdcb4ea 100644 (file)
@@ -1965,8 +1965,13 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,
        IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
        if (proto == IPPROTO_ICMPV6) {
                struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
+               u8 icmp6_type;
 
-               ICMP6MSGOUT_INC_STATS(net, idev, icmp6_hdr(skb)->icmp6_type);
+               if (sk->sk_socket->type == SOCK_RAW && !inet_sk(sk)->hdrincl)
+                       icmp6_type = fl6->fl6_icmp_type;
+               else
+                       icmp6_type = icmp6_hdr(skb)->icmp6_type;
+               ICMP6MSGOUT_INC_STATS(net, idev, icmp6_type);
                ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
        }
 
index 47b6607a13706ef415e0b19f38014700e673da84..5e80e517f071013410349d1fd93afc00a394e284 100644 (file)
@@ -1240,8 +1240,8 @@ route_lookup:
         */
        max_headroom = LL_RESERVED_SPACE(dst->dev) + sizeof(struct ipv6hdr)
                        + dst->header_len + t->hlen;
-       if (max_headroom > dev->needed_headroom)
-               dev->needed_headroom = max_headroom;
+       if (max_headroom > READ_ONCE(dev->needed_headroom))
+               WRITE_ONCE(dev->needed_headroom, max_headroom);
 
        err = ip6_tnl_encap(skb, t, &proto, fl6);
        if (err)
index 929502e51203bc39232ab0e43f768fe5f72b7641..52f828bb5a83daee7b74674fb56b58d430eccff2 100644 (file)
@@ -63,7 +63,7 @@ nf_tproxy_handle_time_wait6(struct sk_buff *skb, int tproto, int thoff,
                                            lport ? lport : hp->dest,
                                            skb->dev, NF_TPROXY_LOOKUP_LISTENER);
                if (sk2) {
-                       inet_twsk_deschedule_put(inet_twsk(sk));
+                       nf_tproxy_twsk_deschedule_put(inet_twsk(sk));
                        sk = sk2;
                }
        }
index bac9ba747bdecf8df24acb6c980a822d8f237403..a327aa481df48b8baed42ae11db53f05ce4f6841 100644 (file)
@@ -141,10 +141,9 @@ EXPORT_SYMBOL(rawv6_mh_filter_unregister);
 static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
 {
        struct net *net = dev_net(skb->dev);
-       struct hlist_nulls_head *hlist;
-       struct hlist_nulls_node *hnode;
        const struct in6_addr *saddr;
        const struct in6_addr *daddr;
+       struct hlist_head *hlist;
        struct sock *sk;
        bool delivered = false;
        __u8 hash;
@@ -155,7 +154,7 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
        hash = raw_hashfunc(net, nexthdr);
        hlist = &raw_v6_hashinfo.ht[hash];
        rcu_read_lock();
-       sk_nulls_for_each(sk, hnode, hlist) {
+       sk_for_each_rcu(sk, hlist) {
                int filtered;
 
                if (!raw_v6_match(net, sk, nexthdr, daddr, saddr,
@@ -333,15 +332,14 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
                u8 type, u8 code, int inner_offset, __be32 info)
 {
        struct net *net = dev_net(skb->dev);
-       struct hlist_nulls_head *hlist;
-       struct hlist_nulls_node *hnode;
+       struct hlist_head *hlist;
        struct sock *sk;
        int hash;
 
        hash = raw_hashfunc(net, nexthdr);
        hlist = &raw_v6_hashinfo.ht[hash];
        rcu_read_lock();
-       sk_nulls_for_each(sk, hnode, hlist) {
+       sk_for_each_rcu(sk, hlist) {
                /* Note: ipv6_hdr(skb) != skb->data */
                const struct ipv6hdr *ip6h = (const struct ipv6hdr *)skb->data;
 
index 488aec9e1a74f338a777e3c6b0e2d53f2b48777c..d1876f19222552ca374b19e37502df0e570946ba 100644 (file)
@@ -32,7 +32,8 @@ static void *ipv6_rpl_segdata_pos(const struct ipv6_rpl_sr_hdr *hdr, int i)
 size_t ipv6_rpl_srh_size(unsigned char n, unsigned char cmpri,
                         unsigned char cmpre)
 {
-       return (n * IPV6_PFXTAIL_LEN(cmpri)) + IPV6_PFXTAIL_LEN(cmpre);
+       return sizeof(struct ipv6_rpl_sr_hdr) + (n * IPV6_PFXTAIL_LEN(cmpri)) +
+               IPV6_PFXTAIL_LEN(cmpre);
 }
 
 void ipv6_rpl_srh_decompress(struct ipv6_rpl_sr_hdr *outhdr,
index 9fb2f33ee3a76a09bbe15a9aaf1371a804f91ee2..a675acfb901d102ce56563b1d50ae827d9e04859 100644 (file)
@@ -1395,9 +1395,11 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
                        msg->msg_name = &sin;
                        msg->msg_namelen = sizeof(sin);
 do_udp_sendmsg:
-                       if (ipv6_only_sock(sk))
-                               return -ENETUNREACH;
-                       return udp_sendmsg(sk, msg, len);
+                       err = ipv6_only_sock(sk) ?
+                               -ENETUNREACH : udp_sendmsg(sk, msg, len);
+                       msg->msg_name = sin6;
+                       msg->msg_namelen = addr_len;
+                       return err;
                }
        }
 
index eb0295d90039577acc88da033d45ac13692c9cfd..fc3fddeb6f36d4066c91d4eae889deccb07799fc 100644 (file)
@@ -83,7 +83,7 @@ struct iucv_irq_data {
        u16 ippathid;
        u8  ipflags1;
        u8  iptype;
-       u32 res2[8];
+       u32 res2[9];
 };
 
 struct iucv_irq_list {
index 4db5a554bdbd9e80eb697a88cb7208e15d7931bc..41a74fc84ca13a4d86d1b16b942667cfc1b3c9a8 100644 (file)
@@ -677,8 +677,8 @@ MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
 MODULE_DESCRIPTION("L2TP over IP");
 MODULE_VERSION("1.0");
 
-/* Use the value of SOCK_DGRAM (2) directory, because __stringify doesn't like
- * enums
+/* Use the values of SOCK_DGRAM (2) as type and IPPROTO_L2TP (115) as protocol,
+ * because __stringify doesn't like enums
  */
-MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 2, IPPROTO_L2TP);
-MODULE_ALIAS_NET_PF_PROTO(PF_INET, IPPROTO_L2TP);
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 115, 2);
+MODULE_ALIAS_NET_PF_PROTO(PF_INET, 115);
index 2478aa60145fbd6c91155fad595e6b37252ed198..5137ea1861ce26a2e6efc1f5c29e4de0fdce2c06 100644 (file)
@@ -806,8 +806,8 @@ MODULE_AUTHOR("Chris Elston <celston@katalix.com>");
 MODULE_DESCRIPTION("L2TP IP encapsulation for IPv6");
 MODULE_VERSION("1.0");
 
-/* Use the value of SOCK_DGRAM (2) directory, because __stringify doesn't like
- * enums
+/* Use the values of SOCK_DGRAM (2) as type and IPPROTO_L2TP (115) as protocol,
+ * because __stringify doesn't like enums
  */
-MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 2, IPPROTO_L2TP);
-MODULE_ALIAS_NET_PF_PROTO(PF_INET6, IPPROTO_L2TP);
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 115, 2);
+MODULE_ALIAS_NET_PF_PROTO(PF_INET6, 115);
index 8eb3423008687a3f09c3512d8adbb00b19579695..d3d861911ed65084bd617736c5c32c3ed899de50 100644 (file)
@@ -2611,6 +2611,17 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
        if (!sband)
                return -EINVAL;
 
+       if (params->basic_rates) {
+               if (!ieee80211_parse_bitrates(link->conf->chandef.width,
+                                             wiphy->bands[sband->band],
+                                             params->basic_rates,
+                                             params->basic_rates_len,
+                                             &link->conf->basic_rates))
+                       return -EINVAL;
+               changed |= BSS_CHANGED_BASIC_RATES;
+               ieee80211_check_rate_mask(link);
+       }
+
        if (params->use_cts_prot >= 0) {
                link->conf->use_cts_prot = params->use_cts_prot;
                changed |= BSS_CHANGED_ERP_CTS_PROT;
@@ -2632,16 +2643,6 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
                changed |= BSS_CHANGED_ERP_SLOT;
        }
 
-       if (params->basic_rates) {
-               ieee80211_parse_bitrates(link->conf->chandef.width,
-                                        wiphy->bands[sband->band],
-                                        params->basic_rates,
-                                        params->basic_rates_len,
-                                        &link->conf->basic_rates);
-               changed |= BSS_CHANGED_BASIC_RATES;
-               ieee80211_check_rate_mask(link);
-       }
-
        if (params->ap_isolate >= 0) {
                if (params->ap_isolate)
                        sdata->flags |= IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
index ecc232eb1ee82f9f3a143a65b5b258a2dbd32773..e082582e0aa284b4af3792c4c6dc7c176f61df68 100644 (file)
@@ -1284,6 +1284,9 @@ struct ieee80211_local {
        struct list_head active_txqs[IEEE80211_NUM_ACS];
        u16 schedule_round[IEEE80211_NUM_ACS];
 
+       /* serializes ieee80211_handle_wake_tx_queue */
+       spinlock_t handle_wake_tx_queue_lock;
+
        u16 airtime_flags;
        u32 aql_txq_limit_low[IEEE80211_NUM_ACS];
        u32 aql_txq_limit_high[IEEE80211_NUM_ACS];
index 846528850612a7d9886be8d5ca5147b24fea61e1..ddf2b7811c557973846a5926ef5b521295740e31 100644 (file)
@@ -802,6 +802,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
        local->aql_threshold = IEEE80211_AQL_THRESHOLD;
        atomic_set(&local->aql_total_pending_airtime, 0);
 
+       spin_lock_init(&local->handle_wake_tx_queue_lock);
+
        INIT_LIST_HEAD(&local->chanctx_list);
        mutex_init(&local->chanctx_mtx);
 
index f7fdfe710951faa1c9402cfd8d71ced290864f3e..af57616d2f1d9368906dfcb68d6cc8f60938e725 100644 (file)
@@ -2765,29 +2765,10 @@ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta
            mesh_rmc_check(sdata, eth->h_source, mesh_hdr))
                return RX_DROP_MONITOR;
 
-       /* Frame has reached destination.  Don't forward */
-       if (ether_addr_equal(sdata->vif.addr, eth->h_dest))
-               goto rx_accept;
-
-       if (!ifmsh->mshcfg.dot11MeshForwarding) {
-               if (is_multicast_ether_addr(eth->h_dest))
-                       goto rx_accept;
-
-               return RX_DROP_MONITOR;
-       }
-
        /* forward packet */
        if (sdata->crypto_tx_tailroom_needed_cnt)
                tailroom = IEEE80211_ENCRYPT_TAILROOM;
 
-       if (!--mesh_hdr->ttl) {
-               if (multicast)
-                       goto rx_accept;
-
-               IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
-               return RX_DROP_MONITOR;
-       }
-
        if (mesh_hdr->flags & MESH_FLAGS_AE) {
                struct mesh_path *mppath;
                char *proxied_addr;
@@ -2814,6 +2795,25 @@ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta
                rcu_read_unlock();
        }
 
+       /* Frame has reached destination.  Don't forward */
+       if (ether_addr_equal(sdata->vif.addr, eth->h_dest))
+               goto rx_accept;
+
+       if (!--mesh_hdr->ttl) {
+               if (multicast)
+                       goto rx_accept;
+
+               IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
+               return RX_DROP_MONITOR;
+       }
+
+       if (!ifmsh->mshcfg.dot11MeshForwarding) {
+               if (is_multicast_ether_addr(eth->h_dest))
+                       goto rx_accept;
+
+               return RX_DROP_MONITOR;
+       }
+
        skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]);
 
        ieee80211_fill_mesh_addresses(&hdr, &hdr.frame_control,
@@ -2833,6 +2833,9 @@ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta
 
                if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr)))
                        return RX_DROP_UNUSABLE;
+
+               if (skb_linearize(fwd_skb))
+                       return RX_DROP_UNUSABLE;
        }
 
        fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr));
@@ -2847,7 +2850,7 @@ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta
                hdrlen += ETH_ALEN;
        else
                fwd_skb->protocol = htons(fwd_skb->len - hdrlen);
-       skb_set_network_header(fwd_skb, hdrlen);
+       skb_set_network_header(fwd_skb, hdrlen + 2);
 
        info = IEEE80211_SKB_CB(fwd_skb);
        memset(info, 0, sizeof(*info));
@@ -2896,7 +2899,7 @@ __ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset)
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        __le16 fc = hdr->frame_control;
        struct sk_buff_head frame_list;
-       static ieee80211_rx_result res;
+       ieee80211_rx_result res;
        struct ethhdr ethhdr;
        const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source;
 
@@ -2930,7 +2933,7 @@ __ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset)
                                          data_offset, true))
                return RX_DROP_UNUSABLE;
 
-       if (rx->sta && rx->sta->amsdu_mesh_control < 0) {
+       if (rx->sta->amsdu_mesh_control < 0) {
                bool valid_std = ieee80211_is_valid_amsdu(skb, true);
                bool valid_nonstd = ieee80211_is_valid_amsdu(skb, false);
 
@@ -3006,7 +3009,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
                }
        }
 
-       if (is_multicast_ether_addr(hdr->addr1))
+       if (is_multicast_ether_addr(hdr->addr1) || !rx->sta)
                return RX_DROP_UNUSABLE;
 
        if (rx->key) {
@@ -3037,7 +3040,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
        struct net_device *dev = sdata->dev;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
        __le16 fc = hdr->frame_control;
-       static ieee80211_rx_result res;
+       ieee80211_rx_result res;
        bool port_control;
        int err;
 
index 7d68dbc872d7736f5d72eeb1b6f64ddbdf67ca6f..941bda9141faab6883a0e7a715eee47d1e34d806 100644 (file)
@@ -1264,7 +1264,8 @@ static int __must_check __sta_info_destroy_part1(struct sta_info *sta)
        list_del_rcu(&sta->list);
        sta->removed = true;
 
-       drv_sta_pre_rcu_remove(local, sta->sdata, sta);
+       if (sta->uploaded)
+               drv_sta_pre_rcu_remove(local, sta->sdata, sta);
 
        if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
            rcu_access_pointer(sdata->u.vlan.sta) == sta)
index 1a28fe5cb614f2a5fe6f9007d1769fa7d6446a18..8c397650b96f605f3b2e75c599337cdac47f5555 100644 (file)
@@ -314,6 +314,8 @@ void ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw,
        struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif);
        struct ieee80211_txq *queue;
 
+       spin_lock(&local->handle_wake_tx_queue_lock);
+
        /* Use ieee80211_next_txq() for airtime fairness accounting */
        ieee80211_txq_schedule_start(hw, txq->ac);
        while ((queue = ieee80211_next_txq(hw, txq->ac))) {
@@ -321,6 +323,7 @@ void ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw,
                ieee80211_return_txq(hw, queue, false);
        }
        ieee80211_txq_schedule_end(hw, txq->ac);
+       spin_unlock(&local->handle_wake_tx_queue_lock);
 }
 EXPORT_SYMBOL(ieee80211_handle_wake_tx_queue);
 
@@ -4903,7 +4906,7 @@ u8 ieee80211_ie_len_eht_cap(struct ieee80211_sub_if_data *sdata, u8 iftype)
                                       &eht_cap->eht_cap_elem,
                                       is_ap);
        return 2 + 1 +
-              sizeof(he_cap->he_cap_elem) + n +
+              sizeof(eht_cap->eht_cap_elem) + n +
               ieee80211_eht_ppe_size(eht_cap->eht_ppe_thres[0],
                                      eht_cap->eht_cap_elem.phy_cap_info);
        return 0;
index a12c63638680122f7f449fba4060066c78a07c14..1601be5764145d3c736c59699ccc3873a726750f 100644 (file)
@@ -147,6 +147,7 @@ u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
 u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
                           struct sta_info *sta, struct sk_buff *skb)
 {
+       const struct ethhdr *eth = (void *)skb->data;
        struct mac80211_qos_map *qos_map;
        bool qos;
 
@@ -154,8 +155,9 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
        skb_get_hash(skb);
 
        /* all mesh/ocb stations are required to support WME */
-       if (sta && (sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
-                   sdata->vif.type == NL80211_IFTYPE_OCB))
+       if ((sdata->vif.type == NL80211_IFTYPE_MESH_POINT &&
+           !is_multicast_ether_addr(eth->h_dest)) ||
+           (sdata->vif.type == NL80211_IFTYPE_OCB && sta))
                qos = true;
        else if (sta)
                qos = sta->sta.wme;
index 9b0933a185ebc9981ff8c64478742f7f6e9d8e9e..5c191bedd72c4440b4ddffdef8848c2011451e8b 100644 (file)
@@ -52,7 +52,7 @@ static int mac802154_scan_cleanup_locked(struct ieee802154_local *local,
        request = rcu_replace_pointer(local->scan_req, NULL, 1);
        if (!request)
                return 0;
-       kfree_rcu(request);
+       kvfree_rcu_mightsleep(request);
 
        /* Advertize first, while we know the devices cannot be removed */
        if (aborted)
@@ -403,7 +403,7 @@ int mac802154_stop_beacons_locked(struct ieee802154_local *local,
        request = rcu_replace_pointer(local->beacon_req, NULL, 1);
        if (!request)
                return 0;
-       kfree_rcu(request);
+       kvfree_rcu_mightsleep(request);
 
        nl802154_beaconing_done(wpan_dev);
 
index d237d142171c5a96b13ef459832fc988fa2f5401..bceaab8dd8e460e7a3459e12af6089ab6bb6b2b7 100644 (file)
@@ -9,11 +9,18 @@
 void mptcp_fastopen_subflow_synack_set_params(struct mptcp_subflow_context *subflow,
                                              struct request_sock *req)
 {
-       struct sock *ssk = subflow->tcp_sock;
-       struct sock *sk = subflow->conn;
+       struct sock *sk, *ssk;
        struct sk_buff *skb;
        struct tcp_sock *tp;
 
+       /* on early fallback the subflow context is deleted by
+        * subflow_syn_recv_sock()
+        */
+       if (!subflow)
+               return;
+
+       ssk = subflow->tcp_sock;
+       sk = subflow->conn;
        tp = tcp_sk(ssk);
 
        subflow->is_mptfo = 1;
index b30cea2fbf3fd0d4706573c4c41624ca3d9cfe26..355f798d575a40542195fcc724819e1de9f2e4e7 100644 (file)
@@ -1192,9 +1192,8 @@ bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
         */
        if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) {
                if (mp_opt.data_fin && mp_opt.data_len == 1 &&
-                   mptcp_update_rcv_data_fin(msk, mp_opt.data_seq, mp_opt.dsn64) &&
-                   schedule_work(&msk->work))
-                       sock_hold(subflow->conn);
+                   mptcp_update_rcv_data_fin(msk, mp_opt.data_seq, mp_opt.dsn64))
+                       mptcp_schedule_work((struct sock *)msk);
 
                return true;
        }
index 56628b52d1001a967eb2e504bdbeac0c4cd17acc..5c8dea49626c31a008f9243498564fbcd3cebb1c 100644 (file)
@@ -997,9 +997,13 @@ out:
        return ret;
 }
 
+static struct lock_class_key mptcp_slock_keys[2];
+static struct lock_class_key mptcp_keys[2];
+
 static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
                                            struct mptcp_pm_addr_entry *entry)
 {
+       bool is_ipv6 = sk->sk_family == AF_INET6;
        int addrlen = sizeof(struct sockaddr_in);
        struct sockaddr_storage addr;
        struct socket *ssock;
@@ -1016,6 +1020,18 @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
        if (!newsk)
                return -EINVAL;
 
+       /* The subflow socket lock is acquired in a nested to the msk one
+        * in several places, even by the TCP stack, and this msk is a kernel
+        * socket: lockdep complains. Instead of propagating the _nested
+        * modifiers in several places, re-init the lock class for the msk
+        * socket to an mptcp specific one.
+        */
+       sock_lock_init_class_and_name(newsk,
+                                     is_ipv6 ? "mlock-AF_INET6" : "mlock-AF_INET",
+                                     &mptcp_slock_keys[is_ipv6],
+                                     is_ipv6 ? "msk_lock-AF_INET6" : "msk_lock-AF_INET",
+                                     &mptcp_keys[is_ipv6]);
+
        lock_sock(newsk);
        ssock = __mptcp_nmpc_socket(mptcp_sk(newsk));
        release_sock(newsk);
index 3ad9c46202fc63a5b3a870bf2ba994a8d9148264..b998e9df53cef4c3e5fcffab0fee9ca0080ef7bf 100644 (file)
@@ -825,7 +825,6 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
        if (sk->sk_socket && !ssk->sk_socket)
                mptcp_sock_graft(ssk, sk->sk_socket);
 
-       mptcp_propagate_sndbuf((struct sock *)msk, ssk);
        mptcp_sockopt_sync_locked(msk, ssk);
        return true;
 }
@@ -2316,7 +2315,26 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
                              unsigned int flags)
 {
        struct mptcp_sock *msk = mptcp_sk(sk);
-       bool need_push, dispose_it;
+       bool dispose_it, need_push = false;
+
+       /* If the first subflow moved to a close state before accept, e.g. due
+        * to an incoming reset, mptcp either:
+        * - if either the subflow or the msk are dead, destroy the context
+        *   (the subflow socket is deleted by inet_child_forget) and the msk
+        * - otherwise do nothing at the moment and take action at accept and/or
+        *   listener shutdown - user-space must be able to accept() the closed
+        *   socket.
+        */
+       if (msk->in_accept_queue && msk->first == ssk) {
+               if (!sock_flag(sk, SOCK_DEAD) && !sock_flag(ssk, SOCK_DEAD))
+                       return;
+
+               /* ensure later check in mptcp_worker() will dispose the msk */
+               sock_set_flag(sk, SOCK_DEAD);
+               lock_sock_nested(ssk, SINGLE_DEPTH_NESTING);
+               mptcp_subflow_drop_ctx(ssk);
+               goto out_release;
+       }
 
        dispose_it = !msk->subflow || ssk != msk->subflow->sk;
        if (dispose_it)
@@ -2343,7 +2361,6 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
                goto out;
        }
 
-       sock_orphan(ssk);
        subflow->disposable = 1;
 
        /* if ssk hit tcp_done(), tcp_cleanup_ulp() cleared the related ops
@@ -2351,6 +2368,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
         * reference owned by msk;
         */
        if (!inet_csk(ssk)->icsk_ulp_ops) {
+               WARN_ON_ONCE(!sock_flag(ssk, SOCK_DEAD));
                kfree_rcu(subflow, rcu);
        } else {
                /* otherwise tcp will dispose of the ssk and subflow ctx */
@@ -2360,11 +2378,14 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
                        inet_csk_listen_stop(ssk);
                        mptcp_event_pm_listener(ssk, MPTCP_EVENT_LISTENER_CLOSED);
                }
+
                __tcp_close(ssk, 0);
 
                /* close acquired an extra ref */
                __sock_put(ssk);
        }
+
+out_release:
        release_sock(ssk);
 
        sock_put(ssk);
@@ -2399,9 +2420,10 @@ static unsigned int mptcp_sync_mss(struct sock *sk, u32 pmtu)
        return 0;
 }
 
-static void __mptcp_close_subflow(struct mptcp_sock *msk)
+static void __mptcp_close_subflow(struct sock *sk)
 {
        struct mptcp_subflow_context *subflow, *tmp;
+       struct mptcp_sock *msk = mptcp_sk(sk);
 
        might_sleep();
 
@@ -2415,16 +2437,17 @@ static void __mptcp_close_subflow(struct mptcp_sock *msk)
                if (!skb_queue_empty_lockless(&ssk->sk_receive_queue))
                        continue;
 
-               mptcp_close_ssk((struct sock *)msk, ssk, subflow);
+               mptcp_close_ssk(sk, ssk, subflow);
        }
+
 }
 
-static bool mptcp_check_close_timeout(const struct sock *sk)
+static bool mptcp_should_close(const struct sock *sk)
 {
        s32 delta = tcp_jiffies32 - inet_csk(sk)->icsk_mtup.probe_timestamp;
        struct mptcp_subflow_context *subflow;
 
-       if (delta >= TCP_TIMEWAIT_LEN)
+       if (delta >= TCP_TIMEWAIT_LEN || mptcp_sk(sk)->in_accept_queue)
                return true;
 
        /* if all subflows are in closed status don't bother with additional
@@ -2609,7 +2632,7 @@ static void mptcp_worker(struct work_struct *work)
 
        lock_sock(sk);
        state = sk->sk_state;
-       if (unlikely(state == TCP_CLOSE))
+       if (unlikely((1 << state) & (TCPF_CLOSE | TCPF_LISTEN)))
                goto unlock;
 
        mptcp_check_data_fin_ack(sk);
@@ -2624,12 +2647,15 @@ static void mptcp_worker(struct work_struct *work)
        __mptcp_check_send_data_fin(sk);
        mptcp_check_data_fin(sk);
 
+       if (test_and_clear_bit(MPTCP_WORK_CLOSE_SUBFLOW, &msk->flags))
+               __mptcp_close_subflow(sk);
+
        /* There is no point in keeping around an orphaned sk timedout or
         * closed, but we need the msk around to reply to incoming DATA_FIN,
         * even if it is orphaned and in FIN_WAIT2 state
         */
        if (sock_flag(sk, SOCK_DEAD)) {
-               if (mptcp_check_close_timeout(sk)) {
+               if (mptcp_should_close(sk)) {
                        inet_sk_state_store(sk, TCP_CLOSE);
                        mptcp_do_fastclose(sk);
                }
@@ -2639,9 +2665,6 @@ static void mptcp_worker(struct work_struct *work)
                }
        }
 
-       if (test_and_clear_bit(MPTCP_WORK_CLOSE_SUBFLOW, &msk->flags))
-               __mptcp_close_subflow(msk);
-
        if (test_and_clear_bit(MPTCP_WORK_RTX, &msk->flags))
                __mptcp_retrans(sk);
 
@@ -2878,6 +2901,14 @@ static void __mptcp_destroy_sock(struct sock *sk)
        sock_put(sk);
 }
 
+void __mptcp_unaccepted_force_close(struct sock *sk)
+{
+       sock_set_flag(sk, SOCK_DEAD);
+       inet_sk_state_store(sk, TCP_CLOSE);
+       mptcp_do_fastclose(sk);
+       __mptcp_destroy_sock(sk);
+}
+
 static __poll_t mptcp_check_readable(struct mptcp_sock *msk)
 {
        /* Concurrent splices from sk_receive_queue into receive_queue will
@@ -3079,6 +3110,7 @@ struct sock *mptcp_sk_clone(const struct sock *sk,
        msk->local_key = subflow_req->local_key;
        msk->token = subflow_req->token;
        msk->subflow = NULL;
+       msk->in_accept_queue = 1;
        WRITE_ONCE(msk->fully_established, false);
        if (mp_opt->suboptions & OPTION_MPTCP_CSUMREQD)
                WRITE_ONCE(msk->csum_enabled, true);
@@ -3096,8 +3128,7 @@ struct sock *mptcp_sk_clone(const struct sock *sk,
        security_inet_csk_clone(nsk, req);
        bh_unlock_sock(nsk);
 
-       /* keep a single reference */
-       __sock_put(nsk);
+       /* note: the newly allocated socket refcount is 2 now */
        return nsk;
 }
 
@@ -3153,8 +3184,6 @@ static struct sock *mptcp_accept(struct sock *sk, int flags, int *err,
                        goto out;
                }
 
-               /* acquire the 2nd reference for the owning socket */
-               sock_hold(new_mptcp_sock);
                newsk = new_mptcp_sock;
                MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEPASSIVEACK);
        } else {
@@ -3705,25 +3734,10 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
                struct sock *newsk = newsock->sk;
 
                set_bit(SOCK_CUSTOM_SOCKOPT, &newsock->flags);
+               msk->in_accept_queue = 0;
 
                lock_sock(newsk);
 
-               /* PM/worker can now acquire the first subflow socket
-                * lock without racing with listener queue cleanup,
-                * we can notify it, if needed.
-                *
-                * Even if remote has reset the initial subflow by now
-                * the refcnt is still at least one.
-                */
-               subflow = mptcp_subflow_ctx(msk->first);
-               list_add(&subflow->node, &msk->conn_list);
-               sock_hold(msk->first);
-               if (mptcp_is_fully_established(newsk))
-                       mptcp_pm_fully_established(msk, msk->first, GFP_KERNEL);
-
-               mptcp_rcv_space_init(msk, msk->first);
-               mptcp_propagate_sndbuf(newsk, msk->first);
-
                /* set ssk->sk_socket of accept()ed flows to mptcp socket.
                 * This is needed so NOSPACE flag can be set from tcp stack.
                 */
@@ -3733,6 +3747,18 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
                        if (!ssk->sk_socket)
                                mptcp_sock_graft(ssk, newsock);
                }
+
+               /* Do late cleanup for the first subflow as necessary. Also
+                * deal with bad peers not doing a complete shutdown.
+                */
+               if (msk->first &&
+                   unlikely(inet_sk_state_load(msk->first) == TCP_CLOSE)) {
+                       __mptcp_close_ssk(newsk, msk->first,
+                                         mptcp_subflow_ctx(msk->first), 0);
+                       if (unlikely(list_empty(&msk->conn_list)))
+                               inet_sk_state_store(newsk, TCP_CLOSE);
+               }
+
                release_sock(newsk);
        }
 
index 61fd8eabfca2028680e04558b4baca9f48bbaaaa..d6469b6ab38e3c6b91fba0ac7465c2a29c7b54cd 100644 (file)
@@ -295,7 +295,8 @@ struct mptcp_sock {
        u8              recvmsg_inq:1,
                        cork:1,
                        nodelay:1,
-                       fastopening:1;
+                       fastopening:1,
+                       in_accept_queue:1;
        int             connect_flags;
        struct work_struct work;
        struct sk_buff  *ooo_last_skb;
@@ -633,6 +634,7 @@ void mptcp_sock_graft(struct sock *sk, struct socket *parent);
 struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk);
 bool __mptcp_close(struct sock *sk, long timeout);
 void mptcp_cancel_work(struct sock *sk);
+void __mptcp_unaccepted_force_close(struct sock *sk);
 void mptcp_set_owner_r(struct sk_buff *skb, struct sock *sk);
 
 bool mptcp_addresses_equal(const struct mptcp_addr_info *a,
@@ -666,6 +668,8 @@ void mptcp_subflow_set_active(struct mptcp_subflow_context *subflow);
 
 bool mptcp_subflow_active(struct mptcp_subflow_context *subflow);
 
+void mptcp_subflow_drop_ctx(struct sock *ssk);
+
 static inline void mptcp_subflow_tcp_fallback(struct sock *sk,
                                              struct mptcp_subflow_context *ctx)
 {
index 4ae1a7304cf0da1840a1d236969549d18cf8ff97..281c1cc8dc8dc072c936d578a03259a7cab75b07 100644 (file)
@@ -397,15 +397,19 @@ void mptcp_subflow_reset(struct sock *ssk)
        struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
        struct sock *sk = subflow->conn;
 
+       /* mptcp_mp_fail_no_response() can reach here on an already closed
+        * socket
+        */
+       if (ssk->sk_state == TCP_CLOSE)
+               return;
+
        /* must hold: tcp_done() could drop last reference on parent */
        sock_hold(sk);
 
-       tcp_set_state(ssk, TCP_CLOSE);
        tcp_send_active_reset(ssk, GFP_ATOMIC);
        tcp_done(ssk);
-       if (!test_and_set_bit(MPTCP_WORK_CLOSE_SUBFLOW, &mptcp_sk(sk)->flags) &&
-           schedule_work(&mptcp_sk(sk)->work))
-               return; /* worker will put sk for us */
+       if (!test_and_set_bit(MPTCP_WORK_CLOSE_SUBFLOW, &mptcp_sk(sk)->flags))
+               mptcp_schedule_work(sk);
 
        sock_put(sk);
 }
@@ -622,7 +626,7 @@ static struct request_sock_ops mptcp_subflow_v6_request_sock_ops __ro_after_init
 static struct tcp_request_sock_ops subflow_request_sock_ipv6_ops __ro_after_init;
 static struct inet_connection_sock_af_ops subflow_v6_specific __ro_after_init;
 static struct inet_connection_sock_af_ops subflow_v6m_specific __ro_after_init;
-static struct proto tcpv6_prot_override;
+static struct proto tcpv6_prot_override __ro_after_init;
 
 static int subflow_v6_conn_request(struct sock *sk, struct sk_buff *skb)
 {
@@ -693,9 +697,10 @@ static bool subflow_hmac_valid(const struct request_sock *req,
 
 static void mptcp_force_close(struct sock *sk)
 {
-       /* the msk is not yet exposed to user-space */
+       /* the msk is not yet exposed to user-space, and refcount is 2 */
        inet_sk_state_store(sk, TCP_CLOSE);
        sk_common_release(sk);
+       sock_put(sk);
 }
 
 static void subflow_ulp_fallback(struct sock *sk,
@@ -711,16 +716,19 @@ static void subflow_ulp_fallback(struct sock *sk,
        mptcp_subflow_ops_undo_override(sk);
 }
 
-static void subflow_drop_ctx(struct sock *ssk)
+void mptcp_subflow_drop_ctx(struct sock *ssk)
 {
        struct mptcp_subflow_context *ctx = mptcp_subflow_ctx(ssk);
 
        if (!ctx)
                return;
 
-       subflow_ulp_fallback(ssk, ctx);
-       if (ctx->conn)
-               sock_put(ctx->conn);
+       list_del(&mptcp_subflow_ctx(ssk)->node);
+       if (inet_csk(ssk)->icsk_ulp_ops) {
+               subflow_ulp_fallback(ssk, ctx);
+               if (ctx->conn)
+                       sock_put(ctx->conn);
+       }
 
        kfree_rcu(ctx, rcu);
 }
@@ -750,6 +758,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
        struct mptcp_options_received mp_opt;
        bool fallback, fallback_is_fatal;
        struct sock *new_msk = NULL;
+       struct mptcp_sock *owner;
        struct sock *child;
 
        pr_debug("listener=%p, req=%p, conn=%p", listener, req, listener->conn);
@@ -816,7 +825,7 @@ create_child:
 
                        if (new_msk)
                                mptcp_copy_inaddrs(new_msk, child);
-                       subflow_drop_ctx(child);
+                       mptcp_subflow_drop_ctx(child);
                        goto out;
                }
 
@@ -824,6 +833,8 @@ create_child:
                ctx->setsockopt_seq = listener->setsockopt_seq;
 
                if (ctx->mp_capable) {
+                       owner = mptcp_sk(new_msk);
+
                        /* this can't race with mptcp_close(), as the msk is
                         * not yet exposted to user-space
                         */
@@ -832,14 +843,14 @@ create_child:
                        /* record the newly created socket as the first msk
                         * subflow, but don't link it yet into conn_list
                         */
-                       WRITE_ONCE(mptcp_sk(new_msk)->first, child);
+                       WRITE_ONCE(owner->first, child);
 
                        /* new mpc subflow takes ownership of the newly
                         * created mptcp socket
                         */
                        mptcp_sk(new_msk)->setsockopt_seq = ctx->setsockopt_seq;
-                       mptcp_pm_new_connection(mptcp_sk(new_msk), child, 1);
-                       mptcp_token_accept(subflow_req, mptcp_sk(new_msk));
+                       mptcp_pm_new_connection(owner, child, 1);
+                       mptcp_token_accept(subflow_req, owner);
                        ctx->conn = new_msk;
                        new_msk = NULL;
 
@@ -847,15 +858,21 @@ create_child:
                         * uses the correct data
                         */
                        mptcp_copy_inaddrs(ctx->conn, child);
+                       mptcp_propagate_sndbuf(ctx->conn, child);
+
+                       mptcp_rcv_space_init(owner, child);
+                       list_add(&ctx->node, &owner->conn_list);
+                       sock_hold(child);
 
                        /* with OoO packets we can reach here without ingress
                         * mpc option
                         */
-                       if (mp_opt.suboptions & OPTION_MPTCP_MPC_ACK)
+                       if (mp_opt.suboptions & OPTION_MPTCP_MPC_ACK) {
                                mptcp_subflow_fully_established(ctx, &mp_opt);
+                               mptcp_pm_fully_established(owner, child, GFP_ATOMIC);
+                               ctx->pm_notified = 1;
+                       }
                } else if (ctx->mp_join) {
-                       struct mptcp_sock *owner;
-
                        owner = subflow_req->msk;
                        if (!owner) {
                                subflow_add_reset_reason(skb, MPTCP_RST_EPROHIBIT);
@@ -899,7 +916,7 @@ out:
        return child;
 
 dispose_child:
-       subflow_drop_ctx(child);
+       mptcp_subflow_drop_ctx(child);
        tcp_rsk(req)->drop_req = true;
        inet_csk_prepare_for_destroy_sock(child);
        tcp_done(child);
@@ -910,7 +927,7 @@ dispose_child:
 }
 
 static struct inet_connection_sock_af_ops subflow_specific __ro_after_init;
-static struct proto tcp_prot_override;
+static struct proto tcp_prot_override __ro_after_init;
 
 enum mapping_status {
        MAPPING_OK,
@@ -1103,8 +1120,8 @@ static enum mapping_status get_mapping_status(struct sock *ssk,
                                skb_ext_del(skb, SKB_EXT_MPTCP);
                                return MAPPING_OK;
                        } else {
-                               if (updated && schedule_work(&msk->work))
-                                       sock_hold((struct sock *)msk);
+                               if (updated)
+                                       mptcp_schedule_work((struct sock *)msk);
 
                                return MAPPING_DATA_FIN;
                        }
@@ -1207,17 +1224,12 @@ static void mptcp_subflow_discard_data(struct sock *ssk, struct sk_buff *skb,
 /* sched mptcp worker to remove the subflow if no more data is pending */
 static void subflow_sched_work_if_closed(struct mptcp_sock *msk, struct sock *ssk)
 {
-       struct sock *sk = (struct sock *)msk;
-
        if (likely(ssk->sk_state != TCP_CLOSE))
                return;
 
        if (skb_queue_empty(&ssk->sk_receive_queue) &&
-           !test_and_set_bit(MPTCP_WORK_CLOSE_SUBFLOW, &msk->flags)) {
-               sock_hold(sk);
-               if (!schedule_work(&msk->work))
-                       sock_put(sk);
-       }
+           !test_and_set_bit(MPTCP_WORK_CLOSE_SUBFLOW, &msk->flags))
+               mptcp_schedule_work((struct sock *)msk);
 }
 
 static bool subflow_can_fallback(struct mptcp_subflow_context *subflow)
@@ -1432,6 +1444,13 @@ static void subflow_error_report(struct sock *ssk)
 {
        struct sock *sk = mptcp_subflow_ctx(ssk)->conn;
 
+       /* bail early if this is a no-op, so that we avoid introducing a
+        * problematic lockdep dependency between TCP accept queue lock
+        * and msk socket spinlock
+        */
+       if (!sk->sk_socket)
+               return;
+
        mptcp_data_lock(sk);
        if (!sock_owned_by_user(sk))
                __mptcp_error_report(sk);
@@ -1808,13 +1827,13 @@ void mptcp_subflow_queue_clean(struct sock *listener_sk, struct sock *listener_s
        struct request_sock_queue *queue = &inet_csk(listener_ssk)->icsk_accept_queue;
        struct mptcp_sock *msk, *next, *head = NULL;
        struct request_sock *req;
+       struct sock *sk;
 
        /* build a list of all unaccepted mptcp sockets */
        spin_lock_bh(&queue->rskq_lock);
        for (req = queue->rskq_accept_head; req; req = req->dl_next) {
                struct mptcp_subflow_context *subflow;
                struct sock *ssk = req->sk;
-               struct mptcp_sock *msk;
 
                if (!sk_is_mptcp(ssk))
                        continue;
@@ -1824,10 +1843,12 @@ void mptcp_subflow_queue_clean(struct sock *listener_sk, struct sock *listener_s
                        continue;
 
                /* skip if already in list */
-               msk = mptcp_sk(subflow->conn);
+               sk = subflow->conn;
+               msk = mptcp_sk(sk);
                if (msk->dl_next || msk == head)
                        continue;
 
+               sock_hold(sk);
                msk->dl_next = head;
                head = msk;
        }
@@ -1841,34 +1862,30 @@ void mptcp_subflow_queue_clean(struct sock *listener_sk, struct sock *listener_s
        release_sock(listener_ssk);
 
        for (msk = head; msk; msk = next) {
-               struct sock *sk = (struct sock *)msk;
-               bool do_cancel_work;
+               sk = (struct sock *)msk;
 
-               sock_hold(sk);
                lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
                next = msk->dl_next;
-               msk->first = NULL;
                msk->dl_next = NULL;
 
-               do_cancel_work = __mptcp_close(sk, 0);
+               __mptcp_unaccepted_force_close(sk);
                release_sock(sk);
-               if (do_cancel_work) {
-                       /* lockdep will report a false positive ABBA deadlock
-                        * between cancel_work_sync and the listener socket.
-                        * The involved locks belong to different sockets WRT
-                        * the existing AB chain.
-                        * Using a per socket key is problematic as key
-                        * deregistration requires process context and must be
-                        * performed at socket disposal time, in atomic
-                        * context.
-                        * Just tell lockdep to consider the listener socket
-                        * released here.
-                        */
-                       mutex_release(&listener_sk->sk_lock.dep_map, _RET_IP_);
-                       mptcp_cancel_work(sk);
-                       mutex_acquire(&listener_sk->sk_lock.dep_map,
-                                     SINGLE_DEPTH_NESTING, 0, _RET_IP_);
-               }
+
+               /* lockdep will report a false positive ABBA deadlock
+                * between cancel_work_sync and the listener socket.
+                * The involved locks belong to different sockets WRT
+                * the existing AB chain.
+                * Using a per socket key is problematic as key
+                * deregistration requires process context and must be
+                * performed at socket disposal time, in atomic
+                * context.
+                * Just tell lockdep to consider the listener socket
+                * released here.
+                */
+               mutex_release(&listener_sk->sk_lock.dep_map, _RET_IP_);
+               mptcp_cancel_work(sk);
+               mutex_acquire(&listener_sk->sk_lock.dep_map, 0, 0, _RET_IP_);
+
                sock_put(sk);
        }
 
@@ -1932,6 +1949,13 @@ static void subflow_ulp_release(struct sock *ssk)
                 * when the subflow is still unaccepted
                 */
                release = ctx->disposable || list_empty(&ctx->node);
+
+               /* inet_child_forget() does not call sk_state_change(),
+                * explicitly trigger the socket close machinery
+                */
+               if (!release && !test_and_set_bit(MPTCP_WORK_CLOSE_SUBFLOW,
+                                                 &mptcp_sk(sk)->flags))
+                       mptcp_schedule_work(sk);
                sock_put(sk);
        }
 
index 80713febfac6dd1911f83d05eb649888dcb93514..d9da942ad53dd98da908d2b80d98a4827eee4954 100644 (file)
@@ -1803,8 +1803,8 @@ struct ncsi_dev *ncsi_register_dev(struct net_device *dev,
        pdev = to_platform_device(dev->dev.parent);
        if (pdev) {
                np = pdev->dev.of_node;
-               if (np && (of_get_property(np, "mellanox,multi-host", NULL) ||
-                          of_get_property(np, "mlx,multi-host", NULL)))
+               if (np && (of_property_read_bool(np, "mellanox,multi-host") ||
+                          of_property_read_bool(np, "mlx,multi-host")))
                        ndp->mlx_multi_host = true;
        }
 
index 7250082e7de56c77298b0d3b62c4f0dff95b77cc..c6a6a6099b4e2200951367ccd90c12c0ac800a6a 100644 (file)
@@ -96,8 +96,8 @@ static DEFINE_MUTEX(nf_conntrack_mutex);
 #define GC_SCAN_MAX_DURATION   msecs_to_jiffies(10)
 #define GC_SCAN_EXPIRED_MAX    (64000u / HZ)
 
-#define MIN_CHAINLEN   8u
-#define MAX_CHAINLEN   (32u - MIN_CHAINLEN)
+#define MIN_CHAINLEN   50u
+#define MAX_CHAINLEN   (80u - MIN_CHAINLEN)
 
 static struct conntrack_gc_work conntrack_gc_work;
 
index c11dff91d52d2795f72dbc628259275489b1b1a2..bfc3aaa2c872bda90476820c4e62366d9c4f2157 100644 (file)
@@ -328,11 +328,12 @@ nla_put_failure:
 }
 
 #ifdef CONFIG_NF_CONNTRACK_MARK
-static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
+static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct,
+                              bool dump)
 {
        u32 mark = READ_ONCE(ct->mark);
 
-       if (!mark)
+       if (!mark && !dump)
                return 0;
 
        if (nla_put_be32(skb, CTA_MARK, htonl(mark)))
@@ -343,7 +344,7 @@ nla_put_failure:
        return -1;
 }
 #else
-#define ctnetlink_dump_mark(a, b) (0)
+#define ctnetlink_dump_mark(a, b, c) (0)
 #endif
 
 #ifdef CONFIG_NF_CONNTRACK_SECMARK
@@ -548,7 +549,7 @@ static int ctnetlink_dump_extinfo(struct sk_buff *skb,
 static int ctnetlink_dump_info(struct sk_buff *skb, struct nf_conn *ct)
 {
        if (ctnetlink_dump_status(skb, ct) < 0 ||
-           ctnetlink_dump_mark(skb, ct) < 0 ||
+           ctnetlink_dump_mark(skb, ct, true) < 0 ||
            ctnetlink_dump_secctx(skb, ct) < 0 ||
            ctnetlink_dump_id(skb, ct) < 0 ||
            ctnetlink_dump_use(skb, ct) < 0 ||
@@ -831,8 +832,7 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
        }
 
 #ifdef CONFIG_NF_CONNTRACK_MARK
-       if (events & (1 << IPCT_MARK) &&
-           ctnetlink_dump_mark(skb, ct) < 0)
+       if (ctnetlink_dump_mark(skb, ct, events & (1 << IPCT_MARK)))
                goto nla_put_failure;
 #endif
        nlmsg_end(skb, nlh);
@@ -2735,7 +2735,7 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
                goto nla_put_failure;
 
 #ifdef CONFIG_NF_CONNTRACK_MARK
-       if (ctnetlink_dump_mark(skb, ct) < 0)
+       if (ctnetlink_dump_mark(skb, ct, true) < 0)
                goto nla_put_failure;
 #endif
        if (ctnetlink_dump_labels(skb, ct) < 0)
index 6004d4b244518b540302ca48264068a507c2306b..e48ab8dfb54101e02342217acd1d8c08a391fd88 100644 (file)
@@ -3447,6 +3447,64 @@ static int nft_table_validate(struct net *net, const struct nft_table *table)
        return 0;
 }
 
+int nft_setelem_validate(const struct nft_ctx *ctx, struct nft_set *set,
+                        const struct nft_set_iter *iter,
+                        struct nft_set_elem *elem)
+{
+       const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
+       struct nft_ctx *pctx = (struct nft_ctx *)ctx;
+       const struct nft_data *data;
+       int err;
+
+       if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
+           *nft_set_ext_flags(ext) & NFT_SET_ELEM_INTERVAL_END)
+               return 0;
+
+       data = nft_set_ext_data(ext);
+       switch (data->verdict.code) {
+       case NFT_JUMP:
+       case NFT_GOTO:
+               pctx->level++;
+               err = nft_chain_validate(ctx, data->verdict.chain);
+               if (err < 0)
+                       return err;
+               pctx->level--;
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+struct nft_set_elem_catchall {
+       struct list_head        list;
+       struct rcu_head         rcu;
+       void                    *elem;
+};
+
+int nft_set_catchall_validate(const struct nft_ctx *ctx, struct nft_set *set)
+{
+       u8 genmask = nft_genmask_next(ctx->net);
+       struct nft_set_elem_catchall *catchall;
+       struct nft_set_elem elem;
+       struct nft_set_ext *ext;
+       int ret = 0;
+
+       list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
+               ext = nft_set_elem_ext(set, catchall->elem);
+               if (!nft_set_elem_active(ext, genmask))
+                       continue;
+
+               elem.priv = catchall->elem;
+               ret = nft_setelem_validate(ctx, set, NULL, &elem);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return ret;
+}
+
 static struct nft_rule *nft_rule_lookup_byid(const struct net *net,
                                             const struct nft_chain *chain,
                                             const struct nlattr *nla);
@@ -4759,12 +4817,6 @@ err_set_name:
        return err;
 }
 
-struct nft_set_elem_catchall {
-       struct list_head        list;
-       struct rcu_head         rcu;
-       void                    *elem;
-};
-
 static void nft_set_catchall_destroy(const struct nft_ctx *ctx,
                                     struct nft_set *set)
 {
@@ -6056,7 +6108,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
        if (err < 0)
                return err;
 
-       if (!nla[NFTA_SET_ELEM_KEY] && !(flags & NFT_SET_ELEM_CATCHALL))
+       if (((flags & NFT_SET_ELEM_CATCHALL) && nla[NFTA_SET_ELEM_KEY]) ||
+           (!(flags & NFT_SET_ELEM_CATCHALL) && !nla[NFTA_SET_ELEM_KEY]))
                return -EINVAL;
 
        if (flags != 0) {
@@ -7052,7 +7105,7 @@ static int nf_tables_newobj(struct sk_buff *skb, const struct nfnl_info *info,
        }
 
        if (nla[NFTA_OBJ_USERDATA]) {
-               obj->udata = nla_memdup(nla[NFTA_OBJ_USERDATA], GFP_KERNEL);
+               obj->udata = nla_memdup(nla[NFTA_OBJ_USERDATA], GFP_KERNEL_ACCOUNT);
                if (obj->udata == NULL)
                        goto err_userdata;
 
index 7f2bda6641bd8a22566b7f2e910e87324cbecace..8e6d7eaf9dc8b5c783b1a7591ff21608e41dcdaf 100644 (file)
@@ -105,11 +105,15 @@ static void nft_last_destroy(const struct nft_ctx *ctx,
 static int nft_last_clone(struct nft_expr *dst, const struct nft_expr *src)
 {
        struct nft_last_priv *priv_dst = nft_expr_priv(dst);
+       struct nft_last_priv *priv_src = nft_expr_priv(src);
 
        priv_dst->last = kzalloc(sizeof(*priv_dst->last), GFP_ATOMIC);
        if (!priv_dst->last)
                return -ENOMEM;
 
+       priv_dst->last->set = priv_src->last->set;
+       priv_dst->last->jiffies = priv_src->last->jiffies;
+
        return 0;
 }
 
index cae5a67241634edacda0ddc8f90aa72932dca507..cecf8ab90e58f7e84dd73168f69c87a50811837c 100644 (file)
@@ -199,37 +199,6 @@ nla_put_failure:
        return -1;
 }
 
-static int nft_lookup_validate_setelem(const struct nft_ctx *ctx,
-                                      struct nft_set *set,
-                                      const struct nft_set_iter *iter,
-                                      struct nft_set_elem *elem)
-{
-       const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
-       struct nft_ctx *pctx = (struct nft_ctx *)ctx;
-       const struct nft_data *data;
-       int err;
-
-       if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
-           *nft_set_ext_flags(ext) & NFT_SET_ELEM_INTERVAL_END)
-               return 0;
-
-       data = nft_set_ext_data(ext);
-       switch (data->verdict.code) {
-       case NFT_JUMP:
-       case NFT_GOTO:
-               pctx->level++;
-               err = nft_chain_validate(ctx, data->verdict.chain);
-               if (err < 0)
-                       return err;
-               pctx->level--;
-               break;
-       default:
-               break;
-       }
-
-       return 0;
-}
-
 static int nft_lookup_validate(const struct nft_ctx *ctx,
                               const struct nft_expr *expr,
                               const struct nft_data **d)
@@ -245,9 +214,12 @@ static int nft_lookup_validate(const struct nft_ctx *ctx,
        iter.skip       = 0;
        iter.count      = 0;
        iter.err        = 0;
-       iter.fn         = nft_lookup_validate_setelem;
+       iter.fn         = nft_setelem_validate;
 
        priv->set->ops->walk(ctx, priv->set, &iter);
+       if (!iter.err)
+               iter.err = nft_set_catchall_validate(ctx, priv->set);
+
        if (iter.err < 0)
                return iter.err;
 
index e55e455275c48ea8875d09e45c474527464c366c..9544c2f16998bf75420576d9a1fad8313297f4d0 100644 (file)
@@ -43,7 +43,7 @@ static int nft_masq_init(const struct nft_ctx *ctx,
                         const struct nft_expr *expr,
                         const struct nlattr * const tb[])
 {
-       u32 plen = sizeof_field(struct nf_nat_range, min_addr.all);
+       u32 plen = sizeof_field(struct nf_nat_range, min_proto.all);
        struct nft_masq *priv = nft_expr_priv(expr);
        int err;
 
index 0479991503900ec24b8ce7391481b46713c1de9b..5c29915ab0289ee615a47a0d336cead0b377cef2 100644 (file)
@@ -226,7 +226,7 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
                priv->flags |= NF_NAT_RANGE_MAP_IPS;
        }
 
-       plen = sizeof_field(struct nf_nat_range, min_addr.all);
+       plen = sizeof_field(struct nf_nat_range, min_proto.all);
        if (tb[NFTA_NAT_REG_PROTO_MIN]) {
                err = nft_parse_register_load(tb[NFTA_NAT_REG_PROTO_MIN],
                                              &priv->sreg_proto_min, plen);
index 123578e289179cd053bc48e02fbd83a07c8dcf13..3ba12a7471b0f6210947cd09db9f582012f3d8c5 100644 (file)
@@ -236,12 +236,16 @@ static void nft_quota_destroy(const struct nft_ctx *ctx,
 static int nft_quota_clone(struct nft_expr *dst, const struct nft_expr *src)
 {
        struct nft_quota *priv_dst = nft_expr_priv(dst);
+       struct nft_quota *priv_src = nft_expr_priv(src);
+
+       priv_dst->quota = priv_src->quota;
+       priv_dst->flags = priv_src->flags;
 
        priv_dst->consumed = kmalloc(sizeof(*priv_dst->consumed), GFP_ATOMIC);
        if (!priv_dst->consumed)
                return -ENOMEM;
 
-       atomic64_set(priv_dst->consumed, 0);
+       *priv_dst->consumed = *priv_src->consumed;
 
        return 0;
 }
index 5f77399875593ba6dd88d6ea54fdae904eb6cd69..67cec56bc84a35ca111853b58f799953b56eef6c 100644 (file)
@@ -48,7 +48,7 @@ static int nft_redir_init(const struct nft_ctx *ctx,
        unsigned int plen;
        int err;
 
-       plen = sizeof_field(struct nf_nat_range, min_addr.all);
+       plen = sizeof_field(struct nf_nat_range, min_proto.all);
        if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
                err = nft_parse_register_load(tb[NFTA_REDIR_REG_PROTO_MIN],
                                              &priv->sreg_proto_min, plen);
@@ -236,7 +236,7 @@ static struct nft_expr_type nft_redir_inet_type __read_mostly = {
        .name           = "redir",
        .ops            = &nft_redir_inet_ops,
        .policy         = nft_redir_policy,
-       .maxattr        = NFTA_MASQ_MAX,
+       .maxattr        = NFTA_REDIR_MAX,
        .owner          = THIS_MODULE,
 };
 
index c6427765975318b4c7fe3d5291dc4d69988f5249..f365dfdd672d7576b02bd5ae2871cf317e879248 100644 (file)
@@ -1952,7 +1952,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
        struct scm_cookie scm;
        struct sock *sk = sock->sk;
        struct netlink_sock *nlk = nlk_sk(sk);
-       size_t copied;
+       size_t copied, max_recvmsg_len;
        struct sk_buff *skb, *data_skb;
        int err, ret;
 
@@ -1985,9 +1985,10 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 #endif
 
        /* Record the max length of recvmsg() calls for future allocations */
-       nlk->max_recvmsg_len = max(nlk->max_recvmsg_len, len);
-       nlk->max_recvmsg_len = min_t(size_t, nlk->max_recvmsg_len,
-                                    SKB_WITH_OVERHEAD(32768));
+       max_recvmsg_len = max(READ_ONCE(nlk->max_recvmsg_len), len);
+       max_recvmsg_len = min_t(size_t, max_recvmsg_len,
+                               SKB_WITH_OVERHEAD(32768));
+       WRITE_ONCE(nlk->max_recvmsg_len, max_recvmsg_len);
 
        copied = data_skb->len;
        if (len < copied) {
@@ -2236,6 +2237,7 @@ static int netlink_dump(struct sock *sk)
        struct netlink_ext_ack extack = {};
        struct netlink_callback *cb;
        struct sk_buff *skb = NULL;
+       size_t max_recvmsg_len;
        struct module *module;
        int err = -ENOBUFS;
        int alloc_min_size;
@@ -2258,8 +2260,9 @@ static int netlink_dump(struct sock *sk)
        cb = &nlk->cb;
        alloc_min_size = max_t(int, cb->min_dump_alloc, NLMSG_GOODSIZE);
 
-       if (alloc_min_size < nlk->max_recvmsg_len) {
-               alloc_size = nlk->max_recvmsg_len;
+       max_recvmsg_len = READ_ONCE(nlk->max_recvmsg_len);
+       if (alloc_min_size < max_recvmsg_len) {
+               alloc_size = max_recvmsg_len;
                skb = alloc_skb(alloc_size,
                                (GFP_KERNEL & ~__GFP_DIRECT_RECLAIM) |
                                __GFP_NOWARN | __GFP_NORETRY);
index 348bf561bc9fb0502dcfc340fd7079d469a6a449..b9264e730fd931f4b3861ae88a2aabe52061e94e 100644 (file)
@@ -1446,8 +1446,8 @@ static int nfc_se_io(struct nfc_dev *dev, u32 se_idx,
        return rc;
 
 error:
-       kfree(cb_context);
        device_unlock(&dev->dev);
+       kfree(cb_context);
        return rc;
 }
 
index ca3ebfdb30231dd48b22cc36d8890c5e4b39223d..a8cf9a88758ef555743e3873648a1ea14b07c0a2 100644 (file)
@@ -913,7 +913,7 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
 {
        struct vport *vport = ovs_vport_rcu(dp, out_port);
 
-       if (likely(vport)) {
+       if (likely(vport && netif_carrier_ok(vport->dev))) {
                u16 mru = OVS_CB(skb)->mru;
                u32 cutlen = OVS_CB(skb)->cutlen;
 
index 5c2fb992803b7acbeed3d712104d45d7e0b3c68f..76f0434d3d06a48b80d80c54241440ff4ce8ea9c 100644 (file)
@@ -393,10 +393,12 @@ static struct qrtr_node *qrtr_node_lookup(unsigned int nid)
        struct qrtr_node *node;
        unsigned long flags;
 
+       mutex_lock(&qrtr_node_lock);
        spin_lock_irqsave(&qrtr_nodes_lock, flags);
        node = radix_tree_lookup(&qrtr_nodes, nid);
        node = qrtr_node_acquire(node);
        spin_unlock_irqrestore(&qrtr_nodes_lock, flags);
+       mutex_unlock(&qrtr_node_lock);
 
        return node;
 }
@@ -496,6 +498,11 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
        if (!size || len != ALIGN(size, 4) + hdrlen)
                goto err;
 
+       if ((cb->type == QRTR_TYPE_NEW_SERVER ||
+            cb->type == QRTR_TYPE_RESUME_TX) &&
+           size < sizeof(struct qrtr_ctrl_pkt))
+               goto err;
+
        if (cb->dst_port != QRTR_PORT_CTRL && cb->type != QRTR_TYPE_DATA &&
            cb->type != QRTR_TYPE_RESUME_TX)
                goto err;
@@ -508,9 +515,6 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
                /* Remote node endpoint can bridge other distant nodes */
                const struct qrtr_ctrl_pkt *pkt;
 
-               if (size < sizeof(*pkt))
-                       goto err;
-
                pkt = data + hdrlen;
                qrtr_node_assign(node, le32_to_cpu(pkt->server.node));
        }
index 722936f7dd988984d0351839c22a3a7319208c3e..0f25a386138c91af11f87d086fda5bc19a85aaf9 100644 (file)
@@ -274,7 +274,7 @@ err:
        return NULL;
 }
 
-static int server_del(struct qrtr_node *node, unsigned int port)
+static int server_del(struct qrtr_node *node, unsigned int port, bool bcast)
 {
        struct qrtr_lookup *lookup;
        struct qrtr_server *srv;
@@ -287,7 +287,7 @@ static int server_del(struct qrtr_node *node, unsigned int port)
        radix_tree_delete(&node->servers, port);
 
        /* Broadcast the removal of local servers */
-       if (srv->node == qrtr_ns.local_node)
+       if (srv->node == qrtr_ns.local_node && bcast)
                service_announce_del(&qrtr_ns.bcast_sq, srv);
 
        /* Announce the service's disappearance to observers */
@@ -373,7 +373,7 @@ static int ctrl_cmd_bye(struct sockaddr_qrtr *from)
                }
                slot = radix_tree_iter_resume(slot, &iter);
                rcu_read_unlock();
-               server_del(node, srv->port);
+               server_del(node, srv->port, true);
                rcu_read_lock();
        }
        rcu_read_unlock();
@@ -459,10 +459,13 @@ static int ctrl_cmd_del_client(struct sockaddr_qrtr *from,
                kfree(lookup);
        }
 
-       /* Remove the server belonging to this port */
+       /* Remove the server belonging to this port but don't broadcast
+        * DEL_SERVER. Neighbours would've already removed the server belonging
+        * to this port due to the DEL_CLIENT broadcast from qrtr_port_remove().
+        */
        node = node_get(node_id);
        if (node)
-               server_del(node, port);
+               server_del(node, port, false);
 
        /* Advertise the removal of this client to all local servers */
        local_node = node_get(qrtr_ns.local_node);
@@ -567,7 +570,7 @@ static int ctrl_cmd_del_server(struct sockaddr_qrtr *from,
        if (!node)
                return -ENOENT;
 
-       return server_del(node, port);
+       return server_del(node, port, true);
 }
 
 static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from,
index 34c50867504160d02d413ea211c075525ad6bf26..296fc1afedd82bdaed2e08aa12a03180a1ff7184 100644 (file)
@@ -1589,6 +1589,10 @@ static int tca_get_fill(struct sk_buff *skb, struct tc_action *actions[],
        t->tca__pad1 = 0;
        t->tca__pad2 = 0;
 
+       if (extack && extack->_msg &&
+           nla_put_string(skb, TCA_ROOT_EXT_WARN_MSG, extack->_msg))
+               goto out_nlmsg_trim;
+
        nest = nla_nest_start_noflag(skb, TCA_ACT_TAB);
        if (!nest)
                goto out_nlmsg_trim;
@@ -1596,10 +1600,6 @@ static int tca_get_fill(struct sk_buff *skb, struct tc_action *actions[],
        if (tcf_action_dump(skb, actions, bind, ref, false) < 0)
                goto out_nlmsg_trim;
 
-       if (extack && extack->_msg &&
-           nla_put_string(skb, TCA_EXT_WARN_MSG, extack->_msg))
-               goto out_nlmsg_trim;
-
        nla_nest_end(skb, nest);
 
        nlh->nlmsg_len = skb_tail_pointer(skb) - b;
index 8dabfb52ea3db383e5172ab07e18792fa3d91341..0d7aee8933c5ffdc5acdb78138a9725ef63824f5 100644 (file)
@@ -158,6 +158,9 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
                nparms->zone = parm->zone;
 
                ret = 0;
+       } else {
+               err = ret;
+               goto out_free;
        }
 
        err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack);
index 2a6b6be0811b84129306409bc55ca553bda3c70a..35785a36c80298f086d6b27f63dfaeb80dfec65f 100644 (file)
@@ -3235,6 +3235,9 @@ int tcf_exts_init_ex(struct tcf_exts *exts, struct net *net, int action,
 
 err_miss_alloc:
        tcf_exts_destroy(exts);
+#ifdef CONFIG_NET_CLS_ACT
+       exts->actions = NULL;
+#endif
        return err;
 }
 EXPORT_SYMBOL(tcf_exts_init_ex);
index e960a46b05205bb0bca7dc0d21531e4d6a3853e3..475fe222a85566639bac75fc4a95bf649a10357d 100644 (file)
@@ -2200,8 +2200,9 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
                fnew->flags = nla_get_u32(tb[TCA_FLOWER_FLAGS]);
 
                if (!tc_flags_valid(fnew->flags)) {
+                       kfree(fnew);
                        err = -EINVAL;
-                       goto errout;
+                       goto errout_tb;
                }
        }
 
@@ -2226,8 +2227,10 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
                }
                spin_unlock(&tp->lock);
 
-               if (err)
-                       goto errout;
+               if (err) {
+                       kfree(fnew);
+                       goto errout_tb;
+               }
        }
        fnew->handle = handle;
 
@@ -2337,7 +2340,6 @@ errout_mask:
        fl_mask_put(head, fnew->mask);
 errout_idr:
        idr_remove(&head->handle_idr, fnew->handle);
-errout:
        __fl_put(fnew);
 errout_tb:
        kfree(tb);
index cf5ebe43b3b4eb7f163da31cc565bc7faaab69e5..02098a02943eb90a67cce829b26a4cf9b79e545c 100644 (file)
@@ -421,15 +421,16 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
        } else
                weight = 1;
 
-       if (tb[TCA_QFQ_LMAX]) {
+       if (tb[TCA_QFQ_LMAX])
                lmax = nla_get_u32(tb[TCA_QFQ_LMAX]);
-               if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) {
-                       pr_notice("qfq: invalid max length %u\n", lmax);
-                       return -EINVAL;
-               }
-       } else
+       else
                lmax = psched_mtu(qdisc_dev(sch));
 
+       if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) {
+               pr_notice("qfq: invalid max length %u\n", lmax);
+               return -EINVAL;
+       }
+
        inv_w = ONE_FP / weight;
        weight = ONE_FP / inv_w;
 
index b91616f819def9e7e067c3e82d26d36a2d34c17e..218e0982c370726b7ea1a7e5c32ce0de3ad9ab2d 100644 (file)
@@ -1830,6 +1830,10 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc,
                err = sctp_wait_for_sndbuf(asoc, &timeo, msg_len);
                if (err)
                        goto err;
+               if (unlikely(sinfo->sinfo_stream >= asoc->stream.outcnt)) {
+                       err = -EINVAL;
+                       goto err;
+               }
        }
 
        if (sctp_state(asoc, CLOSED)) {
index 94727feb07b3e0ebd80e88acf5d08ed19f24da0f..b046b11200c93e53f1df4a91d061449772a643d1 100644 (file)
@@ -1154,7 +1154,8 @@ static void sctp_generate_iftsn(struct sctp_outq *q, __u32 ctsn)
 
 #define _sctp_walk_ifwdtsn(pos, chunk, end) \
        for (pos = chunk->subh.ifwdtsn_hdr->skip; \
-            (void *)pos < (void *)chunk->subh.ifwdtsn_hdr->skip + (end); pos++)
+            (void *)pos <= (void *)chunk->subh.ifwdtsn_hdr->skip + (end) - \
+                           sizeof(struct sctp_ifwdtsn_skip); pos++)
 
 #define sctp_walk_ifwdtsn(pos, ch) \
        _sctp_walk_ifwdtsn((pos), (ch), ntohs((ch)->chunk_hdr->length) - \
index a4cccdfdc00a242ba2334f06404e6cd663bd91de..50c38b624f772c05d8ecd2745da8fa719d6dc4b1 100644 (file)
@@ -2657,16 +2657,14 @@ static int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
 {
        struct sock *sk = sock->sk;
        struct smc_sock *smc;
-       int rc = -EPIPE;
+       int rc;
 
        smc = smc_sk(sk);
        lock_sock(sk);
-       if ((sk->sk_state != SMC_ACTIVE) &&
-           (sk->sk_state != SMC_APPCLOSEWAIT1) &&
-           (sk->sk_state != SMC_INIT))
-               goto out;
 
+       /* SMC does not support connect with fastopen */
        if (msg->msg_flags & MSG_FASTOPEN) {
+               /* not connected yet, fallback */
                if (sk->sk_state == SMC_INIT && !smc->connect_nonblock) {
                        rc = smc_switch_to_fallback(smc, SMC_CLC_DECL_OPTUNSUPP);
                        if (rc)
@@ -2675,6 +2673,11 @@ static int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
                        rc = -EINVAL;
                        goto out;
                }
+       } else if ((sk->sk_state != SMC_ACTIVE) &&
+                  (sk->sk_state != SMC_APPCLOSEWAIT1) &&
+                  (sk->sk_state != SMC_INIT)) {
+               rc = -EPIPE;
+               goto out;
        }
 
        if (smc->use_fallback) {
@@ -3267,6 +3270,17 @@ static int __smc_create(struct net *net, struct socket *sock, int protocol,
                        sk_common_release(sk);
                        goto out;
                }
+
+               /* smc_clcsock_release() does not wait smc->clcsock->sk's
+                * destruction;  its sk_state might not be TCP_CLOSE after
+                * smc->sk is close()d, and TCP timers can be fired later,
+                * which need net ref.
+                */
+               sk = smc->clcsock->sk;
+               __netns_tracker_free(net, &sk->ns_tracker, false);
+               sk->sk_net_refcnt = 1;
+               get_net_track(net, &sk->ns_tracker, GFP_KERNEL);
+               sock_inuse_add(net, 1);
        } else {
                smc->clcsock = clcsock;
        }
@@ -3498,6 +3512,7 @@ out_pnet:
 out_nl:
        smc_nl_exit();
 out_ism:
+       smc_clc_exit();
        smc_ism_exit();
 out_pernet_subsys_stat:
        unregister_pernet_subsys(&smc_net_stat_ops);
index 53f63bfbaf5f92915bb7af4e02fe8fe2e96b89f2..89105e95b4523f0a0d197e7167f27914430f482e 100644 (file)
@@ -114,6 +114,9 @@ int smc_cdc_msg_send(struct smc_connection *conn,
        union smc_host_cursor cfed;
        int rc;
 
+       if (unlikely(!READ_ONCE(conn->sndbuf_desc)))
+               return -ENOBUFS;
+
        smc_cdc_add_pending_send(conn, pend);
 
        conn->tx_cdc_seq++;
index d52060b2680cf0090cb91f454a27f22b10ff2e02..454356771cda55b10c496cbebc470c273d4c56ea 100644 (file)
@@ -1464,7 +1464,7 @@ static void __smc_lgr_terminate(struct smc_link_group *lgr, bool soft)
        if (lgr->terminating)
                return; /* lgr already terminating */
        /* cancel free_work sync, will terminate when lgr->freeing is set */
-       cancel_delayed_work_sync(&lgr->free_work);
+       cancel_delayed_work(&lgr->free_work);
        lgr->terminating = 1;
 
        /* kill remaining link group connections */
index 6bae8ce7059ee97a8e8cee3fa5726bf6ae0b6e86..9c92c0e6c4da8c54f4878172f17f1d1be757f706 100644 (file)
@@ -450,7 +450,9 @@ static struct file_system_type sock_fs_type = {
  *
  *     Returns the &file bound with @sock, implicitly storing it
  *     in sock->file. If dname is %NULL, sets to "".
- *     On failure the return is a ERR pointer (see linux/err.h).
+ *
+ *     On failure @sock is released, and an ERR pointer is returned.
+ *
  *     This function uses GFP_KERNEL internally.
  */
 
@@ -1638,7 +1640,6 @@ static struct socket *__sys_socket_create(int family, int type, int protocol)
 struct file *__sys_socket_file(int family, int type, int protocol)
 {
        struct socket *sock;
-       struct file *file;
        int flags;
 
        sock = __sys_socket_create(family, type, protocol);
@@ -1649,11 +1650,7 @@ struct file *__sys_socket_file(int family, int type, int protocol)
        if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
                flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
 
-       file = sock_alloc_file(sock, flags, NULL);
-       if (IS_ERR(file))
-               sock_release(sock);
-
-       return file;
+       return sock_alloc_file(sock, flags, NULL);
 }
 
 int __sys_socket(int family, int type, int protocol)
index 6c7c52eeed4f85773c71fea22879d04b14a9f665..212c5d57465a1bf56afc96af1e91d135ca6e1325 100644 (file)
@@ -353,7 +353,9 @@ gss_krb5_checksum(struct crypto_ahash *tfm, char *header, int hdrlen,
        err = crypto_ahash_final(req);
        if (err)
                goto out_free_ahash;
-       memcpy(cksumout->data, checksumdata, cksumout->len);
+
+       memcpy(cksumout->data, checksumdata,
+              min_t(int, cksumout->len, crypto_ahash_digestsize(tfm)));
 
 out_free_ahash:
        ahash_request_free(req);
@@ -809,8 +811,7 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset,
        buf->tail[0].iov_len += GSS_KRB5_TOK_HDR_LEN;
        buf->len += GSS_KRB5_TOK_HDR_LEN;
 
-       /* Do the HMAC */
-       hmac.len = GSS_KRB5_MAX_CKSUM_LEN;
+       hmac.len = kctx->gk5e->cksumlength;
        hmac.data = buf->tail[0].iov_base + buf->tail[0].iov_len;
 
        /*
@@ -873,8 +874,7 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len,
        if (ret)
                goto out_err;
 
-       /* Calculate our hmac over the plaintext data */
-       our_hmac_obj.len = sizeof(our_hmac);
+       our_hmac_obj.len = kctx->gk5e->cksumlength;
        our_hmac_obj.data = our_hmac;
        ret = gss_krb5_checksum(ahash, NULL, 0, &subbuf, 0, &our_hmac_obj);
        if (ret)
index ce0541e32fc9827bbc2eb355c5b71b82734da48e..95ca783795c5e241fc36ec9c58b6c0d12afef9d3 100644 (file)
@@ -73,7 +73,6 @@ static void checksum_case(struct kunit *test)
 {
        const struct gss_krb5_test_param *param = test->param_value;
        struct xdr_buf buf = {
-               .head[0].iov_base       = param->plaintext->data,
                .head[0].iov_len        = param->plaintext->len,
                .len                    = param->plaintext->len,
        };
@@ -99,6 +98,10 @@ static void checksum_case(struct kunit *test)
        err = crypto_ahash_setkey(tfm, Kc.data, Kc.len);
        KUNIT_ASSERT_EQ(test, err, 0);
 
+       buf.head[0].iov_base = kunit_kzalloc(test, buf.head[0].iov_len, GFP_KERNEL);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf.head[0].iov_base);
+       memcpy(buf.head[0].iov_base, param->plaintext->data, buf.head[0].iov_len);
+
        checksum.len = gk5e->cksumlength;
        checksum.data = kunit_kzalloc(test, checksum.len, GFP_KERNEL);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, checksum.data);
@@ -1327,6 +1330,7 @@ static void rfc6803_encrypt_case(struct kunit *test)
        if (!gk5e)
                kunit_skip(test, "Encryption type is not available");
 
+       memset(usage_data, 0, sizeof(usage_data));
        usage.data[3] = param->constant;
 
        Ke.len = gk5e->Ke_length;
index 1fd3f5e572854750575fc0ee0a714b5b3ecca33b..fea7ce8fba14e4a54e2d49fcbd163da110b0ec26 100644 (file)
@@ -798,6 +798,7 @@ svc_start_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
 static int
 svc_stop_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
 {
+       struct svc_rqst *rqstp;
        struct task_struct *task;
        unsigned int state = serv->sv_nrthreads-1;
 
@@ -806,7 +807,10 @@ svc_stop_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
                task = choose_victim(serv, pool, &state);
                if (task == NULL)
                        break;
-               kthread_stop(task);
+               rqstp = kthread_data(task);
+               /* Did we lose a race to svo_function threadfn? */
+               if (kthread_stop(task) == -EINTR)
+                       svc_exit_thread(rqstp);
                nrservs++;
        } while (nrservs < 0);
        return 0;
index 983c5891cb5655fe7ddedf1e5053229ea349b429..4246363cb0951c0fba470844ee63ed22d2bc7de9 100644 (file)
@@ -416,14 +416,23 @@ static int unix_gid_hash(kuid_t uid)
        return hash_long(from_kuid(&init_user_ns, uid), GID_HASHBITS);
 }
 
-static void unix_gid_put(struct kref *kref)
+static void unix_gid_free(struct rcu_head *rcu)
 {
-       struct cache_head *item = container_of(kref, struct cache_head, ref);
-       struct unix_gid *ug = container_of(item, struct unix_gid, h);
+       struct unix_gid *ug = container_of(rcu, struct unix_gid, rcu);
+       struct cache_head *item = &ug->h;
+
        if (test_bit(CACHE_VALID, &item->flags) &&
            !test_bit(CACHE_NEGATIVE, &item->flags))
                put_group_info(ug->gi);
-       kfree_rcu(ug, rcu);
+       kfree(ug);
+}
+
+static void unix_gid_put(struct kref *kref)
+{
+       struct cache_head *item = container_of(kref, struct cache_head, ref);
+       struct unix_gid *ug = container_of(item, struct unix_gid, h);
+
+       call_rcu(&ug->rcu, unix_gid_free);
 }
 
 static int unix_gid_match(struct cache_head *corig, struct cache_head *cnew)
index adcbedc244d63f70804ad73f290bfaa2e7c4be3b..6cacd70a15ffa15ed7f70d073cd9d23410d41784 100644 (file)
@@ -2158,6 +2158,7 @@ static void xs_tcp_shutdown(struct rpc_xprt *xprt)
        switch (skst) {
        case TCP_FIN_WAIT1:
        case TCP_FIN_WAIT2:
+       case TCP_LAST_ACK:
                break;
        case TCP_ESTABLISHED:
        case TCP_CLOSE_WAIT:
index 6c593788dc250682cabedcf37332e75ee3b6ce66..a7cc4f9faac28ce10d3088570d2a44f5bef9a8e1 100644 (file)
@@ -508,6 +508,8 @@ handle_error:
                        zc_pfrag.offset = iter_offset.offset;
                        zc_pfrag.size = copy;
                        tls_append_frag(record, &zc_pfrag, copy);
+
+                       iter_offset.offset += copy;
                } else if (copy) {
                        copy = min_t(size_t, copy, pfrag->size - pfrag->offset);
 
index 3735cb00905dfc7b0a12343308c4fae72f1bb839..b32c112984dd9567fd9d07cc6850f234c1914a43 100644 (file)
@@ -405,13 +405,11 @@ static int do_tls_getsockopt_conf(struct sock *sk, char __user *optval,
                        rc = -EINVAL;
                        goto out;
                }
-               lock_sock(sk);
                memcpy(crypto_info_aes_gcm_128->iv,
                       cctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
                       TLS_CIPHER_AES_GCM_128_IV_SIZE);
                memcpy(crypto_info_aes_gcm_128->rec_seq, cctx->rec_seq,
                       TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-               release_sock(sk);
                if (copy_to_user(optval,
                                 crypto_info_aes_gcm_128,
                                 sizeof(*crypto_info_aes_gcm_128)))
@@ -429,13 +427,11 @@ static int do_tls_getsockopt_conf(struct sock *sk, char __user *optval,
                        rc = -EINVAL;
                        goto out;
                }
-               lock_sock(sk);
                memcpy(crypto_info_aes_gcm_256->iv,
                       cctx->iv + TLS_CIPHER_AES_GCM_256_SALT_SIZE,
                       TLS_CIPHER_AES_GCM_256_IV_SIZE);
                memcpy(crypto_info_aes_gcm_256->rec_seq, cctx->rec_seq,
                       TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-               release_sock(sk);
                if (copy_to_user(optval,
                                 crypto_info_aes_gcm_256,
                                 sizeof(*crypto_info_aes_gcm_256)))
@@ -451,13 +447,11 @@ static int do_tls_getsockopt_conf(struct sock *sk, char __user *optval,
                        rc = -EINVAL;
                        goto out;
                }
-               lock_sock(sk);
                memcpy(aes_ccm_128->iv,
                       cctx->iv + TLS_CIPHER_AES_CCM_128_SALT_SIZE,
                       TLS_CIPHER_AES_CCM_128_IV_SIZE);
                memcpy(aes_ccm_128->rec_seq, cctx->rec_seq,
                       TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
-               release_sock(sk);
                if (copy_to_user(optval, aes_ccm_128, sizeof(*aes_ccm_128)))
                        rc = -EFAULT;
                break;
@@ -472,13 +466,11 @@ static int do_tls_getsockopt_conf(struct sock *sk, char __user *optval,
                        rc = -EINVAL;
                        goto out;
                }
-               lock_sock(sk);
                memcpy(chacha20_poly1305->iv,
                       cctx->iv + TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE,
                       TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
                memcpy(chacha20_poly1305->rec_seq, cctx->rec_seq,
                       TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE);
-               release_sock(sk);
                if (copy_to_user(optval, chacha20_poly1305,
                                sizeof(*chacha20_poly1305)))
                        rc = -EFAULT;
@@ -493,13 +485,11 @@ static int do_tls_getsockopt_conf(struct sock *sk, char __user *optval,
                        rc = -EINVAL;
                        goto out;
                }
-               lock_sock(sk);
                memcpy(sm4_gcm_info->iv,
                       cctx->iv + TLS_CIPHER_SM4_GCM_SALT_SIZE,
                       TLS_CIPHER_SM4_GCM_IV_SIZE);
                memcpy(sm4_gcm_info->rec_seq, cctx->rec_seq,
                       TLS_CIPHER_SM4_GCM_REC_SEQ_SIZE);
-               release_sock(sk);
                if (copy_to_user(optval, sm4_gcm_info, sizeof(*sm4_gcm_info)))
                        rc = -EFAULT;
                break;
@@ -513,13 +503,11 @@ static int do_tls_getsockopt_conf(struct sock *sk, char __user *optval,
                        rc = -EINVAL;
                        goto out;
                }
-               lock_sock(sk);
                memcpy(sm4_ccm_info->iv,
                       cctx->iv + TLS_CIPHER_SM4_CCM_SALT_SIZE,
                       TLS_CIPHER_SM4_CCM_IV_SIZE);
                memcpy(sm4_ccm_info->rec_seq, cctx->rec_seq,
                       TLS_CIPHER_SM4_CCM_REC_SEQ_SIZE);
-               release_sock(sk);
                if (copy_to_user(optval, sm4_ccm_info, sizeof(*sm4_ccm_info)))
                        rc = -EFAULT;
                break;
@@ -535,13 +523,11 @@ static int do_tls_getsockopt_conf(struct sock *sk, char __user *optval,
                        rc = -EINVAL;
                        goto out;
                }
-               lock_sock(sk);
                memcpy(crypto_info_aria_gcm_128->iv,
                       cctx->iv + TLS_CIPHER_ARIA_GCM_128_SALT_SIZE,
                       TLS_CIPHER_ARIA_GCM_128_IV_SIZE);
                memcpy(crypto_info_aria_gcm_128->rec_seq, cctx->rec_seq,
                       TLS_CIPHER_ARIA_GCM_128_REC_SEQ_SIZE);
-               release_sock(sk);
                if (copy_to_user(optval,
                                 crypto_info_aria_gcm_128,
                                 sizeof(*crypto_info_aria_gcm_128)))
@@ -559,13 +545,11 @@ static int do_tls_getsockopt_conf(struct sock *sk, char __user *optval,
                        rc = -EINVAL;
                        goto out;
                }
-               lock_sock(sk);
                memcpy(crypto_info_aria_gcm_256->iv,
                       cctx->iv + TLS_CIPHER_ARIA_GCM_256_SALT_SIZE,
                       TLS_CIPHER_ARIA_GCM_256_IV_SIZE);
                memcpy(crypto_info_aria_gcm_256->rec_seq, cctx->rec_seq,
                       TLS_CIPHER_ARIA_GCM_256_REC_SEQ_SIZE);
-               release_sock(sk);
                if (copy_to_user(optval,
                                 crypto_info_aria_gcm_256,
                                 sizeof(*crypto_info_aria_gcm_256)))
@@ -614,11 +598,9 @@ static int do_tls_getsockopt_no_pad(struct sock *sk, char __user *optval,
        if (len < sizeof(value))
                return -EINVAL;
 
-       lock_sock(sk);
        value = -EINVAL;
        if (ctx->rx_conf == TLS_SW || ctx->rx_conf == TLS_HW)
                value = ctx->rx_no_pad;
-       release_sock(sk);
        if (value < 0)
                return value;
 
@@ -635,6 +617,8 @@ static int do_tls_getsockopt(struct sock *sk, int optname,
 {
        int rc = 0;
 
+       lock_sock(sk);
+
        switch (optname) {
        case TLS_TX:
        case TLS_RX:
@@ -651,6 +635,9 @@ static int do_tls_getsockopt(struct sock *sk, int optname,
                rc = -ENOPROTOOPT;
                break;
        }
+
+       release_sock(sk);
+
        return rc;
 }
 
index 782d3701b86f45802d564a91a47e2aaeed5396ba..635b8bf6b937c1d362c62a527d9656c11e97df6b 100644 (file)
@@ -956,7 +956,9 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
                               MSG_CMSG_COMPAT))
                return -EOPNOTSUPP;
 
-       mutex_lock(&tls_ctx->tx_lock);
+       ret = mutex_lock_interruptible(&tls_ctx->tx_lock);
+       if (ret)
+               return ret;
        lock_sock(sk);
 
        if (unlikely(msg->msg_controllen)) {
@@ -1290,7 +1292,9 @@ int tls_sw_sendpage(struct sock *sk, struct page *page,
                      MSG_SENDPAGE_NOTLAST | MSG_SENDPAGE_NOPOLICY))
                return -EOPNOTSUPP;
 
-       mutex_lock(&tls_ctx->tx_lock);
+       ret = mutex_lock_interruptible(&tls_ctx->tx_lock);
+       if (ret)
+               return ret;
        lock_sock(sk);
        ret = tls_sw_do_sendpage(sk, page, offset, size, flags);
        release_sock(sk);
@@ -2127,7 +2131,7 @@ recv_end:
                else
                        err = process_rx_list(ctx, msg, &control, 0,
                                              async_copy_bytes, is_peek);
-               decrypted = max(err, 0);
+               decrypted += max(err, 0);
        }
 
        copied += decrypted;
@@ -2435,11 +2439,19 @@ static void tx_work_handler(struct work_struct *work)
 
        if (!test_and_clear_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask))
                return;
-       mutex_lock(&tls_ctx->tx_lock);
-       lock_sock(sk);
-       tls_tx_records(sk, -1);
-       release_sock(sk);
-       mutex_unlock(&tls_ctx->tx_lock);
+
+       if (mutex_trylock(&tls_ctx->tx_lock)) {
+               lock_sock(sk);
+               tls_tx_records(sk, -1);
+               release_sock(sk);
+               mutex_unlock(&tls_ctx->tx_lock);
+       } else if (!test_and_set_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask)) {
+               /* Someone is holding the tx_lock, they will likely run Tx
+                * and cancel the work on their way out of the lock section.
+                * Schedule a long delay just in case.
+                */
+               schedule_delayed_work(&ctx->tx_work.work, msecs_to_jiffies(10));
+       }
 }
 
 static bool tls_is_tx_ready(struct tls_sw_context_tx *ctx)
index 347122c3575eaae597405369e2e9d8324d6ad240..0b0f18ecce4470d6fd21c084a3ea49e04dcbb9bd 100644 (file)
@@ -2105,7 +2105,8 @@ out:
 #define UNIX_SKB_FRAGS_SZ (PAGE_SIZE << get_order(32768))
 
 #if IS_ENABLED(CONFIG_AF_UNIX_OOB)
-static int queue_oob(struct socket *sock, struct msghdr *msg, struct sock *other)
+static int queue_oob(struct socket *sock, struct msghdr *msg, struct sock *other,
+                    struct scm_cookie *scm, bool fds_sent)
 {
        struct unix_sock *ousk = unix_sk(other);
        struct sk_buff *skb;
@@ -2116,6 +2117,11 @@ static int queue_oob(struct socket *sock, struct msghdr *msg, struct sock *other
        if (!skb)
                return err;
 
+       err = unix_scm_to_skb(scm, skb, !fds_sent);
+       if (err < 0) {
+               kfree_skb(skb);
+               return err;
+       }
        skb_put(skb, 1);
        err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, 1);
 
@@ -2243,7 +2249,7 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 
 #if IS_ENABLED(CONFIG_AF_UNIX_OOB)
        if (msg->msg_flags & MSG_OOB) {
-               err = queue_oob(sock, msg, other);
+               err = queue_oob(sock, msg, other, &scm, fds_sent);
                if (err)
                        goto out_err;
                sent++;
index e9bf155139612d84b0f52de487210ff916ea9b22..2f9d8271c6ec7df2007267d3905703c6c9686d10 100644 (file)
@@ -54,6 +54,9 @@ static int unix_bpf_recvmsg(struct sock *sk, struct msghdr *msg,
        struct sk_psock *psock;
        int copied;
 
+       if (!len)
+               return 0;
+
        psock = sk_psock_get(sk);
        if (unlikely(!psock))
                return __unix_recvmsg(sk, msg, len, flags);
index a1581c77cf84a81bb5503d57039e49b5b970ce85..ee78b4082ef95fe6277bef1fa2960fc9684b1fb3 100644 (file)
@@ -94,6 +94,11 @@ virtio_transport_alloc_skb(struct virtio_vsock_pkt_info *info,
                                         info->op,
                                         info->flags);
 
+       if (info->vsk && !skb_set_owner_sk_safe(skb, sk_vsock(info->vsk))) {
+               WARN_ONCE(1, "failed to allocate skb on vsock socket with sk_refcnt == 0\n");
+               goto out;
+       }
+
        return skb;
 
 out:
@@ -241,21 +246,18 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
 }
 
 static bool virtio_transport_inc_rx_pkt(struct virtio_vsock_sock *vvs,
-                                       struct sk_buff *skb)
+                                       u32 len)
 {
-       if (vvs->rx_bytes + skb->len > vvs->buf_alloc)
+       if (vvs->rx_bytes + len > vvs->buf_alloc)
                return false;
 
-       vvs->rx_bytes += skb->len;
+       vvs->rx_bytes += len;
        return true;
 }
 
 static void virtio_transport_dec_rx_pkt(struct virtio_vsock_sock *vvs,
-                                       struct sk_buff *skb)
+                                       u32 len)
 {
-       int len;
-
-       len = skb_headroom(skb) - sizeof(struct virtio_vsock_hdr) - skb->len;
        vvs->rx_bytes -= len;
        vvs->fwd_cnt += len;
 }
@@ -366,8 +368,15 @@ virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
        u32 free_space;
 
        spin_lock_bh(&vvs->rx_lock);
+
+       if (WARN_ONCE(skb_queue_empty(&vvs->rx_queue) && vvs->rx_bytes,
+                     "rx_queue is empty, but rx_bytes is non-zero\n")) {
+               spin_unlock_bh(&vvs->rx_lock);
+               return err;
+       }
+
        while (total < len && !skb_queue_empty(&vvs->rx_queue)) {
-               skb = __skb_dequeue(&vvs->rx_queue);
+               skb = skb_peek(&vvs->rx_queue);
 
                bytes = len - total;
                if (bytes > skb->len)
@@ -388,10 +397,11 @@ virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
                skb_pull(skb, bytes);
 
                if (skb->len == 0) {
-                       virtio_transport_dec_rx_pkt(vvs, skb);
+                       u32 pkt_len = le32_to_cpu(virtio_vsock_hdr(skb)->len);
+
+                       virtio_transport_dec_rx_pkt(vvs, pkt_len);
+                       __skb_unlink(skb, &vvs->rx_queue);
                        consume_skb(skb);
-               } else {
-                       __skb_queue_head(&vvs->rx_queue, skb);
                }
        }
 
@@ -437,17 +447,17 @@ static int virtio_transport_seqpacket_do_dequeue(struct vsock_sock *vsk,
 
        while (!msg_ready) {
                struct virtio_vsock_hdr *hdr;
+               size_t pkt_len;
 
                skb = __skb_dequeue(&vvs->rx_queue);
                if (!skb)
                        break;
                hdr = virtio_vsock_hdr(skb);
+               pkt_len = (size_t)le32_to_cpu(hdr->len);
 
                if (dequeued_len >= 0) {
-                       size_t pkt_len;
                        size_t bytes_to_copy;
 
-                       pkt_len = (size_t)le32_to_cpu(hdr->len);
                        bytes_to_copy = min(user_buf_len, pkt_len);
 
                        if (bytes_to_copy) {
@@ -466,7 +476,6 @@ static int virtio_transport_seqpacket_do_dequeue(struct vsock_sock *vsk,
                                        dequeued_len = err;
                                } else {
                                        user_buf_len -= bytes_to_copy;
-                                       skb_pull(skb, bytes_to_copy);
                                }
 
                                spin_lock_bh(&vvs->rx_lock);
@@ -484,7 +493,7 @@ static int virtio_transport_seqpacket_do_dequeue(struct vsock_sock *vsk,
                                msg->msg_flags |= MSG_EOR;
                }
 
-               virtio_transport_dec_rx_pkt(vvs, skb);
+               virtio_transport_dec_rx_pkt(vvs, pkt_len);
                kfree_skb(skb);
        }
 
@@ -1040,7 +1049,7 @@ virtio_transport_recv_enqueue(struct vsock_sock *vsk,
 
        spin_lock_bh(&vvs->rx_lock);
 
-       can_enqueue = virtio_transport_inc_rx_pkt(vvs, skb);
+       can_enqueue = virtio_transport_inc_rx_pkt(vvs, len);
        if (!can_enqueue) {
                free_pkt = true;
                goto out;
@@ -1071,7 +1080,7 @@ virtio_transport_recv_enqueue(struct vsock_sock *vsk,
                        memcpy(skb_put(last_skb, skb->len), skb->data, skb->len);
                        free_pkt = true;
                        last_hdr->flags |= hdr->flags;
-                       last_hdr->len = cpu_to_le32(last_skb->len);
+                       le32_add_cpu(&last_hdr->len, len);
                        goto out;
                }
        }
@@ -1299,6 +1308,11 @@ void virtio_transport_recv_pkt(struct virtio_transport *t,
                goto free_pkt;
        }
 
+       if (!skb_set_owner_sk_safe(skb, sk)) {
+               WARN_ONCE(1, "receiving vsock socket has sk_refcnt == 0\n");
+               goto free_pkt;
+       }
+
        vsk = vsock_sk(sk);
 
        lock_sock(sk);
index 36eb16a40745d2fc07f3a8dd5c81396c20320843..95cc4d79ba2961019799ba25a74185c51d8493fc 100644 (file)
@@ -1842,7 +1842,13 @@ static ssize_t vmci_transport_stream_enqueue(
        struct msghdr *msg,
        size_t len)
 {
-       return vmci_qpair_enquev(vmci_trans(vsk)->qpair, msg, len, 0);
+       ssize_t err;
+
+       err = vmci_qpair_enquev(vmci_trans(vsk)->qpair, msg, len, 0);
+       if (err < 0)
+               err = -ENOMEM;
+
+       return err;
 }
 
 static s64 vmci_transport_stream_has_data(struct vsock_sock *vsk)
index 671e03240fc522a5a51b4c47d387b76bfa345eee..89905c092645a5187970883cea0d8a5610cb09d4 100644 (file)
@@ -15,7 +15,6 @@
 struct vsock_loopback {
        struct workqueue_struct *workqueue;
 
-       spinlock_t pkt_list_lock; /* protects pkt_list */
        struct sk_buff_head pkt_queue;
        struct work_struct pkt_work;
 };
@@ -32,9 +31,7 @@ static int vsock_loopback_send_pkt(struct sk_buff *skb)
        struct vsock_loopback *vsock = &the_vsock_loopback;
        int len = skb->len;
 
-       spin_lock_bh(&vsock->pkt_list_lock);
        skb_queue_tail(&vsock->pkt_queue, skb);
-       spin_unlock_bh(&vsock->pkt_list_lock);
 
        queue_work(vsock->workqueue, &vsock->pkt_work);
 
@@ -113,9 +110,9 @@ static void vsock_loopback_work(struct work_struct *work)
 
        skb_queue_head_init(&pkts);
 
-       spin_lock_bh(&vsock->pkt_list_lock);
+       spin_lock_bh(&vsock->pkt_queue.lock);
        skb_queue_splice_init(&vsock->pkt_queue, &pkts);
-       spin_unlock_bh(&vsock->pkt_list_lock);
+       spin_unlock_bh(&vsock->pkt_queue.lock);
 
        while ((skb = __skb_dequeue(&pkts))) {
                virtio_transport_deliver_tap_pkt(skb);
@@ -132,7 +129,6 @@ static int __init vsock_loopback_init(void)
        if (!vsock->workqueue)
                return -ENOMEM;
 
-       spin_lock_init(&vsock->pkt_list_lock);
        skb_queue_head_init(&vsock->pkt_queue);
        INIT_WORK(&vsock->pkt_work, vsock_loopback_work);
 
@@ -156,9 +152,7 @@ static void __exit vsock_loopback_exit(void)
 
        flush_work(&vsock->pkt_work);
 
-       spin_lock_bh(&vsock->pkt_list_lock);
        virtio_vsock_skb_queue_purge(&vsock->pkt_queue);
-       spin_unlock_bh(&vsock->pkt_list_lock);
 
        destroy_workqueue(vsock->workqueue);
 }
index 112b4bb009c80f648748256b322d9a5e7a7e8514..4f63059efd813ba6dd257a7c7ebebacb2f102cd1 100644 (file)
@@ -462,6 +462,11 @@ nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] = {
        [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
 };
 
+static struct netlink_range_validation nl80211_punct_bitmap_range = {
+       .min = 0,
+       .max = 0xffff,
+};
+
 static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
        [0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
        [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
@@ -805,7 +810,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
        [NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN),
        [NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG },
        [NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
-       [NL80211_ATTR_PUNCT_BITMAP] = NLA_POLICY_RANGE(NLA_U8, 0, 0xffff),
+       [NL80211_ATTR_PUNCT_BITMAP] =
+               NLA_POLICY_FULL_RANGE(NLA_U32, &nl80211_punct_bitmap_range),
 };
 
 /* policy for the key attributes */
@@ -8901,7 +8907,7 @@ static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev,
                struct cfg80211_chan_def *chandef;
 
                chandef = wdev_chandef(wdev, link_id);
-               if (!chandef)
+               if (!chandef || !chandef->chan)
                        continue;
 
                /*
@@ -10793,8 +10799,7 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
 
 static struct cfg80211_bss *nl80211_assoc_bss(struct cfg80211_registered_device *rdev,
                                              const u8 *ssid, int ssid_len,
-                                             struct nlattr **attrs,
-                                             const u8 **bssid_out)
+                                             struct nlattr **attrs)
 {
        struct ieee80211_channel *chan;
        struct cfg80211_bss *bss;
@@ -10821,7 +10826,6 @@ static struct cfg80211_bss *nl80211_assoc_bss(struct cfg80211_registered_device
        if (!bss)
                return ERR_PTR(-ENOENT);
 
-       *bssid_out = bssid;
        return bss;
 }
 
@@ -10831,7 +10835,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
        struct net_device *dev = info->user_ptr[1];
        struct cfg80211_assoc_request req = {};
        struct nlattr **attrs = NULL;
-       const u8 *bssid, *ssid;
+       const u8 *ap_addr, *ssid;
        unsigned int link_id;
        int err, ssid_len;
 
@@ -10968,6 +10972,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
                        return -EINVAL;
 
                req.ap_mld_addr = nla_data(info->attrs[NL80211_ATTR_MLD_ADDR]);
+               ap_addr = req.ap_mld_addr;
 
                attrs = kzalloc(attrsize, GFP_KERNEL);
                if (!attrs)
@@ -10993,8 +10998,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
                                goto free;
                        }
                        req.links[link_id].bss =
-                               nl80211_assoc_bss(rdev, ssid, ssid_len, attrs,
-                                                 &bssid);
+                               nl80211_assoc_bss(rdev, ssid, ssid_len, attrs);
                        if (IS_ERR(req.links[link_id].bss)) {
                                err = PTR_ERR(req.links[link_id].bss);
                                req.links[link_id].bss = NULL;
@@ -11045,10 +11049,10 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
                if (req.link_id >= 0)
                        return -EINVAL;
 
-               req.bss = nl80211_assoc_bss(rdev, ssid, ssid_len, info->attrs,
-                                           &bssid);
+               req.bss = nl80211_assoc_bss(rdev, ssid, ssid_len, info->attrs);
                if (IS_ERR(req.bss))
                        return PTR_ERR(req.bss);
+               ap_addr = req.bss->bssid;
        }
 
        err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
@@ -11061,7 +11065,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
                        dev->ieee80211_ptr->conn_owner_nlportid =
                                info->snd_portid;
                        memcpy(dev->ieee80211_ptr->disconnect_bssid,
-                              bssid, ETH_ALEN);
+                              ap_addr, ETH_ALEN);
                }
 
                wdev_unlock(dev->ieee80211_ptr);
index 28ce13840a8891397d8a42988edb5e64a6eecf4f..7bdeb8eea92dcf7cbbe0c35a8501e9627ddc3256 100644 (file)
@@ -1500,8 +1500,6 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev,
                connect->key = NULL;
                connect->key_len = 0;
                connect->key_idx = 0;
-               connect->crypto.cipher_group = 0;
-               connect->crypto.n_ciphers_pairwise = 0;
        }
 
        wdev->connect_keys = connkeys;
index 4681e8e8ad943605b61aa6be685e6c76a70b4c0f..02207e852d796d31a04e3a1a83f500c27b21203d 100644 (file)
@@ -150,10 +150,11 @@ static int xdp_umem_account_pages(struct xdp_umem *umem)
 
 static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
 {
-       u32 npgs_rem, chunk_size = mr->chunk_size, headroom = mr->headroom;
        bool unaligned_chunks = mr->flags & XDP_UMEM_UNALIGNED_CHUNK_FLAG;
-       u64 npgs, addr = mr->addr, size = mr->len;
-       unsigned int chunks, chunks_rem;
+       u32 chunk_size = mr->chunk_size, headroom = mr->headroom;
+       u64 addr = mr->addr, size = mr->len;
+       u32 chunks_rem, npgs_rem;
+       u64 chunks, npgs;
        int err;
 
        if (chunk_size < XDP_UMEM_MIN_CHUNK_SIZE || chunk_size > PAGE_SIZE) {
@@ -188,8 +189,8 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
        if (npgs > U32_MAX)
                return -EINVAL;
 
-       chunks = (unsigned int)div_u64_rem(size, chunk_size, &chunks_rem);
-       if (chunks == 0)
+       chunks = div_u64_rem(size, chunk_size, &chunks_rem);
+       if (!chunks || chunks > U32_MAX)
                return -EINVAL;
 
        if (!unaligned_chunks && chunks_rem)
@@ -202,7 +203,7 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
        umem->headroom = headroom;
        umem->chunk_size = chunk_size;
        umem->chunks = chunks;
-       umem->npgs = (u32)npgs;
+       umem->npgs = npgs;
        umem->pgs = NULL;
        umem->user = NULL;
        umem->flags = mr->flags;
index 2ab3e09e2227126f5e5eba7d4f1ea172de090c58..50baf50dc513ac36f540c172b9a8389d7c78d5f2 100644 (file)
@@ -2815,11 +2815,6 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload,
                        goto error;
                }
 
-               if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL)) {
-                       NL_SET_ERR_MSG(extack, "Only tunnel modes can accommodate an AF_UNSPEC selector");
-                       goto error;
-               }
-
                x->inner_mode = *inner_mode;
 
                if (x->props.family == AF_INET)
index cf5172d4ce68cfed78c88b782335ca4d8b66f09d..103af2b3e986f322882810c132096d65429e3d07 100644 (file)
@@ -1012,7 +1012,9 @@ static int copy_to_user_aead(struct xfrm_algo_aead *aead, struct sk_buff *skb)
                return -EMSGSIZE;
 
        ap = nla_data(nla);
-       memcpy(ap, aead, sizeof(*aead));
+       strscpy_pad(ap->alg_name, aead->alg_name, sizeof(ap->alg_name));
+       ap->alg_key_len = aead->alg_key_len;
+       ap->alg_icv_len = aead->alg_icv_len;
 
        if (redact_secret && aead->alg_key_len)
                memset(ap->alg_key, 0, (aead->alg_key_len + 7) / 8);
@@ -1032,7 +1034,8 @@ static int copy_to_user_ealg(struct xfrm_algo *ealg, struct sk_buff *skb)
                return -EMSGSIZE;
 
        ap = nla_data(nla);
-       memcpy(ap, ealg, sizeof(*ealg));
+       strscpy_pad(ap->alg_name, ealg->alg_name, sizeof(ap->alg_name));
+       ap->alg_key_len = ealg->alg_key_len;
 
        if (redact_secret && ealg->alg_key_len)
                memset(ap->alg_key, 0, (ealg->alg_key_len + 7) / 8);
@@ -1043,6 +1046,40 @@ static int copy_to_user_ealg(struct xfrm_algo *ealg, struct sk_buff *skb)
        return 0;
 }
 
+static int copy_to_user_calg(struct xfrm_algo *calg, struct sk_buff *skb)
+{
+       struct nlattr *nla = nla_reserve(skb, XFRMA_ALG_COMP, sizeof(*calg));
+       struct xfrm_algo *ap;
+
+       if (!nla)
+               return -EMSGSIZE;
+
+       ap = nla_data(nla);
+       strscpy_pad(ap->alg_name, calg->alg_name, sizeof(ap->alg_name));
+       ap->alg_key_len = 0;
+
+       return 0;
+}
+
+static int copy_to_user_encap(struct xfrm_encap_tmpl *ep, struct sk_buff *skb)
+{
+       struct nlattr *nla = nla_reserve(skb, XFRMA_ENCAP, sizeof(*ep));
+       struct xfrm_encap_tmpl *uep;
+
+       if (!nla)
+               return -EMSGSIZE;
+
+       uep = nla_data(nla);
+       memset(uep, 0, sizeof(*uep));
+
+       uep->encap_type = ep->encap_type;
+       uep->encap_sport = ep->encap_sport;
+       uep->encap_dport = ep->encap_dport;
+       uep->encap_oa = ep->encap_oa;
+
+       return 0;
+}
+
 static int xfrm_smark_put(struct sk_buff *skb, struct xfrm_mark *m)
 {
        int ret = 0;
@@ -1098,12 +1135,12 @@ static int copy_to_user_state_extra(struct xfrm_state *x,
                        goto out;
        }
        if (x->calg) {
-               ret = nla_put(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg);
+               ret = copy_to_user_calg(x->calg, skb);
                if (ret)
                        goto out;
        }
        if (x->encap) {
-               ret = nla_put(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
+               ret = copy_to_user_encap(x->encap, skb);
                if (ret)
                        goto out;
        }
index f88d108fbef07adc1e039123e7855617cec6c426..aef85e9e8eeb8d930e41b0dd82b7fd4c8c0fac4e 100644 (file)
@@ -262,6 +262,20 @@ BINDGEN_TARGET             := $(BINDGEN_TARGET_$(SRCARCH))
 # some configurations, with new GCC versions, etc.
 bindgen_extra_c_flags = -w --target=$(BINDGEN_TARGET)
 
+# Auto variable zero-initialization requires an additional special option with
+# clang that is going to be removed sometime in the future (likely in
+# clang-18), so make sure to pass this option only if clang supports it
+# (libclang major version < 16).
+#
+# https://github.com/llvm/llvm-project/issues/44842
+# https://github.com/llvm/llvm-project/blob/llvmorg-16.0.0-rc2/clang/docs/ReleaseNotes.rst#deprecated-compiler-flags
+ifdef CONFIG_INIT_STACK_ALL_ZERO
+libclang_maj_ver=$(shell $(BINDGEN) $(srctree)/scripts/rust_is_available_bindgen_libclang.h 2>&1 | sed -ne 's/.*clang version \([0-9]*\).*/\1/p')
+ifeq ($(shell expr $(libclang_maj_ver) \< 16), 1)
+bindgen_extra_c_flags += -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang
+endif
+endif
+
 bindgen_c_flags = $(filter-out $(bindgen_skip_c_flags), $(c_flags)) \
        $(bindgen_extra_c_flags)
 endif
@@ -283,7 +297,7 @@ quiet_cmd_bindgen = BINDGEN $@
                $(bindgen_target_cflags) $(bindgen_target_extra)
 
 $(obj)/bindings/bindings_generated.rs: private bindgen_target_flags = \
-    $(shell grep -v '^\#\|^$$' $(srctree)/$(src)/bindgen_parameters)
+    $(shell grep -v '^#\|^$$' $(srctree)/$(src)/bindgen_parameters)
 $(obj)/bindings/bindings_generated.rs: $(src)/bindings/bindings_helper.h \
     $(src)/bindgen_parameters FORCE
        $(call if_changed_dep,bindgen)
index 30103325696d801df5458f7f398a997835fbe8fe..8009184bf6d768539507c6a0fc543655d2f671fa 100644 (file)
@@ -18,7 +18,11 @@ use crate::bindings;
 
 // Called from `vsprintf` with format specifier `%pA`.
 #[no_mangle]
-unsafe fn rust_fmt_argument(buf: *mut c_char, end: *mut c_char, ptr: *const c_void) -> *mut c_char {
+unsafe extern "C" fn rust_fmt_argument(
+    buf: *mut c_char,
+    end: *mut c_char,
+    ptr: *const c_void,
+) -> *mut c_char {
     use fmt::Write;
     // SAFETY: The C contract guarantees that `buf` is valid if it's less than `end`.
     let mut w = unsafe { RawFormatter::from_ptrs(buf.cast(), end.cast()) };
index b771310fa4a49e0a1f2389f438784ec899725212..cd3d2a6cf1fc1205c5f3fc62bf5aad5c3a261ab7 100644 (file)
@@ -408,7 +408,7 @@ impl RawFormatter {
     /// If `pos` is less than `end`, then the region between `pos` (inclusive) and `end`
     /// (exclusive) must be valid for writes for the lifetime of the returned [`RawFormatter`].
     pub(crate) unsafe fn from_ptrs(pos: *mut u8, end: *mut u8) -> Self {
-        // INVARIANT: The safety requierments guarantee the type invariants.
+        // INVARIANT: The safety requirements guarantee the type invariants.
         Self {
             beg: pos as _,
             pos: pos as _,
index feb43045d1b1ed84bab049b98cd50af88d3643cc..6e9ce6720a05aacbaa2f7e0dc96c2e67819e7269 100644 (file)
@@ -3,7 +3,6 @@
 /generate_rust_target
 /insert-sys-cert
 /kallsyms
-/list-gitignored
 /module.lds
 /recordmcount
 /sign-file
index e8917975905ca65973bc2e1e005a53006c08e5a3..32b6ba7227284c0482c980d6f9a02a15d8ab4f7a 100644 (file)
@@ -38,7 +38,7 @@ HOSTCFLAGS_sorttable.o += -DMCOUNT_SORT_ENABLED
 endif
 
 # The following programs are only built on demand
-hostprogs += list-gitignored unifdef
+hostprogs += unifdef
 
 # The module linker script is preprocessed on demand
 targets += module.lds
index b941e6341b364f26cba7555a56a9390745656e71..4000ad04c1220d48366b78b568fc1d34d6ed0691 100644 (file)
@@ -2,6 +2,7 @@
 # Makefile for the different targets used to generate full packages of a kernel
 
 include $(srctree)/scripts/Kbuild.include
+include $(srctree)/scripts/Makefile.lib
 
 KERNELPATH := kernel-$(subst -,_,$(KERNELRELEASE))
 KBUILD_PKG_ROOTCMD ?="fakeroot -u"
@@ -26,54 +27,39 @@ fi ; \
 tar -I $(KGZIP) -c $(RCS_TAR_IGNORE) -f $(2).tar.gz \
        --transform 's:^:$(2)/:S' $(TAR_CONTENT) $(3)
 
-# .tmp_filelist .tmp_filelist_exclude
+# Git
 # ---------------------------------------------------------------------------
 
-scripts/list-gitignored: FORCE
-       $(Q)$(MAKE) -f $(srctree)/Makefile scripts_package
+filechk_HEAD = git -C $(srctree) rev-parse --verify HEAD 2>/dev/null
 
-# 1f5d3a6b6532e25a5cdf1f311956b2b03d343a48 removed '*.rej' from .gitignore,
-# but it is definitely a generated file.
-filechk_filelist = \
-       $< --exclude='*.rej' --output=$@_exclude --prefix=./ --rootdir=$(srctree) --stat=-
+.tmp_HEAD: check-git FORCE
+       $(call filechk,HEAD)
 
-.tmp_filelist: scripts/list-gitignored FORCE
-       $(call filechk,filelist)
-
-# tarball
-# ---------------------------------------------------------------------------
-
-quiet_cmd_tar = TAR     $@
-      cmd_tar = tar -c -f $@ $(tar-compress-opt) $(tar-exclude-opt) \
-                --owner=0 --group=0 --sort=name \
-                --transform 's:^\.:$*:S' -C $(tar-rootdir) .
-
-tar-rootdir := $(srctree)
-
-%.tar:
-       $(call cmd,tar)
-
-%.tar.gz: private tar-compress-opt := -I $(KGZIP)
-%.tar.gz:
-       $(call cmd,tar)
-
-%.tar.bz2: private tar-compress-opt := -I $(KBZIP2)
-%.tar.bz2:
-       $(call cmd,tar)
+PHONY += check-git
+check-git:
+       @if ! $(srctree)/scripts/check-git; then \
+               echo >&2 "error: creating source package requires git repository"; \
+               false; \
+       fi
 
-%.tar.xz: private tar-compress-opt := -I $(XZ)
-%.tar.xz:
-       $(call cmd,tar)
+git-config-tar.gz  = -c tar.tar.gz.command="$(KGZIP)"
+git-config-tar.bz2 = -c tar.tar.bz2.command="$(KBZIP2)"
+git-config-tar.xz  = -c tar.tar.xz.command="$(XZ)"
+git-config-tar.zst = -c tar.tar.zst.command="$(ZSTD)"
 
-%.tar.zst: private tar-compress-opt := -I $(ZSTD)
-%.tar.zst:
-       $(call cmd,tar)
+quiet_cmd_archive = ARCHIVE $@
+      cmd_archive = git -C $(srctree) $(git-config-tar$(suffix $@)) archive \
+                    --output=$$(realpath $@) $(archive-args)
 
 # Linux source tarball
 # ---------------------------------------------------------------------------
 
-linux.tar.gz: tar-exclude-opt = --exclude=./$@ --exclude-from=$<_exclude
-linux.tar.gz: .tmp_filelist
+linux-tarballs := $(addprefix linux, .tar.gz)
+
+targets += $(linux-tarballs)
+$(linux-tarballs): archive-args = --prefix=linux/ $$(cat $<)
+$(linux-tarballs): .tmp_HEAD FORCE
+       $(call if_changed,archive)
 
 # rpm-pkg
 # ---------------------------------------------------------------------------
@@ -89,7 +75,7 @@ PHONY += srcrpm-pkg
 srcrpm-pkg: linux.tar.gz
        $(CONFIG_SHELL) $(MKSPEC) >$(objtree)/kernel.spec
        +rpmbuild $(RPMOPTS) --target $(UTS_MACHINE)-linux -bs kernel.spec \
-       --define='_smp_mflags %{nil}' --define='_sourcedir .' --define='_srcrpmdir .'
+       --define='_smp_mflags %{nil}' --define='_sourcedir rpmbuild/SOURCES' --define='_srcrpmdir .'
 
 # binrpm-pkg
 # ---------------------------------------------------------------------------
@@ -101,7 +87,7 @@ binrpm-pkg:
                $(UTS_MACHINE)-linux -bb $(objtree)/binkernel.spec
 
 quiet_cmd_debianize = GEN     $@
-      cmd_debianize = $(srctree)/scripts/package/mkdebian
+      cmd_debianize = $(srctree)/scripts/package/mkdebian $(mkdebian-opts)
 
 debian: FORCE
        $(call cmd,debianize)
@@ -110,6 +96,7 @@ PHONY += debian-orig
 debian-orig: private source = $(shell dpkg-parsechangelog -S Source)
 debian-orig: private version = $(shell dpkg-parsechangelog -S Version | sed 's/-[^-]*$$//')
 debian-orig: private orig-name = $(source)_$(version).orig.tar.gz
+debian-orig: mkdebian-opts = --need-source
 debian-orig: linux.tar.gz debian
        $(Q)if [ "$(df  --output=target .. 2>/dev/null)" = "$(df --output=target $< 2>/dev/null)" ]; then \
                ln -f $< ../$(orig-name); \
@@ -148,74 +135,70 @@ snap-pkg:
 # dir-pkg tar*-pkg - tarball targets
 # ---------------------------------------------------------------------------
 
-tar-pkg-tarball = linux-$(KERNELRELEASE)-$(ARCH).$(1)
-tar-pkg-phony = $(subst .,,$(1))-pkg
-
 tar-install: FORCE
        $(Q)$(MAKE) -f $(srctree)/Makefile
        +$(Q)$(srctree)/scripts/package/buildtar $@
 
+compress-tar.gz  = -I "$(KGZIP)"
+compress-tar.bz2 = -I "$(KBZIP2)"
+compress-tar.xz  = -I "$(XZ)"
+compress-tar.zst = -I "$(ZSTD)"
+
+quiet_cmd_tar = TAR     $@
+      cmd_tar = cd $<; tar cf ../$@ $(compress-tar$(suffix $@)) --owner=root --group=root --sort=name *
+
+dir-tarballs := $(addprefix linux-$(KERNELRELEASE)-$(ARCH), .tar .tar.gz .tar.bz2 .tar.xz .tar.zst)
+
+$(dir-tarballs): tar-install
+       $(call cmd,tar)
+
 PHONY += dir-pkg
 dir-pkg: tar-install
        @echo "Kernel tree successfully created in $<"
 
-define tar-pkg-rule
-PHONY += $(tar-pkg-phony)
-$(tar-pkg-phony): $(tar-pkg-tarball)
+PHONY += tar-pkg
+tar-pkg: linux-$(KERNELRELEASE)-$(ARCH).tar
        @:
 
-$(tar-pkg-tarball): private tar-rootdir := tar-install
-$(tar-pkg-tarball): tar-install
-endef
-
-$(foreach x, tar tar.gz tar.bz2 tar.xz tar.zst, $(eval $(call tar-pkg-rule,$(x))))
+tar%-pkg: linux-$(KERNELRELEASE)-$(ARCH).tar.% FORCE
+       @:
 
 # perf-tar*-src-pkg - generate a source tarball with perf source
 # ---------------------------------------------------------------------------
 
-perf-tar-src-pkg-tarball = perf-$(KERNELVERSION).$(1)
-perf-tar-src-pkg-phony   = perf-$(subst .,,$(1))-src-pkg
-
-quiet_cmd_stage_perf_src = STAGE   $@
-      cmd_stage_perf_src = \
-       rm -rf $@; \
-       mkdir -p $@; \
-       tar -c -f - --exclude-from=$<_exclude -C $(srctree) --files-from=$(srctree)/tools/perf/MANIFEST | \
-       tar -x -f - -C $@
-
-.tmp_perf: .tmp_filelist
-       $(call cmd,stage_perf_src)
-
-filechk_perf_head = \
-       if test -z "$(git -C $(srctree) rev-parse --show-cdup 2>/dev/null)" && \
-              head=$$(git -C $(srctree) rev-parse --verify HEAD 2>/dev/null); then \
-               echo $$head; \
-       else \
-               echo "not a git tree"; \
-       fi
+.tmp_perf:
+       $(Q)mkdir .tmp_perf
 
-.tmp_perf/HEAD: .tmp_perf FORCE
-       $(call filechk,perf_head)
+.tmp_perf/HEAD: .tmp_HEAD | .tmp_perf
+       $(call cmd,copy)
 
 quiet_cmd_perf_version_file = GEN     $@
       cmd_perf_version_file = cd $(srctree)/tools/perf; util/PERF-VERSION-GEN $(dir $(abspath $@))
 
-# PERF-VERSION-FILE and HEAD are independent, but this avoids updating the
+# PERF-VERSION-FILE and .tmp_HEAD are independent, but this avoids updating the
 # timestamp of PERF-VERSION-FILE.
 # The best is to fix tools/perf/util/PERF-VERSION-GEN.
-.tmp_perf/PERF-VERSION-FILE: .tmp_perf/HEAD $(srctree)/tools/perf/util/PERF-VERSION-GEN
+.tmp_perf/PERF-VERSION-FILE: .tmp_HEAD $(srctree)/tools/perf/util/PERF-VERSION-GEN | .tmp_perf
        $(call cmd,perf_version_file)
 
-define perf-tar-src-pkg-rule
-PHONY += $(perf-tar-src-pkg-phony)
-$(perf-tar-src-pkg-phony): $(perf-tar-src-pkg-tarball)
-       @:
+perf-archive-args = --add-file=$$(realpath $(word 2, $^)) \
+       --add-file=$$(realpath $(word 3, $^)) \
+       $$(cat $(word 2, $^))^{tree} $$(cat $<)
+
 
-$(perf-tar-src-pkg-tarball): private tar-rootdir := .tmp_perf
-$(perf-tar-src-pkg-tarball): .tmp_filelist .tmp_perf/HEAD .tmp_perf/PERF-VERSION-FILE
-endef
+perf-tarballs := $(addprefix perf-$(KERNELVERSION), .tar .tar.gz .tar.bz2 .tar.xz .tar.zst)
 
-$(foreach x, tar tar.gz tar.bz2 tar.xz tar.zst, $(eval $(call perf-tar-src-pkg-rule,$(x))))
+targets += $(perf-tarballs)
+$(perf-tarballs): archive-args = --prefix=perf-$(KERNELVERSION)/ $(perf-archive-args)
+$(perf-tarballs): tools/perf/MANIFEST .tmp_perf/HEAD .tmp_perf/PERF-VERSION-FILE FORCE
+       $(call if_changed,archive)
+
+PHONY += perf-tar-src-pkg
+perf-tar-src-pkg: perf-$(KERNELVERSION).tar
+       @:
+
+perf-tar%-src-pkg: perf-$(KERNELVERSION).tar.% FORCE
+       @:
 
 # Help text displayed when executing 'make help'
 # ---------------------------------------------------------------------------
@@ -243,4 +226,13 @@ help:
 PHONY += FORCE
 FORCE:
 
+# Read all saved command lines and dependencies for the $(targets) we
+# may be building above, using $(if_changed{,_dep}). As an
+# optimization, we don't need to read them if the target does not
+# exist, we will rebuild anyway in that case.
+
+existing-targets := $(wildcard $(sort $(targets)))
+
+-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
+
 .PHONY: $(PHONY)
index 7b6756a8c15d99440078dbfbb2b323abf376ed45..4c3f645065a45bf8105d31c3cc1c335fdb9defd2 100644 (file)
@@ -625,7 +625,7 @@ int main(int argc, char **argv)
        p = strrchr(argv[1], '/');
        p = p ? p + 1 : argv[1];
        grammar_name = strdup(p);
-       if (!p) {
+       if (!grammar_name) {
                perror(NULL);
                exit(1);
        }
index 0573c92e841d3209b9034a0673e46a2e750510d5..a7e28b6a514e5e6adc6070e20f46c8c4b160d7cd 100755 (executable)
@@ -45,10 +45,6 @@ Clang)
        version=$2.$3.$4
        min_version=$($min_tool_version llvm)
        ;;
-ICC)
-       version=$(($2 / 100)).$(($2 % 100)).$3
-       min_version=$($min_tool_version icc)
-       ;;
 *)
        echo "$orig_args: unknown C compiler" >&2
        exit 1
diff --git a/scripts/check-git b/scripts/check-git
new file mode 100755 (executable)
index 0000000..2ca6c5d
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# succeed if we are in a git repository
+
+srctree="$(dirname $0)/.."
+
+if ! git -C "${srctree}" rev-parse --verify HEAD >/dev/null 2>/dev/null; then
+       exit 1
+fi
+
+if ! test -z $(git -C "${srctree}" rev-parse --show-cdup 2>/dev/null); then
+       exit 1
+fi
index bd44d12965c98e99042938880a17730c6dfac5c9..4bfbe3c9fa15fa0828ca33b282d9c169d37aab80 100755 (executable)
@@ -6388,6 +6388,15 @@ sub process {
                        }
                }
 
+# check for soon-to-be-deprecated single-argument k[v]free_rcu() API
+               if ($line =~ /\bk[v]?free_rcu\s*\([^(]+\)/) {
+                       if ($line =~ /\bk[v]?free_rcu\s*\([^,]+\)/) {
+                               ERROR("DEPRECATED_API",
+                                     "Single-argument k[v]free_rcu() API is deprecated, please pass rcu_head object or call k[v]free_rcu_mightsleep()." . $herecurr);
+                       }
+               }
+
+
 # check for unnecessary "Out of Memory" messages
                if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
                    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
index f33e61aca93d34ee4cc05b1266f7449ff71fc213..1e5d2eeb726df00e5be8b7aef040b97b011546c8 100755 (executable)
@@ -114,7 +114,6 @@ cat << EOF
 #define __IGNORE_truncate
 #define __IGNORE_stat
 #define __IGNORE_lstat
-#define __IGNORE_fstat
 #define __IGNORE_fcntl
 #define __IGNORE_fadvise64
 #define __IGNORE_newfstatat
@@ -255,6 +254,9 @@ cat << EOF
 /* 64-bit ports never needed these, and new 32-bit ports can use statx */
 #define __IGNORE_fstat64
 #define __IGNORE_fstatat64
+
+/* Newer ports are not required to provide fstat in favor of statx */
+#define __IGNORE_fstat
 EOF
 }
 
index ecc7ea9a4dcfc6f1c89f289f8866bad9ed1e430b..946e250c1b2a6f9b243d8836ea47ad067970530b 100755 (executable)
@@ -104,7 +104,10 @@ def generate_crates(srctree, objtree, sysroot_src):
             name = path.name.replace(".rs", "")
 
             # Skip those that are not crate roots.
-            if f"{name}.o" not in open(path.parent / "Makefile").read():
+            try:
+                if f"{name}.o" not in open(path.parent / "Makefile").read():
+                    continue
+            except FileNotFoundError:
                 continue
 
             logging.info("Adding %s", name)
index 28b3831a7593f42b12b4b3e8a67733d9a1c0fe44..464761a7cf7f25c0b194b1cd72481e2cb2bc5d48 100755 (executable)
@@ -13,4 +13,4 @@ set -e
 #
 # In the future, checking for the `.comment` section may be another
 # option, see https://github.com/rust-lang/rust/pull/97550.
-${NM} "$*" | grep -qE '^[0-9a-fA-F]+ r _R[^[:space:]]+16___IS_RUST_MODULE[^[:space:]]*$'
+${NM} "$*" | grep -qE '^[0-9a-fA-F]+ [Rr] _R[^[:space:]]+16___IS_RUST_MODULE[^[:space:]]*$'
index 8a68179a98a3986ed12a25bcbb0e535c5c54a5f4..a239a87e7bec1c75ffba780d291fb7493c868780 100644 (file)
@@ -119,6 +119,7 @@ static bool is_ignored_symbol(const char *name, char type)
                "kallsyms_markers",
                "kallsyms_token_table",
                "kallsyms_token_index",
+               "kallsyms_seqs_of_names",
                /* Exclude linker generated symbols which vary between passes */
                "_SDA_BASE_",           /* ppc */
                "_SDA2_BASE_",          /* ppc */
index b7c9f1dd5e4229df71e99ae9585424155ac101f0..992575f1e97693af4f715bb66d6dfd7f3a93f58b 100644 (file)
@@ -1226,10 +1226,12 @@ static void (*conf_changed_callback)(void);
 
 void conf_set_changed(bool val)
 {
-       if (conf_changed_callback && conf_changed != val)
-               conf_changed_callback();
+       bool changed = conf_changed != val;
 
        conf_changed = val;
+
+       if (conf_changed_callback && changed)
+               conf_changed_callback();
 }
 
 bool conf_get_changed(void)
index 32620de473ad2dc42e261c3a6fcf49587198b6fd..902eb429b9dbd92e060925fdefd06bf2fdd45b4b 100755 (executable)
@@ -145,7 +145,7 @@ for ORIG_MERGE_FILE in $MERGE_LIST ; do
                NEW_VAL=$(grep -w $CFG $MERGE_FILE)
                BUILTIN_FLAG=false
                if [ "$BUILTIN" = "true" ] && [ "${NEW_VAL#CONFIG_*=}" = "m" ] && [ "${PREV_VAL#CONFIG_*=}" = "y" ]; then
-                       ${WARNOVVERIDE} Previous  value: $PREV_VAL
+                       ${WARNOVERRIDE} Previous  value: $PREV_VAL
                        ${WARNOVERRIDE} New value:       $NEW_VAL
                        ${WARNOVERRIDE} -y passed, will not demote y to m
                        ${WARNOVERRIDE}
diff --git a/scripts/list-gitignored.c b/scripts/list-gitignored.c
deleted file mode 100644 (file)
index f9941f8..0000000
+++ /dev/null
@@ -1,1057 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-//
-// Traverse the source tree, parsing all .gitignore files, and print file paths
-// that are ignored by git.
-// The output is suitable to the --exclude-from option of tar.
-// This is useful until the --exclude-vcs-ignores option gets working correctly.
-//
-// Copyright (C) 2023 Masahiro Yamada <masahiroy@kernel.org>
-//                      (a lot of code imported from GIT)
-
-#include <assert.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-// Imported from commit 23c56f7bd5f1667f8b793d796bf30e39545920f6 in GIT
-//
-//---------------------------(IMPORT FROM GIT BEGIN)---------------------------
-
-// Copied from environment.c
-
-static bool ignore_case;
-
-// Copied from git-compat-util.h
-
-/* Sane ctype - no locale, and works with signed chars */
-#undef isascii
-#undef isspace
-#undef isdigit
-#undef isalpha
-#undef isalnum
-#undef isprint
-#undef islower
-#undef isupper
-#undef tolower
-#undef toupper
-#undef iscntrl
-#undef ispunct
-#undef isxdigit
-
-static const unsigned char sane_ctype[256];
-#define GIT_SPACE 0x01
-#define GIT_DIGIT 0x02
-#define GIT_ALPHA 0x04
-#define GIT_GLOB_SPECIAL 0x08
-#define GIT_REGEX_SPECIAL 0x10
-#define GIT_PATHSPEC_MAGIC 0x20
-#define GIT_CNTRL 0x40
-#define GIT_PUNCT 0x80
-#define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)
-#define isascii(x) (((x) & ~0x7f) == 0)
-#define isspace(x) sane_istest(x,GIT_SPACE)
-#define isdigit(x) sane_istest(x,GIT_DIGIT)
-#define isalpha(x) sane_istest(x,GIT_ALPHA)
-#define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
-#define isprint(x) ((x) >= 0x20 && (x) <= 0x7e)
-#define islower(x) sane_iscase(x, 1)
-#define isupper(x) sane_iscase(x, 0)
-#define is_glob_special(x) sane_istest(x,GIT_GLOB_SPECIAL)
-#define iscntrl(x) (sane_istest(x,GIT_CNTRL))
-#define ispunct(x) sane_istest(x, GIT_PUNCT | GIT_REGEX_SPECIAL | \
-               GIT_GLOB_SPECIAL | GIT_PATHSPEC_MAGIC)
-#define isxdigit(x) (hexval_table[(unsigned char)(x)] != -1)
-#define tolower(x) sane_case((unsigned char)(x), 0x20)
-#define toupper(x) sane_case((unsigned char)(x), 0)
-
-static inline int sane_case(int x, int high)
-{
-       if (sane_istest(x, GIT_ALPHA))
-               x = (x & ~0x20) | high;
-       return x;
-}
-
-static inline int sane_iscase(int x, int is_lower)
-{
-       if (!sane_istest(x, GIT_ALPHA))
-               return 0;
-
-       if (is_lower)
-               return (x & 0x20) != 0;
-       else
-               return (x & 0x20) == 0;
-}
-
-// Copied from ctype.c
-
-enum {
-       S = GIT_SPACE,
-       A = GIT_ALPHA,
-       D = GIT_DIGIT,
-       G = GIT_GLOB_SPECIAL,   /* *, ?, [, \\ */
-       R = GIT_REGEX_SPECIAL,  /* $, (, ), +, ., ^, {, | */
-       P = GIT_PATHSPEC_MAGIC, /* other non-alnum, except for ] and } */
-       X = GIT_CNTRL,
-       U = GIT_PUNCT,
-       Z = GIT_CNTRL | GIT_SPACE
-};
-
-static const unsigned char sane_ctype[256] = {
-       X, X, X, X, X, X, X, X, X, Z, Z, X, X, Z, X, X,         /*   0.. 15 */
-       X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,         /*  16.. 31 */
-       S, P, P, P, R, P, P, P, R, R, G, R, P, P, R, P,         /*  32.. 47 */
-       D, D, D, D, D, D, D, D, D, D, P, P, P, P, P, G,         /*  48.. 63 */
-       P, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,         /*  64.. 79 */
-       A, A, A, A, A, A, A, A, A, A, A, G, G, U, R, P,         /*  80.. 95 */
-       P, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,         /*  96..111 */
-       A, A, A, A, A, A, A, A, A, A, A, R, R, U, P, X,         /* 112..127 */
-       /* Nothing in the 128.. range */
-};
-
-// Copied from hex.c
-
-static const signed char hexval_table[256] = {
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* 00-07 */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* 08-0f */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* 10-17 */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* 18-1f */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* 20-27 */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* 28-2f */
-         0,  1,  2,  3,  4,  5,  6,  7,                /* 30-37 */
-         8,  9, -1, -1, -1, -1, -1, -1,                /* 38-3f */
-        -1, 10, 11, 12, 13, 14, 15, -1,                /* 40-47 */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* 48-4f */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* 50-57 */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* 58-5f */
-        -1, 10, 11, 12, 13, 14, 15, -1,                /* 60-67 */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* 68-67 */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* 70-77 */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* 78-7f */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* 80-87 */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* 88-8f */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* 90-97 */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* 98-9f */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* a0-a7 */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* a8-af */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* b0-b7 */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* b8-bf */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* c0-c7 */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* c8-cf */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* d0-d7 */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* d8-df */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* e0-e7 */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* e8-ef */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* f0-f7 */
-        -1, -1, -1, -1, -1, -1, -1, -1,                /* f8-ff */
-};
-
-// Copied from wildmatch.h
-
-#define WM_CASEFOLD 1
-#define WM_PATHNAME 2
-
-#define WM_NOMATCH 1
-#define WM_MATCH 0
-#define WM_ABORT_ALL -1
-#define WM_ABORT_TO_STARSTAR -2
-
-// Copied from wildmatch.c
-
-typedef unsigned char uchar;
-
-// local modification: remove NEGATE_CLASS(2)
-
-#define CC_EQ(class, len, litmatch) ((len) == sizeof (litmatch)-1 \
-                                   && *(class) == *(litmatch) \
-                                   && strncmp((char*)class, litmatch, len) == 0)
-
-// local modification: simpilify macros
-#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
-#define ISGRAPH(c) (isprint(c) && !isspace(c))
-#define ISPRINT(c) isprint(c)
-#define ISDIGIT(c) isdigit(c)
-#define ISALNUM(c) isalnum(c)
-#define ISALPHA(c) isalpha(c)
-#define ISCNTRL(c) iscntrl(c)
-#define ISLOWER(c) islower(c)
-#define ISPUNCT(c) ispunct(c)
-#define ISSPACE(c) isspace(c)
-#define ISUPPER(c) isupper(c)
-#define ISXDIGIT(c) isxdigit(c)
-
-/* Match pattern "p" against "text" */
-static int dowild(const uchar *p, const uchar *text, unsigned int flags)
-{
-       uchar p_ch;
-       const uchar *pattern = p;
-
-       for ( ; (p_ch = *p) != '\0'; text++, p++) {
-               int matched, match_slash, negated;
-               uchar t_ch, prev_ch;
-               if ((t_ch = *text) == '\0' && p_ch != '*')
-                       return WM_ABORT_ALL;
-               if ((flags & WM_CASEFOLD) && ISUPPER(t_ch))
-                       t_ch = tolower(t_ch);
-               if ((flags & WM_CASEFOLD) && ISUPPER(p_ch))
-                       p_ch = tolower(p_ch);
-               switch (p_ch) {
-               case '\\':
-                       /* Literal match with following character.  Note that the test
-                        * in "default" handles the p[1] == '\0' failure case. */
-                       p_ch = *++p;
-                       /* FALLTHROUGH */
-               default:
-                       if (t_ch != p_ch)
-                               return WM_NOMATCH;
-                       continue;
-               case '?':
-                       /* Match anything but '/'. */
-                       if ((flags & WM_PATHNAME) && t_ch == '/')
-                               return WM_NOMATCH;
-                       continue;
-               case '*':
-                       if (*++p == '*') {
-                               const uchar *prev_p = p - 2;
-                               while (*++p == '*') {}
-                               if (!(flags & WM_PATHNAME))
-                                       /* without WM_PATHNAME, '*' == '**' */
-                                       match_slash = 1;
-                               else if ((prev_p < pattern || *prev_p == '/') &&
-                                   (*p == '\0' || *p == '/' ||
-                                    (p[0] == '\\' && p[1] == '/'))) {
-                                       /*
-                                        * Assuming we already match 'foo/' and are at
-                                        * <star star slash>, just assume it matches
-                                        * nothing and go ahead match the rest of the
-                                        * pattern with the remaining string. This
-                                        * helps make foo/<*><*>/bar (<> because
-                                        * otherwise it breaks C comment syntax) match
-                                        * both foo/bar and foo/a/bar.
-                                        */
-                                       if (p[0] == '/' &&
-                                           dowild(p + 1, text, flags) == WM_MATCH)
-                                               return WM_MATCH;
-                                       match_slash = 1;
-                               } else /* WM_PATHNAME is set */
-                                       match_slash = 0;
-                       } else
-                               /* without WM_PATHNAME, '*' == '**' */
-                               match_slash = flags & WM_PATHNAME ? 0 : 1;
-                       if (*p == '\0') {
-                               /* Trailing "**" matches everything.  Trailing "*" matches
-                                * only if there are no more slash characters. */
-                               if (!match_slash) {
-                                       if (strchr((char *)text, '/'))
-                                               return WM_NOMATCH;
-                               }
-                               return WM_MATCH;
-                       } else if (!match_slash && *p == '/') {
-                               /*
-                                * _one_ asterisk followed by a slash
-                                * with WM_PATHNAME matches the next
-                                * directory
-                                */
-                               const char *slash = strchr((char*)text, '/');
-                               if (!slash)
-                                       return WM_NOMATCH;
-                               text = (const uchar*)slash;
-                               /* the slash is consumed by the top-level for loop */
-                               break;
-                       }
-                       while (1) {
-                               if (t_ch == '\0')
-                                       break;
-                               /*
-                                * Try to advance faster when an asterisk is
-                                * followed by a literal. We know in this case
-                                * that the string before the literal
-                                * must belong to "*".
-                                * If match_slash is false, do not look past
-                                * the first slash as it cannot belong to '*'.
-                                */
-                               if (!is_glob_special(*p)) {
-                                       p_ch = *p;
-                                       if ((flags & WM_CASEFOLD) && ISUPPER(p_ch))
-                                               p_ch = tolower(p_ch);
-                                       while ((t_ch = *text) != '\0' &&
-                                              (match_slash || t_ch != '/')) {
-                                               if ((flags & WM_CASEFOLD) && ISUPPER(t_ch))
-                                                       t_ch = tolower(t_ch);
-                                               if (t_ch == p_ch)
-                                                       break;
-                                               text++;
-                                       }
-                                       if (t_ch != p_ch)
-                                               return WM_NOMATCH;
-                               }
-                               if ((matched = dowild(p, text, flags)) != WM_NOMATCH) {
-                                       if (!match_slash || matched != WM_ABORT_TO_STARSTAR)
-                                               return matched;
-                               } else if (!match_slash && t_ch == '/')
-                                       return WM_ABORT_TO_STARSTAR;
-                               t_ch = *++text;
-                       }
-                       return WM_ABORT_ALL;
-               case '[':
-                       p_ch = *++p;
-                       if (p_ch == '^')
-                               p_ch = '!';
-                       /* Assign literal 1/0 because of "matched" comparison. */
-                       negated = p_ch == '!' ? 1 : 0;
-                       if (negated) {
-                               /* Inverted character class. */
-                               p_ch = *++p;
-                       }
-                       prev_ch = 0;
-                       matched = 0;
-                       do {
-                               if (!p_ch)
-                                       return WM_ABORT_ALL;
-                               if (p_ch == '\\') {
-                                       p_ch = *++p;
-                                       if (!p_ch)
-                                               return WM_ABORT_ALL;
-                                       if (t_ch == p_ch)
-                                               matched = 1;
-                               } else if (p_ch == '-' && prev_ch && p[1] && p[1] != ']') {
-                                       p_ch = *++p;
-                                       if (p_ch == '\\') {
-                                               p_ch = *++p;
-                                               if (!p_ch)
-                                                       return WM_ABORT_ALL;
-                                       }
-                                       if (t_ch <= p_ch && t_ch >= prev_ch)
-                                               matched = 1;
-                                       else if ((flags & WM_CASEFOLD) && ISLOWER(t_ch)) {
-                                               uchar t_ch_upper = toupper(t_ch);
-                                               if (t_ch_upper <= p_ch && t_ch_upper >= prev_ch)
-                                                       matched = 1;
-                                       }
-                                       p_ch = 0; /* This makes "prev_ch" get set to 0. */
-                               } else if (p_ch == '[' && p[1] == ':') {
-                                       const uchar *s;
-                                       int i;
-                                       for (s = p += 2; (p_ch = *p) && p_ch != ']'; p++) {} /*SHARED ITERATOR*/
-                                       if (!p_ch)
-                                               return WM_ABORT_ALL;
-                                       i = p - s - 1;
-                                       if (i < 0 || p[-1] != ':') {
-                                               /* Didn't find ":]", so treat like a normal set. */
-                                               p = s - 2;
-                                               p_ch = '[';
-                                               if (t_ch == p_ch)
-                                                       matched = 1;
-                                               continue;
-                                       }
-                                       if (CC_EQ(s,i, "alnum")) {
-                                               if (ISALNUM(t_ch))
-                                                       matched = 1;
-                                       } else if (CC_EQ(s,i, "alpha")) {
-                                               if (ISALPHA(t_ch))
-                                                       matched = 1;
-                                       } else if (CC_EQ(s,i, "blank")) {
-                                               if (ISBLANK(t_ch))
-                                                       matched = 1;
-                                       } else if (CC_EQ(s,i, "cntrl")) {
-                                               if (ISCNTRL(t_ch))
-                                                       matched = 1;
-                                       } else if (CC_EQ(s,i, "digit")) {
-                                               if (ISDIGIT(t_ch))
-                                                       matched = 1;
-                                       } else if (CC_EQ(s,i, "graph")) {
-                                               if (ISGRAPH(t_ch))
-                                                       matched = 1;
-                                       } else if (CC_EQ(s,i, "lower")) {
-                                               if (ISLOWER(t_ch))
-                                                       matched = 1;
-                                       } else if (CC_EQ(s,i, "print")) {
-                                               if (ISPRINT(t_ch))
-                                                       matched = 1;
-                                       } else if (CC_EQ(s,i, "punct")) {
-                                               if (ISPUNCT(t_ch))
-                                                       matched = 1;
-                                       } else if (CC_EQ(s,i, "space")) {
-                                               if (ISSPACE(t_ch))
-                                                       matched = 1;
-                                       } else if (CC_EQ(s,i, "upper")) {
-                                               if (ISUPPER(t_ch))
-                                                       matched = 1;
-                                               else if ((flags & WM_CASEFOLD) && ISLOWER(t_ch))
-                                                       matched = 1;
-                                       } else if (CC_EQ(s,i, "xdigit")) {
-                                               if (ISXDIGIT(t_ch))
-                                                       matched = 1;
-                                       } else /* malformed [:class:] string */
-                                               return WM_ABORT_ALL;
-                                       p_ch = 0; /* This makes "prev_ch" get set to 0. */
-                               } else if (t_ch == p_ch)
-                                       matched = 1;
-                       } while (prev_ch = p_ch, (p_ch = *++p) != ']');
-                       if (matched == negated ||
-                           ((flags & WM_PATHNAME) && t_ch == '/'))
-                               return WM_NOMATCH;
-                       continue;
-               }
-       }
-
-       return *text ? WM_NOMATCH : WM_MATCH;
-}
-
-/* Match the "pattern" against the "text" string. */
-static int wildmatch(const char *pattern, const char *text, unsigned int flags)
-{
-       // local modification: move WM_CASEFOLD here
-       if (ignore_case)
-               flags |= WM_CASEFOLD;
-
-       return dowild((const uchar*)pattern, (const uchar*)text, flags);
-}
-
-// Copied from dir.h
-
-#define PATTERN_FLAG_NODIR 1
-#define PATTERN_FLAG_ENDSWITH 4
-#define PATTERN_FLAG_MUSTBEDIR 8
-#define PATTERN_FLAG_NEGATIVE 16
-
-// Copied from dir.c
-
-static int fspathncmp(const char *a, const char *b, size_t count)
-{
-       return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
-}
-
-static int simple_length(const char *match)
-{
-       int len = -1;
-
-       for (;;) {
-               unsigned char c = *match++;
-               len++;
-               if (c == '\0' || is_glob_special(c))
-                       return len;
-       }
-}
-
-static int no_wildcard(const char *string)
-{
-       return string[simple_length(string)] == '\0';
-}
-
-static void parse_path_pattern(const char **pattern,
-                              int *patternlen,
-                              unsigned *flags,
-                              int *nowildcardlen)
-{
-       const char *p = *pattern;
-       size_t i, len;
-
-       *flags = 0;
-       if (*p == '!') {
-               *flags |= PATTERN_FLAG_NEGATIVE;
-               p++;
-       }
-       len = strlen(p);
-       if (len && p[len - 1] == '/') {
-               len--;
-               *flags |= PATTERN_FLAG_MUSTBEDIR;
-       }
-       for (i = 0; i < len; i++) {
-               if (p[i] == '/')
-                       break;
-       }
-       if (i == len)
-               *flags |= PATTERN_FLAG_NODIR;
-       *nowildcardlen = simple_length(p);
-       /*
-        * we should have excluded the trailing slash from 'p' too,
-        * but that's one more allocation. Instead just make sure
-        * nowildcardlen does not exceed real patternlen
-        */
-       if (*nowildcardlen > len)
-               *nowildcardlen = len;
-       if (*p == '*' && no_wildcard(p + 1))
-               *flags |= PATTERN_FLAG_ENDSWITH;
-       *pattern = p;
-       *patternlen = len;
-}
-
-static void trim_trailing_spaces(char *buf)
-{
-       char *p, *last_space = NULL;
-
-       for (p = buf; *p; p++)
-               switch (*p) {
-               case ' ':
-                       if (!last_space)
-                               last_space = p;
-                       break;
-               case '\\':
-                       p++;
-                       if (!*p)
-                               return;
-                       /* fallthrough */
-               default:
-                       last_space = NULL;
-               }
-
-       if (last_space)
-               *last_space = '\0';
-}
-
-static int match_basename(const char *basename, int basenamelen,
-                         const char *pattern, int prefix, int patternlen,
-                         unsigned flags)
-{
-       if (prefix == patternlen) {
-               if (patternlen == basenamelen &&
-                   !fspathncmp(pattern, basename, basenamelen))
-                       return 1;
-       } else if (flags & PATTERN_FLAG_ENDSWITH) {
-               /* "*literal" matching against "fooliteral" */
-               if (patternlen - 1 <= basenamelen &&
-                   !fspathncmp(pattern + 1,
-                                  basename + basenamelen - (patternlen - 1),
-                                  patternlen - 1))
-                       return 1;
-       } else {
-               // local modification: call wildmatch() directly
-               if (!wildmatch(pattern, basename, flags))
-                       return 1;
-       }
-       return 0;
-}
-
-static int match_pathname(const char *pathname, int pathlen,
-                         const char *base, int baselen,
-                         const char *pattern, int prefix, int patternlen)
-{
-       // local modification: remove local variables
-
-       /*
-        * match with FNM_PATHNAME; the pattern has base implicitly
-        * in front of it.
-        */
-       if (*pattern == '/') {
-               pattern++;
-               patternlen--;
-               prefix--;
-       }
-
-       /*
-        * baselen does not count the trailing slash. base[] may or
-        * may not end with a trailing slash though.
-        */
-       if (pathlen < baselen + 1 ||
-           (baselen && pathname[baselen] != '/') ||
-           fspathncmp(pathname, base, baselen))
-               return 0;
-
-       // local modification: simplified because always baselen > 0
-       pathname += baselen + 1;
-       pathlen -= baselen + 1;
-
-       if (prefix) {
-               /*
-                * if the non-wildcard part is longer than the
-                * remaining pathname, surely it cannot match.
-                */
-               if (prefix > pathlen)
-                       return 0;
-
-               if (fspathncmp(pattern, pathname, prefix))
-                       return 0;
-               pattern += prefix;
-               patternlen -= prefix;
-               pathname += prefix;
-               pathlen -= prefix;
-
-               /*
-                * If the whole pattern did not have a wildcard,
-                * then our prefix match is all we need; we
-                * do not need to call fnmatch at all.
-                */
-               if (!patternlen && !pathlen)
-                       return 1;
-       }
-
-       // local modification: call wildmatch() directly
-       return !wildmatch(pattern, pathname, WM_PATHNAME);
-}
-
-// Copied from git/utf8.c
-
-static const char utf8_bom[] = "\357\273\277";
-
-//----------------------------(IMPORT FROM GIT END)----------------------------
-
-struct pattern {
-       unsigned int flags;
-       int nowildcardlen;
-       int patternlen;
-       int dirlen;
-       char pattern[];
-};
-
-static struct pattern **pattern_list;
-static int nr_patterns, alloced_patterns;
-
-// Remember the number of patterns at each directory level
-static int *nr_patterns_at;
-// Track the current/max directory level;
-static int depth, max_depth;
-static bool debug_on;
-static FILE *out_fp, *stat_fp;
-static char *prefix = "";
-static char *progname;
-
-static void __attribute__((noreturn)) perror_exit(const char *s)
-{
-       perror(s);
-
-       exit(EXIT_FAILURE);
-}
-
-static void __attribute__((noreturn)) error_exit(const char *fmt, ...)
-{
-       va_list args;
-
-       fprintf(stderr, "%s: error: ", progname);
-
-       va_start(args, fmt);
-       vfprintf(stderr, fmt, args);
-       va_end(args);
-
-       exit(EXIT_FAILURE);
-}
-
-static void debug(const char *fmt, ...)
-{
-       va_list args;
-       int i;
-
-       if (!debug_on)
-               return;
-
-       fprintf(stderr, "[DEBUG] ");
-
-       for (i = 0; i < depth * 2; i++)
-               fputc(' ', stderr);
-
-       va_start(args, fmt);
-       vfprintf(stderr, fmt, args);
-       va_end(args);
-}
-
-static void *xrealloc(void *ptr, size_t size)
-{
-       ptr = realloc(ptr, size);
-       if (!ptr)
-               perror_exit(progname);
-
-       return ptr;
-}
-
-static void *xmalloc(size_t size)
-{
-       return xrealloc(NULL, size);
-}
-
-// similar to last_matching_pattern_from_list() in GIT
-static bool is_ignored(const char *path, int pathlen, int dirlen, bool is_dir)
-{
-       int i;
-
-       // Search in the reverse order because the last matching pattern wins.
-       for (i = nr_patterns - 1; i >= 0; i--) {
-               struct pattern *p = pattern_list[i];
-               unsigned int flags = p->flags;
-               const char *gitignore_dir = p->pattern + p->patternlen + 1;
-               bool ignored;
-
-               if ((flags & PATTERN_FLAG_MUSTBEDIR) && !is_dir)
-                       continue;
-
-               if (flags & PATTERN_FLAG_NODIR) {
-                       if (!match_basename(path + dirlen + 1,
-                                           pathlen - dirlen - 1,
-                                           p->pattern,
-                                           p->nowildcardlen,
-                                           p->patternlen,
-                                           p->flags))
-                               continue;
-               } else {
-                       if (!match_pathname(path, pathlen,
-                                           gitignore_dir, p->dirlen,
-                                           p->pattern,
-                                           p->nowildcardlen,
-                                           p->patternlen))
-                               continue;
-               }
-
-               debug("%s: matches %s%s%s (%s/.gitignore)\n", path,
-                     flags & PATTERN_FLAG_NEGATIVE ? "!" : "", p->pattern,
-                     flags & PATTERN_FLAG_MUSTBEDIR ? "/" : "",
-                     gitignore_dir);
-
-               ignored = (flags & PATTERN_FLAG_NEGATIVE) == 0;
-               if (ignored)
-                       debug("Ignore: %s\n", path);
-
-               return ignored;
-       }
-
-       debug("%s: no match\n", path);
-
-       return false;
-}
-
-static void add_pattern(const char *string, const char *dir, int dirlen)
-{
-       struct pattern *p;
-       int patternlen, nowildcardlen;
-       unsigned int flags;
-
-       parse_path_pattern(&string, &patternlen, &flags, &nowildcardlen);
-
-       if (patternlen == 0)
-               return;
-
-       p = xmalloc(sizeof(*p) + patternlen + dirlen + 2);
-
-       memcpy(p->pattern, string, patternlen);
-       p->pattern[patternlen] = 0;
-       memcpy(p->pattern + patternlen + 1, dir, dirlen);
-       p->pattern[patternlen + 1 + dirlen] = 0;
-
-       p->patternlen = patternlen;
-       p->nowildcardlen = nowildcardlen;
-       p->dirlen = dirlen;
-       p->flags = flags;
-
-       debug("Add pattern: %s%s%s\n",
-             flags & PATTERN_FLAG_NEGATIVE ? "!" : "", p->pattern,
-             flags & PATTERN_FLAG_MUSTBEDIR ? "/" : "");
-
-       if (nr_patterns >= alloced_patterns) {
-               alloced_patterns += 128;
-               pattern_list = xrealloc(pattern_list,
-                                       sizeof(*pattern_list) * alloced_patterns);
-       }
-
-       pattern_list[nr_patterns++] = p;
-}
-
-// similar to add_patterns_from_buffer() in GIT
-static void add_patterns_from_gitignore(const char *dir, int dirlen)
-{
-       struct stat st;
-       char path[PATH_MAX], *buf, *entry;
-       size_t size;
-       int fd, pathlen, i;
-
-       pathlen = snprintf(path, sizeof(path), "%s/.gitignore", dir);
-       if (pathlen >= sizeof(path))
-               error_exit("%s: too long path was truncated\n", path);
-
-       fd = open(path, O_RDONLY | O_NOFOLLOW);
-       if (fd < 0) {
-               if (errno != ENOENT)
-                       return perror_exit(path);
-               return;
-       }
-
-       if (fstat(fd, &st) < 0)
-               perror_exit(path);
-
-       size = st.st_size;
-
-       buf = xmalloc(size + 1);
-       if (read(fd, buf, st.st_size) != st.st_size)
-               perror_exit(path);
-
-       buf[st.st_size] = '\n';
-       if (close(fd))
-               perror_exit(path);
-
-       debug("Parse %s\n", path);
-
-       entry = buf;
-
-       // skip utf8 bom
-       if (!strncmp(entry, utf8_bom, strlen(utf8_bom)))
-               entry += strlen(utf8_bom);
-
-       for (i = entry - buf; i < size; i++) {
-               if (buf[i] == '\n') {
-                       if (entry != buf + i && entry[0] != '#') {
-                               buf[i - (i && buf[i-1] == '\r')] = 0;
-                               trim_trailing_spaces(entry);
-                               add_pattern(entry, dir, dirlen);
-                       }
-                       entry = buf + i + 1;
-               }
-       }
-
-       free(buf);
-}
-
-// Save the current number of patterns and increment the depth
-static void increment_depth(void)
-{
-       if (depth >= max_depth) {
-               max_depth += 1;
-               nr_patterns_at = xrealloc(nr_patterns_at,
-                                         sizeof(*nr_patterns_at) * max_depth);
-       }
-
-       nr_patterns_at[depth] = nr_patterns;
-       depth++;
-}
-
-// Decrement the depth, and free up the patterns of this directory level.
-static void decrement_depth(void)
-{
-       depth--;
-       assert(depth >= 0);
-
-       while (nr_patterns > nr_patterns_at[depth])
-               free(pattern_list[--nr_patterns]);
-}
-
-static void print_path(const char *path)
-{
-       // The path always starts with "./"
-       assert(strlen(path) >= 2);
-
-       // Replace the root directory with a preferred prefix.
-       // This is useful for the tar command.
-       fprintf(out_fp, "%s%s\n", prefix, path + 2);
-}
-
-static void print_stat(const char *path, struct stat *st)
-{
-       if (!stat_fp)
-               return;
-
-       if (!S_ISREG(st->st_mode) && !S_ISLNK(st->st_mode))
-               return;
-
-       assert(strlen(path) >= 2);
-
-       fprintf(stat_fp, "%c %9ld %10ld %s\n",
-               S_ISLNK(st->st_mode) ? 'l' : '-',
-               st->st_size, st->st_mtim.tv_sec, path + 2);
-}
-
-// Traverse the entire directory tree, parsing .gitignore files.
-// Print file paths that are not tracked by git.
-//
-// Return true if all files under the directory are ignored, false otherwise.
-static bool traverse_directory(const char *dir, int dirlen)
-{
-       bool all_ignored = true;
-       DIR *dirp;
-
-       debug("Enter[%d]: %s\n", depth, dir);
-       increment_depth();
-
-       add_patterns_from_gitignore(dir, dirlen);
-
-       dirp = opendir(dir);
-       if (!dirp)
-               perror_exit(dir);
-
-       while (1) {
-               struct dirent *d;
-               struct stat st;
-               char path[PATH_MAX];
-               int pathlen;
-               bool ignored;
-
-               errno = 0;
-               d = readdir(dirp);
-               if (!d) {
-                       if (errno)
-                               perror_exit(dir);
-                       break;
-               }
-
-               if (!strcmp(d->d_name, "..") || !strcmp(d->d_name, "."))
-                       continue;
-
-               pathlen = snprintf(path, sizeof(path), "%s/%s", dir, d->d_name);
-               if (pathlen >= sizeof(path))
-                       error_exit("%s: too long path was truncated\n", path);
-
-               if (lstat(path, &st) < 0)
-                       perror_exit(path);
-
-               if ((!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode)) ||
-                   is_ignored(path, pathlen, dirlen, S_ISDIR(st.st_mode))) {
-                       ignored = true;
-               } else {
-                       if (S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode))
-                               // If all the files in a directory are ignored,
-                               // let's ignore that directory as well. This
-                               // will avoid empty directories in the tarball.
-                               ignored = traverse_directory(path, pathlen);
-                       else
-                               ignored = false;
-               }
-
-               if (ignored) {
-                       print_path(path);
-               } else {
-                       print_stat(path, &st);
-                       all_ignored = false;
-               }
-       }
-
-       if (closedir(dirp))
-               perror_exit(dir);
-
-       decrement_depth();
-       debug("Leave[%d]: %s\n", depth, dir);
-
-       return all_ignored;
-}
-
-static void usage(void)
-{
-       fprintf(stderr,
-               "usage: %s [options]\n"
-               "\n"
-               "Show files that are ignored by git\n"
-               "\n"
-               "options:\n"
-               "  -d, --debug                  print debug messages to stderr\n"
-               "  -e, --exclude PATTERN        add the given exclude pattern\n"
-               "  -h, --help                   show this help message and exit\n"
-               "  -i, --ignore-case            Ignore case differences between the patterns and the files\n"
-               "  -o, --output FILE            output the ignored files to a file (default: '-', i.e. stdout)\n"
-               "  -p, --prefix PREFIX          prefix added to each path (default: empty string)\n"
-               "  -r, --rootdir DIR            root of the source tree (default: current working directory)\n"
-               "  -s, --stat FILE              output the file stat of non-ignored files to a file\n",
-               progname);
-}
-
-static void open_output(const char *pathname, FILE **fp)
-{
-       if (strcmp(pathname, "-")) {
-               *fp = fopen(pathname, "w");
-               if (!*fp)
-                       perror_exit(pathname);
-       } else {
-               *fp = stdout;
-       }
-}
-
-static void close_output(const char *pathname, FILE *fp)
-{
-       fflush(fp);
-
-       if (ferror(fp))
-               error_exit("not all data was written to the output\n");
-
-       if (fclose(fp))
-               perror_exit(pathname);
-}
-
-int main(int argc, char *argv[])
-{
-       const char *output = "-";
-       const char *rootdir = ".";
-       const char *stat = NULL;
-
-       progname = strrchr(argv[0], '/');
-       if (progname)
-               progname++;
-       else
-               progname = argv[0];
-
-       while (1) {
-               static struct option long_options[] = {
-                       {"debug",       no_argument,       NULL, 'd'},
-                       {"help",        no_argument,       NULL, 'h'},
-                       {"ignore-case", no_argument,       NULL, 'i'},
-                       {"output",      required_argument, NULL, 'o'},
-                       {"prefix",      required_argument, NULL, 'p'},
-                       {"rootdir",     required_argument, NULL, 'r'},
-                       {"stat",        required_argument, NULL, 's'},
-                       {"exclude",     required_argument, NULL, 'x'},
-                       {},
-               };
-
-               int c = getopt_long(argc, argv, "dhino:p:r:s:x:", long_options, NULL);
-
-               if (c == -1)
-                       break;
-
-               switch (c) {
-               case 'd':
-                       debug_on = true;
-                       break;
-               case 'h':
-                       usage();
-                       exit(0);
-               case 'i':
-                       ignore_case = true;
-                       break;
-               case 'o':
-                       output = optarg;
-                       break;
-               case 'p':
-                       prefix = optarg;
-                       break;
-               case 'r':
-                       rootdir = optarg;
-                       break;
-               case 's':
-                       stat = optarg;
-                       break;
-               case 'x':
-                       add_pattern(optarg, ".", strlen("."));
-                       break;
-               case '?':
-                       usage();
-                       /* fallthrough */
-               default:
-                       exit(EXIT_FAILURE);
-               }
-       }
-
-       open_output(output, &out_fp);
-       if (stat && stat[0])
-               open_output(stat, &stat_fp);
-
-       if (chdir(rootdir))
-               perror_exit(rootdir);
-
-       add_pattern(".git/", ".", strlen("."));
-
-       if (traverse_directory(".", strlen(".")))
-               print_path("./");
-
-       assert(depth == 0);
-
-       while (nr_patterns > 0)
-               free(pattern_list[--nr_patterns]);
-       free(pattern_list);
-       free(nr_patterns_at);
-
-       close_output(output, out_fp);
-       if (stat_fp)
-               close_output(stat, stat_fp);
-
-       return 0;
-}
index efff8078e39581349f72fd8fbe6e2c062e36d372..9466b6a2abae46c41ec1d4d4e06eb9001dc79608 100644 (file)
@@ -1733,7 +1733,7 @@ static void extract_crcs_for_object(const char *object, struct module *mod)
                if (!isdigit(*p))
                        continue;       /* skip this line */
 
-               crc = strtol(p, &p, 0);
+               crc = strtoul(p, &p, 0);
                if (*p != '\n')
                        continue;       /* skip this line */
 
index ff5e7d8e380bba654657bf43dc544a571fd90e28..7b23f52c70c5fe33145bc4838dd52e95973b3a14 100755 (executable)
@@ -51,8 +51,118 @@ create_package() {
        dpkg-deb $dpkg_deb_opts ${KDEB_COMPRESS:+-Z$KDEB_COMPRESS} --build "$pdir" ..
 }
 
-deploy_kernel_headers () {
+install_linux_image () {
        pdir=$1
+       pname=$2
+
+       rm -rf ${pdir}
+
+       # Only some architectures with OF support have this target
+       if is_enabled CONFIG_OF_EARLY_FLATTREE && [ -d "${srctree}/arch/${SRCARCH}/boot/dts" ]; then
+               ${MAKE} -f ${srctree}/Makefile INSTALL_DTBS_PATH="${pdir}/usr/lib/linux-image-${KERNELRELEASE}" dtbs_install
+       fi
+
+       if is_enabled CONFIG_MODULES; then
+               ${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${pdir}" modules_install
+               rm -f "${pdir}/lib/modules/${KERNELRELEASE}/build"
+               rm -f "${pdir}/lib/modules/${KERNELRELEASE}/source"
+               if [ "${SRCARCH}" = um ] ; then
+                       mkdir -p "${pdir}/usr/lib/uml/modules"
+                       mv "${pdir}/lib/modules/${KERNELRELEASE}" "${pdir}/usr/lib/uml/modules/${KERNELRELEASE}"
+               fi
+       fi
+
+       # Install the kernel
+       if [ "${ARCH}" = um ] ; then
+               mkdir -p "${pdir}/usr/bin" "${pdir}/usr/share/doc/${pname}"
+               cp System.map "${pdir}/usr/lib/uml/modules/${KERNELRELEASE}/System.map"
+               cp ${KCONFIG_CONFIG} "${pdir}/usr/share/doc/${pname}/config"
+               gzip "${pdir}/usr/share/doc/${pname}/config"
+       else
+               mkdir -p "${pdir}/boot"
+               cp System.map "${pdir}/boot/System.map-${KERNELRELEASE}"
+               cp ${KCONFIG_CONFIG} "${pdir}/boot/config-${KERNELRELEASE}"
+       fi
+
+       # Not all arches have the same installed path in debian
+       # XXX: have each arch Makefile export a variable of the canonical image install
+       # path instead
+       case "${SRCARCH}" in
+       um)
+               installed_image_path="usr/bin/linux-${KERNELRELEASE}";;
+       parisc|mips|powerpc)
+               installed_image_path="boot/vmlinux-${KERNELRELEASE}";;
+       *)
+               installed_image_path="boot/vmlinuz-${KERNELRELEASE}";;
+       esac
+       cp "$(${MAKE} -s -f ${srctree}/Makefile image_name)" "${pdir}/${installed_image_path}"
+
+       # Install the maintainer scripts
+       # Note: hook scripts under /etc/kernel are also executed by official Debian
+       # kernel packages, as well as kernel packages built using make-kpkg.
+       # make-kpkg sets $INITRD to indicate whether an initramfs is wanted, and
+       # so do we; recent versions of dracut and initramfs-tools will obey this.
+       debhookdir=${KDEB_HOOKDIR:-/etc/kernel}
+       for script in postinst postrm preinst prerm; do
+               mkdir -p "${pdir}${debhookdir}/${script}.d"
+
+               mkdir -p "${pdir}/DEBIAN"
+               cat <<-EOF > "${pdir}/DEBIAN/${script}"
+
+               #!/bin/sh
+
+               set -e
+
+               # Pass maintainer script parameters to hook scripts
+               export DEB_MAINT_PARAMS="\$*"
+
+               # Tell initramfs builder whether it's wanted
+               export INITRD=$(if_enabled_echo CONFIG_BLK_DEV_INITRD Yes No)
+
+               test -d ${debhookdir}/${script}.d && run-parts --arg="${KERNELRELEASE}" --arg="/${installed_image_path}" ${debhookdir}/${script}.d
+               exit 0
+               EOF
+               chmod 755 "${pdir}/DEBIAN/${script}"
+       done
+}
+
+install_linux_image_dbg () {
+       pdir=$1
+       image_pdir=$2
+
+       rm -rf ${pdir}
+
+       for module in $(find ${image_pdir}/lib/modules/ -name *.ko -printf '%P\n'); do
+               module=lib/modules/${module}
+               mkdir -p $(dirname ${pdir}/usr/lib/debug/${module})
+               # only keep debug symbols in the debug file
+               ${OBJCOPY} --only-keep-debug ${image_pdir}/${module} ${pdir}/usr/lib/debug/${module}
+               # strip original module from debug symbols
+               ${OBJCOPY} --strip-debug ${image_pdir}/${module}
+               # then add a link to those
+               ${OBJCOPY} --add-gnu-debuglink=${pdir}/usr/lib/debug/${module} ${image_pdir}/${module}
+       done
+
+       # re-sign stripped modules
+       if is_enabled CONFIG_MODULE_SIG_ALL; then
+               ${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${image_pdir}" modules_sign
+       fi
+
+       # Build debug package
+       # Different tools want the image in different locations
+       # perf
+       mkdir -p ${pdir}/usr/lib/debug/lib/modules/${KERNELRELEASE}/
+       cp vmlinux ${pdir}/usr/lib/debug/lib/modules/${KERNELRELEASE}/
+       # systemtap
+       mkdir -p ${pdir}/usr/lib/debug/boot/
+       ln -s ../lib/modules/${KERNELRELEASE}/vmlinux ${pdir}/usr/lib/debug/boot/vmlinux-${KERNELRELEASE}
+       # kdump-tools
+       ln -s lib/modules/${KERNELRELEASE}/vmlinux ${pdir}/usr/lib/debug/vmlinux-${KERNELRELEASE}
+}
+
+install_kernel_headers () {
+       pdir=$1
+       version=$2
 
        rm -rf $pdir
 
@@ -89,7 +199,7 @@ deploy_kernel_headers () {
        ln -s /usr/src/linux-headers-$version $pdir/lib/modules/$version/build
 }
 
-deploy_libc_headers () {
+install_libc_headers () {
        pdir=$1
 
        rm -rf $pdir
@@ -104,132 +214,38 @@ deploy_libc_headers () {
        mv $pdir/usr/include/asm $pdir/usr/include/$host_arch/
 }
 
-version=$KERNELRELEASE
-tmpdir=debian/linux-image
-dbg_dir=debian/linux-image-dbg
-packagename=linux-image-$version
-dbg_packagename=$packagename-dbg
-
-if [ "$ARCH" = "um" ] ; then
-       packagename=user-mode-linux-$version
-fi
-
-# Not all arches have the same installed path in debian
-# XXX: have each arch Makefile export a variable of the canonical image install
-# path instead
-case $ARCH in
-um)
-       installed_image_path="usr/bin/linux-$version"
-       ;;
-parisc|mips|powerpc)
-       installed_image_path="boot/vmlinux-$version"
-       ;;
-*)
-       installed_image_path="boot/vmlinuz-$version"
-esac
-
-BUILD_DEBUG=$(if_enabled_echo CONFIG_DEBUG_INFO Yes)
-
-# Setup the directory structure
-rm -rf "$tmpdir" "$dbg_dir" debian/files
-mkdir -m 755 -p "$tmpdir/DEBIAN"
-mkdir -p "$tmpdir/lib" "$tmpdir/boot"
-
-# Install the kernel
-if [ "$ARCH" = "um" ] ; then
-       mkdir -p "$tmpdir/usr/lib/uml/modules/$version" "$tmpdir/usr/bin" "$tmpdir/usr/share/doc/$packagename"
-       cp System.map "$tmpdir/usr/lib/uml/modules/$version/System.map"
-       cp $KCONFIG_CONFIG "$tmpdir/usr/share/doc/$packagename/config"
-       gzip "$tmpdir/usr/share/doc/$packagename/config"
-else
-       cp System.map "$tmpdir/boot/System.map-$version"
-       cp $KCONFIG_CONFIG "$tmpdir/boot/config-$version"
-fi
-cp "$($MAKE -s -f $srctree/Makefile image_name)" "$tmpdir/$installed_image_path"
-
-if is_enabled CONFIG_OF_EARLY_FLATTREE; then
-       # Only some architectures with OF support have this target
-       if [ -d "${srctree}/arch/$SRCARCH/boot/dts" ]; then
-               $MAKE -f $srctree/Makefile INSTALL_DTBS_PATH="$tmpdir/usr/lib/$packagename" dtbs_install
-       fi
-fi
-
-if is_enabled CONFIG_MODULES; then
-       INSTALL_MOD_PATH="$tmpdir" $MAKE -f $srctree/Makefile modules_install
-       rm -f "$tmpdir/lib/modules/$version/build"
-       rm -f "$tmpdir/lib/modules/$version/source"
-       if [ "$ARCH" = "um" ] ; then
-               mv "$tmpdir/lib/modules/$version"/* "$tmpdir/usr/lib/uml/modules/$version/"
-               rmdir "$tmpdir/lib/modules/$version"
-       fi
-       if [ -n "$BUILD_DEBUG" ] ; then
-               for module in $(find $tmpdir/lib/modules/ -name *.ko -printf '%P\n'); do
-                       module=lib/modules/$module
-                       mkdir -p $(dirname $dbg_dir/usr/lib/debug/$module)
-                       # only keep debug symbols in the debug file
-                       $OBJCOPY --only-keep-debug $tmpdir/$module $dbg_dir/usr/lib/debug/$module
-                       # strip original module from debug symbols
-                       $OBJCOPY --strip-debug $tmpdir/$module
-                       # then add a link to those
-                       $OBJCOPY --add-gnu-debuglink=$dbg_dir/usr/lib/debug/$module $tmpdir/$module
-               done
-
-               # resign stripped modules
-               if is_enabled CONFIG_MODULE_SIG_ALL; then
-                       INSTALL_MOD_PATH="$tmpdir" $MAKE -f $srctree/Makefile modules_sign
-               fi
-       fi
-fi
-
-# Install the maintainer scripts
-# Note: hook scripts under /etc/kernel are also executed by official Debian
-# kernel packages, as well as kernel packages built using make-kpkg.
-# make-kpkg sets $INITRD to indicate whether an initramfs is wanted, and
-# so do we; recent versions of dracut and initramfs-tools will obey this.
-debhookdir=${KDEB_HOOKDIR:-/etc/kernel}
-for script in postinst postrm preinst prerm ; do
-       mkdir -p "$tmpdir$debhookdir/$script.d"
-       cat <<EOF > "$tmpdir/DEBIAN/$script"
-#!/bin/sh
-
-set -e
-
-# Pass maintainer script parameters to hook scripts
-export DEB_MAINT_PARAMS="\$*"
-
-# Tell initramfs builder whether it's wanted
-export INITRD=$(if_enabled_echo CONFIG_BLK_DEV_INITRD Yes No)
-
-test -d $debhookdir/$script.d && run-parts --arg="$version" --arg="/$installed_image_path" $debhookdir/$script.d
-exit 0
-EOF
-       chmod 755 "$tmpdir/DEBIAN/$script"
+rm -f debian/files
+
+packages_enabled=$(dh_listpackages)
+
+for package in ${packages_enabled}
+do
+       case ${package} in
+       *-dbg)
+               # This must be done after linux-image, that is, we expect the
+               # debug package appears after linux-image in debian/control.
+               install_linux_image_dbg debian/linux-image-dbg debian/linux-image;;
+       linux-image-*|user-mode-linux-*)
+               install_linux_image debian/linux-image ${package};;
+       linux-libc-dev)
+               install_libc_headers debian/linux-libc-dev;;
+       linux-headers-*)
+               install_kernel_headers debian/linux-headers ${package#linux-headers-};;
+       esac
 done
 
-if [ "$ARCH" != "um" ]; then
-       if is_enabled CONFIG_MODULES; then
-               deploy_kernel_headers debian/linux-headers
-               create_package linux-headers-$version debian/linux-headers
-       fi
-
-       deploy_libc_headers debian/linux-libc-dev
-       create_package linux-libc-dev debian/linux-libc-dev
-fi
-
-create_package "$packagename" "$tmpdir"
-
-if [ -n "$BUILD_DEBUG" ] ; then
-       # Build debug package
-       # Different tools want the image in different locations
-       # perf
-       mkdir -p $dbg_dir/usr/lib/debug/lib/modules/$version/
-       cp vmlinux $dbg_dir/usr/lib/debug/lib/modules/$version/
-       # systemtap
-       mkdir -p $dbg_dir/usr/lib/debug/boot/
-       ln -s ../lib/modules/$version/vmlinux $dbg_dir/usr/lib/debug/boot/vmlinux-$version
-       # kdump-tools
-       ln -s lib/modules/$version/vmlinux $dbg_dir/usr/lib/debug/vmlinux-$version
-       create_package "$dbg_packagename" "$dbg_dir"
-fi
+for package in ${packages_enabled}
+do
+       case ${package} in
+       *-dbg)
+               create_package ${package} debian/linux-image-dbg;;
+       linux-image-*|user-mode-linux-*)
+               create_package ${package} debian/linux-image;;
+       linux-libc-dev)
+               create_package ${package} debian/linux-libc-dev;;
+       linux-headers-*)
+               create_package ${package} debian/linux-headers;;
+       esac
+done
 
 exit 0
index b079b0d121d47359d447a83d87822072d619da28..7950eff01781a306681985ce5a0a46743c411af5 100755 (executable)
@@ -1,16 +1,14 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0-only
 
-# Set up CROSS_COMPILE if we are cross-compiling, but not called from the
-# kernel toplevel Makefile
-if [ -z "${CROSS_COMPILE}${cross_compiling}" -a "${DEB_HOST_ARCH}" != "${DEB_BUILD_ARCH}" ]; then
+# Set up CROSS_COMPILE if not defined yet
+if [ "${CROSS_COMPILE+set}" != "set" -a "${DEB_HOST_ARCH}" != "${DEB_BUILD_ARCH}" ]; then
        echo CROSS_COMPILE=${DEB_HOST_GNU_TYPE}-
 fi
 
 version=$(dpkg-parsechangelog -S Version)
-version_upstream="${version%-*}"
-debian_revision="${version#${version_upstream}}"
-debian_revision="${debian_revision#*-}"
+debian_revision="${version##*-}"
 
-echo KERNELRELEASE=${version_upstream}
-echo KBUILD_BUILD_VERSION=${debian_revision}
+if [ "${version}" != "${debian_revision}" ]; then
+       echo KBUILD_BUILD_VERSION=${debian_revision}
+fi
diff --git a/scripts/package/gen-diff-patch b/scripts/package/gen-diff-patch
new file mode 100755 (executable)
index 0000000..8a98b7b
--- /dev/null
@@ -0,0 +1,36 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-only
+
+diff_patch=$1
+
+mkdir -p "$(dirname "${diff_patch}")"
+
+git -C "${srctree:-.}" diff HEAD > "${diff_patch}"
+
+if [ ! -s "${diff_patch}" ] ||
+   [ -z "$(git -C "${srctree:-.}" ls-files --other --exclude-standard | head -n1)" ]; then
+       exit
+fi
+
+# The source tarball, which is generated by 'git archive', contains everything
+# you committed in the repository. If you have local diff ('git diff HEAD'),
+# it will go into ${diff_patch}. If untracked files are remaining, the resulting
+# source package may not be correct.
+#
+# Examples:
+#  - You modified a source file to add #include "new-header.h"
+#    but forgot to add new-header.h
+#  - You modified a Makefile to add 'obj-$(CONFIG_FOO) += new-dirver.o'
+#    but you forgot to add new-driver.c
+#
+# You need to commit them, or at least stage them by 'git add'.
+#
+# This script does not take care of untracked files because doing so would
+# introduce additional complexity. Instead, print a warning message here if
+# untracked files are found.
+# If all untracked files are just garbage, you can ignore this warning.
+echo >&2 "============================ WARNING ============================"
+echo >&2 "Your working tree has diff from HEAD, and also untracked file(s)."
+echo >&2 "Please make sure you did 'git add' for all new files you need in"
+echo >&2 "the source package."
+echo >&2 "================================================================="
index f74380036bb54e0b107e49da9bdaca8c0b89cb04..74b83c9ae0a843bb77cf5c2b51e3b32e3ec715c1 100755 (executable)
@@ -84,14 +84,73 @@ set_debarch() {
        fi
 }
 
+# Create debian/source/ if it is a source package build
+gen_source ()
+{
+       mkdir -p debian/source
+
+       echo "3.0 (quilt)" > debian/source/format
+
+       {
+               echo "diff-ignore"
+               echo "extend-diff-ignore = .*"
+       } > debian/source/local-options
+
+       # Add .config as a patch
+       mkdir -p debian/patches
+       {
+               echo "Subject: Add .config"
+               echo "Author: ${maintainer}"
+               echo
+               echo "--- /dev/null"
+               echo "+++ linux/.config"
+               diff -u /dev/null "${KCONFIG_CONFIG}" | tail -n +3
+       } > debian/patches/config.patch
+       echo config.patch > debian/patches/series
+
+       "${srctree}/scripts/package/gen-diff-patch" debian/patches/diff.patch
+       if [ -s debian/patches/diff.patch ]; then
+               sed -i "
+                       1iSubject: Add local diff
+                       1iAuthor: ${maintainer}
+                       1i
+               " debian/patches/diff.patch
+
+               echo diff.patch >> debian/patches/series
+       else
+               rm -f debian/patches/diff.patch
+       fi
+}
+
 rm -rf debian
+mkdir debian
+
+email=${DEBEMAIL-$EMAIL}
+
+# use email string directly if it contains <email>
+if echo "${email}" | grep -q '<.*>'; then
+       maintainer=${email}
+else
+       # or construct the maintainer string
+       user=${KBUILD_BUILD_USER-$(id -nu)}
+       name=${DEBFULLNAME-${user}}
+       if [ -z "${email}" ]; then
+               buildhost=${KBUILD_BUILD_HOST-$(hostname -f 2>/dev/null || hostname)}
+               email="${user}@${buildhost}"
+       fi
+       maintainer="${name} <${email}>"
+fi
+
+if [ "$1" = --need-source ]; then
+       gen_source
+fi
 
 # Some variables and settings used throughout the script
 version=$KERNELRELEASE
 if [ -n "$KDEB_PKGVERSION" ]; then
        packageversion=$KDEB_PKGVERSION
 else
-       packageversion=$version-$($srctree/init/build-version)
+       packageversion=$(${srctree}/scripts/setlocalversion --no-local ${srctree})-$($srctree/init/build-version)
 fi
 sourcename=${KDEB_SOURCENAME:-linux-upstream}
 
@@ -104,22 +163,6 @@ fi
 debarch=
 set_debarch
 
-email=${DEBEMAIL-$EMAIL}
-
-# use email string directly if it contains <email>
-if echo $email | grep -q '<.*>'; then
-       maintainer=$email
-else
-       # or construct the maintainer string
-       user=${KBUILD_BUILD_USER-$(id -nu)}
-       name=${DEBFULLNAME-$user}
-       if [ -z "$email" ]; then
-               buildhost=${KBUILD_BUILD_HOST-$(hostname -f 2>/dev/null || hostname)}
-               email="$user@$buildhost"
-       fi
-       maintainer="$name <$email>"
-fi
-
 # Try to determine distribution
 if [ -n "$KDEB_CHANGELOG_DIST" ]; then
         distribution=$KDEB_CHANGELOG_DIST
@@ -132,26 +175,6 @@ else
         echo >&2 "Install lsb-release or set \$KDEB_CHANGELOG_DIST explicitly"
 fi
 
-mkdir -p debian/source/
-echo "3.0 (quilt)" > debian/source/format
-
-{
-       echo "diff-ignore"
-       echo "extend-diff-ignore = .*"
-} > debian/source/local-options
-
-# Add .config as a patch
-mkdir -p debian/patches
-{
-       echo "Subject: Add .config"
-       echo "Author: ${maintainer}"
-       echo
-       echo "--- /dev/null"
-       echo "+++ linux/.config"
-       diff -u /dev/null "${KCONFIG_CONFIG}" | tail -n +3
-} > debian/patches/config
-echo config > debian/patches/series
-
 echo $debarch > debian/arch
 extra_build_depends=", $(if_enabled_echo CONFIG_UNWINDER_ORC libelf-dev:native)"
 extra_build_depends="$extra_build_depends, $(if_enabled_echo CONFIG_SYSTEM_TRUSTED_KEYRING libssl-dev:native)"
@@ -167,7 +190,7 @@ EOF
 
 # Generate copyright file
 cat <<EOF > debian/copyright
-This is a packacked upstream version of the Linux kernel.
+This is a packaged upstream version of the Linux kernel.
 
 The sources may be found at most Linux archive sites, including:
 https://www.kernel.org/pub/linux/kernel
@@ -192,7 +215,7 @@ Section: kernel
 Priority: optional
 Maintainer: $maintainer
 Rules-Requires-Root: no
-Build-Depends: bc, rsync, kmod, cpio, bison, flex $extra_build_depends
+Build-Depends: bc, debhelper, rsync, kmod, cpio, bison, flex $extra_build_depends
 Homepage: https://www.kernel.org/
 
 Package: $packagename-$version
@@ -200,6 +223,10 @@ Architecture: $debarch
 Description: Linux kernel, version $version
  This package contains the Linux kernel, modules and corresponding other
  files, version: $version.
+EOF
+
+if [ "${SRCARCH}" != um ]; then
+cat <<EOF >> debian/control
 
 Package: linux-libc-dev
 Section: devel
@@ -222,6 +249,7 @@ Description: Linux kernel headers for $version on $debarch
  This is useful for people who need to build external modules
 EOF
 fi
+fi
 
 if is_enabled CONFIG_DEBUG_INFO; then
 cat <<EOF >> debian/control
@@ -239,10 +267,12 @@ cat <<EOF > debian/rules
 #!$(command -v $MAKE) -f
 
 srctree ?= .
+KERNELRELEASE = ${KERNELRELEASE}
 
 build-indep:
 build-arch:
        \$(MAKE) -f \$(srctree)/Makefile ARCH=${ARCH} \
+       KERNELRELEASE=\$(KERNELRELEASE) \
        \$(shell \$(srctree)/scripts/package/deb-build-option) \
        olddefconfig all
 
@@ -250,7 +280,9 @@ build: build-arch
 
 binary-indep:
 binary-arch: build-arch
-       \$(MAKE) -f \$(srctree)/Makefile ARCH=${ARCH} intdeb-pkg
+       \$(MAKE) -f \$(srctree)/Makefile ARCH=${ARCH} \
+       KERNELRELEASE=\$(KERNELRELEASE) intdeb-pkg
+
 clean:
        rm -rf debian/files debian/linux-*
        \$(MAKE) -f \$(srctree)/Makefile ARCH=${ARCH} clean
index 3c550960dd39554a0cf60f0e6e3fd123a0eafd46..fc8ad3fbc0a95a96717dc8fd21a81c6ca77502b2 100755 (executable)
@@ -15,15 +15,20 @@ if [ "$1" = prebuilt ]; then
        MAKE="$MAKE -f $srctree/Makefile"
 else
        S=
+
+       mkdir -p rpmbuild/SOURCES
+       cp linux.tar.gz rpmbuild/SOURCES
+       cp "${KCONFIG_CONFIG}" rpmbuild/SOURCES/config
+       "${srctree}/scripts/package/gen-diff-patch" rpmbuild/SOURCES/diff.patch
 fi
 
-if grep -q CONFIG_MODULES=y .config; then
+if grep -q CONFIG_MODULES=y include/config/auto.conf; then
        M=
 else
        M=DEL
 fi
 
-if grep -q CONFIG_DRM=y .config; then
+if grep -q CONFIG_DRM=y include/config/auto.conf; then
        PROVIDES=kernel-drm
 fi
 
@@ -48,7 +53,8 @@ sed -e '/^DEL/d' -e 's/^\t*//' <<EOF
        Vendor: The Linux Community
        URL: https://www.kernel.org
 $S     Source0: linux.tar.gz
-$S     Source1: .config
+$S     Source1: config
+$S     Source2: diff.patch
        Provides: $PROVIDES
 $S     BuildRequires: bc binutils bison dwarves
 $S     BuildRequires: (elfutils-libelf-devel or libelf-devel) flex
@@ -85,7 +91,8 @@ $S$M  against the $__KERNELRELEASE kernel package.
 $S$M
 $S     %prep
 $S     %setup -q -n linux
-$S     cp %{SOURCE1} .
+$S     cp %{SOURCE1} .config
+$S     patch -p1 < %{SOURCE2}
 $S
 $S     %build
 $S     $MAKE %{?_smp_mflags} KERNELRELEASE=$KERNELRELEASE KBUILD_BUILD_VERSION=%{release}
index e54839a42d4b49daf5cc3102e93adab36b59ff50..3d3babac82982b4bfec180b402a7f9e557ceafb4 100755 (executable)
 #
 
 usage() {
-       echo "Usage: $0 [srctree]" >&2
+       echo "Usage: $0 [--no-local] [srctree]" >&2
        exit 1
 }
 
+no_local=false
+if test "$1" = "--no-local"; then
+       no_local=true
+       shift
+fi
+
 srctree=.
 if test $# -gt 0; then
        srctree=$1
@@ -26,14 +32,22 @@ fi
 
 scm_version()
 {
-       local short
+       local short=false
+       local no_dirty=false
        local tag
-       short=false
+
+       while [ $# -gt 0 ];
+       do
+               case "$1" in
+               --short)
+                       short=true;;
+               --no-dirty)
+                       no_dirty=true;;
+               esac
+               shift
+       done
 
        cd "$srctree"
-       if test "$1" = "--short"; then
-               short=true
-       fi
 
        if test -n "$(git rev-parse --show-cdup 2>/dev/null)"; then
                return
@@ -75,6 +89,10 @@ scm_version()
                printf '%s%s' -g "$(echo $head | cut -c1-12)"
        fi
 
+       if ${no_dirty}; then
+               return
+       fi
+
        # Check for uncommitted changes.
        # This script must avoid any write attempt to the source tree, which
        # might be read-only.
@@ -110,11 +128,6 @@ collect_files()
        echo "$res"
 }
 
-if ! test -e include/config/auto.conf; then
-       echo "Error: kernelrelease not valid - run 'make prepare' to update it" >&2
-       exit 1
-fi
-
 if [ -z "${KERNELVERSION}" ]; then
        echo "KERNELVERSION is not set" >&2
        exit 1
@@ -126,6 +139,16 @@ if test ! "$srctree" -ef .; then
        file_localversion="${file_localversion}$(collect_files "$srctree"/localversion*)"
 fi
 
+if ${no_local}; then
+       echo "${KERNELVERSION}$(scm_version --no-dirty)"
+       exit 0
+fi
+
+if ! test -e include/config/auto.conf; then
+       echo "Error: kernelrelease not valid - run 'make prepare' to update it" >&2
+       exit 1
+fi
+
 # version string from CONFIG_LOCALVERSION
 config_localversion=$(sed -n 's/^CONFIG_LOCALVERSION=\(.*\)$/\1/p' include/config/auto.conf)
 
index e6db09a779b779c4dfebe6910b2338bf7df6c28d..97abeb9b9a194b2710d4636c7977a0eba7d6a518 100644 (file)
@@ -32,11 +32,6 @@ config SECURITY
 
          If you are unsure how to answer this question, answer N.
 
-config SECURITY_WRITABLE_HOOKS
-       depends on SECURITY
-       bool
-       default n
-
 config SECURITYFS
        bool "Enable the securityfs filesystem"
        help
@@ -110,7 +105,7 @@ config INTEL_TXT
          See <https://www.intel.com/technology/security/> for more information
          about Intel(R) TXT.
          See <http://tboot.sourceforge.net> for more information about tboot.
-         See Documentation/x86/intel_txt.rst for a description of how to enable
+         See Documentation/arch/x86/intel_txt.rst for a description of how to enable
          Intel TXT support in a kernel boot.
 
          If you are unsure as to whether this is required, answer N.
@@ -246,15 +241,17 @@ endchoice
 
 config LSM
        string "Ordered list of enabled LSMs"
-       default "landlock,lockdown,yama,loadpin,safesetid,integrity,smack,selinux,tomoyo,apparmor,bpf" if DEFAULT_SECURITY_SMACK
-       default "landlock,lockdown,yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo,bpf" if DEFAULT_SECURITY_APPARMOR
-       default "landlock,lockdown,yama,loadpin,safesetid,integrity,tomoyo,bpf" if DEFAULT_SECURITY_TOMOYO
-       default "landlock,lockdown,yama,loadpin,safesetid,integrity,bpf" if DEFAULT_SECURITY_DAC
-       default "landlock,lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor,bpf"
+       default "landlock,lockdown,yama,loadpin,safesetid,smack,selinux,tomoyo,apparmor,bpf" if DEFAULT_SECURITY_SMACK
+       default "landlock,lockdown,yama,loadpin,safesetid,apparmor,selinux,smack,tomoyo,bpf" if DEFAULT_SECURITY_APPARMOR
+       default "landlock,lockdown,yama,loadpin,safesetid,tomoyo,bpf" if DEFAULT_SECURITY_TOMOYO
+       default "landlock,lockdown,yama,loadpin,safesetid,bpf" if DEFAULT_SECURITY_DAC
+       default "landlock,lockdown,yama,loadpin,safesetid,selinux,smack,tomoyo,apparmor,bpf"
        help
          A comma-separated list of LSMs, in initialization order.
-         Any LSMs left off this list will be ignored. This can be
-         controlled at boot with the "lsm=" parameter.
+         Any LSMs left off this list, except for those with order
+         LSM_ORDER_FIRST and LSM_ORDER_LAST, which are always enabled
+         if selected in the kernel configuration, will be ignored.
+         This can be controlled at boot with the "lsm=" parameter.
 
          If unsure, leave this as the default.
 
index d6cc4812ca5372749f8be66d00d2614ea2268a2f..cebba4824e60e5b6532664dafab2c33d53ada007 100644 (file)
@@ -1209,13 +1209,13 @@ static int apparmor_inet_conn_request(const struct sock *sk, struct sk_buff *skb
 /*
  * The cred blob is a pointer to, not an instance of, an aa_label.
  */
-struct lsm_blob_sizes apparmor_blob_sizes __lsm_ro_after_init = {
+struct lsm_blob_sizes apparmor_blob_sizes __ro_after_init = {
        .lbs_cred = sizeof(struct aa_label *),
        .lbs_file = sizeof(struct aa_file_ctx),
        .lbs_task = sizeof(struct aa_task_ctx),
 };
 
-static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
+static struct security_hook_list apparmor_hooks[] __ro_after_init = {
        LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),
        LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),
        LSM_HOOK_INIT(capget, apparmor_capget),
@@ -1427,7 +1427,7 @@ static const struct kernel_param_ops param_ops_aaintbool = {
        .get = param_get_aaintbool
 };
 /* Boot time disable flag */
-static int apparmor_enabled __lsm_ro_after_init = 1;
+static int apparmor_enabled __ro_after_init = 1;
 module_param_named(enabled, apparmor_enabled, aaintbool, 0444);
 
 static int __init apparmor_enabled_setup(char *str)
index e5971fa74fd748a7650e5eb5c37bd4bf738a0c45..cfaf1d0e6a5f5143af2cbf93c942db65e9c42fbf 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/lsm_hooks.h>
 #include <linux/bpf_lsm.h>
 
-static struct security_hook_list bpf_lsm_hooks[] __lsm_ro_after_init = {
+static struct security_hook_list bpf_lsm_hooks[] __ro_after_init = {
        #define LSM_HOOK(RET, DEFAULT, NAME, ...) \
        LSM_HOOK_INIT(NAME, bpf_lsm_##NAME),
        #include <linux/lsm_hook_defs.h>
@@ -22,7 +22,7 @@ static int __init bpf_lsm_init(void)
        return 0;
 }
 
-struct lsm_blob_sizes bpf_lsm_blob_sizes __lsm_ro_after_init = {
+struct lsm_blob_sizes bpf_lsm_blob_sizes __ro_after_init = {
        .lbs_inode = sizeof(struct bpf_storage_blob),
        .lbs_task = sizeof(struct bpf_storage_blob),
 };
index 5bb7d1e962772a3929baa2ef39dfa9dbf3b7475f..0b3fc2f3afe77866d3387f206fe6673a6e9ece14 100644 (file)
@@ -1440,7 +1440,7 @@ int cap_mmap_file(struct file *file, unsigned long reqprot,
 
 #ifdef CONFIG_SECURITY
 
-static struct security_hook_list capability_hooks[] __lsm_ro_after_init = {
+static struct security_hook_list capability_hooks[] __ro_after_init = {
        LSM_HOOK_INIT(capable, cap_capable),
        LSM_HOOK_INIT(settime, cap_settime),
        LSM_HOOK_INIT(ptrace_access_check, cap_ptrace_access_check),
index bef2b9285fb34f8d06d3d04f33c736959f4f771f..7507d14eacc7942f7f50c377dfcbeb9436e0ba0e 100644 (file)
@@ -216,7 +216,7 @@ static void devcgroup_offline(struct cgroup_subsys_state *css)
 }
 
 /*
- * called from kernel/cgroup.c with cgroup_lock() held.
+ * called from kernel/cgroup/cgroup.c with cgroup_lock() held.
  */
 static struct cgroup_subsys_state *
 devcgroup_css_alloc(struct cgroup_subsys_state *parent_css)
index 599429f99f99fdad01e4d5a8182d50ce33b2c2e0..ec6e0d789da1527fe4f7773b9e1963ff2082ab42 100644 (file)
@@ -68,13 +68,34 @@ config INTEGRITY_MACHINE_KEYRING
        depends on INTEGRITY_ASYMMETRIC_KEYS
        depends on SYSTEM_BLACKLIST_KEYRING
        depends on LOAD_UEFI_KEYS
-       depends on !IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
        help
         If set, provide a keyring to which Machine Owner Keys (MOK) may
         be added. This keyring shall contain just MOK keys.  Unlike keys
         in the platform keyring, keys contained in the .machine keyring will
         be trusted within the kernel.
 
+config INTEGRITY_CA_MACHINE_KEYRING
+       bool "Enforce Machine Keyring CA Restrictions"
+       depends on INTEGRITY_MACHINE_KEYRING
+       default n
+       help
+         The .machine keyring can be configured to enforce CA restriction
+         on any key added to it.  By default no restrictions are in place
+         and all Machine Owner Keys (MOK) are added to the machine keyring.
+         If enabled only CA keys are added to the machine keyring, all
+         other MOK keys load into the platform keyring.
+
+config INTEGRITY_CA_MACHINE_KEYRING_MAX
+       bool "Only CA keys without DigitialSignature usage set"
+       depends on INTEGRITY_CA_MACHINE_KEYRING
+       default n
+       help
+         When selected, only load CA keys are loaded into the machine
+         keyring that contain the CA bit set along with the keyCertSign
+         Usage field.  Keys containing the digitialSignature Usage field
+         will not be loaded. The remaining MOK keys are loaded into the
+         .platform keyring.
+
 config LOAD_UEFI_KEYS
        depends on INTEGRITY_PLATFORM_KEYRING
        depends on EFI
index f2193c531f4a461c3fd51f6df13ae7b8d30a6337..6f31ffe23c48886e2636a98efd2de530aa5d63f9 100644 (file)
@@ -132,7 +132,8 @@ int __init integrity_init_keyring(const unsigned int id)
                | KEY_USR_READ | KEY_USR_SEARCH;
 
        if (id == INTEGRITY_KEYRING_PLATFORM ||
-           id == INTEGRITY_KEYRING_MACHINE) {
+           (id == INTEGRITY_KEYRING_MACHINE &&
+           !IS_ENABLED(CONFIG_INTEGRITY_CA_MACHINE_KEYRING))) {
                restriction = NULL;
                goto out;
        }
@@ -144,7 +145,10 @@ int __init integrity_init_keyring(const unsigned int id)
        if (!restriction)
                return -ENOMEM;
 
-       restriction->check = restrict_link_to_ima;
+       if (id == INTEGRITY_KEYRING_MACHINE)
+               restriction->check = restrict_link_by_ca;
+       else
+               restriction->check = restrict_link_to_ima;
 
        /*
         * MOK keys can only be added through a read-only runtime services
index 8638976f7990b76b44cc30beb74d3ec6ad62325f..c73858e8c6d5137e2e811b2431dd46b1d36b4998 100644 (file)
@@ -98,14 +98,6 @@ struct integrity_iint_cache *integrity_inode_get(struct inode *inode)
        struct rb_node *node, *parent = NULL;
        struct integrity_iint_cache *iint, *test_iint;
 
-       /*
-        * The integrity's "iint_cache" is initialized at security_init(),
-        * unless it is not included in the ordered list of LSMs enabled
-        * on the boot command line.
-        */
-       if (!iint_cache)
-               panic("%s: lsm=integrity required.\n", __func__);
-
        iint = integrity_iint_find(inode);
        if (iint)
                return iint;
@@ -182,6 +174,7 @@ static int __init integrity_iintcache_init(void)
 DEFINE_LSM(integrity) = {
        .name = "integrity",
        .init = integrity_iintcache_init,
+       .order = LSM_ORDER_LAST,
 };
 
 
index 2da4404276f0f5a68b0619dd6aa1d06a0fdb7198..07a0ef2baacd856324df852b38bfd087fb4dabbd 100644 (file)
@@ -38,9 +38,12 @@ static void cache_requested_key(struct key *key)
 #ifdef CONFIG_KEYS_REQUEST_CACHE
        struct task_struct *t = current;
 
-       key_put(t->cached_requested_key);
-       t->cached_requested_key = key_get(key);
-       set_tsk_thread_flag(t, TIF_NOTIFY_RESUME);
+       /* Do not cache key if it is a kernel thread */
+       if (!(t->flags & PF_KTHREAD)) {
+               key_put(t->cached_requested_key);
+               t->cached_requested_key = key_get(key);
+               set_tsk_thread_flag(t, TIF_NOTIFY_RESUME);
+       }
 #endif
 }
 
index ec6c37f04a1919b82c7dc7590d3615697568df4c..13dff2a3154513fa719a33233716b542306dc0de 100644 (file)
@@ -34,7 +34,7 @@ static void hook_cred_free(struct cred *const cred)
                landlock_put_ruleset_deferred(dom);
 }
 
-static struct security_hook_list landlock_hooks[] __lsm_ro_after_init = {
+static struct security_hook_list landlock_hooks[] __ro_after_init = {
        LSM_HOOK_INIT(cred_prepare, hook_cred_prepare),
        LSM_HOOK_INIT(cred_free, hook_cred_free),
 };
index adcea0fe7e68e411633323cf536c1dfe69c59dce..1c0c198f6fdb851815cd04acb9191ff86a6dabd1 100644 (file)
@@ -1280,7 +1280,7 @@ static int hook_file_truncate(struct file *const file)
        return -EACCES;
 }
 
-static struct security_hook_list landlock_hooks[] __lsm_ro_after_init = {
+static struct security_hook_list landlock_hooks[] __ro_after_init = {
        LSM_HOOK_INIT(inode_free_security, hook_inode_free_security),
 
        LSM_HOOK_INIT(sb_delete, hook_sb_delete),
index 4c5b9cd71286125944d8658f36f2802a0e338b6a..8a06d6c492bf3e8237174bd93353682638ff1c21 100644 (file)
@@ -108,7 +108,7 @@ static int hook_ptrace_traceme(struct task_struct *const parent)
        return task_ptrace(parent, current);
 }
 
-static struct security_hook_list landlock_hooks[] __lsm_ro_after_init = {
+static struct security_hook_list landlock_hooks[] __ro_after_init = {
        LSM_HOOK_INIT(ptrace_access_check, hook_ptrace_access_check),
        LSM_HOOK_INIT(ptrace_traceme, hook_ptrace_traceme),
 };
index 3f196d2ce4f988c3bef1ff1cbea1b850594d5c0b..0f6113528fa4a869ae79552446f11f47439773e1 100644 (file)
@@ -15,9 +15,9 @@
 #include "ptrace.h"
 #include "setup.h"
 
-bool landlock_initialized __lsm_ro_after_init = false;
+bool landlock_initialized __ro_after_init = false;
 
-struct lsm_blob_sizes landlock_blob_sizes __lsm_ro_after_init = {
+struct lsm_blob_sizes landlock_blob_sizes __ro_after_init = {
        .lbs_cred = sizeof(struct landlock_cred_security),
        .lbs_file = sizeof(struct landlock_file_security),
        .lbs_inode = sizeof(struct landlock_inode_security),
index d73a281adf865e00999c9fbe5b7375599bb89f45..b9d773f11232db417298cbdf859331568d64b32f 100644 (file)
@@ -214,7 +214,7 @@ static int loadpin_load_data(enum kernel_load_data_id id, bool contents)
        return loadpin_check(NULL, (enum kernel_read_file_id) id);
 }
 
-static struct security_hook_list loadpin_hooks[] __lsm_ro_after_init = {
+static struct security_hook_list loadpin_hooks[] __ro_after_init = {
        LSM_HOOK_INIT(sb_free_security, loadpin_sb_free_security),
        LSM_HOOK_INIT(kernel_read_file, loadpin_read_file),
        LSM_HOOK_INIT(kernel_load_data, loadpin_load_data),
index a79b985e917ee642f1b9a7a8350b8a9fc26ff6c8..68d19632aeb7251d0ae40859b169c68693963a74 100644 (file)
@@ -71,7 +71,7 @@ static int lockdown_is_locked_down(enum lockdown_reason what)
        return 0;
 }
 
-static struct security_hook_list lockdown_hooks[] __lsm_ro_after_init = {
+static struct security_hook_list lockdown_hooks[] __ro_after_init = {
        LSM_HOOK_INIT(locked_down, lockdown_is_locked_down),
 };
 
index cf6cc576736f3dbb1d3ad21cf3def26801ec52d4..d5ff7ff45b776d6a352e2fd1fa7e2c79d1602e56 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com>
  * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com>
  * Copyright (C) 2016 Mellanox Technologies
+ * Copyright (C) 2023 Microsoft Corporation <paul@paul-moore.com>
  */
 
 #define pr_fmt(fmt) "LSM: " fmt
@@ -41,7 +42,7 @@
  * all security modules to use the same descriptions for auditing
  * purposes.
  */
-const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = {
+const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX + 1] = {
        [LOCKDOWN_NONE] = "none",
        [LOCKDOWN_MODULE_SIGNATURE] = "unsigned module loading",
        [LOCKDOWN_DEV_MEM] = "/dev/mem,kmem,port",
@@ -74,20 +75,20 @@ const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = {
        [LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality",
 };
 
-struct security_hook_heads security_hook_heads __lsm_ro_after_init;
+struct security_hook_heads security_hook_heads __ro_after_init;
 static BLOCKING_NOTIFIER_HEAD(blocking_lsm_notifier_chain);
 
 static struct kmem_cache *lsm_file_cache;
 static struct kmem_cache *lsm_inode_cache;
 
 char *lsm_names;
-static struct lsm_blob_sizes blob_sizes __lsm_ro_after_init;
+static struct lsm_blob_sizes blob_sizes __ro_after_init;
 
 /* Boot-time LSM user choice */
 static __initdata const char *chosen_lsm_order;
 static __initdata const char *chosen_major_lsm;
 
-static __initconst const char * const builtin_lsm_order = CONFIG_LSM;
+static __initconst const char *const builtin_lsm_order = CONFIG_LSM;
 
 /* Ordered list of LSMs to initialize. */
 static __initdata struct lsm_info **ordered_lsms;
@@ -284,9 +285,9 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
                bool found = false;
 
                for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
-                       if (lsm->order == LSM_ORDER_MUTABLE &&
-                           strcmp(lsm->name, name) == 0) {
-                               append_ordered_lsm(lsm, origin);
+                       if (strcmp(lsm->name, name) == 0) {
+                               if (lsm->order == LSM_ORDER_MUTABLE)
+                                       append_ordered_lsm(lsm, origin);
                                found = true;
                        }
                }
@@ -306,6 +307,12 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
                }
        }
 
+       /* LSM_ORDER_LAST is always last. */
+       for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
+               if (lsm->order == LSM_ORDER_LAST)
+                       append_ordered_lsm(lsm, "   last");
+       }
+
        /* Disable all LSMs not in the ordered list. */
        for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
                if (exists_ordered_lsm(lsm))
@@ -331,7 +338,8 @@ static void __init report_lsm_order(void)
        pr_info("initializing lsm=");
 
        /* Report each enabled LSM name, comma separated. */
-       for (early = __start_early_lsm_info; early < __end_early_lsm_info; early++)
+       for (early = __start_early_lsm_info;
+            early < __end_early_lsm_info; early++)
                if (is_enabled(early))
                        pr_cont("%s%s", first++ == 0 ? "" : ",", early->name);
        for (lsm = ordered_lsms; *lsm; lsm++)
@@ -346,7 +354,7 @@ static void __init ordered_lsm_init(void)
        struct lsm_info **lsm;
 
        ordered_lsms = kcalloc(LSM_COUNT + 1, sizeof(*ordered_lsms),
-                               GFP_KERNEL);
+                              GFP_KERNEL);
 
        if (chosen_lsm_order) {
                if (chosen_major_lsm) {
@@ -419,9 +427,9 @@ int __init security_init(void)
 {
        struct lsm_info *lsm;
 
-       init_debug("legacy security=%s\n", chosen_major_lsm ?: " *unspecified*");
+       init_debug("legacy security=%s\n", chosen_major_lsm ? : " *unspecified*");
        init_debug("  CONFIG_LSM=%s\n", builtin_lsm_order);
-       init_debug("boot arg lsm=%s\n", chosen_lsm_order ?: " *unspecified*");
+       init_debug("boot arg lsm=%s\n", chosen_lsm_order ? : " *unspecified*");
 
        /*
         * Append the names of the early LSM modules now that kmalloc() is
@@ -509,7 +517,7 @@ static int lsm_append(const char *new, char **result)
  * Each LSM has to register its hooks with the infrastructure.
  */
 void __init security_add_hooks(struct security_hook_list *hooks, int count,
-                               const char *lsm)
+                              const char *lsm)
 {
        int i;
 
@@ -778,57 +786,157 @@ static int lsm_superblock_alloc(struct super_block *sb)
 
 /* Security operations */
 
+/**
+ * security_binder_set_context_mgr() - Check if becoming binder ctx mgr is ok
+ * @mgr: task credentials of current binder process
+ *
+ * Check whether @mgr is allowed to be the binder context manager.
+ *
+ * Return: Return 0 if permission is granted.
+ */
 int security_binder_set_context_mgr(const struct cred *mgr)
 {
        return call_int_hook(binder_set_context_mgr, 0, mgr);
 }
 
+/**
+ * security_binder_transaction() - Check if a binder transaction is allowed
+ * @from: sending process
+ * @to: receiving process
+ *
+ * Check whether @from is allowed to invoke a binder transaction call to @to.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_binder_transaction(const struct cred *from,
                                const struct cred *to)
 {
        return call_int_hook(binder_transaction, 0, from, to);
 }
 
+/**
+ * security_binder_transfer_binder() - Check if a binder transfer is allowed
+ * @from: sending process
+ * @to: receiving process
+ *
+ * Check whether @from is allowed to transfer a binder reference to @to.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_binder_transfer_binder(const struct cred *from,
                                    const struct cred *to)
 {
        return call_int_hook(binder_transfer_binder, 0, from, to);
 }
 
+/**
+ * security_binder_transfer_file() - Check if a binder file xfer is allowed
+ * @from: sending process
+ * @to: receiving process
+ * @file: file being transferred
+ *
+ * Check whether @from is allowed to transfer @file to @to.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_binder_transfer_file(const struct cred *from,
                                  const struct cred *to, struct file *file)
 {
        return call_int_hook(binder_transfer_file, 0, from, to, file);
 }
 
+/**
+ * security_ptrace_access_check() - Check if tracing is allowed
+ * @child: target process
+ * @mode: PTRACE_MODE flags
+ *
+ * Check permission before allowing the current process to trace the @child
+ * process.  Security modules may also want to perform a process tracing check
+ * during an execve in the set_security or apply_creds hooks of tracing check
+ * during an execve in the bprm_set_creds hook of binprm_security_ops if the
+ * process is being traced and its security attributes would be changed by the
+ * execve.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_ptrace_access_check(struct task_struct *child, unsigned int mode)
 {
        return call_int_hook(ptrace_access_check, 0, child, mode);
 }
 
+/**
+ * security_ptrace_traceme() - Check if tracing is allowed
+ * @parent: tracing process
+ *
+ * Check that the @parent process has sufficient permission to trace the
+ * current process before allowing the current process to present itself to the
+ * @parent process for tracing.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_ptrace_traceme(struct task_struct *parent)
 {
        return call_int_hook(ptrace_traceme, 0, parent);
 }
 
+/**
+ * security_capget() - Get the capability sets for a process
+ * @target: target process
+ * @effective: effective capability set
+ * @inheritable: inheritable capability set
+ * @permitted: permitted capability set
+ *
+ * Get the @effective, @inheritable, and @permitted capability sets for the
+ * @target process.  The hook may also perform permission checking to determine
+ * if the current process is allowed to see the capability sets of the @target
+ * process.
+ *
+ * Return: Returns 0 if the capability sets were successfully obtained.
+ */
 int security_capget(struct task_struct *target,
-                    kernel_cap_t *effective,
-                    kernel_cap_t *inheritable,
-                    kernel_cap_t *permitted)
+                   kernel_cap_t *effective,
+                   kernel_cap_t *inheritable,
+                   kernel_cap_t *permitted)
 {
        return call_int_hook(capget, 0, target,
-                               effective, inheritable, permitted);
+                            effective, inheritable, permitted);
 }
 
+/**
+ * security_capset() - Set the capability sets for a process
+ * @new: new credentials for the target process
+ * @old: current credentials of the target process
+ * @effective: effective capability set
+ * @inheritable: inheritable capability set
+ * @permitted: permitted capability set
+ *
+ * Set the @effective, @inheritable, and @permitted capability sets for the
+ * current process.
+ *
+ * Return: Returns 0 and update @new if permission is granted.
+ */
 int security_capset(struct cred *new, const struct cred *old,
                    const kernel_cap_t *effective,
                    const kernel_cap_t *inheritable,
                    const kernel_cap_t *permitted)
 {
        return call_int_hook(capset, 0, new, old,
-                               effective, inheritable, permitted);
+                            effective, inheritable, permitted);
 }
 
+/**
+ * security_capable() - Check if a process has the necessary capability
+ * @cred: credentials to examine
+ * @ns: user namespace
+ * @cap: capability requested
+ * @opts: capability check options
+ *
+ * Check whether the @tsk process has the @cap capability in the indicated
+ * credentials.  @cap contains the capability <include/linux/capability.h>.
+ * @opts contains options for the capable check <include/linux/security.h>.
+ *
+ * Return: Returns 0 if the capability is granted.
+ */
 int security_capable(const struct cred *cred,
                     struct user_namespace *ns,
                     int cap,
@@ -837,26 +945,78 @@ int security_capable(const struct cred *cred,
        return call_int_hook(capable, 0, cred, ns, cap, opts);
 }
 
+/**
+ * security_quotactl() - Check if a quotactl() syscall is allowed for this fs
+ * @cmds: commands
+ * @type: type
+ * @id: id
+ * @sb: filesystem
+ *
+ * Check whether the quotactl syscall is allowed for this @sb.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_quotactl(int cmds, int type, int id, struct super_block *sb)
 {
        return call_int_hook(quotactl, 0, cmds, type, id, sb);
 }
 
+/**
+ * security_quota_on() - Check if QUOTAON is allowed for a dentry
+ * @dentry: dentry
+ *
+ * Check whether QUOTAON is allowed for @dentry.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_quota_on(struct dentry *dentry)
 {
        return call_int_hook(quota_on, 0, dentry);
 }
 
+/**
+ * security_syslog() - Check if accessing the kernel message ring is allowed
+ * @type: SYSLOG_ACTION_* type
+ *
+ * Check permission before accessing the kernel message ring or changing
+ * logging to the console.  See the syslog(2) manual page for an explanation of
+ * the @type values.
+ *
+ * Return: Return 0 if permission is granted.
+ */
 int security_syslog(int type)
 {
        return call_int_hook(syslog, 0, type);
 }
 
+/**
+ * security_settime64() - Check if changing the system time is allowed
+ * @ts: new time
+ * @tz: timezone
+ *
+ * Check permission to change the system time, struct timespec64 is defined in
+ * <include/linux/time64.h> and timezone is defined in <include/linux/time.h>.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_settime64(const struct timespec64 *ts, const struct timezone *tz)
 {
        return call_int_hook(settime, 0, ts, tz);
 }
 
+/**
+ * security_vm_enough_memory_mm() - Check if allocating a new mem map is allowed
+ * @mm: mm struct
+ * @pages: number of pages
+ *
+ * Check permissions for allocating a new virtual mapping.  If all LSMs return
+ * a positive value, __vm_enough_memory() will be called with cap_sys_admin
+ * set. If at least one LSM returns 0 or negative, __vm_enough_memory() will be
+ * called with cap_sys_admin cleared.
+ *
+ * Return: Returns 0 if permission is granted by the LSM infrastructure to the
+ *         caller.
+ */
 int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
 {
        struct security_hook_list *hp;
@@ -880,16 +1040,61 @@ int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
        return __vm_enough_memory(mm, pages, cap_sys_admin);
 }
 
+/**
+ * security_bprm_creds_for_exec() - Prepare the credentials for exec()
+ * @bprm: binary program information
+ *
+ * If the setup in prepare_exec_creds did not setup @bprm->cred->security
+ * properly for executing @bprm->file, update the LSM's portion of
+ * @bprm->cred->security to be what commit_creds needs to install for the new
+ * program.  This hook may also optionally check permissions (e.g. for
+ * transitions between security domains).  The hook must set @bprm->secureexec
+ * to 1 if AT_SECURE should be set to request libc enable secure mode.  @bprm
+ * contains the linux_binprm structure.
+ *
+ * Return: Returns 0 if the hook is successful and permission is granted.
+ */
 int security_bprm_creds_for_exec(struct linux_binprm *bprm)
 {
        return call_int_hook(bprm_creds_for_exec, 0, bprm);
 }
 
+/**
+ * security_bprm_creds_from_file() - Update linux_binprm creds based on file
+ * @bprm: binary program information
+ * @file: associated file
+ *
+ * If @file is setpcap, suid, sgid or otherwise marked to change privilege upon
+ * exec, update @bprm->cred to reflect that change. This is called after
+ * finding the binary that will be executed without an interpreter.  This
+ * ensures that the credentials will not be derived from a script that the
+ * binary will need to reopen, which when reopend may end up being a completely
+ * different file.  This hook may also optionally check permissions (e.g. for
+ * transitions between security domains).  The hook must set @bprm->secureexec
+ * to 1 if AT_SECURE should be set to request libc enable secure mode.  The
+ * hook must add to @bprm->per_clear any personality flags that should be
+ * cleared from current->personality.  @bprm contains the linux_binprm
+ * structure.
+ *
+ * Return: Returns 0 if the hook is successful and permission is granted.
+ */
 int security_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file)
 {
        return call_int_hook(bprm_creds_from_file, 0, bprm, file);
 }
 
+/**
+ * security_bprm_check() - Mediate binary handler search
+ * @bprm: binary program information
+ *
+ * This hook mediates the point when a search for a binary handler will begin.
+ * It allows a check against the @bprm->cred->security value which was set in
+ * the preceding creds_for_exec call.  The argv list and envp list are reliably
+ * available in @bprm.  This hook may be called multiple times during a single
+ * execve.  @bprm contains the linux_binprm structure.
+ *
+ * Return: Returns 0 if the hook is successful and permission is granted.
+ */
 int security_bprm_check(struct linux_binprm *bprm)
 {
        int ret;
@@ -900,21 +1105,67 @@ int security_bprm_check(struct linux_binprm *bprm)
        return ima_bprm_check(bprm);
 }
 
+/**
+ * security_bprm_committing_creds() - Install creds for a process during exec()
+ * @bprm: binary program information
+ *
+ * Prepare to install the new security attributes of a process being
+ * transformed by an execve operation, based on the old credentials pointed to
+ * by @current->cred and the information set in @bprm->cred by the
+ * bprm_creds_for_exec hook.  @bprm points to the linux_binprm structure.  This
+ * hook is a good place to perform state changes on the process such as closing
+ * open file descriptors to which access will no longer be granted when the
+ * attributes are changed.  This is called immediately before commit_creds().
+ */
 void security_bprm_committing_creds(struct linux_binprm *bprm)
 {
        call_void_hook(bprm_committing_creds, bprm);
 }
 
+/**
+ * security_bprm_committed_creds() - Tidy up after cred install during exec()
+ * @bprm: binary program information
+ *
+ * Tidy up after the installation of the new security attributes of a process
+ * being transformed by an execve operation.  The new credentials have, by this
+ * point, been set to @current->cred.  @bprm points to the linux_binprm
+ * structure.  This hook is a good place to perform state changes on the
+ * process such as clearing out non-inheritable signal state.  This is called
+ * immediately after commit_creds().
+ */
 void security_bprm_committed_creds(struct linux_binprm *bprm)
 {
        call_void_hook(bprm_committed_creds, bprm);
 }
 
+/**
+ * security_fs_context_dup() - Duplicate a fs_context LSM blob
+ * @fc: destination filesystem context
+ * @src_fc: source filesystem context
+ *
+ * Allocate and attach a security structure to sc->security.  This pointer is
+ * initialised to NULL by the caller.  @fc indicates the new filesystem context.
+ * @src_fc indicates the original filesystem context.
+ *
+ * Return: Returns 0 on success or a negative error code on failure.
+ */
 int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc)
 {
        return call_int_hook(fs_context_dup, 0, fc, src_fc);
 }
 
+/**
+ * security_fs_context_parse_param() - Configure a filesystem context
+ * @fc: filesystem context
+ * @param: filesystem parameter
+ *
+ * Userspace provided a parameter to configure a superblock.  The LSM can
+ * consume the parameter or return it to the caller for use elsewhere.
+ *
+ * Return: If the parameter is used by the LSM it should return 0, if it is
+ *         returned to the caller -ENOPARAM is returned, otherwise a negative
+ *         error code is returned.
+ */
 int security_fs_context_parse_param(struct fs_context *fc,
                                    struct fs_parameter *param)
 {
@@ -933,6 +1184,16 @@ int security_fs_context_parse_param(struct fs_context *fc,
        return rc;
 }
 
+/**
+ * security_sb_alloc() - Allocate a super_block LSM blob
+ * @sb: filesystem superblock
+ *
+ * Allocate and attach a security structure to the sb->s_security field.  The
+ * s_security field is initialized to NULL when the structure is allocated.
+ * @sb contains the super_block structure to be modified.
+ *
+ * Return: Returns 0 if operation was successful.
+ */
 int security_sb_alloc(struct super_block *sb)
 {
        int rc = lsm_superblock_alloc(sb);
@@ -945,11 +1206,25 @@ int security_sb_alloc(struct super_block *sb)
        return rc;
 }
 
+/**
+ * security_sb_delete() - Release super_block LSM associated objects
+ * @sb: filesystem superblock
+ *
+ * Release objects tied to a superblock (e.g. inodes).  @sb contains the
+ * super_block structure being released.
+ */
 void security_sb_delete(struct super_block *sb)
 {
        call_void_hook(sb_delete, sb);
 }
 
+/**
+ * security_sb_free() - Free a super_block LSM blob
+ * @sb: filesystem superblock
+ *
+ * Deallocate and clear the sb->s_security field.  @sb contains the super_block
+ * structure to be modified.
+ */
 void security_sb_free(struct super_block *sb)
 {
        call_void_hook(sb_free_security, sb);
@@ -957,6 +1232,12 @@ void security_sb_free(struct super_block *sb)
        sb->s_security = NULL;
 }
 
+/**
+ * security_free_mnt_opts() - Free memory associated with mount options
+ * @mnt_opts: LSM processed mount options
+ *
+ * Free memory associated with @mnt_ops.
+ */
 void security_free_mnt_opts(void **mnt_opts)
 {
        if (!*mnt_opts)
@@ -966,12 +1247,31 @@ void security_free_mnt_opts(void **mnt_opts)
 }
 EXPORT_SYMBOL(security_free_mnt_opts);
 
+/**
+ * security_sb_eat_lsm_opts() - Consume LSM mount options
+ * @options: mount options
+ * @mnt_opts: LSM processed mount options
+ *
+ * Eat (scan @options) and save them in @mnt_opts.
+ *
+ * Return: Returns 0 on success, negative values on failure.
+ */
 int security_sb_eat_lsm_opts(char *options, void **mnt_opts)
 {
        return call_int_hook(sb_eat_lsm_opts, 0, options, mnt_opts);
 }
 EXPORT_SYMBOL(security_sb_eat_lsm_opts);
 
+/**
+ * security_sb_mnt_opts_compat() - Check if new mount options are allowed
+ * @sb: filesystem superblock
+ * @mnt_opts: new mount options
+ *
+ * Determine if the new mount options in @mnt_opts are allowed given the
+ * existing mounted filesystem at @sb.  @sb superblock being compared.
+ *
+ * Return: Returns 0 if options are compatible.
+ */
 int security_sb_mnt_opts_compat(struct super_block *sb,
                                void *mnt_opts)
 {
@@ -979,6 +1279,16 @@ int security_sb_mnt_opts_compat(struct super_block *sb,
 }
 EXPORT_SYMBOL(security_sb_mnt_opts_compat);
 
+/**
+ * security_sb_remount() - Verify no incompatible mount changes during remount
+ * @sb: filesystem superblock
+ * @mnt_opts: (re)mount options
+ *
+ * Extracts security system specific mount options and verifies no changes are
+ * being made to those options.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_sb_remount(struct super_block *sb,
                        void *mnt_opts)
 {
@@ -986,69 +1296,184 @@ int security_sb_remount(struct super_block *sb,
 }
 EXPORT_SYMBOL(security_sb_remount);
 
+/**
+ * security_sb_kern_mount() - Check if a kernel mount is allowed
+ * @sb: filesystem superblock
+ *
+ * Mount this @sb if allowed by permissions.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_sb_kern_mount(struct super_block *sb)
 {
        return call_int_hook(sb_kern_mount, 0, sb);
 }
 
+/**
+ * security_sb_show_options() - Output the mount options for a superblock
+ * @m: output file
+ * @sb: filesystem superblock
+ *
+ * Show (print on @m) mount options for this @sb.
+ *
+ * Return: Returns 0 on success, negative values on failure.
+ */
 int security_sb_show_options(struct seq_file *m, struct super_block *sb)
 {
        return call_int_hook(sb_show_options, 0, m, sb);
 }
 
+/**
+ * security_sb_statfs() - Check if accessing fs stats is allowed
+ * @dentry: superblock handle
+ *
+ * Check permission before obtaining filesystem statistics for the @mnt
+ * mountpoint.  @dentry is a handle on the superblock for the filesystem.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_sb_statfs(struct dentry *dentry)
 {
        return call_int_hook(sb_statfs, 0, dentry);
 }
 
+/**
+ * security_sb_mount() - Check permission for mounting a filesystem
+ * @dev_name: filesystem backing device
+ * @path: mount point
+ * @type: filesystem type
+ * @flags: mount flags
+ * @data: filesystem specific data
+ *
+ * Check permission before an object specified by @dev_name is mounted on the
+ * mount point named by @nd.  For an ordinary mount, @dev_name identifies a
+ * device if the file system type requires a device.  For a remount
+ * (@flags & MS_REMOUNT), @dev_name is irrelevant.  For a loopback/bind mount
+ * (@flags & MS_BIND), @dev_name identifies the        pathname of the object being
+ * mounted.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_sb_mount(const char *dev_name, const struct path *path,
-                       const char *type, unsigned long flags, void *data)
+                     const char *type, unsigned long flags, void *data)
 {
        return call_int_hook(sb_mount, 0, dev_name, path, type, flags, data);
 }
 
+/**
+ * security_sb_umount() - Check permission for unmounting a filesystem
+ * @mnt: mounted filesystem
+ * @flags: unmount flags
+ *
+ * Check permission before the @mnt file system is unmounted.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_sb_umount(struct vfsmount *mnt, int flags)
 {
        return call_int_hook(sb_umount, 0, mnt, flags);
 }
 
-int security_sb_pivotroot(const struct path *old_path, const struct path *new_path)
+/**
+ * security_sb_pivotroot() - Check permissions for pivoting the rootfs
+ * @old_path: new location for current rootfs
+ * @new_path: location of the new rootfs
+ *
+ * Check permission before pivoting the root filesystem.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
+int security_sb_pivotroot(const struct path *old_path,
+                         const struct path *new_path)
 {
        return call_int_hook(sb_pivotroot, 0, old_path, new_path);
 }
 
+/**
+ * security_sb_set_mnt_opts() - Set the mount options for a filesystem
+ * @sb: filesystem superblock
+ * @mnt_opts: binary mount options
+ * @kern_flags: kernel flags (in)
+ * @set_kern_flags: kernel flags (out)
+ *
+ * Set the security relevant mount options used for a superblock.
+ *
+ * Return: Returns 0 on success, error on failure.
+ */
 int security_sb_set_mnt_opts(struct super_block *sb,
-                               void *mnt_opts,
-                               unsigned long kern_flags,
-                               unsigned long *set_kern_flags)
+                            void *mnt_opts,
+                            unsigned long kern_flags,
+                            unsigned long *set_kern_flags)
 {
        return call_int_hook(sb_set_mnt_opts,
-                               mnt_opts ? -EOPNOTSUPP : 0, sb,
-                               mnt_opts, kern_flags, set_kern_flags);
+                            mnt_opts ? -EOPNOTSUPP : 0, sb,
+                            mnt_opts, kern_flags, set_kern_flags);
 }
 EXPORT_SYMBOL(security_sb_set_mnt_opts);
 
+/**
+ * security_sb_clone_mnt_opts() - Duplicate superblock mount options
+ * @oldsb: source superblock
+ * @newsb: destination superblock
+ * @kern_flags: kernel flags (in)
+ * @set_kern_flags: kernel flags (out)
+ *
+ * Copy all security options from a given superblock to another.
+ *
+ * Return: Returns 0 on success, error on failure.
+ */
 int security_sb_clone_mnt_opts(const struct super_block *oldsb,
-                               struct super_block *newsb,
-                               unsigned long kern_flags,
-                               unsigned long *set_kern_flags)
+                              struct super_block *newsb,
+                              unsigned long kern_flags,
+                              unsigned long *set_kern_flags)
 {
        return call_int_hook(sb_clone_mnt_opts, 0, oldsb, newsb,
-                               kern_flags, set_kern_flags);
+                            kern_flags, set_kern_flags);
 }
 EXPORT_SYMBOL(security_sb_clone_mnt_opts);
 
-int security_move_mount(const struct path *from_path, const struct path *to_path)
+/**
+ * security_move_mount() - Check permissions for moving a mount
+ * @from_path: source mount point
+ * @to_path: destination mount point
+ *
+ * Check permission before a mount is moved.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
+int security_move_mount(const struct path *from_path,
+                       const struct path *to_path)
 {
        return call_int_hook(move_mount, 0, from_path, to_path);
 }
 
+/**
+ * security_path_notify() - Check if setting a watch is allowed
+ * @path: file path
+ * @mask: event mask
+ * @obj_type: file path type
+ *
+ * Check permissions before setting a watch on events as defined by @mask, on
+ * an object at @path, whose type is defined by @obj_type.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_path_notify(const struct path *path, u64 mask,
-                               unsigned int obj_type)
+                        unsigned int obj_type)
 {
        return call_int_hook(path_notify, 0, path, mask, obj_type);
 }
 
+/**
+ * security_inode_alloc() - Allocate an inode LSM blob
+ * @inode: the inode
+ *
+ * Allocate and attach a security structure to @inode->i_security.  The
+ * i_security field is initialized to NULL when the inode structure is
+ * allocated.
+ *
+ * Return: Return 0 if operation was successful.
+ */
 int security_inode_alloc(struct inode *inode)
 {
        int rc = lsm_inode_alloc(inode);
@@ -1069,6 +1494,12 @@ static void inode_free_by_rcu(struct rcu_head *head)
        kmem_cache_free(lsm_inode_cache, head);
 }
 
+/**
+ * security_inode_free() - Free an inode's LSM blob
+ * @inode: the inode
+ *
+ * Deallocate the inode security structure and set @inode->i_security to NULL.
+ */
 void security_inode_free(struct inode *inode)
 {
        integrity_inode_free(inode);
@@ -1084,9 +1515,24 @@ void security_inode_free(struct inode *inode)
         */
        if (inode->i_security)
                call_rcu((struct rcu_head *)inode->i_security,
-                               inode_free_by_rcu);
+                        inode_free_by_rcu);
 }
 
+/**
+ * security_dentry_init_security() - Perform dentry initialization
+ * @dentry: the dentry to initialize
+ * @mode: mode used to determine resource type
+ * @name: name of the last path component
+ * @xattr_name: name of the security/LSM xattr
+ * @ctx: pointer to the resulting LSM context
+ * @ctxlen: length of @ctx
+ *
+ * Compute a context for a dentry as the inode is not yet available since NFSv4
+ * has no label backed by an EA anyway.  It is important to note that
+ * @xattr_name does not need to be free'd by the caller, it is a static string.
+ *
+ * Return: Returns 0 on success, negative values on failure.
+ */
 int security_dentry_init_security(struct dentry *dentry, int mode,
                                  const struct qstr *name,
                                  const char **xattr_name, void **ctx,
@@ -1098,7 +1544,8 @@ int security_dentry_init_security(struct dentry *dentry, int mode,
        /*
         * Only one module will provide a security context.
         */
-       hlist_for_each_entry(hp, &security_hook_heads.dentry_init_security, list) {
+       hlist_for_each_entry(hp, &security_hook_heads.dentry_init_security,
+                            list) {
                rc = hp->hook.dentry_init_security(dentry, mode, name,
                                                   xattr_name, ctx, ctxlen);
                if (rc != LSM_RET_DEFAULT(dentry_init_security))
@@ -1108,15 +1555,51 @@ int security_dentry_init_security(struct dentry *dentry, int mode,
 }
 EXPORT_SYMBOL(security_dentry_init_security);
 
+/**
+ * security_dentry_create_files_as() - Perform dentry initialization
+ * @dentry: the dentry to initialize
+ * @mode: mode used to determine resource type
+ * @name: name of the last path component
+ * @old: creds to use for LSM context calculations
+ * @new: creds to modify
+ *
+ * Compute a context for a dentry as the inode is not yet available and set
+ * that context in passed in creds so that new files are created using that
+ * context. Context is calculated using the passed in creds and not the creds
+ * of the caller.
+ *
+ * Return: Returns 0 on success, error on failure.
+ */
 int security_dentry_create_files_as(struct dentry *dentry, int mode,
                                    struct qstr *name,
                                    const struct cred *old, struct cred *new)
 {
        return call_int_hook(dentry_create_files_as, 0, dentry, mode,
-                               name, old, new);
+                            name, old, new);
 }
 EXPORT_SYMBOL(security_dentry_create_files_as);
 
+/**
+ * security_inode_init_security() - Initialize an inode's LSM context
+ * @inode: the inode
+ * @dir: parent directory
+ * @qstr: last component of the pathname
+ * @initxattrs: callback function to write xattrs
+ * @fs_data: filesystem specific data
+ *
+ * Obtain the security attribute name suffix and value to set on a newly
+ * created inode and set up the incore security field for the new inode.  This
+ * hook is called by the fs code as part of the inode creation transaction and
+ * provides for atomic labeling of the inode, unlike the post_create/mkdir/...
+ * hooks called by the VFS.  The hook function is expected to allocate the name
+ * and value via kmalloc, with the caller being responsible for calling kfree
+ * after using them.  If the security module does not use security attributes
+ * or does not wish to put a security attribute on this particular inode, then
+ * it should return -EOPNOTSUPP to skip this processing.
+ *
+ * Return: Returns 0 on success, -EOPNOTSUPP if no security attribute is
+ * needed, or -ENOMEM on memory allocation failure.
+ */
 int security_inode_init_security(struct inode *inode, struct inode *dir,
                                 const struct qstr *qstr,
                                 const initxattrs initxattrs, void *fs_data)
@@ -1134,9 +1617,9 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
        memset(new_xattrs, 0, sizeof(new_xattrs));
        lsm_xattr = new_xattrs;
        ret = call_int_hook(inode_init_security, -EOPNOTSUPP, inode, dir, qstr,
-                                               &lsm_xattr->name,
-                                               &lsm_xattr->value,
-                                               &lsm_xattr->value_len);
+                           &lsm_xattr->name,
+                           &lsm_xattr->value,
+                           &lsm_xattr->value_len);
        if (ret)
                goto out;
 
@@ -1152,6 +1635,18 @@ out:
 }
 EXPORT_SYMBOL(security_inode_init_security);
 
+/**
+ * security_inode_init_security_anon() - Initialize an anonymous inode
+ * @inode: the inode
+ * @name: the anonymous inode class
+ * @context_inode: an optional related inode
+ *
+ * Set up the incore security field for the new anonymous inode and return
+ * whether the inode creation is permitted by the security module or not.
+ *
+ * Return: Returns 0 on success, -EACCES if the security module denies the
+ * creation of this inode, or another -errno upon other errors.
+ */
 int security_inode_init_security_anon(struct inode *inode,
                                      const struct qstr *name,
                                      const struct inode *context_inode)
@@ -1160,20 +1655,21 @@ int security_inode_init_security_anon(struct inode *inode,
                             context_inode);
 }
 
-int security_old_inode_init_security(struct inode *inode, struct inode *dir,
-                                    const struct qstr *qstr, const char **name,
-                                    void **value, size_t *len)
-{
-       if (unlikely(IS_PRIVATE(inode)))
-               return -EOPNOTSUPP;
-       return call_int_hook(inode_init_security, -EOPNOTSUPP, inode, dir,
-                            qstr, name, value, len);
-}
-EXPORT_SYMBOL(security_old_inode_init_security);
-
 #ifdef CONFIG_SECURITY_PATH
-int security_path_mknod(const struct path *dir, struct dentry *dentry, umode_t mode,
-                       unsigned int dev)
+/**
+ * security_path_mknod() - Check if creating a special file is allowed
+ * @dir: parent directory
+ * @dentry: new file
+ * @mode: new file mode
+ * @dev: device number
+ *
+ * Check permissions when creating a file. Note that this hook is called even
+ * if mknod operation is being done for a regular file.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
+int security_path_mknod(const struct path *dir, struct dentry *dentry,
+                       umode_t mode, unsigned int dev)
 {
        if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry))))
                return 0;
@@ -1181,7 +1677,18 @@ int security_path_mknod(const struct path *dir, struct dentry *dentry, umode_t m
 }
 EXPORT_SYMBOL(security_path_mknod);
 
-int security_path_mkdir(const struct path *dir, struct dentry *dentry, umode_t mode)
+/**
+ * security_path_mkdir() - Check if creating a new directory is allowed
+ * @dir: parent directory
+ * @dentry: new directory
+ * @mode: new directory mode
+ *
+ * Check permissions to create a new directory in the existing directory.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
+int security_path_mkdir(const struct path *dir, struct dentry *dentry,
+                       umode_t mode)
 {
        if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry))))
                return 0;
@@ -1189,6 +1696,15 @@ int security_path_mkdir(const struct path *dir, struct dentry *dentry, umode_t m
 }
 EXPORT_SYMBOL(security_path_mkdir);
 
+/**
+ * security_path_rmdir() - Check if removing a directory is allowed
+ * @dir: parent directory
+ * @dentry: directory to remove
+ *
+ * Check the permission to remove a directory.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_path_rmdir(const struct path *dir, struct dentry *dentry)
 {
        if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry))))
@@ -1196,6 +1712,15 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry)
        return call_int_hook(path_rmdir, 0, dir, dentry);
 }
 
+/**
+ * security_path_unlink() - Check if removing a hard link is allowed
+ * @dir: parent directory
+ * @dentry: file
+ *
+ * Check the permission to remove a hard link to a file.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_path_unlink(const struct path *dir, struct dentry *dentry)
 {
        if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry))))
@@ -1204,6 +1729,16 @@ int security_path_unlink(const struct path *dir, struct dentry *dentry)
 }
 EXPORT_SYMBOL(security_path_unlink);
 
+/**
+ * security_path_symlink() - Check if creating a symbolic link is allowed
+ * @dir: parent directory
+ * @dentry: symbolic link
+ * @old_name: file pathname
+ *
+ * Check the permission to create a symbolic link to a file.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_path_symlink(const struct path *dir, struct dentry *dentry,
                          const char *old_name)
 {
@@ -1212,6 +1747,16 @@ int security_path_symlink(const struct path *dir, struct dentry *dentry,
        return call_int_hook(path_symlink, 0, dir, dentry, old_name);
 }
 
+/**
+ * security_path_link - Check if creating a hard link is allowed
+ * @old_dentry: existing file
+ * @new_dir: new parent directory
+ * @new_dentry: new link
+ *
+ * Check permission before creating a new hard link to a file.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
                       struct dentry *new_dentry)
 {
@@ -1220,19 +1765,42 @@ int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
        return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry);
 }
 
+/**
+ * security_path_rename() - Check if renaming a file is allowed
+ * @old_dir: parent directory of the old file
+ * @old_dentry: the old file
+ * @new_dir: parent directory of the new file
+ * @new_dentry: the new file
+ * @flags: flags
+ *
+ * Check for permission to rename a file or directory.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_path_rename(const struct path *old_dir, struct dentry *old_dentry,
                         const struct path *new_dir, struct dentry *new_dentry,
                         unsigned int flags)
 {
        if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)) ||
-                    (d_is_positive(new_dentry) && IS_PRIVATE(d_backing_inode(new_dentry)))))
+                    (d_is_positive(new_dentry) &&
+                     IS_PRIVATE(d_backing_inode(new_dentry)))))
                return 0;
 
        return call_int_hook(path_rename, 0, old_dir, old_dentry, new_dir,
-                               new_dentry, flags);
+                            new_dentry, flags);
 }
 EXPORT_SYMBOL(security_path_rename);
 
+/**
+ * security_path_truncate() - Check if truncating a file is allowed
+ * @path: file
+ *
+ * Check permission before truncating the file indicated by path.  Note that
+ * truncation permissions may also be checked based on already opened files,
+ * using the security_file_truncate() hook.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_path_truncate(const struct path *path)
 {
        if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry))))
@@ -1240,6 +1808,17 @@ int security_path_truncate(const struct path *path)
        return call_int_hook(path_truncate, 0, path);
 }
 
+/**
+ * security_path_chmod() - Check if changing the file's mode is allowed
+ * @path: file
+ * @mode: new mode
+ *
+ * Check for permission to change a mode of the file @path. The new mode is
+ * specified in @mode which is a bitmask of constants from
+ * <include/uapi/linux/stat.h>.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_path_chmod(const struct path *path, umode_t mode)
 {
        if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry))))
@@ -1247,6 +1826,16 @@ int security_path_chmod(const struct path *path, umode_t mode)
        return call_int_hook(path_chmod, 0, path, mode);
 }
 
+/**
+ * security_path_chown() - Check if changing the file's owner/group is allowed
+ * @path: file
+ * @uid: file owner
+ * @gid: file group
+ *
+ * Check for permission to change owner/group of a file or directory.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
 {
        if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry))))
@@ -1254,13 +1843,32 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
        return call_int_hook(path_chown, 0, path, uid, gid);
 }
 
+/**
+ * security_path_chroot() - Check if changing the root directory is allowed
+ * @path: directory
+ *
+ * Check for permission to change root directory.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_path_chroot(const struct path *path)
 {
        return call_int_hook(path_chroot, 0, path);
 }
-#endif
+#endif /* CONFIG_SECURITY_PATH */
 
-int security_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode)
+/**
+ * security_inode_create() - Check if creating a file is allowed
+ * @dir: the parent directory
+ * @dentry: the file being created
+ * @mode: requested file mode
+ *
+ * Check permission to create a regular file.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
+int security_inode_create(struct inode *dir, struct dentry *dentry,
+                         umode_t mode)
 {
        if (unlikely(IS_PRIVATE(dir)))
                return 0;
@@ -1268,14 +1876,33 @@ int security_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode
 }
 EXPORT_SYMBOL_GPL(security_inode_create);
 
+/**
+ * security_inode_link() - Check if creating a hard link is allowed
+ * @old_dentry: existing file
+ * @dir: new parent directory
+ * @new_dentry: new link
+ *
+ * Check permission before creating a new hard link to a file.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inode_link(struct dentry *old_dentry, struct inode *dir,
-                        struct dentry *new_dentry)
+                       struct dentry *new_dentry)
 {
        if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry))))
                return 0;
        return call_int_hook(inode_link, 0, old_dentry, dir, new_dentry);
 }
 
+/**
+ * security_inode_unlink() - Check if removing a hard link is allowed
+ * @dir: parent directory
+ * @dentry: file
+ *
+ * Check the permission to remove a hard link to a file.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inode_unlink(struct inode *dir, struct dentry *dentry)
 {
        if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
@@ -1283,14 +1910,35 @@ int security_inode_unlink(struct inode *dir, struct dentry *dentry)
        return call_int_hook(inode_unlink, 0, dir, dentry);
 }
 
+/**
+ * security_inode_symlink() - Check if creating a symbolic link is allowed
+ * @dir: parent directory
+ * @dentry: symbolic link
+ * @old_name: existing filename
+ *
+ * Check the permission to create a symbolic link to a file.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inode_symlink(struct inode *dir, struct dentry *dentry,
-                           const char *old_name)
+                          const char *old_name)
 {
        if (unlikely(IS_PRIVATE(dir)))
                return 0;
        return call_int_hook(inode_symlink, 0, dir, dentry, old_name);
 }
 
+/**
+ * security_inode_mkdir() - Check if creation a new director is allowed
+ * @dir: parent directory
+ * @dentry: new directory
+ * @mode: new directory mode
+ *
+ * Check permissions to create a new directory in the existing directory
+ * associated with inode structure @dir.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inode_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 {
        if (unlikely(IS_PRIVATE(dir)))
@@ -1299,6 +1947,15 @@ int security_inode_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 }
 EXPORT_SYMBOL_GPL(security_inode_mkdir);
 
+/**
+ * security_inode_rmdir() - Check if removing a directory is allowed
+ * @dir: parent directory
+ * @dentry: directory to be removed
+ *
+ * Check the permission to remove a directory.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inode_rmdir(struct inode *dir, struct dentry *dentry)
 {
        if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
@@ -1306,32 +1963,68 @@ int security_inode_rmdir(struct inode *dir, struct dentry *dentry)
        return call_int_hook(inode_rmdir, 0, dir, dentry);
 }
 
-int security_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
+/**
+ * security_inode_mknod() - Check if creating a special file is allowed
+ * @dir: parent directory
+ * @dentry: new file
+ * @mode: new file mode
+ * @dev: device number
+ *
+ * Check permissions when creating a special file (or a socket or a fifo file
+ * created via the mknod system call).  Note that if mknod operation is being
+ * done for a regular file, then the create hook will be called and not this
+ * hook.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
+int security_inode_mknod(struct inode *dir, struct dentry *dentry,
+                        umode_t mode, dev_t dev)
 {
        if (unlikely(IS_PRIVATE(dir)))
                return 0;
        return call_int_hook(inode_mknod, 0, dir, dentry, mode, dev);
 }
 
+/**
+ * security_inode_rename() - Check if renaming a file is allowed
+ * @old_dir: parent directory of the old file
+ * @old_dentry: the old file
+ * @new_dir: parent directory of the new file
+ * @new_dentry: the new file
+ * @flags: flags
+ *
+ * Check for permission to rename a file or directory.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
-                          struct inode *new_dir, struct dentry *new_dentry,
-                          unsigned int flags)
+                         struct inode *new_dir, struct dentry *new_dentry,
+                         unsigned int flags)
 {
-        if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)) ||
-            (d_is_positive(new_dentry) && IS_PRIVATE(d_backing_inode(new_dentry)))))
+       if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)) ||
+                    (d_is_positive(new_dentry) &&
+                     IS_PRIVATE(d_backing_inode(new_dentry)))))
                return 0;
 
        if (flags & RENAME_EXCHANGE) {
                int err = call_int_hook(inode_rename, 0, new_dir, new_dentry,
-                                                    old_dir, old_dentry);
+                                       old_dir, old_dentry);
                if (err)
                        return err;
        }
 
        return call_int_hook(inode_rename, 0, old_dir, old_dentry,
-                                          new_dir, new_dentry);
+                            new_dir, new_dentry);
 }
 
+/**
+ * security_inode_readlink() - Check if reading a symbolic link is allowed
+ * @dentry: link
+ *
+ * Check the permission to read the symbolic link.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inode_readlink(struct dentry *dentry)
 {
        if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
@@ -1339,6 +2032,17 @@ int security_inode_readlink(struct dentry *dentry)
        return call_int_hook(inode_readlink, 0, dentry);
 }
 
+/**
+ * security_inode_follow_link() - Check if following a symbolic link is allowed
+ * @dentry: link dentry
+ * @inode: link inode
+ * @rcu: true if in RCU-walk mode
+ *
+ * Check permission to follow a symbolic link when looking up a pathname.  If
+ * @rcu is true, @inode is not stable.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inode_follow_link(struct dentry *dentry, struct inode *inode,
                               bool rcu)
 {
@@ -1347,6 +2051,20 @@ int security_inode_follow_link(struct dentry *dentry, struct inode *inode,
        return call_int_hook(inode_follow_link, 0, dentry, inode, rcu);
 }
 
+/**
+ * security_inode_permission() - Check if accessing an inode is allowed
+ * @inode: inode
+ * @mask: access mask
+ *
+ * Check permission before accessing an inode.  This hook is called by the
+ * existing Linux permission function, so a security module can use it to
+ * provide additional checking for existing Linux permission checks.  Notice
+ * that this hook is called when a file is opened (as well as many other
+ * operations), whereas the file_security_ops permission hook is called when
+ * the actual read/write operations are performed.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inode_permission(struct inode *inode, int mask)
 {
        if (unlikely(IS_PRIVATE(inode)))
@@ -1354,6 +2072,19 @@ int security_inode_permission(struct inode *inode, int mask)
        return call_int_hook(inode_permission, 0, inode, mask);
 }
 
+/**
+ * security_inode_setattr() - Check if setting file attributes is allowed
+ * @idmap: idmap of the mount
+ * @dentry: file
+ * @attr: new attributes
+ *
+ * Check permission before setting file attributes.  Note that the kernel call
+ * to notify_change is performed from several locations, whenever file
+ * attributes change (such as when a file is truncated, chown/chmod operations,
+ * transferring disk quotas, etc).
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inode_setattr(struct mnt_idmap *idmap,
                           struct dentry *dentry, struct iattr *attr)
 {
@@ -1368,6 +2099,14 @@ int security_inode_setattr(struct mnt_idmap *idmap,
 }
 EXPORT_SYMBOL_GPL(security_inode_setattr);
 
+/**
+ * security_inode_getattr() - Check if getting file attributes is allowed
+ * @path: file
+ *
+ * Check permission before obtaining file attributes.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inode_getattr(const struct path *path)
 {
        if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry))))
@@ -1375,6 +2114,19 @@ int security_inode_getattr(const struct path *path)
        return call_int_hook(inode_getattr, 0, path);
 }
 
+/**
+ * security_inode_setxattr() - Check if setting file xattrs is allowed
+ * @idmap: idmap of the mount
+ * @dentry: file
+ * @name: xattr name
+ * @value: xattr value
+ * @size: size of xattr value
+ * @flags: flags
+ *
+ * Check permission before setting the extended attributes.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inode_setxattr(struct mnt_idmap *idmap,
                            struct dentry *dentry, const char *name,
                            const void *value, size_t size, int flags)
@@ -1400,6 +2152,18 @@ int security_inode_setxattr(struct mnt_idmap *idmap,
        return evm_inode_setxattr(idmap, dentry, name, value, size);
 }
 
+/**
+ * security_inode_set_acl() - Check if setting posix acls is allowed
+ * @idmap: idmap of the mount
+ * @dentry: file
+ * @acl_name: acl name
+ * @kacl: acl struct
+ *
+ * Check permission before setting posix acls, the posix acls in @kacl are
+ * identified by @acl_name.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inode_set_acl(struct mnt_idmap *idmap,
                           struct dentry *dentry, const char *acl_name,
                           struct posix_acl *kacl)
@@ -1418,6 +2182,17 @@ int security_inode_set_acl(struct mnt_idmap *idmap,
        return evm_inode_set_acl(idmap, dentry, acl_name, kacl);
 }
 
+/**
+ * security_inode_get_acl() - Check if reading posix acls is allowed
+ * @idmap: idmap of the mount
+ * @dentry: file
+ * @acl_name: acl name
+ *
+ * Check permission before getting osix acls, the posix acls are identified by
+ * @acl_name.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inode_get_acl(struct mnt_idmap *idmap,
                           struct dentry *dentry, const char *acl_name)
 {
@@ -1426,6 +2201,17 @@ int security_inode_get_acl(struct mnt_idmap *idmap,
        return call_int_hook(inode_get_acl, 0, idmap, dentry, acl_name);
 }
 
+/**
+ * security_inode_remove_acl() - Check if removing a posix acl is allowed
+ * @idmap: idmap of the mount
+ * @dentry: file
+ * @acl_name: acl name
+ *
+ * Check permission before removing posix acls, the posix acls are identified
+ * by @acl_name.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inode_remove_acl(struct mnt_idmap *idmap,
                              struct dentry *dentry, const char *acl_name)
 {
@@ -1442,6 +2228,16 @@ int security_inode_remove_acl(struct mnt_idmap *idmap,
        return evm_inode_remove_acl(idmap, dentry, acl_name);
 }
 
+/**
+ * security_inode_post_setxattr() - Update the inode after a setxattr operation
+ * @dentry: file
+ * @name: xattr name
+ * @value: xattr value
+ * @size: xattr value size
+ * @flags: flags
+ *
+ * Update inode security field after successful setxattr operation.
+ */
 void security_inode_post_setxattr(struct dentry *dentry, const char *name,
                                  const void *value, size_t size, int flags)
 {
@@ -1451,6 +2247,16 @@ void security_inode_post_setxattr(struct dentry *dentry, const char *name,
        evm_inode_post_setxattr(dentry, name, value, size);
 }
 
+/**
+ * security_inode_getxattr() - Check if xattr access is allowed
+ * @dentry: file
+ * @name: xattr name
+ *
+ * Check permission before obtaining the extended attributes identified by
+ * @name for @dentry.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inode_getxattr(struct dentry *dentry, const char *name)
 {
        if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
@@ -1458,6 +2264,15 @@ int security_inode_getxattr(struct dentry *dentry, const char *name)
        return call_int_hook(inode_getxattr, 0, dentry, name);
 }
 
+/**
+ * security_inode_listxattr() - Check if listing xattrs is allowed
+ * @dentry: file
+ *
+ * Check permission before obtaining the list of extended attribute names for
+ * @dentry.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inode_listxattr(struct dentry *dentry)
 {
        if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
@@ -1465,6 +2280,17 @@ int security_inode_listxattr(struct dentry *dentry)
        return call_int_hook(inode_listxattr, 0, dentry);
 }
 
+/**
+ * security_inode_removexattr() - Check if removing an xattr is allowed
+ * @idmap: idmap of the mount
+ * @dentry: file
+ * @name: xattr name
+ *
+ * Check permission before removing the extended attribute identified by @name
+ * for @dentry.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inode_removexattr(struct mnt_idmap *idmap,
                               struct dentry *dentry, const char *name)
 {
@@ -1487,17 +2313,55 @@ int security_inode_removexattr(struct mnt_idmap *idmap,
        return evm_inode_removexattr(idmap, dentry, name);
 }
 
+/**
+ * security_inode_need_killpriv() - Check if security_inode_killpriv() required
+ * @dentry: associated dentry
+ *
+ * Called when an inode has been changed to determine if
+ * security_inode_killpriv() should be called.
+ *
+ * Return: Return <0 on error to abort the inode change operation, return 0 if
+ *         security_inode_killpriv() does not need to be called, return >0 if
+ *         security_inode_killpriv() does need to be called.
+ */
 int security_inode_need_killpriv(struct dentry *dentry)
 {
        return call_int_hook(inode_need_killpriv, 0, dentry);
 }
 
+/**
+ * security_inode_killpriv() - The setuid bit is removed, update LSM state
+ * @idmap: idmap of the mount
+ * @dentry: associated dentry
+ *
+ * The @dentry's setuid bit is being removed.  Remove similar security labels.
+ * Called with the dentry->d_inode->i_mutex held.
+ *
+ * Return: Return 0 on success.  If error is returned, then the operation
+ *         causing setuid bit removal is failed.
+ */
 int security_inode_killpriv(struct mnt_idmap *idmap,
                            struct dentry *dentry)
 {
        return call_int_hook(inode_killpriv, 0, idmap, dentry);
 }
 
+/**
+ * security_inode_getsecurity() - Get the xattr security label of an inode
+ * @idmap: idmap of the mount
+ * @inode: inode
+ * @name: xattr name
+ * @buffer: security label buffer
+ * @alloc: allocation flag
+ *
+ * Retrieve a copy of the extended attribute representation of the security
+ * label associated with @name for @inode via @buffer.  Note that @name is the
+ * remainder of the attribute name after the security prefix has been removed.
+ * @alloc is used to specify if the call should return a value via the buffer
+ * or just the value length.
+ *
+ * Return: Returns size of buffer on success.
+ */
 int security_inode_getsecurity(struct mnt_idmap *idmap,
                               struct inode *inode, const char *name,
                               void **buffer, bool alloc)
@@ -1511,14 +2375,31 @@ int security_inode_getsecurity(struct mnt_idmap *idmap,
         * Only one module will provide an attribute with a given name.
         */
        hlist_for_each_entry(hp, &security_hook_heads.inode_getsecurity, list) {
-               rc = hp->hook.inode_getsecurity(idmap, inode, name, buffer, alloc);
+               rc = hp->hook.inode_getsecurity(idmap, inode, name, buffer,
+                                               alloc);
                if (rc != LSM_RET_DEFAULT(inode_getsecurity))
                        return rc;
        }
        return LSM_RET_DEFAULT(inode_getsecurity);
 }
 
-int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags)
+/**
+ * security_inode_setsecurity() - Set the xattr security label of an inode
+ * @inode: inode
+ * @name: xattr name
+ * @value: security label
+ * @size: length of security label
+ * @flags: flags
+ *
+ * Set the security label associated with @name for @inode from the extended
+ * attribute value @value.  @size indicates the size of the @value in bytes.
+ * @flags may be XATTR_CREATE, XATTR_REPLACE, or 0. Note that @name is the
+ * remainder of the attribute name after the security. prefix has been removed.
+ *
+ * Return: Returns 0 on success.
+ */
+int security_inode_setsecurity(struct inode *inode, const char *name,
+                              const void *value, size_t size, int flags)
 {
        struct security_hook_list *hp;
        int rc;
@@ -1530,14 +2411,28 @@ int security_inode_setsecurity(struct inode *inode, const char *name, const void
         */
        hlist_for_each_entry(hp, &security_hook_heads.inode_setsecurity, list) {
                rc = hp->hook.inode_setsecurity(inode, name, value, size,
-                                                               flags);
+                                               flags);
                if (rc != LSM_RET_DEFAULT(inode_setsecurity))
                        return rc;
        }
        return LSM_RET_DEFAULT(inode_setsecurity);
 }
 
-int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size)
+/**
+ * security_inode_listsecurity() - List the xattr security label names
+ * @inode: inode
+ * @buffer: buffer
+ * @buffer_size: size of buffer
+ *
+ * Copy the extended attribute names for the security labels associated with
+ * @inode into @buffer.  The maximum size of @buffer is specified by
+ * @buffer_size.  @buffer may be NULL to request the size of the buffer
+ * required.
+ *
+ * Return: Returns number of bytes used/required on success.
+ */
+int security_inode_listsecurity(struct inode *inode,
+                               char *buffer, size_t buffer_size)
 {
        if (unlikely(IS_PRIVATE(inode)))
                return 0;
@@ -1545,17 +2440,49 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer
 }
 EXPORT_SYMBOL(security_inode_listsecurity);
 
+/**
+ * security_inode_getsecid() - Get an inode's secid
+ * @inode: inode
+ * @secid: secid to return
+ *
+ * Get the secid associated with the node.  In case of failure, @secid will be
+ * set to zero.
+ */
 void security_inode_getsecid(struct inode *inode, u32 *secid)
 {
        call_void_hook(inode_getsecid, inode, secid);
 }
 
+/**
+ * security_inode_copy_up() - Create new creds for an overlayfs copy-up op
+ * @src: union dentry of copy-up file
+ * @new: newly created creds
+ *
+ * A file is about to be copied up from lower layer to upper layer of overlay
+ * filesystem. Security module can prepare a set of new creds and modify as
+ * need be and return new creds. Caller will switch to new creds temporarily to
+ * create new file and release newly allocated creds.
+ *
+ * Return: Returns 0 on success or a negative error code on error.
+ */
 int security_inode_copy_up(struct dentry *src, struct cred **new)
 {
        return call_int_hook(inode_copy_up, 0, src, new);
 }
 EXPORT_SYMBOL(security_inode_copy_up);
 
+/**
+ * security_inode_copy_up_xattr() - Filter xattrs in an overlayfs copy-up op
+ * @name: xattr name
+ *
+ * Filter the xattrs being copied up when a unioned file is copied up from a
+ * lower layer to the union/overlay layer.   The caller is responsible for
+ * reading and writing the xattrs, this hook is merely a filter.
+ *
+ * Return: Returns 0 to accept the xattr, 1 to discard the xattr, -EOPNOTSUPP
+ *         if the security module does not know about attribute, or a negative
+ *         error code to abort the copy up.
+ */
 int security_inode_copy_up_xattr(const char *name)
 {
        struct security_hook_list *hp;
@@ -1567,7 +2494,7 @@ int security_inode_copy_up_xattr(const char *name)
         * any other error code incase of an error.
         */
        hlist_for_each_entry(hp,
-               &security_hook_heads.inode_copy_up_xattr, list) {
+                            &security_hook_heads.inode_copy_up_xattr, list) {
                rc = hp->hook.inode_copy_up_xattr(name);
                if (rc != LSM_RET_DEFAULT(inode_copy_up_xattr))
                        return rc;
@@ -1577,12 +2504,41 @@ int security_inode_copy_up_xattr(const char *name)
 }
 EXPORT_SYMBOL(security_inode_copy_up_xattr);
 
+/**
+ * security_kernfs_init_security() - Init LSM context for a kernfs node
+ * @kn_dir: parent kernfs node
+ * @kn: the kernfs node to initialize
+ *
+ * Initialize the security context of a newly created kernfs node based on its
+ * own and its parent's attributes.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_kernfs_init_security(struct kernfs_node *kn_dir,
                                  struct kernfs_node *kn)
 {
        return call_int_hook(kernfs_init_security, 0, kn_dir, kn);
 }
 
+/**
+ * security_file_permission() - Check file permissions
+ * @file: file
+ * @mask: requested permissions
+ *
+ * Check file permissions before accessing an open file.  This hook is called
+ * by various operations that read or write files.  A security module can use
+ * this hook to perform additional checking on these operations, e.g. to
+ * revalidate permissions on use to support privilege bracketing or policy
+ * changes.  Notice that this hook is used when the actual read/write
+ * operations are performed, whereas the inode_security_ops hook is called when
+ * a file is opened (as well as many other operations).  Although this hook can
+ * be used to revalidate permissions for various system call operations that
+ * read or write files, it does not address the revalidation of permissions for
+ * memory-mapped files.  Security modules must handle this separately if they
+ * need such revalidation.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_file_permission(struct file *file, int mask)
 {
        int ret;
@@ -1594,6 +2550,15 @@ int security_file_permission(struct file *file, int mask)
        return fsnotify_perm(file, mask);
 }
 
+/**
+ * security_file_alloc() - Allocate and init a file's LSM blob
+ * @file: the file
+ *
+ * Allocate and attach a security structure to the file->f_security field.  The
+ * security field is initialized to NULL when the structure is first created.
+ *
+ * Return: Return 0 if the hook is successful and permission is granted.
+ */
 int security_file_alloc(struct file *file)
 {
        int rc = lsm_file_alloc(file);
@@ -1606,6 +2571,12 @@ int security_file_alloc(struct file *file)
        return rc;
 }
 
+/**
+ * security_file_free() - Free a file's LSM blob
+ * @file: the file
+ *
+ * Deallocate and free any security structures stored in file->f_security.
+ */
 void security_file_free(struct file *file)
 {
        void *blob;
@@ -1619,6 +2590,19 @@ void security_file_free(struct file *file)
        }
 }
 
+/**
+ * security_file_ioctl() - Check if an ioctl is allowed
+ * @file: associated file
+ * @cmd: ioctl cmd
+ * @arg: ioctl arguments
+ *
+ * Check permission for an ioctl operation on @file.  Note that @arg sometimes
+ * represents a user space pointer; in other cases, it may be a simple integer
+ * value.  When @arg represents a user space pointer, it should never be used
+ * by the security module.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        return call_int_hook(file_ioctl, 0, file, cmd, arg);
@@ -1658,8 +2642,19 @@ static inline unsigned long mmap_prot(struct file *file, unsigned long prot)
        return prot;
 }
 
+/**
+ * security_mmap_file() - Check if mmap'ing a file is allowed
+ * @file: file
+ * @prot: protection applied by the kernel
+ * @flags: flags
+ *
+ * Check permissions for a mmap operation.  The @file may be NULL, e.g. if
+ * mapping anonymous memory.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_mmap_file(struct file *file, unsigned long prot,
-                       unsigned long flags)
+                      unsigned long flags)
 {
        unsigned long prot_adj = mmap_prot(file, prot);
        int ret;
@@ -1670,13 +2665,31 @@ int security_mmap_file(struct file *file, unsigned long prot,
        return ima_file_mmap(file, prot, prot_adj, flags);
 }
 
+/**
+ * security_mmap_addr() - Check if mmap'ing an address is allowed
+ * @addr: address
+ *
+ * Check permissions for a mmap operation at @addr.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_mmap_addr(unsigned long addr)
 {
        return call_int_hook(mmap_addr, 0, addr);
 }
 
+/**
+ * security_file_mprotect() - Check if changing memory protections is allowed
+ * @vma: memory region
+ * @reqprot: application requested protection
+ * @prot: protection applied by the kernel
+ *
+ * Check permissions before changing memory access permissions.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
-                           unsigned long prot)
+                          unsigned long prot)
 {
        int ret;
 
@@ -1686,32 +2699,97 @@ int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
        return ima_file_mprotect(vma, prot);
 }
 
+/**
+ * security_file_lock() - Check if a file lock is allowed
+ * @file: file
+ * @cmd: lock operation (e.g. F_RDLCK, F_WRLCK)
+ *
+ * Check permission before performing file locking operations.  Note the hook
+ * mediates both flock and fcntl style locks.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_file_lock(struct file *file, unsigned int cmd)
 {
        return call_int_hook(file_lock, 0, file, cmd);
 }
 
+/**
+ * security_file_fcntl() - Check if fcntl() op is allowed
+ * @file: file
+ * @cmd: fnctl command
+ * @arg: command argument
+ *
+ * Check permission before allowing the file operation specified by @cmd from
+ * being performed on the file @file.  Note that @arg sometimes represents a
+ * user space pointer; in other cases, it may be a simple integer value.  When
+ * @arg represents a user space pointer, it should never be used by the
+ * security module.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        return call_int_hook(file_fcntl, 0, file, cmd, arg);
 }
 
+/**
+ * security_file_set_fowner() - Set the file owner info in the LSM blob
+ * @file: the file
+ *
+ * Save owner security information (typically from current->security) in
+ * file->f_security for later use by the send_sigiotask hook.
+ *
+ * Return: Returns 0 on success.
+ */
 void security_file_set_fowner(struct file *file)
 {
        call_void_hook(file_set_fowner, file);
 }
 
+/**
+ * security_file_send_sigiotask() - Check if sending SIGIO/SIGURG is allowed
+ * @tsk: target task
+ * @fown: signal sender
+ * @sig: signal to be sent, SIGIO is sent if 0
+ *
+ * Check permission for the file owner @fown to send SIGIO or SIGURG to the
+ * process @tsk.  Note that this hook is sometimes called from interrupt.  Note
+ * that the fown_struct, @fown, is never outside the context of a struct file,
+ * so the file structure (and associated security information) can always be
+ * obtained: container_of(fown, struct file, f_owner).
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_file_send_sigiotask(struct task_struct *tsk,
-                                 struct fown_struct *fown, int sig)
+                                struct fown_struct *fown, int sig)
 {
        return call_int_hook(file_send_sigiotask, 0, tsk, fown, sig);
 }
 
+/**
+ * security_file_receive() - Check is receiving a file via IPC is allowed
+ * @file: file being received
+ *
+ * This hook allows security modules to control the ability of a process to
+ * receive an open file descriptor via socket IPC.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_file_receive(struct file *file)
 {
        return call_int_hook(file_receive, 0, file);
 }
 
+/**
+ * security_file_open() - Save open() time state for late use by the LSM
+ * @file:
+ *
+ * Save open-time permission checking state for later use upon file_permission,
+ * and recheck access if anything has changed since inode_permission.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_file_open(struct file *file)
 {
        int ret;
@@ -1723,11 +2801,30 @@ int security_file_open(struct file *file)
        return fsnotify_perm(file, MAY_OPEN);
 }
 
+/**
+ * security_file_truncate() - Check if truncating a file is allowed
+ * @file: file
+ *
+ * Check permission before truncating a file, i.e. using ftruncate.  Note that
+ * truncation permission may also be checked based on the path, using the
+ * @path_truncate hook.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_file_truncate(struct file *file)
 {
        return call_int_hook(file_truncate, 0, file);
 }
 
+/**
+ * security_task_alloc() - Allocate a task's LSM blob
+ * @task: the task
+ * @clone_flags: flags indicating what is being shared
+ *
+ * Handle allocation of task-related resources.
+ *
+ * Return: Returns a zero on success, negative values on failure.
+ */
 int security_task_alloc(struct task_struct *task, unsigned long clone_flags)
 {
        int rc = lsm_task_alloc(task);
@@ -1740,6 +2837,13 @@ int security_task_alloc(struct task_struct *task, unsigned long clone_flags)
        return rc;
 }
 
+/**
+ * security_task_free() - Free a task's LSM blob and related resources
+ * @task: task
+ *
+ * Handle release of task-related resources.  Note that this can be called from
+ * interrupt context.
+ */
 void security_task_free(struct task_struct *task)
 {
        call_void_hook(task_free, task);
@@ -1748,6 +2852,16 @@ void security_task_free(struct task_struct *task)
        task->security = NULL;
 }
 
+/**
+ * security_cred_alloc_blank() - Allocate the min memory to allow cred_transfer
+ * @cred: credentials
+ * @gfp: gfp flags
+ *
+ * Only allocate sufficient memory and attach to @cred such that
+ * cred_transfer() will not get ENOMEM.
+ *
+ * Return: Returns 0 on success, negative values on failure.
+ */
 int security_cred_alloc_blank(struct cred *cred, gfp_t gfp)
 {
        int rc = lsm_cred_alloc(cred, gfp);
@@ -1761,6 +2875,12 @@ int security_cred_alloc_blank(struct cred *cred, gfp_t gfp)
        return rc;
 }
 
+/**
+ * security_cred_free() - Free the cred's LSM blob and associated resources
+ * @cred: credentials
+ *
+ * Deallocate and clear the cred->security field in a set of credentials.
+ */
 void security_cred_free(struct cred *cred)
 {
        /*
@@ -1776,6 +2896,16 @@ void security_cred_free(struct cred *cred)
        cred->security = NULL;
 }
 
+/**
+ * security_prepare_creds() - Prepare a new set of credentials
+ * @new: new credentials
+ * @old: original credentials
+ * @gfp: gfp flags
+ *
+ * Prepare a new set of credentials by copying the data from the old set.
+ *
+ * Return: Returns 0 on success, negative values on failure.
+ */
 int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp)
 {
        int rc = lsm_cred_alloc(new, gfp);
@@ -1789,11 +2919,26 @@ int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp)
        return rc;
 }
 
+/**
+ * security_transfer_creds() - Transfer creds
+ * @new: target credentials
+ * @old: original credentials
+ *
+ * Transfer data from original creds to new creds.
+ */
 void security_transfer_creds(struct cred *new, const struct cred *old)
 {
        call_void_hook(cred_transfer, new, old);
 }
 
+/**
+ * security_cred_getsecid() - Get the secid from a set of credentials
+ * @c: credentials
+ * @secid: secid value
+ *
+ * Retrieve the security identifier of the cred structure @c.  In case of
+ * failure, @secid will be set to zero.
+ */
 void security_cred_getsecid(const struct cred *c, u32 *secid)
 {
        *secid = 0;
@@ -1801,16 +2946,46 @@ void security_cred_getsecid(const struct cred *c, u32 *secid)
 }
 EXPORT_SYMBOL(security_cred_getsecid);
 
+/**
+ * security_kernel_act_as() - Set the kernel credentials to act as secid
+ * @new: credentials
+ * @secid: secid
+ *
+ * Set the credentials for a kernel service to act as (subjective context).
+ * The current task must be the one that nominated @secid.
+ *
+ * Return: Returns 0 if successful.
+ */
 int security_kernel_act_as(struct cred *new, u32 secid)
 {
        return call_int_hook(kernel_act_as, 0, new, secid);
 }
 
+/**
+ * security_kernel_create_files_as() - Set file creation context using an inode
+ * @new: target credentials
+ * @inode: reference inode
+ *
+ * Set the file creation context in a set of credentials to be the same as the
+ * objective context of the specified inode.  The current task must be the one
+ * that nominated @inode.
+ *
+ * Return: Returns 0 if successful.
+ */
 int security_kernel_create_files_as(struct cred *new, struct inode *inode)
 {
        return call_int_hook(kernel_create_files_as, 0, new, inode);
 }
 
+/**
+ * security_kernel_module_request() - Check is loading a module is allowed
+ * @kmod_name: module name
+ *
+ * Ability to trigger the kernel to automatically upcall to userspace for
+ * userspace to load a kernel module with the given name.
+ *
+ * Return: Returns 0 if successful.
+ */
 int security_kernel_module_request(char *kmod_name)
 {
        int ret;
@@ -1821,6 +2996,16 @@ int security_kernel_module_request(char *kmod_name)
        return integrity_kernel_module_request(kmod_name);
 }
 
+/**
+ * security_kernel_read_file() - Read a file specified by userspace
+ * @file: file
+ * @id: file identifier
+ * @contents: trust if security_kernel_post_read_file() will be called
+ *
+ * Read a file specified by userspace.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_kernel_read_file(struct file *file, enum kernel_read_file_id id,
                              bool contents)
 {
@@ -1833,6 +3018,19 @@ int security_kernel_read_file(struct file *file, enum kernel_read_file_id id,
 }
 EXPORT_SYMBOL_GPL(security_kernel_read_file);
 
+/**
+ * security_kernel_post_read_file() - Read a file specified by userspace
+ * @file: file
+ * @buf: file contents
+ * @size: size of file contents
+ * @id: file identifier
+ *
+ * Read a file specified by userspace.  This must be paired with a prior call
+ * to security_kernel_read_file() call that indicated this hook would also be
+ * called, see security_kernel_read_file() for more information.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
                                   enum kernel_read_file_id id)
 {
@@ -1845,6 +3043,15 @@ int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
 }
 EXPORT_SYMBOL_GPL(security_kernel_post_read_file);
 
+/**
+ * security_kernel_load_data() - Load data provided by userspace
+ * @id: data identifier
+ * @contents: true if security_kernel_post_load_data() will be called
+ *
+ * Load data provided by userspace.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_kernel_load_data(enum kernel_load_data_id id, bool contents)
 {
        int ret;
@@ -1856,6 +3063,20 @@ int security_kernel_load_data(enum kernel_load_data_id id, bool contents)
 }
 EXPORT_SYMBOL_GPL(security_kernel_load_data);
 
+/**
+ * security_kernel_post_load_data() - Load userspace data from a non-file source
+ * @buf: data
+ * @size: size of data
+ * @id: data identifier
+ * @description: text description of data, specific to the id value
+ *
+ * Load data provided by a non-file source (usually userspace buffer).  This
+ * must be paired with a prior security_kernel_load_data() call that indicated
+ * this hook would also be called, see security_kernel_load_data() for more
+ * information.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_kernel_post_load_data(char *buf, loff_t size,
                                   enum kernel_load_data_id id,
                                   char *description)
@@ -1870,38 +3091,112 @@ int security_kernel_post_load_data(char *buf, loff_t size,
 }
 EXPORT_SYMBOL_GPL(security_kernel_post_load_data);
 
+/**
+ * security_task_fix_setuid() - Update LSM with new user id attributes
+ * @new: updated credentials
+ * @old: credentials being replaced
+ * @flags: LSM_SETID_* flag values
+ *
+ * Update the module's state after setting one or more of the user identity
+ * attributes of the current process.  The @flags parameter indicates which of
+ * the set*uid system calls invoked this hook.  If @new is the set of
+ * credentials that will be installed.  Modifications should be made to this
+ * rather than to @current->cred.
+ *
+ * Return: Returns 0 on success.
+ */
 int security_task_fix_setuid(struct cred *new, const struct cred *old,
                             int flags)
 {
        return call_int_hook(task_fix_setuid, 0, new, old, flags);
 }
 
+/**
+ * security_task_fix_setgid() - Update LSM with new group id attributes
+ * @new: updated credentials
+ * @old: credentials being replaced
+ * @flags: LSM_SETID_* flag value
+ *
+ * Update the module's state after setting one or more of the group identity
+ * attributes of the current process.  The @flags parameter indicates which of
+ * the set*gid system calls invoked this hook.  @new is the set of credentials
+ * that will be installed.  Modifications should be made to this rather than to
+ * @current->cred.
+ *
+ * Return: Returns 0 on success.
+ */
 int security_task_fix_setgid(struct cred *new, const struct cred *old,
-                                int flags)
+                            int flags)
 {
        return call_int_hook(task_fix_setgid, 0, new, old, flags);
 }
 
+/**
+ * security_task_fix_setgroups() - Update LSM with new supplementary groups
+ * @new: updated credentials
+ * @old: credentials being replaced
+ *
+ * Update the module's state after setting the supplementary group identity
+ * attributes of the current process.  @new is the set of credentials that will
+ * be installed.  Modifications should be made to this rather than to
+ * @current->cred.
+ *
+ * Return: Returns 0 on success.
+ */
 int security_task_fix_setgroups(struct cred *new, const struct cred *old)
 {
        return call_int_hook(task_fix_setgroups, 0, new, old);
 }
 
+/**
+ * security_task_setpgid() - Check if setting the pgid is allowed
+ * @p: task being modified
+ * @pgid: new pgid
+ *
+ * Check permission before setting the process group identifier of the process
+ * @p to @pgid.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_task_setpgid(struct task_struct *p, pid_t pgid)
 {
        return call_int_hook(task_setpgid, 0, p, pgid);
 }
 
+/**
+ * security_task_getpgid() - Check if getting the pgid is allowed
+ * @p: task
+ *
+ * Check permission before getting the process group identifier of the process
+ * @p.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_task_getpgid(struct task_struct *p)
 {
        return call_int_hook(task_getpgid, 0, p);
 }
 
+/**
+ * security_task_getsid() - Check if getting the session id is allowed
+ * @p: task
+ *
+ * Check permission before getting the session identifier of the process @p.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_task_getsid(struct task_struct *p)
 {
        return call_int_hook(task_getsid, 0, p);
 }
 
+/**
+ * security_current_getsecid_subj() - Get the current task's subjective secid
+ * @secid: secid value
+ *
+ * Retrieve the subjective security identifier of the current task and return
+ * it in @secid.  In case of failure, @secid will be set to zero.
+ */
 void security_current_getsecid_subj(u32 *secid)
 {
        *secid = 0;
@@ -1909,6 +3204,14 @@ void security_current_getsecid_subj(u32 *secid)
 }
 EXPORT_SYMBOL(security_current_getsecid_subj);
 
+/**
+ * security_task_getsecid_obj() - Get a task's objective secid
+ * @p: target task
+ * @secid: secid value
+ *
+ * Retrieve the objective security identifier of the task_struct in @p and
+ * return it in @secid. In case of failure, @secid will be set to zero.
+ */
 void security_task_getsecid_obj(struct task_struct *p, u32 *secid)
 {
        *secid = 0;
@@ -1916,56 +3219,159 @@ void security_task_getsecid_obj(struct task_struct *p, u32 *secid)
 }
 EXPORT_SYMBOL(security_task_getsecid_obj);
 
+/**
+ * security_task_setnice() - Check if setting a task's nice value is allowed
+ * @p: target task
+ * @nice: nice value
+ *
+ * Check permission before setting the nice value of @p to @nice.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_task_setnice(struct task_struct *p, int nice)
 {
        return call_int_hook(task_setnice, 0, p, nice);
 }
 
+/**
+ * security_task_setioprio() - Check if setting a task's ioprio is allowed
+ * @p: target task
+ * @ioprio: ioprio value
+ *
+ * Check permission before setting the ioprio value of @p to @ioprio.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_task_setioprio(struct task_struct *p, int ioprio)
 {
        return call_int_hook(task_setioprio, 0, p, ioprio);
 }
 
+/**
+ * security_task_getioprio() - Check if getting a task's ioprio is allowed
+ * @p: task
+ *
+ * Check permission before getting the ioprio value of @p.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_task_getioprio(struct task_struct *p)
 {
        return call_int_hook(task_getioprio, 0, p);
 }
 
+/**
+ * security_task_prlimit() - Check if get/setting resources limits is allowed
+ * @cred: current task credentials
+ * @tcred: target task credentials
+ * @flags: LSM_PRLIMIT_* flag bits indicating a get/set/both
+ *
+ * Check permission before getting and/or setting the resource limits of
+ * another task.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_task_prlimit(const struct cred *cred, const struct cred *tcred,
                          unsigned int flags)
 {
        return call_int_hook(task_prlimit, 0, cred, tcred, flags);
 }
 
+/**
+ * security_task_setrlimit() - Check if setting a new rlimit value is allowed
+ * @p: target task's group leader
+ * @resource: resource whose limit is being set
+ * @new_rlim: new resource limit
+ *
+ * Check permission before setting the resource limits of process @p for
+ * @resource to @new_rlim.  The old resource limit values can be examined by
+ * dereferencing (p->signal->rlim + resource).
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_task_setrlimit(struct task_struct *p, unsigned int resource,
-               struct rlimit *new_rlim)
+                           struct rlimit *new_rlim)
 {
        return call_int_hook(task_setrlimit, 0, p, resource, new_rlim);
 }
 
+/**
+ * security_task_setscheduler() - Check if setting sched policy/param is allowed
+ * @p: target task
+ *
+ * Check permission before setting scheduling policy and/or parameters of
+ * process @p.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_task_setscheduler(struct task_struct *p)
 {
        return call_int_hook(task_setscheduler, 0, p);
 }
 
+/**
+ * security_task_getscheduler() - Check if getting scheduling info is allowed
+ * @p: target task
+ *
+ * Check permission before obtaining scheduling information for process @p.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_task_getscheduler(struct task_struct *p)
 {
        return call_int_hook(task_getscheduler, 0, p);
 }
 
-int security_task_movememory(struct task_struct *p)
-{
+/**
+ * security_task_movememory() - Check if moving memory is allowed
+ * @p: task
+ *
+ * Check permission before moving memory owned by process @p.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
+int security_task_movememory(struct task_struct *p)
+{
        return call_int_hook(task_movememory, 0, p);
 }
 
+/**
+ * security_task_kill() - Check if sending a signal is allowed
+ * @p: target process
+ * @info: signal information
+ * @sig: signal value
+ * @cred: credentials of the signal sender, NULL if @current
+ *
+ * Check permission before sending signal @sig to @p.  @info can be NULL, the
+ * constant 1, or a pointer to a kernel_siginfo structure.  If @info is 1 or
+ * SI_FROMKERNEL(info) is true, then the signal should be viewed as coming from
+ * the kernel and should typically be permitted.  SIGIO signals are handled
+ * separately by the send_sigiotask hook in file_security_ops.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_task_kill(struct task_struct *p, struct kernel_siginfo *info,
-                       int sig, const struct cred *cred)
+                      int sig, const struct cred *cred)
 {
        return call_int_hook(task_kill, 0, p, info, sig, cred);
 }
 
+/**
+ * security_task_prctl() - Check if a prctl op is allowed
+ * @option: operation
+ * @arg2: argument
+ * @arg3: argument
+ * @arg4: argument
+ * @arg5: argument
+ *
+ * Check permission before performing a process control operation on the
+ * current process.
+ *
+ * Return: Return -ENOSYS if no-one wanted to handle this op, any other value
+ *         to cause prctl() to return immediately with that value.
+ */
 int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
-                        unsigned long arg4, unsigned long arg5)
+                       unsigned long arg4, unsigned long arg5)
 {
        int thisrc;
        int rc = LSM_RET_DEFAULT(task_prctl);
@@ -1982,27 +3388,69 @@ int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
        return rc;
 }
 
+/**
+ * security_task_to_inode() - Set the security attributes of a task's inode
+ * @p: task
+ * @inode: inode
+ *
+ * Set the security attributes for an inode based on an associated task's
+ * security attributes, e.g. for /proc/pid inodes.
+ */
 void security_task_to_inode(struct task_struct *p, struct inode *inode)
 {
        call_void_hook(task_to_inode, p, inode);
 }
 
+/**
+ * security_create_user_ns() - Check if creating a new userns is allowed
+ * @cred: prepared creds
+ *
+ * Check permission prior to creating a new user namespace.
+ *
+ * Return: Returns 0 if successful, otherwise < 0 error code.
+ */
 int security_create_user_ns(const struct cred *cred)
 {
        return call_int_hook(userns_create, 0, cred);
 }
 
+/**
+ * security_ipc_permission() - Check if sysv ipc access is allowed
+ * @ipcp: ipc permission structure
+ * @flag: requested permissions
+ *
+ * Check permissions for access to IPC.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
 {
        return call_int_hook(ipc_permission, 0, ipcp, flag);
 }
 
+/**
+ * security_ipc_getsecid() - Get the sysv ipc object's secid
+ * @ipcp: ipc permission structure
+ * @secid: secid pointer
+ *
+ * Get the secid associated with the ipc object.  In case of failure, @secid
+ * will be set to zero.
+ */
 void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
 {
        *secid = 0;
        call_void_hook(ipc_getsecid, ipcp, secid);
 }
 
+/**
+ * security_msg_msg_alloc() - Allocate a sysv ipc message LSM blob
+ * @msg: message structure
+ *
+ * Allocate and attach a security structure to the msg->security field.  The
+ * security field is initialized to NULL when the structure is first created.
+ *
+ * Return: Return 0 if operation was successful and permission is granted.
+ */
 int security_msg_msg_alloc(struct msg_msg *msg)
 {
        int rc = lsm_msg_msg_alloc(msg);
@@ -2015,6 +3463,12 @@ int security_msg_msg_alloc(struct msg_msg *msg)
        return rc;
 }
 
+/**
+ * security_msg_msg_free() - Free a sysv ipc message LSM blob
+ * @msg: message structure
+ *
+ * Deallocate the security structure for this message.
+ */
 void security_msg_msg_free(struct msg_msg *msg)
 {
        call_void_hook(msg_msg_free_security, msg);
@@ -2022,6 +3476,15 @@ void security_msg_msg_free(struct msg_msg *msg)
        msg->security = NULL;
 }
 
+/**
+ * security_msg_queue_alloc() - Allocate a sysv ipc msg queue LSM blob
+ * @msq: sysv ipc permission structure
+ *
+ * Allocate and attach a security structure to @msg. The security field is
+ * initialized to NULL when the structure is first created.
+ *
+ * Return: Returns 0 if operation was successful and permission is granted.
+ */
 int security_msg_queue_alloc(struct kern_ipc_perm *msq)
 {
        int rc = lsm_ipc_alloc(msq);
@@ -2034,6 +3497,12 @@ int security_msg_queue_alloc(struct kern_ipc_perm *msq)
        return rc;
 }
 
+/**
+ * security_msg_queue_free() - Free a sysv ipc msg queue LSM blob
+ * @msq: sysv ipc permission structure
+ *
+ * Deallocate security field @perm->security for the message queue.
+ */
 void security_msg_queue_free(struct kern_ipc_perm *msq)
 {
        call_void_hook(msg_queue_free_security, msq);
@@ -2041,28 +3510,84 @@ void security_msg_queue_free(struct kern_ipc_perm *msq)
        msq->security = NULL;
 }
 
+/**
+ * security_msg_queue_associate() - Check if a msg queue operation is allowed
+ * @msq: sysv ipc permission structure
+ * @msqflg: operation flags
+ *
+ * Check permission when a message queue is requested through the msgget system
+ * call. This hook is only called when returning the message queue identifier
+ * for an existing message queue, not when a new message queue is created.
+ *
+ * Return: Return 0 if permission is granted.
+ */
 int security_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg)
 {
        return call_int_hook(msg_queue_associate, 0, msq, msqflg);
 }
 
+/**
+ * security_msg_queue_msgctl() - Check if a msg queue operation is allowed
+ * @msq: sysv ipc permission structure
+ * @cmd: operation
+ *
+ * Check permission when a message control operation specified by @cmd is to be
+ * performed on the message queue with permissions.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd)
 {
        return call_int_hook(msg_queue_msgctl, 0, msq, cmd);
 }
 
+/**
+ * security_msg_queue_msgsnd() - Check if sending a sysv ipc message is allowed
+ * @msq: sysv ipc permission structure
+ * @msg: message
+ * @msqflg: operation flags
+ *
+ * Check permission before a message, @msg, is enqueued on the message queue
+ * with permissions specified in @msq.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_msg_queue_msgsnd(struct kern_ipc_perm *msq,
-                              struct msg_msg *msg, int msqflg)
+                             struct msg_msg *msg, int msqflg)
 {
        return call_int_hook(msg_queue_msgsnd, 0, msq, msg, msqflg);
 }
 
+/**
+ * security_msg_queue_msgrcv() - Check if receiving a sysv ipc msg is allowed
+ * @msq: sysv ipc permission structure
+ * @msg: message
+ * @target: target task
+ * @type: type of message requested
+ * @mode: operation flags
+ *
+ * Check permission before a message, @msg, is removed from the message        queue.
+ * The @target task structure contains a pointer to the process that will be
+ * receiving the message (not equal to the current process when inline receives
+ * are being performed).
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *msg,
-                              struct task_struct *target, long type, int mode)
+                             struct task_struct *target, long type, int mode)
 {
        return call_int_hook(msg_queue_msgrcv, 0, msq, msg, target, type, mode);
 }
 
+/**
+ * security_shm_alloc() - Allocate a sysv shm LSM blob
+ * @shp: sysv ipc permission structure
+ *
+ * Allocate and attach a security structure to the @shp security field.  The
+ * security field is initialized to NULL when the structure is first created.
+ *
+ * Return: Returns 0 if operation was successful and permission is granted.
+ */
 int security_shm_alloc(struct kern_ipc_perm *shp)
 {
        int rc = lsm_ipc_alloc(shp);
@@ -2075,6 +3600,12 @@ int security_shm_alloc(struct kern_ipc_perm *shp)
        return rc;
 }
 
+/**
+ * security_shm_free() - Free a sysv shm LSM blob
+ * @shp: sysv ipc permission structure
+ *
+ * Deallocate the security structure @perm->security for the memory segment.
+ */
 void security_shm_free(struct kern_ipc_perm *shp)
 {
        call_void_hook(shm_free_security, shp);
@@ -2082,21 +3613,65 @@ void security_shm_free(struct kern_ipc_perm *shp)
        shp->security = NULL;
 }
 
+/**
+ * security_shm_associate() - Check if a sysv shm operation is allowed
+ * @shp: sysv ipc permission structure
+ * @shmflg: operation flags
+ *
+ * Check permission when a shared memory region is requested through the shmget
+ * system call. This hook is only called when returning the shared memory
+ * region identifier for an existing region, not when a new shared memory
+ * region is created.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_shm_associate(struct kern_ipc_perm *shp, int shmflg)
 {
        return call_int_hook(shm_associate, 0, shp, shmflg);
 }
 
+/**
+ * security_shm_shmctl() - Check if a sysv shm operation is allowed
+ * @shp: sysv ipc permission structure
+ * @cmd: operation
+ *
+ * Check permission when a shared memory control operation specified by @cmd is
+ * to be performed on the shared memory region with permissions in @shp.
+ *
+ * Return: Return 0 if permission is granted.
+ */
 int security_shm_shmctl(struct kern_ipc_perm *shp, int cmd)
 {
        return call_int_hook(shm_shmctl, 0, shp, cmd);
 }
 
-int security_shm_shmat(struct kern_ipc_perm *shp, char __user *shmaddr, int shmflg)
+/**
+ * security_shm_shmat() - Check if a sysv shm attach operation is allowed
+ * @shp: sysv ipc permission structure
+ * @shmaddr: address of memory region to attach
+ * @shmflg: operation flags
+ *
+ * Check permissions prior to allowing the shmat system call to attach the
+ * shared memory segment with permissions @shp to the data segment of the
+ * calling process. The attaching address is specified by @shmaddr.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
+int security_shm_shmat(struct kern_ipc_perm *shp,
+                      char __user *shmaddr, int shmflg)
 {
        return call_int_hook(shm_shmat, 0, shp, shmaddr, shmflg);
 }
 
+/**
+ * security_sem_alloc() - Allocate a sysv semaphore LSM blob
+ * @sma: sysv ipc permission structure
+ *
+ * Allocate and attach a security structure to the @sma security field. The
+ * security field is initialized to NULL when the structure is first created.
+ *
+ * Return: Returns 0 if operation was successful and permission is granted.
+ */
 int security_sem_alloc(struct kern_ipc_perm *sma)
 {
        int rc = lsm_ipc_alloc(sma);
@@ -2109,6 +3684,12 @@ int security_sem_alloc(struct kern_ipc_perm *sma)
        return rc;
 }
 
+/**
+ * security_sem_free() - Free a sysv semaphore LSM blob
+ * @sma: sysv ipc permission structure
+ *
+ * Deallocate security structure @sma->security for the semaphore.
+ */
 void security_sem_free(struct kern_ipc_perm *sma)
 {
        call_void_hook(sem_free_security, sma);
@@ -2116,22 +3697,62 @@ void security_sem_free(struct kern_ipc_perm *sma)
        sma->security = NULL;
 }
 
+/**
+ * security_sem_associate() - Check if a sysv semaphore operation is allowed
+ * @sma: sysv ipc permission structure
+ * @semflg: operation flags
+ *
+ * Check permission when a semaphore is requested through the semget system
+ * call. This hook is only called when returning the semaphore identifier for
+ * an existing semaphore, not when a new one must be created.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_sem_associate(struct kern_ipc_perm *sma, int semflg)
 {
        return call_int_hook(sem_associate, 0, sma, semflg);
 }
 
+/**
+ * security_sem_semctl() - Check if a sysv semaphore operation is allowed
+ * @sma: sysv ipc permission structure
+ * @cmd: operation
+ *
+ * Check permission when a semaphore operation specified by @cmd is to be
+ * performed on the semaphore.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_sem_semctl(struct kern_ipc_perm *sma, int cmd)
 {
        return call_int_hook(sem_semctl, 0, sma, cmd);
 }
 
+/**
+ * security_sem_semop() - Check if a sysv semaphore operation is allowed
+ * @sma: sysv ipc permission structure
+ * @sops: operations to perform
+ * @nsops: number of operations
+ * @alter: flag indicating changes will be made
+ *
+ * Check permissions before performing operations on members of the semaphore
+ * set. If the @alter flag is nonzero, the semaphore set may be modified.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops,
-                       unsigned nsops, int alter)
+                      unsigned nsops, int alter)
 {
        return call_int_hook(sem_semop, 0, sma, sops, nsops, alter);
 }
 
+/**
+ * security_d_instantiate() - Populate an inode's LSM state based on a dentry
+ * @dentry: dentry
+ * @inode: inode
+ *
+ * Fill in @inode security information for a @dentry if allowed.
+ */
 void security_d_instantiate(struct dentry *dentry, struct inode *inode)
 {
        if (unlikely(inode && IS_PRIVATE(inode)))
@@ -2140,6 +3761,17 @@ void security_d_instantiate(struct dentry *dentry, struct inode *inode)
 }
 EXPORT_SYMBOL(security_d_instantiate);
 
+/**
+ * security_getprocattr() - Read an attribute for a task
+ * @p: the task
+ * @lsm: LSM name
+ * @name: attribute name
+ * @value: attribute value
+ *
+ * Read attribute @name for task @p and store it into @value if allowed.
+ *
+ * Return: Returns the length of @value on success, a negative value otherwise.
+ */
 int security_getprocattr(struct task_struct *p, const char *lsm,
                         const char *name, char **value)
 {
@@ -2153,6 +3785,18 @@ int security_getprocattr(struct task_struct *p, const char *lsm,
        return LSM_RET_DEFAULT(getprocattr);
 }
 
+/**
+ * security_setprocattr() - Set an attribute for a task
+ * @lsm: LSM name
+ * @name: attribute name
+ * @value: attribute value
+ * @size: attribute value size
+ *
+ * Write (set) the current task's attribute @name to @value, size @size if
+ * allowed.
+ *
+ * Return: Returns bytes written on success, a negative value otherwise.
+ */
 int security_setprocattr(const char *lsm, const char *name, void *value,
                         size_t size)
 {
@@ -2166,17 +3810,51 @@ int security_setprocattr(const char *lsm, const char *name, void *value,
        return LSM_RET_DEFAULT(setprocattr);
 }
 
+/**
+ * security_netlink_send() - Save info and check if netlink sending is allowed
+ * @sk: sending socket
+ * @skb: netlink message
+ *
+ * Save security information for a netlink message so that permission checking
+ * can be performed when the message is processed.  The security information
+ * can be saved using the eff_cap field of the netlink_skb_parms structure.
+ * Also may be used to provide fine grained control over message transmission.
+ *
+ * Return: Returns 0 if the information was successfully saved and message is
+ *         allowed to be transmitted.
+ */
 int security_netlink_send(struct sock *sk, struct sk_buff *skb)
 {
        return call_int_hook(netlink_send, 0, sk, skb);
 }
 
+/**
+ * security_ismaclabel() - Check is the named attribute is a MAC label
+ * @name: full extended attribute name
+ *
+ * Check if the extended attribute specified by @name represents a MAC label.
+ *
+ * Return: Returns 1 if name is a MAC attribute otherwise returns 0.
+ */
 int security_ismaclabel(const char *name)
 {
        return call_int_hook(ismaclabel, 0, name);
 }
 EXPORT_SYMBOL(security_ismaclabel);
 
+/**
+ * security_secid_to_secctx() - Convert a secid to a secctx
+ * @secid: secid
+ * @secdata: secctx
+ * @seclen: secctx length
+ *
+ * Convert secid to security context.  If @secdata is NULL the length of the
+ * result will be returned in @seclen, but no @secdata will be returned.  This
+ * does mean that the length could change between calls to check the length and
+ * the next call which actually allocates and returns the @secdata.
+ *
+ * Return: Return 0 on success, error on failure.
+ */
 int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
 {
        struct security_hook_list *hp;
@@ -2196,6 +3874,16 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
 }
 EXPORT_SYMBOL(security_secid_to_secctx);
 
+/**
+ * security_secctx_to_secid() - Convert a secctx to a secid
+ * @secdata: secctx
+ * @seclen: length of secctx
+ * @secid: secid
+ *
+ * Convert security context to secid.
+ *
+ * Return: Returns 0 on success, error on failure.
+ */
 int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
 {
        *secid = 0;
@@ -2203,30 +3891,86 @@ int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
 }
 EXPORT_SYMBOL(security_secctx_to_secid);
 
+/**
+ * security_release_secctx() - Free a secctx buffer
+ * @secdata: secctx
+ * @seclen: length of secctx
+ *
+ * Release the security context.
+ */
 void security_release_secctx(char *secdata, u32 seclen)
 {
        call_void_hook(release_secctx, secdata, seclen);
 }
 EXPORT_SYMBOL(security_release_secctx);
 
+/**
+ * security_inode_invalidate_secctx() - Invalidate an inode's security label
+ * @inode: inode
+ *
+ * Notify the security module that it must revalidate the security context of
+ * an inode.
+ */
 void security_inode_invalidate_secctx(struct inode *inode)
 {
        call_void_hook(inode_invalidate_secctx, inode);
 }
 EXPORT_SYMBOL(security_inode_invalidate_secctx);
 
+/**
+ * security_inode_notifysecctx() - Nofify the LSM of an inode's security label
+ * @inode: inode
+ * @ctx: secctx
+ * @ctxlen: length of secctx
+ *
+ * Notify the security module of what the security context of an inode should
+ * be.  Initializes the incore security context managed by the security module
+ * for this inode.  Example usage: NFS client invokes this hook to initialize
+ * the security context in its incore inode to the value provided by the server
+ * for the file when the server returned the file's attributes to the client.
+ * Must be called with inode->i_mutex locked.
+ *
+ * Return: Returns 0 on success, error on failure.
+ */
 int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
 {
        return call_int_hook(inode_notifysecctx, 0, inode, ctx, ctxlen);
 }
 EXPORT_SYMBOL(security_inode_notifysecctx);
 
+/**
+ * security_inode_setsecctx() - Change the security label of an inode
+ * @dentry: inode
+ * @ctx: secctx
+ * @ctxlen: length of secctx
+ *
+ * Change the security context of an inode.  Updates the incore security
+ * context managed by the security module and invokes the fs code as needed
+ * (via __vfs_setxattr_noperm) to update any backing xattrs that represent the
+ * context.  Example usage: NFS server invokes this hook to change the security
+ * context in its incore inode and on the backing filesystem to a value
+ * provided by the client on a SETATTR operation.  Must be called with
+ * inode->i_mutex locked.
+ *
+ * Return: Returns 0 on success, error on failure.
+ */
 int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
 {
        return call_int_hook(inode_setsecctx, 0, dentry, ctx, ctxlen);
 }
 EXPORT_SYMBOL(security_inode_setsecctx);
 
+/**
+ * security_inode_getsecctx() - Get the security label of an inode
+ * @inode: inode
+ * @ctx: secctx
+ * @ctxlen: length of secctx
+ *
+ * On success, returns 0 and fills out @ctx and @ctxlen with the security
+ * context for the given @inode.
+ *
+ * Return: Returns 0 on success, error on failure.
+ */
 int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
 {
        return call_int_hook(inode_getsecctx, -EOPNOTSUPP, inode, ctx, ctxlen);
@@ -2234,6 +3978,16 @@ int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
 EXPORT_SYMBOL(security_inode_getsecctx);
 
 #ifdef CONFIG_WATCH_QUEUE
+/**
+ * security_post_notification() - Check if a watch notification can be posted
+ * @w_cred: credentials of the task that set the watch
+ * @cred: credentials of the task which triggered the watch
+ * @n: the notification
+ *
+ * Check to see if a watch notification can be posted to a particular queue.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_post_notification(const struct cred *w_cred,
                               const struct cred *cred,
                               struct watch_notification *n)
@@ -2243,106 +3997,336 @@ int security_post_notification(const struct cred *w_cred,
 #endif /* CONFIG_WATCH_QUEUE */
 
 #ifdef CONFIG_KEY_NOTIFICATIONS
+/**
+ * security_watch_key() - Check if a task is allowed to watch for key events
+ * @key: the key to watch
+ *
+ * Check to see if a process is allowed to watch for event notifications from
+ * a key or keyring.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_watch_key(struct key *key)
 {
        return call_int_hook(watch_key, 0, key);
 }
-#endif
+#endif /* CONFIG_KEY_NOTIFICATIONS */
 
 #ifdef CONFIG_SECURITY_NETWORK
-
-int security_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk)
+/**
+ * security_unix_stream_connect() - Check if a AF_UNIX stream is allowed
+ * @sock: originating sock
+ * @other: peer sock
+ * @newsk: new sock
+ *
+ * Check permissions before establishing a Unix domain stream connection
+ * between @sock and @other.
+ *
+ * The @unix_stream_connect and @unix_may_send hooks were necessary because
+ * Linux provides an alternative to the conventional file name space for Unix
+ * domain sockets.  Whereas binding and connecting to sockets in the file name
+ * space is mediated by the typical file permissions (and caught by the mknod
+ * and permission hooks in inode_security_ops), binding and connecting to
+ * sockets in the abstract name space is completely unmediated.  Sufficient
+ * control of Unix domain sockets in the abstract name space isn't possible
+ * using only the socket layer hooks, since we need to know the actual target
+ * socket, which is not looked up until we are inside the af_unix code.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
+int security_unix_stream_connect(struct sock *sock, struct sock *other,
+                                struct sock *newsk)
 {
        return call_int_hook(unix_stream_connect, 0, sock, other, newsk);
 }
 EXPORT_SYMBOL(security_unix_stream_connect);
 
+/**
+ * security_unix_may_send() - Check if AF_UNIX socket can send datagrams
+ * @sock: originating sock
+ * @other: peer sock
+ *
+ * Check permissions before connecting or sending datagrams from @sock to
+ * @other.
+ *
+ * The @unix_stream_connect and @unix_may_send hooks were necessary because
+ * Linux provides an alternative to the conventional file name space for Unix
+ * domain sockets.  Whereas binding and connecting to sockets in the file name
+ * space is mediated by the typical file permissions (and caught by the mknod
+ * and permission hooks in inode_security_ops), binding and connecting to
+ * sockets in the abstract name space is completely unmediated.  Sufficient
+ * control of Unix domain sockets in the abstract name space isn't possible
+ * using only the socket layer hooks, since we need to know the actual target
+ * socket, which is not looked up until we are inside the af_unix code.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_unix_may_send(struct socket *sock,  struct socket *other)
 {
        return call_int_hook(unix_may_send, 0, sock, other);
 }
 EXPORT_SYMBOL(security_unix_may_send);
 
+/**
+ * security_socket_create() - Check if creating a new socket is allowed
+ * @family: protocol family
+ * @type: communications type
+ * @protocol: requested protocol
+ * @kern: set to 1 if a kernel socket is requested
+ *
+ * Check permissions prior to creating a new socket.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_socket_create(int family, int type, int protocol, int kern)
 {
        return call_int_hook(socket_create, 0, family, type, protocol, kern);
 }
 
+/**
+ * security_socket_post_create() - Initialize a newly created socket
+ * @sock: socket
+ * @family: protocol family
+ * @type: communications type
+ * @protocol: requested protocol
+ * @kern: set to 1 if a kernel socket is requested
+ *
+ * This hook allows a module to update or allocate a per-socket security
+ * structure. Note that the security field was not added directly to the socket
+ * structure, but rather, the socket security information is stored in the
+ * associated inode.  Typically, the inode alloc_security hook will allocate
+ * and attach security information to SOCK_INODE(sock)->i_security.  This hook
+ * may be used to update the SOCK_INODE(sock)->i_security field with additional
+ * information that wasn't available when the inode was allocated.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_socket_post_create(struct socket *sock, int family,
                                int type, int protocol, int kern)
 {
        return call_int_hook(socket_post_create, 0, sock, family, type,
-                                               protocol, kern);
+                            protocol, kern);
 }
 
+/**
+ * security_socket_socketpair() - Check if creating a socketpair is allowed
+ * @socka: first socket
+ * @sockb: second socket
+ *
+ * Check permissions before creating a fresh pair of sockets.
+ *
+ * Return: Returns 0 if permission is granted and the connection was
+ *         established.
+ */
 int security_socket_socketpair(struct socket *socka, struct socket *sockb)
 {
        return call_int_hook(socket_socketpair, 0, socka, sockb);
 }
 EXPORT_SYMBOL(security_socket_socketpair);
 
-int security_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
+/**
+ * security_socket_bind() - Check if a socket bind operation is allowed
+ * @sock: socket
+ * @address: requested bind address
+ * @addrlen: length of address
+ *
+ * Check permission before socket protocol layer bind operation is performed
+ * and the socket @sock is bound to the address specified in the @address
+ * parameter.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
+int security_socket_bind(struct socket *sock,
+                        struct sockaddr *address, int addrlen)
 {
        return call_int_hook(socket_bind, 0, sock, address, addrlen);
 }
 
-int security_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen)
+/**
+ * security_socket_connect() - Check if a socket connect operation is allowed
+ * @sock: socket
+ * @address: address of remote connection point
+ * @addrlen: length of address
+ *
+ * Check permission before socket protocol layer connect operation attempts to
+ * connect socket @sock to a remote address, @address.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
+int security_socket_connect(struct socket *sock,
+                           struct sockaddr *address, int addrlen)
 {
        return call_int_hook(socket_connect, 0, sock, address, addrlen);
 }
 
+/**
+ * security_socket_listen() - Check if a socket is allowed to listen
+ * @sock: socket
+ * @backlog: connection queue size
+ *
+ * Check permission before socket protocol layer listen operation.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_socket_listen(struct socket *sock, int backlog)
 {
        return call_int_hook(socket_listen, 0, sock, backlog);
 }
 
+/**
+ * security_socket_accept() - Check if a socket is allowed to accept connections
+ * @sock: listening socket
+ * @newsock: newly creation connection socket
+ *
+ * Check permission before accepting a new connection.  Note that the new
+ * socket, @newsock, has been created and some information copied to it, but
+ * the accept operation has not actually been performed.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_socket_accept(struct socket *sock, struct socket *newsock)
 {
        return call_int_hook(socket_accept, 0, sock, newsock);
 }
 
+/**
+ * security_socket_sendmsg() - Check is sending a message is allowed
+ * @sock: sending socket
+ * @msg: message to send
+ * @size: size of message
+ *
+ * Check permission before transmitting a message to another socket.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size)
 {
        return call_int_hook(socket_sendmsg, 0, sock, msg, size);
 }
 
+/**
+ * security_socket_recvmsg() - Check if receiving a message is allowed
+ * @sock: receiving socket
+ * @msg: message to receive
+ * @size: size of message
+ * @flags: operational flags
+ *
+ * Check permission before receiving a message from a socket.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_socket_recvmsg(struct socket *sock, struct msghdr *msg,
                            int size, int flags)
 {
        return call_int_hook(socket_recvmsg, 0, sock, msg, size, flags);
 }
 
+/**
+ * security_socket_getsockname() - Check if reading the socket addr is allowed
+ * @sock: socket
+ *
+ * Check permission before reading the local address (name) of the socket
+ * object.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_socket_getsockname(struct socket *sock)
 {
        return call_int_hook(socket_getsockname, 0, sock);
 }
 
+/**
+ * security_socket_getpeername() - Check if reading the peer's addr is allowed
+ * @sock: socket
+ *
+ * Check permission before the remote address (name) of a socket object.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_socket_getpeername(struct socket *sock)
 {
        return call_int_hook(socket_getpeername, 0, sock);
 }
 
+/**
+ * security_socket_getsockopt() - Check if reading a socket option is allowed
+ * @sock: socket
+ * @level: option's protocol level
+ * @optname: option name
+ *
+ * Check permissions before retrieving the options associated with socket
+ * @sock.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_socket_getsockopt(struct socket *sock, int level, int optname)
 {
        return call_int_hook(socket_getsockopt, 0, sock, level, optname);
 }
 
+/**
+ * security_socket_setsockopt() - Check if setting a socket option is allowed
+ * @sock: socket
+ * @level: option's protocol level
+ * @optname: option name
+ *
+ * Check permissions before setting the options associated with socket @sock.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_socket_setsockopt(struct socket *sock, int level, int optname)
 {
        return call_int_hook(socket_setsockopt, 0, sock, level, optname);
 }
 
+/**
+ * security_socket_shutdown() - Checks if shutting down the socket is allowed
+ * @sock: socket
+ * @how: flag indicating how sends and receives are handled
+ *
+ * Checks permission before all or part of a connection on the socket @sock is
+ * shut down.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_socket_shutdown(struct socket *sock, int how)
 {
        return call_int_hook(socket_shutdown, 0, sock, how);
 }
 
+/**
+ * security_sock_rcv_skb() - Check if an incoming network packet is allowed
+ * @sk: destination sock
+ * @skb: incoming packet
+ *
+ * Check permissions on incoming network packets.  This hook is distinct from
+ * Netfilter's IP input hooks since it is the first time that the incoming
+ * sk_buff @skb has been associated with a particular socket, @sk.  Must not
+ * sleep inside this hook because some callers hold spinlocks.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
        return call_int_hook(socket_sock_rcv_skb, 0, sk, skb);
 }
 EXPORT_SYMBOL(security_sock_rcv_skb);
 
+/**
+ * security_socket_getpeersec_stream() - Get the remote peer label
+ * @sock: socket
+ * @optval: destination buffer
+ * @optlen: size of peer label copied into the buffer
+ * @len: maximum size of the destination buffer
+ *
+ * This hook allows the security module to provide peer socket security state
+ * for unix or connected tcp sockets to userspace via getsockopt SO_GETPEERSEC.
+ * For tcp sockets this can be meaningful if the socket is associated with an
+ * ipsec SA.
+ *
+ * Return: Returns 0 if all is well, otherwise, typical getsockopt return
+ *         values.
+ */
 int security_socket_getpeersec_stream(struct socket *sock, sockptr_t optval,
                                      sockptr_t optlen, unsigned int len)
 {
@@ -2350,23 +4334,62 @@ int security_socket_getpeersec_stream(struct socket *sock, sockptr_t optval,
                             optval, optlen, len);
 }
 
-int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)
+/**
+ * security_socket_getpeersec_dgram() - Get the remote peer label
+ * @sock: socket
+ * @skb: datagram packet
+ * @secid: remote peer label secid
+ *
+ * This hook allows the security module to provide peer socket security state
+ * for udp sockets on a per-packet basis to userspace via getsockopt
+ * SO_GETPEERSEC. The application must first have indicated the IP_PASSSEC
+ * option via getsockopt. It can then retrieve the security state returned by
+ * this hook for a packet via the SCM_SECURITY ancillary message type.
+ *
+ * Return: Returns 0 on success, error on failure.
+ */
+int security_socket_getpeersec_dgram(struct socket *sock,
+                                    struct sk_buff *skb, u32 *secid)
 {
        return call_int_hook(socket_getpeersec_dgram, -ENOPROTOOPT, sock,
                             skb, secid);
 }
 EXPORT_SYMBOL(security_socket_getpeersec_dgram);
 
+/**
+ * security_sk_alloc() - Allocate and initialize a sock's LSM blob
+ * @sk: sock
+ * @family: protocol family
+ * @priority: gfp flags
+ *
+ * Allocate and attach a security structure to the sk->sk_security field, which
+ * is used to copy security attributes between local stream sockets.
+ *
+ * Return: Returns 0 on success, error on failure.
+ */
 int security_sk_alloc(struct sock *sk, int family, gfp_t priority)
 {
        return call_int_hook(sk_alloc_security, 0, sk, family, priority);
 }
 
+/**
+ * security_sk_free() - Free the sock's LSM blob
+ * @sk: sock
+ *
+ * Deallocate security structure.
+ */
 void security_sk_free(struct sock *sk)
 {
        call_void_hook(sk_free_security, sk);
 }
 
+/**
+ * security_sk_clone() - Clone a sock's LSM state
+ * @sk: original sock
+ * @newsk: target sock
+ *
+ * Clone/copy security structure.
+ */
 void security_sk_clone(const struct sock *sk, struct sock *newsk)
 {
        call_void_hook(sk_clone_security, sk, newsk);
@@ -2379,6 +4402,13 @@ void security_sk_classify_flow(struct sock *sk, struct flowi_common *flic)
 }
 EXPORT_SYMBOL(security_sk_classify_flow);
 
+/**
+ * security_req_classify_flow() - Set a flow's secid based on request_sock
+ * @req: request_sock
+ * @flic: target flow
+ *
+ * Sets @flic's secid to @req's secid.
+ */
 void security_req_classify_flow(const struct request_sock *req,
                                struct flowi_common *flic)
 {
@@ -2386,92 +4416,215 @@ void security_req_classify_flow(const struct request_sock *req,
 }
 EXPORT_SYMBOL(security_req_classify_flow);
 
+/**
+ * security_sock_graft() - Reconcile LSM state when grafting a sock on a socket
+ * @sk: sock being grafted
+ * @parent: target parent socket
+ *
+ * Sets @parent's inode secid to @sk's secid and update @sk with any necessary
+ * LSM state from @parent.
+ */
 void security_sock_graft(struct sock *sk, struct socket *parent)
 {
        call_void_hook(sock_graft, sk, parent);
 }
 EXPORT_SYMBOL(security_sock_graft);
 
+/**
+ * security_inet_conn_request() - Set request_sock state using incoming connect
+ * @sk: parent listening sock
+ * @skb: incoming connection
+ * @req: new request_sock
+ *
+ * Initialize the @req LSM state based on @sk and the incoming connect in @skb.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_inet_conn_request(const struct sock *sk,
-                       struct sk_buff *skb, struct request_sock *req)
+                              struct sk_buff *skb, struct request_sock *req)
 {
        return call_int_hook(inet_conn_request, 0, sk, skb, req);
 }
 EXPORT_SYMBOL(security_inet_conn_request);
 
+/**
+ * security_inet_csk_clone() - Set new sock LSM state based on request_sock
+ * @newsk: new sock
+ * @req: connection request_sock
+ *
+ * Set that LSM state of @sock using the LSM state from @req.
+ */
 void security_inet_csk_clone(struct sock *newsk,
-                       const struct request_sock *req)
+                            const struct request_sock *req)
 {
        call_void_hook(inet_csk_clone, newsk, req);
 }
 
+/**
+ * security_inet_conn_established() - Update sock's LSM state with connection
+ * @sk: sock
+ * @skb: connection packet
+ *
+ * Update @sock's LSM state to represent a new connection from @skb.
+ */
 void security_inet_conn_established(struct sock *sk,
-                       struct sk_buff *skb)
+                                   struct sk_buff *skb)
 {
        call_void_hook(inet_conn_established, sk, skb);
 }
 EXPORT_SYMBOL(security_inet_conn_established);
 
+/**
+ * security_secmark_relabel_packet() - Check if setting a secmark is allowed
+ * @secid: new secmark value
+ *
+ * Check if the process should be allowed to relabel packets to @secid.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_secmark_relabel_packet(u32 secid)
 {
        return call_int_hook(secmark_relabel_packet, 0, secid);
 }
 EXPORT_SYMBOL(security_secmark_relabel_packet);
 
+/**
+ * security_secmark_refcount_inc() - Increment the secmark labeling rule count
+ *
+ * Tells the LSM to increment the number of secmark labeling rules loaded.
+ */
 void security_secmark_refcount_inc(void)
 {
        call_void_hook(secmark_refcount_inc);
 }
 EXPORT_SYMBOL(security_secmark_refcount_inc);
 
+/**
+ * security_secmark_refcount_dec() - Decrement the secmark labeling rule count
+ *
+ * Tells the LSM to decrement the number of secmark labeling rules loaded.
+ */
 void security_secmark_refcount_dec(void)
 {
        call_void_hook(secmark_refcount_dec);
 }
 EXPORT_SYMBOL(security_secmark_refcount_dec);
 
+/**
+ * security_tun_dev_alloc_security() - Allocate a LSM blob for a TUN device
+ * @security: pointer to the LSM blob
+ *
+ * This hook allows a module to allocate a security structure for a TUN        device,
+ * returning the pointer in @security.
+ *
+ * Return: Returns a zero on success, negative values on failure.
+ */
 int security_tun_dev_alloc_security(void **security)
 {
        return call_int_hook(tun_dev_alloc_security, 0, security);
 }
 EXPORT_SYMBOL(security_tun_dev_alloc_security);
 
+/**
+ * security_tun_dev_free_security() - Free a TUN device LSM blob
+ * @security: LSM blob
+ *
+ * This hook allows a module to free the security structure for a TUN device.
+ */
 void security_tun_dev_free_security(void *security)
 {
        call_void_hook(tun_dev_free_security, security);
 }
 EXPORT_SYMBOL(security_tun_dev_free_security);
 
+/**
+ * security_tun_dev_create() - Check if creating a TUN device is allowed
+ *
+ * Check permissions prior to creating a new TUN device.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_tun_dev_create(void)
 {
        return call_int_hook(tun_dev_create, 0);
 }
 EXPORT_SYMBOL(security_tun_dev_create);
 
+/**
+ * security_tun_dev_attach_queue() - Check if attaching a TUN queue is allowed
+ * @security: TUN device LSM blob
+ *
+ * Check permissions prior to attaching to a TUN device queue.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_tun_dev_attach_queue(void *security)
 {
        return call_int_hook(tun_dev_attach_queue, 0, security);
 }
 EXPORT_SYMBOL(security_tun_dev_attach_queue);
 
+/**
+ * security_tun_dev_attach() - Update TUN device LSM state on attach
+ * @sk: associated sock
+ * @security: TUN device LSM blob
+ *
+ * This hook can be used by the module to update any security state associated
+ * with the TUN device's sock structure.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_tun_dev_attach(struct sock *sk, void *security)
 {
        return call_int_hook(tun_dev_attach, 0, sk, security);
 }
 EXPORT_SYMBOL(security_tun_dev_attach);
 
+/**
+ * security_tun_dev_open() - Update TUN device LSM state on open
+ * @security: TUN device LSM blob
+ *
+ * This hook can be used by the module to update any security state associated
+ * with the TUN device's security structure.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_tun_dev_open(void *security)
 {
        return call_int_hook(tun_dev_open, 0, security);
 }
 EXPORT_SYMBOL(security_tun_dev_open);
 
-int security_sctp_assoc_request(struct sctp_association *asoc, struct sk_buff *skb)
+/**
+ * security_sctp_assoc_request() - Update the LSM on a SCTP association req
+ * @asoc: SCTP association
+ * @skb: packet requesting the association
+ *
+ * Passes the @asoc and @chunk->skb of the association INIT packet to the LSM.
+ *
+ * Return: Returns 0 on success, error on failure.
+ */
+int security_sctp_assoc_request(struct sctp_association *asoc,
+                               struct sk_buff *skb)
 {
        return call_int_hook(sctp_assoc_request, 0, asoc, skb);
 }
 EXPORT_SYMBOL(security_sctp_assoc_request);
 
+/**
+ * security_sctp_bind_connect() - Validate a list of addrs for a SCTP option
+ * @sk: socket
+ * @optname: SCTP option to validate
+ * @address: list of IP addresses to validate
+ * @addrlen: length of the address list
+ *
+ * Validiate permissions required for each address associated with sock        @sk.
+ * Depending on @optname, the addresses will be treated as either a connect or
+ * bind service. The @addrlen is calculated on each IPv4 and IPv6 address using
+ * sizeof(struct sockaddr_in) or sizeof(struct sockaddr_in6).
+ *
+ * Return: Returns 0 on success, error on failure.
+ */
 int security_sctp_bind_connect(struct sock *sk, int optname,
                               struct sockaddr *address, int addrlen)
 {
@@ -2480,6 +4633,16 @@ int security_sctp_bind_connect(struct sock *sk, int optname,
 }
 EXPORT_SYMBOL(security_sctp_bind_connect);
 
+/**
+ * security_sctp_sk_clone() - Clone a SCTP sock's LSM state
+ * @asoc: SCTP association
+ * @sk: original sock
+ * @newsk: target sock
+ *
+ * Called whenever a new socket is created by accept(2) (i.e. a TCP style
+ * socket) or when a socket is 'peeled off' e.g userspace calls
+ * sctp_peeloff(3).
+ */
 void security_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk,
                            struct sock *newsk)
 {
@@ -2487,6 +4650,16 @@ void security_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk,
 }
 EXPORT_SYMBOL(security_sctp_sk_clone);
 
+/**
+ * security_sctp_assoc_established() - Update LSM state when assoc established
+ * @asoc: SCTP association
+ * @skb: packet establishing the association
+ *
+ * Passes the @asoc and @chunk->skb of the association COOKIE_ACK packet to the
+ * security module.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_sctp_assoc_established(struct sctp_association *asoc,
                                    struct sk_buff *skb)
 {
@@ -2497,25 +4670,60 @@ EXPORT_SYMBOL(security_sctp_assoc_established);
 #endif /* CONFIG_SECURITY_NETWORK */
 
 #ifdef CONFIG_SECURITY_INFINIBAND
-
+/**
+ * security_ib_pkey_access() - Check if access to an IB pkey is allowed
+ * @sec: LSM blob
+ * @subnet_prefix: subnet prefix of the port
+ * @pkey: IB pkey
+ *
+ * Check permission to access a pkey when modifing a QP.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_ib_pkey_access(void *sec, u64 subnet_prefix, u16 pkey)
 {
        return call_int_hook(ib_pkey_access, 0, sec, subnet_prefix, pkey);
 }
 EXPORT_SYMBOL(security_ib_pkey_access);
 
-int security_ib_endport_manage_subnet(void *sec, const char *dev_name, u8 port_num)
+/**
+ * security_ib_endport_manage_subnet() - Check if SMPs traffic is allowed
+ * @sec: LSM blob
+ * @dev_name: IB device name
+ * @port_num: port number
+ *
+ * Check permissions to send and receive SMPs on a end port.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
+int security_ib_endport_manage_subnet(void *sec,
+                                     const char *dev_name, u8 port_num)
 {
-       return call_int_hook(ib_endport_manage_subnet, 0, sec, dev_name, port_num);
+       return call_int_hook(ib_endport_manage_subnet, 0, sec,
+                            dev_name, port_num);
 }
 EXPORT_SYMBOL(security_ib_endport_manage_subnet);
 
+/**
+ * security_ib_alloc_security() - Allocate an Infiniband LSM blob
+ * @sec: LSM blob
+ *
+ * Allocate a security structure for Infiniband objects.
+ *
+ * Return: Returns 0 on success, non-zero on failure.
+ */
 int security_ib_alloc_security(void **sec)
 {
        return call_int_hook(ib_alloc_security, 0, sec);
 }
 EXPORT_SYMBOL(security_ib_alloc_security);
 
+/**
+ * security_ib_free_security() - Free an Infiniband LSM blob
+ * @sec: LSM blob
+ *
+ * Deallocate an Infiniband security structure.
+ */
 void security_ib_free_security(void *sec)
 {
        call_void_hook(ib_free_security, sec);
@@ -2524,7 +4732,17 @@ EXPORT_SYMBOL(security_ib_free_security);
 #endif /* CONFIG_SECURITY_INFINIBAND */
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
-
+/**
+ * security_xfrm_policy_alloc() - Allocate a xfrm policy LSM blob
+ * @ctxp: xfrm security context being added to the SPD
+ * @sec_ctx: security label provided by userspace
+ * @gfp: gfp flags
+ *
+ * Allocate a security structure to the xp->security field; the security field
+ * is initialized to NULL when the xfrm_policy is allocated.
+ *
+ * Return:  Return 0 if operation was successful.
+ */
 int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
                               struct xfrm_user_sec_ctx *sec_ctx,
                               gfp_t gfp)
@@ -2533,23 +4751,58 @@ int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
 }
 EXPORT_SYMBOL(security_xfrm_policy_alloc);
 
+/**
+ * security_xfrm_policy_clone() - Clone xfrm policy LSM state
+ * @old_ctx: xfrm security context
+ * @new_ctxp: target xfrm security context
+ *
+ * Allocate a security structure in new_ctxp that contains the information from
+ * the old_ctx structure.
+ *
+ * Return: Return 0 if operation was successful.
+ */
 int security_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
-                             struct xfrm_sec_ctx **new_ctxp)
+                              struct xfrm_sec_ctx **new_ctxp)
 {
        return call_int_hook(xfrm_policy_clone_security, 0, old_ctx, new_ctxp);
 }
 
+/**
+ * security_xfrm_policy_free() - Free a xfrm security context
+ * @ctx: xfrm security context
+ *
+ * Free LSM resources associated with @ctx.
+ */
 void security_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
 {
        call_void_hook(xfrm_policy_free_security, ctx);
 }
 EXPORT_SYMBOL(security_xfrm_policy_free);
 
+/**
+ * security_xfrm_policy_delete() - Check if deleting a xfrm policy is allowed
+ * @ctx: xfrm security context
+ *
+ * Authorize deletion of a SPD entry.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
 {
        return call_int_hook(xfrm_policy_delete_security, 0, ctx);
 }
 
+/**
+ * security_xfrm_state_alloc() - Allocate a xfrm state LSM blob
+ * @x: xfrm state being added to the SAD
+ * @sec_ctx: security label provided by userspace
+ *
+ * Allocate a security structure to the @x->security field; the security field
+ * is initialized to NULL when the xfrm_state is allocated. Set the context to
+ * correspond to @sec_ctx.
+ *
+ * Return: Return 0 if operation was successful.
+ */
 int security_xfrm_state_alloc(struct xfrm_state *x,
                              struct xfrm_user_sec_ctx *sec_ctx)
 {
@@ -2557,28 +4810,76 @@ int security_xfrm_state_alloc(struct xfrm_state *x,
 }
 EXPORT_SYMBOL(security_xfrm_state_alloc);
 
+/**
+ * security_xfrm_state_alloc_acquire() - Allocate a xfrm state LSM blob
+ * @x: xfrm state being added to the SAD
+ * @polsec: associated policy's security context
+ * @secid: secid from the flow
+ *
+ * Allocate a security structure to the x->security field; the security field
+ * is initialized to NULL when the xfrm_state is allocated.  Set the context to
+ * correspond to secid.
+ *
+ * Return: Returns 0 if operation was successful.
+ */
 int security_xfrm_state_alloc_acquire(struct xfrm_state *x,
                                      struct xfrm_sec_ctx *polsec, u32 secid)
 {
        return call_int_hook(xfrm_state_alloc_acquire, 0, x, polsec, secid);
 }
 
+/**
+ * security_xfrm_state_delete() - Check if deleting a xfrm state is allowed
+ * @x: xfrm state
+ *
+ * Authorize deletion of x->security.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_xfrm_state_delete(struct xfrm_state *x)
 {
        return call_int_hook(xfrm_state_delete_security, 0, x);
 }
 EXPORT_SYMBOL(security_xfrm_state_delete);
 
+/**
+ * security_xfrm_state_free() - Free a xfrm state
+ * @x: xfrm state
+ *
+ * Deallocate x->security.
+ */
 void security_xfrm_state_free(struct xfrm_state *x)
 {
        call_void_hook(xfrm_state_free_security, x);
 }
 
+/**
+ * security_xfrm_policy_lookup() - Check if using a xfrm policy is allowed
+ * @ctx: target xfrm security context
+ * @fl_secid: flow secid used to authorize access
+ *
+ * Check permission when a flow selects a xfrm_policy for processing XFRMs on a
+ * packet.  The hook is called when selecting either a per-socket policy or a
+ * generic xfrm policy.
+ *
+ * Return: Return 0 if permission is granted, -ESRCH otherwise, or -errno on
+ *         other errors.
+ */
 int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid)
 {
        return call_int_hook(xfrm_policy_lookup, 0, ctx, fl_secid);
 }
 
+/**
+ * security_xfrm_state_pol_flow_match() - Check for a xfrm match
+ * @x: xfrm state to match
+ * @xp: xfrm policy to check for a match
+ * @flic: flow to check for a match.
+ *
+ * Check @xp and @flic for a match with @x.
+ *
+ * Return: Returns 1 if there is a match.
+ */
 int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
                                       struct xfrm_policy *xp,
                                       const struct flowi_common *flic)
@@ -2596,13 +4897,22 @@ int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
         * using the macro
         */
        hlist_for_each_entry(hp, &security_hook_heads.xfrm_state_pol_flow_match,
-                               list) {
+                            list) {
                rc = hp->hook.xfrm_state_pol_flow_match(x, xp, flic);
                break;
        }
        return rc;
 }
 
+/**
+ * security_xfrm_decode_session() - Determine the xfrm secid for a packet
+ * @skb: xfrm packet
+ * @secid: secid
+ *
+ * Decode the packet in @skb and return the security label in @secid.
+ *
+ * Return: Return 0 if all xfrms used have the same secid.
+ */
 int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid)
 {
        return call_int_hook(xfrm_decode_session, 0, skb, secid, 1);
@@ -2611,58 +4921,135 @@ int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid)
 void security_skb_classify_flow(struct sk_buff *skb, struct flowi_common *flic)
 {
        int rc = call_int_hook(xfrm_decode_session, 0, skb, &flic->flowic_secid,
-                               0);
+                              0);
 
        BUG_ON(rc);
 }
 EXPORT_SYMBOL(security_skb_classify_flow);
-
 #endif /* CONFIG_SECURITY_NETWORK_XFRM */
 
 #ifdef CONFIG_KEYS
-
+/**
+ * security_key_alloc() - Allocate and initialize a kernel key LSM blob
+ * @key: key
+ * @cred: credentials
+ * @flags: allocation flags
+ *
+ * Permit allocation of a key and assign security data. Note that key does not
+ * have a serial number assigned at this point.
+ *
+ * Return: Return 0 if permission is granted, -ve error otherwise.
+ */
 int security_key_alloc(struct key *key, const struct cred *cred,
                       unsigned long flags)
 {
        return call_int_hook(key_alloc, 0, key, cred, flags);
 }
 
+/**
+ * security_key_free() - Free a kernel key LSM blob
+ * @key: key
+ *
+ * Notification of destruction; free security data.
+ */
 void security_key_free(struct key *key)
 {
        call_void_hook(key_free, key);
 }
 
+/**
+ * security_key_permission() - Check if a kernel key operation is allowed
+ * @key_ref: key reference
+ * @cred: credentials of actor requesting access
+ * @need_perm: requested permissions
+ *
+ * See whether a specific operational right is granted to a process on a key.
+ *
+ * Return: Return 0 if permission is granted, -ve error otherwise.
+ */
 int security_key_permission(key_ref_t key_ref, const struct cred *cred,
                            enum key_need_perm need_perm)
 {
        return call_int_hook(key_permission, 0, key_ref, cred, need_perm);
 }
 
-int security_key_getsecurity(struct key *key, char **_buffer)
+/**
+ * security_key_getsecurity() - Get the key's security label
+ * @key: key
+ * @buffer: security label buffer
+ *
+ * Get a textual representation of the security context attached to a key for
+ * the purposes of honouring KEYCTL_GETSECURITY.  This function allocates the
+ * storage for the NUL-terminated string and the caller should free it.
+ *
+ * Return: Returns the length of @buffer (including terminating NUL) or -ve if
+ *         an error occurs.  May also return 0 (and a NULL buffer pointer) if
+ *         there is no security label assigned to the key.
+ */
+int security_key_getsecurity(struct key *key, char **buffer)
 {
-       *_buffer = NULL;
-       return call_int_hook(key_getsecurity, 0, key, _buffer);
+       *buffer = NULL;
+       return call_int_hook(key_getsecurity, 0, key, buffer);
 }
-
 #endif /* CONFIG_KEYS */
 
 #ifdef CONFIG_AUDIT
-
+/**
+ * security_audit_rule_init() - Allocate and init an LSM audit rule struct
+ * @field: audit action
+ * @op: rule operator
+ * @rulestr: rule context
+ * @lsmrule: receive buffer for audit rule struct
+ *
+ * Allocate and initialize an LSM audit rule structure.
+ *
+ * Return: Return 0 if @lsmrule has been successfully set, -EINVAL in case of
+ *         an invalid rule.
+ */
 int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule)
 {
        return call_int_hook(audit_rule_init, 0, field, op, rulestr, lsmrule);
 }
 
+/**
+ * security_audit_rule_known() - Check if an audit rule contains LSM fields
+ * @krule: audit rule
+ *
+ * Specifies whether given @krule contains any fields related to the current
+ * LSM.
+ *
+ * Return: Returns 1 in case of relation found, 0 otherwise.
+ */
 int security_audit_rule_known(struct audit_krule *krule)
 {
        return call_int_hook(audit_rule_known, 0, krule);
 }
 
+/**
+ * security_audit_rule_free() - Free an LSM audit rule struct
+ * @lsmrule: audit rule struct
+ *
+ * Deallocate the LSM audit rule structure previously allocated by
+ * audit_rule_init().
+ */
 void security_audit_rule_free(void *lsmrule)
 {
        call_void_hook(audit_rule_free, lsmrule);
 }
 
+/**
+ * security_audit_rule_match() - Check if a label matches an audit rule
+ * @secid: security label
+ * @field: LSM audit field
+ * @op: matching operator
+ * @lsmrule: audit rule
+ *
+ * Determine if given @secid matches a rule previously approved by
+ * security_audit_rule_known().
+ *
+ * Return: Returns 1 if secid matches the rule, 0 if it does not, -ERRNO on
+ *         failure.
+ */
 int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule)
 {
        return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule);
@@ -2670,36 +5057,110 @@ int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule)
 #endif /* CONFIG_AUDIT */
 
 #ifdef CONFIG_BPF_SYSCALL
+/**
+ * security_bpf() - Check if the bpf syscall operation is allowed
+ * @cmd: command
+ * @attr: bpf attribute
+ * @size: size
+ *
+ * Do a initial check for all bpf syscalls after the attribute is copied into
+ * the kernel. The actual security module can implement their own rules to
+ * check the specific cmd they need.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_bpf(int cmd, union bpf_attr *attr, unsigned int size)
 {
        return call_int_hook(bpf, 0, cmd, attr, size);
 }
+
+/**
+ * security_bpf_map() - Check if access to a bpf map is allowed
+ * @map: bpf map
+ * @fmode: mode
+ *
+ * Do a check when the kernel generates and returns a file descriptor for eBPF
+ * maps.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_bpf_map(struct bpf_map *map, fmode_t fmode)
 {
        return call_int_hook(bpf_map, 0, map, fmode);
 }
+
+/**
+ * security_bpf_prog() - Check if access to a bpf program is allowed
+ * @prog: bpf program
+ *
+ * Do a check when the kernel generates and returns a file descriptor for eBPF
+ * programs.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_bpf_prog(struct bpf_prog *prog)
 {
        return call_int_hook(bpf_prog, 0, prog);
 }
+
+/**
+ * security_bpf_map_alloc() - Allocate a bpf map LSM blob
+ * @map: bpf map
+ *
+ * Initialize the security field inside bpf map.
+ *
+ * Return: Returns 0 on success, error on failure.
+ */
 int security_bpf_map_alloc(struct bpf_map *map)
 {
        return call_int_hook(bpf_map_alloc_security, 0, map);
 }
+
+/**
+ * security_bpf_prog_alloc() - Allocate a bpf program LSM blob
+ * @aux: bpf program aux info struct
+ *
+ * Initialize the security field inside bpf program.
+ *
+ * Return: Returns 0 on success, error on failure.
+ */
 int security_bpf_prog_alloc(struct bpf_prog_aux *aux)
 {
        return call_int_hook(bpf_prog_alloc_security, 0, aux);
 }
+
+/**
+ * security_bpf_map_free() - Free a bpf map's LSM blob
+ * @map: bpf map
+ *
+ * Clean up the security information stored inside bpf map.
+ */
 void security_bpf_map_free(struct bpf_map *map)
 {
        call_void_hook(bpf_map_free_security, map);
 }
+
+/**
+ * security_bpf_prog_free() - Free a bpf program's LSM blob
+ * @aux: bpf program aux info struct
+ *
+ * Clean up the security information stored inside bpf prog.
+ */
 void security_bpf_prog_free(struct bpf_prog_aux *aux)
 {
        call_void_hook(bpf_prog_free_security, aux);
 }
 #endif /* CONFIG_BPF_SYSCALL */
 
+/**
+ * security_locked_down() - Check if a kernel feature is allowed
+ * @what: requested kernel feature
+ *
+ * Determine whether a kernel feature that potentially enables arbitrary code
+ * execution in kernel space should be permitted.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_locked_down(enum lockdown_reason what)
 {
        return call_int_hook(locked_down, 0, what);
@@ -2707,26 +5168,65 @@ int security_locked_down(enum lockdown_reason what)
 EXPORT_SYMBOL(security_locked_down);
 
 #ifdef CONFIG_PERF_EVENTS
+/**
+ * security_perf_event_open() - Check if a perf event open is allowed
+ * @attr: perf event attribute
+ * @type: type of event
+ *
+ * Check whether the @type of perf_event_open syscall is allowed.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_perf_event_open(struct perf_event_attr *attr, int type)
 {
        return call_int_hook(perf_event_open, 0, attr, type);
 }
 
+/**
+ * security_perf_event_alloc() - Allocate a perf event LSM blob
+ * @event: perf event
+ *
+ * Allocate and save perf_event security info.
+ *
+ * Return: Returns 0 on success, error on failure.
+ */
 int security_perf_event_alloc(struct perf_event *event)
 {
        return call_int_hook(perf_event_alloc, 0, event);
 }
 
+/**
+ * security_perf_event_free() - Free a perf event LSM blob
+ * @event: perf event
+ *
+ * Release (free) perf_event security info.
+ */
 void security_perf_event_free(struct perf_event *event)
 {
        call_void_hook(perf_event_free, event);
 }
 
+/**
+ * security_perf_event_read() - Check if reading a perf event label is allowed
+ * @event: perf event
+ *
+ * Read perf_event security info if allowed.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_perf_event_read(struct perf_event *event)
 {
        return call_int_hook(perf_event_read, 0, event);
 }
 
+/**
+ * security_perf_event_write() - Check if writing a perf event label is allowed
+ * @event: perf event
+ *
+ * Write perf_event security info if allowed.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_perf_event_write(struct perf_event *event)
 {
        return call_int_hook(perf_event_write, 0, event);
@@ -2734,15 +5234,41 @@ int security_perf_event_write(struct perf_event *event)
 #endif /* CONFIG_PERF_EVENTS */
 
 #ifdef CONFIG_IO_URING
+/**
+ * security_uring_override_creds() - Check if overriding creds is allowed
+ * @new: new credentials
+ *
+ * Check if the current task, executing an io_uring operation, is allowed to
+ * override it's credentials with @new.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_uring_override_creds(const struct cred *new)
 {
        return call_int_hook(uring_override_creds, 0, new);
 }
 
+/**
+ * security_uring_sqpoll() - Check if IORING_SETUP_SQPOLL is allowed
+ *
+ * Check whether the current task is allowed to spawn a io_uring polling thread
+ * (IORING_SETUP_SQPOLL).
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_uring_sqpoll(void)
 {
        return call_int_hook(uring_sqpoll, 0);
 }
+
+/**
+ * security_uring_cmd() - Check if a io_uring passthrough command is allowed
+ * @ioucmd: command
+ *
+ * Check whether the file_operations uring_cmd is allowed to run.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
 int security_uring_cmd(struct io_uring_cmd *ioucmd)
 {
        return call_int_hook(uring_cmd, 0, ioucmd);
index 9e921fc725386ed9c79511012a2679b6ecb52bb1..95a186ec0fcb70beb5f510563c3711ab5eb7ee7a 100644 (file)
@@ -23,30 +23,6 @@ config SECURITY_SELINUX_BOOTPARAM
 
          If you are unsure how to answer this question, answer N.
 
-config SECURITY_SELINUX_DISABLE
-       bool "NSA SELinux runtime disable"
-       depends on SECURITY_SELINUX
-       select SECURITY_WRITABLE_HOOKS
-       default n
-       help
-         This option enables writing to a selinuxfs node 'disable', which
-         allows SELinux to be disabled at runtime prior to the policy load.
-         SELinux will then remain disabled until the next boot.
-         This option is similar to the selinux=0 boot parameter, but is to
-         support runtime disabling of SELinux, e.g. from /sbin/init, for
-         portability across platforms where boot parameters are difficult
-         to employ.
-
-         NOTE: selecting this option will disable the '__ro_after_init'
-         kernel hardening feature for security hooks.   Please consider
-         using the selinux=0 boot parameter instead of enabling this
-         option.
-
-         WARNING: this option is deprecated and will be removed in a future
-         kernel release.
-
-         If you are unsure how to answer this question, answer N.
-
 config SECURITY_SELINUX_DEVELOP
        bool "NSA SELinux Development Support"
        depends on SECURITY_SELINUX
@@ -70,29 +46,6 @@ config SECURITY_SELINUX_AVC_STATS
          /sys/fs/selinux/avc/cache_stats, which may be monitored via
          tools such as avcstat.
 
-config SECURITY_SELINUX_CHECKREQPROT_VALUE
-       int "NSA SELinux checkreqprot default value"
-       depends on SECURITY_SELINUX
-       range 0 1
-       default 0
-       help
-         This option sets the default value for the 'checkreqprot' flag
-         that determines whether SELinux checks the protection requested
-         by the application or the protection that will be applied by the
-         kernel (including any implied execute for read-implies-exec) for
-         mmap and mprotect calls.  If this option is set to 0 (zero),
-         SELinux will default to checking the protection that will be applied
-         by the kernel.  If this option is set to 1 (one), SELinux will
-         default to checking the protection requested by the application.
-         The checkreqprot flag may be changed from the default via the
-         'checkreqprot=' boot parameter.  It may also be changed at runtime
-         via /sys/fs/selinux/checkreqprot if authorized by policy.
-
-         WARNING: this option is deprecated and will be removed in a future
-         kernel release.
-
-         If you are unsure how to answer this question, answer 0.
-
 config SECURITY_SELINUX_SIDTAB_HASH_BITS
        int "NSA SELinux sidtab hashtable size"
        depends on SECURITY_SELINUX
index 77616244488264e697cf82e3c2582c5a0b17adad..0aecf9334ec31e9df00fd5d81a06dc202a66327e 100644 (file)
@@ -23,8 +23,8 @@ ccflags-y := -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include
 $(addprefix $(obj)/,$(selinux-y)): $(obj)/flask.h
 
 quiet_cmd_flask = GEN     $(obj)/flask.h $(obj)/av_permissions.h
-      cmd_flask = scripts/selinux/genheaders/genheaders $(obj)/flask.h $(obj)/av_permissions.h
+      cmd_flask = $< $(obj)/flask.h $(obj)/av_permissions.h
 
 targets += flask.h av_permissions.h
-$(obj)/flask.h: $(src)/include/classmap.h FORCE
+$(obj)/flask.h $(obj)/av_permissions.h &: scripts/selinux/genheaders/genheaders FORCE
        $(call if_changed,flask)
index 9a43af0ebd7de7685f557a8d1ebb54153c3f5938..eaed5c2da02b34d4ae4ce10f32722a1adb1dd637 100644 (file)
@@ -93,7 +93,7 @@ struct selinux_avc {
 
 static struct selinux_avc selinux_avc;
 
-void selinux_avc_init(struct selinux_avc **avc)
+void selinux_avc_init(void)
 {
        int i;
 
@@ -104,18 +104,16 @@ void selinux_avc_init(struct selinux_avc **avc)
        }
        atomic_set(&selinux_avc.avc_cache.active_nodes, 0);
        atomic_set(&selinux_avc.avc_cache.lru_hint, 0);
-       *avc = &selinux_avc;
 }
 
-unsigned int avc_get_cache_threshold(struct selinux_avc *avc)
+unsigned int avc_get_cache_threshold(void)
 {
-       return avc->avc_cache_threshold;
+       return selinux_avc.avc_cache_threshold;
 }
 
-void avc_set_cache_threshold(struct selinux_avc *avc,
-                            unsigned int cache_threshold)
+void avc_set_cache_threshold(unsigned int cache_threshold)
 {
-       avc->avc_cache_threshold = cache_threshold;
+       selinux_avc.avc_cache_threshold = cache_threshold;
 }
 
 static struct avc_callback_node *avc_callbacks __ro_after_init;
@@ -150,7 +148,7 @@ void __init avc_init(void)
                                        0, SLAB_PANIC, NULL);
 }
 
-int avc_get_hash_stats(struct selinux_avc *avc, char *page)
+int avc_get_hash_stats(char *page)
 {
        int i, chain_len, max_chain_len, slots_used;
        struct avc_node *node;
@@ -161,7 +159,7 @@ int avc_get_hash_stats(struct selinux_avc *avc, char *page)
        slots_used = 0;
        max_chain_len = 0;
        for (i = 0; i < AVC_CACHE_SLOTS; i++) {
-               head = &avc->avc_cache.slots[i];
+               head = &selinux_avc.avc_cache.slots[i];
                if (!hlist_empty(head)) {
                        slots_used++;
                        chain_len = 0;
@@ -176,7 +174,7 @@ int avc_get_hash_stats(struct selinux_avc *avc, char *page)
 
        return scnprintf(page, PAGE_SIZE, "entries: %d\nbuckets used: %d/%d\n"
                         "longest chain: %d\n",
-                        atomic_read(&avc->avc_cache.active_nodes),
+                        atomic_read(&selinux_avc.avc_cache.active_nodes),
                         slots_used, AVC_CACHE_SLOTS, max_chain_len);
 }
 
@@ -414,8 +412,7 @@ static inline u32 avc_xperms_audit_required(u32 requested,
        return audited;
 }
 
-static inline int avc_xperms_audit(struct selinux_state *state,
-                                  u32 ssid, u32 tsid, u16 tclass,
+static inline int avc_xperms_audit(u32 ssid, u32 tsid, u16 tclass,
                                   u32 requested, struct av_decision *avd,
                                   struct extended_perms_decision *xpd,
                                   u8 perm, int result,
@@ -427,7 +424,7 @@ static inline int avc_xperms_audit(struct selinux_state *state,
                        requested, avd, xpd, perm, result, &denied);
        if (likely(!audited))
                return 0;
-       return slow_avc_audit(state, ssid, tsid, tclass, requested,
+       return slow_avc_audit(ssid, tsid, tclass, requested,
                        audited, denied, result, ad);
 }
 
@@ -439,30 +436,29 @@ static void avc_node_free(struct rcu_head *rhead)
        avc_cache_stats_incr(frees);
 }
 
-static void avc_node_delete(struct selinux_avc *avc, struct avc_node *node)
+static void avc_node_delete(struct avc_node *node)
 {
        hlist_del_rcu(&node->list);
        call_rcu(&node->rhead, avc_node_free);
-       atomic_dec(&avc->avc_cache.active_nodes);
+       atomic_dec(&selinux_avc.avc_cache.active_nodes);
 }
 
-static void avc_node_kill(struct selinux_avc *avc, struct avc_node *node)
+static void avc_node_kill(struct avc_node *node)
 {
        avc_xperms_free(node->ae.xp_node);
        kmem_cache_free(avc_node_cachep, node);
        avc_cache_stats_incr(frees);
-       atomic_dec(&avc->avc_cache.active_nodes);
+       atomic_dec(&selinux_avc.avc_cache.active_nodes);
 }
 
-static void avc_node_replace(struct selinux_avc *avc,
-                            struct avc_node *new, struct avc_node *old)
+static void avc_node_replace(struct avc_node *new, struct avc_node *old)
 {
        hlist_replace_rcu(&old->list, &new->list);
        call_rcu(&old->rhead, avc_node_free);
-       atomic_dec(&avc->avc_cache.active_nodes);
+       atomic_dec(&selinux_avc.avc_cache.active_nodes);
 }
 
-static inline int avc_reclaim_node(struct selinux_avc *avc)
+static inline int avc_reclaim_node(void)
 {
        struct avc_node *node;
        int hvalue, try, ecx;
@@ -471,17 +467,17 @@ static inline int avc_reclaim_node(struct selinux_avc *avc)
        spinlock_t *lock;
 
        for (try = 0, ecx = 0; try < AVC_CACHE_SLOTS; try++) {
-               hvalue = atomic_inc_return(&avc->avc_cache.lru_hint) &
+               hvalue = atomic_inc_return(&selinux_avc.avc_cache.lru_hint) &
                        (AVC_CACHE_SLOTS - 1);
-               head = &avc->avc_cache.slots[hvalue];
-               lock = &avc->avc_cache.slots_lock[hvalue];
+               head = &selinux_avc.avc_cache.slots[hvalue];
+               lock = &selinux_avc.avc_cache.slots_lock[hvalue];
 
                if (!spin_trylock_irqsave(lock, flags))
                        continue;
 
                rcu_read_lock();
                hlist_for_each_entry(node, head, list) {
-                       avc_node_delete(avc, node);
+                       avc_node_delete(node);
                        avc_cache_stats_incr(reclaims);
                        ecx++;
                        if (ecx >= AVC_CACHE_RECLAIM) {
@@ -497,7 +493,7 @@ out:
        return ecx;
 }
 
-static struct avc_node *avc_alloc_node(struct selinux_avc *avc)
+static struct avc_node *avc_alloc_node(void)
 {
        struct avc_node *node;
 
@@ -508,9 +504,9 @@ static struct avc_node *avc_alloc_node(struct selinux_avc *avc)
        INIT_HLIST_NODE(&node->list);
        avc_cache_stats_incr(allocations);
 
-       if (atomic_inc_return(&avc->avc_cache.active_nodes) >
-           avc->avc_cache_threshold)
-               avc_reclaim_node(avc);
+       if (atomic_inc_return(&selinux_avc.avc_cache.active_nodes) >
+           selinux_avc.avc_cache_threshold)
+               avc_reclaim_node();
 
 out:
        return node;
@@ -524,15 +520,14 @@ static void avc_node_populate(struct avc_node *node, u32 ssid, u32 tsid, u16 tcl
        memcpy(&node->ae.avd, avd, sizeof(node->ae.avd));
 }
 
-static inline struct avc_node *avc_search_node(struct selinux_avc *avc,
-                                              u32 ssid, u32 tsid, u16 tclass)
+static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid, u16 tclass)
 {
        struct avc_node *node, *ret = NULL;
        int hvalue;
        struct hlist_head *head;
 
        hvalue = avc_hash(ssid, tsid, tclass);
-       head = &avc->avc_cache.slots[hvalue];
+       head = &selinux_avc.avc_cache.slots[hvalue];
        hlist_for_each_entry_rcu(node, head, list) {
                if (ssid == node->ae.ssid &&
                    tclass == node->ae.tclass &&
@@ -547,7 +542,6 @@ static inline struct avc_node *avc_search_node(struct selinux_avc *avc,
 
 /**
  * avc_lookup - Look up an AVC entry.
- * @avc: the access vector cache
  * @ssid: source security identifier
  * @tsid: target security identifier
  * @tclass: target security class
@@ -558,13 +552,12 @@ static inline struct avc_node *avc_search_node(struct selinux_avc *avc,
  * then this function returns the avc_node.
  * Otherwise, this function returns NULL.
  */
-static struct avc_node *avc_lookup(struct selinux_avc *avc,
-                                  u32 ssid, u32 tsid, u16 tclass)
+static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass)
 {
        struct avc_node *node;
 
        avc_cache_stats_incr(lookups);
-       node = avc_search_node(avc, ssid, tsid, tclass);
+       node = avc_search_node(ssid, tsid, tclass);
 
        if (node)
                return node;
@@ -573,8 +566,7 @@ static struct avc_node *avc_lookup(struct selinux_avc *avc,
        return NULL;
 }
 
-static int avc_latest_notif_update(struct selinux_avc *avc,
-                                  int seqno, int is_insert)
+static int avc_latest_notif_update(int seqno, int is_insert)
 {
        int ret = 0;
        static DEFINE_SPINLOCK(notif_lock);
@@ -582,14 +574,14 @@ static int avc_latest_notif_update(struct selinux_avc *avc,
 
        spin_lock_irqsave(&notif_lock, flag);
        if (is_insert) {
-               if (seqno < avc->avc_cache.latest_notif) {
+               if (seqno < selinux_avc.avc_cache.latest_notif) {
                        pr_warn("SELinux: avc:  seqno %d < latest_notif %d\n",
-                              seqno, avc->avc_cache.latest_notif);
+                              seqno, selinux_avc.avc_cache.latest_notif);
                        ret = -EAGAIN;
                }
        } else {
-               if (seqno > avc->avc_cache.latest_notif)
-                       avc->avc_cache.latest_notif = seqno;
+               if (seqno > selinux_avc.avc_cache.latest_notif)
+                       selinux_avc.avc_cache.latest_notif = seqno;
        }
        spin_unlock_irqrestore(&notif_lock, flag);
 
@@ -598,7 +590,6 @@ static int avc_latest_notif_update(struct selinux_avc *avc,
 
 /**
  * avc_insert - Insert an AVC entry.
- * @avc: the access vector cache
  * @ssid: source security identifier
  * @tsid: target security identifier
  * @tclass: target security class
@@ -612,13 +603,10 @@ static int avc_latest_notif_update(struct selinux_avc *avc,
  * response to a security_compute_av() call.  If the
  * sequence number @avd->seqno is not less than the latest
  * revocation notification, then the function copies
- * the access vectors into a cache entry, returns
- * avc_node inserted. Otherwise, this function returns NULL.
+ * the access vectors into a cache entry.
  */
-static struct avc_node *avc_insert(struct selinux_avc *avc,
-                                  u32 ssid, u32 tsid, u16 tclass,
-                                  struct av_decision *avd,
-                                  struct avc_xperms_node *xp_node)
+static void avc_insert(u32 ssid, u32 tsid, u16 tclass,
+                      struct av_decision *avd, struct avc_xperms_node *xp_node)
 {
        struct avc_node *pos, *node = NULL;
        int hvalue;
@@ -626,35 +614,35 @@ static struct avc_node *avc_insert(struct selinux_avc *avc,
        spinlock_t *lock;
        struct hlist_head *head;
 
-       if (avc_latest_notif_update(avc, avd->seqno, 1))
-               return NULL;
+       if (avc_latest_notif_update(avd->seqno, 1))
+               return;
 
-       node = avc_alloc_node(avc);
+       node = avc_alloc_node();
        if (!node)
-               return NULL;
+               return;
 
        avc_node_populate(node, ssid, tsid, tclass, avd);
        if (avc_xperms_populate(node, xp_node)) {
-               avc_node_kill(avc, node);
-               return NULL;
+               avc_node_kill(node);
+               return;
        }
 
        hvalue = avc_hash(ssid, tsid, tclass);
-       head = &avc->avc_cache.slots[hvalue];
-       lock = &avc->avc_cache.slots_lock[hvalue];
+       head = &selinux_avc.avc_cache.slots[hvalue];
+       lock = &selinux_avc.avc_cache.slots_lock[hvalue];
        spin_lock_irqsave(lock, flag);
        hlist_for_each_entry(pos, head, list) {
                if (pos->ae.ssid == ssid &&
                        pos->ae.tsid == tsid &&
                        pos->ae.tclass == tclass) {
-                       avc_node_replace(avc, node, pos);
+                       avc_node_replace(node, pos);
                        goto found;
                }
        }
        hlist_add_head_rcu(&node->list, head);
 found:
        spin_unlock_irqrestore(lock, flag);
-       return node;
+       return;
 }
 
 /**
@@ -715,14 +703,14 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
        u32 tcontext_len;
        int rc;
 
-       rc = security_sid_to_context(sad->state, sad->ssid, &scontext,
+       rc = security_sid_to_context(sad->ssid, &scontext,
                                     &scontext_len);
        if (rc)
                audit_log_format(ab, " ssid=%d", sad->ssid);
        else
                audit_log_format(ab, " scontext=%s", scontext);
 
-       rc = security_sid_to_context(sad->state, sad->tsid, &tcontext,
+       rc = security_sid_to_context(sad->tsid, &tcontext,
                                     &tcontext_len);
        if (rc)
                audit_log_format(ab, " tsid=%d", sad->tsid);
@@ -740,7 +728,7 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
        kfree(scontext);
 
        /* in case of invalid context report also the actual context string */
-       rc = security_sid_to_context_inval(sad->state, sad->ssid, &scontext,
+       rc = security_sid_to_context_inval(sad->ssid, &scontext,
                                           &scontext_len);
        if (!rc && scontext) {
                if (scontext_len && scontext[scontext_len - 1] == '\0')
@@ -750,7 +738,7 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
                kfree(scontext);
        }
 
-       rc = security_sid_to_context_inval(sad->state, sad->tsid, &scontext,
+       rc = security_sid_to_context_inval(sad->tsid, &scontext,
                                           &scontext_len);
        if (!rc && scontext) {
                if (scontext_len && scontext[scontext_len - 1] == '\0')
@@ -766,8 +754,7 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
  * Note that it is non-blocking and can be called from under
  * rcu_read_lock().
  */
-noinline int slow_avc_audit(struct selinux_state *state,
-                           u32 ssid, u32 tsid, u16 tclass,
+noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
                            u32 requested, u32 audited, u32 denied, int result,
                            struct common_audit_data *a)
 {
@@ -789,7 +776,6 @@ noinline int slow_avc_audit(struct selinux_state *state,
        sad.audited = audited;
        sad.denied = denied;
        sad.result = result;
-       sad.state = state;
 
        a->selinux_audit_data = &sad;
 
@@ -827,7 +813,6 @@ out:
 
 /**
  * avc_update_node - Update an AVC entry
- * @avc: the access vector cache
  * @event : Updating event
  * @perms : Permission mask bits
  * @driver: xperm driver information
@@ -844,8 +829,7 @@ out:
  * otherwise, this function updates the AVC entry. The original AVC-entry object
  * will release later by RCU.
  */
-static int avc_update_node(struct selinux_avc *avc,
-                          u32 event, u32 perms, u8 driver, u8 xperm, u32 ssid,
+static int avc_update_node(u32 event, u32 perms, u8 driver, u8 xperm, u32 ssid,
                           u32 tsid, u16 tclass, u32 seqno,
                           struct extended_perms_decision *xpd,
                           u32 flags)
@@ -856,7 +840,7 @@ static int avc_update_node(struct selinux_avc *avc,
        struct hlist_head *head;
        spinlock_t *lock;
 
-       node = avc_alloc_node(avc);
+       node = avc_alloc_node();
        if (!node) {
                rc = -ENOMEM;
                goto out;
@@ -865,8 +849,8 @@ static int avc_update_node(struct selinux_avc *avc,
        /* Lock the target slot */
        hvalue = avc_hash(ssid, tsid, tclass);
 
-       head = &avc->avc_cache.slots[hvalue];
-       lock = &avc->avc_cache.slots_lock[hvalue];
+       head = &selinux_avc.avc_cache.slots[hvalue];
+       lock = &selinux_avc.avc_cache.slots_lock[hvalue];
 
        spin_lock_irqsave(lock, flag);
 
@@ -882,7 +866,7 @@ static int avc_update_node(struct selinux_avc *avc,
 
        if (!orig) {
                rc = -ENOENT;
-               avc_node_kill(avc, node);
+               avc_node_kill(node);
                goto out_unlock;
        }
 
@@ -895,7 +879,7 @@ static int avc_update_node(struct selinux_avc *avc,
        if (orig->ae.xp_node) {
                rc = avc_xperms_populate(node, orig->ae.xp_node);
                if (rc) {
-                       avc_node_kill(avc, node);
+                       avc_node_kill(node);
                        goto out_unlock;
                }
        }
@@ -926,7 +910,7 @@ static int avc_update_node(struct selinux_avc *avc,
                avc_add_xperms_decision(node, xpd);
                break;
        }
-       avc_node_replace(avc, node, orig);
+       avc_node_replace(node, orig);
 out_unlock:
        spin_unlock_irqrestore(lock, flag);
 out:
@@ -935,9 +919,8 @@ out:
 
 /**
  * avc_flush - Flush the cache
- * @avc: the access vector cache
  */
-static void avc_flush(struct selinux_avc *avc)
+static void avc_flush(void)
 {
        struct hlist_head *head;
        struct avc_node *node;
@@ -946,8 +929,8 @@ static void avc_flush(struct selinux_avc *avc)
        int i;
 
        for (i = 0; i < AVC_CACHE_SLOTS; i++) {
-               head = &avc->avc_cache.slots[i];
-               lock = &avc->avc_cache.slots_lock[i];
+               head = &selinux_avc.avc_cache.slots[i];
+               lock = &selinux_avc.avc_cache.slots_lock[i];
 
                spin_lock_irqsave(lock, flag);
                /*
@@ -956,7 +939,7 @@ static void avc_flush(struct selinux_avc *avc)
                 */
                rcu_read_lock();
                hlist_for_each_entry(node, head, list)
-                       avc_node_delete(avc, node);
+                       avc_node_delete(node);
                rcu_read_unlock();
                spin_unlock_irqrestore(lock, flag);
        }
@@ -964,15 +947,14 @@ static void avc_flush(struct selinux_avc *avc)
 
 /**
  * avc_ss_reset - Flush the cache and revalidate migrated permissions.
- * @avc: the access vector cache
  * @seqno: policy sequence number
  */
-int avc_ss_reset(struct selinux_avc *avc, u32 seqno)
+int avc_ss_reset(u32 seqno)
 {
        struct avc_callback_node *c;
        int rc = 0, tmprc;
 
-       avc_flush(avc);
+       avc_flush();
 
        for (c = avc_callbacks; c; c = c->next) {
                if (c->events & AVC_CALLBACK_RESET) {
@@ -984,34 +966,32 @@ int avc_ss_reset(struct selinux_avc *avc, u32 seqno)
                }
        }
 
-       avc_latest_notif_update(avc, seqno, 0);
+       avc_latest_notif_update(seqno, 0);
        return rc;
 }
 
-/*
- * Slow-path helper function for avc_has_perm_noaudit,
- * when the avc_node lookup fails. We get called with
- * the RCU read lock held, and need to return with it
- * still held, but drop if for the security compute.
+/**
+ * avc_compute_av - Add an entry to the AVC based on the security policy
+ * @ssid: subject
+ * @tsid: object/target
+ * @tclass: object class
+ * @avd: access vector decision
+ * @xp_node: AVC extended permissions node
  *
- * Don't inline this, since it's the slow-path and just
- * results in a bigger stack frame.
+ * Slow-path helper function for avc_has_perm_noaudit, when the avc_node lookup
+ * fails.  Don't inline this, since it's the slow-path and just results in a
+ * bigger stack frame.
  */
-static noinline
-struct avc_node *avc_compute_av(struct selinux_state *state,
-                               u32 ssid, u32 tsid,
-                               u16 tclass, struct av_decision *avd,
-                               struct avc_xperms_node *xp_node)
+static noinline void avc_compute_av(u32 ssid, u32 tsid, u16 tclass,
+                                   struct av_decision *avd,
+                                   struct avc_xperms_node *xp_node)
 {
-       rcu_read_unlock();
        INIT_LIST_HEAD(&xp_node->xpd_head);
-       security_compute_av(state, ssid, tsid, tclass, avd, &xp_node->xp);
-       rcu_read_lock();
-       return avc_insert(state->avc, ssid, tsid, tclass, avd, xp_node);
+       security_compute_av(ssid, tsid, tclass, avd, &xp_node->xp);
+       avc_insert(ssid, tsid, tclass, avd, xp_node);
 }
 
-static noinline int avc_denied(struct selinux_state *state,
-                              u32 ssid, u32 tsid,
+static noinline int avc_denied(u32 ssid, u32 tsid,
                               u16 tclass, u32 requested,
                               u8 driver, u8 xperm, unsigned int flags,
                               struct av_decision *avd)
@@ -1019,11 +999,11 @@ static noinline int avc_denied(struct selinux_state *state,
        if (flags & AVC_STRICT)
                return -EACCES;
 
-       if (enforcing_enabled(state) &&
+       if (enforcing_enabled() &&
            !(avd->flags & AVD_FLAGS_PERMISSIVE))
                return -EACCES;
 
-       avc_update_node(state->avc, AVC_CALLBACK_GRANT, requested, driver,
+       avc_update_node(AVC_CALLBACK_GRANT, requested, driver,
                        xperm, ssid, tsid, tclass, avd->seqno, NULL, flags);
        return 0;
 }
@@ -1035,8 +1015,7 @@ static noinline int avc_denied(struct selinux_state *state,
  * as-is the case with ioctls, then multiple may be chained together and the
  * driver field is used to specify which set contains the permission.
  */
-int avc_has_extended_perms(struct selinux_state *state,
-                          u32 ssid, u32 tsid, u16 tclass, u32 requested,
+int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested,
                           u8 driver, u8 xperm, struct common_audit_data *ad)
 {
        struct avc_node *node;
@@ -1057,9 +1036,9 @@ int avc_has_extended_perms(struct selinux_state *state,
 
        rcu_read_lock();
 
-       node = avc_lookup(state->avc, ssid, tsid, tclass);
+       node = avc_lookup(ssid, tsid, tclass);
        if (unlikely(!node)) {
-               avc_compute_av(state, ssid, tsid, tclass, &avd, xp_node);
+               avc_compute_av(ssid, tsid, tclass, &avd, xp_node);
        } else {
                memcpy(&avd, &node->ae.avd, sizeof(avd));
                xp_node = node->ae.xp_node;
@@ -1083,10 +1062,10 @@ int avc_has_extended_perms(struct selinux_state *state,
                        goto decision;
                }
                rcu_read_unlock();
-               security_compute_xperms_decision(state, ssid, tsid, tclass,
+               security_compute_xperms_decision(ssid, tsid, tclass,
                                                 driver, &local_xpd);
                rcu_read_lock();
-               avc_update_node(state->avc, AVC_CALLBACK_ADD_XPERMS, requested,
+               avc_update_node(AVC_CALLBACK_ADD_XPERMS, requested,
                                driver, xperm, ssid, tsid, tclass, avd.seqno,
                                &local_xpd, 0);
        } else {
@@ -1100,21 +1079,48 @@ int avc_has_extended_perms(struct selinux_state *state,
 decision:
        denied = requested & ~(avd.allowed);
        if (unlikely(denied))
-               rc = avc_denied(state, ssid, tsid, tclass, requested,
+               rc = avc_denied(ssid, tsid, tclass, requested,
                                driver, xperm, AVC_EXTENDED_PERMS, &avd);
 
        rcu_read_unlock();
 
-       rc2 = avc_xperms_audit(state, ssid, tsid, tclass, requested,
+       rc2 = avc_xperms_audit(ssid, tsid, tclass, requested,
                        &avd, xpd, xperm, rc, ad);
        if (rc2)
                return rc2;
        return rc;
 }
 
+/**
+ * avc_perm_nonode - Add an entry to the AVC
+ * @ssid: subject
+ * @tsid: object/target
+ * @tclass: object class
+ * @requested: requested permissions
+ * @flags: AVC flags
+ * @avd: access vector decision
+ *
+ * This is the "we have no node" part of avc_has_perm_noaudit(), which is
+ * unlikely and needs extra stack space for the new node that we generate, so
+ * don't inline it.
+ */
+static noinline int avc_perm_nonode(u32 ssid, u32 tsid, u16 tclass,
+                                   u32 requested, unsigned int flags,
+                                   struct av_decision *avd)
+{
+       u32 denied;
+       struct avc_xperms_node xp_node;
+
+       avc_compute_av(ssid, tsid, tclass, avd, &xp_node);
+       denied = requested & ~(avd->allowed);
+       if (unlikely(denied))
+               return avc_denied(ssid, tsid, tclass, requested, 0, 0,
+                                 flags, avd);
+       return 0;
+}
+
 /**
  * avc_has_perm_noaudit - Check permissions but perform no auditing.
- * @state: SELinux state
  * @ssid: source security identifier
  * @tsid: target security identifier
  * @tclass: target security class
@@ -1133,40 +1139,36 @@ decision:
  * auditing, e.g. in cases where a lock must be held for the check but
  * should be released for the auditing.
  */
-inline int avc_has_perm_noaudit(struct selinux_state *state,
-                               u32 ssid, u32 tsid,
+inline int avc_has_perm_noaudit(u32 ssid, u32 tsid,
                                u16 tclass, u32 requested,
                                unsigned int flags,
                                struct av_decision *avd)
 {
-       struct avc_node *node;
-       struct avc_xperms_node xp_node;
-       int rc = 0;
        u32 denied;
+       struct avc_node *node;
 
        if (WARN_ON(!requested))
                return -EACCES;
 
        rcu_read_lock();
+       node = avc_lookup(ssid, tsid, tclass);
+       if (unlikely(!node)) {
+               rcu_read_unlock();
+               return avc_perm_nonode(ssid, tsid, tclass, requested,
+                                      flags, avd);
+       }
+       denied = requested & ~node->ae.avd.allowed;
+       memcpy(avd, &node->ae.avd, sizeof(*avd));
+       rcu_read_unlock();
 
-       node = avc_lookup(state->avc, ssid, tsid, tclass);
-       if (unlikely(!node))
-               avc_compute_av(state, ssid, tsid, tclass, avd, &xp_node);
-       else
-               memcpy(avd, &node->ae.avd, sizeof(*avd));
-
-       denied = requested & ~(avd->allowed);
        if (unlikely(denied))
-               rc = avc_denied(state, ssid, tsid, tclass, requested, 0, 0,
-                               flags, avd);
-
-       rcu_read_unlock();
-       return rc;
+               return avc_denied(ssid, tsid, tclass, requested, 0, 0,
+                                 flags, avd);
+       return 0;
 }
 
 /**
  * avc_has_perm - Check permissions and perform any appropriate auditing.
- * @state: SELinux state
  * @ssid: source security identifier
  * @tsid: target security identifier
  * @tclass: target security class
@@ -1181,25 +1183,25 @@ inline int avc_has_perm_noaudit(struct selinux_state *state,
  * permissions are granted, -%EACCES if any permissions are denied, or
  * another -errno upon other errors.
  */
-int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass,
+int avc_has_perm(u32 ssid, u32 tsid, u16 tclass,
                 u32 requested, struct common_audit_data *auditdata)
 {
        struct av_decision avd;
        int rc, rc2;
 
-       rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested, 0,
+       rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0,
                                  &avd);
 
-       rc2 = avc_audit(state, ssid, tsid, tclass, requested, &avd, rc,
+       rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc,
                        auditdata);
        if (rc2)
                return rc2;
        return rc;
 }
 
-u32 avc_policy_seqno(struct selinux_state *state)
+u32 avc_policy_seqno(void)
 {
-       return state->avc->avc_cache.latest_notif;
+       return selinux_avc.avc_cache.latest_notif;
 }
 
 void avc_disable(void)
@@ -1216,7 +1218,7 @@ void avc_disable(void)
         * the cache and get that memory back.
         */
        if (avc_node_cachep) {
-               avc_flush(selinux_state.avc);
+               avc_flush();
                /* kmem_cache_destroy(avc_node_cachep); */
        }
 }
index 9a5bdfc2131471b4b74ba68ee224d0002942f5aa..79b4890e9936dc1ee9e046c8020a22e018ac7990 100644 (file)
@@ -136,17 +136,13 @@ static int __init selinux_enabled_setup(char *str)
 __setup("selinux=", selinux_enabled_setup);
 #endif
 
-static unsigned int selinux_checkreqprot_boot =
-       CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
-
 static int __init checkreqprot_setup(char *str)
 {
        unsigned long checkreqprot;
 
        if (!kstrtoul(str, 0, &checkreqprot)) {
-               selinux_checkreqprot_boot = checkreqprot ? 1 : 0;
                if (checkreqprot)
-                       pr_err("SELinux: checkreqprot set to 1 via kernel parameter.  This is deprecated and will be rejected in a future kernel release.\n");
+                       pr_err("SELinux: checkreqprot set to 1 via kernel parameter.  This is no longer supported.\n");
        }
        return 1;
 }
@@ -257,7 +253,7 @@ static int __inode_security_revalidate(struct inode *inode,
 
        might_sleep_if(may_sleep);
 
-       if (selinux_initialized(&selinux_state) &&
+       if (selinux_initialized() &&
            isec->initialized != LABEL_INITIALIZED) {
                if (!may_sleep)
                        return -ECHILD;
@@ -403,14 +399,12 @@ static int may_context_mount_sb_relabel(u32 sid,
        const struct task_security_struct *tsec = selinux_cred(cred);
        int rc;
 
-       rc = avc_has_perm(&selinux_state,
-                         tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
+       rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
                          FILESYSTEM__RELABELFROM, NULL);
        if (rc)
                return rc;
 
-       rc = avc_has_perm(&selinux_state,
-                         tsec->sid, sid, SECCLASS_FILESYSTEM,
+       rc = avc_has_perm(tsec->sid, sid, SECCLASS_FILESYSTEM,
                          FILESYSTEM__RELABELTO, NULL);
        return rc;
 }
@@ -421,14 +415,12 @@ static int may_context_mount_inode_relabel(u32 sid,
 {
        const struct task_security_struct *tsec = selinux_cred(cred);
        int rc;
-       rc = avc_has_perm(&selinux_state,
-                         tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
+       rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
                          FILESYSTEM__RELABELFROM, NULL);
        if (rc)
                return rc;
 
-       rc = avc_has_perm(&selinux_state,
-                         sid, sbsec->sid, SECCLASS_FILESYSTEM,
+       rc = avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM,
                          FILESYSTEM__ASSOCIATE, NULL);
        return rc;
 }
@@ -511,7 +503,7 @@ static int sb_check_xattr_support(struct super_block *sb)
 
 fallback:
        /* No xattr support - try to fallback to genfs if possible. */
-       rc = security_genfs_sid(&selinux_state, sb->s_type->name, "/",
+       rc = security_genfs_sid(sb->s_type->name, "/",
                                SECCLASS_DIR, &sid);
        if (rc)
                return -EOPNOTSUPP;
@@ -615,7 +607,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
 
        mutex_lock(&sbsec->lock);
 
-       if (!selinux_initialized(&selinux_state)) {
+       if (!selinux_initialized()) {
                if (!opts) {
                        /* Defer initialization until selinux_complete_init,
                           after the initial policy is loaded and the security
@@ -716,7 +708,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
                 * Determine the labeling behavior to use for this
                 * filesystem type.
                 */
-               rc = security_fs_use(&selinux_state, sb);
+               rc = security_fs_use(sb);
                if (rc) {
                        pr_warn("%s: security_fs_use(%s) returned %d\n",
                                        __func__, sb->s_type->name, rc);
@@ -741,8 +733,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
                }
                if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
                        sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
-                       rc = security_transition_sid(&selinux_state,
-                                                    current_sid(),
+                       rc = security_transition_sid(current_sid(),
                                                     current_sid(),
                                                     SECCLASS_FILE, NULL,
                                                     &sbsec->mntpoint_sid);
@@ -881,7 +872,7 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
         * if the parent was able to be mounted it clearly had no special lsm
         * mount options.  thus we can safely deal with this superblock later
         */
-       if (!selinux_initialized(&selinux_state))
+       if (!selinux_initialized())
                return 0;
 
        /*
@@ -911,7 +902,7 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
 
        if (newsbsec->behavior == SECURITY_FS_USE_NATIVE &&
                !(kern_flags & SECURITY_LSM_NATIVE_LABELS) && !set_context) {
-               rc = security_fs_use(&selinux_state, newsb);
+               rc = security_fs_use(newsb);
                if (rc)
                        goto out;
        }
@@ -960,7 +951,7 @@ static int selinux_add_opt(int token, const char *s, void **mnt_opts)
        if (!s)
                return -EINVAL;
 
-       if (!selinux_initialized(&selinux_state)) {
+       if (!selinux_initialized()) {
                pr_warn("SELinux: Unable to set superblock options before the security server is initialized\n");
                return -EINVAL;
        }
@@ -997,7 +988,7 @@ static int selinux_add_opt(int token, const char *s, void **mnt_opts)
                WARN_ON(1);
                return -EINVAL;
        }
-       rc = security_context_str_to_sid(&selinux_state, s, dst_sid, GFP_KERNEL);
+       rc = security_context_str_to_sid(s, dst_sid, GFP_KERNEL);
        if (rc)
                pr_warn("SELinux: security_context_str_to_sid (%s) failed with errno=%d\n",
                        s, rc);
@@ -1014,8 +1005,7 @@ static int show_sid(struct seq_file *m, u32 sid)
        u32 len;
        int rc;
 
-       rc = security_sid_to_context(&selinux_state, sid,
-                                            &context, &len);
+       rc = security_sid_to_context(sid, &context, &len);
        if (!rc) {
                bool has_comma = strchr(context, ',');
 
@@ -1038,7 +1028,7 @@ static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb)
        if (!(sbsec->flags & SE_SBINITIALIZED))
                return 0;
 
-       if (!selinux_initialized(&selinux_state))
+       if (!selinux_initialized())
                return 0;
 
        if (sbsec->flags & FSCONTEXT_MNT) {
@@ -1292,7 +1282,7 @@ static int selinux_genfs_get_sid(struct dentry *dentry,
                                path++;
                        }
                }
-               rc = security_genfs_sid(&selinux_state, sb->s_type->name,
+               rc = security_genfs_sid(sb->s_type->name,
                                        path, tclass, sid);
                if (rc == -ENOENT) {
                        /* No match in policy, mark as unlabeled. */
@@ -1347,7 +1337,7 @@ static int inode_doinit_use_xattr(struct inode *inode, struct dentry *dentry,
                return 0;
        }
 
-       rc = security_context_to_sid_default(&selinux_state, context, rc, sid,
+       rc = security_context_to_sid_default(context, rc, sid,
                                             def_sid, GFP_NOFS);
        if (rc) {
                char *dev = inode->i_sb->s_id;
@@ -1454,7 +1444,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
                sid = sbsec->sid;
 
                /* Try to obtain a transition SID. */
-               rc = security_transition_sid(&selinux_state, task_sid, sid,
+               rc = security_transition_sid(task_sid, sid,
                                             sclass, NULL, &sid);
                if (rc)
                        goto out;
@@ -1599,11 +1589,9 @@ static int cred_has_capability(const struct cred *cred,
                return -EINVAL;
        }
 
-       rc = avc_has_perm_noaudit(&selinux_state,
-                                 sid, sid, sclass, av, 0, &avd);
+       rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd);
        if (!(opts & CAP_OPT_NOAUDIT)) {
-               int rc2 = avc_audit(&selinux_state,
-                                   sid, sid, sclass, av, &avd, rc, &ad);
+               int rc2 = avc_audit(sid, sid, sclass, av, &avd, rc, &ad);
                if (rc2)
                        return rc2;
        }
@@ -1629,8 +1617,7 @@ static int inode_has_perm(const struct cred *cred,
        sid = cred_sid(cred);
        isec = selinux_inode(inode);
 
-       return avc_has_perm(&selinux_state,
-                           sid, isec->sid, isec->sclass, perms, adp);
+       return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp);
 }
 
 /* Same as inode_has_perm, but pass explicit audit data containing
@@ -1703,8 +1690,7 @@ static int file_has_perm(const struct cred *cred,
        ad.u.file = file;
 
        if (sid != fsec->sid) {
-               rc = avc_has_perm(&selinux_state,
-                                 sid, fsec->sid,
+               rc = avc_has_perm(sid, fsec->sid,
                                  SECCLASS_FD,
                                  FD__USE,
                                  &ad);
@@ -1747,7 +1733,7 @@ selinux_determine_inode_label(const struct task_security_struct *tsec,
                *_new_isid = tsec->create_sid;
        } else {
                const struct inode_security_struct *dsec = inode_security(dir);
-               return security_transition_sid(&selinux_state, tsec->sid,
+               return security_transition_sid(tsec->sid,
                                               dsec->sid, tclass,
                                               name, _new_isid);
        }
@@ -1775,8 +1761,7 @@ static int may_create(struct inode *dir,
        ad.type = LSM_AUDIT_DATA_DENTRY;
        ad.u.dentry = dentry;
 
-       rc = avc_has_perm(&selinux_state,
-                         sid, dsec->sid, SECCLASS_DIR,
+       rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,
                          DIR__ADD_NAME | DIR__SEARCH,
                          &ad);
        if (rc)
@@ -1787,13 +1772,11 @@ static int may_create(struct inode *dir,
        if (rc)
                return rc;
 
-       rc = avc_has_perm(&selinux_state,
-                         sid, newsid, tclass, FILE__CREATE, &ad);
+       rc = avc_has_perm(sid, newsid, tclass, FILE__CREATE, &ad);
        if (rc)
                return rc;
 
-       return avc_has_perm(&selinux_state,
-                           newsid, sbsec->sid,
+       return avc_has_perm(newsid, sbsec->sid,
                            SECCLASS_FILESYSTEM,
                            FILESYSTEM__ASSOCIATE, &ad);
 }
@@ -1822,8 +1805,7 @@ static int may_link(struct inode *dir,
 
        av = DIR__SEARCH;
        av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
-       rc = avc_has_perm(&selinux_state,
-                         sid, dsec->sid, SECCLASS_DIR, av, &ad);
+       rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, av, &ad);
        if (rc)
                return rc;
 
@@ -1843,8 +1825,7 @@ static int may_link(struct inode *dir,
                return 0;
        }
 
-       rc = avc_has_perm(&selinux_state,
-                         sid, isec->sid, isec->sclass, av, &ad);
+       rc = avc_has_perm(sid, isec->sid, isec->sclass, av, &ad);
        return rc;
 }
 
@@ -1868,19 +1849,16 @@ static inline int may_rename(struct inode *old_dir,
        ad.type = LSM_AUDIT_DATA_DENTRY;
 
        ad.u.dentry = old_dentry;
-       rc = avc_has_perm(&selinux_state,
-                         sid, old_dsec->sid, SECCLASS_DIR,
+       rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
                          DIR__REMOVE_NAME | DIR__SEARCH, &ad);
        if (rc)
                return rc;
-       rc = avc_has_perm(&selinux_state,
-                         sid, old_isec->sid,
+       rc = avc_has_perm(sid, old_isec->sid,
                          old_isec->sclass, FILE__RENAME, &ad);
        if (rc)
                return rc;
        if (old_is_dir && new_dir != old_dir) {
-               rc = avc_has_perm(&selinux_state,
-                                 sid, old_isec->sid,
+               rc = avc_has_perm(sid, old_isec->sid,
                                  old_isec->sclass, DIR__REPARENT, &ad);
                if (rc)
                        return rc;
@@ -1890,15 +1868,13 @@ static inline int may_rename(struct inode *old_dir,
        av = DIR__ADD_NAME | DIR__SEARCH;
        if (d_is_positive(new_dentry))
                av |= DIR__REMOVE_NAME;
-       rc = avc_has_perm(&selinux_state,
-                         sid, new_dsec->sid, SECCLASS_DIR, av, &ad);
+       rc = avc_has_perm(sid, new_dsec->sid, SECCLASS_DIR, av, &ad);
        if (rc)
                return rc;
        if (d_is_positive(new_dentry)) {
                new_isec = backing_inode_security(new_dentry);
                new_is_dir = d_is_dir(new_dentry);
-               rc = avc_has_perm(&selinux_state,
-                                 sid, new_isec->sid,
+               rc = avc_has_perm(sid, new_isec->sid,
                                  new_isec->sclass,
                                  (new_is_dir ? DIR__RMDIR : FILE__UNLINK), &ad);
                if (rc)
@@ -1918,8 +1894,7 @@ static int superblock_has_perm(const struct cred *cred,
        u32 sid = cred_sid(cred);
 
        sbsec = selinux_superblock(sb);
-       return avc_has_perm(&selinux_state,
-                           sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad);
+       return avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad);
 }
 
 /* Convert a Linux mode and permission mask to an access vector. */
@@ -1993,8 +1968,7 @@ static inline u32 open_file_to_av(struct file *file)
 
 static int selinux_binder_set_context_mgr(const struct cred *mgr)
 {
-       return avc_has_perm(&selinux_state,
-                           current_sid(), cred_sid(mgr), SECCLASS_BINDER,
+       return avc_has_perm(current_sid(), cred_sid(mgr), SECCLASS_BINDER,
                            BINDER__SET_CONTEXT_MGR, NULL);
 }
 
@@ -2007,22 +1981,20 @@ static int selinux_binder_transaction(const struct cred *from,
        int rc;
 
        if (mysid != fromsid) {
-               rc = avc_has_perm(&selinux_state,
-                                 mysid, fromsid, SECCLASS_BINDER,
+               rc = avc_has_perm(mysid, fromsid, SECCLASS_BINDER,
                                  BINDER__IMPERSONATE, NULL);
                if (rc)
                        return rc;
        }
 
-       return avc_has_perm(&selinux_state, fromsid, tosid,
+       return avc_has_perm(fromsid, tosid,
                            SECCLASS_BINDER, BINDER__CALL, NULL);
 }
 
 static int selinux_binder_transfer_binder(const struct cred *from,
                                          const struct cred *to)
 {
-       return avc_has_perm(&selinux_state,
-                           cred_sid(from), cred_sid(to),
+       return avc_has_perm(cred_sid(from), cred_sid(to),
                            SECCLASS_BINDER, BINDER__TRANSFER,
                            NULL);
 }
@@ -2042,8 +2014,7 @@ static int selinux_binder_transfer_file(const struct cred *from,
        ad.u.path = file->f_path;
 
        if (sid != fsec->sid) {
-               rc = avc_has_perm(&selinux_state,
-                                 sid, fsec->sid,
+               rc = avc_has_perm(sid, fsec->sid,
                                  SECCLASS_FD,
                                  FD__USE,
                                  &ad);
@@ -2061,8 +2032,7 @@ static int selinux_binder_transfer_file(const struct cred *from,
                return 0;
 
        isec = backing_inode_security(dentry);
-       return avc_has_perm(&selinux_state,
-                           sid, isec->sid, isec->sclass, file_to_av(file),
+       return avc_has_perm(sid, isec->sid, isec->sclass, file_to_av(file),
                            &ad);
 }
 
@@ -2073,26 +2043,24 @@ static int selinux_ptrace_access_check(struct task_struct *child,
        u32 csid = task_sid_obj(child);
 
        if (mode & PTRACE_MODE_READ)
-               return avc_has_perm(&selinux_state,
-                                   sid, csid, SECCLASS_FILE, FILE__READ, NULL);
+               return avc_has_perm(sid, csid, SECCLASS_FILE, FILE__READ,
+                               NULL);
 
-       return avc_has_perm(&selinux_state,
-                           sid, csid, SECCLASS_PROCESS, PROCESS__PTRACE, NULL);
+       return avc_has_perm(sid, csid, SECCLASS_PROCESS, PROCESS__PTRACE,
+                       NULL);
 }
 
 static int selinux_ptrace_traceme(struct task_struct *parent)
 {
-       return avc_has_perm(&selinux_state,
-                           task_sid_obj(parent), task_sid_obj(current),
+       return avc_has_perm(task_sid_obj(parent), task_sid_obj(current),
                            SECCLASS_PROCESS, PROCESS__PTRACE, NULL);
 }
 
 static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
                          kernel_cap_t *inheritable, kernel_cap_t *permitted)
 {
-       return avc_has_perm(&selinux_state,
-                           current_sid(), task_sid_obj(target), SECCLASS_PROCESS,
-                           PROCESS__GETCAP, NULL);
+       return avc_has_perm(current_sid(), task_sid_obj(target),
+                       SECCLASS_PROCESS, PROCESS__GETCAP, NULL);
 }
 
 static int selinux_capset(struct cred *new, const struct cred *old,
@@ -2100,8 +2068,7 @@ static int selinux_capset(struct cred *new, const struct cred *old,
                          const kernel_cap_t *inheritable,
                          const kernel_cap_t *permitted)
 {
-       return avc_has_perm(&selinux_state,
-                           cred_sid(old), cred_sid(new), SECCLASS_PROCESS,
+       return avc_has_perm(cred_sid(old), cred_sid(new), SECCLASS_PROCESS,
                            PROCESS__SETCAP, NULL);
 }
 
@@ -2168,21 +2135,18 @@ static int selinux_syslog(int type)
        switch (type) {
        case SYSLOG_ACTION_READ_ALL:    /* Read last kernel messages */
        case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */
-               return avc_has_perm(&selinux_state,
-                                   current_sid(), SECINITSID_KERNEL,
+               return avc_has_perm(current_sid(), SECINITSID_KERNEL,
                                    SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, NULL);
        case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */
        case SYSLOG_ACTION_CONSOLE_ON:  /* Enable logging to console */
        /* Set level of messages printed to console */
        case SYSLOG_ACTION_CONSOLE_LEVEL:
-               return avc_has_perm(&selinux_state,
-                                   current_sid(), SECINITSID_KERNEL,
+               return avc_has_perm(current_sid(), SECINITSID_KERNEL,
                                    SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE,
                                    NULL);
        }
        /* All other syslog types */
-       return avc_has_perm(&selinux_state,
-                           current_sid(), SECINITSID_KERNEL,
+       return avc_has_perm(current_sid(), SECINITSID_KERNEL,
                            SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, NULL);
 }
 
@@ -2249,8 +2213,7 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm,
                        av |= PROCESS2__NNP_TRANSITION;
                if (nosuid)
                        av |= PROCESS2__NOSUID_TRANSITION;
-               rc = avc_has_perm(&selinux_state,
-                                 old_tsec->sid, new_tsec->sid,
+               rc = avc_has_perm(old_tsec->sid, new_tsec->sid,
                                  SECCLASS_PROCESS2, av, NULL);
                if (!rc)
                        return 0;
@@ -2261,7 +2224,7 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm,
         * i.e. SIDs that are guaranteed to only be allowed a subset
         * of the permissions of the current SID.
         */
-       rc = security_bounded_transition(&selinux_state, old_tsec->sid,
+       rc = security_bounded_transition(old_tsec->sid,
                                         new_tsec->sid);
        if (!rc)
                return 0;
@@ -2312,7 +2275,7 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm)
                        return rc;
        } else {
                /* Check for a default transition on this program. */
-               rc = security_transition_sid(&selinux_state, old_tsec->sid,
+               rc = security_transition_sid(old_tsec->sid,
                                             isec->sid, SECCLASS_PROCESS, NULL,
                                             &new_tsec->sid);
                if (rc)
@@ -2331,29 +2294,25 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm)
        ad.u.file = bprm->file;
 
        if (new_tsec->sid == old_tsec->sid) {
-               rc = avc_has_perm(&selinux_state,
-                                 old_tsec->sid, isec->sid,
+               rc = avc_has_perm(old_tsec->sid, isec->sid,
                                  SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad);
                if (rc)
                        return rc;
        } else {
                /* Check permissions for the transition. */
-               rc = avc_has_perm(&selinux_state,
-                                 old_tsec->sid, new_tsec->sid,
+               rc = avc_has_perm(old_tsec->sid, new_tsec->sid,
                                  SECCLASS_PROCESS, PROCESS__TRANSITION, &ad);
                if (rc)
                        return rc;
 
-               rc = avc_has_perm(&selinux_state,
-                                 new_tsec->sid, isec->sid,
+               rc = avc_has_perm(new_tsec->sid, isec->sid,
                                  SECCLASS_FILE, FILE__ENTRYPOINT, &ad);
                if (rc)
                        return rc;
 
                /* Check for shared state */
                if (bprm->unsafe & LSM_UNSAFE_SHARE) {
-                       rc = avc_has_perm(&selinux_state,
-                                         old_tsec->sid, new_tsec->sid,
+                       rc = avc_has_perm(old_tsec->sid, new_tsec->sid,
                                          SECCLASS_PROCESS, PROCESS__SHARE,
                                          NULL);
                        if (rc)
@@ -2365,8 +2324,7 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm)
                if (bprm->unsafe & LSM_UNSAFE_PTRACE) {
                        u32 ptsid = ptrace_parent_sid();
                        if (ptsid != 0) {
-                               rc = avc_has_perm(&selinux_state,
-                                                 ptsid, new_tsec->sid,
+                               rc = avc_has_perm(ptsid, new_tsec->sid,
                                                  SECCLASS_PROCESS,
                                                  PROCESS__PTRACE, NULL);
                                if (rc)
@@ -2380,8 +2338,7 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm)
                /* Enable secure mode for SIDs transitions unless
                   the noatsecure permission is granted between
                   the two SIDs, i.e. ahp returns 0. */
-               rc = avc_has_perm(&selinux_state,
-                                 old_tsec->sid, new_tsec->sid,
+               rc = avc_has_perm(old_tsec->sid, new_tsec->sid,
                                  SECCLASS_PROCESS, PROCESS__NOATSECURE,
                                  NULL);
                bprm->secureexec |= !!rc;
@@ -2473,8 +2430,7 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm)
         * higher than the default soft limit for cases where the default is
         * lower than the hard limit, e.g. RLIMIT_CORE or RLIMIT_STACK.
         */
-       rc = avc_has_perm(&selinux_state,
-                         new_tsec->osid, new_tsec->sid, SECCLASS_PROCESS,
+       rc = avc_has_perm(new_tsec->osid, new_tsec->sid, SECCLASS_PROCESS,
                          PROCESS__RLIMITINH, NULL);
        if (rc) {
                /* protect against do_prlimit() */
@@ -2513,8 +2469,7 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
         * This must occur _after_ the task SID has been updated so that any
         * kill done after the flush will be checked against the new SID.
         */
-       rc = avc_has_perm(&selinux_state,
-                         osid, sid, SECCLASS_PROCESS, PROCESS__SIGINH, NULL);
+       rc = avc_has_perm(osid, sid, SECCLASS_PROCESS, PROCESS__SIGINH, NULL);
        if (rc) {
                clear_itimer();
 
@@ -2841,7 +2796,7 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode,
        if (xattr_name)
                *xattr_name = XATTR_NAME_SELINUX;
 
-       return security_sid_to_context(&selinux_state, newsid, (char **)ctx,
+       return security_sid_to_context(newsid, (char **)ctx,
                                       ctxlen);
 }
 
@@ -2895,7 +2850,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
                isec->initialized = LABEL_INITIALIZED;
        }
 
-       if (!selinux_initialized(&selinux_state) ||
+       if (!selinux_initialized() ||
            !(sbsec->flags & SBLABEL_MNT))
                return -EOPNOTSUPP;
 
@@ -2903,7 +2858,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
                *name = XATTR_SELINUX_SUFFIX;
 
        if (value && len) {
-               rc = security_sid_to_context_force(&selinux_state, newsid,
+               rc = security_sid_to_context_force(newsid,
                                                   &context, &clen);
                if (rc)
                        return rc;
@@ -2923,7 +2878,7 @@ static int selinux_inode_init_security_anon(struct inode *inode,
        struct inode_security_struct *isec;
        int rc;
 
-       if (unlikely(!selinux_initialized(&selinux_state)))
+       if (unlikely(!selinux_initialized()))
                return 0;
 
        isec = selinux_inode(inode);
@@ -2947,7 +2902,7 @@ static int selinux_inode_init_security_anon(struct inode *inode,
        } else {
                isec->sclass = SECCLASS_ANON_INODE;
                rc = security_transition_sid(
-                       &selinux_state, tsec->sid, tsec->sid,
+                       tsec->sid, tsec->sid,
                        isec->sclass, name, &isec->sid);
                if (rc)
                        return rc;
@@ -2962,8 +2917,7 @@ static int selinux_inode_init_security_anon(struct inode *inode,
        ad.type = LSM_AUDIT_DATA_ANONINODE;
        ad.u.anonclass = name ? (const char *)name->name : "?";
 
-       return avc_has_perm(&selinux_state,
-                           tsec->sid,
+       return avc_has_perm(tsec->sid,
                            isec->sid,
                            isec->sclass,
                            FILE__CREATE,
@@ -3035,8 +2989,7 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode,
        if (IS_ERR(isec))
                return PTR_ERR(isec);
 
-       return avc_has_perm(&selinux_state,
-                                 sid, isec->sid, isec->sclass, FILE__READ, &ad);
+       return avc_has_perm(sid, isec->sid, isec->sclass, FILE__READ, &ad);
 }
 
 static noinline int audit_inode_permission(struct inode *inode,
@@ -3049,8 +3002,7 @@ static noinline int audit_inode_permission(struct inode *inode,
        ad.type = LSM_AUDIT_DATA_INODE;
        ad.u.inode = inode;
 
-       return slow_avc_audit(&selinux_state,
-                           current_sid(), isec->sid, isec->sclass, perms,
+       return slow_avc_audit(current_sid(), isec->sid, isec->sclass, perms,
                            audited, denied, result, &ad);
 }
 
@@ -3085,8 +3037,7 @@ static int selinux_inode_permission(struct inode *inode, int mask)
        if (IS_ERR(isec))
                return PTR_ERR(isec);
 
-       rc = avc_has_perm_noaudit(&selinux_state,
-                                 sid, isec->sid, isec->sclass, perms, 0,
+       rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass, perms, 0,
                                  &avd);
        audited = avc_audit_required(perms, &avd, rc,
                                     from_access ? FILE__AUDIT_ACCESS : 0,
@@ -3166,7 +3117,7 @@ static int selinux_inode_setxattr(struct mnt_idmap *idmap,
                return dentry_has_perm(current_cred(), dentry, FILE__SETATTR);
        }
 
-       if (!selinux_initialized(&selinux_state))
+       if (!selinux_initialized())
                return (inode_owner_or_capable(idmap, inode) ? 0 : -EPERM);
 
        sbsec = selinux_superblock(inode->i_sb);
@@ -3180,13 +3131,12 @@ static int selinux_inode_setxattr(struct mnt_idmap *idmap,
        ad.u.dentry = dentry;
 
        isec = backing_inode_security(dentry);
-       rc = avc_has_perm(&selinux_state,
-                         sid, isec->sid, isec->sclass,
+       rc = avc_has_perm(sid, isec->sid, isec->sclass,
                          FILE__RELABELFROM, &ad);
        if (rc)
                return rc;
 
-       rc = security_context_to_sid(&selinux_state, value, size, &newsid,
+       rc = security_context_to_sid(value, size, &newsid,
                                     GFP_KERNEL);
        if (rc == -EINVAL) {
                if (!has_cap_mac_admin(true)) {
@@ -3215,25 +3165,23 @@ static int selinux_inode_setxattr(struct mnt_idmap *idmap,
 
                        return rc;
                }
-               rc = security_context_to_sid_force(&selinux_state, value,
+               rc = security_context_to_sid_force(value,
                                                   size, &newsid);
        }
        if (rc)
                return rc;
 
-       rc = avc_has_perm(&selinux_state,
-                         sid, newsid, isec->sclass,
+       rc = avc_has_perm(sid, newsid, isec->sclass,
                          FILE__RELABELTO, &ad);
        if (rc)
                return rc;
 
-       rc = security_validate_transition(&selinux_state, isec->sid, newsid,
+       rc = security_validate_transition(isec->sid, newsid,
                                          sid, isec->sclass);
        if (rc)
                return rc;
 
-       return avc_has_perm(&selinux_state,
-                           newsid,
+       return avc_has_perm(newsid,
                            sbsec->sid,
                            SECCLASS_FILESYSTEM,
                            FILESYSTEM__ASSOCIATE,
@@ -3273,7 +3221,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
                return;
        }
 
-       if (!selinux_initialized(&selinux_state)) {
+       if (!selinux_initialized()) {
                /* If we haven't even been initialized, then we can't validate
                 * against a policy, so leave the label as invalid. It may
                 * resolve to a valid label on the next revalidation try if
@@ -3282,7 +3230,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
                return;
        }
 
-       rc = security_context_to_sid_force(&selinux_state, value, size,
+       rc = security_context_to_sid_force(value, size,
                                           &newsid);
        if (rc) {
                pr_err("SELinux:  unable to map context to SID"
@@ -3326,7 +3274,7 @@ static int selinux_inode_removexattr(struct mnt_idmap *idmap,
                return dentry_has_perm(current_cred(), dentry, FILE__SETATTR);
        }
 
-       if (!selinux_initialized(&selinux_state))
+       if (!selinux_initialized())
                return 0;
 
        /* No one is allowed to remove a SELinux security label.
@@ -3396,7 +3344,7 @@ static int selinux_inode_getsecurity(struct mnt_idmap *idmap,
         * If we're not initialized yet, then we can't validate contexts, so
         * just let vfs_getxattr fall back to using the on-disk xattr.
         */
-       if (!selinux_initialized(&selinux_state) ||
+       if (!selinux_initialized() ||
            strcmp(name, XATTR_SELINUX_SUFFIX))
                return -EOPNOTSUPP;
 
@@ -3411,11 +3359,10 @@ static int selinux_inode_getsecurity(struct mnt_idmap *idmap,
         */
        isec = inode_security(inode);
        if (has_cap_mac_admin(false))
-               error = security_sid_to_context_force(&selinux_state,
-                                                     isec->sid, &context,
+               error = security_sid_to_context_force(isec->sid, &context,
                                                      &size);
        else
-               error = security_sid_to_context(&selinux_state, isec->sid,
+               error = security_sid_to_context(isec->sid,
                                                &context, &size);
        if (error)
                return error;
@@ -3447,7 +3394,7 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name,
        if (!value || !size)
                return -EACCES;
 
-       rc = security_context_to_sid(&selinux_state, value, size, &newsid,
+       rc = security_context_to_sid(value, size, &newsid,
                                     GFP_KERNEL);
        if (rc)
                return rc;
@@ -3464,7 +3411,7 @@ static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t
 {
        const int len = sizeof(XATTR_NAME_SELINUX);
 
-       if (!selinux_initialized(&selinux_state))
+       if (!selinux_initialized())
                return 0;
 
        if (buffer && len <= buffer_size)
@@ -3540,7 +3487,7 @@ static int selinux_kernfs_init_security(struct kernfs_node *kn_dir,
                return rc;
        }
 
-       rc = security_context_to_sid(&selinux_state, context, clen, &parent_sid,
+       rc = security_context_to_sid(context, clen, &parent_sid,
                                     GFP_KERNEL);
        kfree(context);
        if (rc)
@@ -3555,14 +3502,14 @@ static int selinux_kernfs_init_security(struct kernfs_node *kn_dir,
                q.name = kn->name;
                q.hash_len = hashlen_string(kn_dir, kn->name);
 
-               rc = security_transition_sid(&selinux_state, tsec->sid,
+               rc = security_transition_sid(tsec->sid,
                                             parent_sid, secclass, &q,
                                             &newsid);
                if (rc)
                        return rc;
        }
 
-       rc = security_sid_to_context_force(&selinux_state, newsid,
+       rc = security_sid_to_context_force(newsid,
                                           &context, &clen);
        if (rc)
                return rc;
@@ -3602,7 +3549,7 @@ static int selinux_file_permission(struct file *file, int mask)
 
        isec = inode_security(inode);
        if (sid == fsec->sid && fsec->isid == isec->sid &&
-           fsec->pseqno == avc_policy_seqno(&selinux_state))
+           fsec->pseqno == avc_policy_seqno())
                /* No change since file_open check. */
                return 0;
 
@@ -3643,8 +3590,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file,
        ad.u.op->path = file->f_path;
 
        if (ssid != fsec->sid) {
-               rc = avc_has_perm(&selinux_state,
-                                 ssid, fsec->sid,
+               rc = avc_has_perm(ssid, fsec->sid,
                                SECCLASS_FD,
                                FD__USE,
                                &ad);
@@ -3656,8 +3602,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file,
                return 0;
 
        isec = inode_security(inode);
-       rc = avc_has_extended_perms(&selinux_state,
-                                   ssid, isec->sid, isec->sclass,
+       rc = avc_has_extended_perms(ssid, isec->sid, isec->sclass,
                                    requested, driver, xperm, &ad);
 out:
        return rc;
@@ -3726,8 +3671,7 @@ static int file_map_prot_check(struct file *file, unsigned long prot, int shared
                 * private file mapping that will also be writable.
                 * This has an additional check.
                 */
-               rc = avc_has_perm(&selinux_state,
-                                 sid, sid, SECCLASS_PROCESS,
+               rc = avc_has_perm(sid, sid, SECCLASS_PROCESS,
                                  PROCESS__EXECMEM, NULL);
                if (rc)
                        goto error;
@@ -3757,15 +3701,15 @@ static int selinux_mmap_addr(unsigned long addr)
 
        if (addr < CONFIG_LSM_MMAP_MIN_ADDR) {
                u32 sid = current_sid();
-               rc = avc_has_perm(&selinux_state,
-                                 sid, sid, SECCLASS_MEMPROTECT,
+               rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT,
                                  MEMPROTECT__MMAP_ZERO, NULL);
        }
 
        return rc;
 }
 
-static int selinux_mmap_file(struct file *file, unsigned long reqprot,
+static int selinux_mmap_file(struct file *file,
+                            unsigned long reqprot __always_unused,
                             unsigned long prot, unsigned long flags)
 {
        struct common_audit_data ad;
@@ -3780,37 +3724,29 @@ static int selinux_mmap_file(struct file *file, unsigned long reqprot,
                        return rc;
        }
 
-       if (checkreqprot_get(&selinux_state))
-               prot = reqprot;
-
        return file_map_prot_check(file, prot,
                                   (flags & MAP_TYPE) == MAP_SHARED);
 }
 
 static int selinux_file_mprotect(struct vm_area_struct *vma,
-                                unsigned long reqprot,
+                                unsigned long reqprot __always_unused,
                                 unsigned long prot)
 {
        const struct cred *cred = current_cred();
        u32 sid = cred_sid(cred);
 
-       if (checkreqprot_get(&selinux_state))
-               prot = reqprot;
-
        if (default_noexec &&
            (prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
                int rc = 0;
                if (vma->vm_start >= vma->vm_mm->start_brk &&
                    vma->vm_end <= vma->vm_mm->brk) {
-                       rc = avc_has_perm(&selinux_state,
-                                         sid, sid, SECCLASS_PROCESS,
+                       rc = avc_has_perm(sid, sid, SECCLASS_PROCESS,
                                          PROCESS__EXECHEAP, NULL);
                } else if (!vma->vm_file &&
                           ((vma->vm_start <= vma->vm_mm->start_stack &&
                             vma->vm_end >= vma->vm_mm->start_stack) ||
                            vma_is_stack_for_current(vma))) {
-                       rc = avc_has_perm(&selinux_state,
-                                         sid, sid, SECCLASS_PROCESS,
+                       rc = avc_has_perm(sid, sid, SECCLASS_PROCESS,
                                          PROCESS__EXECSTACK, NULL);
                } else if (vma->vm_file && vma->anon_vma) {
                        /*
@@ -3902,8 +3838,7 @@ static int selinux_file_send_sigiotask(struct task_struct *tsk,
        else
                perm = signal_to_av(signum);
 
-       return avc_has_perm(&selinux_state,
-                           fsec->fown_sid, sid,
+       return avc_has_perm(fsec->fown_sid, sid,
                            SECCLASS_PROCESS, perm, NULL);
 }
 
@@ -3929,7 +3864,7 @@ static int selinux_file_open(struct file *file)
         * struct as its SID.
         */
        fsec->isid = isec->sid;
-       fsec->pseqno = avc_policy_seqno(&selinux_state);
+       fsec->pseqno = avc_policy_seqno();
        /*
         * Since the inode label or policy seqno may have changed
         * between the selinux_inode_permission check and the saving
@@ -3948,8 +3883,7 @@ static int selinux_task_alloc(struct task_struct *task,
 {
        u32 sid = current_sid();
 
-       return avc_has_perm(&selinux_state,
-                           sid, sid, SECCLASS_PROCESS, PROCESS__FORK, NULL);
+       return avc_has_perm(sid, sid, SECCLASS_PROCESS, PROCESS__FORK, NULL);
 }
 
 /*
@@ -3991,8 +3925,7 @@ static int selinux_kernel_act_as(struct cred *new, u32 secid)
        u32 sid = current_sid();
        int ret;
 
-       ret = avc_has_perm(&selinux_state,
-                          sid, secid,
+       ret = avc_has_perm(sid, secid,
                           SECCLASS_KERNEL_SERVICE,
                           KERNEL_SERVICE__USE_AS_OVERRIDE,
                           NULL);
@@ -4016,8 +3949,7 @@ static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
        u32 sid = current_sid();
        int ret;
 
-       ret = avc_has_perm(&selinux_state,
-                          sid, isec->sid,
+       ret = avc_has_perm(sid, isec->sid,
                           SECCLASS_KERNEL_SERVICE,
                           KERNEL_SERVICE__CREATE_FILES_AS,
                           NULL);
@@ -4034,8 +3966,7 @@ static int selinux_kernel_module_request(char *kmod_name)
        ad.type = LSM_AUDIT_DATA_KMOD;
        ad.u.kmod_name = kmod_name;
 
-       return avc_has_perm(&selinux_state,
-                           current_sid(), SECINITSID_KERNEL, SECCLASS_SYSTEM,
+       return avc_has_perm(current_sid(), SECINITSID_KERNEL, SECCLASS_SYSTEM,
                            SYSTEM__MODULE_REQUEST, &ad);
 }
 
@@ -4049,8 +3980,7 @@ static int selinux_kernel_module_from_file(struct file *file)
 
        /* init_module */
        if (file == NULL)
-               return avc_has_perm(&selinux_state,
-                                   sid, sid, SECCLASS_SYSTEM,
+               return avc_has_perm(sid, sid, SECCLASS_SYSTEM,
                                        SYSTEM__MODULE_LOAD, NULL);
 
        /* finit_module */
@@ -4060,15 +3990,13 @@ static int selinux_kernel_module_from_file(struct file *file)
 
        fsec = selinux_file(file);
        if (sid != fsec->sid) {
-               rc = avc_has_perm(&selinux_state,
-                                 sid, fsec->sid, SECCLASS_FD, FD__USE, &ad);
+               rc = avc_has_perm(sid, fsec->sid, SECCLASS_FD, FD__USE, &ad);
                if (rc)
                        return rc;
        }
 
        isec = inode_security(file_inode(file));
-       return avc_has_perm(&selinux_state,
-                           sid, isec->sid, SECCLASS_SYSTEM,
+       return avc_has_perm(sid, isec->sid, SECCLASS_SYSTEM,
                                SYSTEM__MODULE_LOAD, &ad);
 }
 
@@ -4106,22 +4034,19 @@ static int selinux_kernel_load_data(enum kernel_load_data_id id, bool contents)
 
 static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
 {
-       return avc_has_perm(&selinux_state,
-                           current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
+       return avc_has_perm(current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
                            PROCESS__SETPGID, NULL);
 }
 
 static int selinux_task_getpgid(struct task_struct *p)
 {
-       return avc_has_perm(&selinux_state,
-                           current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
+       return avc_has_perm(current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
                            PROCESS__GETPGID, NULL);
 }
 
 static int selinux_task_getsid(struct task_struct *p)
 {
-       return avc_has_perm(&selinux_state,
-                           current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
+       return avc_has_perm(current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
                            PROCESS__GETSESSION, NULL);
 }
 
@@ -4137,22 +4062,19 @@ static void selinux_task_getsecid_obj(struct task_struct *p, u32 *secid)
 
 static int selinux_task_setnice(struct task_struct *p, int nice)
 {
-       return avc_has_perm(&selinux_state,
-                           current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
+       return avc_has_perm(current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
                            PROCESS__SETSCHED, NULL);
 }
 
 static int selinux_task_setioprio(struct task_struct *p, int ioprio)
 {
-       return avc_has_perm(&selinux_state,
-                           current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
+       return avc_has_perm(current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
                            PROCESS__SETSCHED, NULL);
 }
 
 static int selinux_task_getioprio(struct task_struct *p)
 {
-       return avc_has_perm(&selinux_state,
-                           current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
+       return avc_has_perm(current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
                            PROCESS__GETSCHED, NULL);
 }
 
@@ -4167,8 +4089,7 @@ static int selinux_task_prlimit(const struct cred *cred, const struct cred *tcre
                av |= PROCESS__SETRLIMIT;
        if (flags & LSM_PRLIMIT_READ)
                av |= PROCESS__GETRLIMIT;
-       return avc_has_perm(&selinux_state,
-                           cred_sid(cred), cred_sid(tcred),
+       return avc_has_perm(cred_sid(cred), cred_sid(tcred),
                            SECCLASS_PROCESS, av, NULL);
 }
 
@@ -4182,8 +4103,7 @@ static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
           later be used as a safe reset point for the soft limit
           upon context transitions.  See selinux_bprm_committing_creds. */
        if (old_rlim->rlim_max != new_rlim->rlim_max)
-               return avc_has_perm(&selinux_state,
-                                   current_sid(), task_sid_obj(p),
+               return avc_has_perm(current_sid(), task_sid_obj(p),
                                    SECCLASS_PROCESS, PROCESS__SETRLIMIT, NULL);
 
        return 0;
@@ -4191,22 +4111,19 @@ static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
 
 static int selinux_task_setscheduler(struct task_struct *p)
 {
-       return avc_has_perm(&selinux_state,
-                           current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
+       return avc_has_perm(current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
                            PROCESS__SETSCHED, NULL);
 }
 
 static int selinux_task_getscheduler(struct task_struct *p)
 {
-       return avc_has_perm(&selinux_state,
-                           current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
+       return avc_has_perm(current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
                            PROCESS__GETSCHED, NULL);
 }
 
 static int selinux_task_movememory(struct task_struct *p)
 {
-       return avc_has_perm(&selinux_state,
-                           current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
+       return avc_has_perm(current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
                            PROCESS__SETSCHED, NULL);
 }
 
@@ -4224,8 +4141,7 @@ static int selinux_task_kill(struct task_struct *p, struct kernel_siginfo *info,
                secid = current_sid();
        else
                secid = cred_sid(cred);
-       return avc_has_perm(&selinux_state,
-                           secid, task_sid_obj(p), SECCLASS_PROCESS, perm, NULL);
+       return avc_has_perm(secid, task_sid_obj(p), SECCLASS_PROCESS, perm, NULL);
 }
 
 static void selinux_task_to_inode(struct task_struct *p,
@@ -4245,8 +4161,8 @@ static int selinux_userns_create(const struct cred *cred)
 {
        u32 sid = current_sid();
 
-       return avc_has_perm(&selinux_state, sid, sid, SECCLASS_USER_NAMESPACE,
-                                               USER_NAMESPACE__CREATE, NULL);
+       return avc_has_perm(sid, sid, SECCLASS_USER_NAMESPACE,
+                       USER_NAMESPACE__CREATE, NULL);
 }
 
 /* Returns error only if unable to parse addresses */
@@ -4504,7 +4420,7 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
        if (unlikely(err))
                return -EACCES;
 
-       err = security_net_peersid_resolve(&selinux_state, nlbl_sid,
+       err = security_net_peersid_resolve(nlbl_sid,
                                           nlbl_type, xfrm_sid, sid);
        if (unlikely(err)) {
                pr_warn(
@@ -4533,7 +4449,7 @@ static int selinux_conn_sid(u32 sk_sid, u32 skb_sid, u32 *conn_sid)
        int err = 0;
 
        if (skb_sid != SECSID_NULL)
-               err = security_sid_mls_copy(&selinux_state, sk_sid, skb_sid,
+               err = security_sid_mls_copy(sk_sid, skb_sid,
                                            conn_sid);
        else
                *conn_sid = sk_sid;
@@ -4551,7 +4467,7 @@ static int socket_sockcreate_sid(const struct task_security_struct *tsec,
                return 0;
        }
 
-       return security_transition_sid(&selinux_state, tsec->sid, tsec->sid,
+       return security_transition_sid(tsec->sid, tsec->sid,
                                       secclass, NULL, socksid);
 }
 
@@ -4568,8 +4484,7 @@ static int sock_has_perm(struct sock *sk, u32 perms)
        ad.u.net = &net;
        ad.u.net->sk = sk;
 
-       return avc_has_perm(&selinux_state,
-                           current_sid(), sksec->sid, sksec->sclass, perms,
+       return avc_has_perm(current_sid(), sksec->sid, sksec->sclass, perms,
                            &ad);
 }
 
@@ -4589,8 +4504,7 @@ static int selinux_socket_create(int family, int type,
        if (rc)
                return rc;
 
-       return avc_has_perm(&selinux_state,
-                           tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
+       return avc_has_perm(tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
 }
 
 static int selinux_socket_post_create(struct socket *sock, int family,
@@ -4719,8 +4633,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
                                                      snum, &sid);
                                if (err)
                                        goto out;
-                               err = avc_has_perm(&selinux_state,
-                                                  sksec->sid, sid,
+                               err = avc_has_perm(sksec->sid, sid,
                                                   sksec->sclass,
                                                   SOCKET__NAME_BIND, &ad);
                                if (err)
@@ -4759,8 +4672,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
                else
                        ad.u.net->v6info.saddr = addr6->sin6_addr;
 
-               err = avc_has_perm(&selinux_state,
-                                  sksec->sid, sid,
+               err = avc_has_perm(sksec->sid, sid,
                                   sksec->sclass, node_perm, &ad);
                if (err)
                        goto out;
@@ -4858,8 +4770,7 @@ static int selinux_socket_connect_helper(struct socket *sock,
                ad.u.net = &net;
                ad.u.net->dport = htons(snum);
                ad.u.net->family = address->sa_family;
-               err = avc_has_perm(&selinux_state,
-                                  sksec->sid, sid, sksec->sclass, perm, &ad);
+               err = avc_has_perm(sksec->sid, sid, sksec->sclass, perm, &ad);
                if (err)
                        return err;
        }
@@ -4971,8 +4882,7 @@ static int selinux_socket_unix_stream_connect(struct sock *sock,
        ad.u.net = &net;
        ad.u.net->sk = other;
 
-       err = avc_has_perm(&selinux_state,
-                          sksec_sock->sid, sksec_other->sid,
+       err = avc_has_perm(sksec_sock->sid, sksec_other->sid,
                           sksec_other->sclass,
                           UNIX_STREAM_SOCKET__CONNECTTO, &ad);
        if (err)
@@ -4980,7 +4890,7 @@ static int selinux_socket_unix_stream_connect(struct sock *sock,
 
        /* server child socket */
        sksec_new->peer_sid = sksec_sock->sid;
-       err = security_sid_mls_copy(&selinux_state, sksec_other->sid,
+       err = security_sid_mls_copy(sksec_other->sid,
                                    sksec_sock->sid, &sksec_new->sid);
        if (err)
                return err;
@@ -5003,8 +4913,7 @@ static int selinux_socket_unix_may_send(struct socket *sock,
        ad.u.net = &net;
        ad.u.net->sk = other->sk;
 
-       return avc_has_perm(&selinux_state,
-                           ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO,
+       return avc_has_perm(ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO,
                            &ad);
 }
 
@@ -5019,8 +4928,7 @@ static int selinux_inet_sys_rcv_skb(struct net *ns, int ifindex,
        err = sel_netif_sid(ns, ifindex, &if_sid);
        if (err)
                return err;
-       err = avc_has_perm(&selinux_state,
-                          peer_sid, if_sid,
+       err = avc_has_perm(peer_sid, if_sid,
                           SECCLASS_NETIF, NETIF__INGRESS, ad);
        if (err)
                return err;
@@ -5028,8 +4936,7 @@ static int selinux_inet_sys_rcv_skb(struct net *ns, int ifindex,
        err = sel_netnode_sid(addrp, family, &node_sid);
        if (err)
                return err;
-       return avc_has_perm(&selinux_state,
-                           peer_sid, node_sid,
+       return avc_has_perm(peer_sid, node_sid,
                            SECCLASS_NODE, NODE__RECVFROM, ad);
 }
 
@@ -5052,8 +4959,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
                return err;
 
        if (selinux_secmark_enabled()) {
-               err = avc_has_perm(&selinux_state,
-                                  sk_sid, skb->secmark, SECCLASS_PACKET,
+               err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
                                   PACKET__RECV, &ad);
                if (err)
                        return err;
@@ -5118,8 +5024,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
                        selinux_netlbl_err(skb, family, err, 0);
                        return err;
                }
-               err = avc_has_perm(&selinux_state,
-                                  sk_sid, peer_sid, SECCLASS_PEER,
+               err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER,
                                   PEER__RECV, &ad);
                if (err) {
                        selinux_netlbl_err(skb, family, err, 0);
@@ -5128,8 +5033,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
        }
 
        if (secmark_active) {
-               err = avc_has_perm(&selinux_state,
-                                  sk_sid, skb->secmark, SECCLASS_PACKET,
+               err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
                                   PACKET__RECV, &ad);
                if (err)
                        return err;
@@ -5155,7 +5059,7 @@ static int selinux_socket_getpeersec_stream(struct socket *sock,
        if (peer_sid == SECSID_NULL)
                return -ENOPROTOOPT;
 
-       err = security_sid_to_context(&selinux_state, peer_sid, &scontext,
+       err = security_sid_to_context(peer_sid, &scontext,
                                      &scontext_len);
        if (err)
                return err;
@@ -5312,8 +5216,7 @@ static int selinux_sctp_process_new_assoc(struct sctp_association *asoc,
                ad.type = LSM_AUDIT_DATA_NET;
                ad.u.net = &net;
                ad.u.net->sk = asoc->base.sk;
-               err = avc_has_perm(&selinux_state,
-                                  sksec->peer_sid, asoc->peer_secid,
+               err = avc_has_perm(sksec->peer_sid, asoc->peer_secid,
                                   sksec->sclass, SCTP_SOCKET__ASSOCIATION,
                                   &ad);
                if (err)
@@ -5534,8 +5437,7 @@ static int selinux_secmark_relabel_packet(u32 sid)
        __tsec = selinux_cred(current_cred());
        tsid = __tsec->sid;
 
-       return avc_has_perm(&selinux_state,
-                           tsid, sid, SECCLASS_PACKET, PACKET__RELABELTO,
+       return avc_has_perm(tsid, sid, SECCLASS_PACKET, PACKET__RELABELTO,
                            NULL);
 }
 
@@ -5584,8 +5486,7 @@ static int selinux_tun_dev_create(void)
         * connections unlike traditional sockets - check the TUN driver to
         * get a better understanding of why this socket is special */
 
-       return avc_has_perm(&selinux_state,
-                           sid, sid, SECCLASS_TUN_SOCKET, TUN_SOCKET__CREATE,
+       return avc_has_perm(sid, sid, SECCLASS_TUN_SOCKET, TUN_SOCKET__CREATE,
                            NULL);
 }
 
@@ -5593,8 +5494,7 @@ static int selinux_tun_dev_attach_queue(void *security)
 {
        struct tun_security_struct *tunsec = security;
 
-       return avc_has_perm(&selinux_state,
-                           current_sid(), tunsec->sid, SECCLASS_TUN_SOCKET,
+       return avc_has_perm(current_sid(), tunsec->sid, SECCLASS_TUN_SOCKET,
                            TUN_SOCKET__ATTACH_QUEUE, NULL);
 }
 
@@ -5622,13 +5522,11 @@ static int selinux_tun_dev_open(void *security)
        u32 sid = current_sid();
        int err;
 
-       err = avc_has_perm(&selinux_state,
-                          sid, tunsec->sid, SECCLASS_TUN_SOCKET,
+       err = avc_has_perm(sid, tunsec->sid, SECCLASS_TUN_SOCKET,
                           TUN_SOCKET__RELABELFROM, NULL);
        if (err)
                return err;
-       err = avc_has_perm(&selinux_state,
-                          sid, sid, SECCLASS_TUN_SOCKET,
+       err = avc_has_perm(sid, sid, SECCLASS_TUN_SOCKET,
                           TUN_SOCKET__RELABELTO, NULL);
        if (err)
                return err;
@@ -5682,8 +5580,7 @@ static unsigned int selinux_ip_forward(void *priv, struct sk_buff *skb,
        }
 
        if (secmark_active)
-               if (avc_has_perm(&selinux_state,
-                                peer_sid, skb->secmark,
+               if (avc_has_perm(peer_sid, skb->secmark,
                                 SECCLASS_PACKET, PACKET__FORWARD_IN, &ad))
                        return NF_DROP;
 
@@ -5763,8 +5660,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
                return NF_DROP;
 
        if (selinux_secmark_enabled())
-               if (avc_has_perm(&selinux_state,
-                                sksec->sid, skb->secmark,
+               if (avc_has_perm(sksec->sid, skb->secmark,
                                 SECCLASS_PACKET, PACKET__SEND, &ad))
                        return NF_DROP_ERR(-ECONNREFUSED);
 
@@ -5889,8 +5785,7 @@ static unsigned int selinux_ip_postroute(void *priv,
                return NF_DROP;
 
        if (secmark_active)
-               if (avc_has_perm(&selinux_state,
-                                peer_sid, skb->secmark,
+               if (avc_has_perm(peer_sid, skb->secmark,
                                 SECCLASS_PACKET, secmark_perm, &ad))
                        return NF_DROP_ERR(-ECONNREFUSED);
 
@@ -5900,15 +5795,13 @@ static unsigned int selinux_ip_postroute(void *priv,
 
                if (sel_netif_sid(state->net, ifindex, &if_sid))
                        return NF_DROP;
-               if (avc_has_perm(&selinux_state,
-                                peer_sid, if_sid,
+               if (avc_has_perm(peer_sid, if_sid,
                                 SECCLASS_NETIF, NETIF__EGRESS, &ad))
                        return NF_DROP_ERR(-ECONNREFUSED);
 
                if (sel_netnode_sid(addrp, family, &node_sid))
                        return NF_DROP;
-               if (avc_has_perm(&selinux_state,
-                                peer_sid, node_sid,
+               if (avc_has_perm(peer_sid, node_sid,
                                 SECCLASS_NODE, NODE__SENDTO, &ad))
                        return NF_DROP_ERR(-ECONNREFUSED);
        }
@@ -5953,8 +5846,8 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
                                sk->sk_protocol, nlh->nlmsg_type,
                                secclass_map[sclass - 1].name,
                                task_pid_nr(current), current->comm);
-                       if (enforcing_enabled(&selinux_state) &&
-                           !security_get_allow_unknown(&selinux_state))
+                       if (enforcing_enabled() &&
+                           !security_get_allow_unknown())
                                return rc;
                        rc = 0;
                } else if (rc == -ENOENT) {
@@ -5993,8 +5886,7 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = ipc_perms->key;
 
-       return avc_has_perm(&selinux_state,
-                           sid, isec->sid, isec->sclass, perms, &ad);
+       return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad);
 }
 
 static int selinux_msg_msg_alloc_security(struct msg_msg *msg)
@@ -6020,8 +5912,7 @@ static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq)
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = msq->key;
 
-       return avc_has_perm(&selinux_state,
-                           sid, isec->sid, SECCLASS_MSGQ,
+       return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
                            MSGQ__CREATE, &ad);
 }
 
@@ -6036,8 +5927,7 @@ static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg)
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = msq->key;
 
-       return avc_has_perm(&selinux_state,
-                           sid, isec->sid, SECCLASS_MSGQ,
+       return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
                            MSGQ__ASSOCIATE, &ad);
 }
 
@@ -6050,8 +5940,7 @@ static int selinux_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd)
        case IPC_INFO:
        case MSG_INFO:
                /* No specific object, just general system-wide information. */
-               return avc_has_perm(&selinux_state,
-                                   current_sid(), SECINITSID_KERNEL,
+               return avc_has_perm(current_sid(), SECINITSID_KERNEL,
                                    SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
        case IPC_STAT:
        case MSG_STAT:
@@ -6091,7 +5980,7 @@ static int selinux_msg_queue_msgsnd(struct kern_ipc_perm *msq, struct msg_msg *m
                 * Compute new sid based on current process and
                 * message queue this message will be stored in
                 */
-               rc = security_transition_sid(&selinux_state, sid, isec->sid,
+               rc = security_transition_sid(sid, isec->sid,
                                             SECCLASS_MSG, NULL, &msec->sid);
                if (rc)
                        return rc;
@@ -6101,18 +5990,15 @@ static int selinux_msg_queue_msgsnd(struct kern_ipc_perm *msq, struct msg_msg *m
        ad.u.ipc_id = msq->key;
 
        /* Can this process write to the queue? */
-       rc = avc_has_perm(&selinux_state,
-                         sid, isec->sid, SECCLASS_MSGQ,
+       rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
                          MSGQ__WRITE, &ad);
        if (!rc)
                /* Can this process send the message */
-               rc = avc_has_perm(&selinux_state,
-                                 sid, msec->sid, SECCLASS_MSG,
+               rc = avc_has_perm(sid, msec->sid, SECCLASS_MSG,
                                  MSG__SEND, &ad);
        if (!rc)
                /* Can the message be put in the queue? */
-               rc = avc_has_perm(&selinux_state,
-                                 msec->sid, isec->sid, SECCLASS_MSGQ,
+               rc = avc_has_perm(msec->sid, isec->sid, SECCLASS_MSGQ,
                                  MSGQ__ENQUEUE, &ad);
 
        return rc;
@@ -6134,12 +6020,10 @@ static int selinux_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *m
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = msq->key;
 
-       rc = avc_has_perm(&selinux_state,
-                         sid, isec->sid,
+       rc = avc_has_perm(sid, isec->sid,
                          SECCLASS_MSGQ, MSGQ__READ, &ad);
        if (!rc)
-               rc = avc_has_perm(&selinux_state,
-                                 sid, msec->sid,
+               rc = avc_has_perm(sid, msec->sid,
                                  SECCLASS_MSG, MSG__RECEIVE, &ad);
        return rc;
 }
@@ -6157,8 +6041,7 @@ static int selinux_shm_alloc_security(struct kern_ipc_perm *shp)
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = shp->key;
 
-       return avc_has_perm(&selinux_state,
-                           sid, isec->sid, SECCLASS_SHM,
+       return avc_has_perm(sid, isec->sid, SECCLASS_SHM,
                            SHM__CREATE, &ad);
 }
 
@@ -6173,8 +6056,7 @@ static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg)
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = shp->key;
 
-       return avc_has_perm(&selinux_state,
-                           sid, isec->sid, SECCLASS_SHM,
+       return avc_has_perm(sid, isec->sid, SECCLASS_SHM,
                            SHM__ASSOCIATE, &ad);
 }
 
@@ -6188,8 +6070,7 @@ static int selinux_shm_shmctl(struct kern_ipc_perm *shp, int cmd)
        case IPC_INFO:
        case SHM_INFO:
                /* No specific object, just general system-wide information. */
-               return avc_has_perm(&selinux_state,
-                                   current_sid(), SECINITSID_KERNEL,
+               return avc_has_perm(current_sid(), SECINITSID_KERNEL,
                                    SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
        case IPC_STAT:
        case SHM_STAT:
@@ -6240,8 +6121,7 @@ static int selinux_sem_alloc_security(struct kern_ipc_perm *sma)
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = sma->key;
 
-       return avc_has_perm(&selinux_state,
-                           sid, isec->sid, SECCLASS_SEM,
+       return avc_has_perm(sid, isec->sid, SECCLASS_SEM,
                            SEM__CREATE, &ad);
 }
 
@@ -6256,8 +6136,7 @@ static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg)
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = sma->key;
 
-       return avc_has_perm(&selinux_state,
-                           sid, isec->sid, SECCLASS_SEM,
+       return avc_has_perm(sid, isec->sid, SECCLASS_SEM,
                            SEM__ASSOCIATE, &ad);
 }
 
@@ -6271,8 +6150,7 @@ static int selinux_sem_semctl(struct kern_ipc_perm *sma, int cmd)
        case IPC_INFO:
        case SEM_INFO:
                /* No specific object, just general system-wide information. */
-               return avc_has_perm(&selinux_state,
-                                   current_sid(), SECINITSID_KERNEL,
+               return avc_has_perm(current_sid(), SECINITSID_KERNEL,
                                    SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
        case GETPID:
        case GETNCNT:
@@ -6359,8 +6237,7 @@ static int selinux_getprocattr(struct task_struct *p,
        __tsec = selinux_cred(__task_cred(p));
 
        if (current != p) {
-               error = avc_has_perm(&selinux_state,
-                                    current_sid(), __tsec->sid,
+               error = avc_has_perm(current_sid(), __tsec->sid,
                                     SECCLASS_PROCESS, PROCESS__GETATTR, NULL);
                if (error)
                        goto bad;
@@ -6387,7 +6264,7 @@ static int selinux_getprocattr(struct task_struct *p,
        if (!sid)
                return 0;
 
-       error = security_sid_to_context(&selinux_state, sid, value, &len);
+       error = security_sid_to_context(sid, value, &len);
        if (error)
                return error;
        return len;
@@ -6409,24 +6286,19 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
         * Basic control over ability to set these attributes at all.
         */
        if (!strcmp(name, "exec"))
-               error = avc_has_perm(&selinux_state,
-                                    mysid, mysid, SECCLASS_PROCESS,
+               error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
                                     PROCESS__SETEXEC, NULL);
        else if (!strcmp(name, "fscreate"))
-               error = avc_has_perm(&selinux_state,
-                                    mysid, mysid, SECCLASS_PROCESS,
+               error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
                                     PROCESS__SETFSCREATE, NULL);
        else if (!strcmp(name, "keycreate"))
-               error = avc_has_perm(&selinux_state,
-                                    mysid, mysid, SECCLASS_PROCESS,
+               error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
                                     PROCESS__SETKEYCREATE, NULL);
        else if (!strcmp(name, "sockcreate"))
-               error = avc_has_perm(&selinux_state,
-                                    mysid, mysid, SECCLASS_PROCESS,
+               error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
                                     PROCESS__SETSOCKCREATE, NULL);
        else if (!strcmp(name, "current"))
-               error = avc_has_perm(&selinux_state,
-                                    mysid, mysid, SECCLASS_PROCESS,
+               error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
                                     PROCESS__SETCURRENT, NULL);
        else
                error = -EINVAL;
@@ -6439,7 +6311,7 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
                        str[size-1] = 0;
                        size--;
                }
-               error = security_context_to_sid(&selinux_state, value, size,
+               error = security_context_to_sid(value, size,
                                                &sid, GFP_KERNEL);
                if (error == -EINVAL && !strcmp(name, "fscreate")) {
                        if (!has_cap_mac_admin(true)) {
@@ -6463,9 +6335,8 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
 
                                return error;
                        }
-                       error = security_context_to_sid_force(
-                                                     &selinux_state,
-                                                     value, size, &sid);
+                       error = security_context_to_sid_force(value, size,
+                                                       &sid);
                }
                if (error)
                        return error;
@@ -6488,7 +6359,7 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
                tsec->create_sid = sid;
        } else if (!strcmp(name, "keycreate")) {
                if (sid) {
-                       error = avc_has_perm(&selinux_state, mysid, sid,
+                       error = avc_has_perm(mysid, sid,
                                             SECCLASS_KEY, KEY__CREATE, NULL);
                        if (error)
                                goto abort_change;
@@ -6503,15 +6374,13 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
 
                /* Only allow single threaded processes to change context */
                if (!current_is_single_threaded()) {
-                       error = security_bounded_transition(&selinux_state,
-                                                           tsec->sid, sid);
+                       error = security_bounded_transition(tsec->sid, sid);
                        if (error)
                                goto abort_change;
                }
 
                /* Check permissions for the transition. */
-               error = avc_has_perm(&selinux_state,
-                                    tsec->sid, sid, SECCLASS_PROCESS,
+               error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS,
                                     PROCESS__DYNTRANSITION, NULL);
                if (error)
                        goto abort_change;
@@ -6520,8 +6389,7 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
                   Otherwise, leave SID unchanged and fail. */
                ptsid = ptrace_parent_sid();
                if (ptsid != 0) {
-                       error = avc_has_perm(&selinux_state,
-                                            ptsid, sid, SECCLASS_PROCESS,
+                       error = avc_has_perm(ptsid, sid, SECCLASS_PROCESS,
                                             PROCESS__PTRACE, NULL);
                        if (error)
                                goto abort_change;
@@ -6548,13 +6416,13 @@ static int selinux_ismaclabel(const char *name)
 
 static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
 {
-       return security_sid_to_context(&selinux_state, secid,
+       return security_sid_to_context(secid,
                                       secdata, seclen);
 }
 
 static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
 {
-       return security_context_to_sid(&selinux_state, secdata, seclen,
+       return security_context_to_sid(secdata, seclen,
                                       secid, GFP_KERNEL);
 }
 
@@ -6674,8 +6542,7 @@ static int selinux_key_permission(key_ref_t key_ref,
        key = key_ref_to_ptr(key_ref);
        ksec = key->security;
 
-       return avc_has_perm(&selinux_state,
-                           sid, ksec->sid, SECCLASS_KEY, perm, NULL);
+       return avc_has_perm(sid, ksec->sid, SECCLASS_KEY, perm, NULL);
 }
 
 static int selinux_key_getsecurity(struct key *key, char **_buffer)
@@ -6685,7 +6552,7 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
        unsigned len;
        int rc;
 
-       rc = security_sid_to_context(&selinux_state, ksec->sid,
+       rc = security_sid_to_context(ksec->sid,
                                     &context, &len);
        if (!rc)
                rc = len;
@@ -6699,8 +6566,7 @@ static int selinux_watch_key(struct key *key)
        struct key_security_struct *ksec = key->security;
        u32 sid = current_sid();
 
-       return avc_has_perm(&selinux_state,
-                           sid, ksec->sid, SECCLASS_KEY, KEY__VIEW, NULL);
+       return avc_has_perm(sid, ksec->sid, SECCLASS_KEY, KEY__VIEW, NULL);
 }
 #endif
 #endif
@@ -6722,8 +6588,7 @@ static int selinux_ib_pkey_access(void *ib_sec, u64 subnet_prefix, u16 pkey_val)
        ibpkey.subnet_prefix = subnet_prefix;
        ibpkey.pkey = pkey_val;
        ad.u.ibpkey = &ibpkey;
-       return avc_has_perm(&selinux_state,
-                           sec->sid, sid,
+       return avc_has_perm(sec->sid, sid,
                            SECCLASS_INFINIBAND_PKEY,
                            INFINIBAND_PKEY__ACCESS, &ad);
 }
@@ -6737,7 +6602,7 @@ static int selinux_ib_endport_manage_subnet(void *ib_sec, const char *dev_name,
        struct ib_security_struct *sec = ib_sec;
        struct lsm_ibendport_audit ibendport;
 
-       err = security_ib_endport_sid(&selinux_state, dev_name, port_num,
+       err = security_ib_endport_sid(dev_name, port_num,
                                      &sid);
 
        if (err)
@@ -6747,8 +6612,7 @@ static int selinux_ib_endport_manage_subnet(void *ib_sec, const char *dev_name,
        ibendport.dev_name = dev_name;
        ibendport.port = port_num;
        ad.u.ibendport = &ibendport;
-       return avc_has_perm(&selinux_state,
-                           sec->sid, sid,
+       return avc_has_perm(sec->sid, sid,
                            SECCLASS_INFINIBAND_ENDPORT,
                            INFINIBAND_ENDPORT__MANAGE_SUBNET, &ad);
 }
@@ -6781,13 +6645,11 @@ static int selinux_bpf(int cmd, union bpf_attr *attr,
 
        switch (cmd) {
        case BPF_MAP_CREATE:
-               ret = avc_has_perm(&selinux_state,
-                                  sid, sid, SECCLASS_BPF, BPF__MAP_CREATE,
+               ret = avc_has_perm(sid, sid, SECCLASS_BPF, BPF__MAP_CREATE,
                                   NULL);
                break;
        case BPF_PROG_LOAD:
-               ret = avc_has_perm(&selinux_state,
-                                  sid, sid, SECCLASS_BPF, BPF__PROG_LOAD,
+               ret = avc_has_perm(sid, sid, SECCLASS_BPF, BPF__PROG_LOAD,
                                   NULL);
                break;
        default:
@@ -6827,16 +6689,14 @@ static int bpf_fd_pass(struct file *file, u32 sid)
        if (file->f_op == &bpf_map_fops) {
                map = file->private_data;
                bpfsec = map->security;
-               ret = avc_has_perm(&selinux_state,
-                                  sid, bpfsec->sid, SECCLASS_BPF,
+               ret = avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
                                   bpf_map_fmode_to_av(file->f_mode), NULL);
                if (ret)
                        return ret;
        } else if (file->f_op == &bpf_prog_fops) {
                prog = file->private_data;
                bpfsec = prog->aux->security;
-               ret = avc_has_perm(&selinux_state,
-                                  sid, bpfsec->sid, SECCLASS_BPF,
+               ret = avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
                                   BPF__PROG_RUN, NULL);
                if (ret)
                        return ret;
@@ -6850,8 +6710,7 @@ static int selinux_bpf_map(struct bpf_map *map, fmode_t fmode)
        struct bpf_security_struct *bpfsec;
 
        bpfsec = map->security;
-       return avc_has_perm(&selinux_state,
-                           sid, bpfsec->sid, SECCLASS_BPF,
+       return avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
                            bpf_map_fmode_to_av(fmode), NULL);
 }
 
@@ -6861,8 +6720,7 @@ static int selinux_bpf_prog(struct bpf_prog *prog)
        struct bpf_security_struct *bpfsec;
 
        bpfsec = prog->aux->security;
-       return avc_has_perm(&selinux_state,
-                           sid, bpfsec->sid, SECCLASS_BPF,
+       return avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
                            BPF__PROG_RUN, NULL);
 }
 
@@ -6911,7 +6769,7 @@ static void selinux_bpf_prog_free(struct bpf_prog_aux *aux)
 }
 #endif
 
-struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = {
+struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
        .lbs_cred = sizeof(struct task_security_struct),
        .lbs_file = sizeof(struct file_security_struct),
        .lbs_inode = sizeof(struct inode_security_struct),
@@ -6936,7 +6794,7 @@ static int selinux_perf_event_open(struct perf_event_attr *attr, int type)
        else
                return -EINVAL;
 
-       return avc_has_perm(&selinux_state, sid, sid, SECCLASS_PERF_EVENT,
+       return avc_has_perm(sid, sid, SECCLASS_PERF_EVENT,
                            requested, NULL);
 }
 
@@ -6967,7 +6825,7 @@ static int selinux_perf_event_read(struct perf_event *event)
        struct perf_event_security_struct *perfsec = event->security;
        u32 sid = current_sid();
 
-       return avc_has_perm(&selinux_state, sid, perfsec->sid,
+       return avc_has_perm(sid, perfsec->sid,
                            SECCLASS_PERF_EVENT, PERF_EVENT__READ, NULL);
 }
 
@@ -6976,7 +6834,7 @@ static int selinux_perf_event_write(struct perf_event *event)
        struct perf_event_security_struct *perfsec = event->security;
        u32 sid = current_sid();
 
-       return avc_has_perm(&selinux_state, sid, perfsec->sid,
+       return avc_has_perm(sid, perfsec->sid,
                            SECCLASS_PERF_EVENT, PERF_EVENT__WRITE, NULL);
 }
 #endif
@@ -6991,7 +6849,7 @@ static int selinux_perf_event_write(struct perf_event *event)
  */
 static int selinux_uring_override_creds(const struct cred *new)
 {
-       return avc_has_perm(&selinux_state, current_sid(), cred_sid(new),
+       return avc_has_perm(current_sid(), cred_sid(new),
                            SECCLASS_IO_URING, IO_URING__OVERRIDE_CREDS, NULL);
 }
 
@@ -7005,7 +6863,7 @@ static int selinux_uring_sqpoll(void)
 {
        int sid = current_sid();
 
-       return avc_has_perm(&selinux_state, sid, sid,
+       return avc_has_perm(sid, sid,
                            SECCLASS_IO_URING, IO_URING__SQPOLL, NULL);
 }
 
@@ -7027,7 +6885,7 @@ static int selinux_uring_cmd(struct io_uring_cmd *ioucmd)
        ad.type = LSM_AUDIT_DATA_FILE;
        ad.u.file = file;
 
-       return avc_has_perm(&selinux_state, current_sid(), isec->sid,
+       return avc_has_perm(current_sid(), isec->sid,
                            SECCLASS_IO_URING, IO_URING__CMD, &ad);
 }
 #endif /* CONFIG_IO_URING */
@@ -7047,7 +6905,7 @@ static int selinux_uring_cmd(struct io_uring_cmd *ioucmd)
  * safely. Breaking the ordering rules above might lead to NULL pointer derefs
  * when disabling SELinux at runtime.
  */
-static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
+static struct security_hook_list selinux_hooks[] __ro_after_init = {
        LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr),
        LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction),
        LSM_HOOK_INIT(binder_transfer_binder, selinux_binder_transfer_binder),
@@ -7334,11 +7192,8 @@ static __init int selinux_init(void)
        pr_info("SELinux:  Initializing.\n");
 
        memset(&selinux_state, 0, sizeof(selinux_state));
-       enforcing_set(&selinux_state, selinux_enforcing_boot);
-       if (CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE)
-               pr_err("SELinux: CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE is non-zero.  This is deprecated and will be rejected in a future kernel release.\n");
-       checkreqprot_set(&selinux_state, selinux_checkreqprot_boot);
-       selinux_avc_init(&selinux_state.avc);
+       enforcing_set(selinux_enforcing_boot);
+       selinux_avc_init();
        mutex_init(&selinux_state.status_lock);
        mutex_init(&selinux_state.policy_mutex);
 
@@ -7398,7 +7253,6 @@ DEFINE_LSM(selinux) = {
 };
 
 #if defined(CONFIG_NETFILTER)
-
 static const struct nf_hook_ops selinux_nf_ops[] = {
        {
                .hook =         selinux_ip_postroute,
@@ -7473,56 +7327,4 @@ static int __init selinux_nf_ip_init(void)
        return 0;
 }
 __initcall(selinux_nf_ip_init);
-
-#ifdef CONFIG_SECURITY_SELINUX_DISABLE
-static void selinux_nf_ip_exit(void)
-{
-       pr_debug("SELinux:  Unregistering netfilter hooks\n");
-
-       unregister_pernet_subsys(&selinux_net_ops);
-}
-#endif
-
-#else /* CONFIG_NETFILTER */
-
-#ifdef CONFIG_SECURITY_SELINUX_DISABLE
-#define selinux_nf_ip_exit()
-#endif
-
 #endif /* CONFIG_NETFILTER */
-
-#ifdef CONFIG_SECURITY_SELINUX_DISABLE
-int selinux_disable(struct selinux_state *state)
-{
-       if (selinux_initialized(state)) {
-               /* Not permitted after initial policy load. */
-               return -EINVAL;
-       }
-
-       if (selinux_disabled(state)) {
-               /* Only do this once. */
-               return -EINVAL;
-       }
-
-       selinux_mark_disabled(state);
-
-       pr_info("SELinux:  Disabled at runtime.\n");
-
-       /*
-        * Unregister netfilter hooks.
-        * Must be done before security_delete_hooks() to avoid breaking
-        * runtime disable.
-        */
-       selinux_nf_ip_exit();
-
-       security_delete_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks));
-
-       /* Try to destroy the avc node cache */
-       avc_disable();
-
-       /* Unregister selinuxfs. */
-       exit_sel_fs();
-
-       return 0;
-}
-#endif
index 5839ca7bb9c75807097ddb558d199101dfdb7a55..48f537b41c583235d08bf2985c4fb45da9078bec 100644 (file)
@@ -141,7 +141,7 @@ static int sel_ib_pkey_sid_slow(u64 subnet_prefix, u16 pkey_num, u32 *sid)
                return 0;
        }
 
-       ret = security_ib_pkey_sid(&selinux_state, subnet_prefix, pkey_num,
+       ret = security_ib_pkey_sid(subnet_prefix, pkey_num,
                                   sid);
        if (ret)
                goto out;
index a915b89d55b0c1281d60acd22241cae79f4a0659..7daf59667f5975daa2fc565843b35185ff001e86 100644 (file)
 /*
  * selinux_ima_collect_state - Read selinux configuration settings
  *
- * @state: selinux_state
- *
  * On success returns the configuration settings string.
  * On error, returns NULL.
  */
-static char *selinux_ima_collect_state(struct selinux_state *state)
+static char *selinux_ima_collect_state(void)
 {
        const char *on = "=1;", *off = "=0;";
        char *buf;
@@ -39,26 +37,27 @@ static char *selinux_ima_collect_state(struct selinux_state *state)
        rc = strscpy(buf, "initialized", buf_len);
        WARN_ON(rc < 0);
 
-       rc = strlcat(buf, selinux_initialized(state) ? on : off, buf_len);
+       rc = strlcat(buf, selinux_initialized() ? on : off, buf_len);
        WARN_ON(rc >= buf_len);
 
        rc = strlcat(buf, "enforcing", buf_len);
        WARN_ON(rc >= buf_len);
 
-       rc = strlcat(buf, enforcing_enabled(state) ? on : off, buf_len);
+       rc = strlcat(buf, enforcing_enabled() ? on : off, buf_len);
        WARN_ON(rc >= buf_len);
 
        rc = strlcat(buf, "checkreqprot", buf_len);
        WARN_ON(rc >= buf_len);
 
-       rc = strlcat(buf, checkreqprot_get(state) ? on : off, buf_len);
+       rc = strlcat(buf, checkreqprot_get() ? on : off, buf_len);
        WARN_ON(rc >= buf_len);
 
        for (i = 0; i < __POLICYDB_CAP_MAX; i++) {
                rc = strlcat(buf, selinux_policycap_names[i], buf_len);
                WARN_ON(rc >= buf_len);
 
-               rc = strlcat(buf, state->policycap[i] ? on : off, buf_len);
+               rc = strlcat(buf, selinux_state.policycap[i] ? on : off,
+                       buf_len);
                WARN_ON(rc >= buf_len);
        }
 
@@ -67,19 +66,17 @@ static char *selinux_ima_collect_state(struct selinux_state *state)
 
 /*
  * selinux_ima_measure_state_locked - Measure SELinux state and hash of policy
- *
- * @state: selinux state struct
  */
-void selinux_ima_measure_state_locked(struct selinux_state *state)
+void selinux_ima_measure_state_locked(void)
 {
        char *state_str = NULL;
        void *policy = NULL;
        size_t policy_len;
        int rc = 0;
 
-       lockdep_assert_held(&state->policy_mutex);
+       lockdep_assert_held(&selinux_state.policy_mutex);
 
-       state_str = selinux_ima_collect_state(state);
+       state_str = selinux_ima_collect_state();
        if (!state_str) {
                pr_err("SELinux: %s: failed to read state.\n", __func__);
                return;
@@ -94,10 +91,10 @@ void selinux_ima_measure_state_locked(struct selinux_state *state)
        /*
         * Measure SELinux policy only after initialization is completed.
         */
-       if (!selinux_initialized(state))
+       if (!selinux_initialized())
                return;
 
-       rc = security_read_state_kernel(state, &policy, &policy_len);
+       rc = security_read_state_kernel(&policy, &policy_len);
        if (rc) {
                pr_err("SELinux: %s: failed to read policy %d.\n", __func__, rc);
                return;
@@ -112,14 +109,12 @@ void selinux_ima_measure_state_locked(struct selinux_state *state)
 
 /*
  * selinux_ima_measure_state - Measure SELinux state and hash of policy
- *
- * @state: selinux state struct
  */
-void selinux_ima_measure_state(struct selinux_state *state)
+void selinux_ima_measure_state(void)
 {
-       lockdep_assert_not_held(&state->policy_mutex);
+       lockdep_assert_not_held(&selinux_state.policy_mutex);
 
-       mutex_lock(&state->policy_mutex);
-       selinux_ima_measure_state_locked(state);
-       mutex_unlock(&state->policy_mutex);
+       mutex_lock(&selinux_state.policy_mutex);
+       selinux_ima_measure_state_locked();
+       mutex_unlock(&selinux_state.policy_mutex);
 }
index 5525b94fd2664f3631eb26e9facfc5310e854b45..9301222c8e55d22f9ef507036abf3ef30ef1f364 100644 (file)
@@ -52,7 +52,6 @@ struct selinux_audit_data {
        u32 audited;
        u32 denied;
        int result;
-       struct selinux_state *state;
 } __randomize_layout;
 
 /*
@@ -97,14 +96,12 @@ static inline u32 avc_audit_required(u32 requested,
        return audited;
 }
 
-int slow_avc_audit(struct selinux_state *state,
-                  u32 ssid, u32 tsid, u16 tclass,
+int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
                   u32 requested, u32 audited, u32 denied, int result,
                   struct common_audit_data *a);
 
 /**
  * avc_audit - Audit the granting or denial of permissions.
- * @state: SELinux state
  * @ssid: source security identifier
  * @tsid: target security identifier
  * @tclass: target security class
@@ -122,8 +119,7 @@ int slow_avc_audit(struct selinux_state *state,
  * be performed under a lock, to allow the lock to be released
  * before calling the auditing code.
  */
-static inline int avc_audit(struct selinux_state *state,
-                           u32 ssid, u32 tsid,
+static inline int avc_audit(u32 ssid, u32 tsid,
                            u16 tclass, u32 requested,
                            struct av_decision *avd,
                            int result,
@@ -133,30 +129,27 @@ static inline int avc_audit(struct selinux_state *state,
        audited = avc_audit_required(requested, avd, result, 0, &denied);
        if (likely(!audited))
                return 0;
-       return slow_avc_audit(state, ssid, tsid, tclass,
+       return slow_avc_audit(ssid, tsid, tclass,
                              requested, audited, denied, result,
                              a);
 }
 
 #define AVC_STRICT 1 /* Ignore permissive mode. */
 #define AVC_EXTENDED_PERMS 2   /* update extended permissions */
-int avc_has_perm_noaudit(struct selinux_state *state,
-                        u32 ssid, u32 tsid,
+int avc_has_perm_noaudit(u32 ssid, u32 tsid,
                         u16 tclass, u32 requested,
                         unsigned flags,
                         struct av_decision *avd);
 
-int avc_has_perm(struct selinux_state *state,
-                u32 ssid, u32 tsid,
+int avc_has_perm(u32 ssid, u32 tsid,
                 u16 tclass, u32 requested,
                 struct common_audit_data *auditdata);
 
-int avc_has_extended_perms(struct selinux_state *state,
-                          u32 ssid, u32 tsid, u16 tclass, u32 requested,
+int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested,
                           u8 driver, u8 perm, struct common_audit_data *ad);
 
 
-u32 avc_policy_seqno(struct selinux_state *state);
+u32 avc_policy_seqno(void);
 
 #define AVC_CALLBACK_GRANT             1
 #define AVC_CALLBACK_TRY_REVOKE                2
@@ -171,11 +164,9 @@ u32 avc_policy_seqno(struct selinux_state *state);
 int avc_add_callback(int (*callback)(u32 event), u32 events);
 
 /* Exported to selinuxfs */
-struct selinux_avc;
-int avc_get_hash_stats(struct selinux_avc *avc, char *page);
-unsigned int avc_get_cache_threshold(struct selinux_avc *avc);
-void avc_set_cache_threshold(struct selinux_avc *avc,
-                            unsigned int cache_threshold);
+int avc_get_hash_stats(char *page);
+unsigned int avc_get_cache_threshold(void);
+void avc_set_cache_threshold(unsigned int cache_threshold);
 
 /* Attempt to free avc node cache */
 void avc_disable(void);
index 42912c917fd40c53b4278cd5e820ac3e4686add4..b9668be7b44337e9cf8ddd4e14308b178511ea89 100644 (file)
@@ -9,8 +9,7 @@
 
 #include <linux/types.h>
 
-struct selinux_avc;
-int avc_ss_reset(struct selinux_avc *avc, u32 seqno);
+int avc_ss_reset(u32 seqno);
 
 /* Class/perm mapping support */
 struct security_class_mapping {
index b09343346e3fe435d81e31283ff8dcbcef4bc134..693a654714eb5fd1ede9c8c6a08b4f639a3036d0 100644 (file)
@@ -16,8 +16,8 @@
 int security_get_bools(struct selinux_policy *policy,
                       u32 *len, char ***names, int **values);
 
-int security_set_bools(struct selinux_state *state, u32 len, int *values);
+int security_set_bools(u32 len, int *values);
 
-int security_get_bool_value(struct selinux_state *state, u32 index);
+int security_get_bool_value(u32 index);
 
 #endif
index 75ca92b4a4622c031ab5d7b568773c13011520c1..05e04172c86d8703c6e682078b7185e3ec390428 100644 (file)
 #include "security.h"
 
 #ifdef CONFIG_IMA
-extern void selinux_ima_measure_state(struct selinux_state *selinux_state);
-extern void selinux_ima_measure_state_locked(
-                       struct selinux_state *selinux_state);
+extern void selinux_ima_measure_state(void);
+extern void selinux_ima_measure_state_locked(void);
 #else
-static inline void selinux_ima_measure_state(struct selinux_state *selinux_state)
+static inline void selinux_ima_measure_state(void)
 {
 }
-static inline void selinux_ima_measure_state_locked(
-                       struct selinux_state *selinux_state)
+static inline void selinux_ima_measure_state_locked(void)
 {
 }
 #endif
index 393aff41d3ef89db689738b45b17f9d8c5958fb4..8746fafeb778996c20938b5911be68e1b152838c 100644 (file)
@@ -86,94 +86,65 @@ extern int selinux_enabled_boot;
 /* limitation of boundary depth  */
 #define POLICYDB_BOUNDS_MAXDEPTH       4
 
-struct selinux_avc;
 struct selinux_policy;
 
 struct selinux_state {
-#ifdef CONFIG_SECURITY_SELINUX_DISABLE
-       bool disabled;
-#endif
 #ifdef CONFIG_SECURITY_SELINUX_DEVELOP
        bool enforcing;
 #endif
-       bool checkreqprot;
        bool initialized;
        bool policycap[__POLICYDB_CAP_MAX];
 
        struct page *status_page;
        struct mutex status_lock;
 
-       struct selinux_avc *avc;
        struct selinux_policy __rcu *policy;
        struct mutex policy_mutex;
 } __randomize_layout;
 
-void selinux_avc_init(struct selinux_avc **avc);
+void selinux_avc_init(void);
 
 extern struct selinux_state selinux_state;
 
-static inline bool selinux_initialized(const struct selinux_state *state)
+static inline bool selinux_initialized(void)
 {
        /* do a synchronized load to avoid race conditions */
-       return smp_load_acquire(&state->initialized);
+       return smp_load_acquire(&selinux_state.initialized);
 }
 
-static inline void selinux_mark_initialized(struct selinux_state *state)
+static inline void selinux_mark_initialized(void)
 {
        /* do a synchronized write to avoid race conditions */
-       smp_store_release(&state->initialized, true);
+       smp_store_release(&selinux_state.initialized, true);
 }
 
 #ifdef CONFIG_SECURITY_SELINUX_DEVELOP
-static inline bool enforcing_enabled(struct selinux_state *state)
+static inline bool enforcing_enabled(void)
 {
-       return READ_ONCE(state->enforcing);
+       return READ_ONCE(selinux_state.enforcing);
 }
 
-static inline void enforcing_set(struct selinux_state *state, bool value)
+static inline void enforcing_set(bool value)
 {
-       WRITE_ONCE(state->enforcing, value);
+       WRITE_ONCE(selinux_state.enforcing, value);
 }
 #else
-static inline bool enforcing_enabled(struct selinux_state *state)
+static inline bool enforcing_enabled(void)
 {
        return true;
 }
 
-static inline void enforcing_set(struct selinux_state *state, bool value)
+static inline void enforcing_set(bool value)
 {
 }
 #endif
 
-static inline bool checkreqprot_get(const struct selinux_state *state)
-{
-       return READ_ONCE(state->checkreqprot);
-}
-
-static inline void checkreqprot_set(struct selinux_state *state, bool value)
+static inline bool checkreqprot_get(void)
 {
-       if (value)
-               pr_err("SELinux: https://github.com/SELinuxProject/selinux-kernel/wiki/DEPRECATE-checkreqprot\n");
-       WRITE_ONCE(state->checkreqprot, value);
+       /* non-zero/true checkreqprot values are no longer supported */
+       return 0;
 }
 
-#ifdef CONFIG_SECURITY_SELINUX_DISABLE
-static inline bool selinux_disabled(struct selinux_state *state)
-{
-       return READ_ONCE(state->disabled);
-}
-
-static inline void selinux_mark_disabled(struct selinux_state *state)
-{
-       WRITE_ONCE(state->disabled, true);
-}
-#else
-static inline bool selinux_disabled(struct selinux_state *state)
-{
-       return false;
-}
-#endif
-
 static inline bool selinux_policycap_netpeer(void)
 {
        struct selinux_state *state = &selinux_state;
@@ -237,20 +208,14 @@ struct selinux_load_state {
        struct selinux_policy_convert_data *convert_data;
 };
 
-int security_mls_enabled(struct selinux_state *state);
-int security_load_policy(struct selinux_state *state,
-                        void *data, size_t len,
+int security_mls_enabled(void);
+int security_load_policy(void *data, size_t len,
                         struct selinux_load_state *load_state);
-void selinux_policy_commit(struct selinux_state *state,
-                          struct selinux_load_state *load_state);
-void selinux_policy_cancel(struct selinux_state *state,
-                          struct selinux_load_state *load_state);
-int security_read_policy(struct selinux_state *state,
-                        void **data, size_t *len);
-int security_read_state_kernel(struct selinux_state *state,
-                              void **data, size_t *len);
-int security_policycap_supported(struct selinux_state *state,
-                                unsigned int req_cap);
+void selinux_policy_commit(struct selinux_load_state *load_state);
+void selinux_policy_cancel(struct selinux_load_state *load_state);
+int security_read_policy(void **data, size_t *len);
+int security_read_state_kernel(void **data, size_t *len);
+int security_policycap_supported(unsigned int req_cap);
 
 #define SEL_VEC_MAX 32
 struct av_decision {
@@ -287,94 +252,68 @@ struct extended_perms {
 /* definitions of av_decision.flags */
 #define AVD_FLAGS_PERMISSIVE   0x0001
 
-void security_compute_av(struct selinux_state *state,
-                        u32 ssid, u32 tsid,
+void security_compute_av(u32 ssid, u32 tsid,
                         u16 tclass, struct av_decision *avd,
                         struct extended_perms *xperms);
 
-void security_compute_xperms_decision(struct selinux_state *state,
-                                     u32 ssid, u32 tsid, u16 tclass,
+void security_compute_xperms_decision(u32 ssid, u32 tsid, u16 tclass,
                                      u8 driver,
                                      struct extended_perms_decision *xpermd);
 
-void security_compute_av_user(struct selinux_state *state,
-                             u32 ssid, u32 tsid,
+void security_compute_av_user(u32 ssid, u32 tsid,
                              u16 tclass, struct av_decision *avd);
 
-int security_transition_sid(struct selinux_state *state,
-                           u32 ssid, u32 tsid, u16 tclass,
+int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
                            const struct qstr *qstr, u32 *out_sid);
 
-int security_transition_sid_user(struct selinux_state *state,
-                                u32 ssid, u32 tsid, u16 tclass,
+int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
                                 const char *objname, u32 *out_sid);
 
-int security_member_sid(struct selinux_state *state, u32 ssid, u32 tsid,
-                       u16 tclass, u32 *out_sid);
+int security_member_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid);
 
-int security_change_sid(struct selinux_state *state, u32 ssid, u32 tsid,
-                       u16 tclass, u32 *out_sid);
+int security_change_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid);
 
-int security_sid_to_context(struct selinux_state *state, u32 sid,
-                           char **scontext, u32 *scontext_len);
+int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len);
 
-int security_sid_to_context_force(struct selinux_state *state,
-                                 u32 sid, char **scontext, u32 *scontext_len);
+int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len);
 
-int security_sid_to_context_inval(struct selinux_state *state,
-                                 u32 sid, char **scontext, u32 *scontext_len);
+int security_sid_to_context_inval(u32 sid, char **scontext, u32 *scontext_len);
 
-int security_context_to_sid(struct selinux_state *state,
-                           const char *scontext, u32 scontext_len,
+int security_context_to_sid(const char *scontext, u32 scontext_len,
                            u32 *out_sid, gfp_t gfp);
 
-int security_context_str_to_sid(struct selinux_state *state,
-                               const char *scontext, u32 *out_sid, gfp_t gfp);
+int security_context_str_to_sid(const char *scontext, u32 *out_sid, gfp_t gfp);
 
-int security_context_to_sid_default(struct selinux_state *state,
-                                   const char *scontext, u32 scontext_len,
+int security_context_to_sid_default(const char *scontext, u32 scontext_len,
                                    u32 *out_sid, u32 def_sid, gfp_t gfp_flags);
 
-int security_context_to_sid_force(struct selinux_state *state,
-                                 const char *scontext, u32 scontext_len,
+int security_context_to_sid_force(const char *scontext, u32 scontext_len,
                                  u32 *sid);
 
-int security_get_user_sids(struct selinux_state *state,
-                          u32 callsid, char *username,
-                          u32 **sids, u32 *nel);
+int security_get_user_sids(u32 callsid, char *username, u32 **sids, u32 *nel);
 
-int security_port_sid(struct selinux_state *state,
-                     u8 protocol, u16 port, u32 *out_sid);
+int security_port_sid(u8 protocol, u16 port, u32 *out_sid);
 
-int security_ib_pkey_sid(struct selinux_state *state,
-                        u64 subnet_prefix, u16 pkey_num, u32 *out_sid);
+int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid);
 
-int security_ib_endport_sid(struct selinux_state *state,
-                           const char *dev_name, u8 port_num, u32 *out_sid);
+int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid);
 
-int security_netif_sid(struct selinux_state *state,
-                      char *name, u32 *if_sid);
+int security_netif_sid(char *name, u32 *if_sid);
 
-int security_node_sid(struct selinux_state *state,
-                     u16 domain, void *addr, u32 addrlen,
+int security_node_sid(u16 domain, void *addr, u32 addrlen,
                      u32 *out_sid);
 
-int security_validate_transition(struct selinux_state *state,
-                                u32 oldsid, u32 newsid, u32 tasksid,
+int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
                                 u16 tclass);
 
-int security_validate_transition_user(struct selinux_state *state,
-                                     u32 oldsid, u32 newsid, u32 tasksid,
+int security_validate_transition_user(u32 oldsid, u32 newsid, u32 tasksid,
                                      u16 tclass);
 
-int security_bounded_transition(struct selinux_state *state,
-                               u32 oldsid, u32 newsid);
+int security_bounded_transition(u32 oldsid, u32 newsid);
 
-int security_sid_mls_copy(struct selinux_state *state,
-                         u32 sid, u32 mls_sid, u32 *new_sid);
+int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
 
-int security_net_peersid_resolve(struct selinux_state *state,
-                                u32 nlbl_sid, u32 nlbl_type,
+int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
                                 u32 xfrm_sid,
                                 u32 *peer_sid);
 
@@ -382,8 +321,8 @@ int security_get_classes(struct selinux_policy *policy,
                         char ***classes, int *nclasses);
 int security_get_permissions(struct selinux_policy *policy,
                             char *class, char ***perms, int *nperms);
-int security_get_reject_unknown(struct selinux_state *state);
-int security_get_allow_unknown(struct selinux_state *state);
+int security_get_reject_unknown(void);
+int security_get_allow_unknown(void);
 
 #define SECURITY_FS_USE_XATTR          1 /* use xattr */
 #define SECURITY_FS_USE_TRANS          2 /* use transition SIDs, e.g. devpts/tmpfs */
@@ -394,10 +333,9 @@ int security_get_allow_unknown(struct selinux_state *state);
 #define SECURITY_FS_USE_NATIVE         7 /* use native label support */
 #define SECURITY_FS_USE_MAX            7 /* Highest SECURITY_FS_USE_XXX */
 
-int security_fs_use(struct selinux_state *state, struct super_block *sb);
+int security_fs_use(struct super_block *sb);
 
-int security_genfs_sid(struct selinux_state *state,
-                      const char *fstype, const char *path, u16 sclass,
+int security_genfs_sid(const char *fstype, const char *path, u16 sclass,
                       u32 *sid);
 
 int selinux_policy_genfs_sid(struct selinux_policy *policy,
@@ -405,23 +343,19 @@ int selinux_policy_genfs_sid(struct selinux_policy *policy,
                       u32 *sid);
 
 #ifdef CONFIG_NETLABEL
-int security_netlbl_secattr_to_sid(struct selinux_state *state,
-                                  struct netlbl_lsm_secattr *secattr,
+int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
                                   u32 *sid);
 
-int security_netlbl_sid_to_secattr(struct selinux_state *state,
-                                  u32 sid,
+int security_netlbl_sid_to_secattr(u32 sid,
                                   struct netlbl_lsm_secattr *secattr);
 #else
-static inline int security_netlbl_secattr_to_sid(struct selinux_state *state,
-                                           struct netlbl_lsm_secattr *secattr,
+static inline int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
                                            u32 *sid)
 {
        return -EIDRM;
 }
 
-static inline int security_netlbl_sid_to_secattr(struct selinux_state *state,
-                                        u32 sid,
+static inline int security_netlbl_sid_to_secattr(u32 sid,
                                         struct netlbl_lsm_secattr *secattr)
 {
        return -ENOENT;
@@ -433,7 +367,7 @@ const char *security_get_initial_sid_context(u32 sid);
 /*
  * status notifier using mmap interface
  */
-extern struct page *selinux_kernel_status_page(struct selinux_state *state);
+extern struct page *selinux_kernel_status_page(void);
 
 #define SELINUX_KERNEL_STATUS_VERSION  1
 struct selinux_kernel_status {
@@ -447,12 +381,9 @@ struct selinux_kernel_status {
         */
 } __packed;
 
-extern void selinux_status_update_setenforce(struct selinux_state *state,
-                                            int enforcing);
-extern void selinux_status_update_policyload(struct selinux_state *state,
-                                            int seqno);
+extern void selinux_status_update_setenforce(int enforcing);
+extern void selinux_status_update_policyload(int seqno);
 extern void selinux_complete_init(void);
-extern int selinux_disable(struct selinux_state *state);
 extern void exit_sel_fs(void);
 extern struct path selinux_null;
 extern void selnl_notify_setenforce(int val);
@@ -462,6 +393,6 @@ extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
 extern void avtab_cache_init(void);
 extern void ebitmap_cache_init(void);
 extern void hashtab_cache_init(void);
-extern int security_sidtab_hash_stats(struct selinux_state *state, char *page);
+extern int security_sidtab_hash_stats(char *page);
 
 #endif /* _SELINUX_SECURITY_H_ */
index 1ab03efe74947a33d368ab3b21b335c3ca07324d..adbe9bea2d268259cf491047484942056ce06d74 100644 (file)
@@ -153,7 +153,7 @@ static int sel_netif_sid_slow(struct net *ns, int ifindex, u32 *sid)
                goto out;
        }
 
-       ret = security_netif_sid(&selinux_state, dev->name, sid);
+       ret = security_netif_sid(dev->name, sid);
        if (ret != 0)
                goto out;
        new = kzalloc(sizeof(*new), GFP_ATOMIC);
index 1321f15799e2f8bf29cefe064facc663db4275a9..767c670d33ead380b6035e06d181a028a9c140d6 100644 (file)
@@ -46,7 +46,7 @@ static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,
 {
        int rc;
 
-       rc = security_netlbl_secattr_to_sid(&selinux_state, secattr, sid);
+       rc = security_netlbl_secattr_to_sid(secattr, sid);
        if (rc == 0 &&
            (secattr->flags & NETLBL_SECATTR_CACHEABLE) &&
            (secattr->flags & NETLBL_SECATTR_CACHE))
@@ -77,8 +77,7 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk)
        secattr = netlbl_secattr_alloc(GFP_ATOMIC);
        if (secattr == NULL)
                return NULL;
-       rc = security_netlbl_sid_to_secattr(&selinux_state, sksec->sid,
-                                           secattr);
+       rc = security_netlbl_sid_to_secattr(sksec->sid, secattr);
        if (rc != 0) {
                netlbl_secattr_free(secattr);
                return NULL;
@@ -245,8 +244,7 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
        if (secattr == NULL) {
                secattr = &secattr_storage;
                netlbl_secattr_init(secattr);
-               rc = security_netlbl_sid_to_secattr(&selinux_state, sid,
-                                                   secattr);
+               rc = security_netlbl_sid_to_secattr(sid, secattr);
                if (rc != 0)
                        goto skbuff_setsid_return;
        }
@@ -283,8 +281,7 @@ int selinux_netlbl_sctp_assoc_request(struct sctp_association *asoc,
                return 0;
 
        netlbl_secattr_init(&secattr);
-       rc = security_netlbl_sid_to_secattr(&selinux_state,
-                                           asoc->secid, &secattr);
+       rc = security_netlbl_sid_to_secattr(asoc->secid, &secattr);
        if (rc != 0)
                goto assoc_request_return;
 
@@ -332,8 +329,7 @@ int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family)
                return 0;
 
        netlbl_secattr_init(&secattr);
-       rc = security_netlbl_sid_to_secattr(&selinux_state, req->secid,
-                                           &secattr);
+       rc = security_netlbl_sid_to_secattr(req->secid, &secattr);
        if (rc != 0)
                goto inet_conn_request_return;
        rc = netlbl_req_setattr(req, &secattr);
@@ -463,8 +459,7 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
                perm = RAWIP_SOCKET__RECVFROM;
        }
 
-       rc = avc_has_perm(&selinux_state,
-                         sksec->sid, nlbl_sid, sksec->sclass, perm, ad);
+       rc = avc_has_perm(sksec->sid, nlbl_sid, sksec->sclass, perm, ad);
        if (rc == 0)
                return 0;
 
index 0ac7df9a93677f403fa59f90c36f4fdae8699323..5c8c77e50aadfac077f3039f705afc948fc2685e 100644 (file)
@@ -204,13 +204,13 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
        new = kzalloc(sizeof(*new), GFP_ATOMIC);
        switch (family) {
        case PF_INET:
-               ret = security_node_sid(&selinux_state, PF_INET,
+               ret = security_node_sid(PF_INET,
                                        addr, sizeof(struct in_addr), sid);
                if (new)
                        new->nsec.addr.ipv4 = *(__be32 *)addr;
                break;
        case PF_INET6:
-               ret = security_node_sid(&selinux_state, PF_INET6,
+               ret = security_node_sid(PF_INET6,
                                        addr, sizeof(struct in6_addr), sid);
                if (new)
                        new->nsec.addr.ipv6 = *(struct in6_addr *)addr;
index 8eec6347cf012bbd1d286507d032e4890867b1e2..2e22ad9c2bd0d116668985e0fb579b5934df9394 100644 (file)
@@ -148,7 +148,7 @@ static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid)
                return 0;
        }
 
-       ret = security_port_sid(&selinux_state, protocol, pnum, sid);
+       ret = security_port_sid(protocol, pnum, sid);
        if (ret != 0)
                goto out;
        new = kzalloc(sizeof(*new), GFP_ATOMIC);
index 18498979a640933e1be2438afff7c5fbe9bf4c3d..69a583b91fc57c5ff04a2f66155278c6156e6ea5 100644 (file)
@@ -77,7 +77,6 @@ struct selinux_fs_info {
        bool policy_opened;
        struct dentry *policycap_dir;
        unsigned long last_ino;
-       struct selinux_state *state;
        struct super_block *sb;
 };
 
@@ -90,7 +89,6 @@ static int selinux_fs_info_create(struct super_block *sb)
                return -ENOMEM;
 
        fsi->last_ino = SEL_INO_NEXT - 1;
-       fsi->state = &selinux_state;
        fsi->sb = sb;
        sb->s_fs_info = fsi;
        return 0;
@@ -125,12 +123,11 @@ static void selinux_fs_info_free(struct super_block *sb)
 static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
                                size_t count, loff_t *ppos)
 {
-       struct selinux_fs_info *fsi = file_inode(filp)->i_sb->s_fs_info;
        char tmpbuf[TMPBUFLEN];
        ssize_t length;
 
        length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
-                          enforcing_enabled(fsi->state));
+                          enforcing_enabled());
        return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 }
 
@@ -139,8 +136,6 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
                                 size_t count, loff_t *ppos)
 
 {
-       struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
-       struct selinux_state *state = fsi->state;
        char *page = NULL;
        ssize_t length;
        int old_value, new_value;
@@ -162,10 +157,9 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
 
        new_value = !!new_value;
 
-       old_value = enforcing_enabled(state);
+       old_value = enforcing_enabled();
        if (new_value != old_value) {
-               length = avc_has_perm(&selinux_state,
-                                     current_sid(), SECINITSID_SECURITY,
+               length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
                                      SECCLASS_SECURITY, SECURITY__SETENFORCE,
                                      NULL);
                if (length)
@@ -176,15 +170,15 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
                        new_value, old_value,
                        from_kuid(&init_user_ns, audit_get_loginuid(current)),
                        audit_get_sessionid(current));
-               enforcing_set(state, new_value);
+               enforcing_set(new_value);
                if (new_value)
-                       avc_ss_reset(state->avc, 0);
+                       avc_ss_reset(0);
                selnl_notify_setenforce(new_value);
-               selinux_status_update_setenforce(state, new_value);
+               selinux_status_update_setenforce(new_value);
                if (!new_value)
                        call_blocking_lsm_notifier(LSM_POLICY_CHANGE, NULL);
 
-               selinux_ima_measure_state(state);
+               selinux_ima_measure_state();
        }
        length = count;
 out:
@@ -204,14 +198,12 @@ static const struct file_operations sel_enforce_ops = {
 static ssize_t sel_read_handle_unknown(struct file *filp, char __user *buf,
                                        size_t count, loff_t *ppos)
 {
-       struct selinux_fs_info *fsi = file_inode(filp)->i_sb->s_fs_info;
-       struct selinux_state *state = fsi->state;
        char tmpbuf[TMPBUFLEN];
        ssize_t length;
        ino_t ino = file_inode(filp)->i_ino;
        int handle_unknown = (ino == SEL_REJECT_UNKNOWN) ?
-               security_get_reject_unknown(state) :
-               !security_get_allow_unknown(state);
+               security_get_reject_unknown() :
+               !security_get_allow_unknown();
 
        length = scnprintf(tmpbuf, TMPBUFLEN, "%d", handle_unknown);
        return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
@@ -224,8 +216,7 @@ static const struct file_operations sel_handle_unknown_ops = {
 
 static int sel_open_handle_status(struct inode *inode, struct file *filp)
 {
-       struct selinux_fs_info *fsi = file_inode(filp)->i_sb->s_fs_info;
-       struct page    *status = selinux_kernel_status_page(fsi->state);
+       struct page    *status = selinux_kernel_status_page();
 
        if (!status)
                return -ENOMEM;
@@ -276,25 +267,13 @@ static const struct file_operations sel_handle_status_ops = {
        .llseek         = generic_file_llseek,
 };
 
-#ifdef CONFIG_SECURITY_SELINUX_DISABLE
 static ssize_t sel_write_disable(struct file *file, const char __user *buf,
                                 size_t count, loff_t *ppos)
 
 {
-       struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
        char *page;
        ssize_t length;
        int new_value;
-       int enforcing;
-
-       /* NOTE: we are now officially considering runtime disable as
-        *       deprecated, and using it will become increasingly painful
-        *       (e.g. sleeping/blocking) as we progress through future
-        *       kernel releases until eventually it is removed
-        */
-       pr_err("SELinux:  Runtime disable is deprecated, use selinux=0 on the kernel cmdline.\n");
-       pr_err("SELinux:  https://github.com/SELinuxProject/selinux-kernel/wiki/DEPRECATE-runtime-disable\n");
-       ssleep(15);
 
        if (count >= PAGE_SIZE)
                return -ENOMEM;
@@ -307,31 +286,21 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf,
        if (IS_ERR(page))
                return PTR_ERR(page);
 
-       length = -EINVAL;
-       if (sscanf(page, "%d", &new_value) != 1)
+       if (sscanf(page, "%d", &new_value) != 1) {
+               length = -EINVAL;
                goto out;
+       }
+       length = count;
 
        if (new_value) {
-               enforcing = enforcing_enabled(fsi->state);
-               length = selinux_disable(fsi->state);
-               if (length)
-                       goto out;
-               audit_log(audit_context(), GFP_KERNEL, AUDIT_MAC_STATUS,
-                       "enforcing=%d old_enforcing=%d auid=%u ses=%u"
-                       " enabled=0 old-enabled=1 lsm=selinux res=1",
-                       enforcing, enforcing,
-                       from_kuid(&init_user_ns, audit_get_loginuid(current)),
-                       audit_get_sessionid(current));
+               pr_err("SELinux: https://github.com/SELinuxProject/selinux-kernel/wiki/DEPRECATE-runtime-disable\n");
+               pr_err("SELinux: Runtime disable is not supported, use selinux=0 on the kernel cmdline.\n");
        }
 
-       length = count;
 out:
        kfree(page);
        return length;
 }
-#else
-#define sel_write_disable NULL
-#endif
 
 static const struct file_operations sel_disable_ops = {
        .write          = sel_write_disable,
@@ -375,12 +344,11 @@ static void sel_remove_entries(struct dentry *de);
 static ssize_t sel_read_mls(struct file *filp, char __user *buf,
                                size_t count, loff_t *ppos)
 {
-       struct selinux_fs_info *fsi = file_inode(filp)->i_sb->s_fs_info;
        char tmpbuf[TMPBUFLEN];
        ssize_t length;
 
        length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
-                          security_mls_enabled(fsi->state));
+                          security_mls_enabled());
        return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 }
 
@@ -397,16 +365,14 @@ struct policy_load_memory {
 static int sel_open_policy(struct inode *inode, struct file *filp)
 {
        struct selinux_fs_info *fsi = inode->i_sb->s_fs_info;
-       struct selinux_state *state = fsi->state;
        struct policy_load_memory *plm = NULL;
        int rc;
 
        BUG_ON(filp->private_data);
 
-       mutex_lock(&fsi->state->policy_mutex);
+       mutex_lock(&selinux_state.policy_mutex);
 
-       rc = avc_has_perm(&selinux_state,
-                         current_sid(), SECINITSID_SECURITY,
+       rc = avc_has_perm(current_sid(), SECINITSID_SECURITY,
                          SECCLASS_SECURITY, SECURITY__READ_POLICY, NULL);
        if (rc)
                goto err;
@@ -420,7 +386,7 @@ static int sel_open_policy(struct inode *inode, struct file *filp)
        if (!plm)
                goto err;
 
-       rc = security_read_policy(state, &plm->data, &plm->len);
+       rc = security_read_policy(&plm->data, &plm->len);
        if (rc)
                goto err;
 
@@ -434,11 +400,11 @@ static int sel_open_policy(struct inode *inode, struct file *filp)
 
        filp->private_data = plm;
 
-       mutex_unlock(&fsi->state->policy_mutex);
+       mutex_unlock(&selinux_state.policy_mutex);
 
        return 0;
 err:
-       mutex_unlock(&fsi->state->policy_mutex);
+       mutex_unlock(&selinux_state.policy_mutex);
 
        if (plm)
                vfree(plm->data);
@@ -467,8 +433,7 @@ static ssize_t sel_read_policy(struct file *filp, char __user *buf,
        struct policy_load_memory *plm = filp->private_data;
        int ret;
 
-       ret = avc_has_perm(&selinux_state,
-                          current_sid(), SECINITSID_SECURITY,
+       ret = avc_has_perm(current_sid(), SECINITSID_SECURITY,
                          SECCLASS_SECURITY, SECURITY__READ_POLICY, NULL);
        if (ret)
                return ret;
@@ -621,10 +586,9 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
        ssize_t length;
        void *data = NULL;
 
-       mutex_lock(&fsi->state->policy_mutex);
+       mutex_lock(&selinux_state.policy_mutex);
 
-       length = avc_has_perm(&selinux_state,
-                             current_sid(), SECINITSID_SECURITY,
+       length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
                              SECCLASS_SECURITY, SECURITY__LOAD_POLICY, NULL);
        if (length)
                goto out;
@@ -643,7 +607,7 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
        if (copy_from_user(data, buf, count) != 0)
                goto out;
 
-       length = security_load_policy(fsi->state, data, count, &load_state);
+       length = security_load_policy(data, count, &load_state);
        if (length) {
                pr_warn_ratelimited("SELinux: failed to load policy\n");
                goto out;
@@ -652,11 +616,11 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
        length = sel_make_policy_nodes(fsi, load_state.policy);
        if (length) {
                pr_warn_ratelimited("SELinux: failed to initialize selinuxfs\n");
-               selinux_policy_cancel(fsi->state, &load_state);
+               selinux_policy_cancel(&load_state);
                goto out;
        }
 
-       selinux_policy_commit(fsi->state, &load_state);
+       selinux_policy_commit(&load_state);
 
        length = count;
 
@@ -665,7 +629,7 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
                from_kuid(&init_user_ns, audit_get_loginuid(current)),
                audit_get_sessionid(current));
 out:
-       mutex_unlock(&fsi->state->policy_mutex);
+       mutex_unlock(&selinux_state.policy_mutex);
        vfree(data);
        return length;
 }
@@ -677,23 +641,20 @@ static const struct file_operations sel_load_ops = {
 
 static ssize_t sel_write_context(struct file *file, char *buf, size_t size)
 {
-       struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
-       struct selinux_state *state = fsi->state;
        char *canon = NULL;
        u32 sid, len;
        ssize_t length;
 
-       length = avc_has_perm(&selinux_state,
-                             current_sid(), SECINITSID_SECURITY,
+       length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
                              SECCLASS_SECURITY, SECURITY__CHECK_CONTEXT, NULL);
        if (length)
                goto out;
 
-       length = security_context_to_sid(state, buf, size, &sid, GFP_KERNEL);
+       length = security_context_to_sid(buf, size, &sid, GFP_KERNEL);
        if (length)
                goto out;
 
-       length = security_sid_to_context(state, sid, &canon, &len);
+       length = security_sid_to_context(sid, &canon, &len);
        if (length)
                goto out;
 
@@ -714,25 +675,22 @@ out:
 static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
                                     size_t count, loff_t *ppos)
 {
-       struct selinux_fs_info *fsi = file_inode(filp)->i_sb->s_fs_info;
        char tmpbuf[TMPBUFLEN];
        ssize_t length;
 
        length = scnprintf(tmpbuf, TMPBUFLEN, "%u",
-                          checkreqprot_get(fsi->state));
+                          checkreqprot_get());
        return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 }
 
 static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
                                      size_t count, loff_t *ppos)
 {
-       struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
        char *page;
        ssize_t length;
        unsigned int new_value;
 
-       length = avc_has_perm(&selinux_state,
-                             current_sid(), SECINITSID_SECURITY,
+       length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
                              SECCLASS_SECURITY, SECURITY__SETCHECKREQPROT,
                              NULL);
        if (length)
@@ -749,24 +707,21 @@ static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
        if (IS_ERR(page))
                return PTR_ERR(page);
 
-       length = -EINVAL;
-       if (sscanf(page, "%u", &new_value) != 1)
+       if (sscanf(page, "%u", &new_value) != 1) {
+               length = -EINVAL;
                goto out;
+       }
+       length = count;
 
        if (new_value) {
                char comm[sizeof(current->comm)];
 
                memcpy(comm, current->comm, sizeof(comm));
-               pr_err("SELinux: %s (%d) set checkreqprot to 1. This is deprecated and will be rejected in a future kernel release.\n",
+               pr_err("SELinux: %s (%d) set checkreqprot to 1. This is no longer supported.\n",
                       comm, current->pid);
        }
 
-       checkreqprot_set(fsi->state, (new_value ? 1 : 0));
-       if (new_value)
-               ssleep(15);
-       length = count;
-
-       selinux_ima_measure_state(fsi->state);
+       selinux_ima_measure_state();
 
 out:
        kfree(page);
@@ -782,16 +737,13 @@ static ssize_t sel_write_validatetrans(struct file *file,
                                        const char __user *buf,
                                        size_t count, loff_t *ppos)
 {
-       struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
-       struct selinux_state *state = fsi->state;
        char *oldcon = NULL, *newcon = NULL, *taskcon = NULL;
        char *req = NULL;
        u32 osid, nsid, tsid;
        u16 tclass;
        int rc;
 
-       rc = avc_has_perm(&selinux_state,
-                         current_sid(), SECINITSID_SECURITY,
+       rc = avc_has_perm(current_sid(), SECINITSID_SECURITY,
                          SECCLASS_SECURITY, SECURITY__VALIDATE_TRANS, NULL);
        if (rc)
                goto out;
@@ -829,19 +781,19 @@ static ssize_t sel_write_validatetrans(struct file *file,
        if (sscanf(req, "%s %s %hu %s", oldcon, newcon, &tclass, taskcon) != 4)
                goto out;
 
-       rc = security_context_str_to_sid(state, oldcon, &osid, GFP_KERNEL);
+       rc = security_context_str_to_sid(oldcon, &osid, GFP_KERNEL);
        if (rc)
                goto out;
 
-       rc = security_context_str_to_sid(state, newcon, &nsid, GFP_KERNEL);
+       rc = security_context_str_to_sid(newcon, &nsid, GFP_KERNEL);
        if (rc)
                goto out;
 
-       rc = security_context_str_to_sid(state, taskcon, &tsid, GFP_KERNEL);
+       rc = security_context_str_to_sid(taskcon, &tsid, GFP_KERNEL);
        if (rc)
                goto out;
 
-       rc = security_validate_transition_user(state, osid, nsid, tsid, tclass);
+       rc = security_validate_transition_user(osid, nsid, tsid, tclass);
        if (!rc)
                rc = count;
 out:
@@ -911,16 +863,13 @@ static const struct file_operations transaction_ops = {
 
 static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
 {
-       struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
-       struct selinux_state *state = fsi->state;
        char *scon = NULL, *tcon = NULL;
        u32 ssid, tsid;
        u16 tclass;
        struct av_decision avd;
        ssize_t length;
 
-       length = avc_has_perm(&selinux_state,
-                             current_sid(), SECINITSID_SECURITY,
+       length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
                              SECCLASS_SECURITY, SECURITY__COMPUTE_AV, NULL);
        if (length)
                goto out;
@@ -939,15 +888,15 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
        if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
                goto out;
 
-       length = security_context_str_to_sid(state, scon, &ssid, GFP_KERNEL);
+       length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL);
        if (length)
                goto out;
 
-       length = security_context_str_to_sid(state, tcon, &tsid, GFP_KERNEL);
+       length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL);
        if (length)
                goto out;
 
-       security_compute_av_user(state, ssid, tsid, tclass, &avd);
+       security_compute_av_user(ssid, tsid, tclass, &avd);
 
        length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT,
                          "%x %x %x %x %u %x",
@@ -962,8 +911,6 @@ out:
 
 static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
 {
-       struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
-       struct selinux_state *state = fsi->state;
        char *scon = NULL, *tcon = NULL;
        char *namebuf = NULL, *objname = NULL;
        u32 ssid, tsid, newsid;
@@ -973,8 +920,7 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
        u32 len;
        int nargs;
 
-       length = avc_has_perm(&selinux_state,
-                             current_sid(), SECINITSID_SECURITY,
+       length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
                              SECCLASS_SECURITY, SECURITY__COMPUTE_CREATE,
                              NULL);
        if (length)
@@ -1030,20 +976,20 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
                objname = namebuf;
        }
 
-       length = security_context_str_to_sid(state, scon, &ssid, GFP_KERNEL);
+       length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL);
        if (length)
                goto out;
 
-       length = security_context_str_to_sid(state, tcon, &tsid, GFP_KERNEL);
+       length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL);
        if (length)
                goto out;
 
-       length = security_transition_sid_user(state, ssid, tsid, tclass,
+       length = security_transition_sid_user(ssid, tsid, tclass,
                                              objname, &newsid);
        if (length)
                goto out;
 
-       length = security_sid_to_context(state, newsid, &newcon, &len);
+       length = security_sid_to_context(newsid, &newcon, &len);
        if (length)
                goto out;
 
@@ -1066,8 +1012,6 @@ out:
 
 static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
 {
-       struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
-       struct selinux_state *state = fsi->state;
        char *scon = NULL, *tcon = NULL;
        u32 ssid, tsid, newsid;
        u16 tclass;
@@ -1075,8 +1019,7 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
        char *newcon = NULL;
        u32 len;
 
-       length = avc_has_perm(&selinux_state,
-                             current_sid(), SECINITSID_SECURITY,
+       length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
                              SECCLASS_SECURITY, SECURITY__COMPUTE_RELABEL,
                              NULL);
        if (length)
@@ -1096,19 +1039,19 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
        if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
                goto out;
 
-       length = security_context_str_to_sid(state, scon, &ssid, GFP_KERNEL);
+       length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL);
        if (length)
                goto out;
 
-       length = security_context_str_to_sid(state, tcon, &tsid, GFP_KERNEL);
+       length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL);
        if (length)
                goto out;
 
-       length = security_change_sid(state, ssid, tsid, tclass, &newsid);
+       length = security_change_sid(ssid, tsid, tclass, &newsid);
        if (length)
                goto out;
 
-       length = security_sid_to_context(state, newsid, &newcon, &len);
+       length = security_sid_to_context(newsid, &newcon, &len);
        if (length)
                goto out;
 
@@ -1127,8 +1070,6 @@ out:
 
 static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
 {
-       struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
-       struct selinux_state *state = fsi->state;
        char *con = NULL, *user = NULL, *ptr;
        u32 sid, *sids = NULL;
        ssize_t length;
@@ -1136,8 +1077,7 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
        int i, rc;
        u32 len, nsids;
 
-       length = avc_has_perm(&selinux_state,
-                             current_sid(), SECINITSID_SECURITY,
+       length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
                              SECCLASS_SECURITY, SECURITY__COMPUTE_USER,
                              NULL);
        if (length)
@@ -1157,18 +1097,18 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
        if (sscanf(buf, "%s %s", con, user) != 2)
                goto out;
 
-       length = security_context_str_to_sid(state, con, &sid, GFP_KERNEL);
+       length = security_context_str_to_sid(con, &sid, GFP_KERNEL);
        if (length)
                goto out;
 
-       length = security_get_user_sids(state, sid, user, &sids, &nsids);
+       length = security_get_user_sids(sid, user, &sids, &nsids);
        if (length)
                goto out;
 
        length = sprintf(buf, "%u", nsids) + 1;
        ptr = buf + length;
        for (i = 0; i < nsids; i++) {
-               rc = security_sid_to_context(state, sids[i], &newcon, &len);
+               rc = security_sid_to_context(sids[i], &newcon, &len);
                if (rc) {
                        length = rc;
                        goto out;
@@ -1192,8 +1132,6 @@ out:
 
 static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
 {
-       struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
-       struct selinux_state *state = fsi->state;
        char *scon = NULL, *tcon = NULL;
        u32 ssid, tsid, newsid;
        u16 tclass;
@@ -1201,8 +1139,7 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
        char *newcon = NULL;
        u32 len;
 
-       length = avc_has_perm(&selinux_state,
-                             current_sid(), SECINITSID_SECURITY,
+       length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
                              SECCLASS_SECURITY, SECURITY__COMPUTE_MEMBER,
                              NULL);
        if (length)
@@ -1222,19 +1159,19 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
        if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
                goto out;
 
-       length = security_context_str_to_sid(state, scon, &ssid, GFP_KERNEL);
+       length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL);
        if (length)
                goto out;
 
-       length = security_context_str_to_sid(state, tcon, &tsid, GFP_KERNEL);
+       length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL);
        if (length)
                goto out;
 
-       length = security_member_sid(state, ssid, tsid, tclass, &newsid);
+       length = security_member_sid(ssid, tsid, tclass, &newsid);
        if (length)
                goto out;
 
-       length = security_sid_to_context(state, newsid, &newcon, &len);
+       length = security_sid_to_context(newsid, &newcon, &len);
        if (length)
                goto out;
 
@@ -1276,7 +1213,7 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
        unsigned index = file_inode(filep)->i_ino & SEL_INO_MASK;
        const char *name = filep->f_path.dentry->d_name.name;
 
-       mutex_lock(&fsi->state->policy_mutex);
+       mutex_lock(&selinux_state.policy_mutex);
 
        ret = -EINVAL;
        if (index >= fsi->bool_num || strcmp(name,
@@ -1288,21 +1225,21 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
        if (!page)
                goto out_unlock;
 
-       cur_enforcing = security_get_bool_value(fsi->state, index);
+       cur_enforcing = security_get_bool_value(index);
        if (cur_enforcing < 0) {
                ret = cur_enforcing;
                goto out_unlock;
        }
        length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing,
                          fsi->bool_pending_values[index]);
-       mutex_unlock(&fsi->state->policy_mutex);
+       mutex_unlock(&selinux_state.policy_mutex);
        ret = simple_read_from_buffer(buf, count, ppos, page, length);
 out_free:
        free_page((unsigned long)page);
        return ret;
 
 out_unlock:
-       mutex_unlock(&fsi->state->policy_mutex);
+       mutex_unlock(&selinux_state.policy_mutex);
        goto out_free;
 }
 
@@ -1327,10 +1264,9 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
        if (IS_ERR(page))
                return PTR_ERR(page);
 
-       mutex_lock(&fsi->state->policy_mutex);
+       mutex_lock(&selinux_state.policy_mutex);
 
-       length = avc_has_perm(&selinux_state,
-                             current_sid(), SECINITSID_SECURITY,
+       length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
                              SECCLASS_SECURITY, SECURITY__SETBOOL,
                              NULL);
        if (length)
@@ -1352,7 +1288,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
        length = count;
 
 out:
-       mutex_unlock(&fsi->state->policy_mutex);
+       mutex_unlock(&selinux_state.policy_mutex);
        kfree(page);
        return length;
 }
@@ -1383,10 +1319,9 @@ static ssize_t sel_commit_bools_write(struct file *filep,
        if (IS_ERR(page))
                return PTR_ERR(page);
 
-       mutex_lock(&fsi->state->policy_mutex);
+       mutex_lock(&selinux_state.policy_mutex);
 
-       length = avc_has_perm(&selinux_state,
-                             current_sid(), SECINITSID_SECURITY,
+       length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
                              SECCLASS_SECURITY, SECURITY__SETBOOL,
                              NULL);
        if (length)
@@ -1398,14 +1333,14 @@ static ssize_t sel_commit_bools_write(struct file *filep,
 
        length = 0;
        if (new_value && fsi->bool_pending_values)
-               length = security_set_bools(fsi->state, fsi->bool_num,
+               length = security_set_bools(fsi->bool_num,
                                            fsi->bool_pending_values);
 
        if (!length)
                length = count;
 
 out:
-       mutex_unlock(&fsi->state->policy_mutex);
+       mutex_unlock(&selinux_state.policy_mutex);
        kfree(page);
        return length;
 }
@@ -1503,13 +1438,11 @@ out:
 static ssize_t sel_read_avc_cache_threshold(struct file *filp, char __user *buf,
                                            size_t count, loff_t *ppos)
 {
-       struct selinux_fs_info *fsi = file_inode(filp)->i_sb->s_fs_info;
-       struct selinux_state *state = fsi->state;
        char tmpbuf[TMPBUFLEN];
        ssize_t length;
 
        length = scnprintf(tmpbuf, TMPBUFLEN, "%u",
-                          avc_get_cache_threshold(state->avc));
+                          avc_get_cache_threshold());
        return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 }
 
@@ -1518,14 +1451,11 @@ static ssize_t sel_write_avc_cache_threshold(struct file *file,
                                             size_t count, loff_t *ppos)
 
 {
-       struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
-       struct selinux_state *state = fsi->state;
        char *page;
        ssize_t ret;
        unsigned int new_value;
 
-       ret = avc_has_perm(&selinux_state,
-                          current_sid(), SECINITSID_SECURITY,
+       ret = avc_has_perm(current_sid(), SECINITSID_SECURITY,
                           SECCLASS_SECURITY, SECURITY__SETSECPARAM,
                           NULL);
        if (ret)
@@ -1546,7 +1476,7 @@ static ssize_t sel_write_avc_cache_threshold(struct file *file,
        if (sscanf(page, "%u", &new_value) != 1)
                goto out;
 
-       avc_set_cache_threshold(state->avc, new_value);
+       avc_set_cache_threshold(new_value);
 
        ret = count;
 out:
@@ -1557,8 +1487,6 @@ out:
 static ssize_t sel_read_avc_hash_stats(struct file *filp, char __user *buf,
                                       size_t count, loff_t *ppos)
 {
-       struct selinux_fs_info *fsi = file_inode(filp)->i_sb->s_fs_info;
-       struct selinux_state *state = fsi->state;
        char *page;
        ssize_t length;
 
@@ -1566,7 +1494,7 @@ static ssize_t sel_read_avc_hash_stats(struct file *filp, char __user *buf,
        if (!page)
                return -ENOMEM;
 
-       length = avc_get_hash_stats(state->avc, page);
+       length = avc_get_hash_stats(page);
        if (length >= 0)
                length = simple_read_from_buffer(buf, count, ppos, page, length);
        free_page((unsigned long)page);
@@ -1577,8 +1505,6 @@ static ssize_t sel_read_avc_hash_stats(struct file *filp, char __user *buf,
 static ssize_t sel_read_sidtab_hash_stats(struct file *filp, char __user *buf,
                                        size_t count, loff_t *ppos)
 {
-       struct selinux_fs_info *fsi = file_inode(filp)->i_sb->s_fs_info;
-       struct selinux_state *state = fsi->state;
        char *page;
        ssize_t length;
 
@@ -1586,7 +1512,7 @@ static ssize_t sel_read_sidtab_hash_stats(struct file *filp, char __user *buf,
        if (!page)
                return -ENOMEM;
 
-       length = security_sidtab_hash_stats(state, page);
+       length = security_sidtab_hash_stats(page);
        if (length >= 0)
                length = simple_read_from_buffer(buf, count, ppos, page,
                                                length);
@@ -1752,13 +1678,12 @@ static int sel_make_ss_files(struct dentry *dir)
 static ssize_t sel_read_initcon(struct file *file, char __user *buf,
                                size_t count, loff_t *ppos)
 {
-       struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
        char *con;
        u32 sid, len;
        ssize_t ret;
 
        sid = file_inode(file)->i_ino&SEL_INO_MASK;
-       ret = security_sid_to_context(fsi->state, sid, &con, &len);
+       ret = security_sid_to_context(sid, &con, &len);
        if (ret)
                return ret;
 
@@ -1852,13 +1777,12 @@ static const struct file_operations sel_perm_ops = {
 static ssize_t sel_read_policycap(struct file *file, char __user *buf,
                                  size_t count, loff_t *ppos)
 {
-       struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
        int value;
        char tmpbuf[TMPBUFLEN];
        ssize_t length;
        unsigned long i_ino = file_inode(file)->i_ino;
 
-       value = security_policycap_supported(fsi->state, i_ino & SEL_INO_MASK);
+       value = security_policycap_supported(i_ino & SEL_INO_MASK);
        length = scnprintf(tmpbuf, TMPBUFLEN, "%d", value);
 
        return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
@@ -2249,13 +2173,3 @@ static int __init init_sel_fs(void)
 }
 
 __initcall(init_sel_fs);
-
-#ifdef CONFIG_SECURITY_SELINUX_DISABLE
-void exit_sel_fs(void)
-{
-       sysfs_remove_mount_point(fs_kobj, "selinux");
-       dput(selinux_null.dentry);
-       kern_unmount(selinuxfs_mount);
-       unregister_filesystem(&sel_fs_type);
-}
-#endif
index 0092b29022f5e46c2d29193c1a8d35e1941d6001..f14d1ffe54c5dc7b4461906f5dcdc3650321f920 100644 (file)
@@ -235,16 +235,16 @@ static void map_decision(struct selinux_map *map,
        }
 }
 
-int security_mls_enabled(struct selinux_state *state)
+int security_mls_enabled(void)
 {
        int mls_enabled;
        struct selinux_policy *policy;
 
-       if (!selinux_initialized(state))
+       if (!selinux_initialized())
                return 0;
 
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        mls_enabled = policy->policydb.mls_enabled;
        rcu_read_unlock();
        return mls_enabled;
@@ -713,8 +713,7 @@ static void context_struct_compute_av(struct policydb *policydb,
                                 tclass, avd);
 }
 
-static int security_validtrans_handle_fail(struct selinux_state *state,
-                                       struct selinux_policy *policy,
+static int security_validtrans_handle_fail(struct selinux_policy *policy,
                                        struct sidtab_entry *oentry,
                                        struct sidtab_entry *nentry,
                                        struct sidtab_entry *tentry,
@@ -740,13 +739,12 @@ out:
        kfree(n);
        kfree(t);
 
-       if (!enforcing_enabled(state))
+       if (!enforcing_enabled())
                return 0;
        return -EPERM;
 }
 
-static int security_compute_validatetrans(struct selinux_state *state,
-                                         u32 oldsid, u32 newsid, u32 tasksid,
+static int security_compute_validatetrans(u32 oldsid, u32 newsid, u32 tasksid,
                                          u16 orig_tclass, bool user)
 {
        struct selinux_policy *policy;
@@ -761,12 +759,12 @@ static int security_compute_validatetrans(struct selinux_state *state,
        int rc = 0;
 
 
-       if (!selinux_initialized(state))
+       if (!selinux_initialized())
                return 0;
 
        rcu_read_lock();
 
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        policydb = &policy->policydb;
        sidtab = policy->sidtab;
 
@@ -813,8 +811,7 @@ static int security_compute_validatetrans(struct selinux_state *state,
                        if (user)
                                rc = -EPERM;
                        else
-                               rc = security_validtrans_handle_fail(state,
-                                                               policy,
+                               rc = security_validtrans_handle_fail(policy,
                                                                oentry,
                                                                nentry,
                                                                tentry,
@@ -829,19 +826,17 @@ out:
        return rc;
 }
 
-int security_validate_transition_user(struct selinux_state *state,
-                                     u32 oldsid, u32 newsid, u32 tasksid,
+int security_validate_transition_user(u32 oldsid, u32 newsid, u32 tasksid,
                                      u16 tclass)
 {
-       return security_compute_validatetrans(state, oldsid, newsid, tasksid,
+       return security_compute_validatetrans(oldsid, newsid, tasksid,
                                              tclass, true);
 }
 
-int security_validate_transition(struct selinux_state *state,
-                                u32 oldsid, u32 newsid, u32 tasksid,
+int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
                                 u16 orig_tclass)
 {
-       return security_compute_validatetrans(state, oldsid, newsid, tasksid,
+       return security_compute_validatetrans(oldsid, newsid, tasksid,
                                              orig_tclass, false);
 }
 
@@ -851,12 +846,10 @@ int security_validate_transition(struct selinux_state *state,
  * It returns 0, if @newsid is bounded by @oldsid.
  * Otherwise, it returns error code.
  *
- * @state: SELinux state
  * @oldsid : current security identifier
  * @newsid : destinated security identifier
  */
-int security_bounded_transition(struct selinux_state *state,
-                               u32 old_sid, u32 new_sid)
+int security_bounded_transition(u32 old_sid, u32 new_sid)
 {
        struct selinux_policy *policy;
        struct policydb *policydb;
@@ -866,11 +859,11 @@ int security_bounded_transition(struct selinux_state *state,
        int index;
        int rc;
 
-       if (!selinux_initialized(state))
+       if (!selinux_initialized())
                return 0;
 
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        policydb = &policy->policydb;
        sidtab = policy->sidtab;
 
@@ -1004,8 +997,7 @@ void services_compute_xperms_decision(struct extended_perms_decision *xpermd,
        }
 }
 
-void security_compute_xperms_decision(struct selinux_state *state,
-                                     u32 ssid,
+void security_compute_xperms_decision(u32 ssid,
                                      u32 tsid,
                                      u16 orig_tclass,
                                      u8 driver,
@@ -1029,10 +1021,10 @@ void security_compute_xperms_decision(struct selinux_state *state,
        memset(xpermd->dontaudit->p, 0, sizeof(xpermd->dontaudit->p));
 
        rcu_read_lock();
-       if (!selinux_initialized(state))
+       if (!selinux_initialized())
                goto allow;
 
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        policydb = &policy->policydb;
        sidtab = policy->sidtab;
 
@@ -1091,7 +1083,6 @@ allow:
 
 /**
  * security_compute_av - Compute access vector decisions.
- * @state: SELinux state
  * @ssid: source security identifier
  * @tsid: target security identifier
  * @orig_tclass: target security class
@@ -1101,8 +1092,7 @@ allow:
  * Compute a set of access vector decisions based on the
  * SID pair (@ssid, @tsid) for the permissions in @tclass.
  */
-void security_compute_av(struct selinux_state *state,
-                        u32 ssid,
+void security_compute_av(u32 ssid,
                         u32 tsid,
                         u16 orig_tclass,
                         struct av_decision *avd,
@@ -1115,10 +1105,10 @@ void security_compute_av(struct selinux_state *state,
        struct context *scontext = NULL, *tcontext = NULL;
 
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        avd_init(policy, avd);
        xperms->len = 0;
-       if (!selinux_initialized(state))
+       if (!selinux_initialized())
                goto allow;
 
        policydb = &policy->policydb;
@@ -1160,8 +1150,7 @@ allow:
        goto out;
 }
 
-void security_compute_av_user(struct selinux_state *state,
-                             u32 ssid,
+void security_compute_av_user(u32 ssid,
                              u32 tsid,
                              u16 tclass,
                              struct av_decision *avd)
@@ -1172,9 +1161,9 @@ void security_compute_av_user(struct selinux_state *state,
        struct context *scontext = NULL, *tcontext = NULL;
 
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        avd_init(policy, avd);
-       if (!selinux_initialized(state))
+       if (!selinux_initialized())
                goto allow;
 
        policydb = &policy->policydb;
@@ -1290,19 +1279,19 @@ static int sidtab_entry_to_string(struct policydb *p,
 
 #include "initial_sid_to_string.h"
 
-int security_sidtab_hash_stats(struct selinux_state *state, char *page)
+int security_sidtab_hash_stats(char *page)
 {
        struct selinux_policy *policy;
        int rc;
 
-       if (!selinux_initialized(state)) {
+       if (!selinux_initialized()) {
                pr_err("SELinux: %s:  called before initial load_policy\n",
                       __func__);
                return -EINVAL;
        }
 
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        rc = sidtab_hash_stats(policy->sidtab, page);
        rcu_read_unlock();
 
@@ -1316,8 +1305,7 @@ const char *security_get_initial_sid_context(u32 sid)
        return initial_sid_to_string[sid];
 }
 
-static int security_sid_to_context_core(struct selinux_state *state,
-                                       u32 sid, char **scontext,
+static int security_sid_to_context_core(u32 sid, char **scontext,
                                        u32 *scontext_len, int force,
                                        int only_invalid)
 {
@@ -1331,7 +1319,7 @@ static int security_sid_to_context_core(struct selinux_state *state,
                *scontext = NULL;
        *scontext_len  = 0;
 
-       if (!selinux_initialized(state)) {
+       if (!selinux_initialized()) {
                if (sid <= SECINITSID_NUM) {
                        char *scontextp;
                        const char *s = initial_sid_to_string[sid];
@@ -1352,7 +1340,7 @@ static int security_sid_to_context_core(struct selinux_state *state,
                return -EINVAL;
        }
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        policydb = &policy->policydb;
        sidtab = policy->sidtab;
 
@@ -1380,7 +1368,6 @@ out_unlock:
 
 /**
  * security_sid_to_context - Obtain a context for a given SID.
- * @state: SELinux state
  * @sid: security identifier, SID
  * @scontext: security context
  * @scontext_len: length in bytes
@@ -1389,24 +1376,22 @@ out_unlock:
  * into a dynamically allocated string of the correct size.  Set @scontext
  * to point to this string and set @scontext_len to the length of the string.
  */
-int security_sid_to_context(struct selinux_state *state,
-                           u32 sid, char **scontext, u32 *scontext_len)
+int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len)
 {
-       return security_sid_to_context_core(state, sid, scontext,
+       return security_sid_to_context_core(sid, scontext,
                                            scontext_len, 0, 0);
 }
 
-int security_sid_to_context_force(struct selinux_state *state, u32 sid,
+int security_sid_to_context_force(u32 sid,
                                  char **scontext, u32 *scontext_len)
 {
-       return security_sid_to_context_core(state, sid, scontext,
+       return security_sid_to_context_core(sid, scontext,
                                            scontext_len, 1, 0);
 }
 
 /**
  * security_sid_to_context_inval - Obtain a context for a given SID if it
  *                                 is invalid.
- * @state: SELinux state
  * @sid: security identifier, SID
  * @scontext: security context
  * @scontext_len: length in bytes
@@ -1417,10 +1402,10 @@ int security_sid_to_context_force(struct selinux_state *state, u32 sid,
  * this string (or NULL if the context is valid) and set @scontext_len to
  * the length of the string (or 0 if the context is valid).
  */
-int security_sid_to_context_inval(struct selinux_state *state, u32 sid,
+int security_sid_to_context_inval(u32 sid,
                                  char **scontext, u32 *scontext_len)
 {
-       return security_sid_to_context_core(state, sid, scontext,
+       return security_sid_to_context_core(sid, scontext,
                                            scontext_len, 1, 1);
 }
 
@@ -1505,8 +1490,7 @@ out:
        return rc;
 }
 
-static int security_context_to_sid_core(struct selinux_state *state,
-                                       const char *scontext, u32 scontext_len,
+static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
                                        u32 *sid, u32 def_sid, gfp_t gfp_flags,
                                        int force)
 {
@@ -1526,7 +1510,7 @@ static int security_context_to_sid_core(struct selinux_state *state,
        if (!scontext2)
                return -ENOMEM;
 
-       if (!selinux_initialized(state)) {
+       if (!selinux_initialized()) {
                int i;
 
                for (i = 1; i < SECINITSID_NUM; i++) {
@@ -1551,7 +1535,7 @@ static int security_context_to_sid_core(struct selinux_state *state,
        }
 retry:
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        policydb = &policy->policydb;
        sidtab = policy->sidtab;
        rc = string_to_context_struct(policydb, sidtab, scontext2,
@@ -1583,7 +1567,6 @@ out:
 
 /**
  * security_context_to_sid - Obtain a SID for a given security context.
- * @state: SELinux state
  * @scontext: security context
  * @scontext_len: length in bytes
  * @sid: security identifier, SID
@@ -1594,18 +1577,16 @@ out:
  * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
  * memory is available, or 0 on success.
  */
-int security_context_to_sid(struct selinux_state *state,
-                           const char *scontext, u32 scontext_len, u32 *sid,
+int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid,
                            gfp_t gfp)
 {
-       return security_context_to_sid_core(state, scontext, scontext_len,
+       return security_context_to_sid_core(scontext, scontext_len,
                                            sid, SECSID_NULL, gfp, 0);
 }
 
-int security_context_str_to_sid(struct selinux_state *state,
-                               const char *scontext, u32 *sid, gfp_t gfp)
+int security_context_str_to_sid(const char *scontext, u32 *sid, gfp_t gfp)
 {
-       return security_context_to_sid(state, scontext, strlen(scontext),
+       return security_context_to_sid(scontext, strlen(scontext),
                                       sid, gfp);
 }
 
@@ -1613,7 +1594,6 @@ int security_context_str_to_sid(struct selinux_state *state,
  * security_context_to_sid_default - Obtain a SID for a given security context,
  * falling back to specified default if needed.
  *
- * @state: SELinux state
  * @scontext: security context
  * @scontext_len: length in bytes
  * @sid: security identifier, SID
@@ -1629,24 +1609,21 @@ int security_context_str_to_sid(struct selinux_state *state,
  * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
  * memory is available, or 0 on success.
  */
-int security_context_to_sid_default(struct selinux_state *state,
-                                   const char *scontext, u32 scontext_len,
+int security_context_to_sid_default(const char *scontext, u32 scontext_len,
                                    u32 *sid, u32 def_sid, gfp_t gfp_flags)
 {
-       return security_context_to_sid_core(state, scontext, scontext_len,
+       return security_context_to_sid_core(scontext, scontext_len,
                                            sid, def_sid, gfp_flags, 1);
 }
 
-int security_context_to_sid_force(struct selinux_state *state,
-                                 const char *scontext, u32 scontext_len,
+int security_context_to_sid_force(const char *scontext, u32 scontext_len,
                                  u32 *sid)
 {
-       return security_context_to_sid_core(state, scontext, scontext_len,
+       return security_context_to_sid_core(scontext, scontext_len,
                                            sid, SECSID_NULL, GFP_KERNEL, 1);
 }
 
 static int compute_sid_handle_invalid_context(
-       struct selinux_state *state,
        struct selinux_policy *policy,
        struct sidtab_entry *sentry,
        struct sidtab_entry *tentry,
@@ -1679,7 +1656,7 @@ out:
        kfree(s);
        kfree(t);
        kfree(n);
-       if (!enforcing_enabled(state))
+       if (!enforcing_enabled())
                return 0;
        return -EACCES;
 }
@@ -1714,8 +1691,7 @@ static void filename_compute_type(struct policydb *policydb,
        }
 }
 
-static int security_compute_sid(struct selinux_state *state,
-                               u32 ssid,
+static int security_compute_sid(u32 ssid,
                                u32 tsid,
                                u16 orig_tclass,
                                u32 specified,
@@ -1736,7 +1712,7 @@ static int security_compute_sid(struct selinux_state *state,
        int rc = 0;
        bool sock;
 
-       if (!selinux_initialized(state)) {
+       if (!selinux_initialized()) {
                switch (orig_tclass) {
                case SECCLASS_PROCESS: /* kernel value */
                        *out_sid = ssid;
@@ -1754,7 +1730,7 @@ retry:
 
        rcu_read_lock();
 
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
 
        if (kern) {
                tclass = unmap_class(&policy->map, orig_tclass);
@@ -1886,7 +1862,7 @@ retry:
 
        /* Check the validity of the context. */
        if (!policydb_context_isvalid(policydb, &newcontext)) {
-               rc = compute_sid_handle_invalid_context(state, policy, sentry,
+               rc = compute_sid_handle_invalid_context(policy, sentry,
                                                        tentry, tclass,
                                                        &newcontext);
                if (rc)
@@ -1908,7 +1884,6 @@ out:
 
 /**
  * security_transition_sid - Compute the SID for a new subject/object.
- * @state: SELinux state
  * @ssid: source security identifier
  * @tsid: target security identifier
  * @tclass: target security class
@@ -1921,27 +1896,24 @@ out:
  * if insufficient memory is available, or %0 if the new SID was
  * computed successfully.
  */
-int security_transition_sid(struct selinux_state *state,
-                           u32 ssid, u32 tsid, u16 tclass,
+int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
                            const struct qstr *qstr, u32 *out_sid)
 {
-       return security_compute_sid(state, ssid, tsid, tclass,
+       return security_compute_sid(ssid, tsid, tclass,
                                    AVTAB_TRANSITION,
                                    qstr ? qstr->name : NULL, out_sid, true);
 }
 
-int security_transition_sid_user(struct selinux_state *state,
-                                u32 ssid, u32 tsid, u16 tclass,
+int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
                                 const char *objname, u32 *out_sid)
 {
-       return security_compute_sid(state, ssid, tsid, tclass,
+       return security_compute_sid(ssid, tsid, tclass,
                                    AVTAB_TRANSITION,
                                    objname, out_sid, false);
 }
 
 /**
  * security_member_sid - Compute the SID for member selection.
- * @state: SELinux state
  * @ssid: source security identifier
  * @tsid: target security identifier
  * @tclass: target security class
@@ -1953,20 +1925,18 @@ int security_transition_sid_user(struct selinux_state *state,
  * if insufficient memory is available, or %0 if the SID was
  * computed successfully.
  */
-int security_member_sid(struct selinux_state *state,
-                       u32 ssid,
+int security_member_sid(u32 ssid,
                        u32 tsid,
                        u16 tclass,
                        u32 *out_sid)
 {
-       return security_compute_sid(state, ssid, tsid, tclass,
+       return security_compute_sid(ssid, tsid, tclass,
                                    AVTAB_MEMBER, NULL,
                                    out_sid, false);
 }
 
 /**
  * security_change_sid - Compute the SID for object relabeling.
- * @state: SELinux state
  * @ssid: source security identifier
  * @tsid: target security identifier
  * @tclass: target security class
@@ -1978,26 +1948,23 @@ int security_member_sid(struct selinux_state *state,
  * if insufficient memory is available, or %0 if the SID was
  * computed successfully.
  */
-int security_change_sid(struct selinux_state *state,
-                       u32 ssid,
+int security_change_sid(u32 ssid,
                        u32 tsid,
                        u16 tclass,
                        u32 *out_sid)
 {
-       return security_compute_sid(state,
-                                   ssid, tsid, tclass, AVTAB_CHANGE, NULL,
+       return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, NULL,
                                    out_sid, false);
 }
 
 static inline int convert_context_handle_invalid_context(
-       struct selinux_state *state,
        struct policydb *policydb,
        struct context *context)
 {
        char *s;
        u32 len;
 
-       if (enforcing_enabled(state))
+       if (enforcing_enabled())
                return -EINVAL;
 
        if (!context_struct_to_string(policydb, context, &s, &len)) {
@@ -2115,8 +2082,7 @@ int services_convert_context(struct convert_context_args *args,
 
        /* Check the validity of the new context. */
        if (!policydb_context_isvalid(args->newp, newc)) {
-               rc = convert_context_handle_invalid_context(args->state,
-                                                           args->oldp, oldc);
+               rc = convert_context_handle_invalid_context(args->oldp, oldc);
                if (rc)
                        goto bad;
        }
@@ -2135,8 +2101,7 @@ bad:
        return 0;
 }
 
-static void security_load_policycaps(struct selinux_state *state,
-                               struct selinux_policy *policy)
+static void security_load_policycaps(struct selinux_policy *policy)
 {
        struct policydb *p;
        unsigned int i;
@@ -2144,8 +2109,8 @@ static void security_load_policycaps(struct selinux_state *state,
 
        p = &policy->policydb;
 
-       for (i = 0; i < ARRAY_SIZE(state->policycap); i++)
-               WRITE_ONCE(state->policycap[i],
+       for (i = 0; i < ARRAY_SIZE(selinux_state.policycap); i++)
+               WRITE_ONCE(selinux_state.policycap[i],
                        ebitmap_get_bit(&p->policycaps, i));
 
        for (i = 0; i < ARRAY_SIZE(selinux_policycap_names); i++)
@@ -2181,9 +2146,9 @@ static void selinux_policy_cond_free(struct selinux_policy *policy)
        kfree(policy);
 }
 
-void selinux_policy_cancel(struct selinux_state *state,
-                          struct selinux_load_state *load_state)
+void selinux_policy_cancel(struct selinux_load_state *load_state)
 {
+       struct selinux_state *state = &selinux_state;
        struct selinux_policy *oldpolicy;
 
        oldpolicy = rcu_dereference_protected(state->policy,
@@ -2194,21 +2159,20 @@ void selinux_policy_cancel(struct selinux_state *state,
        kfree(load_state->convert_data);
 }
 
-static void selinux_notify_policy_change(struct selinux_state *state,
-                                       u32 seqno)
+static void selinux_notify_policy_change(u32 seqno)
 {
        /* Flush external caches and notify userspace of policy load */
-       avc_ss_reset(state->avc, seqno);
+       avc_ss_reset(seqno);
        selnl_notify_policyload(seqno);
-       selinux_status_update_policyload(state, seqno);
+       selinux_status_update_policyload(seqno);
        selinux_netlbl_cache_invalidate();
        selinux_xfrm_notify_policyload();
-       selinux_ima_measure_state_locked(state);
+       selinux_ima_measure_state_locked();
 }
 
-void selinux_policy_commit(struct selinux_state *state,
-                          struct selinux_load_state *load_state)
+void selinux_policy_commit(struct selinux_load_state *load_state)
 {
+       struct selinux_state *state = &selinux_state;
        struct selinux_policy *oldpolicy, *newpolicy = load_state->policy;
        unsigned long flags;
        u32 seqno;
@@ -2241,15 +2205,15 @@ void selinux_policy_commit(struct selinux_state *state,
        }
 
        /* Load the policycaps from the new policy */
-       security_load_policycaps(state, newpolicy);
+       security_load_policycaps(newpolicy);
 
-       if (!selinux_initialized(state)) {
+       if (!selinux_initialized()) {
                /*
                 * After first policy load, the security server is
                 * marked as initialized and ready to handle requests and
                 * any objects created prior to policy load are then labeled.
                 */
-               selinux_mark_initialized(state);
+               selinux_mark_initialized();
                selinux_complete_init();
        }
 
@@ -2259,12 +2223,11 @@ void selinux_policy_commit(struct selinux_state *state,
        kfree(load_state->convert_data);
 
        /* Notify others of the policy change */
-       selinux_notify_policy_change(state, seqno);
+       selinux_notify_policy_change(seqno);
 }
 
 /**
  * security_load_policy - Load a security policy configuration.
- * @state: SELinux state
  * @data: binary policy data
  * @len: length of data in bytes
  * @load_state: policy load state
@@ -2274,9 +2237,10 @@ void selinux_policy_commit(struct selinux_state *state,
  * This function will flush the access vector cache after
  * loading the new policy.
  */
-int security_load_policy(struct selinux_state *state, void *data, size_t len,
+int security_load_policy(void *data, size_t len,
                         struct selinux_load_state *load_state)
 {
+       struct selinux_state *state = &selinux_state;
        struct selinux_policy *newpolicy, *oldpolicy;
        struct selinux_policy_convert_data *convert_data;
        int rc = 0;
@@ -2308,7 +2272,7 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len,
                goto err_mapping;
        }
 
-       if (!selinux_initialized(state)) {
+       if (!selinux_initialized()) {
                /* First policy load, so no need to preserve state from old policy */
                load_state->policy = newpolicy;
                load_state->convert_data = NULL;
@@ -2336,7 +2300,6 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len,
                goto err_free_isids;
        }
 
-       convert_data->args.state = state;
        convert_data->args.oldp = &oldpolicy->policydb;
        convert_data->args.newp = &newpolicy->policydb;
 
@@ -2410,13 +2373,11 @@ static int ocontext_to_sid(struct sidtab *sidtab, struct ocontext *c,
 
 /**
  * security_port_sid - Obtain the SID for a port.
- * @state: SELinux state
  * @protocol: protocol number
  * @port: port number
  * @out_sid: security identifier
  */
-int security_port_sid(struct selinux_state *state,
-                     u8 protocol, u16 port, u32 *out_sid)
+int security_port_sid(u8 protocol, u16 port, u32 *out_sid)
 {
        struct selinux_policy *policy;
        struct policydb *policydb;
@@ -2424,7 +2385,7 @@ int security_port_sid(struct selinux_state *state,
        struct ocontext *c;
        int rc;
 
-       if (!selinux_initialized(state)) {
+       if (!selinux_initialized()) {
                *out_sid = SECINITSID_PORT;
                return 0;
        }
@@ -2432,7 +2393,7 @@ int security_port_sid(struct selinux_state *state,
 retry:
        rc = 0;
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        policydb = &policy->policydb;
        sidtab = policy->sidtab;
 
@@ -2464,13 +2425,11 @@ out:
 
 /**
  * security_ib_pkey_sid - Obtain the SID for a pkey.
- * @state: SELinux state
  * @subnet_prefix: Subnet Prefix
  * @pkey_num: pkey number
  * @out_sid: security identifier
  */
-int security_ib_pkey_sid(struct selinux_state *state,
-                        u64 subnet_prefix, u16 pkey_num, u32 *out_sid)
+int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid)
 {
        struct selinux_policy *policy;
        struct policydb *policydb;
@@ -2478,7 +2437,7 @@ int security_ib_pkey_sid(struct selinux_state *state,
        struct ocontext *c;
        int rc;
 
-       if (!selinux_initialized(state)) {
+       if (!selinux_initialized()) {
                *out_sid = SECINITSID_UNLABELED;
                return 0;
        }
@@ -2486,7 +2445,7 @@ int security_ib_pkey_sid(struct selinux_state *state,
 retry:
        rc = 0;
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        policydb = &policy->policydb;
        sidtab = policy->sidtab;
 
@@ -2518,13 +2477,11 @@ out:
 
 /**
  * security_ib_endport_sid - Obtain the SID for a subnet management interface.
- * @state: SELinux state
  * @dev_name: device name
  * @port_num: port number
  * @out_sid: security identifier
  */
-int security_ib_endport_sid(struct selinux_state *state,
-                           const char *dev_name, u8 port_num, u32 *out_sid)
+int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid)
 {
        struct selinux_policy *policy;
        struct policydb *policydb;
@@ -2532,7 +2489,7 @@ int security_ib_endport_sid(struct selinux_state *state,
        struct ocontext *c;
        int rc;
 
-       if (!selinux_initialized(state)) {
+       if (!selinux_initialized()) {
                *out_sid = SECINITSID_UNLABELED;
                return 0;
        }
@@ -2540,7 +2497,7 @@ int security_ib_endport_sid(struct selinux_state *state,
 retry:
        rc = 0;
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        policydb = &policy->policydb;
        sidtab = policy->sidtab;
 
@@ -2573,12 +2530,10 @@ out:
 
 /**
  * security_netif_sid - Obtain the SID for a network interface.
- * @state: SELinux state
  * @name: interface name
  * @if_sid: interface SID
  */
-int security_netif_sid(struct selinux_state *state,
-                      char *name, u32 *if_sid)
+int security_netif_sid(char *name, u32 *if_sid)
 {
        struct selinux_policy *policy;
        struct policydb *policydb;
@@ -2586,7 +2541,7 @@ int security_netif_sid(struct selinux_state *state,
        int rc;
        struct ocontext *c;
 
-       if (!selinux_initialized(state)) {
+       if (!selinux_initialized()) {
                *if_sid = SECINITSID_NETIF;
                return 0;
        }
@@ -2594,7 +2549,7 @@ int security_netif_sid(struct selinux_state *state,
 retry:
        rc = 0;
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        policydb = &policy->policydb;
        sidtab = policy->sidtab;
 
@@ -2636,14 +2591,12 @@ static int match_ipv6_addrmask(u32 *input, u32 *addr, u32 *mask)
 
 /**
  * security_node_sid - Obtain the SID for a node (host).
- * @state: SELinux state
  * @domain: communication domain aka address family
  * @addrp: address
  * @addrlen: address length in bytes
  * @out_sid: security identifier
  */
-int security_node_sid(struct selinux_state *state,
-                     u16 domain,
+int security_node_sid(u16 domain,
                      void *addrp,
                      u32 addrlen,
                      u32 *out_sid)
@@ -2654,14 +2607,14 @@ int security_node_sid(struct selinux_state *state,
        int rc;
        struct ocontext *c;
 
-       if (!selinux_initialized(state)) {
+       if (!selinux_initialized()) {
                *out_sid = SECINITSID_NODE;
                return 0;
        }
 
 retry:
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        policydb = &policy->policydb;
        sidtab = policy->sidtab;
 
@@ -2725,7 +2678,6 @@ out:
 
 /**
  * security_get_user_sids - Obtain reachable SIDs for a user.
- * @state: SELinux state
  * @fromsid: starting SID
  * @username: username
  * @sids: array of reachable SIDs for user
@@ -2738,8 +2690,7 @@ out:
  * number of elements in the array.
  */
 
-int security_get_user_sids(struct selinux_state *state,
-                          u32 fromsid,
+int security_get_user_sids(u32 fromsid,
                           char *username,
                           u32 **sids,
                           u32 *nel)
@@ -2758,7 +2709,7 @@ int security_get_user_sids(struct selinux_state *state,
        *sids = NULL;
        *nel = 0;
 
-       if (!selinux_initialized(state))
+       if (!selinux_initialized())
                return 0;
 
        mysids = kcalloc(maxnel, sizeof(*mysids), GFP_KERNEL);
@@ -2768,7 +2719,7 @@ int security_get_user_sids(struct selinux_state *state,
 retry:
        mynel = 0;
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        policydb = &policy->policydb;
        sidtab = policy->sidtab;
 
@@ -2834,8 +2785,7 @@ out_unlock:
        }
        for (i = 0, j = 0; i < mynel; i++) {
                struct av_decision dummy_avd;
-               rc = avc_has_perm_noaudit(state,
-                                         fromsid, mysids[i],
+               rc = avc_has_perm_noaudit(fromsid, mysids[i],
                                          SECCLASS_PROCESS, /* kernel value */
                                          PROCESS__TRANSITION, AVC_STRICT,
                                          &dummy_avd);
@@ -2908,7 +2858,6 @@ static inline int __security_genfs_sid(struct selinux_policy *policy,
 
 /**
  * security_genfs_sid - Obtain a SID for a file in a filesystem
- * @state: SELinux state
  * @fstype: filesystem type
  * @path: path from root of mount
  * @orig_sclass: file security class
@@ -2917,8 +2866,7 @@ static inline int __security_genfs_sid(struct selinux_policy *policy,
  * Acquire policy_rwlock before calling __security_genfs_sid() and release
  * it afterward.
  */
-int security_genfs_sid(struct selinux_state *state,
-                      const char *fstype,
+int security_genfs_sid(const char *fstype,
                       const char *path,
                       u16 orig_sclass,
                       u32 *sid)
@@ -2926,14 +2874,14 @@ int security_genfs_sid(struct selinux_state *state,
        struct selinux_policy *policy;
        int retval;
 
-       if (!selinux_initialized(state)) {
+       if (!selinux_initialized()) {
                *sid = SECINITSID_UNLABELED;
                return 0;
        }
 
        do {
                rcu_read_lock();
-               policy = rcu_dereference(state->policy);
+               policy = rcu_dereference(selinux_state.policy);
                retval = __security_genfs_sid(policy, fstype, path,
                                              orig_sclass, sid);
                rcu_read_unlock();
@@ -2953,10 +2901,9 @@ int selinux_policy_genfs_sid(struct selinux_policy *policy,
 
 /**
  * security_fs_use - Determine how to handle labeling for a filesystem.
- * @state: SELinux state
  * @sb: superblock in question
  */
-int security_fs_use(struct selinux_state *state, struct super_block *sb)
+int security_fs_use(struct super_block *sb)
 {
        struct selinux_policy *policy;
        struct policydb *policydb;
@@ -2966,7 +2913,7 @@ int security_fs_use(struct selinux_state *state, struct super_block *sb)
        struct superblock_security_struct *sbsec = selinux_superblock(sb);
        const char *fstype = sb->s_type->name;
 
-       if (!selinux_initialized(state)) {
+       if (!selinux_initialized()) {
                sbsec->behavior = SECURITY_FS_USE_NONE;
                sbsec->sid = SECINITSID_UNLABELED;
                return 0;
@@ -2974,7 +2921,7 @@ int security_fs_use(struct selinux_state *state, struct super_block *sb)
 
 retry:
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        policydb = &policy->policydb;
        sidtab = policy->sidtab;
 
@@ -3067,13 +3014,14 @@ err:
 }
 
 
-int security_set_bools(struct selinux_state *state, u32 len, int *values)
+int security_set_bools(u32 len, int *values)
 {
+       struct selinux_state *state = &selinux_state;
        struct selinux_policy *newpolicy, *oldpolicy;
        int rc;
        u32 i, seqno = 0;
 
-       if (!selinux_initialized(state))
+       if (!selinux_initialized())
                return -EINVAL;
 
        oldpolicy = rcu_dereference_protected(state->policy,
@@ -3134,23 +3082,22 @@ int security_set_bools(struct selinux_state *state, u32 len, int *values)
        selinux_policy_cond_free(oldpolicy);
 
        /* Notify others of the policy change */
-       selinux_notify_policy_change(state, seqno);
+       selinux_notify_policy_change(seqno);
        return 0;
 }
 
-int security_get_bool_value(struct selinux_state *state,
-                           u32 index)
+int security_get_bool_value(u32 index)
 {
        struct selinux_policy *policy;
        struct policydb *policydb;
        int rc;
        u32 len;
 
-       if (!selinux_initialized(state))
+       if (!selinux_initialized())
                return 0;
 
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        policydb = &policy->policydb;
 
        rc = -EFAULT;
@@ -3197,8 +3144,7 @@ out:
  * security_sid_mls_copy() - computes a new sid based on the given
  * sid and the mls portion of mls_sid.
  */
-int security_sid_mls_copy(struct selinux_state *state,
-                         u32 sid, u32 mls_sid, u32 *new_sid)
+int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
 {
        struct selinux_policy *policy;
        struct policydb *policydb;
@@ -3210,7 +3156,7 @@ int security_sid_mls_copy(struct selinux_state *state,
        u32 len;
        int rc;
 
-       if (!selinux_initialized(state)) {
+       if (!selinux_initialized()) {
                *new_sid = sid;
                return 0;
        }
@@ -3220,7 +3166,7 @@ retry:
        context_init(&newcon);
 
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        policydb = &policy->policydb;
        sidtab = policy->sidtab;
 
@@ -3254,7 +3200,7 @@ retry:
 
        /* Check the validity of the new context. */
        if (!policydb_context_isvalid(policydb, &newcon)) {
-               rc = convert_context_handle_invalid_context(state, policydb,
+               rc = convert_context_handle_invalid_context(policydb,
                                                        &newcon);
                if (rc) {
                        if (!context_struct_to_string(policydb, &newcon, &s,
@@ -3288,7 +3234,6 @@ out_unlock:
 
 /**
  * security_net_peersid_resolve - Compare and resolve two network peer SIDs
- * @state: SELinux state
  * @nlbl_sid: NetLabel SID
  * @nlbl_type: NetLabel labeling protocol type
  * @xfrm_sid: XFRM SID
@@ -3308,8 +3253,7 @@ out_unlock:
  *   multiple, inconsistent labels |    -<errno>     |    SECSID_NULL
  *
  */
-int security_net_peersid_resolve(struct selinux_state *state,
-                                u32 nlbl_sid, u32 nlbl_type,
+int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
                                 u32 xfrm_sid,
                                 u32 *peer_sid)
 {
@@ -3337,11 +3281,11 @@ int security_net_peersid_resolve(struct selinux_state *state,
                return 0;
        }
 
-       if (!selinux_initialized(state))
+       if (!selinux_initialized())
                return 0;
 
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        policydb = &policy->policydb;
        sidtab = policy->sidtab;
 
@@ -3482,31 +3426,31 @@ err:
        return rc;
 }
 
-int security_get_reject_unknown(struct selinux_state *state)
+int security_get_reject_unknown(void)
 {
        struct selinux_policy *policy;
        int value;
 
-       if (!selinux_initialized(state))
+       if (!selinux_initialized())
                return 0;
 
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        value = policy->policydb.reject_unknown;
        rcu_read_unlock();
        return value;
 }
 
-int security_get_allow_unknown(struct selinux_state *state)
+int security_get_allow_unknown(void)
 {
        struct selinux_policy *policy;
        int value;
 
-       if (!selinux_initialized(state))
+       if (!selinux_initialized())
                return 0;
 
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        value = policy->policydb.allow_unknown;
        rcu_read_unlock();
        return value;
@@ -3514,7 +3458,6 @@ int security_get_allow_unknown(struct selinux_state *state)
 
 /**
  * security_policycap_supported - Check for a specific policy capability
- * @state: SELinux state
  * @req_cap: capability
  *
  * Description:
@@ -3523,17 +3466,16 @@ int security_get_allow_unknown(struct selinux_state *state)
  * supported, false (0) if it isn't supported.
  *
  */
-int security_policycap_supported(struct selinux_state *state,
-                                unsigned int req_cap)
+int security_policycap_supported(unsigned int req_cap)
 {
        struct selinux_policy *policy;
        int rc;
 
-       if (!selinux_initialized(state))
+       if (!selinux_initialized())
                return 0;
 
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        rc = ebitmap_get_bit(&policy->policydb.policycaps, req_cap);
        rcu_read_unlock();
 
@@ -3569,7 +3511,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
 
        *rule = NULL;
 
-       if (!selinux_initialized(state))
+       if (!selinux_initialized())
                return -EOPNOTSUPP;
 
        switch (field) {
@@ -3696,7 +3638,7 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule)
                return -ENOENT;
        }
 
-       if (!selinux_initialized(state))
+       if (!selinux_initialized())
                return 0;
 
        rcu_read_lock();
@@ -3849,7 +3791,6 @@ static void security_netlbl_cache_add(struct netlbl_lsm_secattr *secattr,
 
 /**
  * security_netlbl_secattr_to_sid - Convert a NetLabel secattr to a SELinux SID
- * @state: SELinux state
  * @secattr: the NetLabel packet security attributes
  * @sid: the SELinux SID
  *
@@ -3863,8 +3804,7 @@ static void security_netlbl_cache_add(struct netlbl_lsm_secattr *secattr,
  * failure.
  *
  */
-int security_netlbl_secattr_to_sid(struct selinux_state *state,
-                                  struct netlbl_lsm_secattr *secattr,
+int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
                                   u32 *sid)
 {
        struct selinux_policy *policy;
@@ -3874,7 +3814,7 @@ int security_netlbl_secattr_to_sid(struct selinux_state *state,
        struct context *ctx;
        struct context ctx_new;
 
-       if (!selinux_initialized(state)) {
+       if (!selinux_initialized()) {
                *sid = SECSID_NULL;
                return 0;
        }
@@ -3882,7 +3822,7 @@ int security_netlbl_secattr_to_sid(struct selinux_state *state,
 retry:
        rc = 0;
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        policydb = &policy->policydb;
        sidtab = policy->sidtab;
 
@@ -3932,7 +3872,6 @@ out:
 
 /**
  * security_netlbl_sid_to_secattr - Convert a SELinux SID to a NetLabel secattr
- * @state: SELinux state
  * @sid: the SELinux SID
  * @secattr: the NetLabel packet security attributes
  *
@@ -3941,19 +3880,18 @@ out:
  * Returns zero on success, negative values on failure.
  *
  */
-int security_netlbl_sid_to_secattr(struct selinux_state *state,
-                                  u32 sid, struct netlbl_lsm_secattr *secattr)
+int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr)
 {
        struct selinux_policy *policy;
        struct policydb *policydb;
        int rc;
        struct context *ctx;
 
-       if (!selinux_initialized(state))
+       if (!selinux_initialized())
                return 0;
 
        rcu_read_lock();
-       policy = rcu_dereference(state->policy);
+       policy = rcu_dereference(selinux_state.policy);
        policydb = &policy->policydb;
 
        rc = -ENOENT;
@@ -4003,14 +3941,13 @@ static int __security_read_policy(struct selinux_policy *policy,
 
 /**
  * security_read_policy - read the policy.
- * @state: selinux_state
  * @data: binary policy data
  * @len: length of data in bytes
  *
  */
-int security_read_policy(struct selinux_state *state,
-                        void **data, size_t *len)
+int security_read_policy(void **data, size_t *len)
 {
+       struct selinux_state *state = &selinux_state;
        struct selinux_policy *policy;
 
        policy = rcu_dereference_protected(
@@ -4028,7 +3965,6 @@ int security_read_policy(struct selinux_state *state,
 
 /**
  * security_read_state_kernel - read the policy.
- * @state: selinux_state
  * @data: binary policy data
  * @len: length of data in bytes
  *
@@ -4038,10 +3974,10 @@ int security_read_policy(struct selinux_state *state,
  *
  * This function must be called with policy_mutex held.
  */
-int security_read_state_kernel(struct selinux_state *state,
-                              void **data, size_t *len)
+int security_read_state_kernel(void **data, size_t *len)
 {
        int err;
+       struct selinux_state *state = &selinux_state;
        struct selinux_policy *policy;
 
        policy = rcu_dereference_protected(
index c4301626487fc1476828db94e1a40a14de2ae830..8a9b85f44b664b392e2e93504c17ce2f5322f9e4 100644 (file)
@@ -30,7 +30,6 @@ struct selinux_policy {
 } __randomize_layout;
 
 struct convert_context_args {
-       struct selinux_state *state;
        struct policydb *oldp;
        struct policydb *newp;
 };
index 4bc8f809934c84deb6e72ceed8078d7782aa18fd..19ef929a075cb06af660e1b9a35fe3518065ae90 100644 (file)
  * It returns a reference to selinux_status_page. If the status page is
  * not allocated yet, it also tries to allocate it at the first time.
  */
-struct page *selinux_kernel_status_page(struct selinux_state *state)
+struct page *selinux_kernel_status_page(void)
 {
        struct selinux_kernel_status   *status;
        struct page                    *result = NULL;
 
-       mutex_lock(&state->status_lock);
-       if (!state->status_page) {
-               state->status_page = alloc_page(GFP_KERNEL|__GFP_ZERO);
+       mutex_lock(&selinux_state.status_lock);
+       if (!selinux_state.status_page) {
+               selinux_state.status_page = alloc_page(GFP_KERNEL|__GFP_ZERO);
 
-               if (state->status_page) {
-                       status = page_address(state->status_page);
+               if (selinux_state.status_page) {
+                       status = page_address(selinux_state.status_page);
 
                        status->version = SELINUX_KERNEL_STATUS_VERSION;
                        status->sequence = 0;
-                       status->enforcing = enforcing_enabled(state);
+                       status->enforcing = enforcing_enabled();
                        /*
                         * NOTE: the next policyload event shall set
                         * a positive value on the status->policyload,
@@ -62,11 +62,11 @@ struct page *selinux_kernel_status_page(struct selinux_state *state)
                         */
                        status->policyload = 0;
                        status->deny_unknown =
-                               !security_get_allow_unknown(state);
+                               !security_get_allow_unknown();
                }
        }
-       result = state->status_page;
-       mutex_unlock(&state->status_lock);
+       result = selinux_state.status_page;
+       mutex_unlock(&selinux_state.status_lock);
 
        return result;
 }
@@ -76,14 +76,13 @@ struct page *selinux_kernel_status_page(struct selinux_state *state)
  *
  * It updates status of the current enforcing/permissive mode.
  */
-void selinux_status_update_setenforce(struct selinux_state *state,
-                                     int enforcing)
+void selinux_status_update_setenforce(int enforcing)
 {
        struct selinux_kernel_status   *status;
 
-       mutex_lock(&state->status_lock);
-       if (state->status_page) {
-               status = page_address(state->status_page);
+       mutex_lock(&selinux_state.status_lock);
+       if (selinux_state.status_page) {
+               status = page_address(selinux_state.status_page);
 
                status->sequence++;
                smp_wmb();
@@ -93,7 +92,7 @@ void selinux_status_update_setenforce(struct selinux_state *state,
                smp_wmb();
                status->sequence++;
        }
-       mutex_unlock(&state->status_lock);
+       mutex_unlock(&selinux_state.status_lock);
 }
 
 /*
@@ -102,23 +101,22 @@ void selinux_status_update_setenforce(struct selinux_state *state,
  * It updates status of the times of policy reloaded, and current
  * setting of deny_unknown.
  */
-void selinux_status_update_policyload(struct selinux_state *state,
-                                     int seqno)
+void selinux_status_update_policyload(int seqno)
 {
        struct selinux_kernel_status   *status;
 
-       mutex_lock(&state->status_lock);
-       if (state->status_page) {
-               status = page_address(state->status_page);
+       mutex_lock(&selinux_state.status_lock);
+       if (selinux_state.status_page) {
+               status = page_address(selinux_state.status_page);
 
                status->sequence++;
                smp_wmb();
 
                status->policyload = seqno;
-               status->deny_unknown = !security_get_allow_unknown(state);
+               status->deny_unknown = !security_get_allow_unknown();
 
                smp_wmb();
                status->sequence++;
        }
-       mutex_unlock(&state->status_lock);
+       mutex_unlock(&selinux_state.status_lock);
 }
index c576832febc67d63d6a14de2c366553649d113a8..1fca42c4d0ae36c753278c429d25ec6029fdb2d5 100644 (file)
@@ -98,13 +98,12 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
        ctx->ctx_len = str_len;
        memcpy(ctx->ctx_str, &uctx[1], str_len);
        ctx->ctx_str[str_len] = '\0';
-       rc = security_context_to_sid(&selinux_state, ctx->ctx_str, str_len,
+       rc = security_context_to_sid(ctx->ctx_str, str_len,
                                     &ctx->ctx_sid, gfp);
        if (rc)
                goto err;
 
-       rc = avc_has_perm(&selinux_state,
-                         tsec->sid, ctx->ctx_sid,
+       rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
                          SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, NULL);
        if (rc)
                goto err;
@@ -140,8 +139,7 @@ static int selinux_xfrm_delete(struct xfrm_sec_ctx *ctx)
        if (!ctx)
                return 0;
 
-       return avc_has_perm(&selinux_state,
-                           tsec->sid, ctx->ctx_sid,
+       return avc_has_perm(tsec->sid, ctx->ctx_sid,
                            SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT,
                            NULL);
 }
@@ -163,8 +161,7 @@ int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid)
        if (!selinux_authorizable_ctx(ctx))
                return -EINVAL;
 
-       rc = avc_has_perm(&selinux_state,
-                         fl_secid, ctx->ctx_sid,
+       rc = avc_has_perm(fl_secid, ctx->ctx_sid,
                          SECCLASS_ASSOCIATION, ASSOCIATION__POLMATCH, NULL);
        return (rc == -EACCES ? -ESRCH : rc);
 }
@@ -205,7 +202,7 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
        /* We don't need a separate SA Vs. policy polmatch check since the SA
         * is now of the same label as the flow and a flow Vs. policy polmatch
         * check had already happened in selinux_xfrm_policy_lookup() above. */
-       return (avc_has_perm(&selinux_state, flic_sid, state_sid,
+       return (avc_has_perm(flic_sid, state_sid,
                             SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO,
                             NULL) ? 0 : 1);
 }
@@ -355,7 +352,7 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
        if (secid == 0)
                return -EINVAL;
 
-       rc = security_sid_to_context(&selinux_state, secid, &ctx_str,
+       rc = security_sid_to_context(secid, &ctx_str,
                                     &str_len);
        if (rc)
                return rc;
@@ -424,8 +421,7 @@ int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb,
        /* This check even when there's no association involved is intended,
         * according to Trent Jaeger, to make sure a process can't engage in
         * non-IPsec communication unless explicitly allowed by policy. */
-       return avc_has_perm(&selinux_state,
-                           sk_sid, peer_sid,
+       return avc_has_perm(sk_sid, peer_sid,
                            SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, ad);
 }
 
@@ -468,6 +464,6 @@ int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb,
        /* This check even when there's no association involved is intended,
         * according to Trent Jaeger, to make sure a process can't engage in
         * non-IPsec communication unless explicitly allowed by policy. */
-       return avc_has_perm(&selinux_state, sk_sid, SECINITSID_UNLABELED,
+       return avc_has_perm(sk_sid, SECINITSID_UNLABELED,
                            SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, ad);
 }
index cfcbb748da2534c24088e5805ec8d1458c228457..7a3e9ab137d85bcf4b0fa11604cb2e095b59dfe3 100644 (file)
@@ -550,23 +550,22 @@ static int smack_sb_alloc_security(struct super_block *sb)
 }
 
 struct smack_mnt_opts {
-       const char *fsdefault, *fsfloor, *fshat, *fsroot, *fstransmute;
+       const char *fsdefault;
+       const char *fsfloor;
+       const char *fshat;
+       const char *fsroot;
+       const char *fstransmute;
 };
 
 static void smack_free_mnt_opts(void *mnt_opts)
 {
-       struct smack_mnt_opts *opts = mnt_opts;
-       kfree(opts->fsdefault);
-       kfree(opts->fsfloor);
-       kfree(opts->fshat);
-       kfree(opts->fsroot);
-       kfree(opts->fstransmute);
-       kfree(opts);
+       kfree(mnt_opts);
 }
 
 static int smack_add_opt(int token, const char *s, void **mnt_opts)
 {
        struct smack_mnt_opts *opts = *mnt_opts;
+       struct smack_known *skp;
 
        if (!opts) {
                opts = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL);
@@ -577,31 +576,35 @@ static int smack_add_opt(int token, const char *s, void **mnt_opts)
        if (!s)
                return -ENOMEM;
 
+       skp = smk_import_entry(s, 0);
+       if (IS_ERR(skp))
+               return PTR_ERR(skp);
+
        switch (token) {
        case Opt_fsdefault:
                if (opts->fsdefault)
                        goto out_opt_err;
-               opts->fsdefault = s;
+               opts->fsdefault = skp->smk_known;
                break;
        case Opt_fsfloor:
                if (opts->fsfloor)
                        goto out_opt_err;
-               opts->fsfloor = s;
+               opts->fsfloor = skp->smk_known;
                break;
        case Opt_fshat:
                if (opts->fshat)
                        goto out_opt_err;
-               opts->fshat = s;
+               opts->fshat = skp->smk_known;
                break;
        case Opt_fsroot:
                if (opts->fsroot)
                        goto out_opt_err;
-               opts->fsroot = s;
+               opts->fsroot = skp->smk_known;
                break;
        case Opt_fstransmute:
                if (opts->fstransmute)
                        goto out_opt_err;
-               opts->fstransmute = s;
+               opts->fstransmute = skp->smk_known;
                break;
        }
        return 0;
@@ -629,33 +632,14 @@ static int smack_fs_context_dup(struct fs_context *fc,
        fc->security = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL);
        if (!fc->security)
                return -ENOMEM;
+
        dst = fc->security;
+       dst->fsdefault = src->fsdefault;
+       dst->fsfloor = src->fsfloor;
+       dst->fshat = src->fshat;
+       dst->fsroot = src->fsroot;
+       dst->fstransmute = src->fstransmute;
 
-       if (src->fsdefault) {
-               dst->fsdefault = kstrdup(src->fsdefault, GFP_KERNEL);
-               if (!dst->fsdefault)
-                       return -ENOMEM;
-       }
-       if (src->fsfloor) {
-               dst->fsfloor = kstrdup(src->fsfloor, GFP_KERNEL);
-               if (!dst->fsfloor)
-                       return -ENOMEM;
-       }
-       if (src->fshat) {
-               dst->fshat = kstrdup(src->fshat, GFP_KERNEL);
-               if (!dst->fshat)
-                       return -ENOMEM;
-       }
-       if (src->fsroot) {
-               dst->fsroot = kstrdup(src->fsroot, GFP_KERNEL);
-               if (!dst->fsroot)
-                       return -ENOMEM;
-       }
-       if (src->fstransmute) {
-               dst->fstransmute = kstrdup(src->fstransmute, GFP_KERNEL);
-               if (!dst->fstransmute)
-                       return -ENOMEM;
-       }
        return 0;
 }
 
@@ -712,8 +696,8 @@ static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts)
                if (token != Opt_error) {
                        arg = kmemdup_nul(arg, from + len - arg, GFP_KERNEL);
                        rc = smack_add_opt(token, arg, mnt_opts);
+                       kfree(arg);
                        if (unlikely(rc)) {
-                               kfree(arg);
                                if (*mnt_opts)
                                        smack_free_mnt_opts(*mnt_opts);
                                *mnt_opts = NULL;
@@ -1477,7 +1461,7 @@ static int smack_inode_getsecurity(struct mnt_idmap *idmap,
        struct socket_smack *ssp;
        struct socket *sock;
        struct super_block *sbp;
-       struct inode *ip = (struct inode *)inode;
+       struct inode *ip = inode;
        struct smack_known *isp;
 
        if (strcmp(name, XATTR_SMACK_SUFFIX) == 0)
@@ -4847,7 +4831,7 @@ static int smack_uring_cmd(struct io_uring_cmd *ioucmd)
 
 #endif /* CONFIG_IO_URING */
 
-struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = {
+struct lsm_blob_sizes smack_blob_sizes __ro_after_init = {
        .lbs_cred = sizeof(struct task_smack),
        .lbs_file = sizeof(struct smack_known *),
        .lbs_inode = sizeof(struct inode_smack),
@@ -4856,7 +4840,7 @@ struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = {
        .lbs_superblock = sizeof(struct superblock_smack),
 };
 
-static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
+static struct security_hook_list smack_hooks[] __ro_after_init = {
        LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check),
        LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme),
        LSM_HOOK_INIT(syslog, smack_syslog),
index 7cf8fdbb29bfd8642d437aee1b28b730d8a62654..610c1536cf70ca482b0fecf2db086a04e63a7b40 100644 (file)
@@ -271,7 +271,7 @@ char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt,
                /* +18 is for " symlink.target=\"%s\"" */
                len += 18 + strlen(symlink);
        }
-       len = tomoyo_round2(len);
+       len = kmalloc_size_roundup(len);
        buf = kzalloc(len, GFP_NOFS);
        if (!buf)
                goto out;
@@ -382,12 +382,12 @@ void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt,
                goto out;
        }
        entry->log = buf;
-       len = tomoyo_round2(strlen(buf) + 1);
+       len = kmalloc_size_roundup(strlen(buf) + 1);
        /*
         * The entry->size is used for memory quota checks.
         * Don't go beyond strlen(entry->log).
         */
-       entry->size = len + tomoyo_round2(sizeof(*entry));
+       entry->size = len + kmalloc_size_roundup(sizeof(*entry));
        spin_lock(&tomoyo_log_lock);
        if (tomoyo_memory_quota[TOMOYO_MEMORY_AUDIT] &&
            tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] + entry->size >=
index f4cd9b58b20547ec29bdfef8a77421b0cb5b596f..969d4aa6fd556f38f09ae7cb573973fd5a209479 100644 (file)
@@ -2094,7 +2094,7 @@ int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
                tomoyo_add_entry(r->domain, entry.query);
                goto out;
        }
-       len = tomoyo_round2(entry.query_len);
+       len = kmalloc_size_roundup(entry.query_len);
        entry.domain = r->domain;
        spin_lock(&tomoyo_query_list_lock);
        if (tomoyo_memory_quota[TOMOYO_MEMORY_QUERY] &&
index ca285f3627053330c1a39ebfe932cc3f2b88b424..a539b2cbb5c45a036b1a508d132bd0e1ba91c3db 100644 (file)
@@ -1276,50 +1276,6 @@ static inline struct tomoyo_policy_namespace *tomoyo_current_namespace(void)
        return tomoyo_domain()->ns;
 }
 
-#if defined(CONFIG_SLOB)
-
-/**
- * tomoyo_round2 - Round up to power of 2 for calculating memory usage.
- *
- * @size: Size to be rounded up.
- *
- * Returns @size.
- *
- * Since SLOB does not round up, this function simply returns @size.
- */
-static inline int tomoyo_round2(size_t size)
-{
-       return size;
-}
-
-#else
-
-/**
- * tomoyo_round2 - Round up to power of 2 for calculating memory usage.
- *
- * @size: Size to be rounded up.
- *
- * Returns rounded size.
- *
- * Strictly speaking, SLAB may be able to allocate (e.g.) 96 bytes instead of
- * (e.g.) 128 bytes.
- */
-static inline int tomoyo_round2(size_t size)
-{
-#if PAGE_SIZE == 4096
-       size_t bsize = 32;
-#else
-       size_t bsize = 64;
-#endif
-       if (!size)
-               return 0;
-       while (size > bsize)
-               bsize <<= 1;
-       return bsize;
-}
-
-#endif
-
 /**
  * list_for_each_cookie - iterate over a list with cookie.
  * @pos:        the &struct list_head to use as a loop cursor.
index af04a7b7eb28544ca435e2cdc286b1ef6732e3ab..25006fddc964b44174ac1871b497ae18df002881 100644 (file)
@@ -499,7 +499,7 @@ static int tomoyo_socket_sendmsg(struct socket *sock, struct msghdr *msg,
        return tomoyo_socket_sendmsg_permission(sock, msg, size);
 }
 
-struct lsm_blob_sizes tomoyo_blob_sizes __lsm_ro_after_init = {
+struct lsm_blob_sizes tomoyo_blob_sizes __ro_after_init = {
        .lbs_task = sizeof(struct tomoyo_task),
 };
 
@@ -546,7 +546,7 @@ static void tomoyo_task_free(struct task_struct *task)
  * tomoyo_security_ops is a "struct security_operations" which is used for
  * registering TOMOYO.
  */
-static struct security_hook_list tomoyo_hooks[] __lsm_ro_after_init = {
+static struct security_hook_list tomoyo_hooks[] __ro_after_init = {
        LSM_HOOK_INIT(cred_prepare, tomoyo_cred_prepare),
        LSM_HOOK_INIT(bprm_committed_creds, tomoyo_bprm_committed_creds),
        LSM_HOOK_INIT(task_alloc, tomoyo_task_alloc),
@@ -583,7 +583,7 @@ static struct security_hook_list tomoyo_hooks[] __lsm_ro_after_init = {
 /* Lock for GC. */
 DEFINE_SRCU(tomoyo_ss);
 
-int tomoyo_enabled __lsm_ro_after_init = 1;
+int tomoyo_enabled __ro_after_init = 1;
 
 /**
  * tomoyo_init - Register TOMOYO Linux as a LSM module.
index 06e226166aab3a7e6d8e544ff3f6db05890f326b..478be269571ab167106032402139e2776a4e71d7 100644 (file)
@@ -421,7 +421,7 @@ static int yama_ptrace_traceme(struct task_struct *parent)
        return rc;
 }
 
-static struct security_hook_list yama_hooks[] __lsm_ro_after_init = {
+static struct security_hook_list yama_hooks[] __ro_after_init = {
        LSM_HOOK_INIT(ptrace_access_check, yama_ptrace_access_check),
        LSM_HOOK_INIT(ptrace_traceme, yama_ptrace_traceme),
        LSM_HOOK_INIT(task_prctl, yama_task_prctl),
index 8b6aeb8a78f7d3ac2819cda7b2781e1ec5035067..02fd65993e7e52e269b6a7fec59d48d3e5e5fda4 100644 (file)
@@ -2155,6 +2155,8 @@ int pcm_lib_apply_appl_ptr(struct snd_pcm_substream *substream,
                ret = substream->ops->ack(substream);
                if (ret < 0) {
                        runtime->control->appl_ptr = old_appl_ptr;
+                       if (ret == -EPIPE)
+                               __snd_pcm_xrun(substream);
                        return ret;
                }
        }
index 331380c2438bcfa470fe5b48bf35dedbd571d53e..5868661d461bc85c8ad2abfd60e4533fa04cd680 100644 (file)
@@ -3521,6 +3521,7 @@ static ssize_t snd_pcm_readv(struct kiocb *iocb, struct iov_iter *to)
        unsigned long i;
        void __user **bufs;
        snd_pcm_uframes_t frames;
+       const struct iovec *iov = iter_iov(to);
 
        pcm_file = iocb->ki_filp->private_data;
        substream = pcm_file->substream;
@@ -3530,18 +3531,20 @@ static ssize_t snd_pcm_readv(struct kiocb *iocb, struct iov_iter *to)
        if (runtime->state == SNDRV_PCM_STATE_OPEN ||
            runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
                return -EBADFD;
-       if (!iter_is_iovec(to))
+       if (!to->user_backed)
                return -EINVAL;
        if (to->nr_segs > 1024 || to->nr_segs != runtime->channels)
                return -EINVAL;
-       if (!frame_aligned(runtime, to->iov->iov_len))
+       if (!frame_aligned(runtime, iov->iov_len))
                return -EINVAL;
-       frames = bytes_to_samples(runtime, to->iov->iov_len);
+       frames = bytes_to_samples(runtime, iov->iov_len);
        bufs = kmalloc_array(to->nr_segs, sizeof(void *), GFP_KERNEL);
        if (bufs == NULL)
                return -ENOMEM;
-       for (i = 0; i < to->nr_segs; ++i)
-               bufs[i] = to->iov[i].iov_base;
+       for (i = 0; i < to->nr_segs; ++i) {
+               bufs[i] = iov->iov_base;
+               iov++;
+       }
        result = snd_pcm_lib_readv(substream, bufs, frames);
        if (result > 0)
                result = frames_to_bytes(runtime, result);
@@ -3558,6 +3561,7 @@ static ssize_t snd_pcm_writev(struct kiocb *iocb, struct iov_iter *from)
        unsigned long i;
        void __user **bufs;
        snd_pcm_uframes_t frames;
+       const struct iovec *iov = iter_iov(from);
 
        pcm_file = iocb->ki_filp->private_data;
        substream = pcm_file->substream;
@@ -3567,17 +3571,19 @@ static ssize_t snd_pcm_writev(struct kiocb *iocb, struct iov_iter *from)
        if (runtime->state == SNDRV_PCM_STATE_OPEN ||
            runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
                return -EBADFD;
-       if (!iter_is_iovec(from))
+       if (!from->user_backed)
                return -EINVAL;
        if (from->nr_segs > 128 || from->nr_segs != runtime->channels ||
-           !frame_aligned(runtime, from->iov->iov_len))
+           !frame_aligned(runtime, iov->iov_len))
                return -EINVAL;
-       frames = bytes_to_samples(runtime, from->iov->iov_len);
+       frames = bytes_to_samples(runtime, iov->iov_len);
        bufs = kmalloc_array(from->nr_segs, sizeof(void *), GFP_KERNEL);
        if (bufs == NULL)
                return -ENOMEM;
-       for (i = 0; i < from->nr_segs; ++i)
-               bufs[i] = from->iov[i].iov_base;
+       for (i = 0; i < from->nr_segs; ++i) {
+               bufs[i] = iov->iov_base;
+               iov++;
+       }
        result = snd_pcm_lib_writev(substream, bufs, frames);
        if (result > 0)
                result = frames_to_bytes(runtime, result);
index 53e094cc411f8676678f424e321f16c66dabeb21..dfe783d01d7d20cb4295625cecc8d5953f3607b3 100644 (file)
@@ -490,7 +490,7 @@ int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
                // packet is important for media clock recovery.
                err = amdtp_domain_start(&tscm->domain, tx_init_skip_cycles, true, true);
                if (err < 0)
-                       return err;
+                       goto error;
 
                if (!amdtp_domain_wait_ready(&tscm->domain, READY_TIMEOUT_MS)) {
                        err = -ETIMEDOUT;
index ae31bb1275940453efb026410e5673d1e53a9d1e..317bdf6dcbef42f0954a7b8e3b757b5c8dcf8185 100644 (file)
@@ -472,6 +472,15 @@ static const struct config_entry config_table[] = {
        },
 #endif
 
+/* Meteor Lake */
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_METEORLAKE)
+       /* Meteorlake-P */
+       {
+               .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
+               .device = 0x7e28,
+       },
+#endif
+
 };
 
 static const struct config_entry *snd_intel_dsp_find_config
index 65012af6a36e4f0c3307340de764cb8f426d4bb2..f58b14b490455040a4dd8449cd6768fc990ab421 100644 (file)
@@ -561,10 +561,13 @@ int snd_cs8427_iec958_active(struct snd_i2c_device *cs8427, int active)
        if (snd_BUG_ON(!cs8427))
                return -ENXIO;
        chip = cs8427->private_data;
-       if (active)
+       if (active) {
                memcpy(chip->playback.pcm_status,
                       chip->playback.def_status, 24);
-       chip->playback.pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+               chip->playback.pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+       } else {
+               chip->playback.pcm_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+       }
        snd_ctl_notify(cs8427->bus->card,
                       SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO,
                       &chip->playback.pcm_ctl->id);
index 27e11b5f70b97dc982867df42074fc35142517d3..c7d7eff86727f83672560c87fbf5e62114f67f91 100644 (file)
@@ -430,7 +430,7 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
                pao = hpi_find_adapter(phm->adapter_index);
        } else {
                /* subsys messages don't address an adapter */
-               _HPI_6205(NULL, phm, phr);
+               phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
                return;
        }
 
index 48af77ae8020f5a5c2ecca1c2bd974cc186f1779..6ec394fb1846845464b5e80158ce401ea4c03fcd 100644 (file)
@@ -1236,7 +1236,7 @@ static int snd_emu10k1_capture_mic_close(struct snd_pcm_substream *substream)
 {
        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
 
-       emu->capture_interrupt = NULL;
+       emu->capture_mic_interrupt = NULL;
        emu->pcm_capture_mic_substream = NULL;
        return 0;
 }
@@ -1344,7 +1344,7 @@ static int snd_emu10k1_capture_efx_close(struct snd_pcm_substream *substream)
 {
        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
 
-       emu->capture_interrupt = NULL;
+       emu->capture_efx_interrupt = NULL;
        emu->pcm_capture_efx_substream = NULL;
        return 0;
 }
@@ -1781,17 +1781,21 @@ int snd_emu10k1_pcm_efx(struct snd_emu10k1 *emu, int device)
        struct snd_kcontrol *kctl;
        int err;
 
-       err = snd_pcm_new(emu->card, "emu10k1 efx", device, 8, 1, &pcm);
+       err = snd_pcm_new(emu->card, "emu10k1 efx", device, emu->audigy ? 0 : 8, 1, &pcm);
        if (err < 0)
                return err;
 
        pcm->private_data = emu;
 
-       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_fx8010_playback_ops);
+       if (!emu->audigy)
+               snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_fx8010_playback_ops);
        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_efx_ops);
 
        pcm->info_flags = 0;
-       strcpy(pcm->name, "Multichannel Capture/PT Playback");
+       if (emu->audigy)
+               strcpy(pcm->name, "Multichannel Capture");
+       else
+               strcpy(pcm->name, "Multichannel Capture/PT Playback");
        emu->pcm_efx = pcm;
 
        /* EFX capture - record the "FXBUS2" channels, by default we connect the EXTINs 
index 81c4a45254ff2e33ee71f2a2a328b144954ff911..77a592f219472d9a472fa33d5e18a4fc6818350d 100644 (file)
@@ -328,14 +328,15 @@ enum {
 #define needs_eld_notify_link(chip)    false
 #endif
 
-#define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \
+#define CONTROLLER_IN_GPU(pci) (((pci)->vendor == 0x8086) &&         \
+                                      (((pci)->device == 0x0a0c) || \
                                        ((pci)->device == 0x0c0c) || \
                                        ((pci)->device == 0x0d0c) || \
                                        ((pci)->device == 0x160c) || \
                                        ((pci)->device == 0x490d) || \
                                        ((pci)->device == 0x4f90) || \
                                        ((pci)->device == 0x4f91) || \
-                                       ((pci)->device == 0x4f92))
+                                       ((pci)->device == 0x4f92)))
 
 #define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
 
index acde4cd58785e0cbaa8196bbacead97826e822ac..099722ebaed83901df9c23904baa13e2bd9734b3 100644 (file)
@@ -4228,8 +4228,10 @@ static int tuning_ctl_set(struct hda_codec *codec, hda_nid_t nid,
 
        for (i = 0; i < TUNING_CTLS_COUNT; i++)
                if (nid == ca0132_tuning_ctls[i].nid)
-                       break;
+                       goto found;
 
+       return -EINVAL;
+found:
        snd_hda_power_up(codec);
        dspio_set_param(codec, ca0132_tuning_ctls[i].mid, 0x20,
                        ca0132_tuning_ctls[i].req,
index 75e1d00074b9fa29465e65bf09f6fcd823ca082e..a889cccdd607cff8848892ba8505724c0a94687b 100644 (file)
@@ -980,7 +980,10 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
        SND_PCI_QUIRK(0x17aa, 0x3905, "Lenovo G50-30", CXT_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x17aa, 0x390b, "Lenovo G50-80", CXT_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
-       SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_PINCFG_LENOVO_NOTEBOOK),
+       /* NOTE: we'd need to extend the quirk for 17aa:3977 as the same
+        * PCI SSID is used on multiple Lenovo models
+        */
+       SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo G50-70", CXT_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", CXT_FIXUP_THINKPAD_ACPI),
@@ -1003,6 +1006,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = {
        { .id = CXT_FIXUP_MUTE_LED_GPIO, .name = "mute-led-gpio" },
        { .id = CXT_FIXUP_HP_ZBOOK_MUTE_LED, .name = "hp-zbook-mute-led" },
        { .id = CXT_FIXUP_HP_MIC_NO_PRESENCE, .name = "hp-mic-fix" },
+       { .id = CXT_PINCFG_LENOVO_NOTEBOOK, .name = "lenovo-20149" },
        {}
 };
 
index 9ea633fe93393531e5df51912c39a9b04528b458..5c6980394dcec2e2d92730e0cbb54eb7b73f2277 100644 (file)
@@ -81,6 +81,7 @@ struct hdmi_spec_per_pin {
        struct delayed_work work;
        struct hdmi_pcm *pcm; /* pointer to spec->pcm_rec[n] dynamically*/
        int pcm_idx; /* which pcm is attached. -1 means no pcm is attached */
+       int prev_pcm_idx; /* previously assigned pcm index */
        int repoll_count;
        bool setup; /* the stream has been set up by prepare callback */
        bool silent_stream;
@@ -1380,9 +1381,17 @@ static void hdmi_attach_hda_pcm(struct hdmi_spec *spec,
        /* pcm already be attached to the pin */
        if (per_pin->pcm)
                return;
+       /* try the previously used slot at first */
+       idx = per_pin->prev_pcm_idx;
+       if (idx >= 0) {
+               if (!test_bit(idx, &spec->pcm_bitmap))
+                       goto found;
+               per_pin->prev_pcm_idx = -1; /* no longer valid, clear it */
+       }
        idx = hdmi_find_pcm_slot(spec, per_pin);
        if (idx == -EBUSY)
                return;
+ found:
        per_pin->pcm_idx = idx;
        per_pin->pcm = get_hdmi_pcm(spec, idx);
        set_bit(idx, &spec->pcm_bitmap);
@@ -1398,6 +1407,7 @@ static void hdmi_detach_hda_pcm(struct hdmi_spec *spec,
                return;
        idx = per_pin->pcm_idx;
        per_pin->pcm_idx = -1;
+       per_pin->prev_pcm_idx = idx; /* remember the previous index */
        per_pin->pcm = NULL;
        if (idx >= 0 && idx < spec->pcm_used)
                clear_bit(idx, &spec->pcm_bitmap);
@@ -1924,6 +1934,7 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
 
                per_pin->pcm = NULL;
                per_pin->pcm_idx = -1;
+               per_pin->prev_pcm_idx = -1;
                per_pin->pin_nid = pin_nid;
                per_pin->pin_nid_idx = spec->num_nids;
                per_pin->dev_id = i;
@@ -4593,7 +4604,7 @@ HDA_CODEC_ENTRY(0x80862814, "DG1 HDMI",   patch_i915_tgl_hdmi),
 HDA_CODEC_ENTRY(0x80862815, "Alderlake HDMI",  patch_i915_tgl_hdmi),
 HDA_CODEC_ENTRY(0x80862816, "Rocketlake HDMI", patch_i915_tgl_hdmi),
 HDA_CODEC_ENTRY(0x80862818, "Raptorlake HDMI", patch_i915_tgl_hdmi),
-HDA_CODEC_ENTRY(0x80862819, "DG2 HDMI",        patch_i915_adlp_hdmi),
+HDA_CODEC_ENTRY(0x80862819, "DG2 HDMI",        patch_i915_tgl_hdmi),
 HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI", patch_i915_icl_hdmi),
 HDA_CODEC_ENTRY(0x8086281b, "Elkhartlake HDMI",        patch_i915_icl_hdmi),
 HDA_CODEC_ENTRY(0x8086281c, "Alderlake-P HDMI", patch_i915_adlp_hdmi),
index 3c629f4ae08076c966f45e952a4b4ede60368570..f70d6a33421d2efce7d7c86b0c7f78364c75c254 100644 (file)
@@ -2624,6 +2624,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
        SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
        SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
+       SND_PCI_QUIRK(0x1558, 0x3702, "Clevo X370SN[VW]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
        SND_PCI_QUIRK(0x1558, 0x50d3, "Clevo PC50[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
        SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
        SND_PCI_QUIRK(0x1558, 0x65d2, "Clevo PB51R[CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
@@ -2631,6 +2632,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1558, 0x65e5, "Clevo PC50D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
        SND_PCI_QUIRK(0x1558, 0x65f1, "Clevo PC50HS", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
        SND_PCI_QUIRK(0x1558, 0x65f5, "Clevo PD50PN[NRT]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
+       SND_PCI_QUIRK(0x1558, 0x66a2, "Clevo PE60RNE", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
        SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
        SND_PCI_QUIRK(0x1558, 0x67e1, "Clevo PB71[DE][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
        SND_PCI_QUIRK(0x1558, 0x67e5, "Clevo PC70D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
@@ -2651,6 +2653,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950),
        SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950),
        SND_PCI_QUIRK(0x1558, 0x97e2, "Clevo P970RC-M", ALC1220_FIXUP_CLEVO_P950),
+       SND_PCI_QUIRK(0x1558, 0xd502, "Clevo PD50SNE", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
        SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
        SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
        SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
@@ -6957,6 +6960,8 @@ enum {
        ALC269_FIXUP_DELL_M101Z,
        ALC269_FIXUP_SKU_IGNORE,
        ALC269_FIXUP_ASUS_G73JW,
+       ALC269_FIXUP_ASUS_N7601ZM_PINS,
+       ALC269_FIXUP_ASUS_N7601ZM,
        ALC269_FIXUP_LENOVO_EAPD,
        ALC275_FIXUP_SONY_HWEQ,
        ALC275_FIXUP_SONY_DISABLE_AAMIX,
@@ -7253,6 +7258,29 @@ static const struct hda_fixup alc269_fixups[] = {
                        { }
                }
        },
+       [ALC269_FIXUP_ASUS_N7601ZM_PINS] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       { 0x19, 0x03A11050 },
+                       { 0x1a, 0x03A11C30 },
+                       { 0x21, 0x03211420 },
+                       { }
+               }
+       },
+       [ALC269_FIXUP_ASUS_N7601ZM] = {
+               .type = HDA_FIXUP_VERBS,
+               .v.verbs = (const struct hda_verb[]) {
+                       {0x20, AC_VERB_SET_COEF_INDEX, 0x62},
+                       {0x20, AC_VERB_SET_PROC_COEF, 0xa007},
+                       {0x20, AC_VERB_SET_COEF_INDEX, 0x10},
+                       {0x20, AC_VERB_SET_PROC_COEF, 0x8420},
+                       {0x20, AC_VERB_SET_COEF_INDEX, 0x0f},
+                       {0x20, AC_VERB_SET_PROC_COEF, 0x7774},
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC269_FIXUP_ASUS_N7601ZM_PINS,
+       },
        [ALC269_FIXUP_LENOVO_EAPD] = {
                .type = HDA_FIXUP_VERBS,
                .v.verbs = (const struct hda_verb[]) {
@@ -9260,7 +9288,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x0a62, "Dell Precision 5560", ALC289_FIXUP_DUAL_SPK),
        SND_PCI_QUIRK(0x1028, 0x0a9d, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x0a9e, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
-       SND_PCI_QUIRK(0x1028, 0x0ac9, "Dell Precision 3260", ALC295_FIXUP_CHROME_BOOK),
        SND_PCI_QUIRK(0x1028, 0x0b19, "Dell XPS 15 9520", ALC289_FIXUP_DUAL_SPK),
        SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK),
        SND_PCI_QUIRK(0x1028, 0x0b37, "Dell Inspiron 16 Plus 7620 2-in-1", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
@@ -9441,12 +9468,15 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x8b47, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8b5d, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
        SND_PCI_QUIRK(0x103c, 0x8b5e, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+       SND_PCI_QUIRK(0x103c, 0x8b65, "HP ProBook 455 15.6 inch G10 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+       SND_PCI_QUIRK(0x103c, 0x8b66, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
        SND_PCI_QUIRK(0x103c, 0x8b7a, "HP", ALC236_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8b7d, "HP", ALC236_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8b87, "HP", ALC236_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8b8a, "HP", ALC236_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8b8b, "HP", ALC236_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8b8d, "HP", ALC236_FIXUP_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x8b8f, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8b92, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8bf0, "HP", ALC236_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
@@ -9461,6 +9491,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1271, "ASUS X430UN", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1043, 0x12a3, "Asus N7691ZM", ALC269_FIXUP_ASUS_N7601ZM),
        SND_PCI_QUIRK(0x1043, 0x12af, "ASUS UX582ZS", ALC245_FIXUP_CS35L41_SPI_2),
        SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
        SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
@@ -9539,6 +9570,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x144d, 0xc830, "Samsung Galaxy Book Ion (NT950XCJ-X716A)", ALC298_FIXUP_SAMSUNG_AMP),
        SND_PCI_QUIRK(0x144d, 0xc832, "Samsung Galaxy Book Flex Alpha (NP730QCJ)", ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
        SND_PCI_QUIRK(0x144d, 0xca03, "Samsung Galaxy Book2 Pro 360 (NP930QED)", ALC298_FIXUP_SAMSUNG_AMP),
+       SND_PCI_QUIRK(0x144d, 0xc868, "Samsung Galaxy Book2 Pro (NP930XED)", ALC298_FIXUP_SAMSUNG_AMP),
        SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
        SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
        SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
@@ -9573,6 +9605,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1558, 0x5101, "Clevo S510WU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x5157, "Clevo W517GU1", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x51a1, "Clevo NS50MU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1558, 0x5630, "Clevo NP50RNJS", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x70a1, "Clevo NB70T[HJK]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x70b3, "Clevo NK70SB", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x70f2, "Clevo NH79EPY", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
@@ -9607,6 +9640,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1558, 0x971d, "Clevo N970T[CDF]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0xa500, "Clevo NL5[03]RU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0xa600, "Clevo NL50NU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1558, 0xa671, "Clevo NP70SN[CDE]", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0xb018, "Clevo NP50D[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0xb019, "Clevo NH77D[BE]Q", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0xb022, "Clevo NH77D[DC][QW]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
@@ -9655,6 +9689,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x22f1, "Thinkpad", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x17aa, 0x22f2, "Thinkpad", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x17aa, 0x22f3, "Thinkpad", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x17aa, 0x2318, "Thinkpad Z13 Gen2", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x17aa, 0x2319, "Thinkpad Z16 Gen2", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x17aa, 0x231a, "Thinkpad Z16 Gen2", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
        SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
        SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
@@ -9707,6 +9744,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
+       SND_PCI_QUIRK(0x17aa, 0x9e56, "Lenovo ZhaoYang CF4620Z", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK),
        SND_PCI_QUIRK(0x1849, 0xa233, "Positivo Master C6300", ALC269_FIXUP_HEADSET_MIC),
        SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
index a794a01a68ca60e55bcd0ab653a0db3e6c3ffcc5..61258b0aac8d65a51206c2fd4f269e197003eec5 100644 (file)
@@ -1707,6 +1707,7 @@ static const struct snd_pci_quirk stac925x_fixup_tbl[] = {
 };
 
 static const struct hda_pintbl ref92hd73xx_pin_configs[] = {
+       // Port A-H
        { 0x0a, 0x02214030 },
        { 0x0b, 0x02a19040 },
        { 0x0c, 0x01a19020 },
@@ -1715,9 +1716,12 @@ static const struct hda_pintbl ref92hd73xx_pin_configs[] = {
        { 0x0f, 0x01014010 },
        { 0x10, 0x01014020 },
        { 0x11, 0x01014030 },
+       // CD in
        { 0x12, 0x02319040 },
+       // Digial Mic ins
        { 0x13, 0x90a000f0 },
        { 0x14, 0x90a000f0 },
+       // Digital outs
        { 0x22, 0x01452050 },
        { 0x23, 0x01452050 },
        {}
@@ -1758,6 +1762,7 @@ static const struct hda_pintbl alienware_m17x_pin_configs[] = {
 };
 
 static const struct hda_pintbl intel_dg45id_pin_configs[] = {
+       // Analog outputs
        { 0x0a, 0x02214230 },
        { 0x0b, 0x02A19240 },
        { 0x0c, 0x01013214 },
@@ -1765,6 +1770,9 @@ static const struct hda_pintbl intel_dg45id_pin_configs[] = {
        { 0x0e, 0x01A19250 },
        { 0x0f, 0x01011212 },
        { 0x10, 0x01016211 },
+       // Digital output
+       { 0x22, 0x01451380 },
+       { 0x23, 0x40f000f0 },
        {}
 };
 
@@ -1955,6 +1963,8 @@ static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = {
                                "DFI LanParty", STAC_92HD73XX_REF),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
                                "DFI LanParty", STAC_92HD73XX_REF),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5001,
+                               "Intel DP45SG", STAC_92HD73XX_INTEL),
        SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5002,
                                "Intel DG45ID", STAC_92HD73XX_INTEL),
        SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5003,
index 1e198e4d57b8d53ac29ec472fb0098aba5481ff3..82d4e0fda91be6a0bfac709c780405d47277afd8 100644 (file)
@@ -170,7 +170,7 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci,
                return -ENOENT;
        }
 
-       err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+       err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
                           sizeof(*chip), &card);
        if (err < 0)
                return err;
index c80114c0ad7bf051ecdd872f37885159d7c46301..b492c32ce07049aaff4c941be5fef2f76cd9bdb8 100644 (file)
@@ -2165,7 +2165,7 @@ static int snd_ymfpci_memalloc(struct snd_ymfpci *chip)
        chip->work_base = ptr;
        chip->work_base_addr = ptr_addr;
        
-       snd_BUG_ON(ptr + chip->work_size !=
+       snd_BUG_ON(ptr + PAGE_ALIGN(chip->work_size) !=
                   chip->work_ptr->area + chip->work_ptr->bytes);
 
        snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, chip->bank_base_playback_addr);
index 4a69ce702360c547e3fc904b1a15d6823227d0c2..0acdf0156f075d02a701868ce67690990302e452 100644 (file)
@@ -269,6 +269,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "8A43"),
                }
        },
+       {
+               .driver_data = &acp6x_card,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+                       DMI_MATCH(DMI_BOARD_NAME, "8A22"),
+               }
+       },
        {}
 };
 
index 0068780fe0a745f423832971427b10c0617d4133..1c1f211a8e2e7aa28ab29f20f035bd100ea4b475 100644 (file)
@@ -2022,6 +2022,11 @@ static int da7213_i2c_probe(struct i2c_client *i2c)
        return ret;
 }
 
+static void da7213_i2c_remove(struct i2c_client *i2c)
+{
+       pm_runtime_disable(&i2c->dev);
+}
+
 static int __maybe_unused da7213_runtime_suspend(struct device *dev)
 {
        struct da7213_priv *da7213 = dev_get_drvdata(dev);
@@ -2065,6 +2070,7 @@ static struct i2c_driver da7213_i2c_driver = {
                .pm = &da7213_pm,
        },
        .probe_new      = da7213_i2c_probe,
+       .remove         = da7213_i2c_remove,
        .id_table       = da7213_i2c_id,
 };
 
index 4a4f09f924bc510ff54fff1cf02a008bca82d982..e3d398b8f54e4f0cd343e2bc56d5cf9295073eae 100644 (file)
@@ -968,6 +968,8 @@ int da7219_aad_init(struct snd_soc_component *component)
        INIT_WORK(&da7219_aad->hptest_work, da7219_aad_hptest_work);
        INIT_WORK(&da7219_aad->jack_det_work, da7219_aad_jack_det_work);
 
+       mutex_init(&da7219_aad->jack_det_mutex);
+
        ret = request_threaded_irq(da7219_aad->irq, da7219_aad_pre_irq_thread,
                                   da7219_aad_irq_thread,
                                   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
index ed4f7cdda04ffe37f8e03c5fa091dd5a6e0e78aa..8b6b7602969488cd1511d6b05b68416c28833f7e 100644 (file)
@@ -436,23 +436,28 @@ static int hdac_hdmi_setup_audio_infoframe(struct hdac_device *hdev,
        return 0;
 }
 
-static int hdac_hdmi_set_tdm_slot(struct snd_soc_dai *dai,
-               unsigned int tx_mask, unsigned int rx_mask,
-               int slots, int slot_width)
+static int hdac_hdmi_set_stream(struct snd_soc_dai *dai,
+                               void *stream, int direction)
 {
        struct hdac_hdmi_priv *hdmi = snd_soc_dai_get_drvdata(dai);
        struct hdac_device *hdev = hdmi->hdev;
        struct hdac_hdmi_dai_port_map *dai_map;
        struct hdac_hdmi_pcm *pcm;
+       struct hdac_stream *hstream;
 
-       dev_dbg(&hdev->dev, "%s: strm_tag: %d\n", __func__, tx_mask);
+       if (!stream)
+               return -EINVAL;
+
+       hstream = (struct hdac_stream *)stream;
+
+       dev_dbg(&hdev->dev, "%s: strm_tag: %d\n", __func__, hstream->stream_tag);
 
        dai_map = &hdmi->dai_map[dai->id];
 
        pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, dai_map->cvt);
 
        if (pcm)
-               pcm->stream_tag = (tx_mask << 4);
+               pcm->stream_tag = (hstream->stream_tag << 4);
 
        return 0;
 }
@@ -1544,7 +1549,7 @@ static const struct snd_soc_dai_ops hdmi_dai_ops = {
        .startup = hdac_hdmi_pcm_open,
        .shutdown = hdac_hdmi_pcm_close,
        .hw_params = hdac_hdmi_set_hw_params,
-       .set_tdm_slot = hdac_hdmi_set_tdm_slot,
+       .set_stream = hdac_hdmi_set_stream,
 };
 
 /*
index 01e8ffda2a4bf37655fc38b1b07fee22b14be197..6d980fbc4207780ccc966df8378f70cf554f4cd4 100644 (file)
@@ -428,8 +428,13 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream,
 {
        struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
        bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+       bool has_capture = !hcp->hcd.no_i2s_capture;
+       bool has_playback = !hcp->hcd.no_i2s_playback;
        int ret = 0;
 
+       if (!((has_playback && tx) || (has_capture && !tx)))
+               return 0;
+
        mutex_lock(&hcp->lock);
        if (hcp->busy) {
                dev_err(dai->dev, "Only one simultaneous stream supported!\n");
@@ -468,6 +473,12 @@ static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
                                struct snd_soc_dai *dai)
 {
        struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
+       bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+       bool has_capture = !hcp->hcd.no_i2s_capture;
+       bool has_playback = !hcp->hcd.no_i2s_playback;
+
+       if (!((has_playback && tx) || (has_capture && !tx)))
+               return;
 
        hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
        hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data);
index a73a7d7a1c0a853915c8d70466f5f160fd33928f..faba4237bd3da84050326b98de2f9682e79c5571 100644 (file)
@@ -3670,9 +3670,9 @@ static int __maybe_unused rx_macro_runtime_suspend(struct device *dev)
        regcache_cache_only(rx->regmap, true);
        regcache_mark_dirty(rx->regmap);
 
-       clk_disable_unprepare(rx->mclk);
-       clk_disable_unprepare(rx->npl);
        clk_disable_unprepare(rx->fsgen);
+       clk_disable_unprepare(rx->npl);
+       clk_disable_unprepare(rx->mclk);
 
        return 0;
 }
index bf27bdd5be2067a867c0ea48bda09a1372ab6a94..589c490a8c48798fd0d9365bcc54eb135eb63728 100644 (file)
@@ -242,7 +242,7 @@ enum {
 
 struct tx_mute_work {
        struct tx_macro *tx;
-       u32 decimator;
+       u8 decimator;
        struct delayed_work dwork;
 };
 
@@ -635,7 +635,7 @@ exit:
        return 0;
 }
 
-static bool is_amic_enabled(struct snd_soc_component *component, int decimator)
+static bool is_amic_enabled(struct snd_soc_component *component, u8 decimator)
 {
        u16 adc_mux_reg, adc_reg, adc_n;
 
@@ -849,7 +849,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
                               struct snd_kcontrol *kcontrol, int event)
 {
        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
-       unsigned int decimator;
+       u8 decimator;
        u16 tx_vol_ctl_reg, dec_cfg_reg, hpf_gate_reg, tx_gain_ctl_reg;
        u8 hpf_cut_off_freq;
        int hpf_delay = TX_MACRO_DMIC_HPF_DELAY_MS;
@@ -1064,7 +1064,8 @@ static int tx_macro_hw_params(struct snd_pcm_substream *substream,
                              struct snd_soc_dai *dai)
 {
        struct snd_soc_component *component = dai->component;
-       u32 decimator, sample_rate;
+       u32 sample_rate;
+       u8 decimator;
        int tx_fs_rate;
        struct tx_macro *tx = snd_soc_component_get_drvdata(component);
 
@@ -1128,7 +1129,7 @@ static int tx_macro_digital_mute(struct snd_soc_dai *dai, int mute, int stream)
 {
        struct snd_soc_component *component = dai->component;
        struct tx_macro *tx = snd_soc_component_get_drvdata(component);
-       u16 decimator;
+       u8 decimator;
 
        /* active decimator not set yet */
        if (tx->active_decimator[dai->id] == -1)
@@ -2097,9 +2098,9 @@ static int __maybe_unused tx_macro_runtime_suspend(struct device *dev)
        regcache_cache_only(tx->regmap, true);
        regcache_mark_dirty(tx->regmap);
 
-       clk_disable_unprepare(tx->mclk);
-       clk_disable_unprepare(tx->npl);
        clk_disable_unprepare(tx->fsgen);
+       clk_disable_unprepare(tx->npl);
+       clk_disable_unprepare(tx->mclk);
 
        return 0;
 }
index ba7480f3831e2cc7e86734802a1ef4f61f7c0b36..3f6f1bdd4e030af22bc363c38933c3f60affc23e 100644 (file)
@@ -2506,9 +2506,9 @@ static int __maybe_unused wsa_macro_runtime_suspend(struct device *dev)
        regcache_cache_only(wsa->regmap, true);
        regcache_mark_dirty(wsa->regmap);
 
-       clk_disable_unprepare(wsa->mclk);
-       clk_disable_unprepare(wsa->npl);
        clk_disable_unprepare(wsa->fsgen);
+       clk_disable_unprepare(wsa->npl);
+       clk_disable_unprepare(wsa->mclk);
 
        return 0;
 }
index f90a6a7ba83b8cb122a8192c197f6e4d57788dc6..fde055c6c89466b361b441814c70ec9a89ee8653 100644 (file)
@@ -31,7 +31,7 @@ static int max98373_dac_event(struct snd_soc_dapm_widget *w,
                        MAX98373_GLOBAL_EN_MASK, 1);
                usleep_range(30000, 31000);
                break;
-       case SND_SOC_DAPM_POST_PMD:
+       case SND_SOC_DAPM_PRE_PMD:
                regmap_update_bits(max98373->regmap,
                        MAX98373_R20FF_GLOBAL_SHDN,
                        MAX98373_GLOBAL_EN_MASK, 0);
@@ -64,7 +64,7 @@ static const struct snd_kcontrol_new max98373_spkfb_control =
 static const struct snd_soc_dapm_widget max98373_dapm_widgets[] = {
 SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback",
        MAX98373_R202B_PCM_RX_EN, 0, 0, max98373_dac_event,
-       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0,
        &max98373_dai_controls),
 SND_SOC_DAPM_OUTPUT("BE_OUT"),
index 614eceda6b9e3181b184beb16eb3c0c5612f787f..33b67db8794e367b5a0d4e7e5d603b8a1f48bb2a 100644 (file)
@@ -294,6 +294,10 @@ config SND_SOC_IMX_SGTL5000
          Say Y if you want to add support for SoC audio on an i.MX board with
          a sgtl5000 codec.
 
+         Note that this is an old driver. Consider enabling
+         SND_SOC_FSL_ASOC_CARD and SND_SOC_SGTL5000 to use the newer
+         driver.
+
 config SND_SOC_IMX_SPDIF
        tristate "SoC Audio support for i.MX boards with S/PDIF"
        select SND_SOC_IMX_PCM_DMA
index 3b81a465814a1f777ed0820a853fbd93eceaf018..05a7d1588d204b60a3f41abd9982a20a5527f996 100644 (file)
@@ -209,14 +209,19 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component,
                be_chan = soc_component_to_pcm(component_be)->chan[substream->stream];
                tmp_chan = be_chan;
        }
-       if (!tmp_chan)
-               tmp_chan = dma_request_slave_channel(dev_be, tx ? "tx" : "rx");
+       if (!tmp_chan) {
+               tmp_chan = dma_request_chan(dev_be, tx ? "tx" : "rx");
+               if (IS_ERR(tmp_chan)) {
+                       dev_err(dev, "failed to request DMA channel for Back-End\n");
+                       return -EINVAL;
+               }
+       }
 
        /*
         * An EDMA DEV_TO_DEV channel is fixed and bound with DMA event of each
         * peripheral, unlike SDMA channel that is allocated dynamically. So no
         * need to configure dma_request and dma_request2, but get dma_chan of
-        * Back-End device directly via dma_request_slave_channel.
+        * Back-End device directly via dma_request_chan.
         */
        if (!asrc->use_edma) {
                /* Get DMA request of Back-End */
index 1b197478b3d90eda6d348852339c6eabdacdb1b5..990bba0be1fb1cb2b8edae47ce9347f27250a6e9 100644 (file)
@@ -1546,7 +1546,7 @@ static const struct fsl_sai_soc_data fsl_sai_imx8qm_data = {
        .use_imx_pcm = true,
        .use_edma = true,
        .fifo_depth = 64,
-       .pins = 1,
+       .pins = 4,
        .reg_offset = 0,
        .mclk0_is_mclk1 = false,
        .flags = 0,
index acd43b6108e9979a7b881a4c8a19c87bb43a76fc..1a1d572cc1d028626bf7a68e950883b0ddb67062 100644 (file)
@@ -117,6 +117,26 @@ static void avs_da7219_codec_exit(struct snd_soc_pcm_runtime *rtd)
        snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component, NULL, NULL);
 }
 
+static int
+avs_da7219_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_params *params)
+{
+       struct snd_interval *rate, *channels;
+       struct snd_mask *fmt;
+
+       rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+       channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+       fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+
+       /* The ADSP will convert the FE rate to 48k, stereo */
+       rate->min = rate->max = 48000;
+       channels->min = channels->max = 2;
+
+       /* set SSP0 to 24 bit */
+       snd_mask_none(fmt);
+       snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
+       return 0;
+}
+
 static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port,
                               struct snd_soc_dai_link **dai_link)
 {
@@ -148,6 +168,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
        dl->num_platforms = 1;
        dl->id = 0;
        dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
+       dl->be_hw_params_fixup = avs_da7219_be_fixup;
        dl->init = avs_da7219_codec_init;
        dl->exit = avs_da7219_codec_exit;
        dl->nonatomic = 1;
index 921f42caf7e09d0547a69e8aa460ec5cf3181d9f..183123d08c5a3b4e39f693d7ab13f14c49b96434 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/soc-acpi.h>
 #include <sound/soc-dapm.h>
@@ -24,6 +25,26 @@ static const struct snd_soc_dapm_route card_base_routes[] = {
        { "Spk", NULL, "Speaker" },
 };
 
+static int
+avs_max98357a_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_params *params)
+{
+       struct snd_interval *rate, *channels;
+       struct snd_mask *fmt;
+
+       rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+       channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+       fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+
+       /* The ADSP will convert the FE rate to 48k, stereo */
+       rate->min = rate->max = 48000;
+       channels->min = channels->max = 2;
+
+       /* set SSP0 to 16 bit */
+       snd_mask_none(fmt);
+       snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
+       return 0;
+}
+
 static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port,
                               struct snd_soc_dai_link **dai_link)
 {
@@ -55,6 +76,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
        dl->num_platforms = 1;
        dl->id = 0;
        dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
+       dl->be_hw_params_fixup = avs_max98357a_be_fixup;
        dl->nonatomic = 1;
        dl->no_pcm = 1;
        dl->dpcm_playback = 1;
index b31fa931ba8b6a848406e391ee3d28ddcf4f960e..b69fc5567135d5330c7a4cc75c0bf2e037ea043d 100644 (file)
@@ -33,15 +33,15 @@ avs_nau8825_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *co
                return -EINVAL;
        }
 
-       if (!SND_SOC_DAPM_EVENT_ON(event)) {
+       if (SND_SOC_DAPM_EVENT_ON(event))
+               ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_MCLK, 24000000,
+                                            SND_SOC_CLOCK_IN);
+       else
                ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_INTERNAL, 0, SND_SOC_CLOCK_IN);
-               if (ret < 0) {
-                       dev_err(card->dev, "set sysclk err = %d\n", ret);
-                       return ret;
-               }
-       }
+       if (ret < 0)
+               dev_err(card->dev, "Set sysclk failed: %d\n", ret);
 
-       return 0;
+       return ret;
 }
 
 static const struct snd_kcontrol_new card_controls[] = {
index 473e9fe5d0bf746ae4c3446d4a9ab23f007bf838..b2c2ba93dcb5606b1d5febad49a1420614b44334 100644 (file)
@@ -169,6 +169,27 @@ static const struct snd_soc_ops avs_rt5682_ops = {
        .hw_params = avs_rt5682_hw_params,
 };
 
+static int
+avs_rt5682_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pcm_hw_params *params)
+{
+       struct snd_interval *rate, *channels;
+       struct snd_mask *fmt;
+
+       rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+       channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+       fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+
+       /* The ADSP will convert the FE rate to 48k, stereo */
+       rate->min = rate->max = 48000;
+       channels->min = channels->max = 2;
+
+       /* set SSPN to 24 bit */
+       snd_mask_none(fmt);
+       snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
+
+       return 0;
+}
+
 static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port,
                               struct snd_soc_dai_link **dai_link)
 {
@@ -201,6 +222,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
        dl->id = 0;
        dl->init = avs_rt5682_codec_init;
        dl->exit = avs_rt5682_codec_exit;
+       dl->be_hw_params_fixup = avs_rt5682_be_fixup;
        dl->ops = &avs_rt5682_ops;
        dl->nonatomic = 1;
        dl->no_pcm = 1;
index c5db6961276240c0d90d6a08c7189aa8bd153a18..2b7f5ad92aca7b885ba0686f829fe9262067f6da 100644 (file)
@@ -15,7 +15,6 @@
 #include <sound/soc-acpi.h>
 #include "../../../codecs/nau8825.h"
 
-#define SKL_NUVOTON_CODEC_DAI  "nau8825-hifi"
 #define SKL_SSM_CODEC_DAI      "ssm4567-hifi"
 
 static struct snd_soc_codec_conf card_codec_conf[] = {
@@ -34,41 +33,11 @@ static const struct snd_kcontrol_new card_controls[] = {
        SOC_DAPM_PIN_SWITCH("Right Speaker"),
 };
 
-static int
-platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *control, int event)
-{
-       struct snd_soc_dapm_context *dapm = w->dapm;
-       struct snd_soc_card *card = dapm->card;
-       struct snd_soc_dai *codec_dai;
-       int ret;
-
-       codec_dai = snd_soc_card_get_codec_dai(card, SKL_NUVOTON_CODEC_DAI);
-       if (!codec_dai) {
-               dev_err(card->dev, "Codec dai not found\n");
-               return -EINVAL;
-       }
-
-       if (SND_SOC_DAPM_EVENT_ON(event)) {
-               ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_MCLK, 24000000,
-                                            SND_SOC_CLOCK_IN);
-               if (ret < 0)
-                       dev_err(card->dev, "set sysclk err = %d\n", ret);
-       } else {
-               ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_INTERNAL, 0, SND_SOC_CLOCK_IN);
-               if (ret < 0)
-                       dev_err(card->dev, "set sysclk err = %d\n", ret);
-       }
-
-       return ret;
-}
-
 static const struct snd_soc_dapm_widget card_widgets[] = {
        SND_SOC_DAPM_SPK("Left Speaker", NULL),
        SND_SOC_DAPM_SPK("Right Speaker", NULL),
        SND_SOC_DAPM_SPK("DP1", NULL),
        SND_SOC_DAPM_SPK("DP2", NULL),
-       SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, platform_clock_control,
-                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 };
 
 static const struct snd_soc_dapm_route card_base_routes[] = {
index 79e0039c79a388f911d90f71f5025aa8a6bf452b..5a12940ef9070819f693e00cb0c338088f439aad 100644 (file)
@@ -533,6 +533,18 @@ static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
 
 /* Please keep this list alphabetically sorted */
 static const struct dmi_system_id byt_rt5640_quirk_table[] = {
+       {       /* Acer Iconia One 7 B1-750 */
+               .matches = {
+                       DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "VESPA2"),
+               },
+               .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
+                                       BYT_RT5640_JD_SRC_JD1_IN4P |
+                                       BYT_RT5640_OVCD_TH_1500UA |
+                                       BYT_RT5640_OVCD_SF_0P75 |
+                                       BYT_RT5640_SSP0_AIF1 |
+                                       BYT_RT5640_MCLK_EN),
+       },
        {       /* Acer Iconia Tab 8 W1-810 */
                .matches = {
                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
index d2ed807abde9590b1968aaf9d1b2c90803ae5b3c..767fa89d08708519d32027540b7d289771532527 100644 (file)
@@ -213,6 +213,17 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
                                        SOF_SDW_PCH_DMIC |
                                        RT711_JD1),
        },
+       {
+               /* NUC15 'Rooks County' LAPRC510 and LAPRC710 skews */
+               .callback = sof_sdw_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LAPRC"),
+               },
+               .driver_data = (void *)(SOF_SDW_TGL_HDMI |
+                                       SOF_SDW_PCH_DMIC |
+                                       RT711_JD2_100K),
+       },
        /* TigerLake-SDCA devices */
        {
                .callback = sof_sdw_quirk_cb,
index 56ee5fef66a8be93b1eafdb210b698d9aa0c1ec8..d8c80041388a7346e76499ea687a661f68a3f70c 100644 (file)
@@ -354,6 +354,20 @@ static const struct snd_soc_acpi_link_adr adl_sdw_rt711_link0_rt1316_link3[] = {
        {}
 };
 
+static const struct snd_soc_acpi_link_adr adl_sdw_rt711_link0_rt1316_link2[] = {
+       {
+               .mask = BIT(0),
+               .num_adr = ARRAY_SIZE(rt711_sdca_0_adr),
+               .adr_d = rt711_sdca_0_adr,
+       },
+       {
+               .mask = BIT(2),
+               .num_adr = ARRAY_SIZE(rt1316_2_single_adr),
+               .adr_d = rt1316_2_single_adr,
+       },
+       {}
+};
+
 static const struct snd_soc_acpi_adr_device mx8373_2_adr[] = {
        {
                .adr = 0x000223019F837300ull,
@@ -559,7 +573,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = {
        {
                .comp_ids = &essx_83x6,
                .drv_name = "sof-essx8336",
-               .sof_tplg_filename = "sof-adl-es83x6", /* the tplg suffix is added at run time */
+               .sof_tplg_filename = "sof-adl-es8336", /* the tplg suffix is added at run time */
                .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER |
                                        SND_SOC_ACPI_TPLG_INTEL_SSP_MSB |
                                        SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
@@ -624,6 +638,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = {
                .drv_name = "sof_sdw",
                .sof_tplg_filename = "sof-adl-rt711-l0-rt1316-l3.tplg",
        },
+       {
+               .link_mask = 0x5, /* 2 active links required */
+               .links = adl_sdw_rt711_link0_rt1316_link2,
+               .drv_name = "sof_sdw",
+               .sof_tplg_filename = "sof-adl-rt711-l0-rt1316-l2.tplg",
+       },
        {
                .link_mask = 0x1, /* link0 required */
                .links = adl_rvp,
index 3aa63aac4a68e28540b06e5af4ca4ed151407a2a..81554d20265897e319fc3cf34d9191960c2bbe51 100644 (file)
@@ -184,9 +184,9 @@ int q6prm_set_lpass_clock(struct device *dev, int clk_id, int clk_attr, int clk_
                          unsigned int freq)
 {
        if (freq)
-               return q6prm_request_lpass_clock(dev, clk_id, clk_attr, clk_attr, freq);
+               return q6prm_request_lpass_clock(dev, clk_id, clk_attr, clk_root, freq);
 
-       return q6prm_release_lpass_clock(dev, clk_id, clk_attr, clk_attr, freq);
+       return q6prm_release_lpass_clock(dev, clk_id, clk_attr, clk_root, freq);
 }
 EXPORT_SYMBOL_GPL(q6prm_set_lpass_clock);
 
index 5eb056b942ce8d6c1d95a9ee49c27be5d8bae8d0..7958c9defd4922fe8a337008f09ae00e0ff9b8ae 100644 (file)
@@ -1661,10 +1661,14 @@ static void dpcm_runtime_setup_fe(struct snd_pcm_substream *substream)
        struct snd_pcm_hardware *hw = &runtime->hw;
        struct snd_soc_dai *dai;
        int stream = substream->stream;
+       u64 formats = hw->formats;
        int i;
 
        soc_pcm_hw_init(hw);
 
+       if (formats)
+               hw->formats &= formats;
+
        for_each_rtd_cpu_dais(fe, i, dai) {
                struct snd_soc_pcm_stream *cpu_stream;
 
index 3aea36c077c9d2262e36b2eb1d9a7c23181c1712..f3bdeba2841221f8b205109db46d53ab04a112f1 100644 (file)
@@ -196,12 +196,15 @@ int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev)
                goto err;
        }
 
+       usleep_range(500, 1000);
+
        /* exit HDA controller reset */
        ret = hda_dsp_ctrl_link_reset(sdev, false);
        if (ret < 0) {
                dev_err(sdev->dev, "error: failed to exit HDA controller reset\n");
                goto err;
        }
+       usleep_range(1000, 1200);
 
        hda_codec_detect_mask(sdev);
 
index 68eb06f13a1fd2539bab66cf9c255d860e059caf..a6f2822401e03da1d3553f50fa4370955219f6e2 100644 (file)
@@ -392,6 +392,12 @@ static int hda_dsp_update_d0i3c_register(struct snd_sof_dev *sdev, u8 value)
        snd_sof_dsp_update8(sdev, HDA_DSP_HDA_BAR, chip->d0i3_offset,
                            SOF_HDA_VS_D0I3C_I3, value);
 
+       /*
+        * The value written to the D0I3C::I3 bit may not be taken into account immediately.
+        * A delay is recommended before checking if D0I3C::CIP is cleared
+        */
+       usleep_range(30, 40);
+
        /* Wait for cmd in progress to be cleared before exiting the function */
        ret = hda_dsp_wait_d0i3c_done(sdev);
        if (ret < 0) {
@@ -400,6 +406,12 @@ static int hda_dsp_update_d0i3c_register(struct snd_sof_dev *sdev, u8 value)
        }
 
        reg = snd_sof_dsp_read8(sdev, HDA_DSP_HDA_BAR, chip->d0i3_offset);
+       /* Confirm d0i3 state changed with paranoia check */
+       if ((reg ^ value) & SOF_HDA_VS_D0I3C_I3) {
+               dev_err(sdev->dev, "failed to update D0I3C!\n");
+               return -EIO;
+       }
+
        trace_sof_intel_D0I3C_updated(sdev, reg);
 
        return 0;
index 69279dcc92dc136630fed5a7ab3860a9f5540091..aff6cb573c270f9a4cf387c400a6c85c94757031 100644 (file)
@@ -78,6 +78,7 @@ static const struct sof_dev_desc glk_desc = {
        .nocodec_tplg_filename = "sof-glk-nocodec.tplg",
        .ops = &sof_apl_ops,
        .ops_init = sof_apl_ops_init,
+       .ops_free = hda_ops_free,
 };
 
 /* PCI IDs */
index 8db3f8d15b55e9f6f708b91a9f11b5fe136ca774..4c0c1c369dcd8a8ffb1fec3d9de2360730e9f0f2 100644 (file)
@@ -48,6 +48,7 @@ static const struct sof_dev_desc cnl_desc = {
        .nocodec_tplg_filename = "sof-cnl-nocodec.tplg",
        .ops = &sof_cnl_ops,
        .ops_init = sof_cnl_ops_init,
+       .ops_free = hda_ops_free,
 };
 
 static const struct sof_dev_desc cfl_desc = {
@@ -111,6 +112,7 @@ static const struct sof_dev_desc cml_desc = {
        .nocodec_tplg_filename = "sof-cnl-nocodec.tplg",
        .ops = &sof_cnl_ops,
        .ops_init = sof_cnl_ops_init,
+       .ops_free = hda_ops_free,
 };
 
 /* PCI IDs */
index d6cf75e357dbf07c9b1e89894cb8fa530d3e26a6..6785669113b3c2ee74f4d0315b4f3053a61ad6e8 100644 (file)
@@ -79,6 +79,7 @@ static const struct sof_dev_desc jsl_desc = {
        .nocodec_tplg_filename = "sof-jsl-nocodec.tplg",
        .ops = &sof_cnl_ops,
        .ops_init = sof_cnl_ops_init,
+       .ops_free = hda_ops_free,
 };
 
 /* PCI IDs */
index 6e4e6d4ef5a5649e781bbb78e053bb5b3f9edbb1..b183dc0014b4b5a102b57c63e0a787bc76b55d01 100644 (file)
@@ -46,6 +46,7 @@ static const struct sof_dev_desc mtl_desc = {
        .nocodec_tplg_filename = "sof-mtl-nocodec.tplg",
        .ops = &sof_mtl_ops,
        .ops_init = sof_mtl_ops_init,
+       .ops_free = hda_ops_free,
 };
 
 /* PCI IDs */
index 3a99dc444f92ea6b46014a4faaf9463fe4421c29..5b4bccf819658eeb356f2f58425c6ebb894f8436 100644 (file)
@@ -38,6 +38,7 @@ static struct sof_dev_desc skl_desc = {
        .nocodec_tplg_filename = "sof-skl-nocodec.tplg",
        .ops = &sof_skl_ops,
        .ops_init = sof_skl_ops_init,
+       .ops_free = hda_ops_free,
 };
 
 static struct sof_dev_desc kbl_desc = {
@@ -61,6 +62,7 @@ static struct sof_dev_desc kbl_desc = {
        .nocodec_tplg_filename = "sof-kbl-nocodec.tplg",
        .ops = &sof_skl_ops,
        .ops_init = sof_skl_ops_init,
+       .ops_free = hda_ops_free,
 };
 
 /* PCI IDs */
index e80c4dfef85a58d71d0db6246199fe55c8b64336..22e769e0831d9349331e646ed5fbbfab1debf68a 100644 (file)
@@ -48,6 +48,7 @@ static const struct sof_dev_desc tgl_desc = {
        .nocodec_tplg_filename = "sof-tgl-nocodec.tplg",
        .ops = &sof_tgl_ops,
        .ops_init = sof_tgl_ops_init,
+       .ops_free = hda_ops_free,
 };
 
 static const struct sof_dev_desc tglh_desc = {
@@ -110,6 +111,7 @@ static const struct sof_dev_desc ehl_desc = {
        .nocodec_tplg_filename = "sof-ehl-nocodec.tplg",
        .ops = &sof_tgl_ops,
        .ops_init = sof_tgl_ops_init,
+       .ops_free = hda_ops_free,
 };
 
 static const struct sof_dev_desc adls_desc = {
@@ -141,6 +143,7 @@ static const struct sof_dev_desc adls_desc = {
        .nocodec_tplg_filename = "sof-adl-nocodec.tplg",
        .ops = &sof_tgl_ops,
        .ops_init = sof_tgl_ops_init,
+       .ops_free = hda_ops_free,
 };
 
 static const struct sof_dev_desc adl_desc = {
@@ -172,6 +175,7 @@ static const struct sof_dev_desc adl_desc = {
        .nocodec_tplg_filename = "sof-adl-nocodec.tplg",
        .ops = &sof_tgl_ops,
        .ops_init = sof_tgl_ops_init,
+       .ops_free = hda_ops_free,
 };
 
 static const struct sof_dev_desc adl_n_desc = {
@@ -203,6 +207,7 @@ static const struct sof_dev_desc adl_n_desc = {
        .nocodec_tplg_filename = "sof-adl-nocodec.tplg",
        .ops = &sof_tgl_ops,
        .ops_init = sof_tgl_ops_init,
+       .ops_free = hda_ops_free,
 };
 
 static const struct sof_dev_desc rpls_desc = {
@@ -234,6 +239,7 @@ static const struct sof_dev_desc rpls_desc = {
        .nocodec_tplg_filename = "sof-rpl-nocodec.tplg",
        .ops = &sof_tgl_ops,
        .ops_init = sof_tgl_ops_init,
+       .ops_free = hda_ops_free,
 };
 
 static const struct sof_dev_desc rpl_desc = {
@@ -265,6 +271,7 @@ static const struct sof_dev_desc rpl_desc = {
        .nocodec_tplg_filename = "sof-rpl-nocodec.tplg",
        .ops = &sof_tgl_ops,
        .ops_init = sof_tgl_ops_init,
+       .ops_free = hda_ops_free,
 };
 
 /* PCI IDs */
index 5b2b409752c585d103c6485e1db5efbdd0243b7d..8c22a00266c06a6ffd94be4e2e921450d721ce14 100644 (file)
@@ -75,11 +75,7 @@ static int tangier_pci_probe(struct snd_sof_dev *sdev)
 
        /* LPE base */
        base = pci_resource_start(pci, desc->resindex_lpe_base) - IRAM_OFFSET;
-       size = pci_resource_len(pci, desc->resindex_lpe_base);
-       if (size < PCI_BAR_SIZE) {
-               dev_err(sdev->dev, "error: I/O region is too small.\n");
-               return -ENODEV;
-       }
+       size = PCI_BAR_SIZE;
 
        dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size);
        sdev->bar[DSP_BAR] = devm_ioremap(sdev->dev, base, size);
index dceb78bfe17c68fc47efbc5c9611828d8efbc439..b1f425b39db94fd54b95bd6e9f3a6bc25538cf58 100644 (file)
@@ -2081,7 +2081,9 @@ static int sof_ipc3_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget *
                break;
        case SOF_DAI_INTEL_ALH:
                if (data) {
-                       config->dai_index = data->dai_index;
+                       /* save the dai_index during hw_params and reuse it for hw_free */
+                       if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS)
+                               config->dai_index = data->dai_index;
                        config->alh.stream_id = data->dai_data;
                }
                break;
@@ -2089,7 +2091,30 @@ static int sof_ipc3_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget *
                break;
        }
 
-       config->flags = flags;
+       /*
+        * The dai_config op is invoked several times and the flags argument varies as below:
+        * BE DAI hw_params: When the op is invoked during the BE DAI hw_params, flags contains
+        * SOF_DAI_CONFIG_FLAGS_HW_PARAMS along with quirks
+        * FE DAI hw_params: When invoked during FE DAI hw_params after the DAI widget has
+        * just been set up in the DSP, flags is set to SOF_DAI_CONFIG_FLAGS_HW_PARAMS with no
+        * quirks
+        * BE DAI trigger: When invoked during the BE DAI trigger, flags is set to
+        * SOF_DAI_CONFIG_FLAGS_PAUSE and contains no quirks
+        * BE DAI hw_free: When invoked during the BE DAI hw_free, flags is set to
+        * SOF_DAI_CONFIG_FLAGS_HW_FREE and contains no quirks
+        * FE DAI hw_free: When invoked during the FE DAI hw_free, flags is set to
+        * SOF_DAI_CONFIG_FLAGS_HW_FREE and contains no quirks
+        *
+        * The DAI_CONFIG IPC is sent to the DSP, only after the widget is set up during the FE
+        * DAI hw_params. But since the BE DAI hw_params precedes the FE DAI hw_params, the quirks
+        * need to be preserved when assigning the flags before sending the IPC.
+        * For the case of PAUSE/HW_FREE, since there are no quirks, flags can be used as is.
+        */
+
+       if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS)
+               config->flags |= flags;
+       else
+               config->flags = flags;
 
        /* only send the IPC if the widget is set up in the DSP */
        if (swidget->use_count > 0) {
@@ -2097,6 +2122,9 @@ static int sof_ipc3_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget *
                                         &reply, sizeof(reply));
                if (ret < 0)
                        dev_err(sdev->dev, "Failed to set dai config for %s\n", dai->name);
+
+               /* clear the flags once the IPC has been sent even if it fails */
+               config->flags = SOF_DAI_CONFIG_FLAGS_NONE;
        }
 
        return ret;
index 3de64ea2dc9aa533c042097e20488630976e0c12..4493bbd7faf12bbda0a2e9ed8d4f6c869f83b0c8 100644 (file)
@@ -970,8 +970,9 @@ static void sof_ipc3_rx_msg(struct snd_sof_dev *sdev)
                return;
        }
 
-       if (hdr.size < sizeof(hdr)) {
-               dev_err(sdev->dev, "The received message size is invalid\n");
+       if (hdr.size < sizeof(hdr) || hdr.size > SOF_IPC_MSG_MAX_SIZE) {
+               dev_err(sdev->dev, "The received message size is invalid: %u\n",
+                       hdr.size);
                return;
        }
 
index 67bd2233fd9a675746ca91396ccddf25fb547f1c..9a71af1a613ac3800c9a5016de2a638cfac5d2d5 100644 (file)
@@ -97,7 +97,8 @@ sof_ipc4_set_volume_data(struct snd_sof_dev *sdev, struct snd_sof_widget *swidge
                }
 
                /* set curve type and duration from topology */
-               data.curve_duration = gain->data.curve_duration;
+               data.curve_duration_l = gain->data.curve_duration_l;
+               data.curve_duration_h = gain->data.curve_duration_h;
                data.curve_type = gain->data.curve_type;
 
                msg->data_ptr = &data;
index 3e27c7a48ebd39a3136063ee9d4daccf07047cb7..3a5394c3dd83bf35053bd5e398de7f345bd1c7ba 100644 (file)
@@ -107,7 +107,7 @@ static const struct sof_topology_token gain_tokens[] = {
                get_token_u32, offsetof(struct sof_ipc4_gain_data, curve_type)},
        {SOF_TKN_GAIN_RAMP_DURATION,
                SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc4_gain_data, curve_duration)},
+               offsetof(struct sof_ipc4_gain_data, curve_duration_l)},
        {SOF_TKN_GAIN_VAL, SND_SOC_TPLG_TUPLE_TYPE_WORD,
                get_token_u32, offsetof(struct sof_ipc4_gain_data, init_val)},
 };
@@ -155,7 +155,7 @@ static void sof_ipc4_dbg_audio_format(struct device *dev,
        for (i = 0; i < num_format; i++, ptr = (u8 *)ptr + object_size) {
                fmt = ptr;
                dev_dbg(dev,
-                       " #%d: %uKHz, %ubit (ch_map %#x ch_cfg %u interleaving_style %u fmt_cfg %#x)\n",
+                       " #%d: %uHz, %ubit (ch_map %#x ch_cfg %u interleaving_style %u fmt_cfg %#x)\n",
                        i, fmt->sampling_frequency, fmt->bit_depth, fmt->ch_map,
                        fmt->ch_cfg, fmt->interleaving_style, fmt->fmt_cfg);
        }
@@ -692,7 +692,7 @@ static int sof_ipc4_widget_setup_comp_pga(struct snd_sof_widget *swidget)
 
        dev_dbg(scomp->dev,
                "pga widget %s: ramp type: %d, ramp duration %d, initial gain value: %#x, cpc %d\n",
-               swidget->widget->name, gain->data.curve_type, gain->data.curve_duration,
+               swidget->widget->name, gain->data.curve_type, gain->data.curve_duration_l,
                gain->data.init_val, gain->base_config.cpc);
 
        ret = sof_ipc4_widget_setup_msg(swidget, &gain->msg);
@@ -980,6 +980,7 @@ static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget)
 
                ipc4_copier = dai->private;
                if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) {
+                       struct sof_ipc4_copier_data *copier_data = &ipc4_copier->data;
                        struct sof_ipc4_alh_configuration_blob *blob;
                        unsigned int group_id;
 
@@ -989,6 +990,9 @@ static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget)
                                           ALH_MULTI_GTW_BASE;
                                ida_free(&alh_group_ida, group_id);
                        }
+
+                       /* clear the node ID */
+                       copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
                }
        }
 
@@ -1801,6 +1805,16 @@ static int sof_ipc4_route_setup(struct snd_sof_dev *sdev, struct snd_sof_route *
        u32 header, extension;
        int ret;
 
+       if (!src_fw_module || !sink_fw_module) {
+               dev_err(sdev->dev,
+                       "cannot bind %s -> %s, no firmware module for: %s%s\n",
+                       src_widget->widget->name, sink_widget->widget->name,
+                       src_fw_module ? "" : " source",
+                       sink_fw_module ? "" : " sink");
+
+               return -ENODEV;
+       }
+
        sroute->src_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget,
                                                     SOF_PIN_TYPE_SOURCE);
        if (sroute->src_queue_id < 0) {
@@ -1940,8 +1954,15 @@ static int sof_ipc4_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget *
                pipeline->skip_during_fe_trigger = true;
                fallthrough;
        case SOF_DAI_INTEL_ALH:
-               copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
-               copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(data->dai_data);
+               /*
+                * Do not clear the node ID when this op is invoked with
+                * SOF_DAI_CONFIG_FLAGS_HW_FREE. It is needed to free the group_ida during
+                * unprepare.
+                */
+               if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) {
+                       copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
+                       copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(data->dai_data);
+               }
                break;
        case SOF_DAI_INTEL_DMIC:
        case SOF_DAI_INTEL_SSP:
index 72529179ac22343063ca3ca1ce9873cd36ca75b3..123f1096f3261d46b0e1eda51376ce9b3c02e1d8 100644 (file)
@@ -46,7 +46,7 @@
 #define SOF_IPC4_NODE_INDEX_INTEL_SSP(x) (((x) & 0xf) << 4)
 
 /* Node ID for DMIC type DAI copiers */
-#define SOF_IPC4_NODE_INDEX_INTEL_DMIC(x) (((x) & 0x7) << 5)
+#define SOF_IPC4_NODE_INDEX_INTEL_DMIC(x) ((x) & 0x7)
 
 #define SOF_IPC4_GAIN_ALL_CHANNELS_MASK 0xffffffff
 #define SOF_IPC4_VOL_ZERO_DB   0x7fffffff
@@ -277,14 +277,16 @@ struct sof_ipc4_control_data {
  * @init_val: Initial value
  * @curve_type: Curve type
  * @reserved: reserved for future use
- * @curve_duration: Curve duration
+ * @curve_duration_l: Curve duration low part
+ * @curve_duration_h: Curve duration high part
  */
 struct sof_ipc4_gain_data {
        uint32_t channels;
        uint32_t init_val;
        uint32_t curve_type;
        uint32_t reserved;
-       uint32_t curve_duration;
+       uint32_t curve_duration_l;
+       uint32_t curve_duration_h;
 } __aligned(8);
 
 /**
index 8ede4b952997846bd61f614b143dbb0e6c583ebc..246b56d24a6f160258e5f4cd55ee8d76ec2db87b 100644 (file)
@@ -405,6 +405,9 @@ static int sof_ipc4_tx_msg(struct snd_sof_dev *sdev, void *msg_data, size_t msg_
 static int sof_ipc4_set_get_data(struct snd_sof_dev *sdev, void *data,
                                 size_t payload_bytes, bool set)
 {
+       const struct sof_dsp_power_state target_state = {
+                       .state = SOF_DSP_PM_D0,
+       };
        size_t payload_limit = sdev->ipc->max_payload_size;
        struct sof_ipc4_msg *ipc4_msg = data;
        struct sof_ipc4_msg tx = {{ 0 }};
@@ -435,6 +438,11 @@ static int sof_ipc4_set_get_data(struct snd_sof_dev *sdev, void *data,
 
        tx.extension |= SOF_IPC4_MOD_EXT_MSG_FIRST_BLOCK(1);
 
+       /* ensure the DSP is in D0i0 before sending IPC */
+       ret = snd_sof_dsp_set_power_state(sdev, &target_state);
+       if (ret < 0)
+               return ret;
+
        /* Serialise IPC TX */
        mutex_lock(&sdev->ipc->tx_mutex);
 
index 8d3383085d12c4ffb8ff5c09417f1ec43937b378..85412aeb1ca16b0ed66d4db24a5e449be4370e57 100644 (file)
@@ -183,6 +183,7 @@ static int sof_suspend(struct device *dev, bool runtime_suspend)
        const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
        pm_message_t pm_state;
        u32 target_state = snd_sof_dsp_power_target(sdev);
+       u32 old_state = sdev->dsp_power_state.state;
        int ret;
 
        /* do nothing if dsp suspend callback is not set */
@@ -192,7 +193,12 @@ static int sof_suspend(struct device *dev, bool runtime_suspend)
        if (runtime_suspend && !sof_ops(sdev)->runtime_suspend)
                return 0;
 
-       if (tplg_ops && tplg_ops->tear_down_all_pipelines)
+       /* we need to tear down pipelines only if the DSP hardware is
+        * active, which happens for PCI devices. if the device is
+        * suspended, it is brought back to full power and then
+        * suspended again
+        */
+       if (tplg_ops && tplg_ops->tear_down_all_pipelines && (old_state == SOF_DSP_PM_D0))
                tplg_ops->tear_down_all_pipelines(sdev, false);
 
        if (sdev->fw_state != SOF_FW_BOOT_COMPLETE)
index 760621bfc80284a05c2ebed28579b29368a01f81..6de388a8d0b8df64e6653acc2df7e09510d50326 100644 (file)
@@ -50,9 +50,27 @@ static int sof_widget_free_unlocked(struct snd_sof_dev *sdev,
        /* reset route setup status for all routes that contain this widget */
        sof_reset_route_setup_status(sdev, swidget);
 
+       /* free DAI config and continue to free widget even if it fails */
+       if (WIDGET_IS_DAI(swidget->id)) {
+               struct snd_sof_dai_config_data data;
+               unsigned int flags = SOF_DAI_CONFIG_FLAGS_HW_FREE;
+
+               data.dai_data = DMA_CHAN_INVALID;
+
+               if (tplg_ops && tplg_ops->dai_config) {
+                       err = tplg_ops->dai_config(sdev, swidget, flags, &data);
+                       if (err < 0)
+                               dev_err(sdev->dev, "failed to free config for widget %s\n",
+                                       swidget->widget->name);
+               }
+       }
+
        /* continue to disable core even if IPC fails */
-       if (tplg_ops && tplg_ops->widget_free)
-               err = tplg_ops->widget_free(sdev, swidget);
+       if (tplg_ops && tplg_ops->widget_free) {
+               ret = tplg_ops->widget_free(sdev, swidget);
+               if (ret < 0 && !err)
+                       err = ret;
+       }
 
        /*
         * disable widget core. continue to route setup status and complete flag
@@ -151,8 +169,12 @@ static int sof_widget_setup_unlocked(struct snd_sof_dev *sdev,
 
        /* send config for DAI components */
        if (WIDGET_IS_DAI(swidget->id)) {
-               unsigned int flags = SOF_DAI_CONFIG_FLAGS_NONE;
+               unsigned int flags = SOF_DAI_CONFIG_FLAGS_HW_PARAMS;
 
+               /*
+                * The config flags saved during BE DAI hw_params will be used for IPC3. IPC4 does
+                * not use the flags argument.
+                */
                if (tplg_ops && tplg_ops->dai_config) {
                        ret = tplg_ops->dai_config(sdev, swidget, flags, NULL);
                        if (ret < 0)
@@ -588,8 +610,8 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm,
        ret = sof_walk_widgets_in_order(sdev, spcm, fe_params, platform_params,
                                        dir, SOF_WIDGET_SETUP);
        if (ret < 0) {
-               ret = sof_walk_widgets_in_order(sdev, spcm, fe_params, platform_params,
-                                               dir, SOF_WIDGET_UNPREPARE);
+               sof_walk_widgets_in_order(sdev, spcm, fe_params, platform_params,
+                                         dir, SOF_WIDGET_UNPREPARE);
                return ret;
        }
 
index 4a62ccc71fcbffa005145fa43f601db69f8ef7b4..9f3a038fe21add2ae6ebbe02a41a029f9bdf8eac 100644 (file)
@@ -1388,14 +1388,15 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
        if (ret < 0) {
                dev_err(scomp->dev, "failed to parse component pin tokens for %s\n",
                        w->name);
-               return ret;
+               goto widget_free;
        }
 
        if (swidget->num_sink_pins > SOF_WIDGET_MAX_NUM_PINS ||
            swidget->num_source_pins > SOF_WIDGET_MAX_NUM_PINS) {
                dev_err(scomp->dev, "invalid pins for %s: [sink: %d, src: %d]\n",
                        swidget->widget->name, swidget->num_sink_pins, swidget->num_source_pins);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto widget_free;
        }
 
        if (swidget->num_sink_pins > 1) {
@@ -1404,7 +1405,7 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
                if (ret < 0) {
                        dev_err(scomp->dev, "failed to parse sink pin binding for %s\n",
                                w->name);
-                       return ret;
+                       goto widget_free;
                }
        }
 
@@ -1414,7 +1415,7 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
                if (ret < 0) {
                        dev_err(scomp->dev, "failed to parse source pin binding for %s\n",
                                w->name);
-                       return ret;
+                       goto widget_free;
                }
        }
 
@@ -1436,9 +1437,8 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
        case snd_soc_dapm_dai_out:
                dai = kzalloc(sizeof(*dai), GFP_KERNEL);
                if (!dai) {
-                       kfree(swidget);
-                       return -ENOMEM;
-
+                       ret = -ENOMEM;
+                       goto widget_free;
                }
 
                ret = sof_widget_parse_tokens(scomp, swidget, tw, token_list, token_list_size);
@@ -1496,8 +1496,7 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
                        tw->shift, swidget->id, tw->name,
                        strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0
                                ? tw->sname : "none");
-               kfree(swidget);
-               return ret;
+               goto widget_free;
        }
 
        if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE)) {
@@ -1518,10 +1517,7 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
                        if (ret) {
                                dev_err(scomp->dev, "widget event binding failed for %s\n",
                                        swidget->widget->name);
-                               kfree(swidget->private);
-                               kfree(swidget->tuples);
-                               kfree(swidget);
-                               return ret;
+                               goto free;
                        }
                }
        }
@@ -1532,10 +1528,8 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
 
                spipe = kzalloc(sizeof(*spipe), GFP_KERNEL);
                if (!spipe) {
-                       kfree(swidget->private);
-                       kfree(swidget->tuples);
-                       kfree(swidget);
-                       return -ENOMEM;
+                       ret = -ENOMEM;
+                       goto free;
                }
 
                spipe->pipe_widget = swidget;
@@ -1546,6 +1540,12 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
        w->dobj.private = swidget;
        list_add(&swidget->list, &sdev->widget_list);
        return ret;
+free:
+       kfree(swidget->private);
+       kfree(swidget->tuples);
+widget_free:
+       kfree(swidget);
+       return ret;
 }
 
 static int sof_route_unload(struct snd_soc_component *scomp,
index 419302e2057e8fbc67c6ee8d940ae9a4876369b2..647fa054d8b1da37a3ec8db6e4608ce8393d8a12 100644 (file)
@@ -455,8 +455,8 @@ static void push_back_to_ready_list(struct snd_usb_endpoint *ep,
  * This function is used both for implicit feedback endpoints and in low-
  * latency playback mode.
  */
-void snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
-                                      bool in_stream_lock)
+int snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
+                                     bool in_stream_lock)
 {
        bool implicit_fb = snd_usb_endpoint_implicit_feedback_sink(ep);
 
@@ -480,7 +480,7 @@ void snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
                spin_unlock_irqrestore(&ep->lock, flags);
 
                if (ctx == NULL)
-                       return;
+                       break;
 
                /* copy over the length information */
                if (implicit_fb) {
@@ -495,11 +495,14 @@ void snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
                        break;
                if (err < 0) {
                        /* push back to ready list again for -EAGAIN */
-                       if (err == -EAGAIN)
+                       if (err == -EAGAIN) {
                                push_back_to_ready_list(ep, ctx);
-                       else
+                               break;
+                       }
+
+                       if (!in_stream_lock)
                                notify_xrun(ep);
-                       return;
+                       return -EPIPE;
                }
 
                err = usb_submit_urb(ctx->urb, GFP_ATOMIC);
@@ -507,13 +510,16 @@ void snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
                        usb_audio_err(ep->chip,
                                      "Unable to submit urb #%d: %d at %s\n",
                                      ctx->index, err, __func__);
-                       notify_xrun(ep);
-                       return;
+                       if (!in_stream_lock)
+                               notify_xrun(ep);
+                       return -EPIPE;
                }
 
                set_bit(ctx->index, &ep->active_mask);
                atomic_inc(&ep->submitted_urbs);
        }
+
+       return 0;
 }
 
 /*
index 924f4351588ce9818fc93826483d91d0dc73f8bf..c09f68ce08b187258c25bc9d8853c5427a82a3b9 100644 (file)
@@ -52,7 +52,7 @@ int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep);
 int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep,
                                      struct snd_urb_ctx *ctx, int idx,
                                      unsigned int avail);
-void snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
-                                      bool in_stream_lock);
+int snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
+                                     bool in_stream_lock);
 
 #endif /* __USBAUDIO_ENDPOINT_H */
index 405dc0bf6678c6bc94533315e063f51a32a576ae..4b1c5ba121f391db21a542a453147256d4055430 100644 (file)
@@ -39,8 +39,12 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
        case UAC_VERSION_1:
        default: {
                struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
-               if (format >= 64)
-                       return 0; /* invalid format */
+               if (format >= 64) {
+                       usb_audio_info(chip,
+                                      "%u:%d: invalid format type 0x%llx is detected, processed as PCM\n",
+                                      fp->iface, fp->altsetting, format);
+                       format = UAC_FORMAT_TYPE_I_PCM;
+               }
                sample_width = fmt->bBitResolution;
                sample_bytes = fmt->bSubframeSize;
                format = 1ULL << format;
index d959da7a1afbab5bca4c92c3613025e48a84432d..eec5232f9fb290c7292d824893563e1bd8326032 100644 (file)
@@ -1639,7 +1639,7 @@ static int snd_usb_pcm_playback_ack(struct snd_pcm_substream *substream)
         * outputs here
         */
        if (!ep->active_mask)
-               snd_usb_queue_pending_output_urbs(ep, true);
+               return snd_usb_queue_pending_output_urbs(ep, true);
        return 0;
 }
 
index e497875fc7e3fecfbb419c7cd632383833bce07a..37e9f6804832641c176afe5ef150031748a77e9a 100644 (file)
@@ -39,7 +39,7 @@ help:
        @echo '  turbostat              - Intel CPU idle stats and freq reporting tool'
        @echo '  usb                    - USB testing tools'
        @echo '  virtio                 - vhost test module'
-       @echo '  vm                     - misc vm tools'
+       @echo '  mm                     - misc mm tools'
        @echo '  wmi                    - WMI interface examples'
        @echo '  x86_energy_perf_policy - Intel energy policy tool'
        @echo ''
@@ -69,7 +69,7 @@ acpi: FORCE
 cpupower: FORCE
        $(call descend,power/$@)
 
-cgroup counter firewire hv guest bootconfig spi usb virtio vm bpf iio gpio objtool leds wmi pci firmware debugging tracing: FORCE
+cgroup counter firewire hv guest bootconfig spi usb virtio mm bpf iio gpio objtool leds wmi pci firmware debugging tracing: FORCE
        $(call descend,$@)
 
 bpf/%: FORCE
@@ -118,7 +118,7 @@ kvm_stat: FORCE
 
 all: acpi cgroup counter cpupower gpio hv firewire \
                perf selftests bootconfig spi turbostat usb \
-               virtio vm bpf x86_energy_perf_policy \
+               virtio mm bpf x86_energy_perf_policy \
                tmon freefall iio objtool kvm_stat wmi \
                pci debugging tracing thermal thermometer thermal-engine
 
@@ -128,7 +128,7 @@ acpi_install:
 cpupower_install:
        $(call descend,power/$(@:_install=),install)
 
-cgroup_install counter_install firewire_install gpio_install hv_install iio_install perf_install bootconfig_install spi_install usb_install virtio_install vm_install bpf_install objtool_install wmi_install pci_install debugging_install tracing_install:
+cgroup_install counter_install firewire_install gpio_install hv_install iio_install perf_install bootconfig_install spi_install usb_install virtio_install mm_install bpf_install objtool_install wmi_install pci_install debugging_install tracing_install:
        $(call descend,$(@:_install=),install)
 
 selftests_install:
@@ -158,7 +158,7 @@ kvm_stat_install:
 install: acpi_install cgroup_install counter_install cpupower_install gpio_install \
                hv_install firewire_install iio_install \
                perf_install selftests_install turbostat_install usb_install \
-               virtio_install vm_install bpf_install x86_energy_perf_policy_install \
+               virtio_install mm_install bpf_install x86_energy_perf_policy_install \
                tmon_install freefall_install objtool_install kvm_stat_install \
                wmi_install pci_install debugging_install intel-speed-select_install \
                tracing_install thermometer_install thermal-engine_install
@@ -169,7 +169,7 @@ acpi_clean:
 cpupower_clean:
        $(call descend,power/cpupower,clean)
 
-cgroup_clean counter_clean hv_clean firewire_clean bootconfig_clean spi_clean usb_clean virtio_clean vm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean pci_clean firmware_clean debugging_clean tracing_clean:
+cgroup_clean counter_clean hv_clean firewire_clean bootconfig_clean spi_clean usb_clean virtio_clean mm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean pci_clean firmware_clean debugging_clean tracing_clean:
        $(call descend,$(@:_clean=),clean)
 
 libapi_clean:
@@ -211,7 +211,7 @@ build_clean:
 
 clean: acpi_clean cgroup_clean counter_clean cpupower_clean hv_clean firewire_clean \
                perf_clean selftests_clean turbostat_clean bootconfig_clean spi_clean usb_clean virtio_clean \
-               vm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \
+               mm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \
                freefall_clean build_clean libbpf_clean libsubcmd_clean \
                gpio_clean objtool_clean leds_clean wmi_clean pci_clean firmware_clean debugging_clean \
                intel-speed-select_clean tracing_clean thermal_clean thermometer_clean thermal-engine_clean
index a7a857f1784d80d6264eeebecbeb371c7d13ba5b..f8129c624b0709815cbd266d569bb12fb70e6047 100644 (file)
@@ -109,6 +109,7 @@ struct kvm_regs {
 #define KVM_ARM_VCPU_SVE               4 /* enable SVE for this CPU */
 #define KVM_ARM_VCPU_PTRAUTH_ADDRESS   5 /* VCPU uses address authentication */
 #define KVM_ARM_VCPU_PTRAUTH_GENERIC   6 /* VCPU uses generic authentication */
+#define KVM_ARM_VCPU_HAS_EL2           7 /* Support nested virtualization */
 
 struct kvm_vcpu_init {
        __u32 target;
index d4e32b3d484379631682aa2b01247803c053b2b4..00b4ba1e5cdf032f81aff9f728dcffea68571880 100644 (file)
@@ -2,7 +2,7 @@
 #ifndef __ASM_LOONGARCH_BITSPERLONG_H
 #define __ASM_LOONGARCH_BITSPERLONG_H
 
-#define __BITS_PER_LONG (__SIZEOF_POINTER__ * 8)
+#define __BITS_PER_LONG (__SIZEOF_LONG__ * 8)
 
 #include <asm-generic/bitsperlong.h>
 
index b70111a75688a794586e12ac3db3deeeb4a948b4..b89005819cd551a9cc983fde516a9a060137ad84 100644 (file)
@@ -13,7 +13,7 @@
 /*
  * Defines x86 CPU feature bits
  */
-#define NCAPINTS                       20         /* N 32-bit words worth of info */
+#define NCAPINTS                       21         /* N 32-bit words worth of info */
 #define NBUGINTS                       1          /* N 32-bit bug flags */
 
 /*
index c44b56f7ffba0d0e4bf881c035a3a3668be9929e..5dfa4fb76f4b2ba025b4c4e45b9e4846b75128c6 100644 (file)
 #define DISABLED_MASK17        0
 #define DISABLED_MASK18        0
 #define DISABLED_MASK19        0
-#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 20)
+#define DISABLED_MASK20        0
+#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 21)
 
 #endif /* _ASM_X86_DISABLED_FEATURES_H */
index 37ff47552bcb7b57fdc75bc0246f2bb3876add4a..ad35355ee43ead14e638ac5c853fd5a82b8ee774 100644 (file)
@@ -25,6 +25,7 @@
 #define _EFER_SVME             12 /* Enable virtualization */
 #define _EFER_LMSLE            13 /* Long Mode Segment Limit Enable */
 #define _EFER_FFXSR            14 /* Enable Fast FXSAVE/FXRSTOR */
+#define _EFER_AUTOIBRS         21 /* Enable Automatic IBRS */
 
 #define EFER_SCE               (1<<_EFER_SCE)
 #define EFER_LME               (1<<_EFER_LME)
@@ -33,6 +34,7 @@
 #define EFER_SVME              (1<<_EFER_SVME)
 #define EFER_LMSLE             (1<<_EFER_LMSLE)
 #define EFER_FFXSR             (1<<_EFER_FFXSR)
+#define EFER_AUTOIBRS          (1<<_EFER_AUTOIBRS)
 
 /* Intel MSRs. Some also available on other CPUs */
 
 #define SPEC_CTRL_RRSBA_DIS_S_SHIFT    6          /* Disable RRSBA behavior */
 #define SPEC_CTRL_RRSBA_DIS_S          BIT(SPEC_CTRL_RRSBA_DIS_S_SHIFT)
 
+/* A mask for bits which the kernel toggles when controlling mitigations */
+#define SPEC_CTRL_MITIGATIONS_MASK     (SPEC_CTRL_IBRS | SPEC_CTRL_STIBP | SPEC_CTRL_SSBD \
+                                                       | SPEC_CTRL_RRSBA_DIS_S)
+
 #define MSR_IA32_PRED_CMD              0x00000049 /* Prediction Command */
 #define PRED_CMD_IBPB                  BIT(0)     /* Indirect Branch Prediction Barrier */
 
 #define MSR_TURBO_RATIO_LIMIT1         0x000001ae
 #define MSR_TURBO_RATIO_LIMIT2         0x000001af
 
+#define MSR_SNOOP_RSP_0                        0x00001328
+#define MSR_SNOOP_RSP_1                        0x00001329
+
 #define MSR_LBR_SELECT                 0x000001c8
 #define MSR_LBR_TOS                    0x000001c9
 
 #define MSR_AMD64_SEV_ES_ENABLED       BIT_ULL(MSR_AMD64_SEV_ES_ENABLED_BIT)
 #define MSR_AMD64_SEV_SNP_ENABLED      BIT_ULL(MSR_AMD64_SEV_SNP_ENABLED_BIT)
 
+/* SNP feature bits enabled by the hypervisor */
+#define MSR_AMD64_SNP_VTOM                     BIT_ULL(3)
+#define MSR_AMD64_SNP_REFLECT_VC               BIT_ULL(4)
+#define MSR_AMD64_SNP_RESTRICTED_INJ           BIT_ULL(5)
+#define MSR_AMD64_SNP_ALT_INJ                  BIT_ULL(6)
+#define MSR_AMD64_SNP_DEBUG_SWAP               BIT_ULL(7)
+#define MSR_AMD64_SNP_PREVENT_HOST_IBS         BIT_ULL(8)
+#define MSR_AMD64_SNP_BTB_ISOLATION            BIT_ULL(9)
+#define MSR_AMD64_SNP_VMPL_SSS                 BIT_ULL(10)
+#define MSR_AMD64_SNP_SECURE_TSC               BIT_ULL(11)
+#define MSR_AMD64_SNP_VMGEXIT_PARAM            BIT_ULL(12)
+#define MSR_AMD64_SNP_IBS_VIRT                 BIT_ULL(14)
+#define MSR_AMD64_SNP_VMSA_REG_PROTECTION      BIT_ULL(16)
+#define MSR_AMD64_SNP_SMT_PROTECTION           BIT_ULL(17)
+
+/* SNP feature bits reserved for future use. */
+#define MSR_AMD64_SNP_RESERVED_BIT13           BIT_ULL(13)
+#define MSR_AMD64_SNP_RESERVED_BIT15           BIT_ULL(15)
+#define MSR_AMD64_SNP_RESERVED_MASK            GENMASK_ULL(63, 18)
+
 #define MSR_AMD64_VIRT_SPEC_CTRL       0xc001011f
 
 /* AMD Collaborative Processor Performance Control MSRs */
 
 /* - AMD: */
 #define MSR_IA32_MBA_BW_BASE           0xc0000200
+#define MSR_IA32_SMBA_BW_BASE          0xc0000280
+#define MSR_IA32_EVT_CFG_BASE          0xc0000400
 
 /* MSR_IA32_VMX_MISC bits */
 #define MSR_IA32_VMX_MISC_INTEL_PT                 (1ULL << 14)
index aff774775c678434e2b20218d0873676f5b4a39b..7ba1726b71c7b8bfc95888dc78508998bba263fe 100644 (file)
@@ -98,6 +98,7 @@
 #define REQUIRED_MASK17        0
 #define REQUIRED_MASK18        0
 #define REQUIRED_MASK19        0
-#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 20)
+#define REQUIRED_MASK20        0
+#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 21)
 
 #endif /* _ASM_X86_REQUIRED_FEATURES_H */
index e48deab8901d4ecb9fddaaf334247e27fb6c1762..7f467fe05d42ea702d45679bc8ce27d18656b124 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/types.h>
 #include <linux/ioctl.h>
+#include <linux/stddef.h>
 
 #define KVM_PIO_PAGE_OFFSET 1
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 2
@@ -507,8 +508,8 @@ struct kvm_nested_state {
         * KVM_{GET,PUT}_NESTED_STATE ioctl values.
         */
        union {
-               struct kvm_vmx_nested_state_data vmx[0];
-               struct kvm_svm_nested_state_data svm[0];
+               __DECLARE_FLEX_ARRAY(struct kvm_vmx_nested_state_data, vmx);
+               __DECLARE_FLEX_ARRAY(struct kvm_svm_nested_state_data, svm);
        } data;
 };
 
@@ -525,6 +526,35 @@ struct kvm_pmu_event_filter {
 #define KVM_PMU_EVENT_ALLOW 0
 #define KVM_PMU_EVENT_DENY 1
 
+#define KVM_PMU_EVENT_FLAG_MASKED_EVENTS BIT(0)
+#define KVM_PMU_EVENT_FLAGS_VALID_MASK (KVM_PMU_EVENT_FLAG_MASKED_EVENTS)
+
+/*
+ * Masked event layout.
+ * Bits   Description
+ * ----   -----------
+ * 7:0    event select (low bits)
+ * 15:8   umask match
+ * 31:16  unused
+ * 35:32  event select (high bits)
+ * 36:54  unused
+ * 55     exclude bit
+ * 63:56  umask mask
+ */
+
+#define KVM_PMU_ENCODE_MASKED_ENTRY(event_select, mask, match, exclude) \
+       (((event_select) & 0xFFULL) | (((event_select) & 0XF00ULL) << 24) | \
+       (((mask) & 0xFFULL) << 56) | \
+       (((match) & 0xFFULL) << 8) | \
+       ((__u64)(!!(exclude)) << 55))
+
+#define KVM_PMU_MASKED_ENTRY_EVENT_SELECT \
+       (GENMASK_ULL(7, 0) | GENMASK_ULL(35, 32))
+#define KVM_PMU_MASKED_ENTRY_UMASK_MASK                (GENMASK_ULL(63, 56))
+#define KVM_PMU_MASKED_ENTRY_UMASK_MATCH       (GENMASK_ULL(15, 8))
+#define KVM_PMU_MASKED_ENTRY_EXCLUDE           (BIT_ULL(55))
+#define KVM_PMU_MASKED_ENTRY_UMASK_MASK_SHIFT  (56)
+
 /* for KVM_{GET,SET,HAS}_DEVICE_ATTR */
 #define KVM_VCPU_TSC_CTRL 0 /* control group for the timestamp counter (TSC) */
 #define   KVM_VCPU_TSC_OFFSET 0 /* attribute for the TSC offset */
index f69c168391aa58cf280ba6fb5aca6630e3593d1a..80e1df482337dfe064d809966a309cecd0930070 100644 (file)
 #define SVM_VMGEXIT_AP_CREATE                  1
 #define SVM_VMGEXIT_AP_DESTROY                 2
 #define SVM_VMGEXIT_HV_FEATURES                        0x8000fffd
+#define SVM_VMGEXIT_TERM_REQUEST               0x8000fffe
+#define SVM_VMGEXIT_TERM_REASON(reason_set, reason_code)       \
+       /* SW_EXITINFO1[3:0] */                                 \
+       (((((u64)reason_set) & 0xf)) |                          \
+       /* SW_EXITINFO1[11:4] */                                \
+       ((((u64)reason_code) & 0xff) << 4))
 #define SVM_VMGEXIT_UNSUPPORTED_EVENT          0x8000ffff
 
 /* Exit code reserved for hypervisor/software use */
index 5418e2f99834e5dec0bd2f12d801da4d7b10d77a..a91ac666f758274c3f1ebf411cdf3469d69b93d2 100644 (file)
@@ -7,7 +7,7 @@
 #include <asm/alternative.h>
 #include <asm/export.h>
 
-.pushsection .noinstr.text, "ax"
+.section .noinstr.text, "ax"
 
 /*
  * We build a jump to memcpy_orig by default which gets NOPped out on
@@ -42,7 +42,7 @@ SYM_TYPED_FUNC_START(__memcpy)
 SYM_FUNC_END(__memcpy)
 EXPORT_SYMBOL(__memcpy)
 
-SYM_FUNC_ALIAS_WEAK(memcpy, __memcpy)
+SYM_FUNC_ALIAS(memcpy, __memcpy)
 EXPORT_SYMBOL(memcpy)
 
 /*
@@ -183,4 +183,3 @@ SYM_FUNC_START_LOCAL(memcpy_orig)
        RET
 SYM_FUNC_END(memcpy_orig)
 
-.popsection
index fc9ffd3ff3b213a38448d5fbff5493989e21a158..6143b1a6fa2caa0d5977d22c3f1c23456ff6d3bf 100644 (file)
@@ -6,6 +6,8 @@
 #include <asm/alternative.h>
 #include <asm/export.h>
 
+.section .noinstr.text, "ax"
+
 /*
  * ISO C memset - set a memory block to a byte value. This function uses fast
  * string to get better performance than the original function. The code is
@@ -43,7 +45,7 @@ SYM_FUNC_START(__memset)
 SYM_FUNC_END(__memset)
 EXPORT_SYMBOL(__memset)
 
-SYM_FUNC_ALIAS_WEAK(memset, __memset)
+SYM_FUNC_ALIAS(memset, __memset)
 EXPORT_SYMBOL(memset)
 
 /*
index f68e2e9eef8b27223f753399dab743f370318d69..a2c484c243f5d9ba5da21fd932d802db1e23054e 100755 (executable)
@@ -87,10 +87,14 @@ xfail grep -i "error" $OUTFILE
 
 echo "Max node number check"
 
-echo -n > $TEMPCONF
-for i in `seq 1 1024` ; do
-   echo "node$i" >> $TEMPCONF
-done
+awk '
+BEGIN {
+  for (i = 0; i < 26; i += 1)
+      printf("%c\n", 65 + i % 26)
+  for (i = 26; i < 8192; i += 1)
+      printf("%c%c%c\n", 65 + i % 26, 65 + (i / 26) % 26, 65 + (i / 26 / 26))
+}
+' > $TEMPCONF
 xpass $BOOTCONF -a $TEMPCONF $INITRD
 
 echo "badnode" >> $TEMPCONF
index 87d112650dfbb0ec9ac6825ae2746c61b2659960..7c0cf5031abe8796fc40c7307ddfde4832f2655d 100644 (file)
@@ -6,7 +6,6 @@
 #include <vdso/bits.h>
 #include <asm/bitsperlong.h>
 
-#define BIT_ULL(nr)            (ULL(1) << (nr))
 #define BIT_MASK(nr)           (UL(1) << ((nr) % BITS_PER_LONG))
 #define BIT_WORD(nr)           ((nr) / BITS_PER_LONG)
 #define BIT_ULL_MASK(nr)       (ULL(1) << ((nr) % BITS_PER_LONG_LONG))
index 25f2bb3a991d3003b3fee9314a767cb281876afb..332b983ead1e4aa9cef4db835198cc92d04ac29d 100644 (file)
@@ -20,7 +20,7 @@
  * Userspace note:
  * The same principle works for userspace, because 'error' pointers
  * fall down to the unused hole far from user space, as described
- * in Documentation/x86/x86_64/mm.rst for x86_64 arch:
+ * in Documentation/arch/x86/x86_64/mm.rst for x86_64 arch:
  *
  * 0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm hole caused by [48:63] sign extension
  * ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole
diff --git a/tools/include/nolibc/.gitignore b/tools/include/nolibc/.gitignore
new file mode 100644 (file)
index 0000000..dea22ea
--- /dev/null
@@ -0,0 +1 @@
+sysroot
index cfd06764b5aeeae9c1843c50f6b7fd7fdfa91797..9839feafd38a14a45c73283fb979cd371a2d8fb7 100644 (file)
@@ -25,8 +25,8 @@ endif
 
 nolibc_arch := $(patsubst arm64,aarch64,$(ARCH))
 arch_file := arch-$(nolibc_arch).h
-all_files := ctype.h errno.h nolibc.h signal.h std.h stdio.h stdlib.h string.h \
-             sys.h time.h types.h unistd.h
+all_files := ctype.h errno.h nolibc.h signal.h stackprotector.h std.h stdint.h \
+             stdio.h stdlib.h string.h sys.h time.h types.h unistd.h
 
 # install all headers needed to support a bare-metal compiler
 all: headers
index e8d0cf545bf145db427191a75ac67fc599e6158c..2d98d78fd3f3a6459d7372dc51c65d1147b471ef 100644 (file)
@@ -181,6 +181,8 @@ struct sys_stat_struct {
 char **environ __attribute__((weak));
 const unsigned long *_auxv __attribute__((weak));
 
+#define __ARCH_SUPPORTS_STACK_PROTECTOR
+
 /* startup code */
 /*
  * i386 System V ABI mandates:
@@ -188,9 +190,12 @@ const unsigned long *_auxv __attribute__((weak));
  * 2) The deepest stack frame should be set to zero
  *
  */
-void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) _start(void)
+void __attribute__((weak,noreturn,optimize("omit-frame-pointer"),no_stack_protector)) _start(void)
 {
        __asm__ volatile (
+#ifdef NOLIBC_STACKPROTECTOR
+               "call __stack_chk_init\n"   // initialize stack protector
+#endif
                "pop %eax\n"                // argc   (first arg, %eax)
                "mov %esp, %ebx\n"          // argv[] (second arg, %ebx)
                "lea 4(%ebx,%eax,4),%ecx\n" // then a NULL then envp (third arg, %ecx)
diff --git a/tools/include/nolibc/arch-loongarch.h b/tools/include/nolibc/arch-loongarch.h
new file mode 100644 (file)
index 0000000..029ee3c
--- /dev/null
@@ -0,0 +1,200 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * LoongArch specific definitions for NOLIBC
+ * Copyright (C) 2023 Loongson Technology Corporation Limited
+ */
+
+#ifndef _NOLIBC_ARCH_LOONGARCH_H
+#define _NOLIBC_ARCH_LOONGARCH_H
+
+/* Syscalls for LoongArch :
+ *   - stack is 16-byte aligned
+ *   - syscall number is passed in a7
+ *   - arguments are in a0, a1, a2, a3, a4, a5
+ *   - the system call is performed by calling "syscall 0"
+ *   - syscall return comes in a0
+ *   - the arguments are cast to long and assigned into the target
+ *     registers which are then simply passed as registers to the asm code,
+ *     so that we don't have to experience issues with register constraints.
+ *
+ * On LoongArch, select() is not implemented so we have to use pselect6().
+ */
+#define __ARCH_WANT_SYS_PSELECT6
+
+#define my_syscall0(num)                                                      \
+({                                                                            \
+       register long _num  __asm__ ("a7") = (num);                           \
+       register long _arg1 __asm__ ("a0");                                   \
+                                                                             \
+       __asm__  volatile (                                                   \
+               "syscall 0\n"                                                 \
+               : "=r"(_arg1)                                                 \
+               : "r"(_num)                                                   \
+               : "memory", "$t0", "$t1", "$t2", "$t3",                       \
+                 "$t4", "$t5", "$t6", "$t7", "$t8"                           \
+       );                                                                    \
+       _arg1;                                                                \
+})
+
+#define my_syscall1(num, arg1)                                                \
+({                                                                            \
+       register long _num  __asm__ ("a7") = (num);                           \
+       register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
+                                                                             \
+       __asm__  volatile (                                                   \
+               "syscall 0\n"                                                 \
+               : "+r"(_arg1)                                                 \
+               : "r"(_num)                                                   \
+               : "memory", "$t0", "$t1", "$t2", "$t3",                       \
+                 "$t4", "$t5", "$t6", "$t7", "$t8"                           \
+       );                                                                    \
+       _arg1;                                                                \
+})
+
+#define my_syscall2(num, arg1, arg2)                                          \
+({                                                                            \
+       register long _num  __asm__ ("a7") = (num);                           \
+       register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
+       register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
+                                                                             \
+       __asm__  volatile (                                                   \
+               "syscall 0\n"                                                 \
+               : "+r"(_arg1)                                                 \
+               : "r"(_arg2),                                                 \
+                 "r"(_num)                                                   \
+               : "memory", "$t0", "$t1", "$t2", "$t3",                       \
+                 "$t4", "$t5", "$t6", "$t7", "$t8"                           \
+       );                                                                    \
+       _arg1;                                                                \
+})
+
+#define my_syscall3(num, arg1, arg2, arg3)                                    \
+({                                                                            \
+       register long _num  __asm__ ("a7") = (num);                           \
+       register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
+       register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
+       register long _arg3 __asm__ ("a2") = (long)(arg3);                    \
+                                                                             \
+       __asm__  volatile (                                                   \
+               "syscall 0\n"                                                 \
+               : "+r"(_arg1)                                                 \
+               : "r"(_arg2), "r"(_arg3),                                     \
+                 "r"(_num)                                                   \
+               : "memory", "$t0", "$t1", "$t2", "$t3",                       \
+                 "$t4", "$t5", "$t6", "$t7", "$t8"                           \
+       );                                                                    \
+       _arg1;                                                                \
+})
+
+#define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
+({                                                                            \
+       register long _num  __asm__ ("a7") = (num);                           \
+       register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
+       register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
+       register long _arg3 __asm__ ("a2") = (long)(arg3);                    \
+       register long _arg4 __asm__ ("a3") = (long)(arg4);                    \
+                                                                             \
+       __asm__  volatile (                                                   \
+               "syscall 0\n"                                                 \
+               : "+r"(_arg1)                                                 \
+               : "r"(_arg2), "r"(_arg3), "r"(_arg4),                         \
+                 "r"(_num)                                                   \
+               : "memory", "$t0", "$t1", "$t2", "$t3",                       \
+                 "$t4", "$t5", "$t6", "$t7", "$t8"                           \
+       );                                                                    \
+       _arg1;                                                                \
+})
+
+#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
+({                                                                            \
+       register long _num  __asm__ ("a7") = (num);                           \
+       register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
+       register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
+       register long _arg3 __asm__ ("a2") = (long)(arg3);                    \
+       register long _arg4 __asm__ ("a3") = (long)(arg4);                    \
+       register long _arg5 __asm__ ("a4") = (long)(arg5);                    \
+                                                                             \
+       __asm__  volatile (                                                   \
+               "syscall 0\n"                                                 \
+               : "+r"(_arg1)                                                 \
+               : "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5),             \
+                 "r"(_num)                                                   \
+               : "memory", "$t0", "$t1", "$t2", "$t3",                       \
+                 "$t4", "$t5", "$t6", "$t7", "$t8"                           \
+       );                                                                    \
+       _arg1;                                                                \
+})
+
+#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)                  \
+({                                                                            \
+       register long _num  __asm__ ("a7") = (num);                           \
+       register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
+       register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
+       register long _arg3 __asm__ ("a2") = (long)(arg3);                    \
+       register long _arg4 __asm__ ("a3") = (long)(arg4);                    \
+       register long _arg5 __asm__ ("a4") = (long)(arg5);                    \
+       register long _arg6 __asm__ ("a5") = (long)(arg6);                    \
+                                                                             \
+       __asm__  volatile (                                                   \
+               "syscall 0\n"                                                 \
+               : "+r"(_arg1)                                                 \
+               : "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), "r"(_arg6), \
+                 "r"(_num)                                                   \
+               : "memory", "$t0", "$t1", "$t2", "$t3",                       \
+                 "$t4", "$t5", "$t6", "$t7", "$t8"                           \
+       );                                                                    \
+       _arg1;                                                                \
+})
+
+char **environ __attribute__((weak));
+const unsigned long *_auxv __attribute__((weak));
+
+#if __loongarch_grlen == 32
+#define LONGLOG      "2"
+#define SZREG        "4"
+#define REG_L        "ld.w"
+#define LONG_S       "st.w"
+#define LONG_ADD     "add.w"
+#define LONG_ADDI    "addi.w"
+#define LONG_SLL     "slli.w"
+#define LONG_BSTRINS "bstrins.w"
+#else // __loongarch_grlen == 64
+#define LONGLOG      "3"
+#define SZREG        "8"
+#define REG_L        "ld.d"
+#define LONG_S       "st.d"
+#define LONG_ADD     "add.d"
+#define LONG_ADDI    "addi.d"
+#define LONG_SLL     "slli.d"
+#define LONG_BSTRINS "bstrins.d"
+#endif
+
+/* startup code */
+void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) _start(void)
+{
+       __asm__ volatile (
+               REG_L        " $a0, $sp, 0\n"         // argc (a0) was in the stack
+               LONG_ADDI    " $a1, $sp, "SZREG"\n"   // argv (a1) = sp + SZREG
+               LONG_SLL     " $a2, $a0, "LONGLOG"\n" // envp (a2) = SZREG*argc ...
+               LONG_ADDI    " $a2, $a2, "SZREG"\n"   //             + SZREG (skip null)
+               LONG_ADD     " $a2, $a2, $a1\n"       //             + argv
+
+               "move          $a3, $a2\n"            // iterate a3 over envp to find auxv (after NULL)
+               "0:\n"                                // do {
+               REG_L        " $a4, $a3, 0\n"         //   a4 = *a3;
+               LONG_ADDI    " $a3, $a3, "SZREG"\n"   //   a3 += sizeof(void*);
+               "bne           $a4, $zero, 0b\n"      // } while (a4);
+               "la.pcrel      $a4, _auxv\n"          // a4 = &_auxv
+               LONG_S       " $a3, $a4, 0\n"         // store a3 into _auxv
+
+               "la.pcrel      $a3, environ\n"        // a3 = &environ
+               LONG_S       " $a2, $a3, 0\n"         // store envp(a2) into environ
+               LONG_BSTRINS " $sp, $zero, 3, 0\n"    // sp must be 16-byte aligned
+               "bl            main\n"                // main() returns the status code, we'll exit with it.
+               "li.w          $a7, 93\n"             // NR_exit == 93
+               "syscall       0\n"
+       );
+       __builtin_unreachable();
+}
+
+#endif // _NOLIBC_ARCH_LOONGARCH_H
index 17f6751208e7e9d93229f1248bf0518c51f48985..f7f2a11d4c3b08fa9af028356da25d7038a381f1 100644 (file)
@@ -181,6 +181,8 @@ struct sys_stat_struct {
 char **environ __attribute__((weak));
 const unsigned long *_auxv __attribute__((weak));
 
+#define __ARCH_SUPPORTS_STACK_PROTECTOR
+
 /* startup code */
 /*
  * x86-64 System V ABI mandates:
@@ -191,6 +193,9 @@ const unsigned long *_auxv __attribute__((weak));
 void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) _start(void)
 {
        __asm__ volatile (
+#ifdef NOLIBC_STACKPROTECTOR
+               "call __stack_chk_init\n"   // initialize stack protector
+#endif
                "pop %rdi\n"                // argc   (first arg, %rdi)
                "mov %rsp, %rsi\n"          // argv[] (second arg, %rsi)
                "lea 8(%rsi,%rdi,8),%rdx\n" // then a NULL then envp (third arg, %rdx)
index 78b067a4fa47acbd12ebc55971ae16144e045aeb..2d5386a8d6aacc1a882e4e3b016b22c6dcfeb0e4 100644 (file)
@@ -29,6 +29,8 @@
 #include "arch-riscv.h"
 #elif defined(__s390x__)
 #include "arch-s390.h"
+#elif defined(__loongarch__)
+#include "arch-loongarch.h"
 #endif
 
 #endif /* _NOLIBC_ARCH_H */
index b2bc48d3cfe4b9321f5478162dc29a623c1fc497..04739a6293c4889da0e9804294f994f9dd78e701 100644 (file)
 #include "string.h"
 #include "time.h"
 #include "unistd.h"
+#include "stackprotector.h"
 
 /* Used by programs to avoid std includes */
 #define NOLIBC
diff --git a/tools/include/nolibc/stackprotector.h b/tools/include/nolibc/stackprotector.h
new file mode 100644 (file)
index 0000000..d119cbb
--- /dev/null
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * Stack protector support for NOLIBC
+ * Copyright (C) 2023 Thomas Weißschuh <linux@weissschuh.net>
+ */
+
+#ifndef _NOLIBC_STACKPROTECTOR_H
+#define _NOLIBC_STACKPROTECTOR_H
+
+#include "arch.h"
+
+#if defined(NOLIBC_STACKPROTECTOR)
+
+#if !defined(__ARCH_SUPPORTS_STACK_PROTECTOR)
+#error "nolibc does not support stack protectors on this arch"
+#endif
+
+#include "sys.h"
+#include "stdlib.h"
+
+/* The functions in this header are using raw syscall macros to avoid
+ * triggering stack protector errors themselves
+ */
+
+__attribute__((weak,noreturn,section(".text.nolibc_stack_chk")))
+void __stack_chk_fail(void)
+{
+       pid_t pid;
+       my_syscall3(__NR_write, STDERR_FILENO, "!!Stack smashing detected!!\n", 28);
+       pid = my_syscall0(__NR_getpid);
+       my_syscall2(__NR_kill, pid, SIGABRT);
+       for (;;);
+}
+
+__attribute__((weak,noreturn,section(".text.nolibc_stack_chk")))
+void __stack_chk_fail_local(void)
+{
+       __stack_chk_fail();
+}
+
+__attribute__((weak,section(".data.nolibc_stack_chk")))
+uintptr_t __stack_chk_guard;
+
+__attribute__((weak,no_stack_protector,section(".text.nolibc_stack_chk")))
+void __stack_chk_init(void)
+{
+       my_syscall3(__NR_getrandom, &__stack_chk_guard, sizeof(__stack_chk_guard), 0);
+       /* a bit more randomness in case getrandom() fails */
+       __stack_chk_guard ^= (uintptr_t) &__stack_chk_guard;
+}
+#endif // defined(NOLIBC_STACKPROTECTOR)
+
+#endif // _NOLIBC_STACKPROTECTOR_H
index 1747ae1253920ec03c6151c97df2f31ecc956158..933bc0be7e1c6be3b7909efc127f1d3b9c611135 100644 (file)
 #define NULL ((void *)0)
 #endif
 
-/* stdint types */
-typedef unsigned char       uint8_t;
-typedef   signed char        int8_t;
-typedef unsigned short     uint16_t;
-typedef   signed short      int16_t;
-typedef unsigned int       uint32_t;
-typedef   signed int        int32_t;
-typedef unsigned long long uint64_t;
-typedef   signed long long  int64_t;
-typedef unsigned long        size_t;
-typedef   signed long       ssize_t;
-typedef unsigned long     uintptr_t;
-typedef   signed long      intptr_t;
-typedef   signed long     ptrdiff_t;
+#include "stdint.h"
 
 /* those are commonly provided by sys/types.h */
 typedef unsigned int          dev_t;
diff --git a/tools/include/nolibc/stdint.h b/tools/include/nolibc/stdint.h
new file mode 100644 (file)
index 0000000..c1ce4f5
--- /dev/null
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * Standard definitions and types for NOLIBC
+ * Copyright (C) 2023 Vincent Dagonneau <v@vda.io>
+ */
+
+#ifndef _NOLIBC_STDINT_H
+#define _NOLIBC_STDINT_H
+
+typedef unsigned char       uint8_t;
+typedef   signed char        int8_t;
+typedef unsigned short     uint16_t;
+typedef   signed short      int16_t;
+typedef unsigned int       uint32_t;
+typedef   signed int        int32_t;
+typedef unsigned long long uint64_t;
+typedef   signed long long  int64_t;
+typedef unsigned long        size_t;
+typedef   signed long       ssize_t;
+typedef unsigned long     uintptr_t;
+typedef   signed long      intptr_t;
+typedef   signed long     ptrdiff_t;
+
+typedef   int8_t       int_least8_t;
+typedef  uint8_t      uint_least8_t;
+typedef  int16_t      int_least16_t;
+typedef uint16_t     uint_least16_t;
+typedef  int32_t      int_least32_t;
+typedef uint32_t     uint_least32_t;
+typedef  int64_t      int_least64_t;
+typedef uint64_t     uint_least64_t;
+
+typedef   int8_t        int_fast8_t;
+typedef  uint8_t       uint_fast8_t;
+typedef  ssize_t       int_fast16_t;
+typedef   size_t      uint_fast16_t;
+typedef  ssize_t       int_fast32_t;
+typedef   size_t      uint_fast32_t;
+typedef  ssize_t       int_fast64_t;
+typedef   size_t      uint_fast64_t;
+
+typedef  int64_t           intmax_t;
+typedef uint64_t          uintmax_t;
+
+/* limits of integral types */
+
+#define        INT8_MIN  (-128)
+#define       INT16_MIN  (-32767-1)
+#define       INT32_MIN  (-2147483647-1)
+#define       INT64_MIN  (-9223372036854775807LL-1)
+
+#define        INT8_MAX  (127)
+#define       INT16_MAX  (32767)
+#define       INT32_MAX  (2147483647)
+#define       INT64_MAX  (9223372036854775807LL)
+
+#define       UINT8_MAX  (255)
+#define      UINT16_MAX  (65535)
+#define      UINT32_MAX  (4294967295U)
+#define      UINT64_MAX  (18446744073709551615ULL)
+
+#define  INT_LEAST8_MIN  INT8_MIN
+#define INT_LEAST16_MIN  INT16_MIN
+#define INT_LEAST32_MIN  INT32_MIN
+#define INT_LEAST64_MIN  INT64_MIN
+
+#define  INT_LEAST8_MAX  INT8_MAX
+#define INT_LEAST16_MAX  INT16_MAX
+#define INT_LEAST32_MAX  INT32_MAX
+#define INT_LEAST64_MAX  INT64_MAX
+
+#define  UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+#define SIZE_MAX         ((size_t)(__LONG_MAX__) * 2 + 1)
+#define INTPTR_MIN       (-__LONG_MAX__ - 1)
+#define INTPTR_MAX       __LONG_MAX__
+#define PTRDIFF_MIN      INTPTR_MIN
+#define PTRDIFF_MAX      INTPTR_MAX
+#define UINTPTR_MAX      SIZE_MAX
+
+#define  INT_FAST8_MIN   INT8_MIN
+#define INT_FAST16_MIN   INTPTR_MIN
+#define INT_FAST32_MIN   INTPTR_MIN
+#define INT_FAST64_MIN   INTPTR_MIN
+
+#define  INT_FAST8_MAX   INT8_MAX
+#define INT_FAST16_MAX   INTPTR_MAX
+#define INT_FAST32_MAX   INTPTR_MAX
+#define INT_FAST64_MAX   INTPTR_MAX
+
+#define  UINT_FAST8_MAX  UINT8_MAX
+#define UINT_FAST16_MAX  SIZE_MAX
+#define UINT_FAST32_MAX  SIZE_MAX
+#define UINT_FAST64_MAX  SIZE_MAX
+
+#endif /* _NOLIBC_STDINT_H */
index 96ac8afc5aeedc047eafaa46fb1a5b024865ca9f..6cbbb52836a00f74286a900196c962ccaec333db 100644 (file)
@@ -273,6 +273,12 @@ int vfprintf(FILE *stream, const char *fmt, va_list args)
        return written;
 }
 
+static __attribute__((unused))
+int vprintf(const char *fmt, va_list args)
+{
+       return vfprintf(stdout, fmt, args);
+}
+
 static __attribute__((unused, format(printf, 2, 3)))
 int fprintf(FILE *stream, const char *fmt, ...)
 {
index b5f8cd35c03be1dc42828f3ea422d47c3fbb94af..5d624dc63a424c3eef1e1099772c645fd80b6b7b 100644 (file)
@@ -11,7 +11,6 @@
 #include "std.h"
 
 /* system includes */
-#include <asm/fcntl.h>   // for O_*
 #include <asm/unistd.h>
 #include <asm/signal.h>  // for SIGCHLD
 #include <asm/ioctls.h>
@@ -20,6 +19,8 @@
 #include <linux/loop.h>
 #include <linux/time.h>
 #include <linux/auxvec.h>
+#include <linux/fcntl.h> // for O_* and AT_*
+#include <linux/stat.h>  // for statx()
 
 #include "arch.h"
 #include "errno.h"
@@ -410,6 +411,27 @@ int getdents64(int fd, struct linux_dirent64 *dirp, int count)
 }
 
 
+/*
+ * uid_t geteuid(void);
+ */
+
+static __attribute__((unused))
+uid_t sys_geteuid(void)
+{
+#ifdef __NR_geteuid32
+       return my_syscall0(__NR_geteuid32);
+#else
+       return my_syscall0(__NR_geteuid);
+#endif
+}
+
+static __attribute__((unused))
+uid_t geteuid(void)
+{
+       return sys_geteuid();
+}
+
+
 /*
  * pid_t getpgid(pid_t pid);
  */
@@ -544,6 +566,27 @@ int gettimeofday(struct timeval *tv, struct timezone *tz)
 }
 
 
+/*
+ * uid_t getuid(void);
+ */
+
+static __attribute__((unused))
+uid_t sys_getuid(void)
+{
+#ifdef __NR_getuid32
+       return my_syscall0(__NR_getuid32);
+#else
+       return my_syscall0(__NR_getuid);
+#endif
+}
+
+static __attribute__((unused))
+uid_t getuid(void)
+{
+       return sys_getuid();
+}
+
+
 /*
  * int ioctl(int fd, unsigned long req, void *value);
  */
@@ -1048,12 +1091,66 @@ pid_t setsid(void)
        return ret;
 }
 
+#if defined(__NR_statx)
+/*
+ * int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf);
+ */
+
+static __attribute__((unused))
+int sys_statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)
+{
+       return my_syscall5(__NR_statx, fd, path, flags, mask, buf);
+}
+
+static __attribute__((unused))
+int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)
+{
+       int ret = sys_statx(fd, path, flags, mask, buf);
+
+       if (ret < 0) {
+               SET_ERRNO(-ret);
+               ret = -1;
+       }
+       return ret;
+}
+#endif
 
 /*
  * int stat(const char *path, struct stat *buf);
  * Warning: the struct stat's layout is arch-dependent.
  */
 
+#if defined(__NR_statx) && !defined(__NR_newfstatat) && !defined(__NR_stat)
+/*
+ * Maybe we can just use statx() when available for all architectures?
+ */
+static __attribute__((unused))
+int sys_stat(const char *path, struct stat *buf)
+{
+       struct statx statx;
+       long ret;
+
+       ret = sys_statx(AT_FDCWD, path, AT_NO_AUTOMOUNT, STATX_BASIC_STATS, &statx);
+       buf->st_dev     = ((statx.stx_dev_minor & 0xff)
+                         | (statx.stx_dev_major << 8)
+                         | ((statx.stx_dev_minor & ~0xff) << 12));
+       buf->st_ino     = statx.stx_ino;
+       buf->st_mode    = statx.stx_mode;
+       buf->st_nlink   = statx.stx_nlink;
+       buf->st_uid     = statx.stx_uid;
+       buf->st_gid     = statx.stx_gid;
+       buf->st_rdev    = ((statx.stx_rdev_minor & 0xff)
+                         | (statx.stx_rdev_major << 8)
+                         | ((statx.stx_rdev_minor & ~0xff) << 12));
+       buf->st_size    = statx.stx_size;
+       buf->st_blksize = statx.stx_blksize;
+       buf->st_blocks  = statx.stx_blocks;
+       buf->st_atime   = statx.stx_atime.tv_sec;
+       buf->st_mtime   = statx.stx_mtime.tv_sec;
+       buf->st_ctime   = statx.stx_ctime.tv_sec;
+       return ret;
+}
+#else
 static __attribute__((unused))
 int sys_stat(const char *path, struct stat *buf)
 {
@@ -1083,6 +1180,7 @@ int sys_stat(const char *path, struct stat *buf)
        buf->st_ctime   = stat.st_ctime;
        return ret;
 }
+#endif
 
 static __attribute__((unused))
 int stat(const char *path, struct stat *buf)
index fbbc0e68c001b053a8d75f3d3bcfa3c7aaa2ab60..aedd7d9e3f64405be2ad1562092c4b7ea852363a 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "std.h"
 #include <linux/time.h>
+#include <linux/stat.h>
 
 
 /* Only the generic macros and types may be defined here. The arch-specific
  * the layout of sys_stat_struct must not be defined here.
  */
 
-/* stat flags (WARNING, octal here) */
+/* stat flags (WARNING, octal here). We need to check for an existing
+ * definition because linux/stat.h may omit to define those if it finds
+ * that any glibc header was already included.
+ */
+#if !defined(S_IFMT)
 #define S_IFDIR        0040000
 #define S_IFCHR        0020000
 #define S_IFBLK        0060000
 #define S_ISLNK(mode)  (((mode) & S_IFMT) == S_IFLNK)
 #define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
 
+#define S_IRWXU 00700
+#define S_IRUSR 00400
+#define S_IWUSR 00200
+#define S_IXUSR 00100
+
+#define S_IRWXG 00070
+#define S_IRGRP 00040
+#define S_IWGRP 00020
+#define S_IXGRP 00010
+
+#define S_IRWXO 00007
+#define S_IROTH 00004
+#define S_IWOTH 00002
+#define S_IXOTH 00001
+#endif
+
 /* dirent types */
 #define DT_UNKNOWN     0x0
 #define DT_FIFO        0x1
 #define MAXPATHLEN     (PATH_MAX)
 #endif
 
-/* Special FD used by all the *at functions */
-#ifndef AT_FDCWD
-#define AT_FDCWD       (-100)
-#endif
-
 /* whence values for lseek() */
 #define SEEK_SET       0
 #define SEEK_CUR       1
@@ -81,6 +97,8 @@
 /* Macros used on waitpid()'s return status */
 #define WEXITSTATUS(status) (((status) & 0xff00) >> 8)
 #define WIFEXITED(status)   (((status) & 0x7f) == 0)
+#define WTERMSIG(status)    ((status) & 0x7f)
+#define WIFSIGNALED(status) ((status) - 1 < 0xff)
 
 /* waitpid() flags */
 #define WNOHANG      1
index 1cfcd52106a420afc327ef8403afdd73da0efb10..ac7d53d986cd11ac84dd0a17e5a7055c779b2b10 100644 (file)
 #include "sys.h"
 
 
+#define STDIN_FILENO  0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+
 static __attribute__((unused))
 int msleep(unsigned int msecs)
 {
index b02c8e0f405757b4f62bf038ae199c8a9decfa68..1c7a0f6632c09e3368dc8b5d15cfc708e5c8cef0 100644 (file)
@@ -91,7 +91,6 @@
 
 /* a horrid kludge trying to make sure that this will fail on old kernels */
 #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
-#define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT)      
 
 #ifndef O_NDELAY
 #define O_NDELAY       O_NONBLOCK
index 2f86b2ad6d7e9d6bd7478c369dc301899a37a791..e8c07da58c9f20ed3b7b4aa886f964d335fa41d2 100644 (file)
@@ -43,6 +43,7 @@
 #define F_SEAL_GROW    0x0004  /* prevent file from growing */
 #define F_SEAL_WRITE   0x0008  /* prevent writes */
 #define F_SEAL_FUTURE_WRITE    0x0010  /* prevent future writes while mapped */
+#define F_SEAL_EXEC    0x0020  /* prevent chmod modifying exec bits */
 /* (1U << 31) is reserved for signed error codes */
 
 /*
index 55155e262646e5fc48b6317054b07b1c15aad02a..d77aef872a0a07e767b2bddad095a250a9da1e65 100644 (file)
@@ -583,6 +583,8 @@ struct kvm_s390_mem_op {
                struct {
                        __u8 ar;        /* the access register number */
                        __u8 key;       /* access key, ignored if flag unset */
+                       __u8 pad1[6];   /* ignored */
+                       __u64 old_addr; /* ignored if cmpxchg flag unset */
                };
                __u32 sida_offset; /* offset into the sida */
                __u8 reserved[32]; /* ignored */
@@ -595,11 +597,17 @@ struct kvm_s390_mem_op {
 #define KVM_S390_MEMOP_SIDA_WRITE      3
 #define KVM_S390_MEMOP_ABSOLUTE_READ   4
 #define KVM_S390_MEMOP_ABSOLUTE_WRITE  5
+#define KVM_S390_MEMOP_ABSOLUTE_CMPXCHG        6
+
 /* flags for kvm_s390_mem_op->flags */
 #define KVM_S390_MEMOP_F_CHECK_ONLY            (1ULL << 0)
 #define KVM_S390_MEMOP_F_INJECT_EXCEPTION      (1ULL << 1)
 #define KVM_S390_MEMOP_F_SKEY_PROTECTION       (1ULL << 2)
 
+/* flags specifying extension support via KVM_CAP_S390_MEM_OP_EXTENSION */
+#define KVM_S390_MEMOP_EXTENSION_CAP_BASE      (1 << 0)
+#define KVM_S390_MEMOP_EXTENSION_CAP_CMPXCHG   (1 << 1)
+
 /* for KVM_INTERRUPT */
 struct kvm_interrupt {
        /* in */
@@ -1175,6 +1183,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_DIRTY_LOG_RING_ACQ_REL 223
 #define KVM_CAP_S390_PROTECTED_ASYNC_DISABLE 224
 #define KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP 225
+#define KVM_CAP_PMU_EVENT_MASKED_EVENTS 226
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
index 588391447bfb09d260448c5c63f8bd3ba0521a52..639524b59930bfcabcd0d352048a3fd4aa1da08b 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
 /* Do not edit directly, auto-generated from: */
 /*     Documentation/netlink/specs/netdev.yaml */
 /* YNL-GEN uapi header */
@@ -33,6 +33,8 @@ enum netdev_xdp_act {
        NETDEV_XDP_ACT_HW_OFFLOAD = 16,
        NETDEV_XDP_ACT_RX_SG = 32,
        NETDEV_XDP_ACT_NDO_XMIT_SG = 64,
+
+       NETDEV_XDP_ACT_MASK = 127,
 };
 
 enum {
index ccb7f5dad59be96b2cba0011717759ff8e67c640..37675437b76860ae4c3bef6a35e0eded9c25d55b 100644 (file)
@@ -374,6 +374,7 @@ enum perf_event_read_format {
 #define PERF_ATTR_SIZE_VER5    112     /* add: aux_watermark */
 #define PERF_ATTR_SIZE_VER6    120     /* add: aux_sample_size */
 #define PERF_ATTR_SIZE_VER7    128     /* add: sig_data */
+#define PERF_ATTR_SIZE_VER8    136     /* add: config3 */
 
 /*
  * Hardware event_id to monitor via a performance monitoring event:
@@ -515,6 +516,8 @@ struct perf_event_attr {
         * truncated accordingly on 32 bit architectures.
         */
        __u64   sig_data;
+
+       __u64   config3; /* extension of config2 */
 };
 
 /*
index a5e06dcbba136d618c6dcf61f0cbb6e3bfe9ea2c..1312a137f7fb85e1b042139f7762b3bb9775fa8e 100644 (file)
@@ -281,6 +281,12 @@ struct prctl_mm_map {
 # define PR_SME_VL_LEN_MASK            0xffff
 # define PR_SME_VL_INHERIT             (1 << 17) /* inherit across exec */
 
+/* Memory deny write / execute */
+#define PR_SET_MDWE                    65
+# define PR_MDWE_REFUSE_EXEC_GAIN      1
+
+#define PR_GET_MDWE                    66
+
 #define PR_SET_VMA             0x53564d41
 # define PR_SET_VMA_ANON_NAME          0
 
index f9f115a7c75b8a3060f0678599e7662d0015b878..92e1b700b51cbdf66aed6b3d17bc32688cd4706b 100644 (file)
  */
 #define VHOST_VDPA_SUSPEND             _IO(VHOST_VIRTIO, 0x7D)
 
+/* Resume a device so it can resume processing virtqueue requests
+ *
+ * After the return of this ioctl the device will have restored all the
+ * necessary states and it is fully operational to continue processing the
+ * virtqueue descriptors.
+ */
+#define VHOST_VDPA_RESUME              _IO(VHOST_VIRTIO, 0x7E)
+
 #endif
index 6d005a1f5d9425d5a2cf2199271f55bb32bcc87c..388b212088ea6a38383918d9d46b82321b11c3d3 100644 (file)
@@ -5,5 +5,6 @@
 #include <vdso/const.h>
 
 #define BIT(nr)                        (UL(1) << (nr))
+#define BIT_ULL(nr)            (ULL(1) << (nr))
 
 #endif /* __VDSO_BITS_H */
index fbaf683353945d11b9c82a6577729c1e41eab93c..e4d05662a96ce38ba029f85960ff896046a22976 100644 (file)
@@ -20,8 +20,8 @@
 /* make sure libbpf doesn't use kernel-only integer typedefs */
 #pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
 
-/* prevent accidental re-addition of reallocarray()/strlcpy() */
-#pragma GCC poison reallocarray strlcpy
+/* prevent accidental re-addition of reallocarray() */
+#pragma GCC poison reallocarray
 
 #include "libbpf.h"
 #include "btf.h"
index 8e708523847094aac15c9f0e1971bb2ae2ce97bf..6dc8b3642458e5dcb64090b63ed9050517e32014 100644 (file)
@@ -28,9 +28,10 @@ Explanation of the Linux-Kernel Memory Consistency Model
   20. THE HAPPENS-BEFORE RELATION: hb
   21. THE PROPAGATES-BEFORE RELATION: pb
   22. RCU RELATIONS: rcu-link, rcu-gp, rcu-rscsi, rcu-order, rcu-fence, and rb
-  23. LOCKING
-  24. PLAIN ACCESSES AND DATA RACES
-  25. ODDS AND ENDS
+  23. SRCU READ-SIDE CRITICAL SECTIONS
+  24. LOCKING
+  25. PLAIN ACCESSES AND DATA RACES
+  26. ODDS AND ENDS
 
 
 
@@ -1848,14 +1849,169 @@ section in P0 both starts before P1's grace period does and ends
 before it does, and the critical section in P2 both starts after P1's
 grace period does and ends after it does.
 
-Addendum: The LKMM now supports SRCU (Sleepable Read-Copy-Update) in
-addition to normal RCU.  The ideas involved are much the same as
-above, with new relations srcu-gp and srcu-rscsi added to represent
-SRCU grace periods and read-side critical sections.  There is a
-restriction on the srcu-gp and srcu-rscsi links that can appear in an
-rcu-order sequence (the srcu-rscsi links must be paired with srcu-gp
-links having the same SRCU domain with proper nesting); the details
-are relatively unimportant.
+The LKMM supports SRCU (Sleepable Read-Copy-Update) in addition to
+normal RCU.  The ideas involved are much the same as above, with new
+relations srcu-gp and srcu-rscsi added to represent SRCU grace periods
+and read-side critical sections.  However, there are some significant
+differences between RCU read-side critical sections and their SRCU
+counterparts, as described in the next section.
+
+
+SRCU READ-SIDE CRITICAL SECTIONS
+--------------------------------
+
+The LKMM uses the srcu-rscsi relation to model SRCU read-side critical
+sections.  They differ from RCU read-side critical sections in the
+following respects:
+
+1.     Unlike the analogous RCU primitives, synchronize_srcu(),
+       srcu_read_lock(), and srcu_read_unlock() take a pointer to a
+       struct srcu_struct as an argument.  This structure is called
+       an SRCU domain, and calls linked by srcu-rscsi must have the
+       same domain.  Read-side critical sections and grace periods
+       associated with different domains are independent of one
+       another; the SRCU version of the RCU Guarantee applies only
+       to pairs of critical sections and grace periods having the
+       same domain.
+
+2.     srcu_read_lock() returns a value, called the index, which must
+       be passed to the matching srcu_read_unlock() call.  Unlike
+       rcu_read_lock() and rcu_read_unlock(), an srcu_read_lock()
+       call does not always have to match the next unpaired
+       srcu_read_unlock().  In fact, it is possible for two SRCU
+       read-side critical sections to overlap partially, as in the
+       following example (where s is an srcu_struct and idx1 and idx2
+       are integer variables):
+
+               idx1 = srcu_read_lock(&s);      // Start of first RSCS
+               idx2 = srcu_read_lock(&s);      // Start of second RSCS
+               srcu_read_unlock(&s, idx1);     // End of first RSCS
+               srcu_read_unlock(&s, idx2);     // End of second RSCS
+
+       The matching is determined entirely by the domain pointer and
+       index value.  By contrast, if the calls had been
+       rcu_read_lock() and rcu_read_unlock() then they would have
+       created two nested (fully overlapping) read-side critical
+       sections: an inner one and an outer one.
+
+3.     The srcu_down_read() and srcu_up_read() primitives work
+       exactly like srcu_read_lock() and srcu_read_unlock(), except
+       that matching calls don't have to execute on the same CPU.
+       (The names are meant to be suggestive of operations on
+       semaphores.)  Since the matching is determined by the domain
+       pointer and index value, these primitives make it possible for
+       an SRCU read-side critical section to start on one CPU and end
+       on another, so to speak.
+
+In order to account for these properties of SRCU, the LKMM models
+srcu_read_lock() as a special type of load event (which is
+appropriate, since it takes a memory location as argument and returns
+a value, just as a load does) and srcu_read_unlock() as a special type
+of store event (again appropriate, since it takes as arguments a
+memory location and a value).  These loads and stores are annotated as
+belonging to the "srcu-lock" and "srcu-unlock" event classes
+respectively.
+
+This approach allows the LKMM to tell whether two events are
+associated with the same SRCU domain, simply by checking whether they
+access the same memory location (i.e., they are linked by the loc
+relation).  It also gives a way to tell which unlock matches a
+particular lock, by checking for the presence of a data dependency
+from the load (srcu-lock) to the store (srcu-unlock).  For example,
+given the situation outlined earlier (with statement labels added):
+
+       A: idx1 = srcu_read_lock(&s);
+       B: idx2 = srcu_read_lock(&s);
+       C: srcu_read_unlock(&s, idx1);
+       D: srcu_read_unlock(&s, idx2);
+
+the LKMM will treat A and B as loads from s yielding values saved in
+idx1 and idx2 respectively.  Similarly, it will treat C and D as
+though they stored the values from idx1 and idx2 in s.  The end result
+is much as if we had written:
+
+       A: idx1 = READ_ONCE(s);
+       B: idx2 = READ_ONCE(s);
+       C: WRITE_ONCE(s, idx1);
+       D: WRITE_ONCE(s, idx2);
+
+except for the presence of the special srcu-lock and srcu-unlock
+annotations.  You can see at once that we have A ->data C and
+B ->data D.  These dependencies tell the LKMM that C is the
+srcu-unlock event matching srcu-lock event A, and D is the
+srcu-unlock event matching srcu-lock event B.
+
+This approach is admittedly a hack, and it has the potential to lead
+to problems.  For example, in:
+
+       idx1 = srcu_read_lock(&s);
+       srcu_read_unlock(&s, idx1);
+       idx2 = srcu_read_lock(&s);
+       srcu_read_unlock(&s, idx2);
+
+the LKMM will believe that idx2 must have the same value as idx1,
+since it reads from the immediately preceding store of idx1 in s.
+Fortunately this won't matter, assuming that litmus tests never do
+anything with SRCU index values other than pass them to
+srcu_read_unlock() or srcu_up_read() calls.
+
+However, sometimes it is necessary to store an index value in a
+shared variable temporarily.  In fact, this is the only way for
+srcu_down_read() to pass the index it gets to an srcu_up_read() call
+on a different CPU.  In more detail, we might have soething like:
+
+       struct srcu_struct s;
+       int x;
+
+       P0()
+       {
+               int r0;
+
+               A: r0 = srcu_down_read(&s);
+               B: WRITE_ONCE(x, r0);
+       }
+
+       P1()
+       {
+               int r1;
+
+               C: r1 = READ_ONCE(x);
+               D: srcu_up_read(&s, r1);
+       }
+
+Assuming that P1 executes after P0 and does read the index value
+stored in x, we can write this (using brackets to represent event
+annotations) as:
+
+       A[srcu-lock] ->data B[once] ->rf C[once] ->data D[srcu-unlock].
+
+The LKMM defines a carry-srcu-data relation to express this pattern;
+it permits an arbitrarily long sequence of
+
+       data ; rf
+
+pairs (that is, a data link followed by an rf link) to occur between
+an srcu-lock event and the final data dependency leading to the
+matching srcu-unlock event.  carry-srcu-data is complicated by the
+need to ensure that none of the intermediate store events in this
+sequence are instances of srcu-unlock.  This is necessary because in a
+pattern like the one above:
+
+       A: idx1 = srcu_read_lock(&s);
+       B: srcu_read_unlock(&s, idx1);
+       C: idx2 = srcu_read_lock(&s);
+       D: srcu_read_unlock(&s, idx2);
+
+the LKMM treats B as a store to the variable s and C as a load from
+that variable, creating an undesirable rf link from B to C:
+
+       A ->data B ->rf C ->data D.
+
+This would cause carry-srcu-data to mistakenly extend a data
+dependency from A to D, giving the impression that D was the
+srcu-unlock event matching A's srcu-lock.  To avoid such problems,
+carry-srcu-data does not accept sequences in which the ends of any of
+the intermediate ->data links (B above) is an srcu-unlock event.
 
 
 LOCKING
index 26554b1c5575e086578d1af42318bc461cb3587c..acac527328a1f092dc8aea877444020394153caa 100644 (file)
@@ -1028,32 +1028,7 @@ Limitations of the Linux-kernel memory model (LKMM) include:
                additional call_rcu() process to the site of the
                emulated rcu-barrier().
 
-       e.      Although sleepable RCU (SRCU) is now modeled, there
-               are some subtle differences between its semantics and
-               those in the Linux kernel.  For example, the kernel
-               might interpret the following sequence as two partially
-               overlapping SRCU read-side critical sections:
-
-                        1  r1 = srcu_read_lock(&my_srcu);
-                        2  do_something_1();
-                        3  r2 = srcu_read_lock(&my_srcu);
-                        4  do_something_2();
-                        5  srcu_read_unlock(&my_srcu, r1);
-                        6  do_something_3();
-                        7  srcu_read_unlock(&my_srcu, r2);
-
-               In contrast, LKMM will interpret this as a nested pair of
-               SRCU read-side critical sections, with the outer critical
-               section spanning lines 1-7 and the inner critical section
-               spanning lines 3-5.
-
-               This difference would be more of a concern had anyone
-               identified a reasonable use case for partially overlapping
-               SRCU read-side critical sections.  For more information
-               on the trickiness of such overlapping, please see:
-               https://paulmck.livejournal.com/40593.html
-
-       f.      Reader-writer locking is not modeled.  It can be
+       e.      Reader-writer locking is not modeled.  It can be
                emulated in litmus tests using atomic read-modify-write
                operations.
 
diff --git a/tools/memory-model/Documentation/locking.txt b/tools/memory-model/Documentation/locking.txt
new file mode 100644 (file)
index 0000000..65c898c
--- /dev/null
@@ -0,0 +1,298 @@
+Locking
+=======
+
+Locking is well-known and the common use cases are straightforward: Any
+CPU holding a given lock sees any changes previously seen or made by any
+CPU before it previously released that same lock.  This last sentence
+is the only part of this document that most developers will need to read.
+
+However, developers who would like to also access lock-protected shared
+variables outside of their corresponding locks should continue reading.
+
+
+Locking and Prior Accesses
+--------------------------
+
+The basic rule of locking is worth repeating:
+
+       Any CPU holding a given lock sees any changes previously seen
+       or made by any CPU before it previously released that same lock.
+
+Note that this statement is a bit stronger than "Any CPU holding a
+given lock sees all changes made by any CPU during the time that CPU was
+previously holding this same lock".  For example, consider the following
+pair of code fragments:
+
+       /* See MP+polocks.litmus. */
+       void CPU0(void)
+       {
+               WRITE_ONCE(x, 1);
+               spin_lock(&mylock);
+               WRITE_ONCE(y, 1);
+               spin_unlock(&mylock);
+       }
+
+       void CPU1(void)
+       {
+               spin_lock(&mylock);
+               r0 = READ_ONCE(y);
+               spin_unlock(&mylock);
+               r1 = READ_ONCE(x);
+       }
+
+The basic rule guarantees that if CPU0() acquires mylock before CPU1(),
+then both r0 and r1 must be set to the value 1.  This also has the
+consequence that if the final value of r0 is equal to 1, then the final
+value of r1 must also be equal to 1.  In contrast, the weaker rule would
+say nothing about the final value of r1.
+
+
+Locking and Subsequent Accesses
+-------------------------------
+
+The converse to the basic rule also holds:  Any CPU holding a given
+lock will not see any changes that will be made by any CPU after it
+subsequently acquires this same lock.  This converse statement is
+illustrated by the following litmus test:
+
+       /* See MP+porevlocks.litmus. */
+       void CPU0(void)
+       {
+               r0 = READ_ONCE(y);
+               spin_lock(&mylock);
+               r1 = READ_ONCE(x);
+               spin_unlock(&mylock);
+       }
+
+       void CPU1(void)
+       {
+               spin_lock(&mylock);
+               WRITE_ONCE(x, 1);
+               spin_unlock(&mylock);
+               WRITE_ONCE(y, 1);
+       }
+
+This converse to the basic rule guarantees that if CPU0() acquires
+mylock before CPU1(), then both r0 and r1 must be set to the value 0.
+This also has the consequence that if the final value of r1 is equal
+to 0, then the final value of r0 must also be equal to 0.  In contrast,
+the weaker rule would say nothing about the final value of r0.
+
+These examples show only a single pair of CPUs, but the effects of the
+locking basic rule extend across multiple acquisitions of a given lock
+across multiple CPUs.
+
+
+Double-Checked Locking
+----------------------
+
+It is well known that more than just a lock is required to make
+double-checked locking work correctly,  This litmus test illustrates
+one incorrect approach:
+
+       /* See Documentation/litmus-tests/locking/DCL-broken.litmus. */
+       void CPU0(void)
+       {
+               r0 = READ_ONCE(flag);
+               if (r0 == 0) {
+                       spin_lock(&lck);
+                       r1 = READ_ONCE(flag);
+                       if (r1 == 0) {
+                               WRITE_ONCE(data, 1);
+                               WRITE_ONCE(flag, 1);
+                       }
+                       spin_unlock(&lck);
+               }
+               r2 = READ_ONCE(data);
+       }
+       /* CPU1() is the exactly the same as CPU0(). */
+
+There are two problems.  First, there is no ordering between the first
+READ_ONCE() of "flag" and the READ_ONCE() of "data".  Second, there is
+no ordering between the two WRITE_ONCE() calls.  It should therefore be
+no surprise that "r2" can be zero, and a quick herd7 run confirms this.
+
+One way to fix this is to use smp_load_acquire() and smp_store_release()
+as shown in this corrected version:
+
+       /* See Documentation/litmus-tests/locking/DCL-fixed.litmus. */
+       void CPU0(void)
+       {
+               r0 = smp_load_acquire(&flag);
+               if (r0 == 0) {
+                       spin_lock(&lck);
+                       r1 = READ_ONCE(flag);
+                       if (r1 == 0) {
+                               WRITE_ONCE(data, 1);
+                               smp_store_release(&flag, 1);
+                       }
+                       spin_unlock(&lck);
+               }
+               r2 = READ_ONCE(data);
+       }
+       /* CPU1() is the exactly the same as CPU0(). */
+
+The smp_load_acquire() guarantees that its load from "flags" will
+be ordered before the READ_ONCE() from data, thus solving the first
+problem.  The smp_store_release() guarantees that its store will be
+ordered after the WRITE_ONCE() to "data", solving the second problem.
+The smp_store_release() pairs with the smp_load_acquire(), thus ensuring
+that the ordering provided by each actually takes effect.  Again, a
+quick herd7 run confirms this.
+
+In short, if you access a lock-protected variable without holding the
+corresponding lock, you will need to provide additional ordering, in
+this case, via the smp_load_acquire() and the smp_store_release().
+
+
+Ordering Provided by a Lock to CPUs Not Holding That Lock
+---------------------------------------------------------
+
+It is not necessarily the case that accesses ordered by locking will be
+seen as ordered by CPUs not holding that lock.  Consider this example:
+
+       /* See Z6.0+pooncelock+pooncelock+pombonce.litmus. */
+       void CPU0(void)
+       {
+               spin_lock(&mylock);
+               WRITE_ONCE(x, 1);
+               WRITE_ONCE(y, 1);
+               spin_unlock(&mylock);
+       }
+
+       void CPU1(void)
+       {
+               spin_lock(&mylock);
+               r0 = READ_ONCE(y);
+               WRITE_ONCE(z, 1);
+               spin_unlock(&mylock);
+       }
+
+       void CPU2(void)
+       {
+               WRITE_ONCE(z, 2);
+               smp_mb();
+               r1 = READ_ONCE(x);
+       }
+
+Counter-intuitive though it might be, it is quite possible to have
+the final value of r0 be 1, the final value of z be 2, and the final
+value of r1 be 0.  The reason for this surprising outcome is that CPU2()
+never acquired the lock, and thus did not fully benefit from the lock's
+ordering properties.
+
+Ordering can be extended to CPUs not holding the lock by careful use
+of smp_mb__after_spinlock():
+
+       /* See Z6.0+pooncelock+poonceLock+pombonce.litmus. */
+       void CPU0(void)
+       {
+               spin_lock(&mylock);
+               WRITE_ONCE(x, 1);
+               WRITE_ONCE(y, 1);
+               spin_unlock(&mylock);
+       }
+
+       void CPU1(void)
+       {
+               spin_lock(&mylock);
+               smp_mb__after_spinlock();
+               r0 = READ_ONCE(y);
+               WRITE_ONCE(z, 1);
+               spin_unlock(&mylock);
+       }
+
+       void CPU2(void)
+       {
+               WRITE_ONCE(z, 2);
+               smp_mb();
+               r1 = READ_ONCE(x);
+       }
+
+This addition of smp_mb__after_spinlock() strengthens the lock
+acquisition sufficiently to rule out the counter-intuitive outcome.
+In other words, the addition of the smp_mb__after_spinlock() prohibits
+the counter-intuitive result where the final value of r0 is 1, the final
+value of z is 2, and the final value of r1 is 0.
+
+
+No Roach-Motel Locking!
+-----------------------
+
+This example requires familiarity with the herd7 "filter" clause, so
+please read up on that topic in litmus-tests.txt.
+
+It is tempting to allow memory-reference instructions to be pulled
+into a critical section, but this cannot be allowed in the general case.
+For example, consider a spin loop preceding a lock-based critical section.
+Now, herd7 does not model spin loops, but we can emulate one with two
+loads, with a "filter" clause to constrain the first to return the
+initial value and the second to return the updated value, as shown below:
+
+       /* See Documentation/litmus-tests/locking/RM-fixed.litmus. */
+       void CPU0(void)
+       {
+               spin_lock(&lck);
+               r2 = atomic_inc_return(&y);
+               WRITE_ONCE(x, 1);
+               spin_unlock(&lck);
+       }
+
+       void CPU1(void)
+       {
+               r0 = READ_ONCE(x);
+               r1 = READ_ONCE(x);
+               spin_lock(&lck);
+               r2 = atomic_inc_return(&y);
+               spin_unlock(&lck);
+       }
+
+       filter (1:r0=0 /\ 1:r1=1)
+       exists (1:r2=1)
+
+The variable "x" is the control variable for the emulated spin loop.
+CPU0() sets it to "1" while holding the lock, and CPU1() emulates the
+spin loop by reading it twice, first into "1:r0" (which should get the
+initial value "0") and then into "1:r1" (which should get the updated
+value "1").
+
+The "filter" clause takes this into account, constraining "1:r0" to
+equal "0" and "1:r1" to equal 1.
+
+Then the "exists" clause checks to see if CPU1() acquired its lock first,
+which should not happen given the filter clause because CPU0() updates
+"x" while holding the lock.  And herd7 confirms this.
+
+But suppose that the compiler was permitted to reorder the spin loop
+into CPU1()'s critical section, like this:
+
+       /* See Documentation/litmus-tests/locking/RM-broken.litmus. */
+       void CPU0(void)
+       {
+               int r2;
+
+               spin_lock(&lck);
+               r2 = atomic_inc_return(&y);
+               WRITE_ONCE(x, 1);
+               spin_unlock(&lck);
+       }
+
+       void CPU1(void)
+       {
+               spin_lock(&lck);
+               r0 = READ_ONCE(x);
+               r1 = READ_ONCE(x);
+               r2 = atomic_inc_return(&y);
+               spin_unlock(&lck);
+       }
+
+       filter (1:r0=0 /\ 1:r1=1)
+       exists (1:r2=1)
+
+If "1:r0" is equal to "0", "1:r1" can never equal "1" because CPU0()
+cannot update "x" while CPU1() holds the lock.  And herd7 confirms this,
+showing zero executions matching the "filter" criteria.
+
+And this is why Linux-kernel lock and unlock primitives must prevent
+code from entering critical sections.  It is not sufficient to only
+prevent code from leaving them.
index 70a9073dec3e57a08faf6bb0b3d70dd11abc0138..ce068700939c559edc8c91b9a931a0feae82e159 100644 (file)
@@ -31,7 +31,8 @@ enum Barriers = 'wmb (*smp_wmb*) ||
                'before-atomic (*smp_mb__before_atomic*) ||
                'after-atomic (*smp_mb__after_atomic*) ||
                'after-spinlock (*smp_mb__after_spinlock*) ||
-               'after-unlock-lock (*smp_mb__after_unlock_lock*)
+               'after-unlock-lock (*smp_mb__after_unlock_lock*) ||
+               'after-srcu-read-unlock (*smp_mb__after_srcu_read_unlock*)
 instructions F[Barriers]
 
 (* SRCU *)
@@ -53,38 +54,31 @@ let rcu-rscs = let rec
        in matched
 
 (* Validate nesting *)
-flag ~empty Rcu-lock \ domain(rcu-rscs) as unbalanced-rcu-locking
-flag ~empty Rcu-unlock \ range(rcu-rscs) as unbalanced-rcu-locking
+flag ~empty Rcu-lock \ domain(rcu-rscs) as unmatched-rcu-lock
+flag ~empty Rcu-unlock \ range(rcu-rscs) as unmatched-rcu-unlock
 
 (* Compute matching pairs of nested Srcu-lock and Srcu-unlock *)
-let srcu-rscs = let rec
-           unmatched-locks = Srcu-lock \ domain(matched)
-       and unmatched-unlocks = Srcu-unlock \ range(matched)
-       and unmatched = unmatched-locks | unmatched-unlocks
-       and unmatched-po = ([unmatched] ; po ; [unmatched]) & loc
-       and unmatched-locks-to-unlocks =
-               ([unmatched-locks] ; po ; [unmatched-unlocks]) & loc
-       and matched = matched | (unmatched-locks-to-unlocks \
-               (unmatched-po ; unmatched-po))
-       in matched
+let carry-srcu-data = (data ; [~ Srcu-unlock] ; rf)*
+let srcu-rscs = ([Srcu-lock] ; carry-srcu-data ; data ; [Srcu-unlock]) & loc
 
 (* Validate nesting *)
-flag ~empty Srcu-lock \ domain(srcu-rscs) as unbalanced-srcu-locking
-flag ~empty Srcu-unlock \ range(srcu-rscs) as unbalanced-srcu-locking
+flag ~empty Srcu-lock \ domain(srcu-rscs) as unmatched-srcu-lock
+flag ~empty Srcu-unlock \ range(srcu-rscs) as unmatched-srcu-unlock
+flag ~empty (srcu-rscs^-1 ; srcu-rscs) \ id as multiple-srcu-matches
 
 (* Check for use of synchronize_srcu() inside an RCU critical section *)
 flag ~empty rcu-rscs & (po ; [Sync-srcu] ; po) as invalid-sleep
 
 (* Validate SRCU dynamic match *)
-flag ~empty different-values(srcu-rscs) as srcu-bad-nesting
+flag ~empty different-values(srcu-rscs) as srcu-bad-value-match
 
 (* Compute marked and plain memory accesses *)
 let Marked = (~M) | IW | Once | Release | Acquire | domain(rmw) | range(rmw) |
-               LKR | LKW | UL | LF | RL | RU
+               LKR | LKW | UL | LF | RL | RU | Srcu-lock | Srcu-unlock
 let Plain = M \ Marked
 
 (* Redefine dependencies to include those carried through plain accesses *)
-let carry-dep = (data ; rfi)*
+let carry-dep = (data ; [~ Srcu-unlock] ; rfi)*
 let addr = carry-dep ; addr
 let ctrl = carry-dep ; ctrl
 let data = carry-dep ; data
index 07f884f9b2bff045a68bfe17ca2c2a6d82d1cd71..adf3c4f412296269bb9f8127cd7e04f276479a57 100644 (file)
@@ -37,8 +37,20 @@ let mb = ([M] ; fencerel(Mb) ; [M]) |
        ([M] ; fencerel(Before-atomic) ; [RMW] ; po? ; [M]) |
        ([M] ; po? ; [RMW] ; fencerel(After-atomic) ; [M]) |
        ([M] ; po? ; [LKW] ; fencerel(After-spinlock) ; [M]) |
-       ([M] ; po ; [UL] ; (co | po) ; [LKW] ;
-               fencerel(After-unlock-lock) ; [M])
+(*
+ * Note: The po-unlock-lock-po relation only passes the lock to the direct
+ * successor, perhaps giving the impression that the ordering of the
+ * smp_mb__after_unlock_lock() fence only affects a single lock handover.
+ * However, in a longer sequence of lock handovers, the implicit
+ * A-cumulative release fences of lock-release ensure that any stores that
+ * propagate to one of the involved CPUs before it hands over the lock to
+ * the next CPU will also propagate to the final CPU handing over the lock
+ * to the CPU that executes the fence.  Therefore, all those stores are
+ * also affected by the fence.
+ *)
+       ([M] ; po-unlock-lock-po ;
+               [After-unlock-lock] ; po ; [M]) |
+       ([M] ; po? ; [Srcu-unlock] ; fencerel(After-srcu-read-unlock) ; [M])
 let gp = po ; [Sync-rcu | Sync-srcu] ; po?
 let strong-fence = mb | gp
 
@@ -69,8 +81,8 @@ let dep = addr | data
 let rwdep = (dep | ctrl) ; [W]
 let overwrite = co | fr
 let to-w = rwdep | (overwrite & int) | (addr ; [Plain] ; wmb)
-let to-r = addr | (dep ; [Marked] ; rfi)
-let ppo = to-r | to-w | fence | (po-unlock-lock-po & int)
+let to-r = (addr ; [R]) | (dep ; [Marked] ; rfi)
+let ppo = to-r | to-w | (fence & int) | (po-unlock-lock-po & int)
 
 (* Propagation: Ordering from release operations and strong fences. *)
 let A-cumul(r) = (rfe ; [Marked])? ; r
index ef0f3c1850dee2d212e0c69e8eb61e3b3b5b90e9..88a39601f52563b670876e3ef4950324dc66224a 100644 (file)
@@ -24,6 +24,7 @@ smp_mb__before_atomic() { __fence{before-atomic}; }
 smp_mb__after_atomic() { __fence{after-atomic}; }
 smp_mb__after_spinlock() { __fence{after-spinlock}; }
 smp_mb__after_unlock_lock() { __fence{after-unlock-lock}; }
+smp_mb__after_srcu_read_unlock() { __fence{after-srcu-read-unlock}; }
 barrier() { __fence{barrier}; }
 
 // Exchange
@@ -49,8 +50,10 @@ synchronize_rcu() { __fence{sync-rcu}; }
 synchronize_rcu_expedited() { __fence{sync-rcu}; }
 
 // SRCU
-srcu_read_lock(X)  __srcu{srcu-lock}(X)
-srcu_read_unlock(X,Y) { __srcu{srcu-unlock}(X,Y); }
+srcu_read_lock(X) __load{srcu-lock}(*X)
+srcu_read_unlock(X,Y) { __store{srcu-unlock}(*X,Y); }
+srcu_down_read(X) __load{srcu-lock}(*X)
+srcu_up_read(X,Y) { __store{srcu-unlock}(*X,Y); }
 synchronize_srcu(X)  { __srcu{sync-srcu}(X); }
 synchronize_srcu_expedited(X)  { __srcu{sync-srcu}(X); }
 
index c492a1ddad91d54a5b76e218a61a92d441ac8659..19c379cf069d2369db344673624a783834f9adce 100644 (file)
@@ -1,2 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
-*.litmus.out
+*.litmus.*
index 6b52f365d73ac4ab99fe1270871f308a51ad2d76..53b5a492739d03ac8d30adc081e075b7ef635bb8 100644 (file)
@@ -36,9 +36,9 @@ let RU = try RU with emptyset
 (* Treat RL as a kind of LF: a read with no ordering properties *)
 let LF = LF | RL
 
-(* There should be no ordinary R or W accesses to spinlocks *)
-let ALL-LOCKS = LKR | LKW | UL | LF | RU
-flag ~empty [M \ IW] ; loc ; [ALL-LOCKS] as mixed-lock-accesses
+(* There should be no ordinary R or W accesses to spinlocks or SRCU structs *)
+let ALL-LOCKS = LKR | LKW | UL | LF | RU | Srcu-lock | Srcu-unlock | Sync-srcu
+flag ~empty [M \ IW \ ALL-LOCKS] ; loc ; [ALL-LOCKS] as mixed-lock-accesses
 
 (* Link Lock-Reads to their RMW-partner Lock-Writes *)
 let lk-rmw = ([LKR] ; po-loc ; [LKW]) \ (po ; po)
index 095c7eb36f9f90a38c2acf50a49ec276fa02f097..fb39bd0fd1b9d2f8e099f83e8da36e8d63774e68 100644 (file)
@@ -27,6 +27,14 @@ checklitmushist.sh
 checklitmus.sh
 
        Check a single litmus test against its "Result:" expected result.
+       Not intended to for manual use.
+
+checktheselitmus.sh
+
+       Check the specified list of litmus tests against their "Result:"
+       expected results.  This takes optional parseargs.sh arguments,
+       followed by "--" followed by pathnames starting from the current
+       directory.
 
 cmplitmushist.sh
 
@@ -43,10 +51,10 @@ initlitmushist.sh
 
 judgelitmus.sh
 
-       Given a .litmus file and its .litmus.out herd7 output, check the
-       .litmus.out file against the .litmus file's "Result:" comment to
-       judge whether the test ran correctly.  Not normally run manually,
-       provided instead for use by other scripts.
+       Given a .litmus file and its herd7 output, check the output file
+       against the .litmus file's "Result:" comment to judge whether
+       the test ran correctly.  Not normally run manually, provided
+       instead for use by other scripts.
 
 newlitmushist.sh
 
@@ -68,3 +76,35 @@ runlitmushist.sh
 README
 
        This file
+
+Testing a change to LKMM might go as follows:
+
+       # Populate expected results without that change, and
+       # runs for about an hour on an 8-CPU x86 system:
+       scripts/initlitmushist.sh --timeout 10m --procs 10
+       # Incorporate the change:
+       git am -s -3 /path/to/patch # Or whatever it takes.
+
+       # Test the new version of LKMM as follows...
+
+       # Runs in seconds, good smoke test:
+       scripts/checkalllitmus.sh
+
+       # Compares results to those produced by initlitmushist.sh,
+       # and runs for about an hour on an 8-CPU x86 system:
+       scripts/checklitmushist.sh --timeout 10m --procs 10
+
+       # Checks results against Result tags, runs in minutes:
+       scripts/checkghlitmus.sh --timeout 10m --procs 10
+
+The checkghlitmus.sh should not report errors in cases where the
+checklitmushist.sh script did not also report a change.  However,
+this check is nevertheless valuable because it can find errors in the
+original version of LKMM.  Note however, that given the above procedure,
+an error in the original LKMM version that is fixed by the patch will
+be reported both as a mismatch by checklitmushist.sh and as an error
+by checkghlitmus.sh.  One exception to this rule of thumb is when the
+test fails completely on the original version of LKMM and passes on the
+new version.  In this case, checklitmushist.sh will report a mismatch
+and checkghlitmus.sh will report success.  This happens when the change
+to LKMM introduces a new primitive for which litmus tests already existed.
index 3c0c7fbbd223b77d173a070d167553edd350daec..2d3ee850a8399ee49f59342f2e13f0333c745f38 100755 (executable)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 # SPDX-License-Identifier: GPL-2.0+
 #
 # Run herd7 tests on all .litmus files in the litmus-tests directory
@@ -8,6 +8,11 @@
 # "^^^".  It also outputs verification results to a file whose name is
 # that of the specified litmus test, but with ".out" appended.
 #
+# If the --hw argument is specified, this script translates the .litmus
+# C-language file to the specified type of assembly and verifies that.
+# But in this case, litmus tests using complex synchronization (such as
+# locking, RCU, and SRCU) are cheerfully ignored.
+#
 # Usage:
 #      checkalllitmus.sh
 #
@@ -17,7 +22,7 @@
 #
 # Copyright IBM Corporation, 2018
 #
-# Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
 
 . scripts/parseargs.sh
 
@@ -30,29 +35,23 @@ else
        exit 255
 fi
 
-# Create any new directories that have appeared in the github litmus
-# repo since the last run.
+# Create any new directories that have appeared in the litmus-tests
+# directory since the last run.
 if test "$LKMM_DESTDIR" != "."
 then
        find $litmusdir -type d -print |
        ( cd "$LKMM_DESTDIR"; sed -e 's/^/mkdir -p /' | sh )
 fi
 
-# Find the checklitmus script.  If it is not where we expect it, then
-# assume that the caller has the PATH environment variable set
-# appropriately.
-if test -x scripts/checklitmus.sh
-then
-       clscript=scripts/checklitmus.sh
-else
-       clscript=checklitmus.sh
-fi
-
 # Run the script on all the litmus tests in the specified directory
 ret=0
 for i in $litmusdir/*.litmus
 do
-       if ! $clscript $i
+       if test -n "$LKMM_HW_MAP_FILE" && ! scripts/simpletest.sh $i
+       then
+               continue
+       fi
+       if ! scripts/checklitmus.sh $i
        then
                ret=1
        fi
index 6589fbb6f6538339c2a126288f75b8b476a3f0c3..d3dfb321259f223ef342733fe96dc65fa96d9624 100755 (executable)
@@ -10,6 +10,7 @@
 # parseargs.sh scripts for arguments.
 
 . scripts/parseargs.sh
+. scripts/hwfnseg.sh
 
 T=/tmp/checkghlitmus.sh.$$
 trap 'rm -rf $T' 0
@@ -32,19 +33,19 @@ then
        ( cd "$LKMM_DESTDIR"; sed -e 's/^/mkdir -p /' | sh )
 fi
 
-# Create a list of the C-language litmus tests previously run.
-( cd $LKMM_DESTDIR; find litmus -name '*.litmus.out' -print ) |
-       sed -e 's/\.out$//' |
-       xargs -r egrep -l '^ \* Result: (Never|Sometimes|Always|DEADLOCK)' |
+# Create a list of the specified litmus tests previously run.
+( cd $LKMM_DESTDIR; find litmus -name "*.litmus${hwfnseg}.out" -print ) |
+       sed -e "s/${hwfnseg}"'\.out$//' |
+       xargs -r grep -E -l '^ \* Result: (Never|Sometimes|Always|DEADLOCK)' |
        xargs -r grep -L "^P${LKMM_PROCS}"> $T/list-C-already
 
 # Create a list of C-language litmus tests with "Result:" commands and
 # no more than the specified number of processes.
-find litmus -name '*.litmus' -exec grep -l -m 1 "^C " {} \; > $T/list-C
-xargs < $T/list-C -r egrep -l '^ \* Result: (Never|Sometimes|Always|DEADLOCK)' > $T/list-C-result
+find litmus -name '*.litmus' -print | mselect7 -arch C > $T/list-C
+xargs < $T/list-C -r grep -E -l '^ \* Result: (Never|Sometimes|Always|DEADLOCK)' > $T/list-C-result
 xargs < $T/list-C-result -r grep -L "^P${LKMM_PROCS}" > $T/list-C-result-short
 
-# Form list of tests without corresponding .litmus.out files
+# Form list of tests without corresponding .out files
 sort $T/list-C-already $T/list-C-result-short | uniq -u > $T/list-C-needed
 
 # Run any needed tests.
index 11461ed40b5e456be0145e45d2ef4464895fed15..4c1d0cf0ddadcf93eb860c986167f013b354daf7 100755 (executable)
@@ -1,10 +1,8 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0+
 #
-# Run a herd7 test and invokes judgelitmus.sh to check the result against
-# a "Result:" comment within the litmus test.  It also outputs verification
-# results to a file whose name is that of the specified litmus test, but
-# with ".out" appended.
+# Invokes runlitmus.sh and judgelitmus.sh on its arguments to run the
+# specified litmus test and pass judgment on the results.
 #
 # Usage:
 #      checklitmus.sh file.litmus
 #
 # Copyright IBM Corporation, 2018
 #
-# Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
 
-litmus=$1
-herdoptions=${LKMM_HERD_OPTIONS--conf linux-kernel.cfg}
-
-if test -f "$litmus" -a -r "$litmus"
-then
-       :
-else
-       echo ' --- ' error: \"$litmus\" is not a readable file
-       exit 255
-fi
-
-echo Herd options: $herdoptions > $LKMM_DESTDIR/$litmus.out
-/usr/bin/time $LKMM_TIMEOUT_CMD herd7 $herdoptions $litmus >> $LKMM_DESTDIR/$litmus.out 2>&1
-
-scripts/judgelitmus.sh $litmus
+scripts/runlitmus.sh $1
+scripts/judgelitmus.sh $1
index 1d210ffb7c8af6084518eabcf073864f1fed6a27..406ecfc0aee4ca8654ae4ebf4b8b168dd5e25bb0 100755 (executable)
@@ -12,7 +12,7 @@
 #
 # Copyright IBM Corporation, 2018
 #
-# Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
 
 . scripts/parseargs.sh
 
diff --git a/tools/memory-model/scripts/checktheselitmus.sh b/tools/memory-model/scripts/checktheselitmus.sh
new file mode 100755 (executable)
index 0000000..10eeb5e
--- /dev/null
@@ -0,0 +1,43 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Invokes checklitmus.sh on its arguments to run the specified litmus
+# test and pass judgment on the results.
+#
+# Usage:
+#      checktheselitmus.sh -- [ file1.litmus [ file2.litmus ... ] ]
+#
+# Run this in the directory containing the memory model, specifying the
+# pathname of the litmus test to check.  The usual parseargs.sh arguments
+# can be specified prior to the "--".
+#
+# This script is intended for use with pathnames that start from the
+# tools/memory-model directory.  If some of the pathnames instead start at
+# the root directory, they all must do so and the "--destdir /" parseargs.sh
+# argument must be specified prior to the "--".  Alternatively, some other
+# "--destdir" argument can be supplied as long as the needed subdirectories
+# are populated.
+#
+# Copyright IBM Corporation, 2018
+#
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
+
+. scripts/parseargs.sh
+
+ret=0
+for i in "$@"
+do
+       if scripts/checklitmus.sh $i
+       then
+               :
+       else
+               ret=1
+       fi
+done
+if test "$ret" -ne 0
+then
+       echo " ^^^ VERIFICATION MISMATCHES" 1>&2
+else
+       echo All litmus tests verified as was expected. 1>&2
+fi
+exit $ret
index 0f498aeeccf5ec6cc76fd2634aa1204db73bdce5..ca1ac8b646144ac95b0ae13d5534bbebcf411ea6 100755 (executable)
@@ -12,12 +12,49 @@ trap 'rm -rf $T' 0
 mkdir $T
 
 # comparetest oldpath newpath
+badmacnam=0
+timedout=0
 perfect=0
 obsline=0
 noobsline=0
 obsresult=0
 badcompare=0
 comparetest () {
+       if grep -q ': Unknown macro ' $1 || grep -q ': Unknown macro ' $2
+       then
+               if grep -q ': Unknown macro ' $1
+               then
+                       badname=`grep ': Unknown macro ' $1 |
+                               sed -e 's/^.*: Unknown macro //' |
+                               sed -e 's/ (User error).*$//'`
+                       echo 'Current LKMM version does not know "'$badname'"' $1
+               fi
+               if grep -q ': Unknown macro ' $2
+               then
+                       badname=`grep ': Unknown macro ' $2 |
+                               sed -e 's/^.*: Unknown macro //' |
+                               sed -e 's/ (User error).*$//'`
+                       echo 'Current LKMM version does not know "'$badname'"' $2
+               fi
+               badmacnam=`expr "$badmacnam" + 1`
+               return 0
+       elif grep -q '^Command exited with non-zero status 124' $1 ||
+            grep -q '^Command exited with non-zero status 124' $2
+       then
+               if grep -q '^Command exited with non-zero status 124' $1 &&
+                  grep -q '^Command exited with non-zero status 124' $2
+               then
+                       echo Both runs timed out: $2
+               elif grep -q '^Command exited with non-zero status 124' $1
+               then
+                       echo Old run timed out: $2
+               elif grep -q '^Command exited with non-zero status 124' $2
+               then
+                       echo New run timed out: $2
+               fi
+               timedout=`expr "$timedout" + 1`
+               return 0
+       fi
        grep -v 'maxresident)k\|minor)pagefaults\|^Time' $1 > $T/oldout
        grep -v 'maxresident)k\|minor)pagefaults\|^Time' $2 > $T/newout
        if cmp -s $T/oldout $T/newout && grep -q '^Observation' $1
@@ -38,7 +75,7 @@ comparetest () {
                        return 0
                fi
        else
-               echo Missing Observation line "(e.g., herd7 timeout)": $2
+               echo Missing Observation line "(e.g., syntax error)": $2
                noobsline=`expr "$noobsline" + 1`
                return 0
        fi
@@ -72,12 +109,20 @@ then
 fi
 if test "$noobsline" -ne 0
 then
-       echo Missing Observation line "(e.g., herd7 timeout)": $noobsline 1>&2
+       echo Missing Observation line "(e.g., syntax error)": $noobsline 1>&2
 fi
 if test "$obsresult" -ne 0
 then
        echo Matching Observation Always/Sometimes/Never result: $obsresult 1>&2
 fi
+if test "$timedout" -ne 0
+then
+       echo "!!!" Timed out: $timedout 1>&2
+fi
+if test "$badmacnam" -ne 0
+then
+       echo "!!!" Unknown primitive: $badmacnam 1>&2
+fi
 if test "$badcompare" -ne 0
 then
        echo "!!!" Result changed: $badcompare 1>&2
diff --git a/tools/memory-model/scripts/hwfnseg.sh b/tools/memory-model/scripts/hwfnseg.sh
new file mode 100755 (executable)
index 0000000..580c328
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Generate the hardware extension to the litmus-test filename, or the
+# empty string if this is an LKMM run.  The extension is placed in
+# the shell variable hwfnseg.
+#
+# Usage:
+#      . hwfnseg.sh
+#
+# Copyright IBM Corporation, 2019
+#
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
+
+if test -z "$LKMM_HW_MAP_FILE"
+then
+       hwfnseg=
+else
+       hwfnseg=".$LKMM_HW_MAP_FILE"
+fi
index 956b6957484d879351d312a1d217df11d9dfd9f2..31ea782955d3f0115ab740d9a0b064228f058878 100755 (executable)
@@ -60,7 +60,7 @@ fi
 
 # Create a list of the C-language litmus tests with no more than the
 # specified number of processes (per the --procs argument).
-find litmus -name '*.litmus' -exec grep -l -m 1 "^C " {} \; > $T/list-C
+find litmus -name '*.litmus' -print | mselect7 -arch C > $T/list-C
 xargs < $T/list-C -r grep -L "^P${LKMM_PROCS}" > $T/list-C-short
 
 scripts/runlitmushist.sh < $T/list-C-short
index 0cc63875e395d06fe890c0f711e748a6226f25ea..1ec5d89fcfbb2a2f6e93803882c94104b20d992d 100755 (executable)
@@ -1,9 +1,22 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0+
 #
-# Given a .litmus test and the corresponding .litmus.out file, check
-# the .litmus.out file against the "Result:" comment to judge whether
-# the test ran correctly.
+# Given a .litmus test and the corresponding litmus output file, check
+# the .litmus.out file against the "Result:" comment to judge whether the
+# test ran correctly.  If the --hw argument is omitted, check against the
+# LKMM output, which is assumed to be in file.litmus.out. If either a
+# "DATARACE" marker in the "Result:" comment or a "Flag data-race" marker
+# in the LKMM output is present, the other must also be as well, at least
+# for litmus tests having a "Result:" comment. In this case, a failure of
+# the Always/Sometimes/Never portion of the "Result:" prediction will be
+# noted, but forgiven.
+#
+# If the --hw argument is provided, this is assumed to be a hardware
+# test, and the output is assumed to be in file.litmus.HW.out, where
+# "HW" is the --hw argument. In addition, non-Sometimes verification
+# results will be noted, but forgiven.  Furthermore, if there is no
+# "Result:" comment but there is an LKMM .litmus.out file, the observation
+# in that file will be used to judge the assembly-language verification.
 #
 # Usage:
 #      judgelitmus.sh file.litmus
@@ -13,7 +26,7 @@
 #
 # Copyright IBM Corporation, 2018
 #
-# Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
 
 litmus=$1
 
@@ -24,55 +37,120 @@ else
        echo ' --- ' error: \"$litmus\" is not a readable file
        exit 255
 fi
-if test -f "$LKMM_DESTDIR/$litmus".out -a -r "$LKMM_DESTDIR/$litmus".out
+if test -z "$LKMM_HW_MAP_FILE"
+then
+       litmusout=$litmus.out
+       lkmmout=
+else
+       litmusout="`echo $litmus |
+               sed -e 's/\.litmus$/.litmus.'${LKMM_HW_MAP_FILE}'/'`.out"
+       lkmmout=$litmus.out
+fi
+if test -f "$LKMM_DESTDIR/$litmusout" -a -r "$LKMM_DESTDIR/$litmusout"
 then
        :
 else
-       echo ' --- ' error: \"$LKMM_DESTDIR/$litmus\".out is not a readable file
+       echo ' --- ' error: \"$LKMM_DESTDIR/$litmusout is not a readable file
        exit 255
 fi
-if grep -q '^ \* Result: ' $litmus
+if grep -q '^Flag data-race$' "$LKMM_DESTDIR/$litmusout"
+then
+       datarace_modeled=1
+fi
+if grep -q '^[( ]\* Result: ' $litmus
+then
+       outcome=`grep -m 1 '^[( ]\* Result: ' $litmus | awk '{ print $3 }'`
+       if grep -m1 '^[( ]\* Result: .* DATARACE' $litmus
+       then
+               datarace_predicted=1
+       fi
+       if test -n "$datarace_predicted" -a -z "$datarace_modeled" -a -z "$LKMM_HW_MAP_FILE"
+       then
+               echo '!!! Predicted data race not modeled' $litmus
+               exit 252
+       elif test -z "$datarace_predicted" -a -n "$datarace_modeled"
+       then
+               # Note that hardware models currently don't model data races
+               echo '!!! Unexpected data race modeled' $litmus
+               exit 253
+       fi
+elif test -n "$LKMM_HW_MAP_FILE" && grep -q '^Observation' $LKMM_DESTDIR/$lkmmout > /dev/null 2>&1
 then
-       outcome=`grep -m 1 '^ \* Result: ' $litmus | awk '{ print $3 }'`
+       outcome=`grep -m 1 '^Observation ' $LKMM_DESTDIR/$lkmmout | awk '{ print $3 }'`
 else
        outcome=specified
 fi
 
-grep '^Observation' $LKMM_DESTDIR/$litmus.out
-if grep -q '^Observation' $LKMM_DESTDIR/$litmus.out
+grep '^Observation' $LKMM_DESTDIR/$litmusout
+if grep -q '^Observation' $LKMM_DESTDIR/$litmusout
 then
        :
+elif grep ': Unknown macro ' $LKMM_DESTDIR/$litmusout
+then
+       badname=`grep ': Unknown macro ' $LKMM_DESTDIR/$litmusout |
+               sed -e 's/^.*: Unknown macro //' |
+               sed -e 's/ (User error).*$//'`
+       badmsg=' !!! Current LKMM version does not know "'$badname'"'" $litmus"
+       echo $badmsg
+       if ! grep -q '!!!' $LKMM_DESTDIR/$litmusout
+       then
+               echo ' !!! '$badmsg >> $LKMM_DESTDIR/$litmusout 2>&1
+       fi
+       exit 254
+elif grep '^Command exited with non-zero status 124' $LKMM_DESTDIR/$litmusout
+then
+       echo ' !!! Timeout' $litmus
+       if ! grep -q '!!!' $LKMM_DESTDIR/$litmusout
+       then
+               echo ' !!! Timeout' >> $LKMM_DESTDIR/$litmusout 2>&1
+       fi
+       exit 124
 else
        echo ' !!! Verification error' $litmus
-       if ! grep -q '!!!' $LKMM_DESTDIR/$litmus.out
+       if ! grep -q '!!!' $LKMM_DESTDIR/$litmusout
        then
-               echo ' !!! Verification error' >> $LKMM_DESTDIR/$litmus.out 2>&1
+               echo ' !!! Verification error' >> $LKMM_DESTDIR/$litmusout 2>&1
        fi
        exit 255
 fi
 if test "$outcome" = DEADLOCK
 then
-       if grep '^Observation' $LKMM_DESTDIR/$litmus.out | grep -q 'Never 0 0$'
+       if grep '^Observation' $LKMM_DESTDIR/$litmusout | grep -q 'Never 0 0$'
        then
                ret=0
        else
                echo " !!! Unexpected non-$outcome verification" $litmus
-               if ! grep -q '!!!' $LKMM_DESTDIR/$litmus.out
+               if ! grep -q '!!!' $LKMM_DESTDIR/$litmusout
                then
-                       echo " !!! Unexpected non-$outcome verification" >> $LKMM_DESTDIR/$litmus.out 2>&1
+                       echo " !!! Unexpected non-$outcome verification" >> $LKMM_DESTDIR/$litmusout 2>&1
                fi
                ret=1
        fi
-elif grep '^Observation' $LKMM_DESTDIR/$litmus.out | grep -q $outcome || test "$outcome" = Maybe
+elif grep '^Observation' $LKMM_DESTDIR/$litmusout | grep -q 'Never 0 0$'
+then
+       echo " !!! Unexpected non-$outcome deadlock" $litmus
+       if ! grep -q '!!!' $LKMM_DESTDIR/$litmusout
+       then
+               echo " !!! Unexpected non-$outcome deadlock" $litmus >> $LKMM_DESTDIR/$litmusout 2>&1
+       fi
+       ret=1
+elif grep '^Observation' $LKMM_DESTDIR/$litmusout | grep -q $outcome || test "$outcome" = Maybe
 then
        ret=0
 else
-       echo " !!! Unexpected non-$outcome verification" $litmus
-       if ! grep -q '!!!' $LKMM_DESTDIR/$litmus.out
+       if test \( -n "$LKMM_HW_MAP_FILE" -a "$outcome" = Sometimes \) -o -n "$datarace_modeled"
        then
-               echo " !!! Unexpected non-$outcome verification" >> $LKMM_DESTDIR/$litmus.out 2>&1
+               flag="--- Forgiven"
+               ret=0
+       else
+               flag="!!! Unexpected"
+               ret=1
+       fi
+       echo " $flag non-$outcome verification" $litmus
+       if ! grep -qe "$flag" $LKMM_DESTDIR/$litmusout
+       then
+               echo " $flag non-$outcome verification" >> $LKMM_DESTDIR/$litmusout 2>&1
        fi
-       ret=1
 fi
-tail -2 $LKMM_DESTDIR/$litmus.out | head -1
+tail -2 $LKMM_DESTDIR/$litmusout | head -1
 exit $ret
index 991f8f81488174b1c6b165efcc53cec167787138..25235e2049cf05bbc1aa870e822085b1204781c5 100755 (executable)
@@ -12,7 +12,7 @@
 #
 # Copyright IBM Corporation, 2018
 #
-# Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
 
 . scripts/parseargs.sh
 
@@ -43,7 +43,7 @@ fi
 
 # Form full list of litmus tests with no more than the specified
 # number of processes (per the --procs argument).
-find litmus -name '*.litmus' -exec grep -l -m 1 "^C " {} \; > $T/list-C-all
+find litmus -name '*.litmus' -print | mselect7 -arch C > $T/list-C-all
 xargs < $T/list-C-all -r grep -L "^P${LKMM_PROCS}" > $T/list-C-short
 
 # Form list of new tests.  Note: This does not handle litmus-test deletion!
index 40f52080fdbd6eb9d82bc3f3bb647fe1da46ffb8..08ded59098607d44c829e6f0a58da8d12545ea46 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0+
 #
-# the corresponding .litmus.out file, and does not judge the result.
+# Parse arguments common to the various scripts.
 #
 # . scripts/parseargs.sh
 #
@@ -9,7 +9,7 @@
 #
 # Copyright IBM Corporation, 2018
 #
-# Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
 
 T=/tmp/parseargs.sh.$$
 mkdir $T
@@ -27,6 +27,7 @@ initparam () {
 
 initparam LKMM_DESTDIR "."
 initparam LKMM_HERD_OPTIONS "-conf linux-kernel.cfg"
+initparam LKMM_HW_MAP_FILE ""
 initparam LKMM_JOBS `getconf _NPROCESSORS_ONLN`
 initparam LKMM_PROCS "3"
 initparam LKMM_TIMEOUT "1m"
@@ -37,10 +38,11 @@ usagehelp () {
        echo "Usage $scriptname [ arguments ]"
        echo "      --destdir path (place for .litmus.out, default by .litmus)"
        echo "      --herdopts -conf linux-kernel.cfg ..."
+       echo "      --hw AArch64"
        echo "      --jobs N (number of jobs, default one per CPU)"
        echo "      --procs N (litmus tests with at most this many processes)"
        echo "      --timeout N (herd7 timeout (e.g., 10s, 1m, 2hr, 1d, '')"
-       echo "Defaults: --destdir '$LKMM_DESTDIR_DEF' --herdopts '$LKMM_HERD_OPTIONS_DEF' --jobs '$LKMM_JOBS_DEF' --procs '$LKMM_PROCS_DEF' --timeout '$LKMM_TIMEOUT_DEF'"
+       echo "Defaults: --destdir '$LKMM_DESTDIR_DEF' --herdopts '$LKMM_HERD_OPTIONS_DEF' --hw '$LKMM_HW_MAP_FILE' --jobs '$LKMM_JOBS_DEF' --procs '$LKMM_PROCS_DEF' --timeout '$LKMM_TIMEOUT_DEF'"
        exit 1
 }
 
@@ -81,7 +83,7 @@ do
                        echo "Cannot create directory --destdir '$LKMM_DESTDIR'"
                        usage
                fi
-               if test -d "$LKMM_DESTDIR" -a -w "$LKMM_DESTDIR" -a -x "$LKMM_DESTDIR"
+               if test -d "$LKMM_DESTDIR" -a -x "$LKMM_DESTDIR"
                then
                        :
                else
@@ -95,6 +97,11 @@ do
                LKMM_HERD_OPTIONS="$2"
                shift
                ;;
+       --hw)
+               checkarg --hw "(.map file architecture name)" "$#" "$2" '^[A-Za-z0-9_-]\+' '^--'
+               LKMM_HW_MAP_FILE="$2"
+               shift
+               ;;
        -j[1-9]*)
                njobs="`echo $1 | sed -e 's/^-j//'`"
                trailchars="`echo $njobs | sed -e 's/[0-9]\+\(.*\)$/\1/'`"
@@ -106,7 +113,7 @@ do
                LKMM_JOBS="`echo $njobs | sed -e 's/^\([0-9]\+\).*$/\1/'`"
                ;;
        --jobs|--job|-j)
-               checkarg --jobs "(number)" "$#" "$2" '^[1-9][0-9]\+$' '^--'
+               checkarg --jobs "(number)" "$#" "$2" '^[1-9][0-9]*$' '^--'
                LKMM_JOBS="$2"
                shift
                ;;
@@ -120,6 +127,10 @@ do
                LKMM_TIMEOUT="$2"
                shift
                ;;
+       --)
+               shift
+               break
+               ;;
        *)
                echo Unknown argument $1
                usage
diff --git a/tools/memory-model/scripts/runlitmus.sh b/tools/memory-model/scripts/runlitmus.sh
new file mode 100755 (executable)
index 0000000..94608d4
--- /dev/null
@@ -0,0 +1,80 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Without the -hw argument, runs a herd7 test and outputs verification
+# results to a file whose name is that of the specified litmus test,
+# but with ".out" appended.
+#
+# If the --hw argument is specified, this script translates the .litmus
+# C-language file to the specified type of assembly and verifies that.
+# But in this case, litmus tests using complex synchronization (such as
+# locking, RCU, and SRCU) are cheerfully ignored.
+#
+# Either way, return the status of the herd7 command.
+#
+# Usage:
+#      runlitmus.sh file.litmus
+#
+# Run this in the directory containing the memory model, specifying the
+# pathname of the litmus test to check.  The caller is expected to have
+# properly set up the LKMM environment variables.
+#
+# Copyright IBM Corporation, 2019
+#
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
+
+litmus=$1
+if test -f "$litmus" -a -r "$litmus"
+then
+       :
+else
+       echo ' !!! ' error: \"$litmus\" is not a readable file
+       exit 255
+fi
+
+if test -z "$LKMM_HW_MAP_FILE" -o ! -e $LKMM_DESTDIR/$litmus.out
+then
+       # LKMM run
+       herdoptions=${LKMM_HERD_OPTIONS--conf linux-kernel.cfg}
+       echo Herd options: $herdoptions > $LKMM_DESTDIR/$litmus.out
+       /usr/bin/time $LKMM_TIMEOUT_CMD herd7 $herdoptions $litmus >> $LKMM_DESTDIR/$litmus.out 2>&1
+       ret=$?
+       if test -z "$LKMM_HW_MAP_FILE"
+       then
+               exit $ret
+       fi
+       echo " --- " Automatically generated LKMM output for '"'--hw $LKMM_HW_MAP_FILE'"' run
+fi
+
+# Hardware run
+
+T=/tmp/checklitmushw.sh.$$
+trap 'rm -rf $T' 0 2
+mkdir $T
+
+# Generate filenames
+mapfile="Linux2${LKMM_HW_MAP_FILE}.map"
+themefile="$T/${LKMM_HW_MAP_FILE}.theme"
+herdoptions="-model $LKMM_HW_CAT_FILE"
+hwlitmus=`echo $litmus | sed -e 's/\.litmus$/.litmus.'${LKMM_HW_MAP_FILE}'/'`
+hwlitmusfile=`echo $hwlitmus | sed -e 's,^.*/,,'`
+
+# Don't run on litmus tests with complex synchronization
+if ! scripts/simpletest.sh $litmus
+then
+       echo ' --- ' error: \"$litmus\" contains locking, RCU, or SRCU
+       exit 254
+fi
+
+# Generate the assembly code and run herd7 on it.
+gen_theme7 -n 10 -map $mapfile -call Linux.call > $themefile
+jingle7 -v -theme $themefile $litmus > $LKMM_DESTDIR/$hwlitmus 2> $T/$hwlitmusfile.jingle7.out
+if grep -q "Generated 0 tests" $T/$hwlitmusfile.jingle7.out
+then
+       echo ' !!! ' jingle7 failed, errors in $hwlitmus.err
+       cp $T/$hwlitmusfile.jingle7.out $LKMM_DESTDIR/$hwlitmus.err
+       exit 253
+fi
+/usr/bin/time $LKMM_TIMEOUT_CMD herd7 -unroll 0 $LKMM_DESTDIR/$hwlitmus > $LKMM_DESTDIR/$hwlitmus.out 2>&1
+
+exit $?
index 6ed376f495bb4eadc72504c66ba5f1ac9a2f9c2f..c6c2bdc67a502169700fbbe6731d75905ade312b 100755 (executable)
@@ -13,7 +13,9 @@
 #
 # Copyright IBM Corporation, 2018
 #
-# Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
+
+. scripts/hwfnseg.sh
 
 T=/tmp/runlitmushist.sh.$$
 trap 'rm -rf $T' 0
@@ -30,15 +32,12 @@ fi
 # Prefixes for per-CPU scripts
 for ((i=0;i<$LKMM_JOBS;i++))
 do
-       echo dir="$LKMM_DESTDIR" > $T/$i.sh
        echo T=$T >> $T/$i.sh
-       echo herdoptions=\"$LKMM_HERD_OPTIONS\" >> $T/$i.sh
        cat << '___EOF___' >> $T/$i.sh
        runtest () {
-               echo ' ... ' /usr/bin/time $LKMM_TIMEOUT_CMD herd7 $herdoptions $1 '>' $dir/$1.out '2>&1'
-               if /usr/bin/time $LKMM_TIMEOUT_CMD herd7 $herdoptions $1 > $dir/$1.out 2>&1
+               if scripts/runlitmus.sh $1
                then
-                       if ! grep -q '^Observation ' $dir/$1.out
+                       if ! grep -q '^Observation ' $LKMM_DESTDIR/$1$2.out
                        then
                                echo ' !!! Herd failed, no Observation:' $1
                        fi
@@ -47,10 +46,16 @@ do
                        if test "$exitcode" -eq 124
                        then
                                exitmsg="timed out"
+                       elif test "$exitcode" -eq 253
+                       then
+                               exitmsg=
                        else
                                exitmsg="failed, exit code $exitcode"
                        fi
-                       echo ' !!! Herd' ${exitmsg}: $1
+                       if test -n "$exitmsg"
+                       then
+                               echo ' !!! Herd' ${exitmsg}: $1
+                       fi
                fi
        }
 ___EOF___
@@ -59,11 +64,13 @@ done
 awk -v q="'" -v b='\\' '
 {
        print "echo `grep " q "^P[0-9]" b "+(" q " " $0 " | tail -1 | sed -e " q "s/^P" b "([0-9]" b "+" b ")(.*$/" b "1/" q "` " $0
-}' | bash |
-sort -k1n |
-awk -v ncpu=$LKMM_JOBS -v t=$T '
+}' | sh | sort -k1n |
+awk -v dq='"' -v hwfnseg="$hwfnseg" -v ncpu="$LKMM_JOBS" -v t="$T" '
 {
-       print "runtest " $2 >> t "/" NR % ncpu ".sh";
+       print "if test -z " dq hwfnseg dq " || scripts/simpletest.sh " dq $2 dq
+       print "then"
+       print "\techo runtest " dq $2 dq " " hwfnseg " >> " t "/" NR % ncpu ".sh";
+       print "fi"
 }
 
 END {
diff --git a/tools/memory-model/scripts/simpletest.sh b/tools/memory-model/scripts/simpletest.sh
new file mode 100755 (executable)
index 0000000..7edc5d3
--- /dev/null
@@ -0,0 +1,35 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Give zero status if this is a simple test and non-zero otherwise.
+# Simple tests do not contain locking, RCU, or SRCU.
+#
+# Usage:
+#      simpletest.sh file.litmus
+#
+# Copyright IBM Corporation, 2019
+#
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
+
+
+litmus=$1
+
+if test -f "$litmus" -a -r "$litmus"
+then
+       :
+else
+       echo ' --- ' error: \"$litmus\" is not a readable file
+       exit 255
+fi
+exclude="^[[:space:]]*\("
+exclude="${exclude}spin_lock(\|spin_unlock(\|spin_trylock(\|spin_is_locked("
+exclude="${exclude}\|rcu_read_lock(\|rcu_read_unlock("
+exclude="${exclude}\|synchronize_rcu(\|synchronize_rcu_expedited("
+exclude="${exclude}\|srcu_read_lock(\|srcu_read_unlock("
+exclude="${exclude}\|synchronize_srcu(\|synchronize_srcu_expedited("
+exclude="${exclude}\)"
+if grep -q $exclude $litmus
+then
+       exit 255
+fi
+exit 0
index 7c2ac124cdc83a21be7ba9bf010b5b1dd120af24..99798894b8790544b3dd83c222c9237af32b94a7 100644 (file)
@@ -857,7 +857,7 @@ int main(int argc, char **argv)
                        if (cull & CULL_PID || filter & FILTER_PID)
                                fprintf(fout, ", PID %d", list[i].pid);
                        if (cull & CULL_TGID || filter & FILTER_TGID)
-                               fprintf(fout, ", TGID %d", list[i].pid);
+                               fprintf(fout, ", TGID %d", list[i].tgid);
                        if (cull & CULL_COMM || filter & FILTER_COMM)
                                fprintf(fout, ", task_comm_name: %s", list[i].comm);
                        if (cull & CULL_ALLOCATOR) {
index db410b74d5395cb63e5094eafdaffc54552912cb..ffaa8038aa8c66d18af3933ece7f7ad695a0632a 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/env python3
-# SPDX-License-Identifier: BSD-3-Clause
+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 
 import argparse
 import json
index 3c73f59eabab987ac0a72f004aad354866645db8..4b3797fe784bad06c42d21cfedcb5428ac2e61ae 100644 (file)
@@ -1,7 +1,8 @@
-# SPDX-License-Identifier: BSD-3-Clause
+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 
-from .nlspec import SpecAttr, SpecAttrSet, SpecFamily, SpecOperation
+from .nlspec import SpecAttr, SpecAttrSet, SpecEnumEntry, SpecEnumSet, \
+    SpecFamily, SpecOperation
 from .ynl import YnlFamily
 
-__all__ = ["SpecAttr", "SpecAttrSet", "SpecFamily", "SpecOperation",
-           "YnlFamily"]
+__all__ = ["SpecAttr", "SpecAttrSet", "SpecEnumEntry", "SpecEnumSet",
+           "SpecFamily", "SpecOperation", "YnlFamily"]
index 71da568e2c28f7b8b0497b3993541370b1f2467e..d04450c2a44af866ef30cf6892a9d0d956c02b92 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: BSD-3-Clause
+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 
 import collections
 import importlib
@@ -57,6 +57,92 @@ class SpecElement:
         pass
 
 
+class SpecEnumEntry(SpecElement):
+    """ Entry within an enum declared in the Netlink spec.
+
+    Attributes:
+        doc         documentation string
+        enum_set    back reference to the enum
+        value       numerical value of this enum (use accessors in most situations!)
+
+    Methods:
+        raw_value   raw value, i.e. the id in the enum, unlike user value which is a mask for flags
+        user_value   user value, same as raw value for enums, for flags it's the mask
+    """
+    def __init__(self, enum_set, yaml, prev, value_start):
+        if isinstance(yaml, str):
+            yaml = {'name': yaml}
+        super().__init__(enum_set.family, yaml)
+
+        self.doc = yaml.get('doc', '')
+        self.enum_set = enum_set
+
+        if 'value' in yaml:
+            self.value = yaml['value']
+        elif prev:
+            self.value = prev.value + 1
+        else:
+            self.value = value_start
+
+    def has_doc(self):
+        return bool(self.doc)
+
+    def raw_value(self):
+        return self.value
+
+    def user_value(self):
+        if self.enum_set['type'] == 'flags':
+            return 1 << self.value
+        else:
+            return self.value
+
+
+class SpecEnumSet(SpecElement):
+    """ Enum type
+
+    Represents an enumeration (list of numerical constants)
+    as declared in the "definitions" section of the spec.
+
+    Attributes:
+        type            enum or flags
+        entries         entries by name
+        entries_by_val  entries by value
+    Methods:
+        get_mask      for flags compute the mask of all defined values
+    """
+    def __init__(self, family, yaml):
+        super().__init__(family, yaml)
+
+        self.type = yaml['type']
+
+        prev_entry = None
+        value_start = self.yaml.get('value-start', 0)
+        self.entries = dict()
+        self.entries_by_val = dict()
+        for entry in self.yaml['entries']:
+            e = self.new_entry(entry, prev_entry, value_start)
+            self.entries[e.name] = e
+            self.entries_by_val[e.raw_value()] = e
+            prev_entry = e
+
+    def new_entry(self, entry, prev_entry, value_start):
+        return SpecEnumEntry(self, entry, prev_entry, value_start)
+
+    def has_doc(self):
+        if 'doc' in self.yaml:
+            return True
+        for entry in self.entries.values():
+            if entry.has_doc():
+                return True
+        return False
+
+    def get_mask(self):
+        mask = 0
+        for e in self.entries.values():
+            mask += e.user_value()
+        return mask
+
+
 class SpecAttr(SpecElement):
     """ Single Netlink atttribute type
 
@@ -95,15 +181,22 @@ class SpecAttrSet(SpecElement):
         self.attrs = collections.OrderedDict()
         self.attrs_by_val = collections.OrderedDict()
 
-        val = 0
-        for elem in self.yaml['attributes']:
-            if 'value' in elem:
-                val = elem['value']
+        if self.subset_of is None:
+            val = 1
+            for elem in self.yaml['attributes']:
+                if 'value' in elem:
+                    val = elem['value']
 
-            attr = self.new_attr(elem, val)
-            self.attrs[attr.name] = attr
-            self.attrs_by_val[attr.value] = attr
-            val += 1
+                attr = self.new_attr(elem, val)
+                self.attrs[attr.name] = attr
+                self.attrs_by_val[attr.value] = attr
+                val += 1
+        else:
+            real_set = family.attr_sets[self.subset_of]
+            for elem in self.yaml['attributes']:
+                attr = real_set[elem['name']]
+                self.attrs[attr.name] = attr
+                self.attrs_by_val[attr.value] = attr
 
     def new_attr(self, elem, value):
         return SpecAttr(self.family, self, elem, value)
@@ -181,14 +274,23 @@ class SpecFamily(SpecElement):
 
     Attributes:
         proto     protocol type (e.g. genetlink)
+        license   spec license (loaded from an SPDX tag on the spec)
 
         attr_sets  dict of attribute sets
         msgs       dict of all messages (index by name)
         msgs_by_value  dict of all messages (indexed by name)
         ops        dict of all valid requests / responses
+        consts     dict of all constants/enums
     """
     def __init__(self, spec_path, schema_path=None):
         with open(spec_path, "r") as stream:
+            prefix = '# SPDX-License-Identifier: '
+            first = stream.readline().strip()
+            if not first.startswith(prefix):
+                raise Exception('SPDX license tag required in the spec')
+            self.license = first[len(prefix):]
+
+            stream.seek(0)
             spec = yaml.safe_load(stream)
 
         self._resolution_list = []
@@ -215,6 +317,7 @@ class SpecFamily(SpecElement):
         self.req_by_value = collections.OrderedDict()
         self.rsp_by_value = collections.OrderedDict()
         self.ops = collections.OrderedDict()
+        self.consts = collections.OrderedDict()
 
         last_exception = None
         while len(self._resolution_list) > 0:
@@ -235,6 +338,9 @@ class SpecFamily(SpecElement):
             if len(resolved) == 0:
                 raise last_exception
 
+    def new_enum(self, elem):
+        return SpecEnumSet(self, elem)
+
     def new_attr_set(self, elem):
         return SpecAttrSet(self, elem)
 
@@ -245,7 +351,7 @@ class SpecFamily(SpecElement):
         self._resolution_list.append(elem)
 
     def _dictify_ops_unified(self):
-        val = 0
+        val = 1
         for elem in self.yaml['operations']['list']:
             if 'value' in elem:
                 val = elem['value']
@@ -256,7 +362,7 @@ class SpecFamily(SpecElement):
             self.msgs[op.name] = op
 
     def _dictify_ops_directional(self):
-        req_val = rsp_val = 0
+        req_val = rsp_val = 1
         for elem in self.yaml['operations']['list']:
             if 'notify' in elem:
                 if 'value' in elem:
@@ -289,6 +395,13 @@ class SpecFamily(SpecElement):
     def resolve(self):
         self.resolve_up(super())
 
+        definitions = self.yaml.get('definitions', [])
+        for elem in definitions:
+            if elem['type'] == 'enum' or elem['type'] == 'flags':
+                self.consts[elem['name']] = self.new_enum(elem)
+            else:
+                self.consts[elem['name']] = elem
+
         for elem in self.yaml['attribute-sets']:
             attr_set = self.new_attr_set(elem)
             self.attr_sets[elem['name']] = attr_set
index 1c7411ee04dc875c7924fa83bba784239b62ff97..32536e1f9064bba576a267b5a02f6fe16a38d4a5 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: BSD-3-Clause
+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 
 import functools
 import os
@@ -200,7 +200,7 @@ def _genl_msg(nl_type, nl_flags, genl_cmd, genl_version, seq=None):
     if seq is None:
         seq = random.randint(1, 1024)
     nlmsg = struct.pack("HHII", nl_type, nl_flags, seq, 0)
-    genlmsg = struct.pack("bbH", genl_cmd, genl_version, 0)
+    genlmsg = struct.pack("BBH", genl_cmd, genl_version, 0)
     return nlmsg + genlmsg
 
 
@@ -264,7 +264,7 @@ class GenlMsg:
         self.hdr = nl_msg.raw[0:4]
         self.raw = nl_msg.raw[4:]
 
-        self.genl_cmd, self.genl_version, _ = struct.unpack("bbH", self.hdr)
+        self.genl_cmd, self.genl_version, _ = struct.unpack("BBH", self.hdr)
 
         self.raw_attrs = NlAttrs(self.raw)
 
@@ -303,11 +303,6 @@ class YnlFamily(SpecFamily):
         self.sock.setsockopt(Netlink.SOL_NETLINK, Netlink.NETLINK_CAP_ACK, 1)
         self.sock.setsockopt(Netlink.SOL_NETLINK, Netlink.NETLINK_EXT_ACK, 1)
 
-        self._types = dict()
-
-        for elem in self.yaml.get('definitions', []):
-            self._types[elem['name']] = elem
-
         self.async_msg_ids = set()
         self.async_msg_queue = []
 
@@ -353,17 +348,17 @@ class YnlFamily(SpecFamily):
 
     def _decode_enum(self, rsp, attr_spec):
         raw = rsp[attr_spec['name']]
-        enum = self._types[attr_spec['enum']]
+        enum = self.consts[attr_spec['enum']]
         i = attr_spec.get('value-start', 0)
         if 'enum-as-flags' in attr_spec and attr_spec['enum-as-flags']:
             value = set()
             while raw:
                 if raw & 1:
-                    value.add(enum['entries'][i])
+                    value.add(enum.entries_by_val[i].name)
                 raw >>= 1
                 i += 1
         else:
-            value = enum['entries'][raw - i]
+            value = enum.entries_by_val[raw - i].name
         rsp[attr_spec['name']] = value
 
     def _decode(self, attrs, space):
index 274e9c566f61b09d093958d1d4fd89b8c9b17905..c16671a02621bfbbe8018985d614c4766ea7fed0 100755 (executable)
@@ -1,11 +1,12 @@
 #!/usr/bin/env python3
+# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
 
 import argparse
 import collections
 import os
 import yaml
 
-from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation
+from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, SpecEnumEntry
 
 
 def c_upper(name):
@@ -566,97 +567,37 @@ class Struct:
         self.inherited = [c_lower(x) for x in sorted(self._inherited)]
 
 
-class EnumEntry:
+class EnumEntry(SpecEnumEntry):
     def __init__(self, enum_set, yaml, prev, value_start):
-        if isinstance(yaml, str):
-            self.name = yaml
-            yaml = {}
-            self.doc = ''
-        else:
-            self.name = yaml['name']
-            self.doc = yaml.get('doc', '')
-
-        self.yaml = yaml
-        self.enum_set = enum_set
-        self.c_name = c_upper(enum_set.value_pfx + self.name)
-
-        if 'value' in yaml:
-            self.value = yaml['value']
-            if prev:
-                self.value_change = (self.value != prev.value + 1)
-        elif prev:
-            self.value_change = False
-            self.value = prev.value + 1
+        super().__init__(enum_set, yaml, prev, value_start)
+
+        if prev:
+            self.value_change = (self.value != prev.value + 1)
         else:
-            self.value = value_start
             self.value_change = (self.value != 0)
-
         self.value_change = self.value_change or self.enum_set['type'] == 'flags'
 
-    def __getitem__(self, key):
-        return self.yaml[key]
-
-    def __contains__(self, key):
-        return key in self.yaml
-
-    def has_doc(self):
-        return bool(self.doc)
+        # Added by resolve:
+        self.c_name = None
+        delattr(self, "c_name")
 
-    # raw value, i.e. the id in the enum, unlike user value which is a mask for flags
-    def raw_value(self):
-        return self.value
+    def resolve(self):
+        self.resolve_up(super())
 
-    # user value, same as raw value for enums, for flags it's the mask
-    def user_value(self):
-        if self.enum_set['type'] == 'flags':
-            return 1 << self.value
-        else:
-            return self.value
+        self.c_name = c_upper(self.enum_set.value_pfx + self.name)
 
 
-class EnumSet:
+class EnumSet(SpecEnumSet):
     def __init__(self, family, yaml):
-        self.yaml = yaml
-        self.family = family
-
         self.render_name = c_lower(family.name + '-' + yaml['name'])
         self.enum_name = 'enum ' + self.render_name
 
         self.value_pfx = yaml.get('name-prefix', f"{family.name}-{yaml['name']}-")
 
-        self.type = yaml['type']
-
-        prev_entry = None
-        value_start = self.yaml.get('value-start', 0)
-        self.entries = {}
-        self.entry_list = []
-        for entry in self.yaml['entries']:
-            e = EnumEntry(self, entry, prev_entry, value_start)
-            self.entries[e.name] = e
-            self.entry_list.append(e)
-            prev_entry = e
-
-    def __getitem__(self, key):
-        return self.yaml[key]
-
-    def __contains__(self, key):
-        return key in self.yaml
-
-    def has_doc(self):
-        if 'doc' in self.yaml:
-            return True
-        for entry in self.entry_list:
-            if entry.has_doc():
-                return True
-        return False
+        super().__init__(family, yaml)
 
-    def get_mask(self):
-        mask = 0
-        idx = self.yaml.get('value-start', 0)
-        for _ in self.entry_list:
-            mask |= 1 << idx
-            idx += 1
-        return mask
+    def new_entry(self, entry, prev_entry, value_start):
+        return EnumEntry(self, entry, prev_entry, value_start)
 
 
 class AttrSet(SpecAttrSet):
@@ -791,8 +732,6 @@ class Family(SpecFamily):
 
         self.mcgrps = self.yaml.get('mcast-groups', {'list': []})
 
-        self.consts = dict()
-
         self.hooks = dict()
         for when in ['pre', 'post']:
             self.hooks[when] = dict()
@@ -819,6 +758,9 @@ class Family(SpecFamily):
         if self.kernel_policy == 'global':
             self._load_global_policy()
 
+    def new_enum(self, elem):
+        return EnumSet(self, elem)
+
     def new_attr_set(self, elem):
         return AttrSet(self, elem)
 
@@ -836,12 +778,6 @@ class Family(SpecFamily):
                 }
 
     def _dictify(self):
-        for elem in self.yaml['definitions']:
-            if elem['type'] == 'enum' or elem['type'] == 'flags':
-                self.consts[elem['name']] = EnumSet(self, elem)
-            else:
-                self.consts[elem['name']] = elem
-
         ntf = []
         for msg in self.msgs.values():
             if 'notify' in msg:
@@ -1979,7 +1915,7 @@ def render_uapi(family, cw):
                 if 'doc' in enum:
                     doc = ' - ' + enum['doc']
                 cw.write_doc_line(enum.enum_name + doc)
-                for entry in enum.entry_list:
+                for entry in enum.entries.values():
                     if entry.has_doc():
                         doc = '@' + entry.c_name + ': ' + entry['doc']
                         cw.write_doc_line(doc)
@@ -1987,7 +1923,7 @@ def render_uapi(family, cw):
 
             uapi_enum_start(family, cw, const, 'name')
             name_pfx = const.get('name-prefix', f"{family.name}-{const['name']}-")
-            for entry in enum.entry_list:
+            for entry in enum.entries.values():
                 suffix = ','
                 if entry.value_change:
                     suffix = f" = {entry.user_value()}" + suffix
@@ -1995,9 +1931,14 @@ def render_uapi(family, cw):
 
             if const.get('render-max', False):
                 cw.nl()
-                max_name = c_upper(name_pfx + 'max')
-                cw.p('__' + max_name + ',')
-                cw.p(max_name + ' = (__' + max_name + ' - 1)')
+                if const['type'] == 'flags':
+                    max_name = c_upper(name_pfx + 'mask')
+                    max_val = f' = {enum.get_mask()},'
+                    cw.p(max_name + max_val)
+                else:
+                    max_name = c_upper(name_pfx + 'max')
+                    cw.p('__' + max_name + ',')
+                    cw.p(max_name + ' = (__' + max_name + ' - 1)')
             cw.block_end(line=';')
             cw.nl()
         elif const['type'] == 'const':
@@ -2044,14 +1985,17 @@ def render_uapi(family, cw):
     max_value = f"({cnt_name} - 1)"
 
     uapi_enum_start(family, cw, family['operations'], 'enum-name')
+    val = 0
     for op in family.msgs.values():
         if separate_ntf and ('notify' in op or 'event' in op):
             continue
 
         suffix = ','
-        if 'value' in op:
-            suffix = f" = {op['value']},"
+        if op.value != val:
+            suffix = f" = {op.value},"
+            val = op.value
         cw.p(op.enum_name + suffix)
+        val += 1
     cw.nl()
     cw.p(cnt_name + ('' if max_by_define else ','))
     if not max_by_define:
@@ -2115,6 +2059,10 @@ def main():
 
     try:
         parsed = Family(args.spec)
+        if parsed.license != '((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)':
+            print('Spec license:', parsed.license)
+            print('License must be: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)')
+            os.sys.exit(1)
     except yaml.YAMLError as exc:
         print(exc)
         os.sys.exit(1)
@@ -2123,13 +2071,10 @@ def main():
     cw = CodeWriter(BaseNlLib(), out_file)
 
     _, spec_kernel = find_kernel_root(args.spec)
-    if args.mode == 'uapi':
-        cw.p('/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */')
+    if args.mode == 'uapi' or args.header:
+        cw.p(f'/* SPDX-License-Identifier: {parsed.license} */')
     else:
-        if args.header:
-            cw.p('/* SPDX-License-Identifier: BSD-3-Clause */')
-        else:
-            cw.p('// SPDX-License-Identifier: BSD-3-Clause')
+        cw.p(f'// SPDX-License-Identifier: {parsed.license}')
     cw.p("/* Do not edit directly, auto-generated from: */")
     cw.p(f"/*\t{spec_kernel} */")
     cw.p(f"/* YNL-GEN {args.mode} {'header' if args.header else 'source'} */")
index 43989ae48ed05634aa63480c94ad9967c182c36a..74f5de1c239944020e1a76555da542d20a11c2bc 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/bash
-# SPDX-License-Identifier: BSD-3-Clause
+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 
 TOOL=$(dirname $(realpath $0))/ynl-gen-c.py
 
index 8e53fc6735ef2668dcc51f571ec4b1eeb505b72f..744db4218e7ac0d4537d1268ea685a8dea21b904 100644 (file)
@@ -181,7 +181,7 @@ b) ORC (Oops Rewind Capability) unwind table generation
    band.  So it doesn't affect runtime performance and it can be
    reliable even when interrupts or exceptions are involved.
 
-   For more details, see Documentation/x86/orc-unwinder.rst.
+   For more details, see Documentation/arch/x86/orc-unwinder.rst.
 
 c) Higher live patching compatibility rate
 
index f937be1afe65ca9c968038c701b927dd4126f409..50ed63f701f106344f88afb4082972ec784d0230 100644 (file)
@@ -1284,9 +1284,9 @@ static const char *uaccess_safe_builtin[] = {
        "copy_mc_fragile_handle_tail",
        "copy_mc_enhanced_fast_string",
        "ftrace_likely_update", /* CONFIG_TRACE_BRANCH_PROFILING */
-       "clear_user_erms",
-       "clear_user_rep_good",
-       "clear_user_original",
+       "rep_stos_alternative",
+       "rep_movs_alternative",
+       "__copy_user_nocache",
        NULL
 };
 
index f8182417b7341d2c4eb99ca618bffe338cb717d7..10bb1d494258dcbc5b95de71f86ad4bf814c8e47 100644 (file)
@@ -538,6 +538,7 @@ static int perf_event__repipe_buildid_mmap2(struct perf_tool *tool,
                        dso->hit = 1;
                }
                dso__put(dso);
+               perf_event__repipe(tool, event, sample, machine);
                return 0;
        }
 
index 5d18a5a6f662481a40697aceae9e47de5f4477b3..fa7c40956d0fa957c95b8755db61d83e0ee1cc4b 100644 (file)
@@ -539,12 +539,7 @@ static int enable_counters(void)
                        return err;
        }
 
-       /*
-        * We need to enable counters only if:
-        * - we don't have tracee (attaching to task or cpu)
-        * - we have initial delay configured
-        */
-       if (!target__none(&target)) {
+       if (!target__enable_on_exec(&target)) {
                if (!all_counters_use_bpf)
                        evlist__enable(evsel_list);
        }
@@ -914,7 +909,7 @@ try_again_reset:
                        return err;
        }
 
-       if (stat_config.initial_delay) {
+       if (target.initial_delay) {
                pr_info(EVLIST_DISABLED_MSG);
        } else {
                err = enable_counters();
@@ -926,8 +921,8 @@ try_again_reset:
        if (forks)
                evlist__start_workload(evsel_list);
 
-       if (stat_config.initial_delay > 0) {
-               usleep(stat_config.initial_delay * USEC_PER_MSEC);
+       if (target.initial_delay > 0) {
+               usleep(target.initial_delay * USEC_PER_MSEC);
                err = enable_counters();
                if (err)
                        return -1;
@@ -1248,7 +1243,7 @@ static struct option stat_options[] = {
                     "aggregate counts per thread", AGGR_THREAD),
        OPT_SET_UINT(0, "per-node", &stat_config.aggr_mode,
                     "aggregate counts per numa node", AGGR_NODE),
-       OPT_INTEGER('D', "delay", &stat_config.initial_delay,
+       OPT_INTEGER('D', "delay", &target.initial_delay,
                    "ms to wait before starting measurement after program start (-1: start with events disabled)"),
        OPT_CALLBACK_NOOPT(0, "metric-only", &stat_config.metric_only, NULL,
                        "Only print computed metrics. No raw values", enable_metric_only),
index d90f8d102eb99eeb2a8a8ce8af3269a35907e889..97598d14e532354826c37186e5f55a3f4ef35ffa 100644 (file)
@@ -40,19 +40,6 @@ def is_counter_value(num):
   return isfloat(num) or num == '<not counted>' or num == '<not supported>'
 
 def check_json_output(expected_items):
-  if expected_items != -1:
-    for line in Lines:
-      if 'failed' not in line:
-        count = 0
-        count = line.count(',')
-        if count != expected_items and count >= 1 and count <= 3 and 'metric-value' in line:
-          # Events that generate >1 metric may have isolated metric
-          # values and possibly other prefixes like interval, core and
-          # aggregate-number.
-          continue
-        if count != expected_items:
-          raise RuntimeError(f'wrong number of fields. counted {count} expected {expected_items}'
-                             f' in \'{line}\'')
   checks = {
       'aggregate-number': lambda x: isfloat(x),
       'core': lambda x: True,
@@ -73,6 +60,16 @@ def check_json_output(expected_items):
   }
   input = '[\n' + ','.join(Lines) + '\n]'
   for item in json.loads(input):
+    if expected_items != -1:
+      count = len(item)
+      if count != expected_items and count >= 1 and count <= 4 and 'metric-value' in item:
+        # Events that generate >1 metric may have isolated metric
+        # values and possibly other prefixes like interval, core and
+        # aggregate-number.
+        pass
+      elif count != expected_items:
+        raise RuntimeError(f'wrong number of fields. counted {count} expected {expected_items}'
+                           f' in \'{item}\'')
     for key, value in item.items():
       if key not in checks:
         raise RuntimeError(f'Unexpected key: key={key} value={value}')
@@ -82,11 +79,11 @@ def check_json_output(expected_items):
 
 try:
   if args.no_args or args.system_wide or args.event:
-    expected_items = 6
-  elif args.interval or args.per_thread or args.system_wide_no_aggr:
     expected_items = 7
-  elif args.per_core or args.per_socket or args.per_node or args.per_die:
+  elif args.interval or args.per_thread or args.system_wide_no_aggr:
     expected_items = 8
+  elif args.per_core or args.per_socket or args.per_node or args.per_die:
+    expected_items = 9
   else:
     # If no option is specified, don't check the number of items.
     expected_items = -1
index b7f050aa6210c92177c7a80a9b2bbf3e08fd2f4f..324fc9e6edd79c91c5a5f4e71ac52b90f475fcd2 100755 (executable)
@@ -7,6 +7,7 @@
 set -e
 
 skip_test=0
+csv_sep=@
 
 function commachecker()
 {
@@ -34,7 +35,7 @@ function commachecker()
                [ "$x" = "Failed" ] && continue
 
                # Count the number of commas
-               x=$(echo $line | tr -d -c ',')
+               x=$(echo $line | tr -d -c $csv_sep)
                cnt="${#x}"
                # echo $line $cnt
                [[ ! "$cnt" =~ $exp ]] && {
@@ -54,7 +55,7 @@ function ParanoidAndNotRoot()
 check_no_args()
 {
        echo -n "Checking CSV output: no args "
-       perf stat -x, true 2>&1 | commachecker --no-args
+       perf stat -x$csv_sep true 2>&1 | commachecker --no-args
        echo "[Success]"
 }
 
@@ -66,7 +67,7 @@ check_system_wide()
                echo "[Skip] paranoid and not root"
                return
        fi
-       perf stat -x, -a true 2>&1 | commachecker --system-wide
+       perf stat -x$csv_sep -a true 2>&1 | commachecker --system-wide
        echo "[Success]"
 }
 
@@ -79,14 +80,14 @@ check_system_wide_no_aggr()
                return
        fi
        echo -n "Checking CSV output: system wide no aggregation "
-       perf stat -x, -A -a --no-merge true 2>&1 | commachecker --system-wide-no-aggr
+       perf stat -x$csv_sep -A -a --no-merge true 2>&1 | commachecker --system-wide-no-aggr
        echo "[Success]"
 }
 
 check_interval()
 {
        echo -n "Checking CSV output: interval "
-       perf stat -x, -I 1000 true 2>&1 | commachecker --interval
+       perf stat -x$csv_sep -I 1000 true 2>&1 | commachecker --interval
        echo "[Success]"
 }
 
@@ -94,7 +95,7 @@ check_interval()
 check_event()
 {
        echo -n "Checking CSV output: event "
-       perf stat -x, -e cpu-clock true 2>&1 | commachecker --event
+       perf stat -x$csv_sep -e cpu-clock true 2>&1 | commachecker --event
        echo "[Success]"
 }
 
@@ -106,7 +107,7 @@ check_per_core()
                echo "[Skip] paranoid and not root"
                return
        fi
-       perf stat -x, --per-core -a true 2>&1 | commachecker --per-core
+       perf stat -x$csv_sep --per-core -a true 2>&1 | commachecker --per-core
        echo "[Success]"
 }
 
@@ -118,7 +119,7 @@ check_per_thread()
                echo "[Skip] paranoid and not root"
                return
        fi
-       perf stat -x, --per-thread -a true 2>&1 | commachecker --per-thread
+       perf stat -x$csv_sep --per-thread -a true 2>&1 | commachecker --per-thread
        echo "[Success]"
 }
 
@@ -130,7 +131,7 @@ check_per_die()
                echo "[Skip] paranoid and not root"
                return
        fi
-       perf stat -x, --per-die -a true 2>&1 | commachecker --per-die
+       perf stat -x$csv_sep --per-die -a true 2>&1 | commachecker --per-die
        echo "[Success]"
 }
 
@@ -142,7 +143,7 @@ check_per_node()
                echo "[Skip] paranoid and not root"
                return
        fi
-       perf stat -x, --per-node -a true 2>&1 | commachecker --per-node
+       perf stat -x$csv_sep --per-node -a true 2>&1 | commachecker --per-node
        echo "[Success]"
 }
 
@@ -154,7 +155,7 @@ check_per_socket()
                echo "[Skip] paranoid and not root"
                return
        fi
-       perf stat -x, --per-socket -a true 2>&1 | commachecker --per-socket
+       perf stat -x$csv_sep --per-socket -a true 2>&1 | commachecker --per-socket
        echo "[Success]"
 }
 
index 38e3b287dbb225885f24d31acebff75d24e5dab1..d877a0a9731f9f2fd6295cc3ef75c6320c697af0 100644 (file)
@@ -277,7 +277,7 @@ int on_switch(u64 *ctx)
        else
                prev_state = get_task_state(prev);
 
-       return off_cpu_stat(ctx, prev, next, prev_state);
+       return off_cpu_stat(ctx, prev, next, prev_state & 0xff);
 }
 
 char LICENSE[] SEC("license") = "Dual BSD/GPL";
index 534d36d26fc38a5ae9c94ce917e581eb6fd6e856..a07473703c6dd65fe2f8ba1295704aa45d6dd4ae 100644 (file)
@@ -842,11 +842,7 @@ int create_perf_stat_counter(struct evsel *evsel,
        if (evsel__is_group_leader(evsel)) {
                attr->disabled = 1;
 
-               /*
-                * In case of initial_delay we enable tracee
-                * events manually.
-                */
-               if (target__none(target) && !config->initial_delay)
+               if (target__enable_on_exec(target))
                        attr->enable_on_exec = 1;
        }
 
index b1c29156c560f83304d75e947df441235519d701..bf1794ebc916d56d25de420d811cd33e01141545 100644 (file)
@@ -166,7 +166,6 @@ struct perf_stat_config {
        FILE                    *output;
        unsigned int             interval;
        unsigned int             timeout;
-       int                      initial_delay;
        unsigned int             unit_width;
        unsigned int             metric_only_len;
        int                      times;
index daec6cba500d4ecb1ee5e3dc739f612df055e60f..880f1af7f6ad6ac220077c5157035f3f918b4205 100644 (file)
@@ -18,6 +18,7 @@ struct target {
        bool         per_thread;
        bool         use_bpf;
        bool         hybrid;
+       int          initial_delay;
        const char   *attr_map;
 };
 
@@ -72,6 +73,17 @@ static inline bool target__none(struct target *target)
        return !target__has_task(target) && !target__has_cpu(target);
 }
 
+static inline bool target__enable_on_exec(struct target *target)
+{
+       /*
+        * Normally enable_on_exec should be set if:
+        *  1) The tracee process is forked (not attaching to existed task or cpu).
+        *  2) And initial_delay is not configured.
+        * Otherwise, we enable tracee events manually.
+        */
+       return target__none(target) && !target->initial_delay;
+}
+
 static inline bool target__has_per_thread(struct target *target)
 {
        return target->system_wide && target->per_thread;
index 52aa0351533c315e4c7bfd4e6a318642757c5e73..388c9e3ad0407b8b536dc69ffc6ea91d0ddd27f6 100644 (file)
@@ -97,7 +97,7 @@ static struct option long_options[] = {
 static void parse_options(int argc, char **argv)
 {
        int option_index = 0;
-       char *pathname;
+       char *pathname, *endptr;
        int opt;
 
        pathname = strdup(argv[0]);
@@ -125,11 +125,23 @@ static void parse_options(int argc, char **argv)
                        log_getinfo = 1;
                        break;
                case 'T':
-                       log_type = atoi(optarg);
+                       log_type = strtol(optarg, &endptr, 0);
+                       if (*endptr || (log_type != 0 && log_type != 1)) {
+                               printf("Number expected: type(0:execution, 1:history) - Quit.\n");
+                               exit(1);
+                       }
+
                        set_log_type = 1;
                        break;
                case 'L':
-                       log_level = atoi(optarg);
+                       log_level = strtol(optarg, &endptr, 0);
+                       if (*endptr ||
+                           (log_level != 0 && log_level != 1 &&
+                            log_level != 2 && log_level != 4)) {
+                               printf("Number expected: level(0, 1, 2, 4) - Quit.\n");
+                               exit(1);
+                       }
+
                        set_log_level = 1;
                        break;
                case 'R':
index 82c09cd25cc2189e405d4cbefed5665514fee50a..bf4ac24a1c7aa818dc3bb96d2e2e070613ebe03a 100755 (executable)
@@ -5556,9 +5556,8 @@ def executeSuspend(quiet=False):
                if not quiet:
                        pprint('CAPTURING TRACE')
                op = sv.writeDatafileHeader(sv.ftracefile, testdata)
-               fp = open(tp+'trace', 'r')
-               for line in fp:
-                       op.write(line)
+               fp = open(tp+'trace', 'rb')
+               op.write(ascii(fp.read()))
                op.close()
                sv.fsetVal('', 'trace')
                sv.platforminfo(cmdafter)
index c7b26a3603afecc8d7bc1f8d282a8857d979268e..8f08c3fd498d5b81185519728fc1c28a8a0d4d5f 100644 (file)
@@ -340,10 +340,12 @@ starts a new interval.
 must be run as root.
 Alternatively, non-root users can be enabled to run turbostat this way:
 
-# setcap cap_sys_admin,cap_sys_rawio,cap_sys_nice=+ep ./turbostat
+# setcap cap_sys_admin,cap_sys_rawio,cap_sys_nice=+ep path/to/turbostat
 
 # chmod +r /dev/cpu/*/msr
 
+# chmod +r /dev/cpu_dma_latency
+
 .B "turbostat "
 reads hardware counters, but doesn't write them.
 So it will not interfere with the OS or other programs, including
index aba460410dbd1b040942806edf676b01b163da8e..8a36ba5df9f90a0dc7c5ecd52b929de4d7b9eafb 100644 (file)
@@ -3,7 +3,7 @@
  * turbostat -- show CPU frequency and C-state residency
  * on modern Intel and AMD processors.
  *
- * Copyright (c) 2022 Intel Corporation.
+ * Copyright (c) 2023 Intel Corporation.
  * Len Brown <len.brown@intel.com>
  */
 
@@ -670,7 +670,7 @@ static int perf_instr_count_open(int cpu_num)
        /* counter for cpu_num, including user + kernel and all processes */
        fd = perf_event_open(&pea, -1, cpu_num, -1, 0);
        if (fd == -1) {
-               warn("cpu%d: perf instruction counter", cpu_num);
+               warnx("capget(CAP_PERFMON) failed, try \"# setcap cap_sys_admin=ep %s\"", progname);
                BIC_NOT_PRESENT(BIC_IPC);
        }
 
@@ -2538,7 +2538,7 @@ static void dump_turbo_ratio_limits(int trl_msr_offset, int family, int model)
 
        get_msr(base_cpu, trl_msr_offset, &msr);
        fprintf(outf, "cpu%d: MSR_%sTURBO_RATIO_LIMIT: 0x%08llx\n",
-               base_cpu, trl_msr_offset == MSR_SECONDARY_TURBO_RATIO_LIMIT ? "SECONDARY" : "", msr);
+               base_cpu, trl_msr_offset == MSR_SECONDARY_TURBO_RATIO_LIMIT ? "SECONDARY_" : "", msr);
 
        if (has_turbo_ratio_group_limits(family, model)) {
                get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &core_counts);
@@ -3502,9 +3502,6 @@ release_msr:
 /*
  * set_my_sched_priority(pri)
  * return previous
- *
- * if non-root, do this:
- * # /sbin/setcap cap_sys_rawio,cap_sys_nice=+ep /usr/bin/turbostat
  */
 int set_my_sched_priority(int priority)
 {
@@ -3518,7 +3515,7 @@ int set_my_sched_priority(int priority)
 
        retval = setpriority(PRIO_PROCESS, 0, priority);
        if (retval)
-               err(retval, "setpriority(%d)", priority);
+               errx(retval, "capget(CAP_SYS_NICE) failed,try \"# setcap cap_sys_nice=ep %s\"", progname);
 
        errno = 0;
        retval = getpriority(PRIO_PROCESS, 0);
@@ -4426,7 +4423,7 @@ int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p)
 
        fprintf(outf, "cpu%d: MSR_HWP_STATUS: 0x%08llx "
                "(%sGuaranteed_Perf_Change, %sExcursion_Min)\n",
-               cpu, msr, ((msr) & 0x1) ? "" : "No-", ((msr) & 0x2) ? "" : "No-");
+               cpu, msr, ((msr) & 0x1) ? "" : "No-", ((msr) & 0x4) ? "" : "No-");
 
        return 0;
 }
@@ -5463,6 +5460,9 @@ unsigned int intel_model_duplicates(unsigned int model)
 
        case INTEL_FAM6_ICELAKE_D:
                return INTEL_FAM6_ICELAKE_X;
+
+       case INTEL_FAM6_EMERALDRAPIDS_X:
+               return INTEL_FAM6_SAPPHIRERAPIDS_X;
        }
        return model;
 }
@@ -5476,13 +5476,13 @@ void print_dev_latency(void)
 
        fd = open(path, O_RDONLY);
        if (fd < 0) {
-               warn("fopen %s\n", path);
+               warnx("capget(CAP_SYS_ADMIN) failed, try \"# setcap cap_sys_admin=ep %s\"", progname);
                return;
        }
 
        retval = read(fd, (void *)&value, sizeof(int));
        if (retval != sizeof(int)) {
-               warn("read %s\n", path);
+               warn("read failed %s", path);
                close(fd);
                return;
        }
@@ -5543,7 +5543,7 @@ void process_cpuid()
        edx_flags = edx;
 
        if (get_msr(sched_getcpu(), MSR_IA32_UCODE_REV, &ucode_patch))
-               warnx("get_msr(UCODE)\n");
+               warnx("get_msr(UCODE)");
 
        /*
         * check max extended function levels of CPUID.
@@ -6225,7 +6225,7 @@ int get_and_dump_counters(void)
 
 void print_version()
 {
-       fprintf(outf, "turbostat version 2022.10.04 - Len Brown <lenb@kernel.org>\n");
+       fprintf(outf, "turbostat version 2023.03.17 - Len Brown <lenb@kernel.org>\n");
 }
 
 #define COMMAND_LINE_SIZE 2048
old mode 100644 (file)
new mode 100755 (executable)
index e565697..08a39ad
@@ -1,11 +1,25 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0+
-#
-# Extract any RCU CPU stall warnings present in specified file.
-# Filter out clocksource lines.  Note that preceding-lines excludes the
-# initial line of the stall warning but trailing-lines includes it.
-#
-# Usage: extract-stall.sh dmesg-file [ preceding-lines [ trailing-lines ] ]
+
+usage() {
+       echo Extract any RCU CPU stall warnings present in specified file.
+       echo Filter out clocksource lines.  Note that preceding-lines excludes the
+       echo initial line of the stall warning but trailing-lines includes it.
+       echo
+       echo Usage: $(basename $0) dmesg-file [ preceding-lines [ trailing-lines ] ]
+       echo
+       echo Error: $1
+}
+
+# Terminate the script, if the argument is missing
+
+if test -f "$1" && test -r "$1"
+then
+       :
+else
+       usage "Console log file \"$1\" missing or unreadable."
+       exit 1
+fi
 
 echo $1
 preceding_lines="${2-3}"
index 741f15420467aecda526d84a62935a19ca4ec936..3905c43369c32245c2f3d8716403f450923aac27 100755 (executable)
@@ -123,7 +123,7 @@ def _suites_from_test_list(tests: List[str]) -> List[str]:
                parts = t.split('.', maxsplit=2)
                if len(parts) != 2:
                        raise ValueError(f'internal KUnit error, test name should be of the form "<suite>.<test>", got "{t}"')
-               suite, case = parts
+               suite, _ = parts
                if not suites or suites[-1] != suite:
                        suites.append(suite)
        return suites
@@ -269,7 +269,7 @@ def massage_argv(argv: Sequence[str]) -> Sequence[str]:
 def get_default_jobs() -> int:
        return len(os.sched_getaffinity(0))
 
-def add_common_opts(parser) -> None:
+def add_common_opts(parser: argparse.ArgumentParser) -> None:
        parser.add_argument('--build_dir',
                            help='As in the make command, it specifies the build '
                            'directory.',
@@ -320,13 +320,13 @@ def add_common_opts(parser) -> None:
                            help='Additional QEMU arguments, e.g. "-smp 8"',
                            action='append', metavar='')
 
-def add_build_opts(parser) -> None:
+def add_build_opts(parser: argparse.ArgumentParser) -> None:
        parser.add_argument('--jobs',
                            help='As in the make command, "Specifies  the number of '
                            'jobs (commands) to run simultaneously."',
                            type=int, default=get_default_jobs(), metavar='N')
 
-def add_exec_opts(parser) -> None:
+def add_exec_opts(parser: argparse.ArgumentParser) -> None:
        parser.add_argument('--timeout',
                            help='maximum number of seconds to allow for all tests '
                            'to run. This does not include time taken to build the '
@@ -351,7 +351,7 @@ def add_exec_opts(parser) -> None:
                            type=str,
                            choices=['suite', 'test'])
 
-def add_parse_opts(parser) -> None:
+def add_parse_opts(parser: argparse.ArgumentParser) -> None:
        parser.add_argument('--raw_output', help='If set don\'t parse output from kernel. '
                            'By default, filters to just KUnit output. Use '
                            '--raw_output=all to show everything',
@@ -386,7 +386,7 @@ def tree_from_args(cli_args: argparse.Namespace) -> kunit_kernel.LinuxSourceTree
                        extra_qemu_args=qemu_args)
 
 
-def run_handler(cli_args):
+def run_handler(cli_args: argparse.Namespace) -> None:
        if not os.path.exists(cli_args.build_dir):
                os.mkdir(cli_args.build_dir)
 
@@ -405,7 +405,7 @@ def run_handler(cli_args):
                sys.exit(1)
 
 
-def config_handler(cli_args):
+def config_handler(cli_args: argparse.Namespace) -> None:
        if cli_args.build_dir and (
                        not os.path.exists(cli_args.build_dir)):
                os.mkdir(cli_args.build_dir)
@@ -421,7 +421,7 @@ def config_handler(cli_args):
                sys.exit(1)
 
 
-def build_handler(cli_args):
+def build_handler(cli_args: argparse.Namespace) -> None:
        linux = tree_from_args(cli_args)
        request = KunitBuildRequest(build_dir=cli_args.build_dir,
                                        make_options=cli_args.make_options,
@@ -434,7 +434,7 @@ def build_handler(cli_args):
                sys.exit(1)
 
 
-def exec_handler(cli_args):
+def exec_handler(cli_args: argparse.Namespace) -> None:
        linux = tree_from_args(cli_args)
        exec_request = KunitExecRequest(raw_output=cli_args.raw_output,
                                        build_dir=cli_args.build_dir,
@@ -450,10 +450,10 @@ def exec_handler(cli_args):
                sys.exit(1)
 
 
-def parse_handler(cli_args):
+def parse_handler(cli_args: argparse.Namespace) -> None:
        if cli_args.file is None:
-               sys.stdin.reconfigure(errors='backslashreplace')  # pytype: disable=attribute-error
-               kunit_output = sys.stdin
+               sys.stdin.reconfigure(errors='backslashreplace')  # type: ignore
+               kunit_output = sys.stdin  # type: Iterable[str]
        else:
                with open(cli_args.file, 'r', errors='backslashreplace') as f:
                        kunit_output = f.read().splitlines()
@@ -475,7 +475,7 @@ subcommand_handlers_map = {
 }
 
 
-def main(argv):
+def main(argv: Sequence[str]) -> None:
        parser = argparse.ArgumentParser(
                        description='Helps writing and running KUnit tests.')
        subparser = parser.add_subparsers(dest='subcommand')
index 48b5f34b2e5d7b0200f7de193e43f454cc7ac832..eb5dd01210b1b41b805779b0733134e6de31cd99 100644 (file)
@@ -8,7 +8,7 @@
 
 from dataclasses import dataclass
 import re
-from typing import Dict, Iterable, List, Set, Tuple
+from typing import Any, Dict, Iterable, List, Tuple
 
 CONFIG_IS_NOT_SET_PATTERN = r'^# CONFIG_(\w+) is not set$'
 CONFIG_PATTERN = r'^CONFIG_(\w+)=(\S+|".*")$'
@@ -34,7 +34,7 @@ class Kconfig:
        def __init__(self) -> None:
                self._entries = {}  # type: Dict[str, str]
 
-       def __eq__(self, other) -> bool:
+       def __eq__(self, other: Any) -> bool:
                if not isinstance(other, self.__class__):
                        return False
                return self._entries == other._entries
index 53e90c3358348dbef24c2bdba395decf60b95ab2..f01f9410612965037e6510028351b566ac7ae382 100644 (file)
@@ -16,9 +16,9 @@ import shutil
 import signal
 import threading
 from typing import Iterator, List, Optional, Tuple
+from types import FrameType
 
 import kunit_config
-from kunit_printer import stdout
 import qemu_config
 
 KCONFIG_PATH = '.config'
@@ -57,7 +57,7 @@ class LinuxSourceTreeOperations:
        def make_arch_config(self, base_kunitconfig: kunit_config.Kconfig) -> kunit_config.Kconfig:
                return base_kunitconfig
 
-       def make_olddefconfig(self, build_dir: str, make_options) -> None:
+       def make_olddefconfig(self, build_dir: str, make_options: Optional[List[str]]) -> None:
                command = ['make', 'ARCH=' + self._linux_arch, 'O=' + build_dir, 'olddefconfig']
                if self._cross_compile:
                        command += ['CROSS_COMPILE=' + self._cross_compile]
@@ -71,7 +71,7 @@ class LinuxSourceTreeOperations:
                except subprocess.CalledProcessError as e:
                        raise ConfigError(e.output.decode())
 
-       def make(self, jobs, build_dir: str, make_options) -> None:
+       def make(self, jobs: int, build_dir: str, make_options: Optional[List[str]]) -> None:
                command = ['make', 'ARCH=' + self._linux_arch, 'O=' + build_dir, '--jobs=' + str(jobs)]
                if make_options:
                        command.extend(make_options)
@@ -92,7 +92,7 @@ class LinuxSourceTreeOperations:
                if stderr:  # likely only due to build warnings
                        print(stderr.decode())
 
-       def start(self, params: List[str], build_dir: str) -> subprocess.Popen:
+       def start(self, params: List[str], build_dir: str) -> subprocess.Popen[str]:
                raise RuntimeError('not implemented!')
 
 
@@ -106,13 +106,14 @@ class LinuxSourceTreeOperationsQemu(LinuxSourceTreeOperations):
                self._kernel_path = qemu_arch_params.kernel_path
                self._kernel_command_line = qemu_arch_params.kernel_command_line + ' kunit_shutdown=reboot'
                self._extra_qemu_params = qemu_arch_params.extra_qemu_params
+               self._serial = qemu_arch_params.serial
 
        def make_arch_config(self, base_kunitconfig: kunit_config.Kconfig) -> kunit_config.Kconfig:
                kconfig = kunit_config.parse_from_string(self._kconfig)
                kconfig.merge_in_entries(base_kunitconfig)
                return kconfig
 
-       def start(self, params: List[str], build_dir: str) -> subprocess.Popen:
+       def start(self, params: List[str], build_dir: str) -> subprocess.Popen[str]:
                kernel_path = os.path.join(build_dir, self._kernel_path)
                qemu_command = ['qemu-system-' + self._qemu_arch,
                                '-nodefaults',
@@ -121,7 +122,7 @@ class LinuxSourceTreeOperationsQemu(LinuxSourceTreeOperations):
                                '-append', ' '.join(params + [self._kernel_command_line]),
                                '-no-reboot',
                                '-nographic',
-                               '-serial', 'stdio'] + self._extra_qemu_params
+                               '-serial', self._serial] + self._extra_qemu_params
                # Note: shlex.join() does what we want, but requires python 3.8+.
                print('Running tests with:\n$', ' '.join(shlex.quote(arg) for arg in qemu_command))
                return subprocess.Popen(qemu_command,
@@ -133,7 +134,7 @@ class LinuxSourceTreeOperationsQemu(LinuxSourceTreeOperations):
 class LinuxSourceTreeOperationsUml(LinuxSourceTreeOperations):
        """An abstraction over command line operations performed on a source tree."""
 
-       def __init__(self, cross_compile=None):
+       def __init__(self, cross_compile: Optional[str]=None):
                super().__init__(linux_arch='um', cross_compile=cross_compile)
 
        def make_arch_config(self, base_kunitconfig: kunit_config.Kconfig) -> kunit_config.Kconfig:
@@ -141,7 +142,7 @@ class LinuxSourceTreeOperationsUml(LinuxSourceTreeOperations):
                kconfig.merge_in_entries(base_kunitconfig)
                return kconfig
 
-       def start(self, params: List[str], build_dir: str) -> subprocess.Popen:
+       def start(self, params: List[str], build_dir: str) -> subprocess.Popen[str]:
                """Runs the Linux UML binary. Must be named 'linux'."""
                linux_bin = os.path.join(build_dir, 'linux')
                params.extend(['mem=1G', 'console=tty', 'kunit_shutdown=halt'])
@@ -216,7 +217,7 @@ def _get_qemu_ops(config_path: str,
 
        if not hasattr(config, 'QEMU_ARCH'):
                raise ValueError('qemu_config module missing "QEMU_ARCH": ' + config_path)
-       params: qemu_config.QemuArchParams = config.QEMU_ARCH  # type: ignore
+       params: qemu_config.QemuArchParams = config.QEMU_ARCH
        if extra_qemu_args:
                params.extra_qemu_params.extend(extra_qemu_args)
        return params.linux_arch, LinuxSourceTreeOperationsQemu(
@@ -230,10 +231,10 @@ class LinuxSourceTree:
              build_dir: str,
              kunitconfig_paths: Optional[List[str]]=None,
              kconfig_add: Optional[List[str]]=None,
-             arch=None,
-             cross_compile=None,
-             qemu_config_path=None,
-             extra_qemu_args=None) -> None:
+             arch: Optional[str]=None,
+             cross_compile: Optional[str]=None,
+             qemu_config_path: Optional[str]=None,
+             extra_qemu_args: Optional[List[str]]=None) -> None:
                signal.signal(signal.SIGINT, self.signal_handler)
                if qemu_config_path:
                        self._arch, self._ops = _get_qemu_ops(qemu_config_path, extra_qemu_args, cross_compile)
@@ -276,7 +277,7 @@ class LinuxSourceTree:
                logging.error(message)
                return False
 
-       def build_config(self, build_dir: str, make_options) -> bool:
+       def build_config(self, build_dir: str, make_options: Optional[List[str]]) -> bool:
                kconfig_path = get_kconfig_path(build_dir)
                if build_dir and not os.path.exists(build_dir):
                        os.mkdir(build_dir)
@@ -304,7 +305,7 @@ class LinuxSourceTree:
                old_kconfig = kunit_config.parse_file(old_path)
                return old_kconfig != self._kconfig
 
-       def build_reconfig(self, build_dir: str, make_options) -> bool:
+       def build_reconfig(self, build_dir: str, make_options: Optional[List[str]]) -> bool:
                """Creates a new .config if it is not a subset of the .kunitconfig."""
                kconfig_path = get_kconfig_path(build_dir)
                if not os.path.exists(kconfig_path):
@@ -320,7 +321,7 @@ class LinuxSourceTree:
                os.remove(kconfig_path)
                return self.build_config(build_dir, make_options)
 
-       def build_kernel(self, jobs, build_dir: str, make_options) -> bool:
+       def build_kernel(self, jobs: int, build_dir: str, make_options: Optional[List[str]]) -> bool:
                try:
                        self._ops.make_olddefconfig(build_dir, make_options)
                        self._ops.make(jobs, build_dir, make_options)
@@ -329,7 +330,7 @@ class LinuxSourceTree:
                        return False
                return self.validate_config(build_dir)
 
-       def run_kernel(self, args=None, build_dir='', filter_glob='', timeout=None) -> Iterator[str]:
+       def run_kernel(self, args: Optional[List[str]]=None, build_dir: str='', filter_glob: str='', timeout: Optional[int]=None) -> Iterator[str]:
                if not args:
                        args = []
                if filter_glob:
@@ -340,7 +341,7 @@ class LinuxSourceTree:
                assert process.stdout is not None  # tell mypy it's set
 
                # Enforce the timeout in a background thread.
-               def _wait_proc():
+               def _wait_proc() -> None:
                        try:
                                process.wait(timeout=timeout)
                        except Exception as e:
@@ -366,6 +367,6 @@ class LinuxSourceTree:
                        waiter.join()
                        subprocess.call(['stty', 'sane'])
 
-       def signal_handler(self, unused_sig, unused_frame) -> None:
+       def signal_handler(self, unused_sig: int, unused_frame: Optional[FrameType]) -> None:
                logging.error('Build interruption occurred. Cleaning console.')
                subprocess.call(['stty', 'sane'])
index a225799f6b1b9e1e8346d10d8655fff8c8922518..fbc094f0567e660c098c0c10acb2b8281cf276f8 100644 (file)
@@ -12,7 +12,6 @@
 from __future__ import annotations
 from dataclasses import dataclass
 import re
-import sys
 import textwrap
 
 from enum import Enum, auto
index 5f1cc55ecdf5893e75e5b5f8a2bf2923ed8b40bc..015adf87dc2c773ac164d4979c2b3a7f96c63aa5 100644 (file)
@@ -15,7 +15,7 @@ _RESET = '\033[0;0m'
 class Printer:
        """Wraps a file object, providing utilities for coloring output, etc."""
 
-       def __init__(self, output: typing.IO):
+       def __init__(self, output: typing.IO[str]):
                self._output = output
                self._use_color = output.isatty()
 
index 0c2190514103faa78433fe5d2fb15139ae68293f..be35999bb84f14dd2909756fdfa8b0673fdd8f95 100755 (executable)
@@ -328,7 +328,7 @@ class KUnitParserTest(unittest.TestCase):
        def test_parse_subtest_header(self):
                ktap_log = test_data_path('test_parse_subtest_header.log')
                with open(ktap_log) as file:
-                       result = kunit_parser.parse_run_tests(file.readlines())
+                       kunit_parser.parse_run_tests(file.readlines())
                self.print_mock.assert_any_call(StrContains('suite (1 subtest)'))
 
        def test_show_test_output_on_failure(self):
index 0b6a80398cccb50fee5fe94def150c0761d96c20..b1fba9016eed00d010c853f2910c9624e01d4af5 100644 (file)
@@ -17,3 +17,4 @@ class QemuArchParams:
   kernel_path: str
   kernel_command_line: str
   extra_qemu_params: List[str]
+  serial: str = 'stdio'
diff --git a/tools/testing/kunit/qemu_configs/m68k.py b/tools/testing/kunit/qemu_configs/m68k.py
new file mode 100644 (file)
index 0000000..287fc38
--- /dev/null
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-only
+from ..qemu_config import QemuArchParams
+
+QEMU_ARCH = QemuArchParams(linux_arch='m68k',
+                          kconfig='''
+CONFIG_VIRT=y''',
+                          qemu_arch='m68k',
+                          kernel_path='vmlinux',
+                          kernel_command_line='console=hvc0',
+                          extra_qemu_params=['-machine', 'virt'])
diff --git a/tools/testing/kunit/qemu_configs/sh.py b/tools/testing/kunit/qemu_configs/sh.py
new file mode 100644 (file)
index 0000000..78a474a
--- /dev/null
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0-only
+from ..qemu_config import QemuArchParams
+
+QEMU_ARCH = QemuArchParams(linux_arch='sh',
+                          kconfig='''
+CONFIG_CPU_SUBTYPE_SH7751R=y
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_SH_RTS7751R2D=y
+CONFIG_RTS7751R2D_PLUS=y
+CONFIG_SERIAL_SH_SCI=y''',
+                          qemu_arch='sh4',
+                          kernel_path='arch/sh/boot/zImage',
+                          kernel_command_line='console=ttySC1',
+                          serial='null',
+                          extra_qemu_params=[
+                                           '-machine', 'r2d',
+                                           '-serial', 'mon:stdio'])
index 066e6f938f6dcccc23dcaff4faa48a30e301f7f4..8208c3b3135efe8ef41712b1a6d22d3ea31ffc16 100755 (executable)
@@ -23,7 +23,7 @@ commands: Dict[str, Sequence[str]] = {
        'kunit_tool_test.py': ['./kunit_tool_test.py'],
        'kunit smoke test': ['./kunit.py', 'run', '--kunitconfig=lib/kunit', '--build_dir=kunit_run_checks'],
        'pytype': ['/bin/sh', '-c', 'pytype *.py'],
-       'mypy': ['/bin/sh', '-c', 'mypy *.py'],
+       'mypy': ['mypy', '--strict', '--exclude', '_test.py$', '--exclude', 'qemu_configs/', '.'],
 }
 
 # The user might not have mypy or pytype installed, skip them if so.
@@ -37,7 +37,7 @@ def main(argv: Sequence[str]) -> None:
        if argv:
                raise RuntimeError('This script takes no arguments')
 
-       future_to_name: Dict[futures.Future, str] = {}
+       future_to_name: Dict[futures.Future[None], str] = {}
        executor = futures.ThreadPoolExecutor(max_workers=len(commands))
        for name, argv in commands.items():
                if name in necessary_deps and shutil.which(necessary_deps[name]) is None:
@@ -73,7 +73,7 @@ def main(argv: Sequence[str]) -> None:
                sys.exit(1)
 
 
-def run_cmd(argv: Sequence[str]):
+def run_cmd(argv: Sequence[str]) -> None:
        subprocess.check_output(argv, stderr=subprocess.STDOUT, cwd=ABS_TOOL_PATH, timeout=TIMEOUT)
 
 
index 958ee9bdb3166df00ce3160160d2a546cb1353f0..4c89ff333f6f080eee71832a6e7e4e36d964ca4d 100644 (file)
@@ -108,6 +108,7 @@ static noinline void check_new_node(struct maple_tree *mt)
        MT_BUG_ON(mt, mn->slot[1] != NULL);
        MT_BUG_ON(mt, mas_allocated(&mas) != 0);
 
+       mn->parent = ma_parent_ptr(mn);
        ma_free_rcu(mn);
        mas.node = MAS_START;
        mas_nomem(&mas, GFP_KERNEL);
@@ -160,6 +161,7 @@ static noinline void check_new_node(struct maple_tree *mt)
                MT_BUG_ON(mt, mas_allocated(&mas) != i);
                MT_BUG_ON(mt, !mn);
                MT_BUG_ON(mt, not_empty(mn));
+               mn->parent = ma_parent_ptr(mn);
                ma_free_rcu(mn);
        }
 
@@ -192,6 +194,7 @@ static noinline void check_new_node(struct maple_tree *mt)
                MT_BUG_ON(mt, not_empty(mn));
                MT_BUG_ON(mt, mas_allocated(&mas) != i - 1);
                MT_BUG_ON(mt, !mn);
+               mn->parent = ma_parent_ptr(mn);
                ma_free_rcu(mn);
        }
 
@@ -210,6 +213,7 @@ static noinline void check_new_node(struct maple_tree *mt)
                        mn = mas_pop_node(&mas);
                        MT_BUG_ON(mt, not_empty(mn));
                        MT_BUG_ON(mt, mas_allocated(&mas) != j - 1);
+                       mn->parent = ma_parent_ptr(mn);
                        ma_free_rcu(mn);
                }
                MT_BUG_ON(mt, mas_allocated(&mas) != 0);
@@ -233,6 +237,7 @@ static noinline void check_new_node(struct maple_tree *mt)
                        MT_BUG_ON(mt, mas_allocated(&mas) != i - j);
                        mn = mas_pop_node(&mas);
                        MT_BUG_ON(mt, not_empty(mn));
+                       mn->parent = ma_parent_ptr(mn);
                        ma_free_rcu(mn);
                        MT_BUG_ON(mt, mas_allocated(&mas) != i - j - 1);
                }
@@ -269,6 +274,7 @@ static noinline void check_new_node(struct maple_tree *mt)
                        mn = mas_pop_node(&mas); /* get the next node. */
                        MT_BUG_ON(mt, mn == NULL);
                        MT_BUG_ON(mt, not_empty(mn));
+                       mn->parent = ma_parent_ptr(mn);
                        ma_free_rcu(mn);
                }
                MT_BUG_ON(mt, mas_allocated(&mas) != 0);
@@ -294,6 +300,7 @@ static noinline void check_new_node(struct maple_tree *mt)
                        mn = mas_pop_node(&mas2); /* get the next node. */
                        MT_BUG_ON(mt, mn == NULL);
                        MT_BUG_ON(mt, not_empty(mn));
+                       mn->parent = ma_parent_ptr(mn);
                        ma_free_rcu(mn);
                }
                MT_BUG_ON(mt, mas_allocated(&mas2) != 0);
@@ -334,10 +341,12 @@ static noinline void check_new_node(struct maple_tree *mt)
        MT_BUG_ON(mt, mas_allocated(&mas) != MAPLE_ALLOC_SLOTS + 2);
        mn = mas_pop_node(&mas);
        MT_BUG_ON(mt, not_empty(mn));
+       mn->parent = ma_parent_ptr(mn);
        ma_free_rcu(mn);
        for (i = 1; i <= MAPLE_ALLOC_SLOTS + 1; i++) {
                mn = mas_pop_node(&mas);
                MT_BUG_ON(mt, not_empty(mn));
+               mn->parent = ma_parent_ptr(mn);
                ma_free_rcu(mn);
        }
        MT_BUG_ON(mt, mas_allocated(&mas) != 0);
@@ -375,6 +384,7 @@ static noinline void check_new_node(struct maple_tree *mt)
                mas_node_count(&mas, i); /* Request */
                mas_nomem(&mas, GFP_KERNEL); /* Fill request */
                mn = mas_pop_node(&mas); /* get the next node. */
+               mn->parent = ma_parent_ptr(mn);
                ma_free_rcu(mn);
                mas_destroy(&mas);
 
@@ -382,10 +392,13 @@ static noinline void check_new_node(struct maple_tree *mt)
                mas_node_count(&mas, i); /* Request */
                mas_nomem(&mas, GFP_KERNEL); /* Fill request */
                mn = mas_pop_node(&mas); /* get the next node. */
+               mn->parent = ma_parent_ptr(mn);
                ma_free_rcu(mn);
                mn = mas_pop_node(&mas); /* get the next node. */
+               mn->parent = ma_parent_ptr(mn);
                ma_free_rcu(mn);
                mn = mas_pop_node(&mas); /* get the next node. */
+               mn->parent = ma_parent_ptr(mn);
                ma_free_rcu(mn);
                mas_destroy(&mas);
        }
@@ -35369,6 +35382,7 @@ static noinline void check_prealloc(struct maple_tree *mt)
        MT_BUG_ON(mt, allocated != 1 + height * 3);
        mn = mas_pop_node(&mas);
        MT_BUG_ON(mt, mas_allocated(&mas) != allocated - 1);
+       mn->parent = ma_parent_ptr(mn);
        ma_free_rcu(mn);
        MT_BUG_ON(mt, mas_preallocate(&mas, GFP_KERNEL) != 0);
        mas_destroy(&mas);
@@ -35386,6 +35400,7 @@ static noinline void check_prealloc(struct maple_tree *mt)
        mas_destroy(&mas);
        allocated = mas_allocated(&mas);
        MT_BUG_ON(mt, allocated != 0);
+       mn->parent = ma_parent_ptr(mn);
        ma_free_rcu(mn);
 
        MT_BUG_ON(mt, mas_preallocate(&mas, GFP_KERNEL) != 0);
@@ -35756,6 +35771,7 @@ void farmer_tests(void)
        tree.ma_root = mt_mk_node(node, maple_leaf_64);
        mt_dump(&tree);
 
+       node->parent = ma_parent_ptr(node);
        ma_free_rcu(node);
 
        /* Check things that will make lockdep angry */
index 13a6837a0c6bc62902833292e10d055cafdbc6c1..97dcdaa656f6e6bcff0d765e66a638785a7393ca 100644 (file)
@@ -58,6 +58,7 @@ TARGETS += nsfs
 TARGETS += pidfd
 TARGETS += pid_namespace
 TARGETS += powerpc
+TARGETS += prctl
 TARGETS += proc
 TARGETS += pstore
 TARGETS += ptrace
index 5fd1424db37d82c399b4bfda72652e54c38dfe4c..c382f579fe94a73120e25233ab9da267557bd07b 100644 (file)
@@ -4,10 +4,15 @@
 # No binaries, but make sure arg-less "make" doesn't trigger "run_tests"
 all:
 
-uname_M := $(shell uname -m 2>/dev/null || echo not)
-ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
+ARCH ?= $(shell uname -m 2>/dev/null || echo not)
+ARCH := $(shell echo $(ARCH) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
 
-TEST_PROGS := run.sh
-TEST_FILES := basic.sh tbench.sh gitsource.sh
+ifeq (x86,$(ARCH))
+TEST_FILES += ../../../power/x86/amd_pstate_tracer/amd_pstate_trace.py
+TEST_FILES += ../../../power/x86/intel_pstate_tracer/intel_pstate_tracer.py
+endif
+
+TEST_PROGS += run.sh
+TEST_FILES += basic.sh tbench.sh gitsource.sh
 
 include ../lib.mk
index dbc1fe45599d6a70c5f1fd425254d7e1b2538370..5f2171f0116de323558e958f2f99dae14162f9d1 100755 (executable)
@@ -117,7 +117,7 @@ parse_gitsource()
        printf "Gitsource-$1-#$2 power consumption(J): $en_sum\n" | tee -a $OUTFILE_GIT.result
 
        # Permance is the number of run gitsource per second, denoted 1/t, where 1 is the number of run gitsource in t
-       # senconds. It is well known that P=E/t, where P is power measured in watts(W), E is energy measured in joules(J),
+       # seconds. It is well known that P=E/t, where P is power measured in watts(W), E is energy measured in joules(J),
        # and t is time measured in seconds(s). This means that performance per watt becomes
        #        1/t     1/t     1
        #       ----- = ----- = ---
@@ -175,7 +175,7 @@ gather_gitsource()
        printf "Gitsource-$1 avg power consumption(J): $avg_en\n" | tee -a $OUTFILE_GIT.result
 
        # Permance is the number of run gitsource per second, denoted 1/t, where 1 is the number of run gitsource in t
-       # senconds. It is well known that P=E/t, where P is power measured in watts(W), E is energy measured in joules(J),
+       # seconds. It is well known that P=E/t, where P is power measured in watts(W), E is energy measured in joules(J),
        # and t is time measured in seconds(s). This means that performance per watt becomes
        #        1/t     1/t     1
        #       ----- = ----- = ---
index 57cad57e59c0e7815cdd08027215ae1cdca5570b..de4d8e9c9565d0af58f764cbbd182644fa7a0091 100755 (executable)
@@ -244,7 +244,7 @@ prerequisite()
                if [ "$scaling_driver" != "$CURRENT_TEST" ]; then
                        echo "$0 # Skipped: Test can only run on $CURRENT_TEST driver or run comparative test."
                        echo "$0 # Please set X86_AMD_PSTATE enabled or run comparative test."
-                       echo "$0 # Current cpufreq scaling drvier is $scaling_driver."
+                       echo "$0 # Current cpufreq scaling driver is $scaling_driver."
                        exit $ksft_skip
                fi
        else
@@ -252,7 +252,7 @@ prerequisite()
                        "tbench" | "gitsource")
                                if [ "$scaling_driver" != "$COMPARATIVE_TEST" ]; then
                                        echo "$0 # Skipped: Comparison test can only run on $COMPARISON_TEST driver."
-                                       echo "$0 # Current cpufreq scaling drvier is $scaling_driver."
+                                       echo "$0 # Current cpufreq scaling driver is $scaling_driver."
                                        exit $ksft_skip
                                fi
                                ;;
index 48f56c86ad4579970300940813c94340712b9ac0..b413b0af07f990c70c3c9ef94386eae62843bd68 100644 (file)
@@ -38,7 +38,7 @@ $(OUTPUT)/vec-syscfg: vec-syscfg.c $(OUTPUT)/rdvl.o
 $(OUTPUT)/vlset: vlset.c
 $(OUTPUT)/za-fork: za-fork.c $(OUTPUT)/za-fork-asm.o
        $(CC) -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \
-               -include ../../../../include/nolibc/nolibc.h \
+               -include ../../../../include/nolibc/nolibc.h -I../..\
                -static -ffreestanding -Wall $^ -o $@
 $(OUTPUT)/za-ptrace: za-ptrace.c
 $(OUTPUT)/za-test: za-test.S $(OUTPUT)/asm-utils.o
index ff475c649e96698eab7c0613c131d4a2025d0b6d..b86cb1049497f39647566dcf03e39a96a69e2d23 100644 (file)
@@ -9,42 +9,9 @@
 #include <linux/sched.h>
 #include <linux/wait.h>
 
-#define EXPECTED_TESTS 1
-
-static void putstr(const char *str)
-{
-       write(1, str, strlen(str));
-}
-
-static void putnum(unsigned int num)
-{
-       char c;
-
-       if (num / 10)
-               putnum(num / 10);
-
-       c = '0' + (num % 10);
-       write(1, &c, 1);
-}
+#include "kselftest.h"
 
-static int tests_run;
-static int tests_passed;
-static int tests_failed;
-static int tests_skipped;
-
-static void print_summary(void)
-{
-       if (tests_passed + tests_failed + tests_skipped != EXPECTED_TESTS)
-               putstr("# UNEXPECTED TEST COUNT: ");
-
-       putstr("# Totals: pass:");
-       putnum(tests_passed);
-       putstr(" fail:");
-       putnum(tests_failed);
-       putstr(" xfail:0 xpass:0 skip:");
-       putnum(tests_skipped);
-       putstr(" error:0\n");
-}
+#define EXPECTED_TESTS 1
 
 int fork_test(void);
 int verify_fork(void);
@@ -63,22 +30,21 @@ int fork_test_c(void)
        if (newpid == 0) {
                /* In child */
                if (!verify_fork()) {
-                       putstr("# ZA state invalid in child\n");
+                       ksft_print_msg("ZA state invalid in child\n");
                        exit(0);
                } else {
                        exit(1);
                }
        }
        if (newpid < 0) {
-               putstr("# fork() failed: -");
-               putnum(-newpid);
-               putstr("\n");
+               ksft_print_msg("fork() failed: %d\n", newpid);
+
                return 0;
        }
 
        parent_result = verify_fork();
        if (!parent_result)
-               putstr("# ZA state invalid in parent\n");
+               ksft_print_msg("ZA state invalid in parent\n");
 
        for (;;) {
                waiting = waitpid(newpid, &child_status, 0);
@@ -86,18 +52,16 @@ int fork_test_c(void)
                if (waiting < 0) {
                        if (errno == EINTR)
                                continue;
-                       putstr("# waitpid() failed: ");
-                       putnum(errno);
-                       putstr("\n");
+                       ksft_print_msg("waitpid() failed: %d\n", errno);
                        return 0;
                }
                if (waiting != newpid) {
-                       putstr("# waitpid() returned wrong PID\n");
+                       ksft_print_msg("waitpid() returned wrong PID\n");
                        return 0;
                }
 
                if (!WIFEXITED(child_status)) {
-                       putstr("# child did not exit\n");
+                       ksft_print_msg("child did not exit\n");
                        return 0;
                }
 
@@ -105,29 +69,14 @@ int fork_test_c(void)
        }
 }
 
-#define run_test(name)                      \
-       if (name()) {                        \
-               tests_passed++;              \
-       } else {                             \
-               tests_failed++;              \
-               putstr("not ");              \
-       }                                    \
-       putstr("ok ");                       \
-       putnum(++tests_run);                 \
-       putstr(" " #name "\n");
-
 int main(int argc, char **argv)
 {
        int ret, i;
 
-       putstr("TAP version 13\n");
-       putstr("1..");
-       putnum(EXPECTED_TESTS);
-       putstr("\n");
+       ksft_print_header();
+       ksft_set_plan(EXPECTED_TESTS);
 
-       putstr("# PID: ");
-       putnum(getpid());
-       putstr("\n");
+       ksft_print_msg("PID: %d\n", getpid());
 
        /*
         * This test is run with nolibc which doesn't support hwcap and
@@ -136,21 +85,16 @@ int main(int argc, char **argv)
         */
        ret = open("/proc/sys/abi/sme_default_vector_length", O_RDONLY, 0);
        if (ret >= 0) {
-               run_test(fork_test);
+               ksft_test_result(fork_test(), "fork_test");
 
        } else {
-               putstr("# SME support not present\n");
-
+               ksft_print_msg("SME not supported\n");
                for (i = 0; i < EXPECTED_TESTS; i++) {
-                       putstr("ok ");
-                       putnum(i);
-                       putstr(" skipped\n");
+                       ksft_test_result_skip("fork_test\n");
                }
-
-               tests_skipped += EXPECTED_TESTS;
        }
 
-       print_summary();
+       ksft_finished();
 
        return 0;
 }
index cbb600be943d338a3c36f699d4698ee8f8b30222..210d643fda6c7b6d4eadc02e64fed0498dc0b5ee 100644 (file)
@@ -879,6 +879,34 @@ static struct btf_raw_test raw_tests[] = {
        .btf_load_err = true,
        .err_str = "Invalid elem",
 },
+{
+       .descr = "var after datasec, ptr followed by modifier",
+       .raw_types = {
+               /* .bss section */                              /* [1] */
+               BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2),
+                       sizeof(void*)+4),
+               BTF_VAR_SECINFO_ENC(4, 0, sizeof(void*)),
+               BTF_VAR_SECINFO_ENC(6, sizeof(void*), 4),
+               /* int */                                       /* [2] */
+               BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+               /* int* */                                      /* [3] */
+               BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
+               BTF_VAR_ENC(NAME_TBD, 3, 0),                    /* [4] */
+               /* const int */                                 /* [5] */
+               BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
+               BTF_VAR_ENC(NAME_TBD, 5, 0),                    /* [6] */
+               BTF_END_RAW,
+       },
+       .str_sec = "\0a\0b\0c\0",
+       .str_sec_size = sizeof("\0a\0b\0c\0"),
+       .map_type = BPF_MAP_TYPE_ARRAY,
+       .map_name = ".bss",
+       .key_size = sizeof(int),
+       .value_size = sizeof(void*)+4,
+       .key_type_id = 0,
+       .value_type_id = 1,
+       .max_entries = 1,
+},
 /* Test member exceeds the size of struct.
  *
  * struct A {
diff --git a/tools/testing/selftests/bpf/prog_tests/uninit_stack.c b/tools/testing/selftests/bpf/prog_tests/uninit_stack.c
new file mode 100644 (file)
index 0000000..e64c719
--- /dev/null
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <test_progs.h>
+#include "uninit_stack.skel.h"
+
+void test_uninit_stack(void)
+{
+       RUN_TESTS(uninit_stack);
+}
index 2666c84dbd014a4576366ea7338ccf51e10e1f05..8251a0fc6ee94d80403298b9cb69fabf4c0bc4dc 100644 (file)
@@ -65,12 +65,13 @@ static int attach_tc_prog(struct bpf_tc_hook *hook, int fd)
 }
 
 /* The maximum permissible size is: PAGE_SIZE - sizeof(struct xdp_page_head) -
- * sizeof(struct skb_shared_info) - XDP_PACKET_HEADROOM = 3368 bytes
+ * SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) - XDP_PACKET_HEADROOM =
+ * 3408 bytes for 64-byte cacheline and 3216 for 256-byte one.
  */
 #if defined(__s390x__)
-#define MAX_PKT_SIZE 3176
+#define MAX_PKT_SIZE 3216
 #else
-#define MAX_PKT_SIZE 3368
+#define MAX_PKT_SIZE 3408
 #endif
 static void test_max_pkt_size(int fd)
 {
@@ -166,8 +167,7 @@ void test_xdp_do_redirect(void)
 
        if (!ASSERT_EQ(query_opts.feature_flags,
                       NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
-                      NETDEV_XDP_ACT_NDO_XMIT | NETDEV_XDP_ACT_RX_SG |
-                      NETDEV_XDP_ACT_NDO_XMIT_SG,
+                      NETDEV_XDP_ACT_RX_SG,
                       "veth_src query_opts.feature_flags"))
                goto out;
 
@@ -175,11 +175,36 @@ void test_xdp_do_redirect(void)
        if (!ASSERT_OK(err, "veth_dst bpf_xdp_query"))
                goto out;
 
+       if (!ASSERT_EQ(query_opts.feature_flags,
+                      NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                      NETDEV_XDP_ACT_RX_SG,
+                      "veth_dst query_opts.feature_flags"))
+               goto out;
+
+       /* Enable GRO */
+       SYS("ethtool -K veth_src gro on");
+       SYS("ethtool -K veth_dst gro on");
+
+       err = bpf_xdp_query(ifindex_src, XDP_FLAGS_DRV_MODE, &query_opts);
+       if (!ASSERT_OK(err, "veth_src bpf_xdp_query gro on"))
+               goto out;
+
        if (!ASSERT_EQ(query_opts.feature_flags,
                       NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
                       NETDEV_XDP_ACT_NDO_XMIT | NETDEV_XDP_ACT_RX_SG |
                       NETDEV_XDP_ACT_NDO_XMIT_SG,
-                      "veth_dst query_opts.feature_flags"))
+                      "veth_src query_opts.feature_flags gro on"))
+               goto out;
+
+       err = bpf_xdp_query(ifindex_dst, XDP_FLAGS_DRV_MODE, &query_opts);
+       if (!ASSERT_OK(err, "veth_dst bpf_xdp_query gro on"))
+               goto out;
+
+       if (!ASSERT_EQ(query_opts.feature_flags,
+                      NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                      NETDEV_XDP_ACT_NDO_XMIT | NETDEV_XDP_ACT_RX_SG |
+                      NETDEV_XDP_ACT_NDO_XMIT_SG,
+                      "veth_dst query_opts.feature_flags gro on"))
                goto out;
 
        memcpy(skel->rodata->expect_dst, &pkt_udp.eth.h_dest, ETH_ALEN);
index aa4beae99f4f6ed6df6f2c60d9b8470f229dd1b7..8c5e98da9ae9f036889eda11508573b8e27fe751 100644 (file)
@@ -273,6 +273,8 @@ static int verify_xsk_metadata(struct xsk *xsk)
        if (!ASSERT_NEQ(meta->rx_hash, 0, "rx_hash"))
                return -1;
 
+       ASSERT_EQ(meta->rx_hash_type, 0, "rx_hash_type");
+
        xsk_ring_cons__release(&xsk->rx, 1);
        refill_rx(xsk, comp_addr);
 
index b3b326b8e2d1cb38cf374d18737529ce0fb7d9a4..6dab9cffda132b755c554fcddb67af752b22187a 100644 (file)
@@ -2,6 +2,7 @@
 /* Copyright (c) 2021 Facebook */
 #include "vmlinux.h"
 #include <bpf/bpf_helpers.h>
+#define vm_flags vm_start
 
 char _license[] SEC("license") = "GPL";
 
index 591104e79812ef2918c23f84b692790fe519f8fc..e96b901a733c5878d48de3dc1dcc3f4dd32f89af 100644 (file)
@@ -5,12 +5,10 @@
 #include <errno.h>
 #include <linux/capability.h>
 
-struct kernel_cap_struct {
-       __u64 val;
-} __attribute__((preserve_access_index));
+typedef struct { unsigned long long val; } kernel_cap_t;
 
 struct cred {
-       struct kernel_cap_struct cap_effective;
+       kernel_cap_t cap_effective;
 } __attribute__((preserve_access_index));
 
 char _license[] SEC("license") = "GPL";
@@ -18,8 +16,8 @@ char _license[] SEC("license") = "GPL";
 SEC("lsm.s/userns_create")
 int BPF_PROG(test_userns_create, const struct cred *cred, int ret)
 {
-       struct kernel_cap_struct caps = cred->cap_effective;
-       __u64 cap_mask = BIT_LL(CAP_SYS_ADMIN);
+       kernel_cap_t caps = cred->cap_effective;
+       __u64 cap_mask = 1ULL << CAP_SYS_ADMIN;
 
        if (ret)
                return 0;
index 98327bdbbfd24700900ac94667bb7e0269d9a1fd..8fba3f3649e227d521c84caac140ccf9dc5812a8 100644 (file)
@@ -5,12 +5,12 @@
 #include "bpf_misc.h"
 
 struct Small {
-       int x;
+       long x;
 };
 
 struct Big {
-       int x;
-       int y;
+       long x;
+       long y;
 };
 
 __noinline int foo(const struct Big *big)
@@ -22,7 +22,7 @@ __noinline int foo(const struct Big *big)
 }
 
 SEC("cgroup_skb/ingress")
-__failure __msg("invalid indirect read from stack")
+__failure __msg("invalid indirect access to stack")
 int global_func10(struct __sk_buff *skb)
 {
        const struct Small small = {.x = skb->len };
diff --git a/tools/testing/selftests/bpf/progs/uninit_stack.c b/tools/testing/selftests/bpf/progs/uninit_stack.c
new file mode 100644 (file)
index 0000000..8a40347
--- /dev/null
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+#include "bpf_misc.h"
+
+/* Read an uninitialized value from stack at a fixed offset */
+SEC("socket")
+__naked int read_uninit_stack_fixed_off(void *ctx)
+{
+       asm volatile ("                                 \
+               r0 = 0;                                 \
+               /* force stack depth to be 128 */       \
+               *(u64*)(r10 - 128) = r1;                \
+               r1 = *(u8 *)(r10 - 8 );                 \
+               r0 += r1;                               \
+               r1 = *(u8 *)(r10 - 11);                 \
+               r1 = *(u8 *)(r10 - 13);                 \
+               r1 = *(u8 *)(r10 - 15);                 \
+               r1 = *(u16*)(r10 - 16);                 \
+               r1 = *(u32*)(r10 - 32);                 \
+               r1 = *(u64*)(r10 - 64);                 \
+               /* read from a spill of a wrong size, it is a separate  \
+                * branch in check_stack_read_fixed_off()               \
+                */                                     \
+               *(u32*)(r10 - 72) = r1;                 \
+               r1 = *(u64*)(r10 - 72);                 \
+               r0 = 0;                                 \
+               exit;                                   \
+"
+                     ::: __clobber_all);
+}
+
+/* Read an uninitialized value from stack at a variable offset */
+SEC("socket")
+__naked int read_uninit_stack_var_off(void *ctx)
+{
+       asm volatile ("                                 \
+               call %[bpf_get_prandom_u32];            \
+               /* force stack depth to be 64 */        \
+               *(u64*)(r10 - 64) = r0;                 \
+               r0 = -r0;                               \
+               /* give r0 a range [-31, -1] */         \
+               if r0 s<= -32 goto exit_%=;             \
+               if r0 s>= 0 goto exit_%=;               \
+               /* access stack using r0 */             \
+               r1 = r10;                               \
+               r1 += r0;                               \
+               r2 = *(u8*)(r1 + 0);                    \
+exit_%=:       r0 = 0;                                 \
+               exit;                                   \
+"
+                     :
+                     : __imm(bpf_get_prandom_u32)
+                     : __clobber_all);
+}
+
+static __noinline void dummy(void) {}
+
+/* Pass a pointer to uninitialized stack memory to a helper.
+ * Passed memory block should be marked as STACK_MISC after helper call.
+ */
+SEC("socket")
+__log_level(7) __msg("fp-104=mmmmmmmm")
+__naked int helper_uninit_to_misc(void *ctx)
+{
+       asm volatile ("                                 \
+               /* force stack depth to be 128 */       \
+               *(u64*)(r10 - 128) = r1;                \
+               r1 = r10;                               \
+               r1 += -128;                             \
+               r2 = 32;                                \
+               call %[bpf_trace_printk];               \
+               /* Call to dummy() forces print_verifier_state(..., true),      \
+                * thus showing the stack state, matched by __msg().            \
+                */                                     \
+               call %[dummy];                          \
+               r0 = 0;                                 \
+               exit;                                   \
+"
+                     :
+                     : __imm(bpf_trace_printk),
+                       __imm(dummy)
+                     : __clobber_all);
+}
+
+char _license[] SEC("license") = "GPL";
index 4c55b4d79d3d44744b52b6485e0ecaa26e4a9b69..e1c787815e44bba5a9f1e41d4649f84f16f1510f 100644 (file)
@@ -12,10 +12,14 @@ struct {
        __type(value, __u32);
 } xsk SEC(".maps");
 
+__u64 pkts_skip = 0;
+__u64 pkts_fail = 0;
+__u64 pkts_redir = 0;
+
 extern int bpf_xdp_metadata_rx_timestamp(const struct xdp_md *ctx,
                                         __u64 *timestamp) __ksym;
-extern int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx,
-                                   __u32 *hash) __ksym;
+extern int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, __u32 *hash,
+                                   enum xdp_rss_hash_type *rss_type) __ksym;
 
 SEC("xdp")
 int rx(struct xdp_md *ctx)
@@ -26,7 +30,7 @@ int rx(struct xdp_md *ctx)
        struct udphdr *udp = NULL;
        struct iphdr *iph = NULL;
        struct xdp_meta *meta;
-       int ret;
+       int err;
 
        data = (void *)(long)ctx->data;
        data_end = (void *)(long)ctx->data_end;
@@ -46,17 +50,20 @@ int rx(struct xdp_md *ctx)
                        udp = NULL;
        }
 
-       if (!udp)
+       if (!udp) {
+               __sync_add_and_fetch(&pkts_skip, 1);
                return XDP_PASS;
+       }
 
-       if (udp->dest != bpf_htons(9091))
+       /* Forwarding UDP:9091 to AF_XDP */
+       if (udp->dest != bpf_htons(9091)) {
+               __sync_add_and_fetch(&pkts_skip, 1);
                return XDP_PASS;
+       }
 
-       bpf_printk("forwarding UDP:9091 to AF_XDP");
-
-       ret = bpf_xdp_adjust_meta(ctx, -(int)sizeof(struct xdp_meta));
-       if (ret != 0) {
-               bpf_printk("bpf_xdp_adjust_meta returned %d", ret);
+       err = bpf_xdp_adjust_meta(ctx, -(int)sizeof(struct xdp_meta));
+       if (err) {
+               __sync_add_and_fetch(&pkts_fail, 1);
                return XDP_PASS;
        }
 
@@ -65,20 +72,19 @@ int rx(struct xdp_md *ctx)
        meta = data_meta;
 
        if (meta + 1 > data) {
-               bpf_printk("bpf_xdp_adjust_meta doesn't appear to work");
+               __sync_add_and_fetch(&pkts_fail, 1);
                return XDP_PASS;
        }
 
-       if (!bpf_xdp_metadata_rx_timestamp(ctx, &meta->rx_timestamp))
-               bpf_printk("populated rx_timestamp with %llu", meta->rx_timestamp);
-       else
+       err = bpf_xdp_metadata_rx_timestamp(ctx, &meta->rx_timestamp);
+       if (err)
                meta->rx_timestamp = 0; /* Used by AF_XDP as not avail signal */
 
-       if (!bpf_xdp_metadata_rx_hash(ctx, &meta->rx_hash))
-               bpf_printk("populated rx_hash with %u", meta->rx_hash);
-       else
-               meta->rx_hash = 0; /* Used by AF_XDP as not avail signal */
+       err = bpf_xdp_metadata_rx_hash(ctx, &meta->rx_hash, &meta->rx_hash_type);
+       if (err < 0)
+               meta->rx_hash_err = err; /* Used by AF_XDP as no hash signal */
 
+       __sync_add_and_fetch(&pkts_redir, 1);
        return bpf_redirect_map(&xsk, ctx->rx_queue_index, XDP_PASS);
 }
 
index 77678b03438970c7bbc6c1b3102739d9c9baf71f..d151d406a123efc004c1fb09f28844adccade711 100644 (file)
@@ -21,8 +21,8 @@ struct {
 
 extern int bpf_xdp_metadata_rx_timestamp(const struct xdp_md *ctx,
                                         __u64 *timestamp) __ksym;
-extern int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx,
-                                   __u32 *hash) __ksym;
+extern int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, __u32 *hash,
+                                   enum xdp_rss_hash_type *rss_type) __ksym;
 
 SEC("xdp")
 int rx(struct xdp_md *ctx)
@@ -56,7 +56,7 @@ int rx(struct xdp_md *ctx)
        if (timestamp == 0)
                meta->rx_timestamp = 1;
 
-       bpf_xdp_metadata_rx_hash(ctx, &meta->rx_hash);
+       bpf_xdp_metadata_rx_hash(ctx, &meta->rx_hash, &meta->rx_hash_type);
 
        return bpf_redirect_map(&xsk, ctx->rx_queue_index, XDP_PASS);
 }
index cf69d05451c39b5873fb823491a1a8c4010f9b5d..85f88d9d7a78565d4239a6fb6a18ae6a36d03f6e 100644 (file)
@@ -5,17 +5,18 @@
 #include <bpf/bpf_helpers.h>
 #include <bpf/bpf_endian.h>
 
-extern int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx,
-                                   __u32 *hash) __ksym;
+extern int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, __u32 *hash,
+                                   enum xdp_rss_hash_type *rss_type) __ksym;
 
 int called;
 
 SEC("freplace/rx")
 int freplace_rx(struct xdp_md *ctx)
 {
+       enum xdp_rss_hash_type type = 0;
        u32 hash = 0;
        /* Call _any_ metadata function to make sure we don't crash. */
-       bpf_xdp_metadata_rx_hash(ctx, &hash);
+       bpf_xdp_metadata_rx_hash(ctx, &hash, &type);
        called++;
        return XDP_PASS;
 }
index 9d993926bf0efb6a582077db5f751e496c98ef9e..289ed202ec66aec63d11e492a5ed60906e906500 100644 (file)
         * that fp-8 stack slot was unused in the fall-through
         * branch and will accept the program incorrectly
         */
-       BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 2),
+       BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
+       BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 2, 2),
        BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
        BPF_JMP_IMM(BPF_JA, 0, 0, 0),
        BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
        BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
        BPF_LD_MAP_FD(BPF_REG_1, 0),
        BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
+       BPF_MOV64_IMM(BPF_REG_0, 0),
        BPF_EXIT_INSN(),
        },
-       .fixup_map_hash_48b = { 6 },
-       .errstr = "invalid indirect read from stack R2 off -8+0 size 8",
-       .result = REJECT,
-       .prog_type = BPF_PROG_TYPE_XDP,
+       .fixup_map_hash_48b = { 7 },
+       .errstr_unpriv = "invalid indirect read from stack R2 off -8+0 size 8",
+       .result_unpriv = REJECT,
+       /* in privileged mode reads from uninitialized stack locations are permitted */
+       .result = ACCEPT,
 },
 {
        "calls: ctx read at start of subprog",
index a6c869a7319cd23a4ed5cae14e4aa0a80dad94c9..9c4885885aba0627b558136347267479e5436ea1 100644 (file)
 {
        "helper access to variable memory: stack, bitwise AND, zero included",
        .insns = {
-       BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, 8),
-       BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
-       BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
-       BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
-       BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
-       BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
-       BPF_MOV64_IMM(BPF_REG_3, 0),
-       BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
+       /* set max stack size */
+       BPF_ST_MEM(BPF_DW, BPF_REG_10, -128, 0),
+       /* set r3 to a random value */
+       BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
+       /* use bitwise AND to limit r3 range to [0, 64] */
+       BPF_ALU64_IMM(BPF_AND, BPF_REG_3, 64),
+       BPF_LD_MAP_FD(BPF_REG_1, 0),
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+       BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
+       BPF_MOV64_IMM(BPF_REG_4, 0),
+       /* Call bpf_ringbuf_output(), it is one of a few helper functions with
+        * ARG_CONST_SIZE_OR_ZERO parameter allowed in unpriv mode.
+        * For unpriv this should signal an error, because memory at &fp[-64] is
+        * not initialized.
+        */
+       BPF_EMIT_CALL(BPF_FUNC_ringbuf_output),
        BPF_EXIT_INSN(),
        },
-       .errstr = "invalid indirect read from stack R1 off -64+0 size 64",
-       .result = REJECT,
-       .prog_type = BPF_PROG_TYPE_TRACEPOINT,
+       .fixup_map_ringbuf = { 4 },
+       .errstr_unpriv = "invalid indirect read from stack R2 off -64+0 size 64",
+       .result_unpriv = REJECT,
+       /* in privileged mode reads from uninitialized stack locations are permitted */
+       .result = ACCEPT,
 },
 {
        "helper access to variable memory: stack, bitwise AND + JMP, wrong max",
 {
        "helper access to variable memory: stack, JMP, no min check",
        .insns = {
-       BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, 8),
-       BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
-       BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
-       BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
-       BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
-       BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 3),
-       BPF_MOV64_IMM(BPF_REG_3, 0),
-       BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
+       /* set max stack size */
+       BPF_ST_MEM(BPF_DW, BPF_REG_10, -128, 0),
+       /* set r3 to a random value */
+       BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
+       /* use JMP to limit r3 range to [0, 64] */
+       BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 64, 6),
+       BPF_LD_MAP_FD(BPF_REG_1, 0),
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+       BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
+       BPF_MOV64_IMM(BPF_REG_4, 0),
+       /* Call bpf_ringbuf_output(), it is one of a few helper functions with
+        * ARG_CONST_SIZE_OR_ZERO parameter allowed in unpriv mode.
+        * For unpriv this should signal an error, because memory at &fp[-64] is
+        * not initialized.
+        */
+       BPF_EMIT_CALL(BPF_FUNC_ringbuf_output),
        BPF_MOV64_IMM(BPF_REG_0, 0),
        BPF_EXIT_INSN(),
        },
-       .errstr = "invalid indirect read from stack R1 off -64+0 size 64",
-       .result = REJECT,
-       .prog_type = BPF_PROG_TYPE_TRACEPOINT,
+       .fixup_map_ringbuf = { 4 },
+       .errstr_unpriv = "invalid indirect read from stack R2 off -64+0 size 64",
+       .result_unpriv = REJECT,
+       /* in privileged mode reads from uninitialized stack locations are permitted */
+       .result = ACCEPT,
 },
 {
        "helper access to variable memory: stack, JMP (signed), no min check",
 {
        "helper access to variable memory: 8 bytes leak",
        .insns = {
-       BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, 8),
-       BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
-       BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
+       /* set max stack size */
+       BPF_ST_MEM(BPF_DW, BPF_REG_10, -128, 0),
+       /* set r3 to a random value */
+       BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
+       BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
+       BPF_LD_MAP_FD(BPF_REG_1, 0),
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+       BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
        BPF_MOV64_IMM(BPF_REG_0, 0),
        BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
        BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
        BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
        BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
+       /* Note: fp[-32] left uninitialized */
        BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
        BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
        BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
-       BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
-       BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
-       BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 63),
-       BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
-       BPF_MOV64_IMM(BPF_REG_3, 0),
-       BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
-       BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
+       /* Limit r3 range to [1, 64] */
+       BPF_ALU64_IMM(BPF_AND, BPF_REG_3, 63),
+       BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 1),
+       BPF_MOV64_IMM(BPF_REG_4, 0),
+       /* Call bpf_ringbuf_output(), it is one of a few helper functions with
+        * ARG_CONST_SIZE_OR_ZERO parameter allowed in unpriv mode.
+        * For unpriv this should signal an error, because memory region [1, 64]
+        * at &fp[-64] is not fully initialized.
+        */
+       BPF_EMIT_CALL(BPF_FUNC_ringbuf_output),
+       BPF_MOV64_IMM(BPF_REG_0, 0),
        BPF_EXIT_INSN(),
        },
-       .errstr = "invalid indirect read from stack R1 off -64+32 size 64",
-       .result = REJECT,
-       .prog_type = BPF_PROG_TYPE_TRACEPOINT,
+       .fixup_map_ringbuf = { 3 },
+       .errstr_unpriv = "invalid indirect read from stack R2 off -64+32 size 64",
+       .result_unpriv = REJECT,
+       /* in privileged mode reads from uninitialized stack locations are permitted */
+       .result = ACCEPT,
 },
 {
        "helper access to variable memory: 8 bytes no leak (init memory)",
index 070893fb290074c0c68f1dae454993123eef5c02..02d9e004260b333944c29aed33e82c3d51e96a00 100644 (file)
                /* bpf_strtoul() */
                BPF_EMIT_CALL(BPF_FUNC_strtoul),
 
-               BPF_MOV64_IMM(BPF_REG_0, 1),
+               BPF_MOV64_IMM(BPF_REG_0, 0),
                BPF_EXIT_INSN(),
        },
-       .result = REJECT,
-       .prog_type = BPF_PROG_TYPE_CGROUP_SYSCTL,
-       .errstr = "invalid indirect read from stack R4 off -16+4 size 8",
+       .result_unpriv = REJECT,
+       .errstr_unpriv = "invalid indirect read from stack R4 off -16+4 size 8",
+       /* in privileged mode reads from uninitialized stack locations are permitted */
+       .result = ACCEPT,
 },
 {
        "ARG_PTR_TO_LONG misaligned",
index d63fd8991b03aa9e9f3f2ec1b3f03419f8a1686c..745d6b5842fd4e15e79820ea4c4cfd0659b14386 100644 (file)
                BPF_EXIT_INSN(),
        },
        .fixup_map_hash_8b = { 3 },
-       .errstr = "invalid read from stack off -16+0 size 8",
-       .result = REJECT,
-       .prog_type = BPF_PROG_TYPE_TRACEPOINT,
+       .errstr_unpriv = "invalid read from stack off -16+0 size 8",
+       .result_unpriv = REJECT,
+       /* in privileged mode reads from uninitialized stack locations are permitted */
+       .result = ACCEPT,
 },
 {
        "precision tracking for u32 spill/fill",
        BPF_EXIT_INSN(),
        },
        .flags = BPF_F_TEST_STATE_FREQ,
-       .errstr = "invalid read from stack off -8+1 size 8",
-       .result = REJECT,
+       .errstr_unpriv = "invalid read from stack off -8+1 size 8",
+       .result_unpriv = REJECT,
+       /* in privileged mode reads from uninitialized stack locations are permitted */
+       .result = ACCEPT,
 },
index d11d0b28be41672d35074d25c17a375b71be1061..108dd3ee1edda0cd9c326b85ed7b72b09b32cbd2 100644 (file)
        .prog_type = BPF_PROG_TYPE_SCHED_CLS,
        .result = ACCEPT,
 },
-{
-       "sk_storage_get(map, skb->sk, &stack_value, 1): partially init stack_value",
-       .insns = {
-       BPF_MOV64_IMM(BPF_REG_2, 0),
-       BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_2, -8),
-       BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, offsetof(struct __sk_buff, sk)),
-       BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
-       BPF_MOV64_IMM(BPF_REG_0, 0),
-       BPF_EXIT_INSN(),
-       BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
-       BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
-       BPF_MOV64_IMM(BPF_REG_0, 0),
-       BPF_EXIT_INSN(),
-       BPF_MOV64_IMM(BPF_REG_4, 1),
-       BPF_MOV64_REG(BPF_REG_3, BPF_REG_10),
-       BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, -8),
-       BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
-       BPF_LD_MAP_FD(BPF_REG_1, 0),
-       BPF_EMIT_CALL(BPF_FUNC_sk_storage_get),
-       BPF_MOV64_IMM(BPF_REG_0, 0),
-       BPF_EXIT_INSN(),
-       },
-       .fixup_sk_storage_map = { 14 },
-       .prog_type = BPF_PROG_TYPE_SCHED_CLS,
-       .result = REJECT,
-       .errstr = "invalid indirect read from stack",
-},
 {
        "bpf_map_lookup_elem(smap, &key)",
        .insns = {
index 9bb302dade237f250c705ff10826e7d40b8ec42f..d1463bf4949afd10188f25938a66c49cb75a2129 100644 (file)
        BPF_MOV64_IMM(BPF_REG_0, 0),
        BPF_EXIT_INSN(),
        },
-       .result = REJECT,
-       .errstr = "invalid read from stack off -4+0 size 4",
-       .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+       .result_unpriv = REJECT,
+       .errstr_unpriv = "invalid read from stack off -4+0 size 4",
+       /* in privileged mode reads from uninitialized stack locations are permitted */
+       .result = ACCEPT,
 },
 {
        "Spill a u32 const scalar.  Refill as u16.  Offset to skb->data",
index d37f512fad16e3b8fa2d1f46fd2974a9a6937217..b183e26c03f10c09a824b4fb51a432bf0ddc32df 100644 (file)
        .result = REJECT,
        .prog_type = BPF_PROG_TYPE_LWT_IN,
 },
-{
-       "indirect variable-offset stack access, max_off+size > max_initialized",
-       .insns = {
-       /* Fill only the second from top 8 bytes of the stack. */
-       BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
-       /* Get an unknown value. */
-       BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
-       /* Make it small and 4-byte aligned. */
-       BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
-       BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 16),
-       /* Add it to fp.  We now have either fp-12 or fp-16, but we don't know
-        * which. fp-12 size 8 is partially uninitialized stack.
-        */
-       BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
-       /* Dereference it indirectly. */
-       BPF_LD_MAP_FD(BPF_REG_1, 0),
-       BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
-       BPF_MOV64_IMM(BPF_REG_0, 0),
-       BPF_EXIT_INSN(),
-       },
-       .fixup_map_hash_8b = { 5 },
-       .errstr = "invalid indirect read from stack R2 var_off",
-       .result = REJECT,
-       .prog_type = BPF_PROG_TYPE_LWT_IN,
-},
 {
        "indirect variable-offset stack access, min_off < min_initialized",
        .insns = {
        .result = ACCEPT,
        .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
 },
-{
-       "indirect variable-offset stack access, uninitialized",
-       .insns = {
-       BPF_MOV64_IMM(BPF_REG_2, 6),
-       BPF_MOV64_IMM(BPF_REG_3, 28),
-       /* Fill the top 16 bytes of the stack. */
-       BPF_ST_MEM(BPF_W, BPF_REG_10, -16, 0),
-       BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
-       /* Get an unknown value. */
-       BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1, 0),
-       /* Make it small and 4-byte aligned. */
-       BPF_ALU64_IMM(BPF_AND, BPF_REG_4, 4),
-       BPF_ALU64_IMM(BPF_SUB, BPF_REG_4, 16),
-       /* Add it to fp.  We now have either fp-12 or fp-16, we don't know
-        * which, but either way it points to initialized stack.
-        */
-       BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_10),
-       BPF_MOV64_IMM(BPF_REG_5, 8),
-       /* Dereference it indirectly. */
-       BPF_EMIT_CALL(BPF_FUNC_getsockopt),
-       BPF_MOV64_IMM(BPF_REG_0, 0),
-       BPF_EXIT_INSN(),
-       },
-       .errstr = "invalid indirect read from stack R4 var_off",
-       .result = REJECT,
-       .prog_type = BPF_PROG_TYPE_SOCK_OPS,
-},
 {
        "indirect variable-offset stack access, ok",
        .insns = {
index 1c8acb68b977cd04bda4096fdde12344b1a3c54a..987cf0db5ebc80f70b3c62d641bc878ed8ee1805 100644 (file)
@@ -141,7 +141,11 @@ static void verify_xdp_metadata(void *data)
        meta = data - sizeof(*meta);
 
        printf("rx_timestamp: %llu\n", meta->rx_timestamp);
-       printf("rx_hash: %u\n", meta->rx_hash);
+       if (meta->rx_hash_err < 0)
+               printf("No rx_hash err=%d\n", meta->rx_hash_err);
+       else
+               printf("rx_hash: 0x%X with RSS type:0x%X\n",
+                      meta->rx_hash, meta->rx_hash_type);
 }
 
 static void verify_skb_metadata(int fd)
@@ -212,7 +216,9 @@ static int verify_metadata(struct xsk *rx_xsk, int rxq, int server_fd)
        while (true) {
                errno = 0;
                ret = poll(fds, rxq + 1, 1000);
-               printf("poll: %d (%d)\n", ret, errno);
+               printf("poll: %d (%d) skip=%llu fail=%llu redir=%llu\n",
+                      ret, errno, bpf_obj->bss->pkts_skip,
+                      bpf_obj->bss->pkts_fail, bpf_obj->bss->pkts_redir);
                if (ret < 0)
                        break;
                if (ret == 0)
index f6780fbb0a214765a14a293cf7fb0654e4a32297..0c4624dc6f2f719183b21e7e0bd1fbc9e6b72164 100644 (file)
@@ -12,4 +12,8 @@
 struct xdp_meta {
        __u64 rx_timestamp;
        __u32 rx_hash;
+       union {
+               __u32 rx_hash_type;
+               __s32 rx_hash_err;
+       };
 };
index 1e616a8c6a9cfd8035c3dff13ab5204d73d3d059..f4f7c0aef702b916a6a6adfd3f41ecce71b40f4c 100644 (file)
@@ -98,6 +98,11 @@ static int alloc_anon_50M_check(const char *cgroup, void *arg)
        int ret = -1;
 
        buf = malloc(size);
+       if (buf == NULL) {
+               fprintf(stderr, "malloc() failed\n");
+               return -1;
+       }
+
        for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
                *ptr = 0;
 
@@ -211,6 +216,11 @@ static int alloc_anon_noexit(const char *cgroup, void *arg)
        char *buf, *ptr;
 
        buf = malloc(size);
+       if (buf == NULL) {
+               fprintf(stderr, "malloc() failed\n");
+               return -1;
+       }
+
        for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
                *ptr = 0;
 
@@ -778,6 +788,11 @@ static int alloc_anon_50M_check_swap(const char *cgroup, void *arg)
        int ret = -1;
 
        buf = malloc(size);
+       if (buf == NULL) {
+               fprintf(stderr, "malloc() failed\n");
+               return -1;
+       }
+
        for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
                *ptr = 0;
 
index cd4582129c7d69c1e45b6a3acbd7a5f2c6c07e67..e495f895a2cdd0bc5bfe77bb8cfdfdf20c0584ed 100644 (file)
@@ -129,7 +129,7 @@ int main(int argc, char *argv[])
        uid_t uid = getuid();
 
        ksft_print_header();
-       ksft_set_plan(17);
+       ksft_set_plan(18);
        test_clone3_supported();
 
        /* Just a simple clone3() should return 0.*/
@@ -195,5 +195,8 @@ int main(int argc, char *argv[])
        test_clone3(CLONE_NEWPID, getpagesize() + 8, -E2BIG,
                        CLONE3_ARGS_NO_TEST);
 
-       return !ksft_get_fail_cnt() ? ksft_exit_pass() : ksft_exit_fail();
+       /* Do a clone3() in a new time namespace */
+       test_clone3(CLONE_NEWTIME, 0, 0, CLONE3_ARGS_NO_TEST);
+
+       ksft_finished();
 }
index 8e3b786a748f97bf7d288a25d97a614cd41210ca..03f92d7aeb19b970acfdb2d28ad882f630c12567 100644 (file)
@@ -8,10 +8,12 @@ TEST_PROGS := \
        dev_addr_lists.sh \
        mode-1-recovery-updelay.sh \
        mode-2-recovery-updelay.sh \
-       option_prio.sh
+       bond_options.sh \
+       bond-eth-type-change.sh
 
 TEST_FILES := \
        lag_lib.sh \
+       bond_topo_3d1c.sh \
        net_forwarding_lib.sh
 
 include ../../../lib.mk
diff --git a/tools/testing/selftests/drivers/net/bonding/bond-eth-type-change.sh b/tools/testing/selftests/drivers/net/bonding/bond-eth-type-change.sh
new file mode 100755 (executable)
index 0000000..5cdd220
--- /dev/null
@@ -0,0 +1,85 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Test bond device ether type changing
+#
+
+ALL_TESTS="
+       bond_test_unsuccessful_enslave_type_change
+       bond_test_successful_enslave_type_change
+"
+REQUIRE_MZ=no
+NUM_NETIFS=0
+lib_dir=$(dirname "$0")
+source "$lib_dir"/net_forwarding_lib.sh
+
+bond_check_flags()
+{
+       local bonddev=$1
+
+       ip -d l sh dev "$bonddev" | grep -q "MASTER"
+       check_err $? "MASTER flag is missing from the bond device"
+
+       ip -d l sh dev "$bonddev" | grep -q "SLAVE"
+       check_err $? "SLAVE flag is missing from the bond device"
+}
+
+# test enslaved bond dev type change from ARPHRD_ETHER and back
+# this allows us to test both MASTER and SLAVE flags at once
+bond_test_enslave_type_change()
+{
+       local test_success=$1
+       local devbond0="test-bond0"
+       local devbond1="test-bond1"
+       local devbond2="test-bond2"
+       local nonethdev="test-noneth0"
+
+       # create a non-ARPHRD_ETHER device for testing (e.g. nlmon type)
+       ip link add name "$nonethdev" type nlmon
+       check_err $? "could not create a non-ARPHRD_ETHER device (nlmon)"
+       ip link add name "$devbond0" type bond
+       if [ $test_success -eq 1 ]; then
+               # we need devbond0 in active-backup mode to successfully enslave nonethdev
+               ip link set dev "$devbond0" type bond mode active-backup
+               check_err $? "could not change bond mode to active-backup"
+       fi
+       ip link add name "$devbond1" type bond
+       ip link add name "$devbond2" type bond
+       ip link set dev "$devbond0" master "$devbond1"
+       check_err $? "could not enslave $devbond0 to $devbond1"
+       # change bond type to non-ARPHRD_ETHER
+       ip link set dev "$nonethdev" master "$devbond0" 1>/dev/null 2>/dev/null
+       ip link set dev "$nonethdev" nomaster 1>/dev/null 2>/dev/null
+       # restore ARPHRD_ETHER type by enslaving such device
+       ip link set dev "$devbond2" master "$devbond0"
+       check_err $? "could not enslave $devbond2 to $devbond0"
+       ip link set dev "$devbond1" nomaster
+
+       bond_check_flags "$devbond0"
+
+       # clean up
+       ip link del dev "$devbond0"
+       ip link del dev "$devbond1"
+       ip link del dev "$devbond2"
+       ip link del dev "$nonethdev"
+}
+
+bond_test_unsuccessful_enslave_type_change()
+{
+       RET=0
+
+       bond_test_enslave_type_change 0
+       log_test "Change ether type of an enslaved bond device with unsuccessful enslave"
+}
+
+bond_test_successful_enslave_type_change()
+{
+       RET=0
+
+       bond_test_enslave_type_change 1
+       log_test "Change ether type of an enslaved bond device with successful enslave"
+}
+
+tests_run
+
+exit "$EXIT_STATUS"
diff --git a/tools/testing/selftests/drivers/net/bonding/bond_options.sh b/tools/testing/selftests/drivers/net/bonding/bond_options.sh
new file mode 100755 (executable)
index 0000000..db29a31
--- /dev/null
@@ -0,0 +1,264 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Test bonding options with mode 1,5,6
+
+ALL_TESTS="
+       prio
+       arp_validate
+"
+
+REQUIRE_MZ=no
+NUM_NETIFS=0
+lib_dir=$(dirname "$0")
+source ${lib_dir}/net_forwarding_lib.sh
+source ${lib_dir}/bond_topo_3d1c.sh
+
+skip_prio()
+{
+       local skip=1
+
+       # check if iproute support prio option
+       ip -n ${s_ns} link set eth0 type bond_slave prio 10
+       [[ $? -ne 0 ]] && skip=0
+
+       # check if kernel support prio option
+       ip -n ${s_ns} -d link show eth0 | grep -q "prio 10"
+       [[ $? -ne 0 ]] && skip=0
+
+       return $skip
+}
+
+skip_ns()
+{
+       local skip=1
+
+       # check if iproute support ns_ip6_target option
+       ip -n ${s_ns} link add bond1 type bond ns_ip6_target ${g_ip6}
+       [[ $? -ne 0 ]] && skip=0
+
+       # check if kernel support ns_ip6_target option
+       ip -n ${s_ns} -d link show bond1 | grep -q "ns_ip6_target ${g_ip6}"
+       [[ $? -ne 0 ]] && skip=0
+
+       ip -n ${s_ns} link del bond1
+
+       return $skip
+}
+
+active_slave=""
+check_active_slave()
+{
+       local target_active_slave=$1
+       active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")
+       test "$active_slave" = "$target_active_slave"
+       check_err $? "Current active slave is $active_slave but not $target_active_slave"
+}
+
+
+# Test bonding prio option
+prio_test()
+{
+       local param="$1"
+       RET=0
+
+       # create bond
+       bond_reset "${param}"
+
+       # check bonding member prio value
+       ip -n ${s_ns} link set eth0 type bond_slave prio 0
+       ip -n ${s_ns} link set eth1 type bond_slave prio 10
+       ip -n ${s_ns} link set eth2 type bond_slave prio 11
+       cmd_jq "ip -n ${s_ns} -d -j link show eth0" \
+               ".[].linkinfo.info_slave_data | select (.prio == 0)" "-e" &> /dev/null
+       check_err $? "eth0 prio is not 0"
+       cmd_jq "ip -n ${s_ns} -d -j link show eth1" \
+               ".[].linkinfo.info_slave_data | select (.prio == 10)" "-e" &> /dev/null
+       check_err $? "eth1 prio is not 10"
+       cmd_jq "ip -n ${s_ns} -d -j link show eth2" \
+               ".[].linkinfo.info_slave_data | select (.prio == 11)" "-e" &> /dev/null
+       check_err $? "eth2 prio is not 11"
+
+       bond_check_connection "setup"
+
+       # active slave should be the primary slave
+       check_active_slave eth1
+
+       # active slave should be the higher prio slave
+       ip -n ${s_ns} link set $active_slave down
+       bond_check_connection "fail over"
+       check_active_slave eth2
+
+       # when only 1 slave is up
+       ip -n ${s_ns} link set $active_slave down
+       bond_check_connection "only 1 slave up"
+       check_active_slave eth0
+
+       # when a higher prio slave change to up
+       ip -n ${s_ns} link set eth2 up
+       bond_check_connection "higher prio slave up"
+       case $primary_reselect in
+               "0")
+                       check_active_slave "eth2"
+                       ;;
+               "1")
+                       check_active_slave "eth0"
+                       ;;
+               "2")
+                       check_active_slave "eth0"
+                       ;;
+       esac
+       local pre_active_slave=$active_slave
+
+       # when the primary slave change to up
+       ip -n ${s_ns} link set eth1 up
+       bond_check_connection "primary slave up"
+       case $primary_reselect in
+               "0")
+                       check_active_slave "eth1"
+                       ;;
+               "1")
+                       check_active_slave "$pre_active_slave"
+                       ;;
+               "2")
+                       check_active_slave "$pre_active_slave"
+                       ip -n ${s_ns} link set $active_slave down
+                       bond_check_connection "pre_active slave down"
+                       check_active_slave "eth1"
+                       ;;
+       esac
+
+       # Test changing bond slave prio
+       if [[ "$primary_reselect" == "0" ]];then
+               ip -n ${s_ns} link set eth0 type bond_slave prio 1000000
+               ip -n ${s_ns} link set eth1 type bond_slave prio 0
+               ip -n ${s_ns} link set eth2 type bond_slave prio -50
+               ip -n ${s_ns} -d link show eth0 | grep -q 'prio 1000000'
+               check_err $? "eth0 prio is not 1000000"
+               ip -n ${s_ns} -d link show eth1 | grep -q 'prio 0'
+               check_err $? "eth1 prio is not 0"
+               ip -n ${s_ns} -d link show eth2 | grep -q 'prio -50'
+               check_err $? "eth3 prio is not -50"
+               check_active_slave "eth1"
+
+               ip -n ${s_ns} link set $active_slave down
+               bond_check_connection "change slave prio"
+               check_active_slave "eth0"
+       fi
+}
+
+prio_miimon()
+{
+       local primary_reselect
+       local mode=$1
+
+       for primary_reselect in 0 1 2; do
+               prio_test "mode $mode miimon 100 primary eth1 primary_reselect $primary_reselect"
+               log_test "prio" "$mode miimon primary_reselect $primary_reselect"
+       done
+}
+
+prio_arp()
+{
+       local primary_reselect
+       local mode=$1
+
+       for primary_reselect in 0 1 2; do
+               prio_test "mode active-backup arp_interval 100 arp_ip_target ${g_ip4} primary eth1 primary_reselect $primary_reselect"
+               log_test "prio" "$mode arp_ip_target primary_reselect $primary_reselect"
+       done
+}
+
+prio_ns()
+{
+       local primary_reselect
+       local mode=$1
+
+       if skip_ns; then
+               log_test_skip "prio ns" "Current iproute or kernel doesn't support bond option 'ns_ip6_target'."
+               return 0
+       fi
+
+       for primary_reselect in 0 1 2; do
+               prio_test "mode active-backup arp_interval 100 ns_ip6_target ${g_ip6} primary eth1 primary_reselect $primary_reselect"
+               log_test "prio" "$mode ns_ip6_target primary_reselect $primary_reselect"
+       done
+}
+
+prio()
+{
+       local mode modes="active-backup balance-tlb balance-alb"
+
+       if skip_prio; then
+               log_test_skip "prio" "Current iproute or kernel doesn't support bond option 'prio'."
+               return 0
+       fi
+
+       for mode in $modes; do
+               prio_miimon $mode
+               prio_arp $mode
+               prio_ns $mode
+       done
+}
+
+arp_validate_test()
+{
+       local param="$1"
+       RET=0
+
+       # create bond
+       bond_reset "${param}"
+
+       bond_check_connection
+       [ $RET -ne 0 ] && log_test "arp_validate" "$retmsg"
+
+       # wait for a while to make sure the mii status stable
+       sleep 5
+       for i in $(seq 0 2); do
+               mii_status=$(cmd_jq "ip -n ${s_ns} -j -d link show eth$i" ".[].linkinfo.info_slave_data.mii_status")
+               if [ ${mii_status} != "UP" ]; then
+                       RET=1
+                       log_test "arp_validate" "interface eth$i mii_status $mii_status"
+               fi
+       done
+}
+
+arp_validate_arp()
+{
+       local mode=$1
+       local val
+       for val in $(seq 0 6); do
+               arp_validate_test "mode $mode arp_interval 100 arp_ip_target ${g_ip4} arp_validate $val"
+               log_test "arp_validate" "$mode arp_ip_target arp_validate $val"
+       done
+}
+
+arp_validate_ns()
+{
+       local mode=$1
+       local val
+
+       if skip_ns; then
+               log_test_skip "arp_validate ns" "Current iproute or kernel doesn't support bond option 'ns_ip6_target'."
+               return 0
+       fi
+
+       for val in $(seq 0 6); do
+               arp_validate_test "mode $mode arp_interval 100 ns_ip6_target ${g_ip6} arp_validate $val"
+               log_test "arp_validate" "$mode ns_ip6_target arp_validate $val"
+       done
+}
+
+arp_validate()
+{
+       arp_validate_arp "active-backup"
+       arp_validate_ns "active-backup"
+}
+
+trap cleanup EXIT
+
+setup_prepare
+setup_wait
+tests_run
+
+exit $EXIT_STATUS
diff --git a/tools/testing/selftests/drivers/net/bonding/bond_topo_3d1c.sh b/tools/testing/selftests/drivers/net/bonding/bond_topo_3d1c.sh
new file mode 100644 (file)
index 0000000..4045ca9
--- /dev/null
@@ -0,0 +1,143 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Topology for Bond mode 1,5,6 testing
+#
+#  +-------------------------------------+
+#  |                bond0                |
+#  |                  +                  |  Server
+#  |      eth0        | eth1   eth2      |  192.0.2.1/24
+#  |        +-------------------+        |  2001:db8::1/24
+#  |        |         |         |        |
+#  +-------------------------------------+
+#           |         |         |
+#  +-------------------------------------+
+#  |        |         |         |        |
+#  |    +---+---------+---------+---+    |  Gateway
+#  |    |            br0            |    |  192.0.2.254/24
+#  |    +-------------+-------------+    |  2001:db8::254/24
+#  |                  |                  |
+#  +-------------------------------------+
+#                     |
+#  +-------------------------------------+
+#  |                  |                  |  Client
+#  |                  +                  |  192.0.2.10/24
+#  |                eth0                 |  2001:db8::10/24
+#  +-------------------------------------+
+
+s_ns="s-$(mktemp -u XXXXXX)"
+c_ns="c-$(mktemp -u XXXXXX)"
+g_ns="g-$(mktemp -u XXXXXX)"
+s_ip4="192.0.2.1"
+c_ip4="192.0.2.10"
+g_ip4="192.0.2.254"
+s_ip6="2001:db8::1"
+c_ip6="2001:db8::10"
+g_ip6="2001:db8::254"
+
+gateway_create()
+{
+       ip netns add ${g_ns}
+       ip -n ${g_ns} link add br0 type bridge
+       ip -n ${g_ns} link set br0 up
+       ip -n ${g_ns} addr add ${g_ip4}/24 dev br0
+       ip -n ${g_ns} addr add ${g_ip6}/24 dev br0
+}
+
+gateway_destroy()
+{
+       ip -n ${g_ns} link del br0
+       ip netns del ${g_ns}
+}
+
+server_create()
+{
+       ip netns add ${s_ns}
+       ip -n ${s_ns} link add bond0 type bond mode active-backup miimon 100
+
+       for i in $(seq 0 2); do
+               ip -n ${s_ns} link add eth${i} type veth peer name s${i} netns ${g_ns}
+
+               ip -n ${g_ns} link set s${i} up
+               ip -n ${g_ns} link set s${i} master br0
+               ip -n ${s_ns} link set eth${i} master bond0
+       done
+
+       ip -n ${s_ns} link set bond0 up
+       ip -n ${s_ns} addr add ${s_ip4}/24 dev bond0
+       ip -n ${s_ns} addr add ${s_ip6}/24 dev bond0
+       sleep 2
+}
+
+# Reset bond with new mode and options
+bond_reset()
+{
+       local param="$1"
+
+       ip -n ${s_ns} link set bond0 down
+       ip -n ${s_ns} link del bond0
+
+       ip -n ${s_ns} link add bond0 type bond $param
+       for i in $(seq 0 2); do
+               ip -n ${s_ns} link set eth$i master bond0
+       done
+
+       ip -n ${s_ns} link set bond0 up
+       ip -n ${s_ns} addr add ${s_ip4}/24 dev bond0
+       ip -n ${s_ns} addr add ${s_ip6}/24 dev bond0
+       sleep 2
+}
+
+server_destroy()
+{
+       for i in $(seq 0 2); do
+               ip -n ${s_ns} link del eth${i}
+       done
+       ip netns del ${s_ns}
+}
+
+client_create()
+{
+       ip netns add ${c_ns}
+       ip -n ${c_ns} link add eth0 type veth peer name c0 netns ${g_ns}
+
+       ip -n ${g_ns} link set c0 up
+       ip -n ${g_ns} link set c0 master br0
+
+       ip -n ${c_ns} link set eth0 up
+       ip -n ${c_ns} addr add ${c_ip4}/24 dev eth0
+       ip -n ${c_ns} addr add ${c_ip6}/24 dev eth0
+}
+
+client_destroy()
+{
+       ip -n ${c_ns} link del eth0
+       ip netns del ${c_ns}
+}
+
+setup_prepare()
+{
+       gateway_create
+       server_create
+       client_create
+}
+
+cleanup()
+{
+       pre_cleanup
+
+       client_destroy
+       server_destroy
+       gateway_destroy
+}
+
+bond_check_connection()
+{
+       local msg=${1:-"check connection"}
+
+       sleep 2
+       ip netns exec ${s_ns} ping ${c_ip4} -c5 -i 0.1 &>/dev/null
+       check_err $? "${msg}: ping failed"
+       ip netns exec ${s_ns} ping6 ${c_ip6} -c5 -i 0.1 &>/dev/null
+       check_err $? "${msg}: ping6 failed"
+}
diff --git a/tools/testing/selftests/drivers/net/bonding/option_prio.sh b/tools/testing/selftests/drivers/net/bonding/option_prio.sh
deleted file mode 100755 (executable)
index c32eebf..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-#!/bin/bash
-# SPDX-License-Identifier: GPL-2.0
-#
-# Test bonding option prio
-#
-
-ALL_TESTS="
-       prio_arp_ip_target_test
-       prio_miimon_test
-"
-
-REQUIRE_MZ=no
-REQUIRE_JQ=no
-NUM_NETIFS=0
-lib_dir=$(dirname "$0")
-source "$lib_dir"/net_forwarding_lib.sh
-
-destroy()
-{
-       ip link del bond0 &>/dev/null
-       ip link del br0 &>/dev/null
-       ip link del veth0 &>/dev/null
-       ip link del veth1 &>/dev/null
-       ip link del veth2 &>/dev/null
-       ip netns del ns1 &>/dev/null
-       ip link del veth3 &>/dev/null
-}
-
-cleanup()
-{
-       pre_cleanup
-
-       destroy
-}
-
-skip()
-{
-        local skip=1
-       ip link add name bond0 type bond mode 1 miimon 100 &>/dev/null
-       ip link add name veth0 type veth peer name veth0_p
-       ip link set veth0 master bond0
-
-       # check if iproute support prio option
-       ip link set dev veth0 type bond_slave prio 10
-       [[ $? -ne 0 ]] && skip=0
-
-       # check if bonding support prio option
-       ip -d link show veth0 | grep -q "prio 10"
-       [[ $? -ne 0 ]] && skip=0
-
-       ip link del bond0 &>/dev/null
-       ip link del veth0
-
-       return $skip
-}
-
-active_slave=""
-check_active_slave()
-{
-       local target_active_slave=$1
-       active_slave="$(cat /sys/class/net/bond0/bonding/active_slave)"
-       test "$active_slave" = "$target_active_slave"
-       check_err $? "Current active slave is $active_slave but not $target_active_slave"
-}
-
-
-# Test bonding prio option with mode=$mode monitor=$monitor
-# and primary_reselect=$primary_reselect
-prio_test()
-{
-       RET=0
-
-       local monitor=$1
-       local mode=$2
-       local primary_reselect=$3
-
-       local bond_ip4="192.169.1.2"
-       local peer_ip4="192.169.1.1"
-       local bond_ip6="2009:0a:0b::02"
-       local peer_ip6="2009:0a:0b::01"
-
-
-       # create veths
-       ip link add name veth0 type veth peer name veth0_p
-       ip link add name veth1 type veth peer name veth1_p
-       ip link add name veth2 type veth peer name veth2_p
-
-       # create bond
-       if [[ "$monitor" == "miimon" ]];then
-               ip link add name bond0 type bond mode $mode miimon 100 primary veth1 primary_reselect $primary_reselect
-       elif [[ "$monitor" == "arp_ip_target" ]];then
-               ip link add name bond0 type bond mode $mode arp_interval 1000 arp_ip_target $peer_ip4 primary veth1 primary_reselect $primary_reselect
-       elif [[ "$monitor" == "ns_ip6_target" ]];then
-               ip link add name bond0 type bond mode $mode arp_interval 1000 ns_ip6_target $peer_ip6 primary veth1 primary_reselect $primary_reselect
-       fi
-       ip link set bond0 up
-       ip link set veth0 master bond0
-       ip link set veth1 master bond0
-       ip link set veth2 master bond0
-       # check bonding member prio value
-       ip link set dev veth0 type bond_slave prio 0
-       ip link set dev veth1 type bond_slave prio 10
-       ip link set dev veth2 type bond_slave prio 11
-       ip -d link show veth0 | grep -q 'prio 0'
-       check_err $? "veth0 prio is not 0"
-       ip -d link show veth1 | grep -q 'prio 10'
-       check_err $? "veth0 prio is not 10"
-       ip -d link show veth2 | grep -q 'prio 11'
-       check_err $? "veth0 prio is not 11"
-
-       ip link set veth0 up
-       ip link set veth1 up
-       ip link set veth2 up
-       ip link set veth0_p up
-       ip link set veth1_p up
-       ip link set veth2_p up
-
-       # prepare ping target
-       ip link add name br0 type bridge
-       ip link set br0 up
-       ip link set veth0_p master br0
-       ip link set veth1_p master br0
-       ip link set veth2_p master br0
-       ip link add name veth3 type veth peer name veth3_p
-       ip netns add ns1
-       ip link set veth3_p master br0 up
-       ip link set veth3 netns ns1 up
-       ip netns exec ns1 ip addr add $peer_ip4/24 dev veth3
-       ip netns exec ns1 ip addr add $peer_ip6/64 dev veth3
-       ip addr add $bond_ip4/24 dev bond0
-       ip addr add $bond_ip6/64 dev bond0
-       sleep 5
-
-       ping $peer_ip4 -c5 -I bond0 &>/dev/null
-       check_err $? "ping failed 1."
-       ping6 $peer_ip6 -c5 -I bond0 &>/dev/null
-       check_err $? "ping6 failed 1."
-
-       # active salve should be the primary slave
-       check_active_slave veth1
-
-       # active slave should be the higher prio slave
-       ip link set $active_slave down
-       ping $peer_ip4 -c5 -I bond0 &>/dev/null
-       check_err $? "ping failed 2."
-       check_active_slave veth2
-
-       # when only 1 slave is up
-       ip link set $active_slave down
-       ping $peer_ip4 -c5 -I bond0 &>/dev/null
-       check_err $? "ping failed 3."
-       check_active_slave veth0
-
-       # when a higher prio slave change to up
-       ip link set veth2 up
-       ping $peer_ip4 -c5 -I bond0 &>/dev/null
-       check_err $? "ping failed 4."
-       case $primary_reselect in
-               "0")
-                       check_active_slave "veth2"
-                       ;;
-               "1")
-                       check_active_slave "veth0"
-                       ;;
-               "2")
-                       check_active_slave "veth0"
-                       ;;
-       esac
-       local pre_active_slave=$active_slave
-
-       # when the primary slave change to up
-       ip link set veth1 up
-       ping $peer_ip4 -c5 -I bond0 &>/dev/null
-       check_err $? "ping failed 5."
-       case $primary_reselect in
-               "0")
-                       check_active_slave "veth1"
-                       ;;
-               "1")
-                       check_active_slave "$pre_active_slave"
-                       ;;
-               "2")
-                       check_active_slave "$pre_active_slave"
-                       ip link set $active_slave down
-                       ping $peer_ip4 -c5 -I bond0 &>/dev/null
-                       check_err $? "ping failed 6."
-                       check_active_slave "veth1"
-                       ;;
-       esac
-
-       # Test changing bond salve prio
-       if [[ "$primary_reselect" == "0" ]];then
-               ip link set dev veth0 type bond_slave prio 1000000
-               ip link set dev veth1 type bond_slave prio 0
-               ip link set dev veth2 type bond_slave prio -50
-               ip -d link show veth0 | grep -q 'prio 1000000'
-               check_err $? "veth0 prio is not 1000000"
-               ip -d link show veth1 | grep -q 'prio 0'
-               check_err $? "veth1 prio is not 0"
-               ip -d link show veth2 | grep -q 'prio -50'
-               check_err $? "veth3 prio is not -50"
-               check_active_slave "veth1"
-
-               ip link set $active_slave down
-               ping $peer_ip4 -c5 -I bond0 &>/dev/null
-               check_err $? "ping failed 7."
-               check_active_slave "veth0"
-       fi
-
-       cleanup
-
-       log_test "prio_test" "Test bonding option 'prio' with mode=$mode monitor=$monitor and primary_reselect=$primary_reselect"
-}
-
-prio_miimon_test()
-{
-       local mode
-       local primary_reselect
-
-       for mode in 1 5 6; do
-               for primary_reselect in 0 1 2; do
-                       prio_test "miimon" $mode $primary_reselect
-               done
-       done
-}
-
-prio_arp_ip_target_test()
-{
-       local primary_reselect
-
-       for primary_reselect in 0 1 2; do
-               prio_test "arp_ip_target" 1 $primary_reselect
-       done
-}
-
-if skip;then
-       log_test_skip "option_prio.sh" "Current iproute doesn't support 'prio'."
-       exit 0
-fi
-
-trap cleanup EXIT
-
-tests_run
-
-exit "$EXIT_STATUS"
index 9c5a55abca6b688a29375afda91d5c6937783fb4..5b5cef445b5490350b9a7da03496f209a1fb02b8 100644 (file)
@@ -17,5 +17,6 @@ CONFIG_FTRACE_SYSCALLS=y
 CONFIG_FUNCTION_TRACER=y
 CONFIG_HIDRAW=y
 CONFIG_HID=y
+CONFIG_HID_BPF=y
 CONFIG_INPUT_EVDEV=y
 CONFIG_UHID=y
index 33a0dbd26bd342c4159df46de49177c5ef66e068..829be379545adacd3efc7c7e3a729954c2e20eef 100644 (file)
 #ifndef __KSELFTEST_H
 #define __KSELFTEST_H
 
+#ifndef NOLIBC
 #include <errno.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdarg.h>
 #include <stdio.h>
+#endif
 
 #ifndef ARRAY_SIZE
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
index cfa36f38794844078b8f429f845b427831b326c4..9b004905d1d3141c19051055c51a7900cbbdbea1 100644 (file)
@@ -180,9 +180,7 @@ static void host_test_system_suspend(void)
 
        enter_guest(source);
 
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_SYSTEM_EVENT,
-                   "Unhandled exit reason: %u (%s)",
-                   run->exit_reason, exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(source, KVM_EXIT_SYSTEM_EVENT);
        TEST_ASSERT(run->system_event.type == KVM_SYSTEM_EVENT_SUSPEND,
                    "Unhandled system event: %u (expected: %u)",
                    run->system_event.type, KVM_SYSTEM_EVENT_SUSPEND);
index 80d6416f3012e6c8605b1e5fb07a21085a0f7cd7..a6e9f215ce700c9cf3ef44093697998b3d36b5a2 100644 (file)
@@ -63,6 +63,15 @@ void test_assert(bool exp, const char *exp_str,
                    #a, #b, #a, (unsigned long) __a, #b, (unsigned long) __b); \
 } while (0)
 
+#define TEST_ASSERT_KVM_EXIT_REASON(vcpu, expected) do {               \
+       __u32 exit_reason = (vcpu)->run->exit_reason;                   \
+                                                                       \
+       TEST_ASSERT(exit_reason == (expected),                          \
+                   "Wanted KVM exit reason: %u (%s), got: %u (%s)",    \
+                   (expected), exit_reason_str((expected)),            \
+                   exit_reason, exit_reason_str(exit_reason));         \
+} while (0)
+
 #define TEST_FAIL(fmt, ...) do { \
        TEST_ASSERT(false, fmt, ##__VA_ARGS__); \
        __builtin_unreachable(); \
index 53ffa43c90db1b0d8eb16b956ae7aaeddffe051a..90387ddcb2a9de8e63f0a1b853975895efe46bab 100644 (file)
@@ -1063,6 +1063,8 @@ uint64_t *vm_get_page_table_entry(struct kvm_vm *vm, uint64_t vaddr);
 
 uint64_t kvm_hypercall(uint64_t nr, uint64_t a0, uint64_t a1, uint64_t a2,
                       uint64_t a3);
+uint64_t __xen_hypercall(uint64_t nr, uint64_t a0, void *a1);
+void xen_hypercall(uint64_t nr, uint64_t a0, void *a1);
 
 void __vm_xsave_require_permission(int bit, const char *name);
 
index 3ea24a5f4c43ecf12921340005ecefff7e819596..8ec20ac33de022012c7935314f1e6c1b28792f17 100644 (file)
@@ -1815,38 +1815,53 @@ void vm_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent)
                vcpu_dump(stream, vcpu, indent + 2);
 }
 
+#define KVM_EXIT_STRING(x) {KVM_EXIT_##x, #x}
+
 /* Known KVM exit reasons */
 static struct exit_reason {
        unsigned int reason;
        const char *name;
 } exit_reasons_known[] = {
-       {KVM_EXIT_UNKNOWN, "UNKNOWN"},
-       {KVM_EXIT_EXCEPTION, "EXCEPTION"},
-       {KVM_EXIT_IO, "IO"},
-       {KVM_EXIT_HYPERCALL, "HYPERCALL"},
-       {KVM_EXIT_DEBUG, "DEBUG"},
-       {KVM_EXIT_HLT, "HLT"},
-       {KVM_EXIT_MMIO, "MMIO"},
-       {KVM_EXIT_IRQ_WINDOW_OPEN, "IRQ_WINDOW_OPEN"},
-       {KVM_EXIT_SHUTDOWN, "SHUTDOWN"},
-       {KVM_EXIT_FAIL_ENTRY, "FAIL_ENTRY"},
-       {KVM_EXIT_INTR, "INTR"},
-       {KVM_EXIT_SET_TPR, "SET_TPR"},
-       {KVM_EXIT_TPR_ACCESS, "TPR_ACCESS"},
-       {KVM_EXIT_S390_SIEIC, "S390_SIEIC"},
-       {KVM_EXIT_S390_RESET, "S390_RESET"},
-       {KVM_EXIT_DCR, "DCR"},
-       {KVM_EXIT_NMI, "NMI"},
-       {KVM_EXIT_INTERNAL_ERROR, "INTERNAL_ERROR"},
-       {KVM_EXIT_OSI, "OSI"},
-       {KVM_EXIT_PAPR_HCALL, "PAPR_HCALL"},
-       {KVM_EXIT_DIRTY_RING_FULL, "DIRTY_RING_FULL"},
-       {KVM_EXIT_X86_RDMSR, "RDMSR"},
-       {KVM_EXIT_X86_WRMSR, "WRMSR"},
-       {KVM_EXIT_XEN, "XEN"},
-       {KVM_EXIT_HYPERV, "HYPERV"},
+       KVM_EXIT_STRING(UNKNOWN),
+       KVM_EXIT_STRING(EXCEPTION),
+       KVM_EXIT_STRING(IO),
+       KVM_EXIT_STRING(HYPERCALL),
+       KVM_EXIT_STRING(DEBUG),
+       KVM_EXIT_STRING(HLT),
+       KVM_EXIT_STRING(MMIO),
+       KVM_EXIT_STRING(IRQ_WINDOW_OPEN),
+       KVM_EXIT_STRING(SHUTDOWN),
+       KVM_EXIT_STRING(FAIL_ENTRY),
+       KVM_EXIT_STRING(INTR),
+       KVM_EXIT_STRING(SET_TPR),
+       KVM_EXIT_STRING(TPR_ACCESS),
+       KVM_EXIT_STRING(S390_SIEIC),
+       KVM_EXIT_STRING(S390_RESET),
+       KVM_EXIT_STRING(DCR),
+       KVM_EXIT_STRING(NMI),
+       KVM_EXIT_STRING(INTERNAL_ERROR),
+       KVM_EXIT_STRING(OSI),
+       KVM_EXIT_STRING(PAPR_HCALL),
+       KVM_EXIT_STRING(S390_UCONTROL),
+       KVM_EXIT_STRING(WATCHDOG),
+       KVM_EXIT_STRING(S390_TSCH),
+       KVM_EXIT_STRING(EPR),
+       KVM_EXIT_STRING(SYSTEM_EVENT),
+       KVM_EXIT_STRING(S390_STSI),
+       KVM_EXIT_STRING(IOAPIC_EOI),
+       KVM_EXIT_STRING(HYPERV),
+       KVM_EXIT_STRING(ARM_NISV),
+       KVM_EXIT_STRING(X86_RDMSR),
+       KVM_EXIT_STRING(X86_WRMSR),
+       KVM_EXIT_STRING(DIRTY_RING_FULL),
+       KVM_EXIT_STRING(AP_RESET_HOLD),
+       KVM_EXIT_STRING(X86_BUS_LOCK),
+       KVM_EXIT_STRING(XEN),
+       KVM_EXIT_STRING(RISCV_SBI),
+       KVM_EXIT_STRING(RISCV_CSR),
+       KVM_EXIT_STRING(NOTIFY),
 #ifdef KVM_EXIT_MEMORY_NOT_PRESENT
-       {KVM_EXIT_MEMORY_NOT_PRESENT, "MEMORY_NOT_PRESENT"},
+       KVM_EXIT_STRING(MEMORY_NOT_PRESENT),
 #endif
 };
 
index cdb7daeed5fd956a1076c39d35bad166d09ac788..2c432fa164f194ade8a3d51a79f27c8dbb0e32ee 100644 (file)
@@ -35,8 +35,7 @@ static uint64_t diag318_handler(void)
        vcpu_run(vcpu);
        run = vcpu->run;
 
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_S390_SIEIC,
-                   "DIAGNOSE 0x0318 instruction was not intercepted");
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_S390_SIEIC);
        TEST_ASSERT(run->s390_sieic.icptcode == ICPT_INSTRUCTION,
                    "Unexpected intercept code: 0x%x", run->s390_sieic.icptcode);
        TEST_ASSERT((run->s390_sieic.ipa & 0xff00) == IPA0_DIAG,
index 5c22fa4c2825efb1d51df880fea85dbb4dcce036..b772193f6c186d659b8053e9703ff6abe6754ee7 100644 (file)
@@ -165,26 +165,33 @@ size_t get_trans_hugepagesz(void)
 size_t get_def_hugetlb_pagesz(void)
 {
        char buf[64];
-       const char *tag = "Hugepagesize:";
+       const char *hugepagesize = "Hugepagesize:";
+       const char *hugepages_total = "HugePages_Total:";
        FILE *f;
 
        f = fopen("/proc/meminfo", "r");
        TEST_ASSERT(f != NULL, "Error in opening /proc/meminfo");
 
        while (fgets(buf, sizeof(buf), f) != NULL) {
-               if (strstr(buf, tag) == buf) {
+               if (strstr(buf, hugepages_total) == buf) {
+                       unsigned long long total = strtoull(buf + strlen(hugepages_total), NULL, 10);
+                       if (!total) {
+                               fprintf(stderr, "HUGETLB is not enabled in /proc/sys/vm/nr_hugepages\n");
+                               exit(KSFT_SKIP);
+                       }
+               }
+               if (strstr(buf, hugepagesize) == buf) {
                        fclose(f);
-                       return strtoull(buf + strlen(tag), NULL, 10) << 10;
+                       return strtoull(buf + strlen(hugepagesize), NULL, 10) << 10;
                }
        }
 
-       if (feof(f))
-               TEST_FAIL("HUGETLB is not configured in host kernel");
-       else
-               TEST_FAIL("Error in reading /proc/meminfo");
+       if (feof(f)) {
+               fprintf(stderr, "HUGETLB is not configured in host kernel");
+               exit(KSFT_SKIP);
+       }
 
-       fclose(f);
-       return 0;
+       TEST_FAIL("Error in reading /proc/meminfo");
 }
 
 #define ANON_FLAGS     (MAP_PRIVATE | MAP_ANONYMOUS)
index ae1e573d94ce71d6832d15c3eeb191d938f693e6..c39a4353ba194c13257e1aaae62c0ee6889c776d 100644 (file)
@@ -1139,21 +1139,36 @@ const struct kvm_cpuid_entry2 *get_cpuid_entry(const struct kvm_cpuid2 *cpuid,
        return NULL;
 }
 
+#define X86_HYPERCALL(inputs...)                                       \
+({                                                                     \
+       uint64_t r;                                                     \
+                                                                       \
+       asm volatile("test %[use_vmmcall], %[use_vmmcall]\n\t"          \
+                    "jnz 1f\n\t"                                       \
+                    "vmcall\n\t"                                       \
+                    "jmp 2f\n\t"                                       \
+                    "1: vmmcall\n\t"                                   \
+                    "2:"                                               \
+                    : "=a"(r)                                          \
+                    : [use_vmmcall] "r" (host_cpu_is_amd), inputs);    \
+                                                                       \
+       r;                                                              \
+})
+
 uint64_t kvm_hypercall(uint64_t nr, uint64_t a0, uint64_t a1, uint64_t a2,
                       uint64_t a3)
 {
-       uint64_t r;
-
-       asm volatile("test %[use_vmmcall], %[use_vmmcall]\n\t"
-                    "jnz 1f\n\t"
-                    "vmcall\n\t"
-                    "jmp 2f\n\t"
-                    "1: vmmcall\n\t"
-                    "2:"
-                    : "=a"(r)
-                    : "a"(nr), "b"(a0), "c"(a1), "d"(a2), "S"(a3),
-                      [use_vmmcall] "r" (host_cpu_is_amd));
-       return r;
+       return X86_HYPERCALL("a"(nr), "b"(a0), "c"(a1), "d"(a2), "S"(a3));
+}
+
+uint64_t __xen_hypercall(uint64_t nr, uint64_t a0, void *a1)
+{
+       return X86_HYPERCALL("a"(nr), "D"(a0), "S"(a1));
+}
+
+void xen_hypercall(uint64_t nr, uint64_t a0, void *a1)
+{
+       GUEST_ASSERT(!__xen_hypercall(nr, a0, a1));
 }
 
 const struct kvm_cpuid2 *kvm_get_supported_hv_cpuid(void)
index 2ddde41c44ba994904c1e73228528da2182c49a8..636a70ddac1ea36151cb57a0dfd74ddcca33de14 100644 (file)
@@ -126,10 +126,7 @@ void test_req_and_verify_all_valid_regs(struct kvm_vcpu *vcpu)
        run->kvm_valid_regs = TEST_SYNC_FIELDS;
        rv = _vcpu_run(vcpu);
        TEST_ASSERT(rv == 0, "vcpu_run failed: %d\n", rv);
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_S390_SIEIC,
-                   "Unexpected exit reason: %u (%s)\n",
-                   run->exit_reason,
-                   exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_S390_SIEIC);
        TEST_ASSERT(run->s390_sieic.icptcode == 4 &&
                    (run->s390_sieic.ipa >> 8) == 0x83 &&
                    (run->s390_sieic.ipb >> 16) == 0x501,
@@ -165,10 +162,7 @@ void test_set_and_verify_various_reg_values(struct kvm_vcpu *vcpu)
 
        rv = _vcpu_run(vcpu);
        TEST_ASSERT(rv == 0, "vcpu_run failed: %d\n", rv);
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_S390_SIEIC,
-                   "Unexpected exit reason: %u (%s)\n",
-                   run->exit_reason,
-                   exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_S390_SIEIC);
        TEST_ASSERT(run->s.regs.gprs[11] == 0xBAD1DEA + 1,
                    "r11 sync regs value incorrect 0x%llx.",
                    run->s.regs.gprs[11]);
@@ -200,10 +194,7 @@ void test_clear_kvm_dirty_regs_bits(struct kvm_vcpu *vcpu)
        run->s.regs.diag318 = 0x4B1D;
        rv = _vcpu_run(vcpu);
        TEST_ASSERT(rv == 0, "vcpu_run failed: %d\n", rv);
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_S390_SIEIC,
-                   "Unexpected exit reason: %u (%s)\n",
-                   run->exit_reason,
-                   exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_S390_SIEIC);
        TEST_ASSERT(run->s.regs.gprs[11] != 0xDEADBEEF,
                    "r11 sync regs value incorrect 0x%llx.",
                    run->s.regs.gprs[11]);
index 2ef1d1b72ce43194894386df947b0a2def9b2f49..a849ce23ca97560eed95b3ba44b0492a2bc17902 100644 (file)
@@ -308,7 +308,6 @@ static void test_delete_memory_region(void)
 static void test_zero_memory_regions(void)
 {
        struct kvm_vcpu *vcpu;
-       struct kvm_run *run;
        struct kvm_vm *vm;
 
        pr_info("Testing KVM_RUN with zero added memory regions\n");
@@ -318,10 +317,7 @@ static void test_zero_memory_regions(void)
 
        vm_ioctl(vm, KVM_SET_NR_MMU_PAGES, (void *)64ul);
        vcpu_run(vcpu);
-
-       run = vcpu->run;
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_INTERNAL_ERROR,
-                   "Unexpected exit_reason = %u\n", run->exit_reason);
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_INTERNAL_ERROR);
 
        kvm_vm_free(vm);
 }
index bd72c6eb3b670a4f49dab41f67d97cadfd3278c3..b646cdb5055adb3ab9f3f03e68381d422ed5e27d 100644 (file)
@@ -241,7 +241,6 @@ int main(int argc, char *argv[])
        struct kvm_regs regs1, regs2;
        struct kvm_vcpu *vcpu;
        struct kvm_vm *vm;
-       struct kvm_run *run;
        struct kvm_x86_state *state;
        int xsave_restore_size;
        vm_vaddr_t amx_cfg, tiledata, xsavedata;
@@ -268,7 +267,6 @@ int main(int argc, char *argv[])
                    "KVM should enumerate max XSAVE size when XSAVE is supported");
        xsave_restore_size = kvm_cpu_property(X86_PROPERTY_XSTATE_MAX_SIZE);
 
-       run = vcpu->run;
        vcpu_regs_get(vcpu, &regs1);
 
        /* Register #NM handler */
@@ -291,10 +289,7 @@ int main(int argc, char *argv[])
 
        for (stage = 1; ; stage++) {
                vcpu_run(vcpu);
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Stage %d: unexpected exit reason: %u (%s),\n",
-                           stage, run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_ABORT:
@@ -350,7 +345,6 @@ int main(int argc, char *argv[])
                /* Restore state in a new VM.  */
                vcpu = vm_recreate_with_one_vcpu(vm);
                vcpu_load_state(vcpu, state);
-               run = vcpu->run;
                kvm_x86_state_cleanup(state);
 
                memset(&regs2, 0, sizeof(regs2));
index 1027a671c7d3aaceb3971ec3b10ca28227cb29d6..624dc725e14dc0d3170b7fbe6414c92907102027 100644 (file)
@@ -50,7 +50,6 @@ static void guest_code(void)
 int main(int argc, char *argv[])
 {
        struct kvm_vcpu *vcpu;
-       struct kvm_run *run;
        struct kvm_vm *vm;
        struct kvm_sregs sregs;
        struct ucall uc;
@@ -58,15 +57,10 @@ int main(int argc, char *argv[])
        TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_XSAVE));
 
        vm = vm_create_with_one_vcpu(&vcpu, guest_code);
-       run = vcpu->run;
 
        while (1) {
                vcpu_run(vcpu);
-
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Unexpected exit reason: %u (%s),\n",
-                           run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_SYNC:
index 7ef99c3359a0db8eda4bde8026fc831a62f33a93..f6b295e0b2d2bb2ef7d8f3f9359df5125c17069d 100644 (file)
@@ -204,7 +204,7 @@ int main(void)
        vcpu_guest_debug_set(vcpu, &debug);
 
        vcpu_run(vcpu);
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, "KVM_EXIT_IO");
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
        cmd = get_ucall(vcpu, &uc);
        TEST_ASSERT(cmd == UCALL_DONE, "UCALL_DONE");
 
index e43a7df25f2c53321cfdc776de2b7fa87d992276..0a1573d52882b7b127307a829b0d1dc4d1af6560 100644 (file)
@@ -24,10 +24,7 @@ static inline void handle_flds_emulation_failure_exit(struct kvm_vcpu *vcpu)
        uint8_t *insn_bytes;
        uint64_t flags;
 
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_INTERNAL_ERROR,
-                   "Unexpected exit reason: %u (%s)",
-                   run->exit_reason,
-                   exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_INTERNAL_ERROR);
 
        TEST_ASSERT(run->emulation_failure.suberror == KVM_INTERNAL_ERROR_EMULATION,
                    "Unexpected suberror: %u",
index 2ee0af0d449efcab6f14b4242f43ce40eeb7995c..f25749eaa6a84bb16f0405fdf8847ace33ce04ce 100644 (file)
@@ -207,13 +207,11 @@ int main(void)
 {
        struct kvm_vcpu *vcpu;
        struct kvm_vm *vm;
-       struct kvm_run *run;
        struct ucall uc;
        vm_vaddr_t tsc_page_gva;
        int stage;
 
        vm = vm_create_with_one_vcpu(&vcpu, guest_main);
-       run = vcpu->run;
 
        vcpu_set_hv_cpuid(vcpu);
 
@@ -227,10 +225,7 @@ int main(void)
 
        for (stage = 1;; stage++) {
                vcpu_run(vcpu);
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Stage %d: unexpected exit reason: %u (%s),\n",
-                           stage, run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_ABORT:
index af29e5776d4034e90efc6a772596f703ff580ced..7bde0c4dfdbd18b769a2580c68c2e789a7a692a6 100644 (file)
@@ -237,7 +237,6 @@ int main(int argc, char *argv[])
 
        struct kvm_vcpu *vcpu;
        struct kvm_vm *vm;
-       struct kvm_run *run;
        struct ucall uc;
        int stage;
 
@@ -266,13 +265,8 @@ int main(int argc, char *argv[])
        pr_info("Running L1 which uses EVMCS to run L2\n");
 
        for (stage = 1;; stage++) {
-               run = vcpu->run;
-
                vcpu_run(vcpu);
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Stage %d: unexpected exit reason: %u (%s),\n",
-                           stage, run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_ABORT:
index c5e3b39edd0797b71fa3c0b386514b3fcac4ebe6..78606de9385dae2b4ff88fb9ddd69bc83c5a8962 100644 (file)
@@ -122,7 +122,6 @@ static void guest_test_msrs_access(void)
 {
        struct kvm_cpuid2 *prev_cpuid = NULL;
        struct kvm_vcpu *vcpu;
-       struct kvm_run *run;
        struct kvm_vm *vm;
        struct ucall uc;
        int stage = 0;
@@ -151,8 +150,6 @@ static void guest_test_msrs_access(void)
                vm_init_descriptor_tables(vm);
                vcpu_init_descriptor_tables(vcpu);
 
-               run = vcpu->run;
-
                /* TODO: Make this entire test easier to maintain. */
                if (stage >= 21)
                        vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_SYNIC2, 0);
@@ -494,9 +491,7 @@ static void guest_test_msrs_access(void)
                         msr->idx, msr->write ? "write" : "read");
 
                vcpu_run(vcpu);
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "unexpected exit reason: %u (%s)",
-                           run->exit_reason, exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_ABORT:
@@ -518,7 +513,6 @@ static void guest_test_hcalls_access(void)
 {
        struct kvm_cpuid2 *prev_cpuid = NULL;
        struct kvm_vcpu *vcpu;
-       struct kvm_run *run;
        struct kvm_vm *vm;
        struct ucall uc;
        int stage = 0;
@@ -550,8 +544,6 @@ static void guest_test_hcalls_access(void)
                        vcpu_init_cpuid(vcpu, prev_cpuid);
                }
 
-               run = vcpu->run;
-
                switch (stage) {
                case 0:
                        vcpu_set_cpuid_feature(vcpu, HV_MSR_HYPERCALL_AVAILABLE);
@@ -669,9 +661,7 @@ static void guest_test_hcalls_access(void)
                pr_debug("Stage %d: testing hcall: 0x%lx\n", stage, hcall->control);
 
                vcpu_run(vcpu);
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "unexpected exit reason: %u (%s)",
-                           run->exit_reason, exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_ABORT:
index 0cbb0e646ef8d7e7e804b730c773dcfd497a0658..6feb5ddb031dac66aeabe18b7733f8639f29af63 100644 (file)
@@ -243,7 +243,6 @@ int main(int argc, char *argv[])
 {
        struct kvm_vm *vm;
        struct kvm_vcpu *vcpu[3];
-       unsigned int exit_reason;
        vm_vaddr_t hcall_page;
        pthread_t threads[2];
        int stage = 1, r;
@@ -283,10 +282,7 @@ int main(int argc, char *argv[])
        while (true) {
                vcpu_run(vcpu[0]);
 
-               exit_reason = vcpu[0]->run->exit_reason;
-               TEST_ASSERT(exit_reason == KVM_EXIT_IO,
-                           "unexpected exit reason: %u (%s)",
-                           exit_reason, exit_reason_str(exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu[0], KVM_EXIT_IO);
 
                switch (get_ucall(vcpu[0], &uc)) {
                case UCALL_SYNC:
index 68a7d354ea070a290cb818f7877fd712d0e7b1ea..e446d76d1c0c38f7ed41ff0ed3dfc736b6b3693c 100644 (file)
@@ -156,7 +156,6 @@ int main(int argc, char *argv[])
        vm_vaddr_t hcall_page;
        struct kvm_vcpu *vcpu;
        struct kvm_vm *vm;
-       struct kvm_run *run;
        struct ucall uc;
        int stage;
 
@@ -165,7 +164,6 @@ int main(int argc, char *argv[])
        /* Create VM */
        vm = vm_create_with_one_vcpu(&vcpu, guest_code);
        vcpu_set_hv_cpuid(vcpu);
-       run = vcpu->run;
        vcpu_alloc_svm(vm, &nested_gva);
        vcpu_alloc_hyperv_test_pages(vm, &hv_pages_gva);
 
@@ -177,10 +175,7 @@ int main(int argc, char *argv[])
 
        for (stage = 1;; stage++) {
                vcpu_run(vcpu);
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Stage %d: unexpected exit reason: %u (%s),\n",
-                           stage, run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_ABORT:
index 68f97ff720a74f8eeb3c3a4d12daa84d24696954..4758b6ef5618e387d3a838908e78d2e51af79fa7 100644 (file)
@@ -542,18 +542,13 @@ static void *vcpu_thread(void *arg)
        struct ucall uc;
        int old;
        int r;
-       unsigned int exit_reason;
 
        r = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old);
        TEST_ASSERT(!r, "pthread_setcanceltype failed on vcpu_id=%u with errno=%d",
                    vcpu->id, r);
 
        vcpu_run(vcpu);
-       exit_reason = vcpu->run->exit_reason;
-
-       TEST_ASSERT(exit_reason == KVM_EXIT_IO,
-                   "vCPU %u exited with unexpected exit reason %u-%s, expected KVM_EXIT_IO",
-                   vcpu->id, exit_reason, exit_reason_str(exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
        switch (get_ucall(vcpu, &uc)) {
        case UCALL_ABORT:
@@ -587,7 +582,6 @@ int main(int argc, char *argv[])
 {
        struct kvm_vm *vm;
        struct kvm_vcpu *vcpu[3];
-       unsigned int exit_reason;
        pthread_t threads[2];
        vm_vaddr_t test_data_page, gva;
        vm_paddr_t gpa;
@@ -657,11 +651,7 @@ int main(int argc, char *argv[])
 
        while (true) {
                vcpu_run(vcpu[0]);
-               exit_reason = vcpu[0]->run->exit_reason;
-
-               TEST_ASSERT(exit_reason == KVM_EXIT_IO,
-                           "unexpected exit reason: %u (%s)",
-                           exit_reason, exit_reason_str(exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu[0], KVM_EXIT_IO);
 
                switch (get_ucall(vcpu[0], &uc)) {
                case UCALL_SYNC:
index 813ce282cf5612b72e9909c7f825f94dfb2bc231..1778704360a6634ee7df3dfacd8f63fd3d236cab 100644 (file)
@@ -105,7 +105,6 @@ static void setup_clock(struct kvm_vm *vm, struct test_case *test_case)
 static void enter_guest(struct kvm_vcpu *vcpu)
 {
        struct kvm_clock_data start, end;
-       struct kvm_run *run = vcpu->run;
        struct kvm_vm *vm = vcpu->vm;
        struct ucall uc;
        int i;
@@ -118,9 +117,7 @@ static void enter_guest(struct kvm_vcpu *vcpu)
                vcpu_run(vcpu);
                vm_ioctl(vm, KVM_GET_CLOCK, &end);
 
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "unexpected exit reason: %u (%s)",
-                           run->exit_reason, exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_SYNC:
index 619655c1a1f39fbf950149a13d9feec57f8f6ea8..f774a9e62858f3a35736591223db35c4acceacba 100644 (file)
@@ -111,14 +111,11 @@ static void pr_hcall(struct ucall *uc)
 
 static void enter_guest(struct kvm_vcpu *vcpu)
 {
-       struct kvm_run *run = vcpu->run;
        struct ucall uc;
 
        while (true) {
                vcpu_run(vcpu);
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "unexpected exit reason: %u (%s)",
-                           run->exit_reason, exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_PR_MSR:
index 016070cad36edb59405b4b10d42b7b398911d125..72812644d7f5ea6b212f525376ca7a5a3f74648f 100644 (file)
@@ -64,7 +64,6 @@ int main(int argc, char *argv[])
 {
        uint64_t disabled_quirks;
        struct kvm_vcpu *vcpu;
-       struct kvm_run *run;
        struct kvm_vm *vm;
        struct ucall uc;
        int testcase;
@@ -74,18 +73,12 @@ int main(int argc, char *argv[])
        vm = vm_create_with_one_vcpu(&vcpu, guest_code);
        vcpu_clear_cpuid_feature(vcpu, X86_FEATURE_MWAIT);
 
-       run = vcpu->run;
-
        vm_init_descriptor_tables(vm);
        vcpu_init_descriptor_tables(vcpu);
 
        while (1) {
                vcpu_run(vcpu);
-
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Unexpected exit reason: %u (%s),\n",
-                           run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_SYNC:
index ac33835f78f45afa2a1bc2d387bf03c18025efc5..6502aa23c2f84b81d4187a42b7ec057b5354311a 100644 (file)
@@ -166,12 +166,9 @@ static void __attribute__((__flatten__)) l1_guest_code(void *test_data)
 
 static void assert_ucall_vector(struct kvm_vcpu *vcpu, int vector)
 {
-       struct kvm_run *run = vcpu->run;
        struct ucall uc;
 
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                   "Unexpected exit reason: %u (%s),\n",
-                   run->exit_reason, exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
        switch (get_ucall(vcpu, &uc)) {
        case UCALL_SYNC:
index 310a104d94f06ab0533ef5fc4cfef0e675a65e07..c9a07963d68aaedcc6b45d4e00e932e5981645b0 100644 (file)
@@ -36,15 +36,12 @@ static void guest_code(void)
 
 static void test_msr_platform_info_enabled(struct kvm_vcpu *vcpu)
 {
-       struct kvm_run *run = vcpu->run;
        struct ucall uc;
 
        vm_enable_cap(vcpu->vm, KVM_CAP_MSR_PLATFORM_INFO, true);
        vcpu_run(vcpu);
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                       "Exit_reason other than KVM_EXIT_IO: %u (%s),\n",
-                       run->exit_reason,
-                       exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
+
        get_ucall(vcpu, &uc);
        TEST_ASSERT(uc.cmd == UCALL_SYNC,
                        "Received ucall other than UCALL_SYNC: %lu\n", uc.cmd);
@@ -56,14 +53,9 @@ static void test_msr_platform_info_enabled(struct kvm_vcpu *vcpu)
 
 static void test_msr_platform_info_disabled(struct kvm_vcpu *vcpu)
 {
-       struct kvm_run *run = vcpu->run;
-
        vm_enable_cap(vcpu->vm, KVM_CAP_MSR_PLATFORM_INFO, false);
        vcpu_run(vcpu);
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_SHUTDOWN,
-                       "Exit_reason other than KVM_EXIT_SHUTDOWN: %u (%s)\n",
-                       run->exit_reason,
-                       exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_SHUTDOWN);
 }
 
 int main(int argc, char *argv[])
index bad7ef8c5b92e991f6e3d689c98c1c9139e31ca0..2feef25ba69134ea132e9fb441e5fca732de67bc 100644 (file)
@@ -151,14 +151,10 @@ static void amd_guest_code(void)
  */
 static uint64_t run_vcpu_to_sync(struct kvm_vcpu *vcpu)
 {
-       struct kvm_run *run = vcpu->run;
        struct ucall uc;
 
        vcpu_run(vcpu);
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                   "Exit_reason other than KVM_EXIT_IO: %u (%s)\n",
-                   run->exit_reason,
-                   exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
        get_ucall(vcpu, &uc);
        TEST_ASSERT(uc.cmd == UCALL_SYNC,
                    "Received ucall other than UCALL_SYNC: %lu", uc.cmd);
index cb38a478e1f62aec9e52ca861baddfaf07b03ee8..e18b86666e1fc2d9814c287f81fae95dc9dadfa4 100644 (file)
@@ -133,7 +133,6 @@ int main(int argc, char *argv[])
        struct kvm_vcpu *vcpu;
        struct kvm_regs regs;
        struct kvm_vm *vm;
-       struct kvm_run *run;
        struct kvm_x86_state *state;
        int stage, stage_reported;
 
@@ -142,8 +141,6 @@ int main(int argc, char *argv[])
        /* Create VM */
        vm = vm_create_with_one_vcpu(&vcpu, guest_code);
 
-       run = vcpu->run;
-
        vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, SMRAM_GPA,
                                    SMRAM_MEMSLOT, SMRAM_PAGES, 0);
        TEST_ASSERT(vm_phy_pages_alloc(vm, SMRAM_PAGES, SMRAM_GPA, SMRAM_MEMSLOT)
@@ -169,10 +166,7 @@ int main(int argc, char *argv[])
 
        for (stage = 1;; stage++) {
                vcpu_run(vcpu);
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Stage %d: unexpected exit reason: %u (%s),\n",
-                           stage, run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                memset(&regs, 0, sizeof(regs));
                vcpu_regs_get(vcpu, &regs);
@@ -208,7 +202,6 @@ int main(int argc, char *argv[])
 
                vcpu = vm_recreate_with_one_vcpu(vm);
                vcpu_load_state(vcpu, state);
-               run = vcpu->run;
                kvm_x86_state_cleanup(state);
        }
 
index ea578971fb9f9278893ed115a63dbfa417979727..4c4925a8ab4523452326a417634764f85fce19ca 100644 (file)
@@ -158,14 +158,12 @@ int main(int argc, char *argv[])
        struct kvm_regs regs1, regs2;
        struct kvm_vcpu *vcpu;
        struct kvm_vm *vm;
-       struct kvm_run *run;
        struct kvm_x86_state *state;
        struct ucall uc;
        int stage;
 
        /* Create VM */
        vm = vm_create_with_one_vcpu(&vcpu, guest_code);
-       run = vcpu->run;
 
        vcpu_regs_get(vcpu, &regs1);
 
@@ -183,10 +181,7 @@ int main(int argc, char *argv[])
 
        for (stage = 1;; stage++) {
                vcpu_run(vcpu);
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Stage %d: unexpected exit reason: %u (%s),\n",
-                           stage, run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_ABORT:
@@ -214,7 +209,6 @@ int main(int argc, char *argv[])
                /* Restore state in a new VM.  */
                vcpu = vm_recreate_with_one_vcpu(vm);
                vcpu_load_state(vcpu, state);
-               run = vcpu->run;
                kvm_x86_state_cleanup(state);
 
                memset(&regs2, 0, sizeof(regs2));
index 4a07ba227b9954cbe99dc10b84bea96e78e80f22..32bef39bec2178068238a2de650f87179acc22f6 100644 (file)
@@ -85,7 +85,6 @@ static void l1_guest_code(struct svm_test_data *svm)
 int main(int argc, char *argv[])
 {
        struct kvm_vcpu *vcpu;
-       struct kvm_run *run;
        vm_vaddr_t svm_gva;
        struct kvm_vm *vm;
        struct ucall uc;
@@ -103,13 +102,8 @@ int main(int argc, char *argv[])
        vcpu_alloc_svm(vm, &svm_gva);
        vcpu_args_set(vcpu, 1, svm_gva);
 
-       run = vcpu->run;
-
        vcpu_run(vcpu);
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                   "Got exit_reason other than KVM_EXIT_IO: %u (%s)\n",
-                   run->exit_reason,
-                   exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
        switch (get_ucall(vcpu, &uc)) {
        case UCALL_ABORT:
index e73fcdef47bbe910a4643a33404c17c28635097d..d6fcdcc3af3144b6805cf3d9530614b03476ac79 100644 (file)
@@ -42,7 +42,6 @@ static void l1_guest_code(struct svm_test_data *svm, struct idt_entry *idt)
 int main(int argc, char *argv[])
 {
        struct kvm_vcpu *vcpu;
-       struct kvm_run *run;
        vm_vaddr_t svm_gva;
        struct kvm_vm *vm;
 
@@ -55,13 +54,9 @@ int main(int argc, char *argv[])
        vcpu_alloc_svm(vm, &svm_gva);
 
        vcpu_args_set(vcpu, 2, svm_gva, vm->idt);
-       run = vcpu->run;
 
        vcpu_run(vcpu);
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_SHUTDOWN,
-                   "Got exit_reason other than KVM_EXIT_SHUTDOWN: %u (%s)\n",
-                   run->exit_reason,
-                   exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_SHUTDOWN);
 
        kvm_vm_free(vm);
 }
index b34980d45648a68de61051cd521f49b21e8fa719..4e2479716da6eb5b567151593beac16c419a8220 100644 (file)
@@ -176,16 +176,12 @@ static void run_test(bool is_nmi)
        memset(&debug, 0, sizeof(debug));
        vcpu_guest_debug_set(vcpu, &debug);
 
-       struct kvm_run *run = vcpu->run;
        struct ucall uc;
 
        alarm(2);
        vcpu_run(vcpu);
        alarm(0);
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                   "Got exit_reason other than KVM_EXIT_IO: %u (%s)\n",
-                   run->exit_reason,
-                   exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
        switch (get_ucall(vcpu, &uc)) {
        case UCALL_ABORT:
index c3ac45df748325151aae1f7c27e994be924c171c..8a62cca28cfbb377af77b31b985b3e8694430edf 100644 (file)
@@ -47,14 +47,10 @@ int main(int argc, char *argv[])
        vcpu_args_set(vcpu, 1, svm_gva);
 
        for (;;) {
-               volatile struct kvm_run *run = vcpu->run;
                struct ucall uc;
 
                vcpu_run(vcpu);
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Got exit_reason other than KVM_EXIT_IO: %u (%s)\n",
-                           run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_ABORT:
index d2f9b5bdfab20b6c3eae23afc249049b61af343d..2da89fdc2471a7f95983c66b1c744a5365ad007c 100644 (file)
@@ -132,10 +132,7 @@ int main(int argc, char *argv[])
        /* TODO: BUILD TIME CHECK: TEST_ASSERT(KVM_SYNC_X86_NUM_FIELDS != 3); */
        run->kvm_valid_regs = TEST_SYNC_FIELDS;
        rv = _vcpu_run(vcpu);
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                   "Unexpected exit reason: %u (%s),\n",
-                   run->exit_reason,
-                   exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
        vcpu_regs_get(vcpu, &regs);
        compare_regs(&regs, &run->s.regs.regs);
@@ -154,10 +151,7 @@ int main(int argc, char *argv[])
        run->kvm_valid_regs = TEST_SYNC_FIELDS;
        run->kvm_dirty_regs = KVM_SYNC_X86_REGS | KVM_SYNC_X86_SREGS;
        rv = _vcpu_run(vcpu);
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                   "Unexpected exit reason: %u (%s),\n",
-                   run->exit_reason,
-                   exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
        TEST_ASSERT(run->s.regs.regs.rbx == 0xBAD1DEA + 1,
                    "rbx sync regs value incorrect 0x%llx.",
                    run->s.regs.regs.rbx);
@@ -181,10 +175,7 @@ int main(int argc, char *argv[])
        run->kvm_dirty_regs = 0;
        run->s.regs.regs.rbx = 0xDEADBEEF;
        rv = _vcpu_run(vcpu);
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                   "Unexpected exit reason: %u (%s),\n",
-                   run->exit_reason,
-                   exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
        TEST_ASSERT(run->s.regs.regs.rbx != 0xDEADBEEF,
                    "rbx sync regs value incorrect 0x%llx.",
                    run->s.regs.regs.rbx);
@@ -199,10 +190,7 @@ int main(int argc, char *argv[])
        regs.rbx = 0xBAC0;
        vcpu_regs_set(vcpu, &regs);
        rv = _vcpu_run(vcpu);
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                   "Unexpected exit reason: %u (%s),\n",
-                   run->exit_reason,
-                   exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
        TEST_ASSERT(run->s.regs.regs.rbx == 0xAAAA,
                    "rbx sync regs value incorrect 0x%llx.",
                    run->s.regs.regs.rbx);
@@ -219,10 +207,7 @@ int main(int argc, char *argv[])
        run->kvm_dirty_regs = TEST_SYNC_FIELDS;
        run->s.regs.regs.rbx = 0xBBBB;
        rv = _vcpu_run(vcpu);
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                   "Unexpected exit reason: %u (%s),\n",
-                   run->exit_reason,
-                   exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
        TEST_ASSERT(run->s.regs.regs.rbx == 0xBBBB,
                    "rbx sync regs value incorrect 0x%llx.",
                    run->s.regs.regs.rbx);
index ead5d878a71c458348d9e86100016bc8bd2a72b4..56306a19144a7db90a7f0906aede46e75ee346a1 100644 (file)
@@ -89,9 +89,7 @@ int main(void)
        run = vcpu->run;
        vcpu_run(vcpu);
 
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                   "Expected KVM_EXIT_IO, got: %u (%s)\n",
-                   run->exit_reason, exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
        TEST_ASSERT(run->io.port == ARBITRARY_IO_PORT,
                    "Expected IN from port %d from L2, got port %d",
                    ARBITRARY_IO_PORT, run->io.port);
@@ -111,10 +109,7 @@ int main(void)
 
 
        if (has_svm) {
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_SHUTDOWN,
-                           "Got exit_reason other than KVM_EXIT_SHUTDOWN: %u (%s)\n",
-                           run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_SHUTDOWN);
        } else {
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_DONE:
index 47139aab74084b29ba356dd9ddd4d76edb0105eb..5b669818e39aaa2313d0887c0324aca4b628ed3c 100644 (file)
@@ -64,14 +64,10 @@ static void *run_vcpu(void *_cpu_nr)
        pthread_spin_unlock(&create_lock);
 
        for (;;) {
-               volatile struct kvm_run *run = vcpu->run;
                 struct ucall uc;
 
                vcpu_run(vcpu);
-                TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                            "Got exit_reason other than KVM_EXIT_IO: %u (%s)\n",
-                            run->exit_reason,
-                            exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                 case UCALL_DONE:
index a897c7fd8abe464d57a2927f5526b3f6f7044d62..85f34ca7e49e531c11e09f700738d0eec2a0e0fa 100644 (file)
@@ -137,15 +137,11 @@ static void guest_gp_handler(struct ex_regs *regs)
 
 static void run_vcpu_expect_gp(struct kvm_vcpu *vcpu)
 {
-       unsigned int exit_reason;
        struct ucall uc;
 
        vcpu_run(vcpu);
 
-       exit_reason = vcpu->run->exit_reason;
-       TEST_ASSERT(exit_reason == KVM_EXIT_IO,
-                   "exited with unexpected exit reason %u-%s, expected KVM_EXIT_IO",
-                   exit_reason, exit_reason_str(exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
        TEST_ASSERT(get_ucall(vcpu, &uc) == UCALL_SYNC,
                    "Expect UCALL_SYNC\n");
        TEST_ASSERT(uc.args[1] == SYNC_GP, "#GP is expected.");
@@ -182,7 +178,6 @@ static void *run_ucna_injection(void *arg)
        struct ucall uc;
        int old;
        int r;
-       unsigned int exit_reason;
 
        r = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old);
        TEST_ASSERT(r == 0,
@@ -191,10 +186,7 @@ static void *run_ucna_injection(void *arg)
 
        vcpu_run(params->vcpu);
 
-       exit_reason = params->vcpu->run->exit_reason;
-       TEST_ASSERT(exit_reason == KVM_EXIT_IO,
-                   "unexpected exit reason %u-%s, expected KVM_EXIT_IO",
-                   exit_reason, exit_reason_str(exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(params->vcpu, KVM_EXIT_IO);
        TEST_ASSERT(get_ucall(params->vcpu, &uc) == UCALL_SYNC,
                    "Expect UCALL_SYNC\n");
        TEST_ASSERT(uc.args[1] == SYNC_FIRST_UCNA, "Injecting first UCNA.");
@@ -204,10 +196,7 @@ static void *run_ucna_injection(void *arg)
        inject_ucna(params->vcpu, FIRST_UCNA_ADDR);
        vcpu_run(params->vcpu);
 
-       exit_reason = params->vcpu->run->exit_reason;
-       TEST_ASSERT(exit_reason == KVM_EXIT_IO,
-                   "unexpected exit reason %u-%s, expected KVM_EXIT_IO",
-                   exit_reason, exit_reason_str(exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(params->vcpu, KVM_EXIT_IO);
        TEST_ASSERT(get_ucall(params->vcpu, &uc) == UCALL_SYNC,
                    "Expect UCALL_SYNC\n");
        TEST_ASSERT(uc.args[1] == SYNC_SECOND_UCNA, "Injecting second UCNA.");
@@ -217,10 +206,7 @@ static void *run_ucna_injection(void *arg)
        inject_ucna(params->vcpu, SECOND_UCNA_ADDR);
        vcpu_run(params->vcpu);
 
-       exit_reason = params->vcpu->run->exit_reason;
-       TEST_ASSERT(exit_reason == KVM_EXIT_IO,
-                   "unexpected exit reason %u-%s, expected KVM_EXIT_IO",
-                   exit_reason, exit_reason_str(exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(params->vcpu, KVM_EXIT_IO);
        if (get_ucall(params->vcpu, &uc) == UCALL_ABORT) {
                TEST_ASSERT(false, "vCPU assertion failure: %s.\n",
                            (const char *)uc.args[0]);
index 91076c9787b41e322a1b3c3de2c35b066295d710..0cb51fa42773b23278448b66174f05052a407465 100644 (file)
@@ -63,11 +63,7 @@ int main(int argc, char *argv[])
 
        while (1) {
                vcpu_run(vcpu);
-
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Unexpected exit reason: %u (%s),\n",
-                           run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                if (get_ucall(vcpu, &uc))
                        break;
index 25fa55344a10efb23b972e41d1f62262ee928e70..3533dc2fbfeeb136b217eb79e819e2e374e2b0cd 100644 (file)
@@ -410,10 +410,7 @@ static void process_rdmsr(struct kvm_vcpu *vcpu, uint32_t msr_index)
 
        check_for_guest_assert(vcpu);
 
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_X86_RDMSR,
-                   "Unexpected exit reason: %u (%s),\n",
-                   run->exit_reason,
-                   exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_X86_RDMSR);
        TEST_ASSERT(run->msr.index == msr_index,
                        "Unexpected msr (0x%04x), expected 0x%04x",
                        run->msr.index, msr_index);
@@ -445,10 +442,7 @@ static void process_wrmsr(struct kvm_vcpu *vcpu, uint32_t msr_index)
 
        check_for_guest_assert(vcpu);
 
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_X86_WRMSR,
-                   "Unexpected exit reason: %u (%s),\n",
-                   run->exit_reason,
-                   exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_X86_WRMSR);
        TEST_ASSERT(run->msr.index == msr_index,
                        "Unexpected msr (0x%04x), expected 0x%04x",
                        run->msr.index, msr_index);
@@ -472,15 +466,11 @@ static void process_wrmsr(struct kvm_vcpu *vcpu, uint32_t msr_index)
 
 static void process_ucall_done(struct kvm_vcpu *vcpu)
 {
-       struct kvm_run *run = vcpu->run;
        struct ucall uc;
 
        check_for_guest_assert(vcpu);
 
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                   "Unexpected exit reason: %u (%s)",
-                   run->exit_reason,
-                   exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
        TEST_ASSERT(get_ucall(vcpu, &uc) == UCALL_DONE,
                    "Unexpected ucall command: %lu, expected UCALL_DONE (%d)",
@@ -489,15 +479,11 @@ static void process_ucall_done(struct kvm_vcpu *vcpu)
 
 static uint64_t process_ucall(struct kvm_vcpu *vcpu)
 {
-       struct kvm_run *run = vcpu->run;
        struct ucall uc = {};
 
        check_for_guest_assert(vcpu);
 
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                   "Unexpected exit reason: %u (%s)",
-                   run->exit_reason,
-                   exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
        switch (get_ucall(vcpu, &uc)) {
        case UCALL_SYNC:
index 5abecf06329eaccd2ac85e0fb6b57075d5628f15..2bed5fb3a0d6e51aa63f9732d77dac330378d2c8 100644 (file)
@@ -96,21 +96,14 @@ int main(int argc, char *argv[])
 
                vcpu_run(vcpu);
                if (apic_access_addr == high_gpa) {
-                       TEST_ASSERT(run->exit_reason ==
-                                   KVM_EXIT_INTERNAL_ERROR,
-                                   "Got exit reason other than KVM_EXIT_INTERNAL_ERROR: %u (%s)\n",
-                                   run->exit_reason,
-                                   exit_reason_str(run->exit_reason));
+                       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_INTERNAL_ERROR);
                        TEST_ASSERT(run->internal.suberror ==
                                    KVM_INTERNAL_ERROR_EMULATION,
                                    "Got internal suberror other than KVM_INTERNAL_ERROR_EMULATION: %u\n",
                                    run->internal.suberror);
                        break;
                }
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Got exit_reason other than KVM_EXIT_IO: %u (%s)\n",
-                           run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_ABORT:
index d79651b027402d6f349eb594a03fdc425ce3843a..dad988351493e089bf0f9b62d7604d89b65137a7 100644 (file)
@@ -64,10 +64,7 @@ int main(int argc, char *argv[])
                struct ucall uc;
 
                vcpu_run(vcpu);
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Got exit_reason other than KVM_EXIT_IO: %u (%s)\n",
-                           run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                if (run->io.port == PORT_L0_EXIT)
                        break;
index f0456fb031b1ef465c9f6177af630599e5d92daf..e4ad5fef52ffc5b08ec8d3f445b518b52229e672 100644 (file)
@@ -73,7 +73,6 @@ int main(int argc, char *argv[])
 
        struct kvm_vcpu *vcpu;
        struct kvm_vm *vm;
-       struct kvm_run *run;
        struct ucall uc;
        bool done = false;
 
@@ -84,7 +83,6 @@ int main(int argc, char *argv[])
        vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code);
        vmx = vcpu_alloc_vmx(vm, &vmx_pages_gva);
        vcpu_args_set(vcpu, 1, vmx_pages_gva);
-       run = vcpu->run;
 
        /* Add an extra memory slot for testing dirty logging */
        vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS,
@@ -117,10 +115,7 @@ int main(int argc, char *argv[])
        while (!done) {
                memset(host_test_mem, 0xaa, TEST_MEM_PAGES * 4096);
                vcpu_run(vcpu);
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Unexpected exit reason: %u (%s),\n",
-                           run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_ABORT:
index ccdfa5dc1a4dc6fdc5876575dfb6240c3beff536..be0bdb8c6f78c27a3fa573ea87f66ddc58bf79c8 100644 (file)
@@ -26,9 +26,7 @@ static void __run_vcpu_with_invalid_state(struct kvm_vcpu *vcpu)
 
        vcpu_run(vcpu);
 
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_INTERNAL_ERROR,
-                   "Expected KVM_EXIT_INTERNAL_ERROR, got %d (%s)\n",
-                   run->exit_reason, exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_INTERNAL_ERROR);
        TEST_ASSERT(run->emulation_failure.suberror == KVM_INTERNAL_ERROR_EMULATION,
                    "Expected emulation failure, got %d\n",
                    run->emulation_failure.suberror);
index 6bfb4bb471ca2b68f7cdaeeece7b93ba4d6d33db..a100ee5f000936e8e397d2112071b19f18192ff5 100644 (file)
@@ -74,9 +74,7 @@ int main(int argc, char *argv[])
         * The first exit to L0 userspace should be an I/O access from L2.
         * Running L1 should launch L2 without triggering an exit to userspace.
         */
-       TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                   "Expected KVM_EXIT_IO, got: %u (%s)\n",
-                   run->exit_reason, exit_reason_str(run->exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
        TEST_ASSERT(run->io.port == ARBITRARY_IO_PORT,
                    "Expected IN from port %d from L2, got port %d",
index 465a9434d61c2b9d7cc3611d719e32598365f00b..d427eb146bc5818e8d96a93da7c00a1b485bcf81 100644 (file)
@@ -183,14 +183,10 @@ int main(int argc, char *argv[])
        vcpu_ioctl(vcpu, KVM_SET_TSC_KHZ, (void *) (tsc_khz / l1_scale_factor));
 
        for (;;) {
-               volatile struct kvm_run *run = vcpu->run;
                struct ucall uc;
 
                vcpu_run(vcpu);
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Got exit_reason other than KVM_EXIT_IO: %u (%s)\n",
-                           run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_ABORT:
index 0efdc05969a56395db7774821c9023fb93928d9c..affc32800158415225e2a5c0cd2d75ce0f727e30 100644 (file)
@@ -157,7 +157,6 @@ int main(int argc, char *argv[])
 
        struct kvm_regs regs1, regs2;
        struct kvm_vm *vm;
-       struct kvm_run *run;
        struct kvm_vcpu *vcpu;
        struct kvm_x86_state *state;
        struct ucall uc;
@@ -173,7 +172,6 @@ int main(int argc, char *argv[])
 
        /* Create VM */
        vm = vm_create_with_one_vcpu(&vcpu, guest_code);
-       run = vcpu->run;
 
        vcpu_regs_get(vcpu, &regs1);
 
@@ -182,10 +180,7 @@ int main(int argc, char *argv[])
 
        for (stage = 1;; stage++) {
                vcpu_run(vcpu);
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Stage %d: unexpected exit reason: %u (%s),\n",
-                           stage, run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_ABORT:
@@ -237,7 +232,6 @@ int main(int argc, char *argv[])
                /* Restore state in a new VM.  */
                vcpu = vm_recreate_with_one_vcpu(vm);
                vcpu_load_state(vcpu, state);
-               run = vcpu->run;
                kvm_x86_state_cleanup(state);
 
                memset(&regs2, 0, sizeof(regs2));
index ff8ecdf32ae07d9e448e32af6839943a1ed3d51b..2ceb5c78c442710166c2ecc1243d812cb1839793 100644 (file)
@@ -131,14 +131,10 @@ int main(int argc, char *argv[])
        vcpu_args_set(vcpu, 1, vmx_pages_gva);
 
        for (;;) {
-               volatile struct kvm_run *run = vcpu->run;
                struct ucall uc;
 
                vcpu_run(vcpu);
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Got exit_reason other than KVM_EXIT_IO: %u (%s)\n",
-                           run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_ABORT:
index 3d272d7f961ef1948e65e588f0d6cad30e7ebe70..67ac2a3292efd4e5a4ff24073af25849ce375dd9 100644 (file)
@@ -198,7 +198,6 @@ static void *vcpu_thread(void *arg)
        struct ucall uc;
        int old;
        int r;
-       unsigned int exit_reason;
 
        r = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old);
        TEST_ASSERT(r == 0,
@@ -207,11 +206,8 @@ static void *vcpu_thread(void *arg)
 
        fprintf(stderr, "vCPU thread running vCPU %u\n", vcpu->id);
        vcpu_run(vcpu);
-       exit_reason = vcpu->run->exit_reason;
 
-       TEST_ASSERT(exit_reason == KVM_EXIT_IO,
-                   "vCPU %u exited with unexpected exit reason %u-%s, expected KVM_EXIT_IO",
-                   vcpu->id, exit_reason, exit_reason_str(exit_reason));
+       TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
        if (get_ucall(vcpu, &uc) == UCALL_ABORT) {
                TEST_ASSERT(false,
index 5a3bf8f6141761ef81750d7ba04ae46768a7f874..05898ad9f4d992b3c7eba0a9ec677b21315689e6 100644 (file)
@@ -26,6 +26,9 @@
 #define DUMMY_REGION_GPA       (SHINFO_REGION_GPA + (3 * PAGE_SIZE))
 #define DUMMY_REGION_SLOT      11
 
+#define DUMMY_REGION_GPA_2     (SHINFO_REGION_GPA + (4 * PAGE_SIZE))
+#define DUMMY_REGION_SLOT_2    12
+
 #define SHINFO_ADDR    (SHINFO_REGION_GPA)
 #define VCPU_INFO_ADDR (SHINFO_REGION_GPA + 0x40)
 #define PVTIME_ADDR    (SHINFO_REGION_GPA + PAGE_SIZE)
 #define EVTCHN_TEST2 66
 #define EVTCHN_TIMER 13
 
+enum {
+       TEST_INJECT_VECTOR = 0,
+       TEST_RUNSTATE_runnable,
+       TEST_RUNSTATE_blocked,
+       TEST_RUNSTATE_offline,
+       TEST_RUNSTATE_ADJUST,
+       TEST_RUNSTATE_DATA,
+       TEST_STEAL_TIME,
+       TEST_EVTCHN_MASKED,
+       TEST_EVTCHN_UNMASKED,
+       TEST_EVTCHN_SLOWPATH,
+       TEST_EVTCHN_SEND_IOCTL,
+       TEST_EVTCHN_HCALL,
+       TEST_EVTCHN_HCALL_SLOWPATH,
+       TEST_EVTCHN_HCALL_EVENTFD,
+       TEST_TIMER_SETUP,
+       TEST_TIMER_WAIT,
+       TEST_TIMER_RESTORE,
+       TEST_POLL_READY,
+       TEST_POLL_TIMEOUT,
+       TEST_POLL_MASKED,
+       TEST_POLL_WAKE,
+       TEST_TIMER_PAST,
+       TEST_LOCKING_SEND_RACE,
+       TEST_LOCKING_POLL_RACE,
+       TEST_LOCKING_POLL_TIMEOUT,
+       TEST_DONE,
+
+       TEST_GUEST_SAW_IRQ,
+};
+
 #define XEN_HYPERCALL_MSR      0x40000000
 
 #define MIN_STEAL_TIME         50000
@@ -144,7 +178,7 @@ static void evtchn_handler(struct ex_regs *regs)
        vi->evtchn_pending_sel = 0;
        guest_saw_irq = true;
 
-       GUEST_SYNC(0x20);
+       GUEST_SYNC(TEST_GUEST_SAW_IRQ);
 }
 
 static void guest_wait_for_irq(void)
@@ -165,41 +199,41 @@ static void guest_code(void)
        );
 
        /* Trigger an interrupt injection */
-       GUEST_SYNC(0);
+       GUEST_SYNC(TEST_INJECT_VECTOR);
 
        guest_wait_for_irq();
 
        /* Test having the host set runstates manually */
-       GUEST_SYNC(RUNSTATE_runnable);
+       GUEST_SYNC(TEST_RUNSTATE_runnable);
        GUEST_ASSERT(rs->time[RUNSTATE_runnable] != 0);
        GUEST_ASSERT(rs->state == 0);
 
-       GUEST_SYNC(RUNSTATE_blocked);
+       GUEST_SYNC(TEST_RUNSTATE_blocked);
        GUEST_ASSERT(rs->time[RUNSTATE_blocked] != 0);
        GUEST_ASSERT(rs->state == 0);
 
-       GUEST_SYNC(RUNSTATE_offline);
+       GUEST_SYNC(TEST_RUNSTATE_offline);
        GUEST_ASSERT(rs->time[RUNSTATE_offline] != 0);
        GUEST_ASSERT(rs->state == 0);
 
        /* Test runstate time adjust */
-       GUEST_SYNC(4);
+       GUEST_SYNC(TEST_RUNSTATE_ADJUST);
        GUEST_ASSERT(rs->time[RUNSTATE_blocked] == 0x5a);
        GUEST_ASSERT(rs->time[RUNSTATE_offline] == 0x6b6b);
 
        /* Test runstate time set */
-       GUEST_SYNC(5);
+       GUEST_SYNC(TEST_RUNSTATE_DATA);
        GUEST_ASSERT(rs->state_entry_time >= 0x8000);
        GUEST_ASSERT(rs->time[RUNSTATE_runnable] == 0);
        GUEST_ASSERT(rs->time[RUNSTATE_blocked] == 0x6b6b);
        GUEST_ASSERT(rs->time[RUNSTATE_offline] == 0x5a);
 
        /* sched_yield() should result in some 'runnable' time */
-       GUEST_SYNC(6);
+       GUEST_SYNC(TEST_STEAL_TIME);
        GUEST_ASSERT(rs->time[RUNSTATE_runnable] >= MIN_STEAL_TIME);
 
        /* Attempt to deliver a *masked* interrupt */
-       GUEST_SYNC(7);
+       GUEST_SYNC(TEST_EVTCHN_MASKED);
 
        /* Wait until we see the bit set */
        struct shared_info *si = (void *)SHINFO_VADDR;
@@ -207,71 +241,65 @@ static void guest_code(void)
                __asm__ __volatile__ ("rep nop" : : : "memory");
 
        /* Now deliver an *unmasked* interrupt */
-       GUEST_SYNC(8);
+       GUEST_SYNC(TEST_EVTCHN_UNMASKED);
 
        guest_wait_for_irq();
 
        /* Change memslots and deliver an interrupt */
-       GUEST_SYNC(9);
+       GUEST_SYNC(TEST_EVTCHN_SLOWPATH);
 
        guest_wait_for_irq();
 
        /* Deliver event channel with KVM_XEN_HVM_EVTCHN_SEND */
-       GUEST_SYNC(10);
+       GUEST_SYNC(TEST_EVTCHN_SEND_IOCTL);
 
        guest_wait_for_irq();
 
-       GUEST_SYNC(11);
+       GUEST_SYNC(TEST_EVTCHN_HCALL);
 
        /* Our turn. Deliver event channel (to ourselves) with
         * EVTCHNOP_send hypercall. */
-       unsigned long rax;
        struct evtchn_send s = { .port = 127 };
-       __asm__ __volatile__ ("vmcall" :
-                             "=a" (rax) :
-                             "a" (__HYPERVISOR_event_channel_op),
-                             "D" (EVTCHNOP_send),
-                             "S" (&s));
+       xen_hypercall(__HYPERVISOR_event_channel_op, EVTCHNOP_send, &s);
+
+       guest_wait_for_irq();
+
+       GUEST_SYNC(TEST_EVTCHN_HCALL_SLOWPATH);
 
-       GUEST_ASSERT(rax == 0);
+       /*
+        * Same again, but this time the host has messed with memslots so it
+        * should take the slow path in kvm_xen_set_evtchn().
+        */
+       xen_hypercall(__HYPERVISOR_event_channel_op, EVTCHNOP_send, &s);
 
        guest_wait_for_irq();
 
-       GUEST_SYNC(12);
+       GUEST_SYNC(TEST_EVTCHN_HCALL_EVENTFD);
 
        /* Deliver "outbound" event channel to an eventfd which
         * happens to be one of our own irqfds. */
        s.port = 197;
-       __asm__ __volatile__ ("vmcall" :
-                             "=a" (rax) :
-                             "a" (__HYPERVISOR_event_channel_op),
-                             "D" (EVTCHNOP_send),
-                             "S" (&s));
-
-       GUEST_ASSERT(rax == 0);
+       xen_hypercall(__HYPERVISOR_event_channel_op, EVTCHNOP_send, &s);
 
        guest_wait_for_irq();
 
-       GUEST_SYNC(13);
+       GUEST_SYNC(TEST_TIMER_SETUP);
 
        /* Set a timer 100ms in the future. */
-       __asm__ __volatile__ ("vmcall" :
-                             "=a" (rax) :
-                             "a" (__HYPERVISOR_set_timer_op),
-                             "D" (rs->state_entry_time + 100000000));
-       GUEST_ASSERT(rax == 0);
+       xen_hypercall(__HYPERVISOR_set_timer_op,
+                     rs->state_entry_time + 100000000, NULL);
 
-       GUEST_SYNC(14);
+       GUEST_SYNC(TEST_TIMER_WAIT);
 
        /* Now wait for the timer */
        guest_wait_for_irq();
 
-       GUEST_SYNC(15);
+       GUEST_SYNC(TEST_TIMER_RESTORE);
 
        /* The host has 'restored' the timer. Just wait for it. */
        guest_wait_for_irq();
 
-       GUEST_SYNC(16);
+       GUEST_SYNC(TEST_POLL_READY);
 
        /* Poll for an event channel port which is already set */
        u32 ports[1] = { EVTCHN_TIMER };
@@ -281,65 +309,41 @@ static void guest_code(void)
                .timeout = 0,
        };
 
-       __asm__ __volatile__ ("vmcall" :
-                             "=a" (rax) :
-                             "a" (__HYPERVISOR_sched_op),
-                             "D" (SCHEDOP_poll),
-                             "S" (&p));
+       xen_hypercall(__HYPERVISOR_sched_op, SCHEDOP_poll, &p);
 
-       GUEST_ASSERT(rax == 0);
-
-       GUEST_SYNC(17);
+       GUEST_SYNC(TEST_POLL_TIMEOUT);
 
        /* Poll for an unset port and wait for the timeout. */
        p.timeout = 100000000;
-       __asm__ __volatile__ ("vmcall" :
-                             "=a" (rax) :
-                             "a" (__HYPERVISOR_sched_op),
-                             "D" (SCHEDOP_poll),
-                             "S" (&p));
-
-       GUEST_ASSERT(rax == 0);
+       xen_hypercall(__HYPERVISOR_sched_op, SCHEDOP_poll, &p);
 
-       GUEST_SYNC(18);
+       GUEST_SYNC(TEST_POLL_MASKED);
 
        /* A timer will wake the masked port we're waiting on, while we poll */
        p.timeout = 0;
-       __asm__ __volatile__ ("vmcall" :
-                             "=a" (rax) :
-                             "a" (__HYPERVISOR_sched_op),
-                             "D" (SCHEDOP_poll),
-                             "S" (&p));
-
-       GUEST_ASSERT(rax == 0);
+       xen_hypercall(__HYPERVISOR_sched_op, SCHEDOP_poll, &p);
 
-       GUEST_SYNC(19);
+       GUEST_SYNC(TEST_POLL_WAKE);
 
        /* A timer wake an *unmasked* port which should wake us with an
         * actual interrupt, while we're polling on a different port. */
        ports[0]++;
        p.timeout = 0;
-       __asm__ __volatile__ ("vmcall" :
-                             "=a" (rax) :
-                             "a" (__HYPERVISOR_sched_op),
-                             "D" (SCHEDOP_poll),
-                             "S" (&p));
-
-       GUEST_ASSERT(rax == 0);
+       xen_hypercall(__HYPERVISOR_sched_op, SCHEDOP_poll, &p);
 
        guest_wait_for_irq();
 
-       GUEST_SYNC(20);
+       GUEST_SYNC(TEST_TIMER_PAST);
 
        /* Timer should have fired already */
        guest_wait_for_irq();
 
-       GUEST_SYNC(21);
+       GUEST_SYNC(TEST_LOCKING_SEND_RACE);
        /* Racing host ioctls */
 
        guest_wait_for_irq();
 
-       GUEST_SYNC(22);
+       GUEST_SYNC(TEST_LOCKING_POLL_RACE);
        /* Racing vmcall against host ioctl */
 
        ports[0] = 0;
@@ -360,24 +364,19 @@ wait_for_timer:
         * timer IRQ is dropped due to an invalid event channel.
         */
        for (i = 0; i < 100 && !guest_saw_irq; i++)
-               asm volatile("vmcall"
-                            : "=a" (rax)
-                            : "a" (__HYPERVISOR_sched_op),
-                              "D" (SCHEDOP_poll),
-                              "S" (&p)
-                            : "memory");
+               __xen_hypercall(__HYPERVISOR_sched_op, SCHEDOP_poll, &p);
 
        /*
         * Re-send the timer IRQ if it was (likely) dropped due to the timer
         * expiring while the event channel was invalid.
         */
        if (!guest_saw_irq) {
-               GUEST_SYNC(23);
+               GUEST_SYNC(TEST_LOCKING_POLL_TIMEOUT);
                goto wait_for_timer;
        }
        guest_saw_irq = false;
 
-       GUEST_SYNC(24);
+       GUEST_SYNC(TEST_DONE);
 }
 
 static int cmp_timespec(struct timespec *a, struct timespec *b)
@@ -623,15 +622,10 @@ int main(int argc, char *argv[])
        bool evtchn_irq_expected = false;
 
        for (;;) {
-               volatile struct kvm_run *run = vcpu->run;
                struct ucall uc;
 
                vcpu_run(vcpu);
-
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Got exit_reason other than KVM_EXIT_IO: %u (%s)\n",
-                           run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_ABORT:
@@ -647,25 +641,26 @@ int main(int argc, char *argv[])
                                            "runstate times don't add up");
 
                        switch (uc.args[1]) {
-                       case 0:
+                       case TEST_INJECT_VECTOR:
                                if (verbose)
                                        printf("Delivering evtchn upcall\n");
                                evtchn_irq_expected = true;
                                vinfo->evtchn_upcall_pending = 1;
                                break;
 
-                       case RUNSTATE_runnable...RUNSTATE_offline:
+                       case TEST_RUNSTATE_runnable...TEST_RUNSTATE_offline:
                                TEST_ASSERT(!evtchn_irq_expected, "Event channel IRQ not seen");
                                if (!do_runstate_tests)
                                        goto done;
                                if (verbose)
                                        printf("Testing runstate %s\n", runstate_names[uc.args[1]]);
                                rst.type = KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT;
-                               rst.u.runstate.state = uc.args[1];
+                               rst.u.runstate.state = uc.args[1] + RUNSTATE_runnable -
+                                       TEST_RUNSTATE_runnable;
                                vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &rst);
                                break;
 
-                       case 4:
+                       case TEST_RUNSTATE_ADJUST:
                                if (verbose)
                                        printf("Testing RUNSTATE_ADJUST\n");
                                rst.type = KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST;
@@ -680,7 +675,7 @@ int main(int argc, char *argv[])
                                vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &rst);
                                break;
 
-                       case 5:
+                       case TEST_RUNSTATE_DATA:
                                if (verbose)
                                        printf("Testing RUNSTATE_DATA\n");
                                rst.type = KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA;
@@ -692,7 +687,7 @@ int main(int argc, char *argv[])
                                vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &rst);
                                break;
 
-                       case 6:
+                       case TEST_STEAL_TIME:
                                if (verbose)
                                        printf("Testing steal time\n");
                                /* Yield until scheduler delay exceeds target */
@@ -702,7 +697,7 @@ int main(int argc, char *argv[])
                                } while (get_run_delay() < rundelay);
                                break;
 
-                       case 7:
+                       case TEST_EVTCHN_MASKED:
                                if (!do_eventfd_tests)
                                        goto done;
                                if (verbose)
@@ -712,7 +707,7 @@ int main(int argc, char *argv[])
                                alarm(1);
                                break;
 
-                       case 8:
+                       case TEST_EVTCHN_UNMASKED:
                                if (verbose)
                                        printf("Testing unmasked event channel\n");
                                /* Unmask that, but deliver the other one */
@@ -723,7 +718,7 @@ int main(int argc, char *argv[])
                                alarm(1);
                                break;
 
-                       case 9:
+                       case TEST_EVTCHN_SLOWPATH:
                                TEST_ASSERT(!evtchn_irq_expected,
                                            "Expected event channel IRQ but it didn't happen");
                                shinfo->evtchn_pending[1] = 0;
@@ -736,7 +731,7 @@ int main(int argc, char *argv[])
                                alarm(1);
                                break;
 
-                       case 10:
+                       case TEST_EVTCHN_SEND_IOCTL:
                                TEST_ASSERT(!evtchn_irq_expected,
                                            "Expected event channel IRQ but it didn't happen");
                                if (!do_evtchn_tests)
@@ -756,7 +751,7 @@ int main(int argc, char *argv[])
                                alarm(1);
                                break;
 
-                       case 11:
+                       case TEST_EVTCHN_HCALL:
                                TEST_ASSERT(!evtchn_irq_expected,
                                            "Expected event channel IRQ but it didn't happen");
                                shinfo->evtchn_pending[1] = 0;
@@ -767,7 +762,20 @@ int main(int argc, char *argv[])
                                alarm(1);
                                break;
 
-                       case 12:
+                       case TEST_EVTCHN_HCALL_SLOWPATH:
+                               TEST_ASSERT(!evtchn_irq_expected,
+                                           "Expected event channel IRQ but it didn't happen");
+                               shinfo->evtchn_pending[0] = 0;
+
+                               if (verbose)
+                                       printf("Testing guest EVTCHNOP_send direct to evtchn after memslot change\n");
+                               vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS,
+                                                           DUMMY_REGION_GPA_2, DUMMY_REGION_SLOT_2, 1, 0);
+                               evtchn_irq_expected = true;
+                               alarm(1);
+                               break;
+
+                       case TEST_EVTCHN_HCALL_EVENTFD:
                                TEST_ASSERT(!evtchn_irq_expected,
                                            "Expected event channel IRQ but it didn't happen");
                                shinfo->evtchn_pending[0] = 0;
@@ -778,7 +786,7 @@ int main(int argc, char *argv[])
                                alarm(1);
                                break;
 
-                       case 13:
+                       case TEST_TIMER_SETUP:
                                TEST_ASSERT(!evtchn_irq_expected,
                                            "Expected event channel IRQ but it didn't happen");
                                shinfo->evtchn_pending[1] = 0;
@@ -787,7 +795,7 @@ int main(int argc, char *argv[])
                                        printf("Testing guest oneshot timer\n");
                                break;
 
-                       case 14:
+                       case TEST_TIMER_WAIT:
                                memset(&tmr, 0, sizeof(tmr));
                                tmr.type = KVM_XEN_VCPU_ATTR_TYPE_TIMER;
                                vcpu_ioctl(vcpu, KVM_XEN_VCPU_GET_ATTR, &tmr);
@@ -801,7 +809,7 @@ int main(int argc, char *argv[])
                                alarm(1);
                                break;
 
-                       case 15:
+                       case TEST_TIMER_RESTORE:
                                TEST_ASSERT(!evtchn_irq_expected,
                                            "Expected event channel IRQ but it didn't happen");
                                shinfo->evtchn_pending[0] = 0;
@@ -815,7 +823,7 @@ int main(int argc, char *argv[])
                                alarm(1);
                                break;
 
-                       case 16:
+                       case TEST_POLL_READY:
                                TEST_ASSERT(!evtchn_irq_expected,
                                            "Expected event channel IRQ but it didn't happen");
 
@@ -825,14 +833,14 @@ int main(int argc, char *argv[])
                                alarm(1);
                                break;
 
-                       case 17:
+                       case TEST_POLL_TIMEOUT:
                                if (verbose)
                                        printf("Testing SCHEDOP_poll timeout\n");
                                shinfo->evtchn_pending[0] = 0;
                                alarm(1);
                                break;
 
-                       case 18:
+                       case TEST_POLL_MASKED:
                                if (verbose)
                                        printf("Testing SCHEDOP_poll wake on masked event\n");
 
@@ -841,7 +849,7 @@ int main(int argc, char *argv[])
                                alarm(1);
                                break;
 
-                       case 19:
+                       case TEST_POLL_WAKE:
                                shinfo->evtchn_pending[0] = shinfo->evtchn_mask[0] = 0;
                                if (verbose)
                                        printf("Testing SCHEDOP_poll wake on unmasked event\n");
@@ -858,7 +866,7 @@ int main(int argc, char *argv[])
                                alarm(1);
                                break;
 
-                       case 20:
+                       case TEST_TIMER_PAST:
                                TEST_ASSERT(!evtchn_irq_expected,
                                            "Expected event channel IRQ but it didn't happen");
                                /* Read timer and check it is no longer pending */
@@ -875,7 +883,7 @@ int main(int argc, char *argv[])
                                alarm(1);
                                break;
 
-                       case 21:
+                       case TEST_LOCKING_SEND_RACE:
                                TEST_ASSERT(!evtchn_irq_expected,
                                            "Expected event channel IRQ but it didn't happen");
                                alarm(0);
@@ -897,7 +905,7 @@ int main(int argc, char *argv[])
                                        __vm_ioctl(vm, KVM_XEN_HVM_EVTCHN_SEND, &uxe);
                                break;
 
-                       case 22:
+                       case TEST_LOCKING_POLL_RACE:
                                TEST_ASSERT(!evtchn_irq_expected,
                                            "Expected event channel IRQ but it didn't happen");
 
@@ -912,7 +920,7 @@ int main(int argc, char *argv[])
                                vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &tmr);
                                break;
 
-                       case 23:
+                       case TEST_LOCKING_POLL_TIMEOUT:
                                /*
                                 * Optional and possibly repeated sync point.
                                 * Injecting the timer IRQ may fail if the
@@ -934,7 +942,7 @@ int main(int argc, char *argv[])
                                                         SHINFO_RACE_TIMEOUT * 1000000000ULL;
                                vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &tmr);
                                break;
-                       case 24:
+                       case TEST_DONE:
                                TEST_ASSERT(!evtchn_irq_expected,
                                            "Expected event channel IRQ but it didn't happen");
 
@@ -945,7 +953,7 @@ int main(int argc, char *argv[])
                                TEST_ASSERT(ret == 0, "pthread_join() failed: %s", strerror(ret));
                                goto done;
 
-                       case 0x20:
+                       case TEST_GUEST_SAW_IRQ:
                                TEST_ASSERT(evtchn_irq_expected, "Unexpected event channel IRQ");
                                evtchn_irq_expected = false;
                                break;
index 88914d48c65ed8fb5270c5d96ae45c9c55faee5d..c94cde3b523f2b14a4f61986c835ad5503a95337 100644 (file)
@@ -122,10 +122,7 @@ int main(int argc, char *argv[])
                        continue;
                }
 
-               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Got exit_reason other than KVM_EXIT_IO: %u (%s)\n",
-                           run->exit_reason,
-                           exit_reason_str(run->exit_reason));
+               TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 
                switch (get_ucall(vcpu, &uc)) {
                case UCALL_ABORT:
index f7900e75d2306d2ff79d930e78a1c9110c69b48b..05400462c77996a71a439dfd7946904cbff06aa0 100644 (file)
@@ -10,12 +10,14 @@ endif
 CLANG_TARGET_FLAGS_arm          := arm-linux-gnueabi
 CLANG_TARGET_FLAGS_arm64        := aarch64-linux-gnu
 CLANG_TARGET_FLAGS_hexagon      := hexagon-linux-musl
+CLANG_TARGET_FLAGS_i386         := i386-linux-gnu
 CLANG_TARGET_FLAGS_m68k         := m68k-linux-gnu
 CLANG_TARGET_FLAGS_mips         := mipsel-linux-gnu
 CLANG_TARGET_FLAGS_powerpc      := powerpc64le-linux-gnu
 CLANG_TARGET_FLAGS_riscv        := riscv64-linux-gnu
 CLANG_TARGET_FLAGS_s390         := s390x-linux-gnu
 CLANG_TARGET_FLAGS_x86          := x86_64-linux-gnu
+CLANG_TARGET_FLAGS_x86_64       := x86_64-linux-gnu
 CLANG_TARGET_FLAGS              := $(CLANG_TARGET_FLAGS_$(ARCH))
 
 ifeq ($(CROSS_COMPILE),)
index f466a099f1bf75c5d39f810a165fdcf9bc104706..bc91bef5d254e5770d29188aae81f1259829b511 100644 (file)
@@ -163,9 +163,8 @@ TEST_F(mdwe, mprotect_WRITE_EXEC)
 
 TEST_F(mdwe, mmap_FIXED)
 {
-       void *p, *p2;
+       void *p;
 
-       p2 = mmap(NULL, self->size, PROT_READ | PROT_EXEC, self->flags, 0, 0);
        self->p = mmap(NULL, self->size, PROT_READ, self->flags, 0, 0);
        ASSERT_NE(self->p, MAP_FAILED);
 
index 582669ca38e9dd98ea2236577e5a4313ea887742..c6a8c732b802176dea234feb34ec13d6a73d6fc8 100644 (file)
@@ -18,6 +18,7 @@
 #include <grp.h>
 #include <stdbool.h>
 #include <stdarg.h>
+#include <linux/mount.h>
 
 #include "../kselftest_harness.h"
 
index a6911cae368c77b49f0083def57bbfdac75463b5..80f06aa620345815171f8f708043ddbbc1beabcb 100644 (file)
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 bind_bhash
 bind_timewait
+bind_wildcard
 csum
 cmsg_sender
 diag_uid
index 6cd8993454d7e0b647e5db3fb80526b18de0ce6f..80fbfe0330f6ec726b60b71761ca64df6e9d5b2f 100644 (file)
@@ -80,6 +80,7 @@ TEST_GEN_FILES += sctp_hello
 TEST_GEN_FILES += csum
 TEST_GEN_FILES += nat6to4.o
 TEST_GEN_FILES += ip_local_port_range
+TEST_GEN_FILES += bind_wildcard
 
 TEST_FILES := settings
 
diff --git a/tools/testing/selftests/net/bind_wildcard.c b/tools/testing/selftests/net/bind_wildcard.c
new file mode 100644 (file)
index 0000000..58edfc1
--- /dev/null
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright Amazon.com Inc. or its affiliates. */
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include "../kselftest_harness.h"
+
+FIXTURE(bind_wildcard)
+{
+       struct sockaddr_in addr4;
+       struct sockaddr_in6 addr6;
+       int expected_errno;
+};
+
+FIXTURE_VARIANT(bind_wildcard)
+{
+       const __u32 addr4_const;
+       const struct in6_addr *addr6_const;
+};
+
+FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_any)
+{
+       .addr4_const = INADDR_ANY,
+       .addr6_const = &in6addr_any,
+};
+
+FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_local)
+{
+       .addr4_const = INADDR_ANY,
+       .addr6_const = &in6addr_loopback,
+};
+
+FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_any)
+{
+       .addr4_const = INADDR_LOOPBACK,
+       .addr6_const = &in6addr_any,
+};
+
+FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_local)
+{
+       .addr4_const = INADDR_LOOPBACK,
+       .addr6_const = &in6addr_loopback,
+};
+
+FIXTURE_SETUP(bind_wildcard)
+{
+       self->addr4.sin_family = AF_INET;
+       self->addr4.sin_port = htons(0);
+       self->addr4.sin_addr.s_addr = htonl(variant->addr4_const);
+
+       self->addr6.sin6_family = AF_INET6;
+       self->addr6.sin6_port = htons(0);
+       self->addr6.sin6_addr = *variant->addr6_const;
+
+       if (variant->addr6_const == &in6addr_any)
+               self->expected_errno = EADDRINUSE;
+       else
+               self->expected_errno = 0;
+}
+
+FIXTURE_TEARDOWN(bind_wildcard)
+{
+}
+
+void bind_sockets(struct __test_metadata *_metadata,
+                 FIXTURE_DATA(bind_wildcard) *self,
+                 struct sockaddr *addr1, socklen_t addrlen1,
+                 struct sockaddr *addr2, socklen_t addrlen2)
+{
+       int fd[2];
+       int ret;
+
+       fd[0] = socket(addr1->sa_family, SOCK_STREAM, 0);
+       ASSERT_GT(fd[0], 0);
+
+       ret = bind(fd[0], addr1, addrlen1);
+       ASSERT_EQ(ret, 0);
+
+       ret = getsockname(fd[0], addr1, &addrlen1);
+       ASSERT_EQ(ret, 0);
+
+       ((struct sockaddr_in *)addr2)->sin_port = ((struct sockaddr_in *)addr1)->sin_port;
+
+       fd[1] = socket(addr2->sa_family, SOCK_STREAM, 0);
+       ASSERT_GT(fd[1], 0);
+
+       ret = bind(fd[1], addr2, addrlen2);
+       if (self->expected_errno) {
+               ASSERT_EQ(ret, -1);
+               ASSERT_EQ(errno, self->expected_errno);
+       } else {
+               ASSERT_EQ(ret, 0);
+       }
+
+       close(fd[1]);
+       close(fd[0]);
+}
+
+TEST_F(bind_wildcard, v4_v6)
+{
+       bind_sockets(_metadata, self,
+                    (struct sockaddr *)&self->addr4, sizeof(self->addr6),
+                    (struct sockaddr *)&self->addr6, sizeof(self->addr6));
+}
+
+TEST_F(bind_wildcard, v6_v4)
+{
+       bind_sockets(_metadata, self,
+                    (struct sockaddr *)&self->addr6, sizeof(self->addr6),
+                    (struct sockaddr *)&self->addr4, sizeof(self->addr4));
+}
+
+TEST_HARNESS_MAIN
index cc9fd55ab8699b0c3092ea2708ee2a363e846195..2529226ce87ca2afc86b6d96d9d0d5886864a0cd 100644 (file)
@@ -48,3 +48,4 @@ CONFIG_BAREUDP=m
 CONFIG_IPV6_IOAM6_LWTUNNEL=y
 CONFIG_CRYPTO_SM4_GENERIC=y
 CONFIG_AMT=m
+CONFIG_IP_SCTP=m
index 2b5d6ff8737388f60b9b8cef771368e8dd49d81b..2d84c7a0be6b21e7f3fbbc5472e88d1f28220a75 100755 (executable)
@@ -59,6 +59,8 @@ class devlink_ports(object):
         assert stderr == ""
         ports = json.loads(stdout)['port']
 
+        validate_devlink_output(ports, 'flavour')
+
         for port in ports:
             if dev in port:
                 if ports[port]['flavour'] == 'physical':
@@ -220,6 +222,27 @@ def split_splittable_port(port, k, lanes, dev):
     unsplit(port.bus_info)
 
 
+def validate_devlink_output(devlink_data, target_property=None):
+    """
+    Determine if test should be skipped by checking:
+      1. devlink_data contains values
+      2. The target_property exist in devlink_data
+    """
+    skip_reason = None
+    if any(devlink_data.values()):
+        if target_property:
+            skip_reason = "{} not found in devlink output, test skipped".format(target_property)
+            for key in devlink_data:
+                if target_property in devlink_data[key]:
+                    skip_reason = None
+    else:
+        skip_reason = 'devlink output is empty, test skipped'
+
+    if skip_reason:
+        print(skip_reason)
+        sys.exit(KSFT_SKIP)
+
+
 def make_parser():
     parser = argparse.ArgumentParser(description='A test for port splitting.')
     parser.add_argument('--dev',
@@ -240,12 +263,9 @@ def main(cmdline=None):
         stdout, stderr = run_command(cmd)
         assert stderr == ""
 
+        validate_devlink_output(json.loads(stdout))
         devs = json.loads(stdout)['dev']
-        if devs:
-            dev = list(devs.keys())[0]
-        else:
-            print("no devlink device was found, test skipped")
-            sys.exit(KSFT_SKIP)
+        dev = list(devs.keys())[0]
 
     cmd = "devlink dev show %s" % dev
     stdout, stderr = run_command(cmd)
@@ -255,6 +275,7 @@ def main(cmdline=None):
 
     ports = devlink_ports(dev)
 
+    found_max_lanes = False
     for port in ports.if_names:
         max_lanes = get_max_lanes(port.name)
 
@@ -277,6 +298,11 @@ def main(cmdline=None):
                 split_splittable_port(port, lane, max_lanes, dev)
 
                 lane //= 2
+        found_max_lanes = True
+
+    if not found_max_lanes:
+        print(f"Test not started, no port of device {dev} reports max_lanes")
+        sys.exit(KSFT_SKIP)
 
 
 if __name__ == "__main__":
index 66c5be25c13d03892d878b4f58154f657daa54c9..b1eb7bce599dc0e76078df68df84c9ce117eac8e 100755 (executable)
@@ -240,7 +240,7 @@ check_expected_one()
        fi
 
        stdbuf -o0 -e0 printf "\tExpected value for '%s': '%s', got '%s'.\n" \
-               "${var}" "${!var}" "${!exp}"
+               "${var}" "${!exp}" "${!var}"
        return 1
 }
 
@@ -913,6 +913,7 @@ test_listener()
                $client4_port > /dev/null 2>&1 &
        local listener_pid=$!
 
+       sleep 0.5
        verify_listener_events $client_evts $LISTENER_CREATED $AF_INET 10.0.2.2 $client4_port
 
        # ADD_ADDR from client to server machine reusing the subflow port
@@ -928,6 +929,7 @@ test_listener()
        # Delete the listener from the client ns, if one was created
        kill_wait $listener_pid
 
+       sleep 0.5
        verify_listener_events $client_evts $LISTENER_CLOSED $AF_INET 10.0.2.2 $client4_port
 }
 
index 3243c90d449e6ec2bea681c37974287b7939f55a..5d467d1993cb12a8d225654b4dde833fd23755ba 100644 (file)
@@ -62,7 +62,7 @@ class OvsDatapath(GenericNetlinkSocket):
         nla_map = (
             ("OVS_DP_ATTR_UNSPEC", "none"),
             ("OVS_DP_ATTR_NAME", "asciiz"),
-            ("OVS_DP_ATTR_UPCALL_PID", "uint32"),
+            ("OVS_DP_ATTR_UPCALL_PID", "array(uint32)"),
             ("OVS_DP_ATTR_STATS", "dpstats"),
             ("OVS_DP_ATTR_MEGAFLOW_STATS", "megaflowstats"),
             ("OVS_DP_ATTR_USER_FEATURES", "uint32"),
index 0fd0d2db3abc1baf3c7834b24547a297145f80f9..a26c5624429fb1a029d1d472921154e73a7ea86b 100755 (executable)
@@ -60,6 +60,7 @@ ip link set dev $VETH up
 ip -n $NETNS link set dev $VETH up
 chk_rps "changing rps_default_mask affect newly created devices" "" $VETH 3
 chk_rps "changing rps_default_mask don't affect newly child netns[II]" $NETNS $VETH 0
+ip link del dev $VETH
 ip netns del $NETNS
 
 setup
index 924ecb3f1f737ded0e608478c27a6737090f5c26..dd40d9f6f25998b845049de06ef4b47210f8f85a 100755 (executable)
@@ -404,6 +404,8 @@ EOF
        echo SERVER-$family | ip netns exec "$ns1" timeout 5 socat -u STDIN TCP-LISTEN:2000 &
        sc_s=$!
 
+       sleep 1
+
        result=$(ip netns exec "$ns0" timeout 1 socat TCP:$daddr:2000 STDOUT)
 
        if [ "$result" = "SERVER-inet" ];then
index 8fe61d3e3cce0a8f4beda0640f05f49ffc5eb721..bbce57420465cd81e94c61e478eb914ea29685ec 100644 (file)
@@ -1,6 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 # Makefile for nolibc tests
 include ../../../scripts/Makefile.include
+# We need this for the "cc-option" macro.
+include ../../../build/Build.include
 
 # we're in ".../tools/testing/selftests/nolibc"
 ifeq ($(srctree),)
@@ -13,52 +15,56 @@ ARCH = $(SUBARCH)
 endif
 
 # kernel image names by architecture
-IMAGE_i386    = arch/x86/boot/bzImage
-IMAGE_x86_64  = arch/x86/boot/bzImage
-IMAGE_x86     = arch/x86/boot/bzImage
-IMAGE_arm64   = arch/arm64/boot/Image
-IMAGE_arm     = arch/arm/boot/zImage
-IMAGE_mips    = vmlinuz
-IMAGE_riscv   = arch/riscv/boot/Image
-IMAGE_s390    = arch/s390/boot/bzImage
-IMAGE         = $(IMAGE_$(ARCH))
-IMAGE_NAME    = $(notdir $(IMAGE))
+IMAGE_i386       = arch/x86/boot/bzImage
+IMAGE_x86_64     = arch/x86/boot/bzImage
+IMAGE_x86        = arch/x86/boot/bzImage
+IMAGE_arm64      = arch/arm64/boot/Image
+IMAGE_arm        = arch/arm/boot/zImage
+IMAGE_mips       = vmlinuz
+IMAGE_riscv      = arch/riscv/boot/Image
+IMAGE_s390       = arch/s390/boot/bzImage
+IMAGE_loongarch  = arch/loongarch/boot/vmlinuz.efi
+IMAGE            = $(IMAGE_$(ARCH))
+IMAGE_NAME       = $(notdir $(IMAGE))
 
 # default kernel configurations that appear to be usable
-DEFCONFIG_i386    = defconfig
-DEFCONFIG_x86_64  = defconfig
-DEFCONFIG_x86     = defconfig
-DEFCONFIG_arm64   = defconfig
-DEFCONFIG_arm     = multi_v7_defconfig
-DEFCONFIG_mips    = malta_defconfig
-DEFCONFIG_riscv   = defconfig
-DEFCONFIG_s390    = defconfig
-DEFCONFIG         = $(DEFCONFIG_$(ARCH))
+DEFCONFIG_i386       = defconfig
+DEFCONFIG_x86_64     = defconfig
+DEFCONFIG_x86        = defconfig
+DEFCONFIG_arm64      = defconfig
+DEFCONFIG_arm        = multi_v7_defconfig
+DEFCONFIG_mips       = malta_defconfig
+DEFCONFIG_riscv      = defconfig
+DEFCONFIG_s390       = defconfig
+DEFCONFIG_loongarch  = defconfig
+DEFCONFIG            = $(DEFCONFIG_$(ARCH))
 
 # optional tests to run (default = all)
 TEST =
 
 # QEMU_ARCH: arch names used by qemu
-QEMU_ARCH_i386    = i386
-QEMU_ARCH_x86_64  = x86_64
-QEMU_ARCH_x86     = x86_64
-QEMU_ARCH_arm64   = aarch64
-QEMU_ARCH_arm     = arm
-QEMU_ARCH_mips    = mipsel  # works with malta_defconfig
-QEMU_ARCH_riscv   = riscv64
-QEMU_ARCH_s390    = s390x
-QEMU_ARCH         = $(QEMU_ARCH_$(ARCH))
+QEMU_ARCH_i386       = i386
+QEMU_ARCH_x86_64     = x86_64
+QEMU_ARCH_x86        = x86_64
+QEMU_ARCH_arm64      = aarch64
+QEMU_ARCH_arm        = arm
+QEMU_ARCH_mips       = mipsel  # works with malta_defconfig
+QEMU_ARCH_riscv      = riscv64
+QEMU_ARCH_s390       = s390x
+QEMU_ARCH_loongarch  = loongarch64
+QEMU_ARCH            = $(QEMU_ARCH_$(ARCH))
 
 # QEMU_ARGS : some arch-specific args to pass to qemu
-QEMU_ARGS_i386    = -M pc -append "console=ttyS0,9600 i8042.noaux panic=-1 $(TEST:%=NOLIBC_TEST=%)"
-QEMU_ARGS_x86_64  = -M pc -append "console=ttyS0,9600 i8042.noaux panic=-1 $(TEST:%=NOLIBC_TEST=%)"
-QEMU_ARGS_x86     = -M pc -append "console=ttyS0,9600 i8042.noaux panic=-1 $(TEST:%=NOLIBC_TEST=%)"
-QEMU_ARGS_arm64   = -M virt -cpu cortex-a53 -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)"
-QEMU_ARGS_arm     = -M virt -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)"
-QEMU_ARGS_mips    = -M malta -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)"
-QEMU_ARGS_riscv   = -M virt -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
-QEMU_ARGS_s390    = -M s390-ccw-virtio -m 1G -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
-QEMU_ARGS         = $(QEMU_ARGS_$(ARCH))
+QEMU_ARGS_i386       = -M pc -append "console=ttyS0,9600 i8042.noaux panic=-1 $(TEST:%=NOLIBC_TEST=%)"
+QEMU_ARGS_x86_64     = -M pc -append "console=ttyS0,9600 i8042.noaux panic=-1 $(TEST:%=NOLIBC_TEST=%)"
+QEMU_ARGS_x86        = -M pc -append "console=ttyS0,9600 i8042.noaux panic=-1 $(TEST:%=NOLIBC_TEST=%)"
+QEMU_ARGS_arm64      = -M virt -cpu cortex-a53 -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)"
+QEMU_ARGS_arm        = -M virt -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)"
+QEMU_ARGS_mips       = -M malta -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)"
+QEMU_ARGS_riscv      = -M virt -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
+QEMU_ARGS_s390       = -M s390-ccw-virtio -m 1G -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
+QEMU_ARGS_loongarch  = -M virt -append "console=ttyS0,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
+QEMU_ARGS            = $(QEMU_ARGS_$(ARCH))
 
 # OUTPUT is only set when run from the main makefile, otherwise
 # it defaults to this nolibc directory.
@@ -70,8 +76,16 @@ else
 Q=@
 endif
 
+CFLAGS_STACKPROTECTOR = -DNOLIBC_STACKPROTECTOR \
+                       $(call cc-option,-mstack-protector-guard=global) \
+                       $(call cc-option,-fstack-protector-all)
+CFLAGS_STKP_i386 = $(CFLAGS_STACKPROTECTOR)
+CFLAGS_STKP_x86_64 = $(CFLAGS_STACKPROTECTOR)
+CFLAGS_STKP_x86 = $(CFLAGS_STACKPROTECTOR)
 CFLAGS_s390 = -m64
-CFLAGS  ?= -Os -fno-ident -fno-asynchronous-unwind-tables $(CFLAGS_$(ARCH))
+CFLAGS  ?= -Os -fno-ident -fno-asynchronous-unwind-tables \
+               $(call cc-option,-fno-stack-protector) \
+               $(CFLAGS_STKP_$(ARCH)) $(CFLAGS_$(ARCH))
 LDFLAGS := -s
 
 help:
index c4a0c915139cd6eb34c8f0225f924c9aeb48d152..21bacc928bf7b260518496fcecd0cf2960628a27 100644 (file)
@@ -130,111 +130,111 @@ static int pad_spc(int llen, int cnt, const char *fmt, ...)
  */
 
 #define EXPECT_ZR(cond, expr)                          \
-       do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_zr(expr, llen); } while (0)
+       do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_zr(expr, llen); } while (0)
 
 static int expect_zr(int expr, int llen)
 {
        int ret = !(expr == 0);
 
        llen += printf(" = %d ", expr);
-       pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+       pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
        return ret;
 }
 
 
 #define EXPECT_NZ(cond, expr, val)                     \
-       do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_nz(expr, llen; } while (0)
+       do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_nz(expr, llen; } while (0)
 
 static int expect_nz(int expr, int llen)
 {
        int ret = !(expr != 0);
 
        llen += printf(" = %d ", expr);
-       pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+       pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
        return ret;
 }
 
 
 #define EXPECT_EQ(cond, expr, val)                             \
-       do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_eq(expr, llen, val); } while (0)
+       do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_eq(expr, llen, val); } while (0)
 
-static int expect_eq(int expr, int llen, int val)
+static int expect_eq(uint64_t expr, int llen, uint64_t val)
 {
        int ret = !(expr == val);
 
-       llen += printf(" = %d ", expr);
-       pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+       llen += printf(" = %lld ", expr);
+       pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
        return ret;
 }
 
 
 #define EXPECT_NE(cond, expr, val)                             \
-       do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_ne(expr, llen, val); } while (0)
+       do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_ne(expr, llen, val); } while (0)
 
 static int expect_ne(int expr, int llen, int val)
 {
        int ret = !(expr != val);
 
        llen += printf(" = %d ", expr);
-       pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+       pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
        return ret;
 }
 
 
 #define EXPECT_GE(cond, expr, val)                             \
-       do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_ge(expr, llen, val); } while (0)
+       do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_ge(expr, llen, val); } while (0)
 
 static int expect_ge(int expr, int llen, int val)
 {
        int ret = !(expr >= val);
 
        llen += printf(" = %d ", expr);
-       pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+       pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
        return ret;
 }
 
 
 #define EXPECT_GT(cond, expr, val)                             \
-       do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_gt(expr, llen, val); } while (0)
+       do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_gt(expr, llen, val); } while (0)
 
 static int expect_gt(int expr, int llen, int val)
 {
        int ret = !(expr > val);
 
        llen += printf(" = %d ", expr);
-       pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+       pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
        return ret;
 }
 
 
 #define EXPECT_LE(cond, expr, val)                             \
-       do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_le(expr, llen, val); } while (0)
+       do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_le(expr, llen, val); } while (0)
 
 static int expect_le(int expr, int llen, int val)
 {
        int ret = !(expr <= val);
 
        llen += printf(" = %d ", expr);
-       pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+       pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
        return ret;
 }
 
 
 #define EXPECT_LT(cond, expr, val)                             \
-       do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_lt(expr, llen, val); } while (0)
+       do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_lt(expr, llen, val); } while (0)
 
 static int expect_lt(int expr, int llen, int val)
 {
        int ret = !(expr < val);
 
        llen += printf(" = %d ", expr);
-       pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+       pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
        return ret;
 }
 
 
 #define EXPECT_SYSZR(cond, expr)                               \
-       do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_syszr(expr, llen); } while (0)
+       do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_syszr(expr, llen); } while (0)
 
 static int expect_syszr(int expr, int llen)
 {
@@ -243,17 +243,17 @@ static int expect_syszr(int expr, int llen)
        if (expr) {
                ret = 1;
                llen += printf(" = %d %s ", expr, errorname(errno));
-               llen += pad_spc(llen, 40, "[FAIL]\n");
+               llen += pad_spc(llen, 64, "[FAIL]\n");
        } else {
                llen += printf(" = %d ", expr);
-               llen += pad_spc(llen, 40, " [OK]\n");
+               llen += pad_spc(llen, 64, " [OK]\n");
        }
        return ret;
 }
 
 
 #define EXPECT_SYSEQ(cond, expr, val)                          \
-       do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_syseq(expr, llen, val); } while (0)
+       do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_syseq(expr, llen, val); } while (0)
 
 static int expect_syseq(int expr, int llen, int val)
 {
@@ -262,17 +262,17 @@ static int expect_syseq(int expr, int llen, int val)
        if (expr != val) {
                ret = 1;
                llen += printf(" = %d %s ", expr, errorname(errno));
-               llen += pad_spc(llen, 40, "[FAIL]\n");
+               llen += pad_spc(llen, 64, "[FAIL]\n");
        } else {
                llen += printf(" = %d ", expr);
-               llen += pad_spc(llen, 40, " [OK]\n");
+               llen += pad_spc(llen, 64, " [OK]\n");
        }
        return ret;
 }
 
 
 #define EXPECT_SYSNE(cond, expr, val)                          \
-       do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_sysne(expr, llen, val); } while (0)
+       do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_sysne(expr, llen, val); } while (0)
 
 static int expect_sysne(int expr, int llen, int val)
 {
@@ -281,17 +281,17 @@ static int expect_sysne(int expr, int llen, int val)
        if (expr == val) {
                ret = 1;
                llen += printf(" = %d %s ", expr, errorname(errno));
-               llen += pad_spc(llen, 40, "[FAIL]\n");
+               llen += pad_spc(llen, 64, "[FAIL]\n");
        } else {
                llen += printf(" = %d ", expr);
-               llen += pad_spc(llen, 40, " [OK]\n");
+               llen += pad_spc(llen, 64, " [OK]\n");
        }
        return ret;
 }
 
 
 #define EXPECT_SYSER(cond, expr, expret, experr)                       \
-       do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_syserr(expr, expret, experr, llen); } while (0)
+       do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_syserr(expr, expret, experr, llen); } while (0)
 
 static int expect_syserr(int expr, int expret, int experr, int llen)
 {
@@ -302,16 +302,16 @@ static int expect_syserr(int expr, int expret, int experr, int llen)
        if (expr != expret || _errno != experr) {
                ret = 1;
                llen += printf(" != (%d %s) ", expret, errorname(experr));
-               llen += pad_spc(llen, 40, "[FAIL]\n");
+               llen += pad_spc(llen, 64, "[FAIL]\n");
        } else {
-               llen += pad_spc(llen, 40, " [OK]\n");
+               llen += pad_spc(llen, 64, " [OK]\n");
        }
        return ret;
 }
 
 
 #define EXPECT_PTRZR(cond, expr)                               \
-       do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_ptrzr(expr, llen); } while (0)
+       do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_ptrzr(expr, llen); } while (0)
 
 static int expect_ptrzr(const void *expr, int llen)
 {
@@ -320,16 +320,16 @@ static int expect_ptrzr(const void *expr, int llen)
        llen += printf(" = <%p> ", expr);
        if (expr) {
                ret = 1;
-               llen += pad_spc(llen, 40, "[FAIL]\n");
+               llen += pad_spc(llen, 64, "[FAIL]\n");
        } else {
-               llen += pad_spc(llen, 40, " [OK]\n");
+               llen += pad_spc(llen, 64, " [OK]\n");
        }
        return ret;
 }
 
 
 #define EXPECT_PTRNZ(cond, expr)                               \
-       do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_ptrnz(expr, llen); } while (0)
+       do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_ptrnz(expr, llen); } while (0)
 
 static int expect_ptrnz(const void *expr, int llen)
 {
@@ -338,16 +338,16 @@ static int expect_ptrnz(const void *expr, int llen)
        llen += printf(" = <%p> ", expr);
        if (!expr) {
                ret = 1;
-               llen += pad_spc(llen, 40, "[FAIL]\n");
+               llen += pad_spc(llen, 64, "[FAIL]\n");
        } else {
-               llen += pad_spc(llen, 40, " [OK]\n");
+               llen += pad_spc(llen, 64, " [OK]\n");
        }
        return ret;
 }
 
 
 #define EXPECT_STRZR(cond, expr)                               \
-       do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_strzr(expr, llen); } while (0)
+       do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_strzr(expr, llen); } while (0)
 
 static int expect_strzr(const char *expr, int llen)
 {
@@ -356,16 +356,16 @@ static int expect_strzr(const char *expr, int llen)
        llen += printf(" = <%s> ", expr);
        if (expr) {
                ret = 1;
-               llen += pad_spc(llen, 40, "[FAIL]\n");
+               llen += pad_spc(llen, 64, "[FAIL]\n");
        } else {
-               llen += pad_spc(llen, 40, " [OK]\n");
+               llen += pad_spc(llen, 64, " [OK]\n");
        }
        return ret;
 }
 
 
 #define EXPECT_STRNZ(cond, expr)                               \
-       do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_strnz(expr, llen); } while (0)
+       do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_strnz(expr, llen); } while (0)
 
 static int expect_strnz(const char *expr, int llen)
 {
@@ -374,16 +374,16 @@ static int expect_strnz(const char *expr, int llen)
        llen += printf(" = <%s> ", expr);
        if (!expr) {
                ret = 1;
-               llen += pad_spc(llen, 40, "[FAIL]\n");
+               llen += pad_spc(llen, 64, "[FAIL]\n");
        } else {
-               llen += pad_spc(llen, 40, " [OK]\n");
+               llen += pad_spc(llen, 64, " [OK]\n");
        }
        return ret;
 }
 
 
 #define EXPECT_STREQ(cond, expr, cmp)                          \
-       do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_streq(expr, llen, cmp); } while (0)
+       do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_streq(expr, llen, cmp); } while (0)
 
 static int expect_streq(const char *expr, int llen, const char *cmp)
 {
@@ -392,16 +392,16 @@ static int expect_streq(const char *expr, int llen, const char *cmp)
        llen += printf(" = <%s> ", expr);
        if (strcmp(expr, cmp) != 0) {
                ret = 1;
-               llen += pad_spc(llen, 40, "[FAIL]\n");
+               llen += pad_spc(llen, 64, "[FAIL]\n");
        } else {
-               llen += pad_spc(llen, 40, " [OK]\n");
+               llen += pad_spc(llen, 64, " [OK]\n");
        }
        return ret;
 }
 
 
 #define EXPECT_STRNE(cond, expr, cmp)                          \
-       do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_strne(expr, llen, cmp); } while (0)
+       do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_strne(expr, llen, cmp); } while (0)
 
 static int expect_strne(const char *expr, int llen, const char *cmp)
 {
@@ -410,9 +410,9 @@ static int expect_strne(const char *expr, int llen, const char *cmp)
        llen += printf(" = <%s> ", expr);
        if (strcmp(expr, cmp) == 0) {
                ret = 1;
-               llen += pad_spc(llen, 40, "[FAIL]\n");
+               llen += pad_spc(llen, 64, "[FAIL]\n");
        } else {
-               llen += pad_spc(llen, 40, " [OK]\n");
+               llen += pad_spc(llen, 64, " [OK]\n");
        }
        return ret;
 }
@@ -477,6 +477,7 @@ static int test_getpagesize(void)
 int run_syscall(int min, int max)
 {
        struct stat stat_buf;
+       int euid0;
        int proc;
        int test;
        int tmp;
@@ -486,6 +487,9 @@ int run_syscall(int min, int max)
        /* <proc> indicates whether or not /proc is mounted */
        proc = stat("/proc", &stat_buf) == 0;
 
+       /* this will be used to skip certain tests that can't be run unprivileged */
+       euid0 = geteuid() == 0;
+
        for (test = min; test >= 0 && test <= max; test++) {
                int llen = 0; // line length
 
@@ -511,7 +515,7 @@ int run_syscall(int min, int max)
                CASE_TEST(chmod_net);         EXPECT_SYSZR(proc, chmod("/proc/self/net", 0555)); break;
                CASE_TEST(chmod_self);        EXPECT_SYSER(proc, chmod("/proc/self", 0555), -1, EPERM); break;
                CASE_TEST(chown_self);        EXPECT_SYSER(proc, chown("/proc/self", 0, 0), -1, EPERM); break;
-               CASE_TEST(chroot_root);       EXPECT_SYSZR(1, chroot("/")); break;
+               CASE_TEST(chroot_root);       EXPECT_SYSZR(euid0, chroot("/")); break;
                CASE_TEST(chroot_blah);       EXPECT_SYSER(1, chroot("/proc/self/blah"), -1, ENOENT); break;
                CASE_TEST(chroot_exe);        EXPECT_SYSER(proc, chroot("/proc/self/exe"), -1, ENOTDIR); break;
                CASE_TEST(close_m1);          EXPECT_SYSER(1, close(-1), -1, EBADF); break;
@@ -536,7 +540,7 @@ int run_syscall(int min, int max)
                CASE_TEST(ioctl_tiocinq);     EXPECT_SYSZR(1, ioctl(0, TIOCINQ, &tmp)); break;
                CASE_TEST(link_root1);        EXPECT_SYSER(1, link("/", "/"), -1, EEXIST); break;
                CASE_TEST(link_blah);         EXPECT_SYSER(1, link("/proc/self/blah", "/blah"), -1, ENOENT); break;
-               CASE_TEST(link_dir);          EXPECT_SYSER(1, link("/", "/blah"), -1, EPERM); break;
+               CASE_TEST(link_dir);          EXPECT_SYSER(euid0, link("/", "/blah"), -1, EPERM); break;
                CASE_TEST(link_cross);        EXPECT_SYSER(proc, link("/proc/self/net", "/blah"), -1, EXDEV); break;
                CASE_TEST(lseek_m1);          EXPECT_SYSER(1, lseek(-1, 0, SEEK_SET), -1, EBADF); break;
                CASE_TEST(lseek_0);           EXPECT_SYSER(1, lseek(0, 0, SEEK_SET), -1, ESPIPE); break;
@@ -602,6 +606,59 @@ int run_stdlib(int min, int max)
                CASE_TEST(memcmp_e0_20);       EXPECT_GT(1, memcmp("aaa\xe0", "aaa\x20", 4), 0); break;
                CASE_TEST(memcmp_80_e0);       EXPECT_LT(1, memcmp("aaa\x80", "aaa\xe0", 4), 0); break;
                CASE_TEST(memcmp_e0_80);       EXPECT_GT(1, memcmp("aaa\xe0", "aaa\x80", 4), 0); break;
+               CASE_TEST(limit_int8_max);          EXPECT_EQ(1, INT8_MAX,         (int8_t)          0x7f); break;
+               CASE_TEST(limit_int8_min);          EXPECT_EQ(1, INT8_MIN,         (int8_t)          0x80); break;
+               CASE_TEST(limit_uint8_max);         EXPECT_EQ(1, UINT8_MAX,        (uint8_t)         0xff); break;
+               CASE_TEST(limit_int16_max);         EXPECT_EQ(1, INT16_MAX,        (int16_t)         0x7fff); break;
+               CASE_TEST(limit_int16_min);         EXPECT_EQ(1, INT16_MIN,        (int16_t)         0x8000); break;
+               CASE_TEST(limit_uint16_max);        EXPECT_EQ(1, UINT16_MAX,       (uint16_t)        0xffff); break;
+               CASE_TEST(limit_int32_max);         EXPECT_EQ(1, INT32_MAX,        (int32_t)         0x7fffffff); break;
+               CASE_TEST(limit_int32_min);         EXPECT_EQ(1, INT32_MIN,        (int32_t)         0x80000000); break;
+               CASE_TEST(limit_uint32_max);        EXPECT_EQ(1, UINT32_MAX,       (uint32_t)        0xffffffff); break;
+               CASE_TEST(limit_int64_max);         EXPECT_EQ(1, INT64_MAX,        (int64_t)         0x7fffffffffffffff); break;
+               CASE_TEST(limit_int64_min);         EXPECT_EQ(1, INT64_MIN,        (int64_t)         0x8000000000000000); break;
+               CASE_TEST(limit_uint64_max);        EXPECT_EQ(1, UINT64_MAX,       (uint64_t)        0xffffffffffffffff); break;
+               CASE_TEST(limit_int_least8_max);    EXPECT_EQ(1, INT_LEAST8_MAX,   (int_least8_t)    0x7f); break;
+               CASE_TEST(limit_int_least8_min);    EXPECT_EQ(1, INT_LEAST8_MIN,   (int_least8_t)    0x80); break;
+               CASE_TEST(limit_uint_least8_max);   EXPECT_EQ(1, UINT_LEAST8_MAX,  (uint_least8_t)   0xff); break;
+               CASE_TEST(limit_int_least16_max);   EXPECT_EQ(1, INT_LEAST16_MAX,  (int_least16_t)   0x7fff); break;
+               CASE_TEST(limit_int_least16_min);   EXPECT_EQ(1, INT_LEAST16_MIN,  (int_least16_t)   0x8000); break;
+               CASE_TEST(limit_uint_least16_max);  EXPECT_EQ(1, UINT_LEAST16_MAX, (uint_least16_t)  0xffff); break;
+               CASE_TEST(limit_int_least32_max);   EXPECT_EQ(1, INT_LEAST32_MAX,  (int_least32_t)   0x7fffffff); break;
+               CASE_TEST(limit_int_least32_min);   EXPECT_EQ(1, INT_LEAST32_MIN,  (int_least32_t)   0x80000000); break;
+               CASE_TEST(limit_uint_least32_max);  EXPECT_EQ(1, UINT_LEAST32_MAX, (uint_least32_t)  0xffffffffU); break;
+               CASE_TEST(limit_int_least64_min);   EXPECT_EQ(1, INT_LEAST64_MIN,  (int_least64_t)   0x8000000000000000LL); break;
+               CASE_TEST(limit_int_least64_max);   EXPECT_EQ(1, INT_LEAST64_MAX,  (int_least64_t)   0x7fffffffffffffffLL); break;
+               CASE_TEST(limit_uint_least64_max);  EXPECT_EQ(1, UINT_LEAST64_MAX, (uint_least64_t)  0xffffffffffffffffULL); break;
+               CASE_TEST(limit_int_fast8_max);     EXPECT_EQ(1, INT_FAST8_MAX,    (int_fast8_t)     0x7f); break;
+               CASE_TEST(limit_int_fast8_min);     EXPECT_EQ(1, INT_FAST8_MIN,    (int_fast8_t)     0x80); break;
+               CASE_TEST(limit_uint_fast8_max);    EXPECT_EQ(1, UINT_FAST8_MAX,   (uint_fast8_t)    0xff); break;
+               CASE_TEST(limit_int_fast16_min);    EXPECT_EQ(1, INT_FAST16_MIN,   (int_fast16_t)    INTPTR_MIN); break;
+               CASE_TEST(limit_int_fast16_max);    EXPECT_EQ(1, INT_FAST16_MAX,   (int_fast16_t)    INTPTR_MAX); break;
+               CASE_TEST(limit_uint_fast16_max);   EXPECT_EQ(1, UINT_FAST16_MAX,  (uint_fast16_t)   UINTPTR_MAX); break;
+               CASE_TEST(limit_int_fast32_min);    EXPECT_EQ(1, INT_FAST32_MIN,   (int_fast32_t)    INTPTR_MIN); break;
+               CASE_TEST(limit_int_fast32_max);    EXPECT_EQ(1, INT_FAST32_MAX,   (int_fast32_t)    INTPTR_MAX); break;
+               CASE_TEST(limit_uint_fast32_max);   EXPECT_EQ(1, UINT_FAST32_MAX,  (uint_fast32_t)   UINTPTR_MAX); break;
+               CASE_TEST(limit_int_fast64_min);    EXPECT_EQ(1, INT_FAST64_MIN,   (int_fast64_t)    INTPTR_MIN); break;
+               CASE_TEST(limit_int_fast64_max);    EXPECT_EQ(1, INT_FAST64_MAX,   (int_fast64_t)    INTPTR_MAX); break;
+               CASE_TEST(limit_uint_fast64_max);   EXPECT_EQ(1, UINT_FAST64_MAX,  (uint_fast64_t)   UINTPTR_MAX); break;
+#if __SIZEOF_LONG__ == 8
+               CASE_TEST(limit_intptr_min);        EXPECT_EQ(1, INTPTR_MIN,       (intptr_t)        0x8000000000000000LL); break;
+               CASE_TEST(limit_intptr_max);        EXPECT_EQ(1, INTPTR_MAX,       (intptr_t)        0x7fffffffffffffffLL); break;
+               CASE_TEST(limit_uintptr_max);       EXPECT_EQ(1, UINTPTR_MAX,      (uintptr_t)       0xffffffffffffffffULL); break;
+               CASE_TEST(limit_ptrdiff_min);       EXPECT_EQ(1, PTRDIFF_MIN,      (ptrdiff_t)       0x8000000000000000LL); break;
+               CASE_TEST(limit_ptrdiff_max);       EXPECT_EQ(1, PTRDIFF_MAX,      (ptrdiff_t)       0x7fffffffffffffffLL); break;
+               CASE_TEST(limit_size_max);          EXPECT_EQ(1, SIZE_MAX,         (size_t)          0xffffffffffffffffULL); break;
+#elif __SIZEOF_LONG__ == 4
+               CASE_TEST(limit_intptr_min);        EXPECT_EQ(1, INTPTR_MIN,       (intptr_t)        0x80000000); break;
+               CASE_TEST(limit_intptr_max);        EXPECT_EQ(1, INTPTR_MAX,       (intptr_t)        0x7fffffff); break;
+               CASE_TEST(limit_uintptr_max);       EXPECT_EQ(1, UINTPTR_MAX,      (uintptr_t)       0xffffffffU); break;
+               CASE_TEST(limit_ptrdiff_min);       EXPECT_EQ(1, PTRDIFF_MIN,      (ptrdiff_t)       0x80000000); break;
+               CASE_TEST(limit_ptrdiff_max);       EXPECT_EQ(1, PTRDIFF_MAX,      (ptrdiff_t)       0x7fffffff); break;
+               CASE_TEST(limit_size_max);          EXPECT_EQ(1, SIZE_MAX,         (size_t)          0xffffffffU); break;
+#else
+# warning "__SIZEOF_LONG__ is undefined"
+#endif /* __SIZEOF_LONG__ */
                case __LINE__:
                        return ret; /* must be last */
                /* note: do not set any defaults so as to permit holes above */
@@ -610,6 +667,63 @@ int run_stdlib(int min, int max)
        return ret;
 }
 
+#if defined(__clang__)
+__attribute__((optnone))
+#elif defined(__GNUC__)
+__attribute__((optimize("O0")))
+#endif
+static int smash_stack(void)
+{
+       char buf[100];
+
+       for (size_t i = 0; i < 200; i++)
+               buf[i] = 'P';
+
+       return 1;
+}
+
+static int run_protection(int min, int max)
+{
+       pid_t pid;
+       int llen = 0, status;
+
+       llen += printf("0 -fstackprotector ");
+
+#if !defined(NOLIBC_STACKPROTECTOR)
+       llen += printf("not supported");
+       pad_spc(llen, 64, "[SKIPPED]\n");
+       return 0;
+#endif
+
+       pid = -1;
+       pid = fork();
+
+       switch (pid) {
+       case -1:
+               llen += printf("fork()");
+               pad_spc(llen, 64, "[FAIL]\n");
+               return 1;
+
+       case 0:
+               close(STDOUT_FILENO);
+               close(STDERR_FILENO);
+
+               smash_stack();
+               return 1;
+
+       default:
+               pid = waitpid(pid, &status, 0);
+
+               if (pid == -1 || !WIFSIGNALED(status) || WTERMSIG(status) != SIGABRT) {
+                       llen += printf("waitpid()");
+                       pad_spc(llen, 64, "[FAIL]\n");
+                       return 1;
+               }
+               pad_spc(llen, 64, " [OK]\n");
+               return 0;
+       }
+}
+
 /* prepare what needs to be prepared for pid 1 (stdio, /dev, /proc, etc) */
 int prepare(void)
 {
@@ -660,10 +774,11 @@ int prepare(void)
 }
 
 /* This is the definition of known test names, with their functions */
-static struct test test_names[] = {
+static const struct test test_names[] = {
        /* add new tests here */
-       { .name = "syscall",   .func = run_syscall  },
-       { .name = "stdlib",    .func = run_stdlib   },
+       { .name = "syscall",    .func = run_syscall    },
+       { .name = "stdlib",     .func = run_stdlib     },
+       { .name = "protection", .func = run_protection },
        { 0 }
 };
 
index 91af2b631bc96037875a0e6bdb3dd8305229e412..7a657b25f686d38e125a82d15a5279285bfd83ad 100644 (file)
@@ -2,3 +2,4 @@
 disable-tsc-ctxt-sw-stress-test
 disable-tsc-on-off-stress-test
 disable-tsc-test
+set-anon-vma-name-test
index c7923b205222dd0361a8971426780fde5498c19a..c058b81eeb41860b8dd915a72146340f253c0f18 100644 (file)
@@ -5,7 +5,7 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
 
 ifeq ($(ARCH),x86)
 TEST_PROGS := disable-tsc-ctxt-sw-stress-test disable-tsc-on-off-stress-test \
-               disable-tsc-test
+               disable-tsc-test set-anon-vma-name-test
 all: $(TEST_PROGS)
 
 include ../lib.mk
diff --git a/tools/testing/selftests/prctl/config b/tools/testing/selftests/prctl/config
new file mode 100644 (file)
index 0000000..c6ed03c
--- /dev/null
@@ -0,0 +1 @@
+CONFIG_ANON_VMA_NAME=y
diff --git a/tools/testing/selftests/prctl/set-anon-vma-name-test.c b/tools/testing/selftests/prctl/set-anon-vma-name-test.c
new file mode 100644 (file)
index 0000000..26d853c
--- /dev/null
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * This test covers the anonymous VMA naming functionality through prctl calls
+ */
+
+#include <errno.h>
+#include <sys/prctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <string.h>
+
+#include "../kselftest_harness.h"
+
+#define AREA_SIZE 1024
+
+#define GOOD_NAME "goodname"
+#define BAD_NAME "badname\1"
+
+#ifndef PR_SET_VMA
+#define PR_SET_VMA 0x53564d41
+#define PR_SET_VMA_ANON_NAME 0
+#endif
+
+
+int rename_vma(unsigned long addr, unsigned long size, char *name)
+{
+       int res;
+
+       res = prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, addr, size, name);
+       if (res < 0)
+               return -errno;
+       return res;
+}
+
+int was_renaming_successful(char *target_name, unsigned long ptr)
+{
+       FILE *maps_file;
+
+       char line_buf[512], name[128], mode[8];
+       unsigned long start_addr, end_addr, offset;
+       unsigned int major_id, minor_id, node_id;
+
+       char target_buf[128];
+       int res = 0, sscanf_res;
+
+       // The entry name in maps will be in format [anon:<target_name>]
+       sprintf(target_buf, "[anon:%s]", target_name);
+       maps_file = fopen("/proc/self/maps", "r");
+       if (!maps_file) {
+               printf("## /proc/self/maps file opening error\n");
+               return 0;
+       }
+
+       // Parse the maps file to find the entry we renamed
+       while (fgets(line_buf, sizeof(line_buf), maps_file)) {
+               sscanf_res = sscanf(line_buf, "%lx-%lx %7s %lx %u:%u %u %s", &start_addr,
+                                       &end_addr, mode, &offset, &major_id,
+                                       &minor_id, &node_id, name);
+               if (sscanf_res == EOF) {
+                       res = 0;
+                       printf("## EOF while parsing the maps file\n");
+                       break;
+               }
+               if (!strcmp(name, target_buf) && start_addr == ptr) {
+                       res = 1;
+                       break;
+               }
+       }
+       fclose(maps_file);
+       return res;
+}
+
+FIXTURE(vma) {
+       void *ptr_anon, *ptr_not_anon;
+};
+
+FIXTURE_SETUP(vma) {
+       self->ptr_anon = mmap(NULL, AREA_SIZE, PROT_READ | PROT_WRITE,
+                                       MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+       ASSERT_NE(self->ptr_anon, NULL);
+       self->ptr_not_anon = mmap(NULL, AREA_SIZE, PROT_READ | PROT_WRITE,
+                                       MAP_PRIVATE, 0, 0);
+       ASSERT_NE(self->ptr_not_anon, NULL);
+}
+
+FIXTURE_TEARDOWN(vma) {
+       munmap(self->ptr_anon, AREA_SIZE);
+       munmap(self->ptr_not_anon, AREA_SIZE);
+}
+
+TEST_F(vma, renaming) {
+       TH_LOG("Try to rename the VMA with correct parameters");
+       EXPECT_GE(rename_vma((unsigned long)self->ptr_anon, AREA_SIZE, GOOD_NAME), 0);
+       EXPECT_TRUE(was_renaming_successful(GOOD_NAME, (unsigned long)self->ptr_anon));
+
+       TH_LOG("Try to pass invalid name (with non-printable character \\1) to rename the VMA");
+       EXPECT_EQ(rename_vma((unsigned long)self->ptr_anon, AREA_SIZE, BAD_NAME), -EINVAL);
+
+       TH_LOG("Try to rename non-anonynous VMA");
+       EXPECT_EQ(rename_vma((unsigned long) self->ptr_not_anon, AREA_SIZE, GOOD_NAME), -EINVAL);
+}
+
+TEST_HARNESS_MAIN
index 54900657eb442f81835e7e7c8f1647f8bedceb2d..a6884f66dc0130b5970544065a28745e73a26cc1 100644 (file)
@@ -151,7 +151,7 @@ out:
 
 int main(int argc, char *argv[])
 {
-       siginfo_t siginfo[SIGNR];
+       siginfo_t siginfo;
        int i, exit_code = 1;
        sigset_t blockmask;
        pid_t child;
@@ -176,13 +176,13 @@ int main(int argc, char *argv[])
 
        /* Send signals in process-wide and per-thread queues */
        for (i = 0; i < SIGNR; i++) {
-               siginfo->si_code = TEST_SICODE_SHARE;
-               siginfo->si_int = i;
-               sys_rt_sigqueueinfo(child, SIGRTMIN, siginfo);
+               siginfo.si_code = TEST_SICODE_SHARE;
+               siginfo.si_int = i;
+               sys_rt_sigqueueinfo(child, SIGRTMIN, &siginfo);
 
-               siginfo->si_code = TEST_SICODE_PRIV;
-               siginfo->si_int = i;
-               sys_rt_tgsigqueueinfo(child, child, SIGRTMIN, siginfo);
+               siginfo.si_code = TEST_SICODE_PRIV;
+               siginfo.si_int = i;
+               sys_rt_tgsigqueueinfo(child, child, SIGRTMIN, &siginfo);
        }
 
        if (sys_ptrace(PTRACE_ATTACH, child, NULL, NULL) == -1)
index 8a968fbda02c9e5e452281dd59017681f4b97f60..88ca4e36848908272a9947c07ff6b6afc8224578 100755 (executable)
@@ -193,7 +193,7 @@ do
        qemu_cmd_dir="`dirname "$i"`"
        kernel_dir="`echo $qemu_cmd_dir | sed -e 's/\.[0-9]\+$//'`"
        jitter_dir="`dirname "$kernel_dir"`"
-       kvm-transform.sh "$kernel_dir/bzImage" "$qemu_cmd_dir/console.log" "$jitter_dir" $dur "$bootargs" < $T/qemu-cmd > $i
+       kvm-transform.sh "$kernel_dir/bzImage" "$qemu_cmd_dir/console.log" "$jitter_dir" "$dur" "$bootargs" < $T/qemu-cmd > $i
        if test -n "$arg_remote"
        then
                echo "# TORTURE_KCONFIG_GDB_ARG=''" >> $i
diff --git a/tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh b/tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh
new file mode 100755 (executable)
index 0000000..2e63ef0
--- /dev/null
@@ -0,0 +1,78 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Run SRCU-lockdep tests and report any that fail to meet expectations.
+#
+# Copyright (C) 2021 Meta Platforms, Inc.
+#
+# Authors: Paul E. McKenney <paulmck@kernel.org>
+
+usage () {
+       echo "Usage: $scriptname optional arguments:"
+       echo "       --datestamp string"
+       exit 1
+}
+
+ds=`date +%Y.%m.%d-%H.%M.%S`-srcu_lockdep
+scriptname="$0"
+
+T="`mktemp -d ${TMPDIR-/tmp}/srcu_lockdep.sh.XXXXXX`"
+trap 'rm -rf $T' 0
+
+RCUTORTURE="`pwd`/tools/testing/selftests/rcutorture"; export RCUTORTURE
+PATH=${RCUTORTURE}/bin:$PATH; export PATH
+. functions.sh
+
+while test $# -gt 0
+do
+       case "$1" in
+       --datestamp)
+               checkarg --datestamp "(relative pathname)" "$#" "$2" '^[a-zA-Z0-9._/-]*$' '^--'
+               ds=$2
+               shift
+               ;;
+       *)
+               echo Unknown argument $1
+               usage
+               ;;
+       esac
+       shift
+done
+
+err=
+nerrs=0
+for d in 0 1
+do
+       for t in 0 1 2
+       do
+               for c in 1 2 3
+               do
+                       err=
+                       val=$((d*1000+t*10+c))
+                       tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 5s --configs "SRCU-P" --bootargs "rcutorture.test_srcu_lockdep=$val" --trust-make --datestamp "$ds/$val" > "$T/kvm.sh.out" 2>&1
+                       ret=$?
+                       mv "$T/kvm.sh.out" "$RCUTORTURE/res/$ds/$val"
+                       if test "$d" -ne 0 && test "$ret" -eq 0
+                       then
+                               err=1
+                               echo -n Unexpected success for > "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
+                       fi
+                       if test "$d" -eq 0 && test "$ret" -ne 0
+                       then
+                               err=1
+                               echo -n Unexpected failure for > "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
+                       fi
+                       if test -n "$err"
+                       then
+                               grep "rcu_torture_init_srcu_lockdep: test_srcu_lockdep = " "$RCUTORTURE/res/$ds/$val/SRCU-P/console.log" | sed -e 's/^.*rcu_torture_init_srcu_lockdep://' >> "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
+                               cat "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
+                               nerrs=$((nerrs+1))
+                       fi
+               done
+       done
+done
+if test "$nerrs" -ne 0
+then
+       exit 1
+fi
+exit 0
index 130d0de4c3bbd3e5c4133823f5bfb7650a0a4f06..5a2ae2264403f063ad596c80d6ee824739bcb687 100755 (executable)
@@ -497,16 +497,16 @@ fi
 
 if test "$do_clocksourcewd" = "yes"
 then
-       torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000"
+       torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 tsc=watchdog"
        torture_set "clocksourcewd-1" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 45s --configs TREE03 --kconfig "CONFIG_TEST_CLOCKSOURCE_WATCHDOG=y" --trust-make
 
-       torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 clocksource.max_cswd_read_retries=1"
+       torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 clocksource.max_cswd_read_retries=1 tsc=watchdog"
        torture_set "clocksourcewd-2" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 45s --configs TREE03 --kconfig "CONFIG_TEST_CLOCKSOURCE_WATCHDOG=y" --trust-make
 
        # In case our work is already done...
        if test "$do_rcutorture" != "yes"
        then
-               torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000"
+               torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 tsc=watchdog"
                torture_set "clocksourcewd-3" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 45s --configs TREE03 --trust-make
        fi
 fi
index 41bae5824339453c7a0b3a9fc6db60ba98588bc5..28e23d05d5a5574b14a17cb65397fef6b47ccf55 100644 (file)
@@ -5,3 +5,5 @@ LOCK04
 LOCK05
 LOCK06
 LOCK07
+LOCK08
+LOCK09
diff --git a/tools/testing/selftests/rcutorture/configs/lock/LOCK08 b/tools/testing/selftests/rcutorture/configs/lock/LOCK08
new file mode 100644 (file)
index 0000000..1d1da14
--- /dev/null
@@ -0,0 +1,6 @@
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
+CONFIG_HOTPLUG_CPU=y
+CONFIG_PREEMPT_NONE=n
+CONFIG_PREEMPT_VOLUNTARY=n
+CONFIG_PREEMPT=y
diff --git a/tools/testing/selftests/rcutorture/configs/lock/LOCK08.boot b/tools/testing/selftests/rcutorture/configs/lock/LOCK08.boot
new file mode 100644 (file)
index 0000000..b8b6cae
--- /dev/null
@@ -0,0 +1 @@
+locktorture.torture_type=mutex_lock locktorture.nested_locks=8
diff --git a/tools/testing/selftests/rcutorture/configs/lock/LOCK09 b/tools/testing/selftests/rcutorture/configs/lock/LOCK09
new file mode 100644 (file)
index 0000000..1d1da14
--- /dev/null
@@ -0,0 +1,6 @@
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
+CONFIG_HOTPLUG_CPU=y
+CONFIG_PREEMPT_NONE=n
+CONFIG_PREEMPT_VOLUNTARY=n
+CONFIG_PREEMPT=y
diff --git a/tools/testing/selftests/rcutorture/configs/lock/LOCK09.boot b/tools/testing/selftests/rcutorture/configs/lock/LOCK09.boot
new file mode 100644 (file)
index 0000000..fd5eff1
--- /dev/null
@@ -0,0 +1 @@
+locktorture.torture_type=rtmutex_lock locktorture.nested_locks=8
index 8ae41d5f81a3e941e5f5cbf1bc295ed75b4ba3ad..04831ef1f9b55421063775b3a543f9a2f0cc6536 100644 (file)
@@ -15,3 +15,4 @@ CONFIG_DEBUG_LOCK_ALLOC=n
 CONFIG_RCU_BOOST=n
 CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
 CONFIG_RCU_EXPERT=y
+CONFIG_BOOTPARAM_HOTPLUG_CPU0=y
index ae395981b5e5e7c03499bd3d9140c6de8b034690..dc4985064b3adb31f8db2d6ffc65a283774ac6df 100644 (file)
@@ -15,3 +15,4 @@ CONFIG_DEBUG_LOCK_ALLOC=n
 CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
 CONFIG_RCU_EXPERT=y
 CONFIG_RCU_EQS_DEBUG=y
+CONFIG_RCU_LAZY=y
index 42acb1a64ce10b2b1460143cd44c39ec4021b4c4..3f5fb66f16df7b4c4ab6247f69a7a76e5ff7406f 100644 (file)
@@ -71,9 +71,5 @@ CONFIG_TASKS_RCU
 
        These are controlled by CONFIG_PREEMPT and/or CONFIG_SMP.
 
-CONFIG_SRCU
-
-       Selected by CONFIG_RCU_TORTURE_TEST, so cannot disable.
-
 
 boot parameters ignored: TBD
index 68ff856d36f0bc52720f31dae88bea29d01470bb..8a4fe8693be63e5ae2ad40dea0ed68fd07fd4bf0 100644 (file)
@@ -48,7 +48,7 @@ static int perf_event_open_llc_miss(pid_t pid, int cpu_no)
        return 0;
 }
 
-static int initialize_llc_perf(void)
+static void initialize_llc_perf(void)
 {
        memset(&pea_llc_miss, 0, sizeof(struct perf_event_attr));
        memset(&rf_cqm, 0, sizeof(struct read_format));
@@ -59,8 +59,6 @@ static int initialize_llc_perf(void)
        pea_llc_miss.config = PERF_COUNT_HW_CACHE_MISSES;
 
        rf_cqm.nr = 1;
-
-       return 0;
 }
 
 static int reset_enable_llc_perf(pid_t pid, int cpu_no)
@@ -79,7 +77,7 @@ static int reset_enable_llc_perf(pid_t pid, int cpu_no)
 
 /*
  * get_llc_perf:       llc cache miss through perf events
- * @cpu_no:            CPU number that the benchmark PID is binded to
+ * @llc_perf_miss:     LLC miss counter that is filled on success
  *
  * Perf events like HW_CACHE_MISSES could be used to validate number of
  * cache lines allocated.
@@ -234,20 +232,19 @@ int cat_val(struct resctrl_val_param *param)
        if (ret)
                return ret;
 
-       if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) {
-               ret = initialize_llc_perf();
-               if (ret)
-                       return ret;
-       }
+       if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)))
+               initialize_llc_perf();
 
        /* Test runs until the callback setup() tells the test to stop. */
        while (1) {
                if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) {
                        ret = param->setup(1, param);
-                       if (ret) {
+                       if (ret == END_OF_TESTS) {
                                ret = 0;
                                break;
                        }
+                       if (ret < 0)
+                               break;
                        ret = reset_enable_llc_perf(bm_pid, param->cpu_no);
                        if (ret)
                                break;
index 1c5e90c632548100c92c803432d154678c9ba98d..fb1443f888c4c90beabca9c93649ce3458c7a7a5 100644 (file)
@@ -40,7 +40,7 @@ static int cat_setup(int num, ...)
 
        /* Run NUM_OF_RUNS times */
        if (p->num_of_runs >= NUM_OF_RUNS)
-               return -1;
+               return END_OF_TESTS;
 
        if (p->num_of_runs == 0) {
                sprintf(schemata, "%lx", p->mask);
@@ -103,7 +103,6 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
        unsigned long l_mask, l_mask_1;
        int ret, pipefd[2], sibling_cpu_no;
        char pipe_message;
-       pid_t bm_pid;
 
        cache_size = 0;
 
@@ -145,7 +144,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
        struct resctrl_val_param param = {
                .resctrl_val    = CAT_STR,
                .cpu_no         = cpu_no,
-               .mum_resctrlfs  = 0,
+               .mum_resctrlfs  = false,
                .setup          = cat_setup,
        };
 
@@ -167,6 +166,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
                return errno;
        }
 
+       fflush(stdout);
        bm_pid = fork();
 
        /* Set param values for child thread which will be allocated bitmask
@@ -180,28 +180,31 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
                strcpy(param.filename, RESULT_FILE_NAME1);
                param.num_of_runs = 0;
                param.cpu_no = sibling_cpu_no;
+       } else {
+               ret = signal_handler_register();
+               if (ret) {
+                       kill(bm_pid, SIGKILL);
+                       goto out;
+               }
        }
 
        remove(param.filename);
 
        ret = cat_val(&param);
-       if (ret)
-               return ret;
-
-       ret = check_results(&param);
-       if (ret)
-               return ret;
+       if (ret == 0)
+               ret = check_results(&param);
 
        if (bm_pid == 0) {
                /* Tell parent that child is ready */
                close(pipefd[0]);
                pipe_message = 1;
                if (write(pipefd[1], &pipe_message, sizeof(pipe_message)) <
-                   sizeof(pipe_message)) {
-                       close(pipefd[1]);
+                   sizeof(pipe_message))
+                       /*
+                        * Just print the error message.
+                        * Let while(1) run and wait for itself to be killed.
+                        */
                        perror("# failed signaling parent process");
-                       return errno;
-               }
 
                close(pipefd[1]);
                while (1)
@@ -219,11 +222,13 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
                }
                close(pipefd[0]);
                kill(bm_pid, SIGKILL);
+               signal_handler_unregister();
        }
 
+out:
        cat_test_cleanup();
        if (bm_pid)
                umount_resctrlfs();
 
-       return 0;
+       return ret;
 }
index 8968e36db99d79cca16e99321e4f79e72bad4e24..af71b21412710b8d2ea511e36569225f9dd64f7e 100644 (file)
@@ -32,7 +32,7 @@ static int cmt_setup(int num, ...)
 
        /* Run NUM_OF_RUNS times */
        if (p->num_of_runs >= NUM_OF_RUNS)
-               return -1;
+               return END_OF_TESTS;
 
        p->num_of_runs++;
 
@@ -82,12 +82,11 @@ void cmt_test_cleanup(void)
 
 int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
 {
-       int ret, mum_resctrlfs;
+       int ret;
 
        cache_size = 0;
-       mum_resctrlfs = 1;
 
-       ret = remount_resctrlfs(mum_resctrlfs);
+       ret = remount_resctrlfs(true);
        if (ret)
                return ret;
 
@@ -118,7 +117,7 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
                .ctrlgrp        = "c1",
                .mongrp         = "m1",
                .cpu_no         = cpu_no,
-               .mum_resctrlfs  = 0,
+               .mum_resctrlfs  = false,
                .filename       = RESULT_FILE_NAME,
                .mask           = ~(long_mask << n) & long_mask,
                .span           = cache_size * n / count_of_bits,
@@ -133,13 +132,12 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
 
        ret = resctrl_val(benchmark_cmd, &param);
        if (ret)
-               return ret;
+               goto out;
 
        ret = check_results(&param, n);
-       if (ret)
-               return ret;
 
+out:
        cmt_test_cleanup();
 
-       return 0;
+       return ret;
 }
index 56ccbeae0638d57fda0e99d4eaa70ae6b742e370..341cc93ca84c4b86535c4fb58043ed52af96ae2e 100644 (file)
@@ -14,7 +14,6 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <inttypes.h>
-#include <malloc.h>
 #include <string.h>
 
 #include "resctrl.h"
@@ -33,14 +32,6 @@ static void sb(void)
 #endif
 }
 
-static void ctrl_handler(int signo)
-{
-       free(startptr);
-       printf("\nEnding\n");
-       sb();
-       exit(EXIT_SUCCESS);
-}
-
 static void cl_flush(void *p)
 {
 #if defined(__i386) || defined(__x86_64)
@@ -64,10 +55,14 @@ static void mem_flush(void *p, size_t s)
 
 static void *malloc_and_init_memory(size_t s)
 {
+       void *p = NULL;
        uint64_t *p64;
        size_t s64;
+       int ret;
 
-       void *p = memalign(PAGE_SIZE, s);
+       ret = posix_memalign(&p, PAGE_SIZE, s);
+       if (ret < 0)
+               return NULL;
 
        p64 = (uint64_t *)p;
        s64 = s / sizeof(uint64_t);
@@ -198,12 +193,6 @@ int run_fill_buf(unsigned long span, int malloc_and_init_memory,
        unsigned long long cache_size = span;
        int ret;
 
-       /* set up ctrl-c handler */
-       if (signal(SIGINT, ctrl_handler) == SIG_ERR)
-               printf("Failed to catch SIGINT!\n");
-       if (signal(SIGHUP, ctrl_handler) == SIG_ERR)
-               printf("Failed to catch SIGHUP!\n");
-
        ret = fill_cache(cache_size, malloc_and_init_memory, memflush, op,
                         resctrl_val);
        if (ret) {
index 1a1bdb6180cf2ac32c2f30bf5ff7245f4dc5922f..cde3781a9ab0504aaddd916248247ac556a9b739 100644 (file)
@@ -28,6 +28,7 @@ static int mba_setup(int num, ...)
        struct resctrl_val_param *p;
        char allocation_str[64];
        va_list param;
+       int ret;
 
        va_start(param, num);
        p = va_arg(param, struct resctrl_val_param *);
@@ -41,20 +42,24 @@ static int mba_setup(int num, ...)
                return 0;
 
        if (allocation < ALLOCATION_MIN || allocation > ALLOCATION_MAX)
-               return -1;
+               return END_OF_TESTS;
 
        sprintf(allocation_str, "%d", allocation);
 
-       write_schemata(p->ctrlgrp, allocation_str, p->cpu_no, p->resctrl_val);
+       ret = write_schemata(p->ctrlgrp, allocation_str, p->cpu_no,
+                            p->resctrl_val);
+       if (ret < 0)
+               return ret;
+
        allocation -= ALLOCATION_STEP;
 
        return 0;
 }
 
-static void show_mba_info(unsigned long *bw_imc, unsigned long *bw_resc)
+static bool show_mba_info(unsigned long *bw_imc, unsigned long *bw_resc)
 {
        int allocation, runs;
-       bool failed = false;
+       bool ret = false;
 
        ksft_print_msg("Results are displayed in (MB)\n");
        /* Memory bandwidth from 100% down to 10% */
@@ -90,13 +95,15 @@ static void show_mba_info(unsigned long *bw_imc, unsigned long *bw_resc)
                ksft_print_msg("avg_bw_imc: %lu\n", avg_bw_imc);
                ksft_print_msg("avg_bw_resc: %lu\n", avg_bw_resc);
                if (avg_diff_per > MAX_DIFF_PERCENT)
-                       failed = true;
+                       ret = true;
        }
 
        ksft_print_msg("%s Check schemata change using MBA\n",
-                      failed ? "Fail:" : "Pass:");
-       if (failed)
+                      ret ? "Fail:" : "Pass:");
+       if (ret)
                ksft_print_msg("At least one test failed\n");
+
+       return ret;
 }
 
 static int check_results(void)
@@ -132,9 +139,7 @@ static int check_results(void)
 
        fclose(fp);
 
-       show_mba_info(bw_imc, bw_resc);
-
-       return 0;
+       return show_mba_info(bw_imc, bw_resc);
 }
 
 void mba_test_cleanup(void)
@@ -149,7 +154,7 @@ int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd)
                .ctrlgrp        = "c1",
                .mongrp         = "m1",
                .cpu_no         = cpu_no,
-               .mum_resctrlfs  = 1,
+               .mum_resctrlfs  = true,
                .filename       = RESULT_FILE_NAME,
                .bw_report      = bw_report,
                .setup          = mba_setup
@@ -160,13 +165,12 @@ int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd)
 
        ret = resctrl_val(benchmark_cmd, &param);
        if (ret)
-               return ret;
+               goto out;
 
        ret = check_results();
-       if (ret)
-               return ret;
 
+out:
        mba_test_cleanup();
 
-       return 0;
+       return ret;
 }
index 8392e5c55ed02599dd15446f27acce245faca90a..538d35a6485acd0c885896104e03b0f34a82ae33 100644 (file)
@@ -89,23 +89,24 @@ static int check_results(int span)
 static int mbm_setup(int num, ...)
 {
        struct resctrl_val_param *p;
-       static int num_of_runs;
        va_list param;
        int ret = 0;
 
-       /* Run NUM_OF_RUNS times */
-       if (num_of_runs++ >= NUM_OF_RUNS)
-               return -1;
-
        va_start(param, num);
        p = va_arg(param, struct resctrl_val_param *);
        va_end(param);
 
+       /* Run NUM_OF_RUNS times */
+       if (p->num_of_runs >= NUM_OF_RUNS)
+               return END_OF_TESTS;
+
        /* Set up shemata with 100% allocation on the first run. */
-       if (num_of_runs == 0)
+       if (p->num_of_runs == 0)
                ret = write_schemata(p->ctrlgrp, "100", p->cpu_no,
                                     p->resctrl_val);
 
+       p->num_of_runs++;
+
        return ret;
 }
 
@@ -122,7 +123,7 @@ int mbm_bw_change(int span, int cpu_no, char *bw_report, char **benchmark_cmd)
                .mongrp         = "m1",
                .span           = span,
                .cpu_no         = cpu_no,
-               .mum_resctrlfs  = 1,
+               .mum_resctrlfs  = true,
                .filename       = RESULT_FILE_NAME,
                .bw_report      =  bw_report,
                .setup          = mbm_setup
@@ -133,13 +134,12 @@ int mbm_bw_change(int span, int cpu_no, char *bw_report, char **benchmark_cmd)
 
        ret = resctrl_val(benchmark_cmd, &param);
        if (ret)
-               return ret;
+               goto out;
 
        ret = check_results(span);
-       if (ret)
-               return ret;
 
+out:
        mbm_test_cleanup();
 
-       return 0;
+       return ret;
 }
index f0ded31fb3c7cbf05540480cfe64ef7000d52e1d..87e39456dee082166ac96398c792b9729114684e 100644 (file)
@@ -28,7 +28,7 @@
 #define MB                     (1024 * 1024)
 #define RESCTRL_PATH           "/sys/fs/resctrl"
 #define PHYS_ID_PATH           "/sys/devices/system/cpu/cpu"
-#define CBM_MASK_PATH          "/sys/fs/resctrl/info"
+#define INFO_PATH              "/sys/fs/resctrl/info"
 #define L3_PATH                        "/sys/fs/resctrl/info/L3"
 #define MB_PATH                        "/sys/fs/resctrl/info/MB"
 #define L3_MON_PATH            "/sys/fs/resctrl/info/L3_MON"
@@ -37,6 +37,8 @@
 #define ARCH_INTEL     1
 #define ARCH_AMD       2
 
+#define END_OF_TESTS   1
+
 #define PARENT_EXIT(err_msg)                   \
        do {                                    \
                perror(err_msg);                \
@@ -62,7 +64,7 @@ struct resctrl_val_param {
        char            mongrp[64];
        int             cpu_no;
        unsigned long   span;
-       int             mum_resctrlfs;
+       bool            mum_resctrlfs;
        char            filename[64];
        char            *bw_report;
        unsigned long   mask;
@@ -107,6 +109,8 @@ void mba_test_cleanup(void);
 int get_cbm_mask(char *cache_type, char *cbm_mask);
 int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size);
 void ctrlc_handler(int signum, siginfo_t *info, void *ptr);
+int signal_handler_register(void);
+void signal_handler_unregister(void);
 int cat_val(struct resctrl_val_param *param);
 void cat_test_cleanup(void);
 int cat_perf_miss_val(int cpu_no, int no_of_bits, char *cache_type);
index df0d8d8526fc6c91b7b622776c78d41e9d0ab7c0..9b9751206e1c134d5ea8610b5ec5f95aae2ef8db 100644 (file)
@@ -77,7 +77,7 @@ static void run_mbm_test(bool has_ben, char **benchmark_cmd, int span,
 
        ksft_print_msg("Starting MBM BW change ...\n");
 
-       if (!validate_resctrl_feature_request(MBM_STR)) {
+       if (!validate_resctrl_feature_request(MBM_STR) || (get_vendor() != ARCH_INTEL)) {
                ksft_test_result_skip("Hardware does not support MBM or MBM is disabled\n");
                return;
        }
@@ -88,7 +88,6 @@ static void run_mbm_test(bool has_ben, char **benchmark_cmd, int span,
        ksft_test_result(!res, "MBM: bw change\n");
        if ((get_vendor() == ARCH_INTEL) && res)
                ksft_print_msg("Intel MBM may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
-       mbm_test_cleanup();
 }
 
 static void run_mba_test(bool has_ben, char **benchmark_cmd, int span,
@@ -98,7 +97,7 @@ static void run_mba_test(bool has_ben, char **benchmark_cmd, int span,
 
        ksft_print_msg("Starting MBA Schemata change ...\n");
 
-       if (!validate_resctrl_feature_request(MBA_STR)) {
+       if (!validate_resctrl_feature_request(MBA_STR) || (get_vendor() != ARCH_INTEL)) {
                ksft_test_result_skip("Hardware does not support MBA or MBA is disabled\n");
                return;
        }
@@ -107,7 +106,6 @@ static void run_mba_test(bool has_ben, char **benchmark_cmd, int span,
                sprintf(benchmark_cmd[1], "%d", span);
        res = mba_schemata_change(cpu_no, bw_report, benchmark_cmd);
        ksft_test_result(!res, "MBA: schemata change\n");
-       mba_test_cleanup();
 }
 
 static void run_cmt_test(bool has_ben, char **benchmark_cmd, int cpu_no)
@@ -126,7 +124,6 @@ static void run_cmt_test(bool has_ben, char **benchmark_cmd, int cpu_no)
        ksft_test_result(!res, "CMT: test\n");
        if ((get_vendor() == ARCH_INTEL) && res)
                ksft_print_msg("Intel CMT may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
-       cmt_test_cleanup();
 }
 
 static void run_cat_test(int cpu_no, int no_of_bits)
@@ -142,7 +139,6 @@ static void run_cat_test(int cpu_no, int no_of_bits)
 
        res = cat_perf_miss_val(cpu_no, no_of_bits, "L3");
        ksft_test_result(!res, "CAT: test\n");
-       cat_test_cleanup();
 }
 
 int main(int argc, char **argv)
@@ -258,10 +254,10 @@ int main(int argc, char **argv)
 
        ksft_set_plan(tests ? : 4);
 
-       if ((get_vendor() == ARCH_INTEL) && mbm_test)
+       if (mbm_test)
                run_mbm_test(has_ben, benchmark_cmd, span, cpu_no, bw_report);
 
-       if ((get_vendor() == ARCH_INTEL) && mba_test)
+       if (mba_test)
                run_mba_test(has_ben, benchmark_cmd, span, cpu_no, bw_report);
 
        if (cmt_test)
@@ -272,5 +268,5 @@ int main(int argc, char **argv)
 
        umount_resctrlfs();
 
-       return ksft_exit_pass();
+       ksft_finished();
 }
index b32b96356ec70a79136b44b9d3b045894ba9c0b1..ab1eab1e7ff63e838416c67aec1e1469a193639d 100644 (file)
@@ -476,6 +476,45 @@ void ctrlc_handler(int signum, siginfo_t *info, void *ptr)
        exit(EXIT_SUCCESS);
 }
 
+/*
+ * Register CTRL-C handler for parent, as it has to kill
+ * child process before exiting.
+ */
+int signal_handler_register(void)
+{
+       struct sigaction sigact;
+       int ret = 0;
+
+       sigact.sa_sigaction = ctrlc_handler;
+       sigemptyset(&sigact.sa_mask);
+       sigact.sa_flags = SA_SIGINFO;
+       if (sigaction(SIGINT, &sigact, NULL) ||
+           sigaction(SIGTERM, &sigact, NULL) ||
+           sigaction(SIGHUP, &sigact, NULL)) {
+               perror("# sigaction");
+               ret = -1;
+       }
+       return ret;
+}
+
+/*
+ * Reset signal handler to SIG_DFL.
+ * Non-Value return because the caller should keep
+ * the error code of other path even if sigaction fails.
+ */
+void signal_handler_unregister(void)
+{
+       struct sigaction sigact;
+
+       sigact.sa_handler = SIG_DFL;
+       sigemptyset(&sigact.sa_mask);
+       if (sigaction(SIGINT, &sigact, NULL) ||
+           sigaction(SIGTERM, &sigact, NULL) ||
+           sigaction(SIGHUP, &sigact, NULL)) {
+               perror("# sigaction");
+       }
+}
+
 /*
  * print_results_bw:   the memory bandwidth results are stored in a file
  * @filename:          file that stores the results
@@ -629,6 +668,7 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
         * Fork to start benchmark, save child's pid so that it can be killed
         * when needed
         */
+       fflush(stdout);
        bm_pid = fork();
        if (bm_pid == -1) {
                perror("# Unable to fork");
@@ -670,39 +710,28 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
 
        ksft_print_msg("Benchmark PID: %d\n", bm_pid);
 
-       /*
-        * Register CTRL-C handler for parent, as it has to kill benchmark
-        * before exiting
-        */
-       sigact.sa_sigaction = ctrlc_handler;
-       sigemptyset(&sigact.sa_mask);
-       sigact.sa_flags = SA_SIGINFO;
-       if (sigaction(SIGINT, &sigact, NULL) ||
-           sigaction(SIGTERM, &sigact, NULL) ||
-           sigaction(SIGHUP, &sigact, NULL)) {
-               perror("# sigaction");
-               ret = errno;
+       ret = signal_handler_register();
+       if (ret)
                goto out;
-       }
 
        value.sival_ptr = benchmark_cmd;
 
        /* Taskset benchmark to specified cpu */
        ret = taskset_benchmark(bm_pid, param->cpu_no);
        if (ret)
-               goto out;
+               goto unregister;
 
        /* Write benchmark to specified control&monitoring grp in resctrl FS */
        ret = write_bm_pid_to_resctrl(bm_pid, param->ctrlgrp, param->mongrp,
                                      resctrl_val);
        if (ret)
-               goto out;
+               goto unregister;
 
        if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) ||
            !strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
                ret = initialize_mem_bw_imc();
                if (ret)
-                       goto out;
+                       goto unregister;
 
                initialize_mem_bw_resctrl(param->ctrlgrp, param->mongrp,
                                          param->cpu_no, resctrl_val);
@@ -717,7 +746,7 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
                    sizeof(pipe_message)) {
                        perror("# failed reading message from child process");
                        close(pipefd[0]);
-                       goto out;
+                       goto unregister;
                }
        }
        close(pipefd[0]);
@@ -726,7 +755,7 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
        if (sigqueue(bm_pid, SIGUSR1, value) == -1) {
                perror("# sigqueue SIGUSR1 to child");
                ret = errno;
-               goto out;
+               goto unregister;
        }
 
        /* Give benchmark enough time to fully run */
@@ -734,32 +763,29 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
 
        /* Test runs until the callback setup() tells the test to stop. */
        while (1) {
+               ret = param->setup(1, param);
+               if (ret == END_OF_TESTS) {
+                       ret = 0;
+                       break;
+               }
+               if (ret < 0)
+                       break;
+
                if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) ||
                    !strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
-                       ret = param->setup(1, param);
-                       if (ret) {
-                               ret = 0;
-                               break;
-                       }
-
                        ret = measure_vals(param, &bw_resc_start);
                        if (ret)
                                break;
                } else if (!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) {
-                       ret = param->setup(1, param);
-                       if (ret) {
-                               ret = 0;
-                               break;
-                       }
                        sleep(1);
                        ret = measure_cache_vals(param, bm_pid);
                        if (ret)
                                break;
-               } else {
-                       break;
                }
        }
 
+unregister:
+       signal_handler_unregister();
 out:
        kill(bm_pid, SIGKILL);
        umount_resctrlfs();
index 6f543e470ad4aacc999cf946bca301754b9c65c9..fb00245dee92e8b035d881cbe556cd09023de939 100644 (file)
@@ -210,7 +210,7 @@ int get_cbm_mask(char *cache_type, char *cbm_mask)
        if (!cbm_mask)
                return -1;
 
-       sprintf(cbm_mask_path, "%s/%s/cbm_mask", CBM_MASK_PATH, cache_type);
+       sprintf(cbm_mask_path, "%s/%s/cbm_mask", INFO_PATH, cache_type);
 
        fp = fopen(cbm_mask_path, "r");
        if (!fp) {
@@ -498,6 +498,7 @@ int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val)
        FILE *fp;
 
        if (strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) &&
+           strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) &&
            strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) &&
            strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR)))
                return -ENOENT;
@@ -523,7 +524,8 @@ int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val)
        if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) ||
            !strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR)))
                sprintf(schema, "%s%d%c%s", "L3:", resource_id, '=', schemata);
-       if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)))
+       if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) ||
+           !strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)))
                sprintf(schema, "%s%d%c%s", "MB:", resource_id, '=', schemata);
 
        fp = fopen(controlgroup, "w");
@@ -676,6 +678,7 @@ int filter_dmesg(void)
                perror("pipe");
                return ret;
        }
+       fflush(stdout);
        pid = fork();
        if (pid == 0) {
                close(pipefds[0]);
index 25e0d95d37133177fe52e2cce64f01ba73f2712c..3e1619b6bf2da5156a8e53dfba7aeab60b4d03a8 100644 (file)
@@ -334,6 +334,12 @@ int main(int argc, char *argv[])
        validate(get_cs_cookie(pid) != 0);
        validate(get_cs_cookie(pid) == get_cs_cookie(procs[pidx].thr_tids[0]));
 
+       validate(_prctl(PR_SCHED_CORE, PR_SCHED_CORE_MAX, 0, PIDTYPE_PGID, 0) < 0
+               && errno == EINVAL);
+
+       validate(_prctl(PR_SCHED_CORE, PR_SCHED_CORE_SHARE_TO, 0, PIDTYPE_PGID, 1) < 0
+               && errno == EINVAL);
+
        if (errors) {
                printf("TESTS FAILED. errors: %d\n", errors);
                res = 10;
diff --git a/tools/testing/selftests/sigaltstack/current_stack_pointer.h b/tools/testing/selftests/sigaltstack/current_stack_pointer.h
new file mode 100644 (file)
index 0000000..ea9bdf3
--- /dev/null
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#if __alpha__
+register unsigned long sp asm("$30");
+#elif __arm__ || __aarch64__ || __csky__ || __m68k__ || __mips__ || __riscv
+register unsigned long sp asm("sp");
+#elif __i386__
+register unsigned long sp asm("esp");
+#elif __loongarch64
+register unsigned long sp asm("$sp");
+#elif __ppc__
+register unsigned long sp asm("r1");
+#elif __s390x__
+register unsigned long sp asm("%15");
+#elif __sh__
+register unsigned long sp asm("r15");
+#elif __x86_64__
+register unsigned long sp asm("rsp");
+#elif __XTENSA__
+register unsigned long sp asm("a1");
+#else
+#error "implement current_stack_pointer equivalent"
+#endif
index c53b070755b65eb9f4454c795ad31521020ba284..98d37cb744fb28f628e628bcfb27bb24a714ac87 100644 (file)
@@ -20,6 +20,7 @@
 #include <sys/auxv.h>
 
 #include "../kselftest.h"
+#include "current_stack_pointer.h"
 
 #ifndef SS_AUTODISARM
 #define SS_AUTODISARM  (1U << 31)
@@ -46,12 +47,6 @@ void my_usr1(int sig, siginfo_t *si, void *u)
        stack_t stk;
        struct stk_data *p;
 
-#if __s390x__
-       register unsigned long sp asm("%15");
-#else
-       register unsigned long sp asm("sp");
-#endif
-
        if (sp < (unsigned long)sstack ||
                        sp >= (unsigned long)sstack + stack_size) {
                ksft_exit_fail_msg("SP is not on sigaltstack\n");
index 625e42901237c0c47db7bb129ff9921e3633bfde..d884fd69dd510bce52c684f496eb68b9d5ba866b 100644 (file)
 #include <sys/auxv.h>
 #include <sys/mman.h>
 #include <sys/shm.h>
+#include <sys/ptrace.h>
 #include <sys/syscall.h>
 #include <sys/wait.h>
+#include <sys/uio.h>
 
 #include "../kselftest.h" /* For __cpuid_count() */
 
@@ -583,6 +585,13 @@ static void test_dynamic_state(void)
        _exit(0);
 }
 
+static inline int __compare_tiledata_state(struct xsave_buffer *xbuf1, struct xsave_buffer *xbuf2)
+{
+       return memcmp(&xbuf1->bytes[xtiledata.xbuf_offset],
+                     &xbuf2->bytes[xtiledata.xbuf_offset],
+                     xtiledata.size);
+}
+
 /*
  * Save current register state and compare it to @xbuf1.'
  *
@@ -599,9 +608,7 @@ static inline bool __validate_tiledata_regs(struct xsave_buffer *xbuf1)
                fatal_error("failed to allocate XSAVE buffer\n");
 
        xsave(xbuf2, XFEATURE_MASK_XTILEDATA);
-       ret = memcmp(&xbuf1->bytes[xtiledata.xbuf_offset],
-                    &xbuf2->bytes[xtiledata.xbuf_offset],
-                    xtiledata.size);
+       ret = __compare_tiledata_state(xbuf1, xbuf2);
 
        free(xbuf2);
 
@@ -826,6 +833,99 @@ static void test_context_switch(void)
        free(finfo);
 }
 
+/* Ptrace test */
+
+/*
+ * Make sure the ptracee has the expanded kernel buffer on the first
+ * use. Then, initialize the state before performing the state
+ * injection from the ptracer.
+ */
+static inline void ptracee_firstuse_tiledata(void)
+{
+       load_rand_tiledata(stashed_xsave);
+       init_xtiledata();
+}
+
+/*
+ * Ptracer injects the randomized tile data state. It also reads
+ * before and after that, which will execute the kernel's state copy
+ * functions. So, the tester is advised to double-check any emitted
+ * kernel messages.
+ */
+static void ptracer_inject_tiledata(pid_t target)
+{
+       struct xsave_buffer *xbuf;
+       struct iovec iov;
+
+       xbuf = alloc_xbuf();
+       if (!xbuf)
+               fatal_error("unable to allocate XSAVE buffer");
+
+       printf("\tRead the init'ed tiledata via ptrace().\n");
+
+       iov.iov_base = xbuf;
+       iov.iov_len = xbuf_size;
+
+       memset(stashed_xsave, 0, xbuf_size);
+
+       if (ptrace(PTRACE_GETREGSET, target, (uint32_t)NT_X86_XSTATE, &iov))
+               fatal_error("PTRACE_GETREGSET");
+
+       if (!__compare_tiledata_state(stashed_xsave, xbuf))
+               printf("[OK]\tThe init'ed tiledata was read from ptracee.\n");
+       else
+               printf("[FAIL]\tThe init'ed tiledata was not read from ptracee.\n");
+
+       printf("\tInject tiledata via ptrace().\n");
+
+       load_rand_tiledata(xbuf);
+
+       memcpy(&stashed_xsave->bytes[xtiledata.xbuf_offset],
+              &xbuf->bytes[xtiledata.xbuf_offset],
+              xtiledata.size);
+
+       if (ptrace(PTRACE_SETREGSET, target, (uint32_t)NT_X86_XSTATE, &iov))
+               fatal_error("PTRACE_SETREGSET");
+
+       if (ptrace(PTRACE_GETREGSET, target, (uint32_t)NT_X86_XSTATE, &iov))
+               fatal_error("PTRACE_GETREGSET");
+
+       if (!__compare_tiledata_state(stashed_xsave, xbuf))
+               printf("[OK]\tTiledata was correctly written to ptracee.\n");
+       else
+               printf("[FAIL]\tTiledata was not correctly written to ptracee.\n");
+}
+
+static void test_ptrace(void)
+{
+       pid_t child;
+       int status;
+
+       child = fork();
+       if (child < 0) {
+               err(1, "fork");
+       } else if (!child) {
+               if (ptrace(PTRACE_TRACEME, 0, NULL, NULL))
+                       err(1, "PTRACE_TRACEME");
+
+               ptracee_firstuse_tiledata();
+
+               raise(SIGTRAP);
+               _exit(0);
+       }
+
+       do {
+               wait(&status);
+       } while (WSTOPSIG(status) != SIGTRAP);
+
+       ptracer_inject_tiledata(child);
+
+       ptrace(PTRACE_DETACH, child, NULL, NULL);
+       wait(&status);
+       if (!WIFEXITED(status) || WEXITSTATUS(status))
+               err(1, "ptrace test");
+}
+
 int main(void)
 {
        /* Check hardware availability at first */
@@ -846,6 +946,8 @@ int main(void)
        ctxtswtest_config.num_threads = 5;
        test_context_switch();
 
+       test_ptrace();
+
        clearhandler(SIGILL);
        free_stashed_xsave();
 
index 67e9f9df3a8c4eae6421fe23b8bcef89319140ea..12b97c92fbb20dcf68adfc5d03eca7dc8dd1c0c4 100644 (file)
@@ -860,6 +860,199 @@ static void test_stream_poll_rcvlowat_client(const struct test_opts *opts)
        close(fd);
 }
 
+#define INV_BUF_TEST_DATA_LEN 512
+
+static void test_inv_buf_client(const struct test_opts *opts, bool stream)
+{
+       unsigned char data[INV_BUF_TEST_DATA_LEN] = {0};
+       ssize_t ret;
+       int fd;
+
+       if (stream)
+               fd = vsock_stream_connect(opts->peer_cid, 1234);
+       else
+               fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
+
+       if (fd < 0) {
+               perror("connect");
+               exit(EXIT_FAILURE);
+       }
+
+       control_expectln("SENDDONE");
+
+       /* Use invalid buffer here. */
+       ret = recv(fd, NULL, sizeof(data), 0);
+       if (ret != -1) {
+               fprintf(stderr, "expected recv(2) failure, got %zi\n", ret);
+               exit(EXIT_FAILURE);
+       }
+
+       if (errno != ENOMEM) {
+               fprintf(stderr, "unexpected recv(2) errno %d\n", errno);
+               exit(EXIT_FAILURE);
+       }
+
+       ret = recv(fd, data, sizeof(data), MSG_DONTWAIT);
+
+       if (stream) {
+               /* For SOCK_STREAM we must continue reading. */
+               if (ret != sizeof(data)) {
+                       fprintf(stderr, "expected recv(2) success, got %zi\n", ret);
+                       exit(EXIT_FAILURE);
+               }
+               /* Don't check errno in case of success. */
+       } else {
+               /* For SOCK_SEQPACKET socket's queue must be empty. */
+               if (ret != -1) {
+                       fprintf(stderr, "expected recv(2) failure, got %zi\n", ret);
+                       exit(EXIT_FAILURE);
+               }
+
+               if (errno != EAGAIN) {
+                       fprintf(stderr, "unexpected recv(2) errno %d\n", errno);
+                       exit(EXIT_FAILURE);
+               }
+       }
+
+       control_writeln("DONE");
+
+       close(fd);
+}
+
+static void test_inv_buf_server(const struct test_opts *opts, bool stream)
+{
+       unsigned char data[INV_BUF_TEST_DATA_LEN] = {0};
+       ssize_t res;
+       int fd;
+
+       if (stream)
+               fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
+       else
+               fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
+
+       if (fd < 0) {
+               perror("accept");
+               exit(EXIT_FAILURE);
+       }
+
+       res = send(fd, data, sizeof(data), 0);
+       if (res != sizeof(data)) {
+               fprintf(stderr, "unexpected send(2) result %zi\n", res);
+               exit(EXIT_FAILURE);
+       }
+
+       control_writeln("SENDDONE");
+
+       control_expectln("DONE");
+
+       close(fd);
+}
+
+static void test_stream_inv_buf_client(const struct test_opts *opts)
+{
+       test_inv_buf_client(opts, true);
+}
+
+static void test_stream_inv_buf_server(const struct test_opts *opts)
+{
+       test_inv_buf_server(opts, true);
+}
+
+static void test_seqpacket_inv_buf_client(const struct test_opts *opts)
+{
+       test_inv_buf_client(opts, false);
+}
+
+static void test_seqpacket_inv_buf_server(const struct test_opts *opts)
+{
+       test_inv_buf_server(opts, false);
+}
+
+#define HELLO_STR "HELLO"
+#define WORLD_STR "WORLD"
+
+static void test_stream_virtio_skb_merge_client(const struct test_opts *opts)
+{
+       ssize_t res;
+       int fd;
+
+       fd = vsock_stream_connect(opts->peer_cid, 1234);
+       if (fd < 0) {
+               perror("connect");
+               exit(EXIT_FAILURE);
+       }
+
+       /* Send first skbuff. */
+       res = send(fd, HELLO_STR, strlen(HELLO_STR), 0);
+       if (res != strlen(HELLO_STR)) {
+               fprintf(stderr, "unexpected send(2) result %zi\n", res);
+               exit(EXIT_FAILURE);
+       }
+
+       control_writeln("SEND0");
+       /* Peer reads part of first skbuff. */
+       control_expectln("REPLY0");
+
+       /* Send second skbuff, it will be appended to the first. */
+       res = send(fd, WORLD_STR, strlen(WORLD_STR), 0);
+       if (res != strlen(WORLD_STR)) {
+               fprintf(stderr, "unexpected send(2) result %zi\n", res);
+               exit(EXIT_FAILURE);
+       }
+
+       control_writeln("SEND1");
+       /* Peer reads merged skbuff packet. */
+       control_expectln("REPLY1");
+
+       close(fd);
+}
+
+static void test_stream_virtio_skb_merge_server(const struct test_opts *opts)
+{
+       unsigned char buf[64];
+       ssize_t res;
+       int fd;
+
+       fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
+       if (fd < 0) {
+               perror("accept");
+               exit(EXIT_FAILURE);
+       }
+
+       control_expectln("SEND0");
+
+       /* Read skbuff partially. */
+       res = recv(fd, buf, 2, 0);
+       if (res != 2) {
+               fprintf(stderr, "expected recv(2) returns 2 bytes, got %zi\n", res);
+               exit(EXIT_FAILURE);
+       }
+
+       control_writeln("REPLY0");
+       control_expectln("SEND1");
+
+       res = recv(fd, buf + 2, sizeof(buf) - 2, 0);
+       if (res != 8) {
+               fprintf(stderr, "expected recv(2) returns 8 bytes, got %zi\n", res);
+               exit(EXIT_FAILURE);
+       }
+
+       res = recv(fd, buf, sizeof(buf) - 8 - 2, MSG_DONTWAIT);
+       if (res != -1) {
+               fprintf(stderr, "expected recv(2) failure, got %zi\n", res);
+               exit(EXIT_FAILURE);
+       }
+
+       if (memcmp(buf, HELLO_STR WORLD_STR, strlen(HELLO_STR WORLD_STR))) {
+               fprintf(stderr, "pattern mismatch\n");
+               exit(EXIT_FAILURE);
+       }
+
+       control_writeln("REPLY1");
+
+       close(fd);
+}
+
 static struct test_case test_cases[] = {
        {
                .name = "SOCK_STREAM connection reset",
@@ -920,6 +1113,21 @@ static struct test_case test_cases[] = {
                .run_client = test_seqpacket_bigmsg_client,
                .run_server = test_seqpacket_bigmsg_server,
        },
+       {
+               .name = "SOCK_STREAM test invalid buffer",
+               .run_client = test_stream_inv_buf_client,
+               .run_server = test_stream_inv_buf_server,
+       },
+       {
+               .name = "SOCK_SEQPACKET test invalid buffer",
+               .run_client = test_seqpacket_inv_buf_client,
+               .run_server = test_seqpacket_inv_buf_server,
+       },
+       {
+               .name = "SOCK_STREAM virtio skb merge",
+               .run_client = test_stream_virtio_skb_merge_client,
+               .run_server = test_stream_virtio_skb_merge_server,
+       },
        {},
 };
 
index 075588c4da0815227ccb95609d477477d99203a4..9934d48d9a55772f4c49ad513f8f8c651370d736 100644 (file)
@@ -2,3 +2,4 @@
 *.d
 virtio_test
 vringh_test
+virtio-trace/trace-agent
index b64845b823abde33b051563585d4c718a051a501..4fb9368bf7519b36e8c49ac78ad3ffa9ef15d496 100644 (file)
@@ -61,7 +61,7 @@ and
       id=channel0,name=agent-ctl-path\
  ##data path##
      -chardev pipe,id=charchannel1,path=/tmp/virtio-trace/trace-path-cpu0\
-     -device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel0,\
+     -device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,\
       id=channel1,name=trace-path-cpu0\
       ...
 
index ee01e40e8bc65e06ba3b74e3f50d5aaa485bcea1..61230532fef10f7261db75e5757a8b2c4366d2d9 100644 (file)
@@ -353,6 +353,12 @@ static int cpio_mkfile(const char *name, const char *location,
                buf.st_mtime = 0xffffffff;
        }
 
+       if (buf.st_mtime < 0) {
+               fprintf(stderr, "%s: Timestamp negative, clipping.\n",
+                       location);
+               buf.st_mtime = 0;
+       }
+
        if (buf.st_size > 0xffffffff) {
                fprintf(stderr, "%s: Size exceeds maximum cpio file size\n",
                        location);
@@ -602,10 +608,10 @@ int main (int argc, char *argv[])
        /*
         * Timestamps after 2106-02-07 06:28:15 UTC have an ascii hex time_t
         * representation that exceeds 8 chars and breaks the cpio header
-        * specification.
+        * specification. Negative timestamps similarly exceed 8 chars.
         */
-       if (default_mtime > 0xffffffff) {
-               fprintf(stderr, "ERROR: Timestamp too large for cpio format\n");
+       if (default_mtime > 0xffffffff || default_mtime < 0) {
+               fprintf(stderr, "ERROR: Timestamp out of range for cpio format\n");
                exit(1);
        }
 
index 2a3ed401ce4653377d55de9b02ccfa9e6086f3f3..b0af834ffa95092540d0aee1e39602c3907d84bb 100644 (file)
@@ -55,6 +55,15 @@ irqfd_inject(struct work_struct *work)
                            irqfd->gsi, 1, false);
 }
 
+static void irqfd_resampler_notify(struct kvm_kernel_irqfd_resampler *resampler)
+{
+       struct kvm_kernel_irqfd *irqfd;
+
+       list_for_each_entry_srcu(irqfd, &resampler->list, resampler_link,
+                                srcu_read_lock_held(&resampler->kvm->irq_srcu))
+               eventfd_signal(irqfd->resamplefd, 1);
+}
+
 /*
  * Since resampler irqfds share an IRQ source ID, we de-assert once
  * then notify all of the resampler irqfds using this GSI.  We can't
@@ -65,7 +74,6 @@ irqfd_resampler_ack(struct kvm_irq_ack_notifier *kian)
 {
        struct kvm_kernel_irqfd_resampler *resampler;
        struct kvm *kvm;
-       struct kvm_kernel_irqfd *irqfd;
        int idx;
 
        resampler = container_of(kian,
@@ -76,11 +84,7 @@ irqfd_resampler_ack(struct kvm_irq_ack_notifier *kian)
                    resampler->notifier.gsi, 0, false);
 
        idx = srcu_read_lock(&kvm->irq_srcu);
-
-       list_for_each_entry_srcu(irqfd, &resampler->list, resampler_link,
-           srcu_read_lock_held(&kvm->irq_srcu))
-               eventfd_signal(irqfd->resamplefd, 1);
-
+       irqfd_resampler_notify(resampler);
        srcu_read_unlock(&kvm->irq_srcu, idx);
 }
 
@@ -96,8 +100,12 @@ irqfd_resampler_shutdown(struct kvm_kernel_irqfd *irqfd)
        synchronize_srcu(&kvm->irq_srcu);
 
        if (list_empty(&resampler->list)) {
-               list_del(&resampler->link);
+               list_del_rcu(&resampler->link);
                kvm_unregister_irq_ack_notifier(kvm, &resampler->notifier);
+               /*
+                * synchronize_srcu(&kvm->irq_srcu) already called
+                * in kvm_unregister_irq_ack_notifier().
+                */
                kvm_set_irq(kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID,
                            resampler->notifier.gsi, 0, false);
                kfree(resampler);
@@ -369,7 +377,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
                        resampler->notifier.irq_acked = irqfd_resampler_ack;
                        INIT_LIST_HEAD(&resampler->link);
 
-                       list_add(&resampler->link, &kvm->irqfds.resampler_list);
+                       list_add_rcu(&resampler->link, &kvm->irqfds.resampler_list);
                        kvm_register_irq_ack_notifier(kvm,
                                                      &resampler->notifier);
                        irqfd->resampler = resampler;
@@ -644,6 +652,31 @@ void kvm_irq_routing_update(struct kvm *kvm)
        spin_unlock_irq(&kvm->irqfds.lock);
 }
 
+bool kvm_notify_irqfd_resampler(struct kvm *kvm,
+                               unsigned int irqchip,
+                               unsigned int pin)
+{
+       struct kvm_kernel_irqfd_resampler *resampler;
+       int gsi, idx;
+
+       idx = srcu_read_lock(&kvm->irq_srcu);
+       gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
+       if (gsi != -1) {
+               list_for_each_entry_srcu(resampler,
+                                        &kvm->irqfds.resampler_list, link,
+                                        srcu_read_lock_held(&kvm->irq_srcu)) {
+                       if (resampler->notifier.gsi == gsi) {
+                               irqfd_resampler_notify(resampler);
+                               srcu_read_unlock(&kvm->irq_srcu, idx);
+                               return true;
+                       }
+               }
+       }
+       srcu_read_unlock(&kvm->irq_srcu, idx);
+
+       return false;
+}
+
 /*
  * create a host-wide workqueue for issuing deferred shutdown requests
  * aggregated from all vm* instances. We need our own isolated
index d255964ec331ef5c9aebf90243990ef4da0aec2b..b1679d08a216099a379df472a6cc52c268e4e51d 100644 (file)
@@ -4479,7 +4479,6 @@ static long kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg)
 #endif
 #ifdef CONFIG_HAVE_KVM_IRQFD
        case KVM_CAP_IRQFD:
-       case KVM_CAP_IRQFD_RESAMPLE:
 #endif
        case KVM_CAP_IOEVENTFD_ANY_LENGTH:
        case KVM_CAP_CHECK_EXTENSION_VM: